// 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 "" }