release 0.1.0

This commit is contained in:
rus07tam 2026-05-06 12:21:06 +03:00
commit 30d94536a9
90 changed files with 7722 additions and 0 deletions

View file

@ -0,0 +1,38 @@
(namespace tests.bool
(test.case "bool.bool?"
(assert.ok! (bool? true))
(assert.ok! (bool? false))
(assert.not! (bool? 1))
)
(test.case "bool.not"
(assert.eq! (bool.not true) false)
(assert.eq! (bool.not false) true)
)
(test.case "bool.and"
(assert.ok! (bool.and true true))
(assert.not! (bool.and true false))
(assert.not! (bool.and false true))
(assert.not! (bool.and false false))
)
(test.case "bool.or"
(assert.ok! (bool.or true true))
(assert.ok! (bool.or true false))
(assert.ok! (bool.or false true))
(assert.not! (bool.or false false))
)
(test.case "bool.nand"
(assert.not! (bool.nand true true))
(assert.ok! (bool.nand true false))
(assert.ok! (bool.nand false true))
(assert.ok! (bool.nand false false))
)
(test.case "bool.new"
(assert.eq! (bool.new true) true)
(assert.eq! (bool.new false) false)
)
)

View file

@ -0,0 +1,41 @@
(namespace tests.cmp
(test.case "cmp.eq?"
(assert.ok! (eq? 1 1))
(assert.not! (eq? 1 2))
)
(test.case "cmp.nq?"
(assert.ok! (nq? 1 2))
(assert.not! (nq? 1 1))
)
(test.case "cmp.cmp"
(assert.eq! (cmp 1 2) :less)
(assert.eq! (cmp 2 1) :greater)
(assert.eq! (cmp 1 1) :equal)
)
(test.case "cmp.lt?"
(assert.ok! (lt? 1 2))
(assert.not! (lt? 2 1))
(assert.not! (lt? 1 1))
)
(test.case "cmp.lte?"
(assert.ok! (lte? 1 2))
(assert.ok! (lte? 1 1))
(assert.not! (lte? 2 1))
)
(test.case "cmp.gt?"
(assert.ok! (gt? 2 1))
(assert.not! (gt? 1 2))
(assert.not! (gt? 1 1))
)
(test.case "cmp.gte?"
(assert.ok! (gte? 2 1))
(assert.ok! (gte? 1 1))
(assert.not! (gte? 1 2))
)
)

View file

@ -0,0 +1,42 @@
(namespace tests.loop
(test.case "while.basic-true"
(def counter 0)
(while (eq? counter 0)
(set! counter 1))
(assert.eq! counter 1)
)
(test.case "while.condition-false"
(def counter 5)
(while (lt? counter 0)
(set! counter (+ counter 1)))
(assert.eq! counter 5)
)
(test.case "while.counting-loop"
(def n 0)
(while (lt? n 10)
(set! n (+ n 1)))
(assert.eq! n 10)
)
(test.case "while.loop-condition-reached"
(def i 0)
(while (lt? i 5)
(set! i (+ i 1)))
(assert.eq! i 5)
)
(test.case "while.nested"
(def outer 0)
(def inner 0)
(def total 0)
(while (lt? outer 3)
(set! inner 0)
(while (lt? inner 2)
(set! total (+ total 1))
(set! inner (+ inner 1)))
(set! outer (+ outer 1)))
(assert.eq! total 6)
)
)

View file

@ -0,0 +1,14 @@
(seq
(include "vec")
(include "str")
(include "set")
(include "map")
(include "bool")
(include "option")
(include "scope")
(include "null")
(include "cmp")
(include "math")
(include "types")
(include "loop")
)

View file

