aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/test/lux/data')
-rw-r--r--stdlib/source/test/lux/data/collection/bits.lux7
-rw-r--r--stdlib/source/test/lux/data/collection/dictionary.lux8
-rw-r--r--stdlib/source/test/lux/data/collection/dictionary/ordered.lux4
-rw-r--r--stdlib/source/test/lux/data/collection/list.lux528
4 files changed, 389 insertions, 158 deletions
diff --git a/stdlib/source/test/lux/data/collection/bits.lux b/stdlib/source/test/lux/data/collection/bits.lux
index 166ced163..cadd2d26d 100644
--- a/stdlib/source/test/lux/data/collection/bits.lux
+++ b/stdlib/source/test/lux/data/collection/bits.lux
@@ -78,9 +78,10 @@
(/.set idx /.empty)))
(not (/.intersects? sample (/.not sample)))))
(_.cover [/.not]
- (and (not (:: /.equivalence = sample (/.not sample)))
- (:: /.equivalence = sample (/.not (/.not sample)))
- (is? /.empty (/.not /.empty))))
+ (and (is? /.empty (/.not /.empty))
+ (or (is? /.empty sample)
+ (and (not (:: /.equivalence = sample (/.not sample)))
+ (:: /.equivalence = sample (/.not (/.not sample)))))))
(_.cover [/.xor]
(and (is? /.empty (/.xor sample sample))
(n.= (/.size (/.xor sample (/.not sample)))
diff --git a/stdlib/source/test/lux/data/collection/dictionary.lux b/stdlib/source/test/lux/data/collection/dictionary.lux
index b2956fa85..181d6efa4 100644
--- a/stdlib/source/test/lux/data/collection/dictionary.lux
+++ b/stdlib/source/test/lux/data/collection/dictionary.lux
@@ -51,8 +51,8 @@
(_.cover [/.entries /.keys /.values]
(:: (list.equivalence (equivalence.product n.equivalence n.equivalence)) =
(/.entries dict)
- (list.zip2 (/.keys dict)
- (/.values dict))))
+ (list.zip/2 (/.keys dict)
+ (/.values dict))))
(_.cover [/.merge]
(let [merging-with-oneself (let [(^open ".") (/.equivalence n.equivalence)]
@@ -67,8 +67,8 @@
(_.cover [/.merge-with]
(list.every? (function (_ [x x*2]) (n.= (n.* 2 x) x*2))
- (list.zip2 (/.values dict)
- (/.values (/.merge-with n.+ dict dict)))))
+ (list.zip/2 (/.values dict)
+ (/.values (/.merge-with n.+ dict dict)))))
(_.cover [/.from-list]
(let [(^open ".") (/.equivalence n.equivalence)]
diff --git a/stdlib/source/test/lux/data/collection/dictionary/ordered.lux b/stdlib/source/test/lux/data/collection/dictionary/ordered.lux
index 32d73290f..f45f1d0d4 100644
--- a/stdlib/source/test/lux/data/collection/dictionary/ordered.lux
+++ b/stdlib/source/test/lux/data/collection/dictionary/ordered.lux
@@ -46,8 +46,8 @@
values (r.set n.hash size r.nat)
extra-key (|> r.nat (r.filter (|>> (set.member? keys) not)))
extra-value r.nat
- #let [pairs (list.zip2 (set.to-list keys)
- (set.to-list values))
+ #let [pairs (list.zip/2 (set.to-list keys)
+ (set.to-list values))
sample (/.from-list n.order pairs)
sorted-pairs (list.sort (function (_ [left _] [right _])
(n.< left right))
diff --git a/stdlib/source/test/lux/data/collection/list.lux b/stdlib/source/test/lux/data/collection/list.lux
index e1f469fae..e6c971ae2 100644
--- a/stdlib/source/test/lux/data/collection/list.lux
+++ b/stdlib/source/test/lux/data/collection/list.lux
@@ -1,10 +1,10 @@
(.module:
[lux #*
- ["%" data/text/format (#+ format)]
["_" test (#+ Test)]
[abstract
[monad (#+ do)]
["." enum]
+ ["." equivalence]
{[0 #spec]
[/
["$." equivalence]
@@ -15,170 +15,400 @@
["$." monad]]}]
[control
pipe
- ["." io]]
+ ["." io]
+ ["." function]]
[data
["." bit]
["." product]
["." maybe]
+ ["." text ("#@." equivalence)]
[number
["n" nat]
- ["." int]]]
+ ["." int]]
+ [collection
+ ["." set]]]
[math
- ["r" random]]]
+ ["." random (#+ Random)]]]
{1
["." / ("#@." monad)]})
(def: bounded-size
- (r.Random Nat)
- (|> r.nat
- (:: r.monad map (|>> (n.% 100) (n.+ 10)))))
+ (Random Nat)
+ (:: random.monad map (n.% 100)
+ random.nat))
+
+(def: random
+ (Random (List Nat))
+ (do {@ random.monad}
+ [size ..bounded-size]
+ (|> random.nat
+ (random.set n.hash size)
+ (:: @ map set.to-list))))
(def: signatures
Test
- (do {@ r.monad}
- [size bounded-size]
+ ($_ _.and
+ (_.with-cover [/.equivalence]
+ ($equivalence.spec (/.equivalence n.equivalence) ..random))
+ (_.with-cover [/.monoid]
+ ($monoid.spec (/.equivalence n.equivalence) /.monoid ..random))
+ (_.with-cover [/.fold]
+ ($fold.spec /@wrap /.equivalence /.fold))
+ (_.with-cover [/.functor]
+ ($functor.spec /@wrap /.equivalence /.functor))
+ (_.with-cover [/.apply]
+ ($apply.spec /@wrap /.equivalence /.apply))
+ (_.with-cover [/.monad]
+ ($monad.spec /@wrap /.equivalence /.monad))
+
+ (do {@ random.monad}
+ [parameter random.nat
+ subject random.nat]
+ (let [lift (/.lift io.monad)
+ (^open "io@.") io.monad
+ expected (n.+ parameter subject)]
+ (_.cover [/.with /.lift]
+ (|> (io.run (do (/.with io.monad)
+ [a (lift (io@wrap parameter))
+ b (wrap subject)]
+ (wrap (n.+ a b))))
+ (case> (^ (list actual))
+ (n.= expected actual)
+
+ _
+ false)))))
+ ))
+
+(def: whole
+ Test
+ (do {@ random.monad}
+ [size ..bounded-size
+ #let [(^open "/@.") (/.equivalence n.equivalence)]
+ sample (:: @ map set.to-list (random.set n.hash size random.nat))]
($_ _.and
- ($equivalence.spec (/.equivalence n.equivalence) (r.list size r.nat))
- ($monoid.spec (/.equivalence n.equivalence) /.monoid (r.list size r.nat))
- ($fold.spec /@wrap /.equivalence /.fold)
- ($functor.spec /@wrap /.equivalence /.functor)
- ($apply.spec /@wrap /.equivalence /.apply)
- ($monad.spec /@wrap /.equivalence /.monad)
-
- (do @
- [parameter r.nat
- subject r.nat]
- (let [lift (/.lift io.monad)
- (^open "io@.") io.monad
- expected (n.+ parameter subject)]
- (_.test "Can add list functionality to any monad."
- (|> (io.run (do (/.with io.monad)
- [a (lift (io@wrap parameter))
- b (wrap subject)]
- (wrap (n.+ a b))))
- (case> (^ (list actual))
- (n.= expected actual)
-
- _
- false)))))
+ (_.cover [/.size]
+ (n.= size (/.size sample)))
+ (_.cover [/.empty?]
+ (:: bit.equivalence =
+ (/.empty? sample)
+ (n.= 0 (/.size sample))))
+ (_.cover [/.repeat]
+ (n.= size (/.size (/.repeat size []))))
+ (_.cover [/.reverse]
+ (and (not (/@= sample
+ (/.reverse sample)))
+ (/@= sample
+ (/.reverse (/.reverse sample)))))
+ (_.cover [/.every? /.any?]
+ (if (/.every? n.even? sample)
+ (not (/.any? (bit.complement n.even?) sample))
+ (/.any? (bit.complement n.even?) sample)))
+ (_.cover [/.sort]
+ (let [<<< n.<
+
+ size-preservation!
+ (n.= (/.size sample)
+ (/.size (/.sort <<< sample)))
+
+ symmetry!
+ (/@= (/.sort <<< sample)
+ (/.reverse (/.sort (function.flip <<<) sample)))]
+ (and size-preservation!
+ symmetry!)))
)))
+(def: indices
+ Test
+ (let [(^open "/@.") (/.equivalence n.equivalence)
+ (^open "/@.") /.functor]
+ (do {@ random.monad}
+ [sample ..random
+ #let [size (/.size sample)]]
+ ($_ _.and
+ (_.cover [/.indices]
+ (let [indices (/.indices size)
+
+ expected-amount!
+ (n.= size (/.size indices))
+
+ already-sorted!
+ (/@= indices
+ (/.sort n.< indices))
+
+ expected-numbers!
+ (/.every? (n.= (dec size))
+ (/.zip-with/2 n.+
+ indices
+ (/.sort n.> indices)))]
+ (and expected-amount!
+ already-sorted!
+ expected-numbers!)))
+ (_.cover [/.enumeration]
+ (let [enumeration (/.enumeration sample)]
+ (and (/@= (/.indices (/.size enumeration))
+ (/@map product.left enumeration))
+ (/@= sample
+ (/@map product.right enumeration)))))
+ (_.cover [/.nth]
+ (/.every? (function (_ [index expected])
+ (case (/.nth index sample)
+ (#.Some actual)
+ (n.= expected actual)
+
+ #.None
+ false))
+ (/.enumeration sample)))
+ ))))
+
+(def: slice
+ Test
+ (let [(^open "/@.") (/.equivalence n.equivalence)
+ (^open "/@.") /.monoid]
+ (do {@ random.monad}
+ [sample ..random
+ #let [size (/.size sample)]
+ idx (:: @ map (n.% size) random.nat)
+ chunk-size (:: @ map (|>> (n.% size) inc) random.nat)]
+ ($_ _.and
+ (_.cover [/.filter]
+ (let [positives (/.filter n.even? sample)
+ negatives (/.filter (bit.complement n.even?) sample)]
+ (and (/.every? n.even? positives)
+ (not (/.any? n.even? negatives))
+
+ (n.= (/.size sample)
+ (n.+ (/.size positives)
+ (/.size negatives))))))
+ (_.cover [/.partition]
+ (let [[positives negatives] (/.partition n.even? sample)]
+ (and (/@= (/.filter n.even? sample)
+ positives)
+ (/@= (/.filter (bit.complement n.even?) sample)
+ negatives))))
+ (_.cover [/.split]
+ (let [[left right] (/.split idx sample)]
+ (/@= sample
+ (/@compose left right))))
+ (_.cover [/.split-with]
+ (let [[left right] (/.split-with n.even? sample)]
+ (/@= sample
+ (/@compose left right))))
+ (_.cover [/.take /.drop]
+ (/@= sample
+ (/@compose (/.take idx sample)
+ (/.drop idx sample))))
+ (_.cover [/.take-while /.drop-while]
+ (/@= sample
+ (/@compose (/.take-while n.even? sample)
+ (/.drop-while n.even? sample))))
+ (_.cover [/.chunk]
+ (let [chunks (/.chunk chunk-size sample)]
+ (and (/.every? (|>> /.size (n.<= chunk-size)) chunks)
+ (/@= sample
+ (/.concat chunks)))))
+ ))))
+
+(def: member
+ Test
+ (let [(^open "/@.") (/.equivalence n.equivalence)]
+ (do {@ random.monad}
+ [sample ..random]
+ (`` ($_ _.and
+ (_.cover [/.member?]
+ (/.every? (/.member? n.equivalence sample)
+ sample))
+ (~~ (template [<head> <tail> <pre>]
+ [($_ _.and
+ (_.cover [<head>]
+ (case [(<pre> sample) (<head> sample)]
+ [(#.Cons expected _) (#.Some actual)]
+ (n.= expected actual)
+
+ [#.Nil #.None]
+ true
+
+ _
+ false))
+ (_.cover [<tail>]
+ (case [(<pre> sample) (<tail> sample)]
+ [(#.Cons _ expected) (#.Some actual)]
+ (/@= (<pre> expected) actual)
+
+ [#.Nil #.None]
+ true
+
+ _
+ false))
+ )]
+
+ [/.head /.tail |>]
+ [/.last /.inits /.reverse]
+ ))
+ )))))
+
+(def: grouping
+ Test
+ (let [(^open "/@.") (/.equivalence n.equivalence)
+ (^open "/@.") /.functor
+ (^open "/@.") /.monoid
+
+ +/2 (: (-> Nat Nat Nat)
+ (function (_ left right)
+ ($_ n.+ left right)))
+ +/3 (: (-> Nat Nat Nat Nat)
+ (function (_ left mid right)
+ ($_ n.+ left mid right)))]
+ (do {@ random.monad}
+ [sample/0 ..random
+ sample/1 ..random
+ sample/2 ..random]
+ ($_ _.and
+ (_.cover [/.as-pairs]
+ (n.= (n./ 2 (/.size sample/0))
+ (/.size (/.as-pairs sample/0))))
+ (_.cover [/.zip/2]
+ (let [zipped (/.zip/2 sample/0 sample/1)
+ zipped::size (/.size zipped)
+
+ size-of-smaller-list!
+ (n.= zipped::size
+ (n.min (/.size sample/0) (/.size sample/1)))
+
+ can-extract-values!
+ (and (/@= (/.take zipped::size sample/0)
+ (/@map product.left zipped))
+ (/@= (/.take zipped::size sample/1)
+ (/@map product.right zipped)))]
+ (and size-of-smaller-list!
+ can-extract-values!)))
+ (_.cover [/.zip/3]
+ (let [zipped (/.zip/3 sample/0 sample/1 sample/2)
+ zipped::size (/.size zipped)
+
+ size-of-smaller-list!
+ (n.= zipped::size
+ ($_ n.min
+ (/.size sample/0)
+ (/.size sample/1)
+ (/.size sample/2)))
+
+ can-extract-values!
+ (and (/@= (/.take zipped::size sample/0)
+ (/@map product.left zipped))
+ (/@= (/.take zipped::size sample/1)
+ (/@map (|>> product.right product.left) zipped))
+ (/@= (/.take zipped::size sample/2)
+ (/@map (|>> product.right product.right) zipped)))]
+ (and size-of-smaller-list!
+ can-extract-values!)))
+ (_.cover [/.zip]
+ (and (:: (/.equivalence (equivalence.product n.equivalence n.equivalence)) =
+ (/.zip/2 sample/0 sample/1)
+ ((/.zip 2) sample/0 sample/1))
+ (:: (/.equivalence ($_ equivalence.product n.equivalence n.equivalence n.equivalence)) =
+ (/.zip/3 sample/0 sample/1 sample/2)
+ ((/.zip 3) sample/0 sample/1 sample/2))))
+
+ (_.cover [/.zip-with/2]
+ (/@= (/@map (function (_ [left right])
+ (+/2 left right))
+ (/.zip/2 sample/0 sample/1))
+ (/.zip-with/2 +/2 sample/0 sample/1)))
+ (_.cover [/.zip-with/3]
+ (/@= (/@map (function (_ [left mid right])
+ (+/3 left mid right))
+ (/.zip/3 sample/0 sample/1 sample/2))
+ (/.zip-with/3 +/3 sample/0 sample/1 sample/2)))
+ (_.cover [/.zip-with]
+ (and (/@= (/.zip-with/2 +/2 sample/0 sample/1)
+ ((/.zip-with 2) +/2 sample/0 sample/1))
+ (/@= (/.zip-with/3 +/3 sample/0 sample/1 sample/2)
+ ((/.zip-with 3) +/3 sample/0 sample/1 sample/2))))
+ (_.cover [/.concat]
+ (and (/@= (/@compose sample/0 sample/1)
+ (/.concat (list sample/0 sample/1)))
+ (/@= ($_ /@compose sample/0 sample/1 sample/2)
+ (/.concat (list sample/0 sample/1 sample/2)))))
+ ))))
+
+(def: search
+ Test
+ (let [(^open "/@.") /.functor
+
+ choose (: (-> Nat (Maybe Text))
+ (function (_ value)
+ (if (n.even? value)
+ (#.Some (:: n.decimal encode value))
+ #.None)))]
+ (do {@ random.monad}
+ [sample ..random]
+ ($_ _.and
+ (_.cover [/.one]
+ (case [(|> sample
+ (/.filter n.even?)
+ (/@map (:: n.decimal encode))
+ /.head)
+ (/.one choose sample)]
+ [(#.Some expected) (#.Some actual)]
+ (text@= expected actual)
+
+ [#.None #.None]
+ true
+
+ _
+ false))
+ (_.cover [/.all]
+ (:: (/.equivalence text.equivalence) =
+ (|> sample
+ (/.filter n.even?)
+ (/@map (:: n.decimal encode)))
+ (/.all choose sample)))
+ (_.cover [/.find]
+ (case (/.find n.even? sample)
+ (#.Some found)
+ (and (n.even? found)
+ (/.any? n.even? sample)
+ (not (/.every? (bit.complement n.even?) sample)))
+
+ #.None
+ (and (not (/.any? n.even? sample))
+ (/.every? (bit.complement n.even?) sample))))
+ ))))
+
(def: #export test
Test
- (<| (_.context (%.name (name-of .List)))
- (do {@ r.monad}
- [size bounded-size
- #let [(^open "/@.") (/.equivalence n.equivalence)
- (^open "/@.") /.functor
- (^open "/@.") /.monoid]
- idx (:: @ map (n.% size) r.nat)
- sample (r.list size r.nat)
- other-size bounded-size
- other-sample (r.list other-size r.nat)
- separator r.nat]
- ($_ _.and
- ..signatures
-
- (_.test "The size function should correctly portray the size of the list."
- (n.= size (/.size sample)))
- (_.test "The repeat function should produce as many elements as asked of it."
- (n.= size (/.size (/.repeat size []))))
- (_.test "Reversing a list does not change it's size."
- (n.= (/.size sample)
- (/.size (/.reverse sample))))
- (_.test "Reversing a list twice results in the original list."
- (/@= sample
- (/.reverse (/.reverse sample))))
- (_.test "Filtering by a predicate and its complement should result in a number of elements equal to the original list."
- (and (n.= (/.size sample)
- (n.+ (/.size (/.filter n.even? sample))
- (/.size (/.filter (bit.complement n.even?) sample))))
- (let [[plus minus] (/.partition n.even? sample)]
- (n.= (/.size sample)
- (n.+ (/.size plus)
- (/.size minus))))))
- (_.test "If every element in a list satisfies a predicate, there can't be any that satisfy its complement."
- (if (/.every? n.even? sample)
- (and (not (/.any? (bit.complement n.even?) sample))
- (/.empty? (/.filter (bit.complement n.even?) sample)))
- (/.any? (bit.complement n.even?) sample)))
- (_.test "Any element of the list can be considered its member."
- (let [elem (maybe.assume (/.nth idx sample))]
- (/.member? n.equivalence sample elem)))
- (_.test "Appending the head and the tail should yield the original list."
- (let [head (maybe.assume (/.head sample))
- tail (maybe.assume (/.tail sample))]
- (/@= sample
- (#.Cons head tail))))
- (_.test "Appending the inits and the last should yield the original list."
- (let [inits (maybe.assume (/.inits sample))
- last (maybe.assume (/.last sample))]
- (/@= sample
- (/@compose inits (list last)))))
- (_.test "Splitting a list into chunks and re-appending them should yield the original list."
- (let [[left right] (/.split idx sample)
- [left' right'] (/.split-with n.even? sample)]
- (and (/@= sample
- (/@compose left right))
- (/@= sample
- (/@compose left' right'))
- (/@= sample
- (/@compose (/.take idx sample)
- (/.drop idx sample)))
- (/@= sample
- (/@compose (/.take-while n.even? sample)
- (/.drop-while n.even? sample)))
- )))
- (_.test "Segmenting the list in pairs should yield as many elements as N/2."
- (n.= (n./ 2 size)
- (/.size (/.as-pairs sample))))
- (_.test "Sorting a list shouldn't change it's size."
- (n.= (/.size sample)
- (/.size (/.sort n.< sample))))
- (_.test "Sorting a list with one order should yield the reverse of sorting it with the opposite order."
- (/@= (/.sort n.< sample)
- (/.reverse (/.sort n.> sample))))
- (_.test "If you zip 2 lists, the result's size will be that of the smaller list."
- (n.= (/.size (/.zip2 sample other-sample))
- (n.min (/.size sample) (/.size other-sample))))
- (_.test "I can pair-up elements of a list in order."
- (let [zipped (/.zip2 sample other-sample)
- num-zipper (/.size zipped)]
- (and (|> zipped (/@map product.left) (/@= (/.take num-zipper sample)))
- (|> zipped (/@map product.right) (/@= (/.take num-zipper other-sample))))))
- (_.test "You can generate indices for any size, and they will be in ascending order."
- (let [indices (/.indices size)]
- (and (n.= size (/.size indices))
- (/@= indices
- (/.sort n.< indices))
- (/.every? (n.= (dec size))
- (/.zip2-with n.+
- indices
- (/.sort n.> indices)))
- )))
- (_.test "The 'interpose' function places a value between every member of a list."
- (let [sample+ (/.interpose separator sample)]
- (and (n.= (|> size (n.* 2) dec)
- (/.size sample+))
- (|> sample+ /.as-pairs (/@map product.right) (/.every? (n.= separator))))))
- (_.test "You can find any value that satisfies some criterium, if such values exist in the list."
- (case (/.find n.even? sample)
- (#.Some found)
- (and (n.even? found)
- (/.any? n.even? sample)
- (not (/.every? (bit.complement n.even?) sample)))
-
- #.None
- (and (not (/.any? n.even? sample))
- (/.every? (bit.complement n.even?) sample))))
- (_.test "You can iteratively construct a list, generating values until you're done."
- (/@= (enum.range n.enum 0 (dec size))
- (/.iterate (function (_ n) (if (n.< size n) (#.Some (inc n)) #.None))
- 0)))
- (_.test "Can enumerate all elements in a list."
- (let [enum-sample (/.enumerate sample)]
- (and (/@= (/.indices (/.size enum-sample))
- (/@map product.left enum-sample))
- (/@= sample
- (/@map product.right enum-sample)))))
- ))))
+ (<| (_.covering /._)
+ (_.with-cover [.List])
+ (let [(^open "/@.") (/.equivalence n.equivalence)
+ (^open "/@.") /.functor]
+ (do {@ random.monad}
+ [sample ..random
+ separator random.nat]
+ ($_ _.and
+ ..signatures
+ ..whole
+ ..indices
+ ..slice
+ ..member
+ ..grouping
+ ..search
+
+ (_.cover [/.interpose]
+ (let [sample+ (/.interpose separator sample)]
+ (and (n.= (|> (/.size sample) (n.* 2) dec)
+ (/.size sample+))
+ (|> sample+ /.as-pairs (/.every? (|>> product.right (n.= separator)))))))
+ (_.cover [/.iterate]
+ (let [size (/.size sample)]
+ (/@= (/.indices size)
+ (/.iterate (function (_ index)
+ (if (n.< size index)
+ (#.Some (inc index))
+ #.None))
+ 0))))
+ (_.cover [/.folds]
+ (/@= (/@map (function (_ index)
+ (:: /.fold fold n.+ 0 (/.take index sample)))
+ (/.indices (inc (/.size sample))))
+ (/.folds n.+ 0 sample)))
+ )))))