Files
rose-ash/lib/erlang/tests/lists_ext.sx
giles 3ae35a4b9b
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 58s
erlang: lists flatten/1 + max/1 + min/1 (833/833)
Structural/aggregate ops in lib/erlang/lists-ext.sx: flatten/1 deep
flatten, max/1 and min/1 by full Erlang term order (badarg on empty).
Extreme-finder uses er-ext-lt?'s SX boolean directly in if (er-truthy?
only recognises Erlang bool atoms). lists_ext suite 52 -> 62.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 13:41:15 +00:00

241 lines
10 KiB
Plaintext

;; lists-ext tests — lists:sort/1, lists:sort/2, lists:usort/1.
;; Each case evaluates an Erlang expression that reduces to the bool
;; atom `true` (via =:= on the sorted result) and checks its name.
(define er-lx-test-count 0)
(define er-lx-test-pass 0)
(define er-lx-test-fails (list))
(define
er-lx-test
(fn
(name actual expected)
(set! er-lx-test-count (+ er-lx-test-count 1))
(if
(= actual expected)
(set! er-lx-test-pass (+ er-lx-test-pass 1))
(append! er-lx-test-fails {:name name :expected expected :actual actual}))))
;; eval an Erlang source string and return the result atom's name
(define er-lx-nm (fn (src) (get (erlang-eval-ast src) :name)))
;; ── lists:sort/1 ──────────────────────────────────────────────────
(er-lx-test "sort/1 ascending"
(er-lx-nm "lists:sort([3,1,2]) =:= [1,2,3]") "true")
(er-lx-test "sort/1 already sorted"
(er-lx-nm "lists:sort([1,2,3]) =:= [1,2,3]") "true")
(er-lx-test "sort/1 empty"
(er-lx-nm "lists:sort([]) =:= []") "true")
(er-lx-test "sort/1 singleton"
(er-lx-nm "lists:sort([7]) =:= [7]") "true")
(er-lx-test "sort/1 keeps duplicates"
(er-lx-nm "lists:sort([3,1,2,1]) =:= [1,1,2,3]") "true")
(er-lx-test "sort/1 length preserved"
(erlang-eval-ast "length(lists:sort([5,4,3,2,1]))") 5)
(er-lx-test "sort/1 term order: number < atom"
(er-lx-nm "lists:sort([b,a,1]) =:= [1,a,b]") "true")
(er-lx-test "sort/1 tuples elementwise"
(er-lx-nm "lists:sort([{2,a},{1,b},{1,a}]) =:= [{1,a},{1,b},{2,a}]") "true")
;; ── lists:sort/2 ──────────────────────────────────────────────────
(er-lx-test "sort/2 ascending =<"
(er-lx-nm "lists:sort(fun(A,B) -> A =< B end, [3,1,2]) =:= [1,2,3]") "true")
(er-lx-test "sort/2 descending >="
(er-lx-nm "lists:sort(fun(A,B) -> A >= B end, [1,3,2]) =:= [3,2,1]") "true")
(er-lx-test "sort/2 stable on equal keys"
(er-lx-nm
"lists:sort(fun({A,_},{B,_}) -> A =< B end, [{1,x},{1,y},{0,z}]) =:= [{0,z},{1,x},{1,y}]")
"true")
(er-lx-test "sort/2 empty"
(er-lx-nm "lists:sort(fun(A,B) -> A =< B end, []) =:= []") "true")
;; ── lists:usort/1 ─────────────────────────────────────────────────
(er-lx-test "usort/1 removes duplicates"
(er-lx-nm "lists:usort([3,1,2,1,3]) =:= [1,2,3]") "true")
(er-lx-test "usort/1 empty"
(er-lx-nm "lists:usort([]) =:= []") "true")
(er-lx-test "usort/1 all equal collapses to one"
(er-lx-nm "lists:usort([5,5,5]) =:= [5]") "true")
(er-lx-test "usort/1 already unique"
(er-lx-nm "lists:usort([1,2,3]) =:= [1,2,3]") "true")
(er-lx-test "usort/1 length after dedup"
(erlang-eval-ast "length(lists:usort([4,4,2,2,1,1,4]))") 3)
;; ── lists:keyfind/3 ───────────────────────────────────────────────
(er-lx-test "keyfind hit"
(erlang-eval-ast "element(2, lists:keyfind(b, 1, [{a,1},{b,2},{c,3}]))") 2)
(er-lx-test "keyfind first match only"
(erlang-eval-ast "element(2, lists:keyfind(a, 1, [{a,1},{a,9}]))") 1)
(er-lx-test "keyfind miss returns false"
(er-lx-nm "lists:keyfind(z, 1, [{a,1},{b,2}])") "false")
(er-lx-test "keyfind on second element"
(er-lx-nm "element(1, lists:keyfind(2, 2, [{a,1},{b,2}]))") "b")
(er-lx-test "keyfind skips short tuples"
(er-lx-nm "lists:keyfind(x, 2, [{x},{y,x}]) =:= {y,x}") "true")
;; ── lists:keymember/3 ─────────────────────────────────────────────
(er-lx-test "keymember true"
(er-lx-nm "lists:keymember(b, 1, [{a,1},{b,2}])") "true")
(er-lx-test "keymember false"
(er-lx-nm "lists:keymember(z, 1, [{a,1},{b,2}])") "false")
;; ── lists:keydelete/3 ─────────────────────────────────────────────
(er-lx-test "keydelete removes first match"
(er-lx-nm "lists:keydelete(b, 1, [{a,1},{b,2},{c,3}]) =:= [{a,1},{c,3}]") "true")
(er-lx-test "keydelete only first"
(er-lx-nm "lists:keydelete(a, 1, [{a,1},{a,2},{b,3}]) =:= [{a,2},{b,3}]") "true")
(er-lx-test "keydelete miss unchanged"
(er-lx-nm "lists:keydelete(z, 1, [{a,1},{b,2}]) =:= [{a,1},{b,2}]") "true")
;; ── lists:keyreplace/4 ────────────────────────────────────────────
(er-lx-test "keyreplace hit"
(er-lx-nm
"lists:keyreplace(b, 1, [{a,1},{b,2},{c,3}], {b,99}) =:= [{a,1},{b,99},{c,3}]")
"true")
(er-lx-test "keyreplace miss unchanged"
(er-lx-nm
"lists:keyreplace(z, 1, [{a,1}], {z,0}) =:= [{a,1}]") "true")
;; ── lists:keystore/4 ──────────────────────────────────────────────
(er-lx-test "keystore replaces existing"
(er-lx-nm
"lists:keystore(b, 1, [{a,1},{b,2}], {b,99}) =:= [{a,1},{b,99}]") "true")
(er-lx-test "keystore appends when absent"
(er-lx-nm
"lists:keystore(z, 1, [{a,1},{b,2}], {z,0}) =:= [{a,1},{b,2},{z,0}]") "true")
;; ── lists:keytake/3 ───────────────────────────────────────────────
(er-lx-test "keytake hit value tag"
(er-lx-nm "element(1, lists:keytake(b, 1, [{a,1},{b,2},{c,3}]))") "value")
(er-lx-test "keytake hit tuple"
(er-lx-nm
"element(2, lists:keytake(b, 1, [{a,1},{b,2},{c,3}])) =:= {b,2}") "true")
(er-lx-test "keytake hit rest"
(er-lx-nm
"element(3, lists:keytake(b, 1, [{a,1},{b,2},{c,3}])) =:= [{a,1},{c,3}]") "true")
(er-lx-test "keytake miss false"
(er-lx-nm "lists:keytake(z, 1, [{a,1}])") "false")
;; ── lists:keysort/2 ───────────────────────────────────────────────
(er-lx-test "keysort by element 1"
(er-lx-nm
"lists:keysort(1, [{c,3},{a,1},{b,2}]) =:= [{a,1},{b,2},{c,3}]") "true")
(er-lx-test "keysort by element 2"
(er-lx-nm
"lists:keysort(2, [{a,3},{b,1},{c,2}]) =:= [{b,1},{c,2},{a,3}]") "true")
(er-lx-test "keysort stable on equal keys"
(er-lx-nm
"lists:keysort(1, [{a,1},{a,2},{a,3}]) =:= [{a,1},{a,2},{a,3}]") "true")
;; ── lists:foldr/3 ─────────────────────────────────────────────────
(er-lx-test "foldr preserves order"
(er-lx-nm
"lists:foldr(fun(X,Acc) -> [X|Acc] end, [], [1,2,3]) =:= [1,2,3]") "true")
(er-lx-test "foldr sum"
(erlang-eval-ast "lists:foldr(fun(X,A) -> X+A end, 0, [1,2,3,4])") 10)
(er-lx-test "foldr empty returns acc"
(erlang-eval-ast "lists:foldr(fun(X,A) -> X+A end, 42, [])") 42)
;; ── lists:partition/2 ─────────────────────────────────────────────
(er-lx-test "partition evens/odds"
(er-lx-nm
"lists:partition(fun(X) -> X rem 2 =:= 0 end, [1,2,3,4,5]) =:= {[2,4],[1,3,5]}")
"true")
(er-lx-test "partition all satisfy"
(er-lx-nm "lists:partition(fun(_) -> true end, [1,2]) =:= {[1,2],[]}") "true")
(er-lx-test "partition empty"
(er-lx-nm "lists:partition(fun(_) -> true end, []) =:= {[],[]}") "true")
;; ── lists:takewhile/2 ─────────────────────────────────────────────
(er-lx-test "takewhile prefix"
(er-lx-nm "lists:takewhile(fun(X) -> X < 3 end, [1,2,3,4,1]) =:= [1,2]") "true")
(er-lx-test "takewhile none"
(er-lx-nm "lists:takewhile(fun(X) -> X < 0 end, [1,2]) =:= []") "true")
(er-lx-test "takewhile all"
(er-lx-nm "lists:takewhile(fun(X) -> X < 9 end, [1,2,3]) =:= [1,2,3]") "true")
;; ── lists:dropwhile/2 ─────────────────────────────────────────────
(er-lx-test "dropwhile prefix"
(er-lx-nm "lists:dropwhile(fun(X) -> X < 3 end, [1,2,3,4,1]) =:= [3,4,1]") "true")
(er-lx-test "dropwhile all"
(er-lx-nm "lists:dropwhile(fun(X) -> X < 9 end, [1,2,3]) =:= []") "true")
(er-lx-test "dropwhile none"
(er-lx-nm "lists:dropwhile(fun(X) -> X < 0 end, [1,2]) =:= [1,2]") "true")
;; ── lists:splitwith/2 ─────────────────────────────────────────────
(er-lx-test "splitwith"
(er-lx-nm
"lists:splitwith(fun(X) -> X < 3 end, [1,2,3,4,1]) =:= {[1,2],[3,4,1]}") "true")
(er-lx-test "splitwith empty"
(er-lx-nm "lists:splitwith(fun(_) -> true end, []) =:= {[],[]}") "true")
;; ── lists:flatten/1 ───────────────────────────────────────────────
(er-lx-test "flatten nested"
(er-lx-nm "lists:flatten([1,[2,[3,4]],5]) =:= [1,2,3,4,5]") "true")
(er-lx-test "flatten already flat"
(er-lx-nm "lists:flatten([1,2,3]) =:= [1,2,3]") "true")
(er-lx-test "flatten empty"
(er-lx-nm "lists:flatten([]) =:= []") "true")
(er-lx-test "flatten deep empties"
(er-lx-nm "lists:flatten([[],[1],[[]]]) =:= [1]") "true")
(er-lx-test "flatten length"
(erlang-eval-ast "length(lists:flatten([[1,2],[3],[4,5,6]]))") 6)
;; ── lists:max/1 ───────────────────────────────────────────────────
(er-lx-test "max ints"
(erlang-eval-ast "lists:max([3,1,4,1,5,9,2,6])") 9)
(er-lx-test "max single"
(erlang-eval-ast "lists:max([7])") 7)
(er-lx-test "max atoms term order"
(er-lx-nm "lists:max([a,c,b]) =:= c") "true")
;; ── lists:min/1 ───────────────────────────────────────────────────
(er-lx-test "min ints"
(erlang-eval-ast "lists:min([3,1,4,1,5])") 1)
(er-lx-test "min mixed term order"
(er-lx-nm "lists:min([a,1,b]) =:= 1") "true")