diff options
Diffstat (limited to 'stdlib/source/test/lux/data/number.lux')
-rw-r--r-- | stdlib/source/test/lux/data/number.lux | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/stdlib/source/test/lux/data/number.lux b/stdlib/source/test/lux/data/number.lux new file mode 100644 index 000000000..9d870ab08 --- /dev/null +++ b/stdlib/source/test/lux/data/number.lux @@ -0,0 +1,185 @@ +(.module: + [lux #* + [control + ["M" monad (#+ Monad do)] + pipe] + [data + number + [text ("text/." equivalence) + format]] + [math + ["r" random]]] + lux/test) + +(do-template [category rand-gen <Equivalence> <Order>] + [(context: (format "[" category "] " "Equivalence & Order") + (<| (times 100) + (do @ + [x rand-gen + y rand-gen] + (test "" (and (:: <Equivalence> = x x) + (or (:: <Equivalence> = x y) + (:: <Order> < y x) + (:: <Order> > y x)))))))] + + ["Nat" r.nat equivalence order] + ["Int" r.int equivalence order] + ["Rev" r.rev equivalence order] + ["Frac" r.frac equivalence order] + ) + +(do-template [category rand-gen <Number> <Order>] + [(context: (format "[" category "] " "Number") + (<| (times 100) + (do @ + [x rand-gen + #let [(^open ".") <Number> + (^open ".") <Order>]] + (test "" (and (>= x (abs x)) + ## abs(0.0) == 0.0 && negate(abs(0.0)) == -0.0 + (or (text/= "Frac" category) + (not (= x (negate x)))) + (= x (negate (negate x))) + ## There is loss of precision when multiplying + (or (text/= "Rev" category) + (= x (* (signum x) + (abs x)))))))))] + + ["Nat" r.nat number order] + ["Int" r.int number order] + ["Rev" r.rev number order] + ["Frac" r.frac number order] + ) + +(do-template [category rand-gen <Enum> <Number> <Order>] + [(context: (format "[" category "] " "Enum") + (<| (times 100) + (do @ + [x rand-gen] + (test "" (let [(^open ".") <Number> + (^open ".") <Order>] + (and (> x + (:: <Enum> succ x)) + (< x + (:: <Enum> pred x)) + + (= x + (|> x (:: <Enum> pred) (:: <Enum> succ))) + (= x + (|> x (:: <Enum> succ) (:: <Enum> pred))) + ))))))] + + ["Nat" r.nat enum number order] + ["Int" r.int enum number order] + ) + +(do-template [category rand-gen <Number> <Order> <Interval> <test>] + [(context: (format "[" category "] " "Interval") + (<| (times 100) + (do @ + [x (|> rand-gen (r.filter <test>)) + #let [(^open ".") <Number> + (^open ".") <Order>]] + (test "" (and (<= x (:: <Interval> bottom)) + (>= x (:: <Interval> top)))))))] + + ["Nat" r.nat number order interval (function (_ _) #1)] + ["Int" r.int number order interval (function (_ _) #1)] + ## Both min and max values will be positive (thus, greater than zero) + ["Rev" r.rev number order interval (function (_ _) #1)] + ["Frac" r.frac number order interval (f/> +0.0)] + ) + +(do-template [category rand-gen <Number> <Order> <Monoid> <cap> <test>] + [(context: (format "[" category "] " "Monoid") + (<| (times 100) + (do @ + [x (|> rand-gen (:: @ map (|>> (:: <Number> abs) <cap>)) (r.filter <test>)) + #let [(^open ".") <Number> + (^open ".") <Order> + (^open ".") <Monoid>]] + (test "Composing with identity doesn't change the value." + (and (= x (compose identity x)) + (= x (compose x identity)) + (= identity (compose identity identity)))))))] + + ["Nat/Add" r.nat number order add@monoid (n/% 1000) (function (_ _) #1)] + ["Nat/Mul" r.nat number order mul@monoid (n/% 1000) (function (_ _) #1)] + ["Nat/Min" r.nat number order min@monoid (n/% 1000) (function (_ _) #1)] + ["Nat/Max" r.nat number order max@monoid (n/% 1000) (function (_ _) #1)] + ["Int/Add" r.int number order add@monoid (i/% +1000) (function (_ _) #1)] + ["Int/Mul" r.int number order mul@monoid (i/% +1000) (function (_ _) #1)] + ["Int/Min" r.int number order min@monoid (i/% +1000) (function (_ _) #1)] + ["Int/Max" r.int number order max@monoid (i/% +1000) (function (_ _) #1)] + ["Rev/Add" r.rev number order add@monoid (r/% .125) (function (_ _) #1)] + ["Rev/Mul" r.rev number order mul@monoid (r/% .125) (function (_ _) #1)] + ["Rev/Min" r.rev number order min@monoid (r/% .125) (function (_ _) #1)] + ["Rev/Max" r.rev number order max@monoid (r/% .125) (function (_ _) #1)] + ["Frac/Add" r.frac number order add@monoid (f/% +1000.0) (f/> +0.0)] + ["Frac/Mul" r.frac number order mul@monoid (f/% +1000.0) (f/> +0.0)] + ["Frac/Min" r.frac number order min@monoid (f/% +1000.0) (f/> +0.0)] + ["Frac/Max" r.frac number order max@monoid (f/% +1000.0) (f/> +0.0)] + ) + +(do-template [<category> <rand-gen> <Equivalence> <Codec>] + [(context: (format "[" <category> "] " "Alternative formats") + (<| (times 100) + (do @ + [x <rand-gen>] + (test "Can encode/decode values." + (|> x + (:: <Codec> encode) + (:: <Codec> decode) + (case> (#.Right x') + (:: <Equivalence> = x x') + + (#.Left _) + #0))))))] + + ["Nat/Binary" r.nat equivalence binary@codec] + ["Nat/Octal" r.nat equivalence octal@codec] + ["Nat/Decimal" r.nat equivalence codec] + ["Nat/Hex" r.nat equivalence hex@codec] + + ["Int/Binary" r.int equivalence binary@codec] + ["Int/Octal" r.int equivalence octal@codec] + ["Int/Decimal" r.int equivalence codec] + ["Int/Hex" r.int equivalence hex@codec] + + ["Rev/Binary" r.rev equivalence binary@codec] + ["Rev/Octal" r.rev equivalence octal@codec] + ["Rev/Decimal" r.rev equivalence codec] + ["Rev/Hex" r.rev equivalence hex@codec] + + ["Frac/Binary" r.frac equivalence binary@codec] + ["Frac/Octal" r.frac equivalence octal@codec] + ["Frac/Decimal" r.frac equivalence codec] + ["Frac/Hex" r.frac equivalence hex@codec] + ) + +(context: "Can convert frac values to/from their bit patterns." + (<| (times 100) + (do @ + [raw r.frac + factor (|> r.nat (:: @ map (|>> (n/% 1000) (n/max 1)))) + #let [sample (|> factor .int int-to-frac (f/* raw))]] + (test "Can convert frac values to/from their bit patterns." + (|> sample frac-to-bits bits-to-frac (f/= sample)))))) + +(context: "Macros for alternative numeric encodings." + ($_ seq + (test "Binary." + (and (n/= (bin "11001001") (bin "11_00_10_01")) + (i/= (bin "+11001001") (bin "+11_00_10_01")) + (r/= (bin ".11001001") (bin ".11_00_10_01")) + (f/= (bin "+1100.1001") (bin "+11_00.10_01")))) + (test "Octal." + (and (n/= (oct "615243") (oct "615_243")) + (i/= (oct "+615243") (oct "+615_243")) + (r/= (oct ".615243") (oct ".615_243")) + (f/= (oct "+6152.43") (oct "+615_2.43")))) + (test "Hexadecimal." + (and (n/= (hex "deadBEEF") (hex "dead_BEEF")) + (i/= (hex "+deadBEEF") (hex "+dead_BEEF")) + (r/= (hex ".deadBEEF") (hex ".dead_BEEF")) + (f/= (hex "+deadBE.EF") (hex "+dead_BE.EF")))))) |