225 lines
9.4 KiB
EmacsLisp
225 lines
9.4 KiB
EmacsLisp
// tests/suite/test_collections.el — tests for native list operations
|
|
//
|
|
// runtime/collections.el does not exist; this file tests the native list
|
|
// primitives that are always available in El: el_list_empty, el_list_append,
|
|
// el_list_len, el_list_get.
|
|
//
|
|
// These primitives underpin str_split, str_join, and the env.el list helpers.
|
|
|
|
// ── el_list_empty ─────────────────────────────────────────────────────────────
|
|
|
|
fn test_list_empty_basic(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
assert_int_eq(el_list_len(lst), 0, "empty list has length 0")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_empty_multiple(_: String) -> String {
|
|
let a: [String] = el_list_empty()
|
|
let b: [String] = el_list_empty()
|
|
assert_int_eq(el_list_len(a), 0, "first empty list has length 0")
|
|
assert_int_eq(el_list_len(b), 0, "second empty list has length 0")
|
|
// Append to one does not affect the other
|
|
let a2: [String] = el_list_append(a, "hello")
|
|
assert_int_eq(el_list_len(a2), 1, "appended list has length 1")
|
|
assert_int_eq(el_list_len(b), 0, "other empty list unaffected")
|
|
return ""
|
|
}
|
|
|
|
// ── el_list_append ────────────────────────────────────────────────────────────
|
|
|
|
fn test_list_append_single(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst2: [String] = el_list_append(lst, "hello")
|
|
assert_int_eq(el_list_len(lst2), 1, "length is 1 after append")
|
|
assert_eq(el_list_get(lst2, 0), "hello", "first element is what was appended")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_append_multiple(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst = el_list_append(lst, "alpha")
|
|
let lst = el_list_append(lst, "beta")
|
|
let lst = el_list_append(lst, "gamma")
|
|
assert_int_eq(el_list_len(lst), 3, "length 3 after 3 appends")
|
|
assert_eq(el_list_get(lst, 0), "alpha", "first element: alpha")
|
|
assert_eq(el_list_get(lst, 1), "beta", "second element: beta")
|
|
assert_eq(el_list_get(lst, 2), "gamma", "third element: gamma")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_append_order(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst = el_list_append(lst, "1")
|
|
let lst = el_list_append(lst, "2")
|
|
let lst = el_list_append(lst, "3")
|
|
let lst = el_list_append(lst, "4")
|
|
let lst = el_list_append(lst, "5")
|
|
assert_int_eq(el_list_len(lst), 5, "five elements appended")
|
|
assert_eq(el_list_get(lst, 0), "1", "order preserved: index 0")
|
|
assert_eq(el_list_get(lst, 2), "3", "order preserved: index 2")
|
|
assert_eq(el_list_get(lst, 4), "5", "order preserved: index 4")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_append_empty_string(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst = el_list_append(lst, "")
|
|
assert_int_eq(el_list_len(lst), 1, "empty string element counted")
|
|
assert_eq(el_list_get(lst, 0), "", "empty string retrievable")
|
|
return ""
|
|
}
|
|
|
|
// ── el_list_len ───────────────────────────────────────────────────────────────
|
|
|
|
fn test_list_len_basic(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
assert_int_eq(el_list_len(lst), 0, "initial length 0")
|
|
let lst = el_list_append(lst, "a")
|
|
assert_int_eq(el_list_len(lst), 1, "length 1 after one append")
|
|
let lst = el_list_append(lst, "b")
|
|
assert_int_eq(el_list_len(lst), 2, "length 2 after two appends")
|
|
let lst = el_list_append(lst, "c")
|
|
assert_int_eq(el_list_len(lst), 3, "length 3 after three appends")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_len_large(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let i: Int = 0
|
|
while i < 20 {
|
|
let lst = el_list_append(lst, int_to_str(i))
|
|
let i = i + 1
|
|
}
|
|
assert_int_eq(el_list_len(lst), 20, "length 20 after 20 appends")
|
|
assert_eq(el_list_get(lst, 0), "0", "first element is 0")
|
|
assert_eq(el_list_get(lst, 19), "19", "last element is 19")
|
|
return ""
|
|
}
|
|
|
|
// ── el_list_get ───────────────────────────────────────────────────────────────
|
|
|
|
fn test_list_get_basic(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst = el_list_append(lst, "first")
|
|
let lst = el_list_append(lst, "second")
|
|
let lst = el_list_append(lst, "third")
|
|
assert_eq(el_list_get(lst, 0), "first", "get index 0")
|
|
assert_eq(el_list_get(lst, 1), "second", "get index 1")
|
|
assert_eq(el_list_get(lst, 2), "third", "get index 2")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_get_preserves_content(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst = el_list_append(lst, "hello world")
|
|
let lst = el_list_append(lst, "{\"json\":\"value\"}")
|
|
let lst = el_list_append(lst, "line1\nline2")
|
|
assert_eq(el_list_get(lst, 0), "hello world", "spaces in element preserved")
|
|
assert_eq(el_list_get(lst, 1), "{\"json\":\"value\"}", "JSON string preserved")
|
|
assert_eq(el_list_get(lst, 2), "line1\nline2", "newline in element preserved")
|
|
return ""
|
|
}
|
|
|
|
// ── list with str_join / str_split roundtrip ─────────────────────────────────
|
|
|
|
fn test_list_split_join_roundtrip(_: String) -> String {
|
|
let original: String = "apple,banana,cherry"
|
|
let parts: [String] = str_split(original, ",")
|
|
assert_int_eq(el_list_len(parts), 3, "split yields 3 parts")
|
|
let rejoined: String = str_join(parts, ",")
|
|
assert_eq(rejoined, original, "split then join is identity")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_build_and_join(_: String) -> String {
|
|
let parts: [String] = el_list_empty()
|
|
let parts = el_list_append(parts, "one")
|
|
let parts = el_list_append(parts, "two")
|
|
let parts = el_list_append(parts, "three")
|
|
let joined: String = str_join(parts, " + ")
|
|
assert_eq(joined, "one + two + three", "join with multi-char separator")
|
|
assert_int_eq(el_list_len(parts), 3, "original list unchanged")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_from_split_access(_: String) -> String {
|
|
let parts: [String] = str_split("a:b:c:d:e", ":")
|
|
assert_int_eq(el_list_len(parts), 5, "split into 5 parts")
|
|
assert_eq(el_list_get(parts, 0), "a", "first part")
|
|
assert_eq(el_list_get(parts, 2), "c", "middle part")
|
|
assert_eq(el_list_get(parts, 4), "e", "last part")
|
|
return ""
|
|
}
|
|
|
|
// ── native_list_empty / native_list_append (aliases from join.el style) ───────
|
|
|
|
fn test_native_list_empty_basic(_: String) -> String {
|
|
let lst: [String] = native_list_empty()
|
|
assert_int_eq(el_list_len(lst), 0, "native_list_empty yields empty list")
|
|
return ""
|
|
}
|
|
|
|
fn test_native_list_append_basic(_: String) -> String {
|
|
let lst: [String] = native_list_empty()
|
|
let lst = native_list_append(lst, "hello")
|
|
let lst = native_list_append(lst, "world")
|
|
assert_int_eq(el_list_len(lst), 2, "native_list_append: length 2")
|
|
assert_eq(el_list_get(lst, 0), "hello", "native_list_append: first element")
|
|
assert_eq(el_list_get(lst, 1), "world", "native_list_append: second element")
|
|
return ""
|
|
}
|
|
|
|
fn test_native_list_join(_: String) -> String {
|
|
let parts: [String] = native_list_empty()
|
|
let parts = native_list_append(parts, "alpha")
|
|
let parts = native_list_append(parts, "beta")
|
|
let parts = native_list_append(parts, "gamma")
|
|
let result: String = str_join(parts, ", ")
|
|
assert_eq(result, "alpha, beta, gamma", "native list joined correctly")
|
|
return ""
|
|
}
|
|
|
|
// ── env.el list helpers (get / len) ──────────────────────────────────────────
|
|
|
|
fn test_env_list_helpers(_: String) -> String {
|
|
let lst: [String] = el_list_empty()
|
|
let lst = el_list_append(lst, "x")
|
|
let lst = el_list_append(lst, "y")
|
|
let lst = el_list_append(lst, "z")
|
|
assert_int_eq(len(lst), 3, "len() alias for el_list_len")
|
|
assert_eq(get(lst, 0), "x", "get() alias for el_list_get index 0")
|
|
assert_eq(get(lst, 2), "z", "get() alias for el_list_get index 2")
|
|
return ""
|
|
}
|
|
|
|
// ── list as accumulator pattern ───────────────────────────────────────────────
|
|
|
|
fn test_list_accumulate_loop(_: String) -> String {
|
|
let results: [String] = el_list_empty()
|
|
let i: Int = 0
|
|
while i < 5 {
|
|
let results = el_list_append(results, int_to_str(i * i))
|
|
let i = i + 1
|
|
}
|
|
assert_int_eq(el_list_len(results), 5, "accumulated 5 squares")
|
|
assert_eq(el_list_get(results, 0), "0", "0^2 = 0")
|
|
assert_eq(el_list_get(results, 1), "1", "1^2 = 1")
|
|
assert_eq(el_list_get(results, 2), "4", "2^2 = 4")
|
|
assert_eq(el_list_get(results, 3), "9", "3^2 = 9")
|
|
assert_eq(el_list_get(results, 4), "16", "4^2 = 16")
|
|
return ""
|
|
}
|
|
|
|
fn test_list_string_building(_: String) -> String {
|
|
let words: [String] = el_list_empty()
|
|
let words = el_list_append(words, "the")
|
|
let words = el_list_append(words, "quick")
|
|
let words = el_list_append(words, "brown")
|
|
let words = el_list_append(words, "fox")
|
|
let sentence: String = str_join(words, " ")
|
|
assert_eq(sentence, "the quick brown fox", "words joined into sentence")
|
|
assert_int_eq(str_count_words(sentence), 4, "sentence has 4 words")
|
|
return ""
|
|
}
|