aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/collection/stream.lux
blob: 398873f2fc5328777afa6c133d27ffe4354ae588 (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 (.except)
   ["_" test (.only Test)]
   [abstract
    [monad (.only do)]
    [equivalence (.only Equivalence)]
    ["[0]" enum]
    [\\specification
     ["$[0]" functor]
     ["$[0]" comonad]]]
   [data
    ["[0]" text (.only)
     ["%" \\format (.only format)]]
    [collection
     ["[0]" list (.open: "[1]#[0]" functor)]]]
   [math
    ["[0]" random]
    [number
     ["n" nat]]]]]
 [\\library
  ["[0]" /]])

(def (equivalence super)
  (All (_ a) (-> (Equivalence a) (Equivalence (/.Stream a))))
  (implementation
   (def (= reference subject)
     (at (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 (at ! each (n.% 100) random.nat)
         size (at ! each (|>> (n.% 10) ++) random.nat)
         offset (at ! each (n.% 100) random.nat)
         cycle_start random.nat
         cycle_next (random.list size random.nat)]
        (all _.and
             (_.for [/.functor]
                    ($functor.spec /.repeated ..equivalence /.functor))
             (_.for [/.comonad]
                    ($comonad.spec /.repeated ..equivalence /.comonad))
             
             (_.coverage [/.item]
               (n.= (n.+ offset index)
                    (/.item index (..iterations ++ offset))))
             (_.coverage [/.repeated]
               (n.= repeated
                    (/.item index (/.repeated repeated))))
             (_.coverage [/.first]
               (list#= (enum.range n.enum offset (-- (n.+ size offset)))
                       (/.first size (..iterations ++ offset))))
             (_.coverage [/.after]
               (list#= (enum.range n.enum offset (-- (n.+ size offset)))
                       (/.first size (/.after offset (..iterations ++ 0)))))
             (_.coverage [/.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)))))
             (_.coverage [/.while]
               (list#= (enum.range n.enum 0 (-- size))
                       (/.while (n.< size) (..iterations ++ 0))))
             (_.coverage [/.until]
               (list#= (enum.range n.enum offset (-- (n.+ size offset)))
                       (/.while (n.< (n.+ size offset))
                                (/.until (n.< offset) (..iterations ++ 0)))))
             (_.coverage [/.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)))))
             (_.coverage [/.head]
               (n.= offset
                    (/.head (..iterations ++ offset))))
             (_.coverage [/.tail]
               (list#= (enum.range n.enum (++ offset) (n.+ size offset))
                       (/.first size (/.tail (..iterations ++ offset)))))
             (_.coverage [/.only]
               (list#= (list#each (n.* 2) (enum.range n.enum 0 (-- size)))
                       (/.first size (/.only n.even? (..iterations ++ 0)))))
             (_.coverage [/.partition]
               (let [[evens odds] (/.partition n.even? (..iterations ++ 0))]
                 (and (n.= (n.* 2 offset)
                           (/.item offset evens))
                      (n.= (++ (n.* 2 offset))
                           (/.item offset odds)))))
             (_.coverage [/.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)))))
             (_.coverage [/.cycle]
               (let [cycle (list.partial cycle_start cycle_next)]
                 (list#= (list.together (list.repeated size cycle))
                         (/.first (n.* size (list.size cycle))
                                  (/.cycle [cycle_start cycle_next])))))
             (_.coverage [/.pattern]
               (let [(/.pattern first second third next) (..iterations ++ offset)]
                 (and (n.= offset first)
                      (n.= (n.+ 1 offset) second)
                      (n.= (n.+ 2 offset) third))))
             ))))