aboutsummaryrefslogtreecommitdiff
path: root/stdlib/test/test/lux/concurrency/frp.lux
blob: 2d9a45167cff96ac479e23219fbc2067ebb9d57a (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
(;module:
  lux
  (lux [io #- run]
       (control monad)
       (data [number]
             text/format)
       (concurrency [promise #+ Promise Monad<Promise> "Promise/" Monad<Promise>]
                    ["&" frp]))
  lux/test)

(def: (List->Chan values)
  (-> (List Int) (&;Chan Int))
  (let [_chan (: (&;Chan Int) (&;chan))]
    (io;run (do Monad<IO>
              [_ (mapM @ (function [value] (&;write value _chan))
                       values)
               _ (&;close _chan)]
              (wrap _chan)))))

(context: "FRP"
  ($_ seq
      (do Monad<Promise>
        [elems (&;consume (List->Chan (list 0 1 2 3 4 5)))]
        (test "Can consume a chan into a list."
              (case elems
                (^ (list 0 1 2 3 4 5))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (let [input (List->Chan (list 0 1 2 3 4 5))
                                output (: (&;Chan Int) (&;chan))]
                            (exec (&;pipe input output)
                              output)))]
        (test "Can pipe one channel into another."
              (case elems
                (^ (list 0 1 2 3 4 5))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (&;filter i.even? (List->Chan (list 0 1 2 3 4 5))))]
        (test "Can filter a channel's elements."
              (case elems
                (^ (list 0 2 4))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (&;merge (list (List->Chan (list 0 1 2 3 4 5))
                                         (List->Chan (list 0 -1 -2 -3 -4 -5)))))]
        (test "Can merge channels."
              (case elems
                (^ (list 0 1 2 3 4 5 0 -1 -2 -3 -4 -5))
                true

                _
                false)))
      
      (do Monad<Promise>
        [output (&;fold (function [base input] (Promise/wrap (i.+ input base))) 0 (List->Chan (list 0 1 2 3 4 5)))]
        (test "Can fold over a channel."
              (i.= 15 output)))

      (do Monad<Promise>
        [elems (&;consume (&;distinct number;Eq<Int> (List->Chan (list 0 0 0 1 2 2 3 3 3 3 4 4 4 5 5))))]
        (test "Can avoid immediate repetition in the channel."
              (case elems
                (^ (list 0 1 2 3 4 5))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (&;once (:: promise;Monad<Promise> wrap 12345)))]
        (test "Can convert a promise into a single-value channel."
              (case elems
                (^ (list 12345))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (:: &;Functor<Chan> map i.inc (List->Chan (list 0 1 2 3 4 5))))]
        (test "Functor goes over every element in a channel."
              (case elems
                (^ (list 1 2 3 4 5 6))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (let [(^open) &;Applicative<Chan>]
                            (apply (wrap i.inc) (wrap 12345))))]
        (test "Applicative works over all channel values."
              (case elems
                (^ (list 12346))
                true

                _
                false)))

      (do Monad<Promise>
        [elems (&;consume (do &;Monad<Chan>
                            [f (wrap i.inc)
                             a (wrap 12345)]
                            (wrap (f a))))]
        (test "Monad works over all channel values."
              (case elems
                (^ (list 12346))
                true

                _
                false)))
      ))