aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/collection/stream.lux
blob: 85ddec9168e2e04ddd042ed71e550e9c54096890 (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
124
125
126
127
128
... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

(.require
 [library
  [lux (.except)
   [abstract
    [monad (.only do)]
    [equivalence (.only Equivalence)]
    ["[0]" enum]
    ["[0]" functor
     ["[1]T" \\test (.only Injection Comparison)]]
    ["[0]" comonad
     ["[1]T" \\test]]]
   [data
    ["[0]" text (.only)
     ["%" \\format (.only format)]]
    [collection
     ["[0]" list (.use "[1]#[0]" functor)]]]
   [math
    ["[0]" random]
    [number
     ["n" nat]]]
   [test
    ["_" property (.only Test)]]]]
 [\\library
  ["[0]" /]])

(def (equivalence super)
  (All (_ a) (-> (Equivalence a) (Equivalence (/.Stream a))))
  (implementation
   (def (= reference subject)
     (of (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 (of ! each (n.% 100) random.nat)
         size (of ! each (|>> (n.% 10) ++) random.nat)
         offset (of ! each (n.% 100) random.nat)
         cycle_start random.nat
         cycle_next (random.list size random.nat)]
        (all _.and
             (_.for [/.functor]
                    (functorT.spec /.repeated ..equivalence /.functor))
             (_.for [/.comonad]
                    (comonadT.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))))
             ))))