@ -0,0 +1,83 @@
(namespace tests.map
(test.case "map.len"
(assert.eq! (map.len (map.new)) 0)
)
(test.case "map.empty?"
(assert.ok! (map.empty? (map.new)))
)
(test.case "map.is-empty?"
(assert.ok! (map.is-empty? (map.new)))
)
(test.case "map.get"
(seq
(def m (map.new :a 1 :b 2))
(assert.eq! (map.get m :a) 1)
(assert.eq! (map.get m :b) 2)
(assert.eq! (map.get m :c) null)
)
)
(test.case "map.put"
(seq
(def m (map.new :a 1))
(def m2 (map.put m :b 2))
(assert.eq! (map.len m2) 2)
(assert.eq! (map.get m2 :b) 2)
)
)
(test.case "map.has-key?"
(seq
(def m (map.new :a 1 :b 2))
(assert.ok! (map.has-key? m :a))
(assert.not! (map.has-key? m :c))
)
)
(test.case "map.has-value?"
(seq
(def m (map.new :a 1 :b 2))
(assert.ok! (map.has-value? m 1))
(assert.not! (map.has-value? m 5))
)
)
(test.case "map.keys"
(seq
(def m (map.new :a 1 :b 2))
(def ks (map.keys m))
(assert.eq! (vec.len ks) 2)
)
)
(test.case "map.values"
(seq
(def m (map.new :a 1 :b 2))
(def vs (map.values m))
(assert.eq! (vec.len vs) 2)
)
)
(test.case "map.merge"
(seq
(def m1 (map.new :a 1 :b 2))
(def m2 (map.new :b 20 :c 3))
(def m3 (map.merge m1 m2))
(assert.eq! (map.get m3 :a) 1)
(assert.eq! (map.get m3 :b) 20)
(assert.eq! (map.get m3 :c) 3)
)
)
(test.case "map.dissoc"
(seq
(def m (map.new :a 1 :b 2 :c 3))
(def m2 (map.dissoc m :b))
(assert.eq! (map.len m2) 2)
(assert.not! (map.has-key? m2 :b))
)
)
)

View file

@ -0,0 +1,40 @@
(namespace tests.math
(test.case "math.add"
(assert.eq! (+ 1 2) 3)
(assert.eq! (+ 0 0) 0)
)
(test.case "math.sub"
(assert.eq! (- 5 3) 2)
(assert.eq! (- 1 1) 0)
)
(test.case "math.mul"
(assert.eq! (* 3 4) 12)
(assert.eq! (* 0 5) 0)
)
(test.case "math.div"
(assert.eq! (/ 10 2) 5)
)
(test.case "math.mod"
(assert.eq! (% 10 3) 1)
(assert.eq! (% 5 5) 0)
)
(test.case "math.pow"
(assert.eq! (** 2 3) 8)
(assert.eq! (** 5 2) 25)
)
(test.case "math.++"
(assert.eq! (++ 5) 6)
(assert.eq! (++ 0) 1)
)
(test.case "math.--"
(assert.eq! (-- 5) 4)
(assert.eq! (-- 0) -1)
)
)

View file

@ -0,0 +1,8 @@
(namespace tests.null
(test.case "null.null?"
(assert.ok! (null? null))
(assert.ok! (null? :nil))
(assert.not! (null? 0))
(assert.not! (null? false))
)
)

View file

@ -0,0 +1,33 @@
(namespace tests.option
(test.case "option.ok"
(seq
(def opt (option.ok 42))
(assert.ok! (option.ok? opt))
(assert.eq! (vec.get opt 1) 42)
)
)
(test.case "option.err"
(seq
(def opt (option.err "error"))
(assert.ok! (option.err? opt))
(assert.eq! (vec.get opt 1) "error")
)
)
(test.case "option.ok?"
(assert.ok! (option.ok? (option.ok 1)))
(assert.not! (option.ok? (option.err "x")))
)
(test.case "option.err?"
(assert.ok! (option.err? (option.err "x")))
(assert.not! (option.err? (option.ok 1)))
)
(test.case "option.option?"
(assert.ok! (option? (option.ok 1)))
(assert.ok! (option? (option.err "x")))
(assert.not! (option? [1 2]))
)
)

View file

@ -0,0 +1,78 @@
(namespace tests.scopes
(test.case "def"
(def x 1)
(assert.eq! x 1)
(def [y z] [1 2])
(assert.eq! y 1)
(assert.eq! z 2)
)
(test.case "def bounded"
(def x 1)
(try
(def x 2)
(catch :Panic (return))
)
(unreachable!)
)
(test.case "set!"
(def [x y] [1 1])
(set! x 2)
(assert.eq! x 2)
(set! [x y] [3 4])
(assert.eq! x 3)
(assert.eq! y 4)
)
(test.case "set! unbounded"
(try
(set! x 2)
(catch :UnboundVariable (return))
)
(unreachable!)
)
(test.case "lookup"
(def x 1)
(assert.eq! (lookup x null) 1)
(assert.eq! (lookup y null) null)
)
(test.case "inheritance"
(scope
(def x 1)
(scope
(assert.eq! x 1)
(set! x 2)
)
(assert.eq! x 2)
)
)
(test.case "shadowing"
(scope
(def x 100)
(scope
(def x 1)
)
(assert.eq! x 100)
)
(assert.eq! (lookup x null) null)
)
(test.case "leakage"
(scope (def x 1))
(assert.eq! (lookup x null) null)
(scope (def y 2))
(assert.eq! (lookup y null) null)
(scope
(scope (def z 1))
(assert.eq! (lookup z null) null)
)
)
)

