;; ========================================================================== ;; test-primitives.sx — Exhaustive tests for all pure primitives ;; ========================================================================== ;; -------------------------------------------------------------------------- ;; Arithmetic ;; -------------------------------------------------------------------------- (defsuite "arithmetic" (deftest "add" (assert-equal 3 (+ 1 2))) (deftest "add multiple" (assert-equal 10 (+ 1 2 3 4))) (deftest "add zero" (assert-equal 5 (+ 5 0))) (deftest "add negative" (assert-equal -1 (+ 1 -2))) (deftest "subtract" (assert-equal 3 (- 5 2))) (deftest "subtract negative" (assert-equal 7 (- 5 -2))) (deftest "multiply" (assert-equal 12 (* 3 4))) (deftest "multiply zero" (assert-equal 0 (* 5 0))) (deftest "multiply negative" (assert-equal -6 (* 2 -3))) (deftest "divide" (assert-equal 3 (/ 9 3))) (deftest "divide float" (assert-equal 2.5 (/ 5 2))) (deftest "mod" (assert-equal 1 (mod 7 3))) (deftest "mod negative" (assert-true (or (= (mod -1 3) 2) (= (mod -1 3) -1)))) (deftest "inc" (assert-equal 6 (inc 5))) (deftest "dec" (assert-equal 4 (dec 5))) (deftest "abs positive" (assert-equal 5 (abs 5))) (deftest "abs negative" (assert-equal 5 (abs -5))) (deftest "abs zero" (assert-equal 0 (abs 0))) (deftest "min" (assert-equal 2 (min 2 5))) (deftest "max" (assert-equal 5 (max 2 5)))) ;; -------------------------------------------------------------------------- ;; Comparison ;; -------------------------------------------------------------------------- (defsuite "comparison" (deftest "equal numbers" (assert-true (= 1 1))) (deftest "not equal numbers" (assert-false (= 1 2))) (deftest "equal strings" (assert-true (= "a" "a"))) (deftest "less than" (assert-true (< 1 2))) (deftest "not less than" (assert-false (< 2 1))) (deftest "greater than" (assert-true (> 2 1))) (deftest "not greater than" (assert-false (> 1 2))) (deftest "less equal" (assert-true (<= 1 1))) (deftest "less equal less" (assert-true (<= 1 2))) (deftest "greater equal" (assert-true (>= 2 2))) (deftest "greater equal greater" (assert-true (>= 3 2))) (deftest "not" (assert-true (not false))) (deftest "not true" (assert-false (not true))) (deftest "not nil" (assert-true (not nil)))) ;; -------------------------------------------------------------------------- ;; Predicates ;; -------------------------------------------------------------------------- (defsuite "predicates" (deftest "nil? nil" (assert-true (nil? nil))) (deftest "nil? number" (assert-false (nil? 0))) (deftest "nil? string" (assert-false (nil? ""))) (deftest "number? num" (assert-true (number? 42))) (deftest "number? string" (assert-false (number? "42"))) (deftest "number? bool" (assert-false (number? true))) (deftest "string? str" (assert-true (string? "hi"))) (deftest "string? num" (assert-false (string? 42))) (deftest "list? list" (assert-true (list? (list 1 2)))) (deftest "list? empty" (assert-true (list? (list)))) (deftest "list? string" (assert-false (list? "hi"))) (deftest "dict? dict" (assert-true (dict? (dict "a" 1)))) (deftest "dict? list" (assert-false (dict? (list 1)))) (deftest "empty? empty list" (assert-true (empty? (list)))) (deftest "empty? nonempty" (assert-false (empty? (list 1)))) (deftest "empty? empty string" (assert-true (empty? ""))) (deftest "empty? nonempty string" (assert-false (empty? "a"))) (deftest "empty? nil" (assert-true (empty? nil)))) ;; -------------------------------------------------------------------------- ;; String operations ;; -------------------------------------------------------------------------- (defsuite "strings" (deftest "str concat" (assert-equal "hello world" (str "hello" " " "world"))) (deftest "str number" (assert-equal "42" (str 42))) (deftest "str empty" (assert-equal "" (str))) (deftest "len string" (assert-equal 5 (len "hello"))) (deftest "len empty" (assert-equal 0 (len ""))) (deftest "slice" (assert-equal "ell" (slice "hello" 1 4))) (deftest "slice from" (assert-equal "llo" (slice "hello" 2))) (deftest "slice empty" (assert-equal "" (slice "hello" 2 2))) (deftest "join" (assert-equal "a,b,c" (join "," (list "a" "b" "c")))) (deftest "join empty" (assert-equal "" (join "," (list)))) (deftest "join single" (assert-equal "a" (join "," (list "a")))) (deftest "split" (assert-equal (list "a" "b" "c") (split "a,b,c" ","))) (deftest "upper" (assert-equal "HELLO" (upper "hello"))) (deftest "lower" (assert-equal "hello" (lower "HELLO"))) (deftest "trim" (assert-equal "hi" (trim " hi "))) (deftest "contains?" (assert-true (contains? "hello world" "world"))) (deftest "contains? false" (assert-false (contains? "hello" "xyz"))) (deftest "starts-with?" (assert-true (starts-with? "hello" "hel"))) (deftest "starts-with? false" (assert-false (starts-with? "hello" "xyz"))) (deftest "ends-with?" (assert-true (ends-with? "hello" "llo"))) (deftest "ends-with? false" (assert-false (ends-with? "hello" "xyz"))) (deftest "replace" (assert-equal "hXllo" (replace "hello" "e" "X"))) (deftest "string-length" (assert-equal 5 (string-length "hello"))) (deftest "index-of found" (assert-equal 2 (index-of "hello" "l"))) (deftest "index-of not found" (assert-equal -1 (index-of "hello" "z")))) ;; -------------------------------------------------------------------------- ;; List operations ;; -------------------------------------------------------------------------- (defsuite "lists" (deftest "list create" (assert-equal (list 1 2 3) (list 1 2 3))) (deftest "first" (assert-equal 1 (first (list 1 2 3)))) (deftest "first empty" (assert-nil (first (list)))) (deftest "rest" (assert-equal (list 2 3) (rest (list 1 2 3)))) (deftest "rest single" (assert-equal (list) (rest (list 1)))) (deftest "rest empty" (assert-equal (list) (rest (list)))) (deftest "nth" (assert-equal 2 (nth (list 1 2 3) 1))) (deftest "nth out of bounds" (assert-nil (nth (list 1 2) 5))) (deftest "last" (assert-equal 3 (last (list 1 2 3)))) (deftest "last single" (assert-equal 1 (last (list 1)))) (deftest "len list" (assert-equal 3 (len (list 1 2 3)))) (deftest "len empty" (assert-equal 0 (len (list)))) (deftest "cons" (assert-equal (list 0 1 2) (cons 0 (list 1 2)))) (deftest "append" (assert-equal (list 1 2 3 4) (append (list 1 2) (list 3 4)))) (deftest "append element" (assert-equal (list 1 2 3) (append (list 1 2) (list 3)))) (deftest "slice list" (assert-equal (list 2 3) (slice (list 1 2 3 4) 1 3))) (deftest "concat" (assert-equal (list 1 2 3 4) (concat (list 1 2) (list 3 4)))) (deftest "reverse" (assert-equal (list 3 2 1) (reverse (list 1 2 3)))) (deftest "reverse empty" (assert-equal (list) (reverse (list)))) (deftest "contains? list" (assert-true (contains? (list 1 2 3) 2))) (deftest "contains? list false" (assert-false (contains? (list 1 2 3) 5))) (deftest "range" (assert-equal (list 0 1 2) (range 0 3))) (deftest "range step" (assert-equal (list 0 2 4) (range 0 6 2))) (deftest "flatten" (assert-equal (list 1 2 3 4) (flatten (list (list 1 2) (list 3 4)))))) ;; -------------------------------------------------------------------------- ;; Dict operations ;; -------------------------------------------------------------------------- (defsuite "dicts" (deftest "dict create" (assert-equal 1 (get (dict "a" 1 "b" 2) "a"))) (deftest "get missing" (assert-nil (get (dict "a" 1) "z"))) (deftest "get default" (assert-equal 99 (get (dict "a" 1) "z" 99))) (deftest "keys" (assert-true (contains? (keys (dict "a" 1 "b" 2)) "a"))) (deftest "has-key?" (assert-true (has-key? (dict "a" 1) "a"))) (deftest "has-key? false" (assert-false (has-key? (dict "a" 1) "z"))) (deftest "assoc" (assert-equal 2 (get (assoc (dict "a" 1) "b" 2) "b"))) (deftest "dissoc" (assert-false (has-key? (dissoc (dict "a" 1 "b" 2) "a") "a"))) (deftest "len dict" (assert-equal 2 (len (dict "a" 1 "b" 2)))) (deftest "len empty dict" (assert-equal 0 (len (dict)))) (deftest "empty? dict" (assert-true (empty? (dict)))) (deftest "empty? nonempty dict" (assert-false (empty? (dict "a" 1))))) ;; -------------------------------------------------------------------------- ;; Higher-order functions ;; -------------------------------------------------------------------------- (defsuite "higher-order" (deftest "map" (assert-equal (list 2 4 6) (map (fn (x) (* x 2)) (list 1 2 3)))) (deftest "map empty" (assert-equal (list) (map (fn (x) x) (list)))) (deftest "filter" (assert-equal (list 2 4) (filter (fn (x) (= (mod x 2) 0)) (list 1 2 3 4 5)))) (deftest "filter none" (assert-equal (list) (filter (fn (x) false) (list 1 2 3)))) (deftest "reduce" (assert-equal 10 (reduce (fn (acc x) (+ acc x)) 0 (list 1 2 3 4)))) (deftest "reduce empty" (assert-equal 0 (reduce (fn (acc x) (+ acc x)) 0 (list)))) (deftest "some true" (assert-true (some (fn (x) (> x 3)) (list 1 2 3 4 5)))) (deftest "some false" (assert-false (some (fn (x) (> x 10)) (list 1 2 3)))) (deftest "some empty" (assert-false (some (fn (x) true) (list)))) (deftest "every? true" (assert-true (every? (fn (x) (> x 0)) (list 1 2 3)))) (deftest "every? false" (assert-false (every? (fn (x) (> x 2)) (list 1 2 3)))) (deftest "every? empty" (assert-true (every? (fn (x) false) (list)))) (deftest "for-each returns nil" (let ((log (list))) (for-each (fn (x) (append! log x)) (list 1 2 3)) (assert-equal (list 1 2 3) log))) (deftest "map-indexed" (assert-equal (list (list 0 "a") (list 1 "b")) (map-indexed (fn (i x) (list i x)) (list "a" "b"))))) ;; -------------------------------------------------------------------------- ;; Type coercion ;; -------------------------------------------------------------------------- (defsuite "type-coercion" (deftest "str bool" (assert-true (or (= (str true) "true") (= (str true) "True")))) (deftest "str nil" (assert-equal "" (str nil))) (deftest "str list" (assert-true (not (empty? (str (list 1 2 3)))))) (deftest "parse-int" (assert-equal 42 (parse-int "42"))) (deftest "parse-float skipped" (assert-true true)))