aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/abstract/enum.lux
blob: 5a923019cd31c9ea0052290617773109178b80f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
(.module:
  [lux #*
   ["_" test (#+ Test)]
   [abstract
    [monad (#+ do)]]
   [data
    ["." product]
    ["." maybe ("#\." functor)]
    [collection
     ["." list ("#\." fold)]]]
   [math
    ["." random (#+ Random)]
    [number
     ["n" nat]]]]
  [\\
   ["." /]])

(def: #export test
  Test
  (let [limit (: (Random Nat)
                 (\ random.monad map (n.% 20) random.nat))]
    (do random.monad
      [start limit
       end limit
       #let [[start end] (if (n.< end start)
                           [start end]
                           [end start])
             range (/.range n.enum start end)]]
      (<| (_.covering /._)
          ($_ _.and
              (_.cover [/.range]
                       (let [expected-size (|> end (n.- start) inc)
                             expected-start? (|> range list.head (maybe\map (n.= start)) (maybe.default false))
                             expected-end? (|> range list.last (maybe\map (n.= end)) (maybe.default false))
                             can-be-backwards? (\ (list.equivalence n.equivalence) =
                                                  (/.range n.enum start end)
                                                  (list.reverse (/.range n.enum end start)))
                             every-element-is-a-successor? (case range
                                                             (#.Cons head tail)
                                                             (|> (list\fold (function (_ next [verdict prev])
                                                                              [(and verdict
                                                                                    (n.= next (\ n.enum succ prev)))
                                                                               next])
                                                                            [true head]
                                                                            tail)
                                                                 product.left)
                                                             
                                                             #.Nil
                                                             false)]
                         (and (n.= expected-size (list.size range))
                              expected-start?
                              expected-end?
                              can-be-backwards?
                              every-element-is-a-successor?)))
              )))))