View file

@ -0,0 +1,44 @@
(namespace tests.set
(test.case "set.empty?"
(assert.ok! (set.empty? (set.new)))
(assert.not! (set.empty? (set.new 1)))
)
(test.case "set.len"
(assert.eq! (set.len (set.new)) 0)
(assert.eq! (set.len (set.new 1)) 1)
(assert.eq! (set.len (set.new 1 2 3)) 3)
)
(test.case "set.has"
(assert.ok! (set.has (set.new 1 2 3) 2))
(assert.not! (set.has (set.new 1 2 3) 5))
)
(test.case "set.add"
(assert.ok! (set.has (set.add (set.new 1 2) 3) 3))
(assert.eq! (set.len (set.add (set.new 1 2) 3)) 3)
)
(test.case "set.remove"
(assert.not! (set.has (set.remove (set.new 1 2 3) 2) 2))
(assert.eq! (set.len (set.remove (set.new 1 2 3) 2)) 2)
)
(test.case "set.union"
(assert.eq! (set.len (set.union (set.new 1 2) (set.new 2 3))) 3)
(assert.ok! (set.has (set.union (set.new 1 2) (set.new 2 3)) 1))
(assert.ok! (set.has (set.union (set.new 1 2) (set.new 2 3)) 3))
)
(test.case "set.intersection"
(assert.eq! (set.len (set.intersection (set.new 1 2 3) (set.new 2 3 4))) 2)
(assert.ok! (set.has (set.intersection (set.new 1 2 3) (set.new 2 3 4)) 2))
(assert.ok! (set.has (set.intersection (set.new 1 2 3) (set.new 2 3 4)) 3))
)
(test.case "set.difference"
(assert.eq! (set.len (set.difference (set.new 1 2 3) (set.new 2 3))) 1)
(assert.ok! (set.has (set.difference (set.new 1 2 3) (set.new 2 3)) 1))
)
)

View file

@ -0,0 +1,67 @@
(namespace tests.str
(test.case "str.len"
(assert.eq! (str.len "") 0)
(assert.eq! (str.len "hello") 5)
)
(test.case "str.empty?"
(assert.ok! (str.empty? ""))
(assert.not! (str.empty? "a"))
)
(test.case "str.is-empty?"
(assert.ok! (str.is-empty? ""))
(assert.not! (str.is-empty? "a"))
)
(test.case "str.first"
(assert.eq! (str.first "hello") "h")
)
(test.case "str.last"
(assert.eq! (str.last "hello") "o")
)
(test.case "str.concat"
(assert.eq! (str.concat "hello" " " "world") "hello world")
)
(test.case "str.substring"
(assert.eq! (str.substring "hello" 0 3) "hel")
(assert.eq! (str.substring "hello" 1 4) "ell")
)
(test.case "str.take"
(assert.eq! (str.take "hello" 3) "hel")
)
(test.case "str.drop"
(assert.eq! (str.drop "hello" 2) "llo")
)
(test.case "str.reverse"
(assert.eq! (str.reverse "hello") "olleh")
)
(test.case "str.starts-with?"
(assert.ok! (str.starts-with? "hello" "hel"))
(assert.not! (str.starts-with? "hello" "xyz"))
)
(test.case "str.ends-with?"
(assert.ok! (str.ends-with? "hello" "lo"))
(assert.not! (str.ends-with? "hello" "xyz"))
)
(test.case "str.split"
(assert.eq! (str.split "hello world" " ") ["hello" "world"])
(assert.eq! (str.split "hello world" "w") ["hello " "orld"])
(assert.eq! (str.split "hello world" "x") ["hello world"])
)
(test.case "str.join"
(assert.eq! (str.join " " ["hello" "world"]) "hello world")
(assert.eq! (str.join "w" ["hello " "orld"]) "hello world")
(assert.eq! (str.join "x" ["hello world"]) "hello world")
)
)

