aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/data/collection/sequence.lux
blob: 6e806e629a779381b173ad1794d078b88b4d4c56 (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
(.module:
  [lux #*
   [control
    [monad (#+ do Monad)]
    comonad]
   [data
    ["." maybe]
    [number
     ["." nat ("#/." codec)]]
    ["." text ("#/." monoid)]
    [collection
     ["." list]
     ["&" sequence]]]
   [math
    ["r" random]]]
  lux/test)

(context: "Sequences"
  (<| (times 100)
      (do @
        [size (|> r.nat (:: @ map (|>> (n/% 100) (n/max 2))))
         offset (|> r.nat (:: @ map (n/% 100)))
         factor (|> r.nat (:: @ map (|>> (n/% 100) (n/max 2))))
         elem r.nat
         cycle-seed (r.list size r.nat)
         cycle-sample-idx (|> r.nat (:: @ map (n/% 1000)))
         #let [(^open "List/.") (list.equivalence number.equivalence)
               sample0 (&.iterate inc 0)
               sample1 (&.iterate inc offset)]]
        ($_ seq
            (test "Can move along a sequence and take slices off it."
                  (and (and (List/= (list.n/range 0 (dec size))
                                    (&.take size sample0))
                            (List/= (list.n/range offset (dec (n/+ offset size)))
                                    (&.take size (&.drop offset sample0)))
                            (let [[drops takes] (&.split size sample0)]
                              (and (List/= (list.n/range 0 (dec size))
                                           drops)
                                   (List/= (list.n/range size (dec (n/* 2 size)))
                                           (&.take size takes)))))
                       (and (List/= (list.n/range 0 (dec size))
                                    (&.take-while (n/< size) sample0))
                            (List/= (list.n/range offset (dec (n/+ offset size)))
                                    (&.take-while (n/< (n/+ offset size))
                                                  (&.drop-while (n/< offset) sample0)))
                            (let [[drops takes] (&.split-while (n/< size) sample0)]
                              (and (List/= (list.n/range 0 (dec size))
                                           drops)
                                   (List/= (list.n/range size (dec (n/* 2 size)))
                                           (&.take-while (n/< (n/* 2 size)) takes)))))
                       ))

            (test "Can repeat any element and infinite number of times."
                  (n/= elem (&.nth offset (&.repeat elem))))

            (test "Can obtain the head & tail of a sequence."
                  (and (n/= offset (&.head sample1))
                       (List/= (list.n/range (inc offset) (n/+ offset size))
                               (&.take size (&.tail sample1)))))

            (test "Can filter sequences."
                  (and (n/= (n/* 2 offset)
                            (&.nth offset
                                   (&.filter n/even? sample0)))
                       (let [[evens odds] (&.partition n/even? (&.iterate inc 0))]
                         (and (n/= (n/* 2 offset)
                                   (&.nth offset evens))
                              (n/= (inc (n/* 2 offset))
                                   (&.nth offset odds))))))

            (test "Functor goes over 'all' elements in a sequence."
                  (let [(^open "&/.") &.functor
                        there (&/map (n/* factor) sample0)
                        back-again (&/map (n// factor) there)]
                    (and (not (List/= (&.take size sample0)
                                      (&.take size there)))
                         (List/= (&.take size sample0)
                                 (&.take size back-again)))))

            (test "CoMonad produces a value for every element in a sequence."
                  (let [(^open "&/.") &.functor]
                    (List/= (&.take size (&/map (n/* factor) sample1))
                            (&.take size
                                    (be &.comonad
                                      [inputs sample1]
                                      (n/* factor (&.head inputs)))))))

            (test "'unfold' generalizes 'iterate'."
                  (let [(^open "&/.") &.functor
                        (^open "List/.") (list.equivalence text.equivalence)]
                    (List/= (&.take size
                                    (&/map nat/encode (&.iterate inc offset)))
                            (&.take size
                                    (&.unfold (function (_ n) [(inc n) (nat/encode n)])
                                              offset)))))

            (test "Can cycle over the same elements as an infinite sequence."
                  (|> (&.cycle cycle-seed)
                      maybe.assume
                      (&.nth cycle-sample-idx)
                      (n/= (|> cycle-seed
                               (list.nth (n/% size cycle-sample-idx))
                               maybe.assume))))
            ))))