aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/collection/stream.lux
blob: 64c5d63378a2d2dac987a3b490484a53e3586be9 (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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
(.using
 [library
  [lux "*"
   ["_" test {"+" Test}]
   [abstract
    [monad {"+" do}]
    [equivalence {"+" Equivalence}]
    ["[0]" enum]
    [\\specification
     ["$[0]" functor]
     ["$[0]" comonad]]]
   [data
    ["[0]" text
     ["%" format {"+" format}]]
    [collection
     ["[0]" list ("[1]#[0]" functor)]]]
   [math
    ["[0]" random]
    [number
     ["n" nat]]]]]
 [\\library
  ["[0]" /]])

(implementation: (equivalence super)
  (All (_ a) (-> (Equivalence a) (Equivalence (/.Stream a))))

  (def: (= reference subject)
    (# (list.equivalence super) =
       (/.first 100 reference)
       (/.first 100 subject))))

(def: (iterations step)
  (All (_ a)
    (-> (-> a a)
        (-> a (/.Stream a))))
  (/.iterations
   (function (_ state)
     (let [state' (step state)]
       [state' state]))))

(def: .public test
  Test
  (<| (_.covering /._)
      (_.for [/.Stream])
      (let [(open "list#[0]") (list.equivalence n.equivalence)])
      (do [! random.monad]
        [repeated random.nat
         index (# ! each (n.% 100) random.nat)
         size (# ! each (|>> (n.% 10) ++) random.nat)
         offset (# ! each (n.% 100) random.nat)
         cycle_start random.nat
         cycle_next (random.list size random.nat)]
        ($_ _.and
            (_.for [/.functor]
                   ($functor.spec /.repeated ..equivalence /.functor))
            (_.for [/.comonad]
                   ($comonad.spec /.repeated ..equivalence /.comonad))
            
            (_.cover [/.item]
                     (n.= (n.+ offset index)
                          (/.item index (..iterations ++ offset))))
            (_.cover [/.repeated]
                     (n.= repeated
                          (/.item index (/.repeated repeated))))
            (_.cover [/.first]
                     (list#= (enum.range n.enum offset (-- (n.+ size offset)))
                             (/.first size (..iterations ++ offset))))
            (_.cover [/.after]
                     (list#= (enum.range n.enum offset (-- (n.+ size offset)))
                             (/.first size (/.after offset (..iterations ++ 0)))))
            (_.cover [/.split_at]
                     (let [[drops takes] (/.split_at size (..iterations ++ 0))]
                       (and (list#= (enum.range n.enum 0 (-- size))
                                    drops)
                            (list#= (enum.range n.enum size (-- (n.* 2 size)))
                                    (/.first size takes)))))
            (_.cover [/.while]
                     (list#= (enum.range n.enum 0 (-- size))
                             (/.while (n.< size) (..iterations ++ 0))))
            (_.cover [/.until]
                     (list#= (enum.range n.enum offset (-- (n.+ size offset)))
                             (/.while (n.< (n.+ size offset))
                                      (/.until (n.< offset) (..iterations ++ 0)))))
            (_.cover [/.split_when]
                     (let [[drops takes] (/.split_when (n.= size) (..iterations ++ 0))]
                       (and (list#= (enum.range n.enum 0 (-- size))
                                    drops)
                            (list#= (enum.range n.enum size (-- (n.* 2 size)))
                                    (/.while (n.< (n.* 2 size)) takes)))))
            (_.cover [/.head]
                     (n.= offset
                          (/.head (..iterations ++ offset))))
            (_.cover [/.tail]
                     (list#= (enum.range n.enum (++ offset) (n.+ size offset))
                             (/.first size (/.tail (..iterations ++ offset)))))
            (_.cover [/.only]
                     (list#= (list#each (n.* 2) (enum.range n.enum 0 (-- size)))
                             (/.first size (/.only n.even? (..iterations ++ 0)))))
            (_.cover [/.partition]
                     (let [[evens odds] (/.partition n.even? (..iterations ++ 0))]
                       (and (n.= (n.* 2 offset)
                                 (/.item offset evens))
                            (n.= (++ (n.* 2 offset))
                                 (/.item offset odds)))))
            (_.cover [/.iterations]
                     (let [(open "/#[0]") /.functor
                           (open "list#[0]") (list.equivalence text.equivalence)]
                       (list#= (/.first size
                                        (/#each %.nat (..iterations ++ offset)))
                               (/.first size
                                        (/.iterations (function (_ n) [(++ n) (%.nat n)])
                                                      offset)))))
            (_.cover [/.cycle]
                     (let [cycle (partial_list cycle_start cycle_next)]
                       (list#= (list.together (list.repeated size cycle))
                               (/.first (n.* size (list.size cycle))
                                        (/.cycle [cycle_start cycle_next])))))
            (_.cover [/.pattern]
                     (let [(/.pattern first second third next) (..iterations ++ offset)]
                       (and (n.= offset first)
                            (n.= (n.+ 1 offset) second)
                            (n.= (n.+ 2 offset) third))))
            ))))