View file

@ -0,0 +1,53 @@
(namespace tests.types
(test.case "types.is?"
(assert.ok! (is? 42 :int))
(assert.ok! (is? "hello" :str))
(assert.ok! (is? [] :vec))
(assert.not! (is? 42 :str))
)
(test.case "types.guard"
(seq
(def int-guard (guard :int))
(assert.ok! (int-guard 42))
(assert.not! (int-guard "42"))
)
)
(test.case "types.kw?"
(assert.ok! (kw? :keyword))
(assert.not! (kw? "not-keyword"))
)
(test.case "types.type?"
(assert.ok! (type? :int))
(assert.ok! (type? :str))
(assert.not! (type? :unknown))
)
(test.case "types.str?"
(assert.ok! (str? "hello"))
(assert.not! (str? 42))
)
(test.case "types.vec?"
(assert.ok! (vec? []))
(assert.ok! (vec? [1 2 3]))
(assert.not! (vec? 42))
)
(test.case "types.bool?"
(assert.ok! (bool? true))
(assert.ok! (bool? false))
(assert.not! (bool? 1))
)
(test.case "types.null?"
(assert.ok! (null? null))
(assert.not! (null? 0))
)
(test.case "types.map.is?"
(assert.ok! (map.is? (map.new)))
)
)

View file

@ -0,0 +1,91 @@
(namespace tests.vec
(test.case "vec.empty?"
(assert.ok! (vec.empty? []))
(assert.not! (vec.empty? [1]))
)
(test.case "vec.len"
(assert.eq! (vec.len []) 0)
(assert.eq! (vec.len [1]) 1)
(assert.eq! (vec.len [1 2 3]) 3)
)
(test.case "vec.first"
(assert.eq! (vec.first [1 2 3]) 1)
(assert.eq! (vec.first ["a"]) "a")
)
(test.case "vec.last"
(assert.eq! (vec.last [1 2 3]) 3)
(assert.eq! (vec.last ["x"]) "x")
)
(test.case "vec.get"
(assert.eq! (vec.get [10 20 30] 0) 10)
(assert.eq! (vec.get [10 20 30] 1) 20)
(assert.eq! (vec.get [10 20 30] 2) 30)
)
(test.case "vec.map"
(assert.eq!
(vec.map (lambda [x _] (+ x 1)) [1 2 3])
[2 3 4])
)
(test.case "vec.filter"
(assert.eq!
(vec.filter (lambda [x _] (gt? x 1)) [1 2 3])
[2 3])
)
(test.case "vec.has"
(assert.ok! (vec.has [1 2 3] 2))
(assert.not! (vec.has [1 2 3] 5))
)
(test.case "vec.includes?"
(assert.ok! (vec.includes? [1 2 3] 2))
(assert.not! (vec.includes? [1 2 3] 5))
)
(test.case "vec.find"
(assert.eq!
(vec.find (lambda [x _] (gt? x 2)) [1 2 3 4])
3)
)
(test.case "vec.reverse"
(assert.eq! (vec.reverse [1 2 3]) [3 2 1])
)
(test.case "vec.take"
(assert.eq! (vec.take [1 2 3 4 5] 3) [1 2 3])
)
(test.case "vec.drop"
(assert.eq! (vec.drop [1 2 3 4 5] 2) [3 4 5])
)
(test.case "vec.uniq"
(assert.eq! (vec.uniq [1 2 2 3 3 3]) [1 2 3])
)
(test.case "vec.every?"
(assert.ok! (vec.every? (lambda [x _] (gt? x 0)) [1 2 3]))
(assert.not! (vec.every? (lambda [x _] (gt? x 1)) [1 2 3]))
)
(test.case "vec.some?"
(assert.ok! (vec.some? (lambda [x _] (gt? x 2)) [1 2 3]))
(assert.not! (vec.some? (lambda [x _] (gt? x 5)) [1 2 3]))
)
(test.case "vec.count"
(assert.eq! (vec.count (lambda [x _] (gt? x 1)) [1 2 3]) 2)
)
(test.case "vec.sum"
(assert.eq! (vec.sum [1 2 3]) 6)
(assert.eq! (vec.sum []) 0)
)
)