(;module: lux lux/test (lux (control monad) [io] [math] ["R" random] (data [text "T/" Eq] text/format) [compiler] (macro ["s" syntax #+ syntax:]))) (test: "Value identity." [size (|> R;nat (:: @ map (|>. (n.% +100) (n.max +10)))) x (R;text size) y (R;text size)] ($_ seq (assert "Every value is identical to itself, and the 'id' function doesn't change values in any way." (and (is x x) (is x (id x)))) (assert "Values created separately can't be identical." (not (is x y))) )) (do-template [category rand-gen inc dec even? odd? = < >] [(test: (format "[" category "] " "Moving up-down or down-up should result in same value.") [value rand-gen] (assert "" (and (|> value inc dec (= value)) (|> value dec inc (= value))))) (test: (format "[" category "] " "(x+1) > x && (x-1) < x") [value rand-gen] (assert "" (and (|> value inc (> value)) (|> value dec (< value))))) (test: (format "[" category "] " "Every odd/even number is surrounded by two of the other kind.") [value rand-gen] (assert "" (if (even? value) (and (|> value inc odd?) (|> value dec odd?)) (and (|> value inc even?) (|> value dec even?)))))] ["Nat" R;nat n.inc n.dec n.even? n.odd? n.= n.< n.>] ["Int" R;int i.inc i.dec i.even? i.odd? i.= i.< i.>] ) (do-template [category rand-gen = < > <= >= min max] [(test: (format "[" category "] " "The symmetry of numerical comparisons.") [x rand-gen y rand-gen] (assert "" (or (= x y) (if (< y x) (> x y) (< x y))))) (test: (format "[" category "] " "Minimums and maximums.") [x rand-gen y rand-gen] (assert "" (and (and (<= x (min x y)) (<= y (min x y))) (and (>= x (max x y)) (>= y (max x y))) )))] ["Int" R;int i.= i.< i.> i.<= i.>= i.min i.max] ["Nat" R;nat n.= n.< n.> n.<= n.>= n.min n.max] ["Real" R;real r.= r.< r.> r.<= r.>= r.min r.max] ["Deg" R;deg d.= d.< d.> d.<= d.>= d.min d.max] ) (do-template [category rand-gen = + - * / <%> > <0> <1> %x ] [(test: (format "[" category "] " "Additive identity") [x rand-gen] (assert "" (and (|> x (+ <0>) (= x)) (|> x (- <0>) (= x))))) (test: (format "[" category "] " "Addition & Substraction") [x (:: @ map rand-gen) y (:: @ map rand-gen) #let [x (* x) y (* y)]] (assert "" (and (|> x (- y) (+ y) (= x)) (|> x (+ y) (- y) (= x))))) (test: (format "[" category "] " "Multiplicative identity") [x rand-gen] (assert "" ## Skip this test for Deg ## because Deg division loses the last ## 32 bits of precision. (or (T/= "Deg" category) (and (|> x (* <1>) (= x)) (|> x (/ <1>) (= x)))))) (test: (format "[" category "] " "Multiplication & Division") [x (:: @ map rand-gen) y (|> rand-gen (:: @ map ) (R;filter (|>. (= <0>) not))) #let [r (<%> y x) x' (- r x)]] (assert "" ## Skip this test for Deg ## because Deg division loses the last ## 32 bits of precision. (or (T/= "Deg" category) (or (> x' y) (|> x' (/ y) (* y) (= x')))) ))] ["Nat" R;nat n.= n.+ n.- n.* n./ n.% n.> +0 +1 +1000000 %n (n.% +1000) id] ["Int" R;int i.= i.+ i.- i.* i./ i.% i.> 0 1 1000000 %i (i.% 1000) id] ["Real" R;real r.= r.+ r.- r.* r./ r.% r.> 0.0 1.0 1000000.0 %r id math;floor] ["Deg" R;deg d.= d.+ d.- d.* d./ d.% d.> .0 (_lux_proc ["deg" "max-value"] []) (_lux_proc ["deg" "max-value"] []) %f id id] ) (do-template [category rand-gen -> <- = %a %z] [(test: (format "[" category "] " "Numeric conversions") [value rand-gen #let [value ( value)]] (assert "" (|> value -> <- (= value))))] ["Int->Nat" R;int int-to-nat nat-to-int i.= (i.% 1000000) %i %n] ["Nat->Int" R;nat nat-to-int int-to-nat n.= (n.% +1000000) %n %i] ["Int->Real" R;int int-to-real real-to-int i.= (i.% 1000000) %i %r] ["Real->Int" R;real real-to-int int-to-real r.= math;floor %r %i] ## [R;real real-to-deg deg-to-real r.= (r.% 1.0) %r %f] ) (test: "Simple macros and constructs" ($_ seq (assert "Can write easy loops for iterative programming." (i.= 1000 (loop [counter 0 value 1] (if (i.< 3 counter) (recur (i.inc counter) (i.* 10 value)) value)))) (assert "Can create lists easily through macros." (and (case (list 1 2 3) (#;Cons 1 (#;Cons 2 (#;Cons 3 #;Nil))) true _ false) (case (list& 1 2 3 (list 4 5 6)) (#;Cons 1 (#;Cons 2 (#;Cons 3 (#;Cons 4 (#;Cons 5 (#;Cons 6 #;Nil)))))) true _ false))) (assert "Can have defaults for Maybe values." (and (is "yolo" (default "yolo" #;None)) (is "lol" (default "yolo" (#;Some "lol"))))) )) (template: (hypotenuse x y) (i.+ (i.* x x) (i.* y y))) (test: "Templates" [x R;int y R;int] (assert "Template application is a stand-in for the templated code." (i.= (i.+ (i.* x x) (i.* y y)) (hypotenuse x y))))