aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/number.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/test/lux/data/number.lux')
-rw-r--r--stdlib/source/test/lux/data/number.lux185
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"))))))