aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/abstract/enum.lux
blob: afb40be03ea372e27cfb986bb69ea2b55e69e4ab (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
56
57
(.module:
  [library
   [lux #*
    ["_" test (#+ Test)]
    [abstract
     [monad (#+ do)]]
    [control
     ["." maybe ("#\." functor)]]
    [data
     ["." product]
     [collection
      ["." list ("#\." mix)]]]
    [math
     ["." random (#+ Random)]
     [number
      ["n" nat]]]]]
  [\\library
   ["." /]])

(def: .public test
  Test
  (let [limit (: (Random Nat)
                 (\ random.monad each (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) ++)
                             expected_start? (|> range list.head (maybe\each (n.= start)) (maybe.else false))
                             expected_end? (|> range list.last (maybe\each (n.= end)) (maybe.else false))
                             can_be_backwards? (\ (list.equivalence n.equivalence) =
                                                  (/.range n.enum start end)
                                                  (list.reversed (/.range n.enum end start)))
                             every_element_is_a_successor? (case range
                                                             (#.Item head tail)
                                                             (|> (list\mix (function (_ next [verdict prev])
                                                                             [(and verdict
                                                                                   (n.= next (\ n.enum succ prev)))
                                                                              next])
                                                                           [true head]
                                                                           tail)
                                                                 product.left)
                                                             
                                                             #.End
                                                             false)]
                         (and (n.= expected_size (list.size range))
                              expected_start?
                              expected_end?
                              can_be_backwards?
                              every_element_is_a_successor?)))
              )))))