aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/control/concurrency/csp.lux
blob: 057ff60c855233de776d563917d7614dd5d3e60b (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
(.require
 [library
  [lux (.except)
   [abstract
    [monad (.only do)]
    ["[0]" functor
     ["[1]T" \\test (.only Injection Comparison)]]
    [\\specification
     ["$[0]" monad]]]
   [control
    ["[0]" io]
    ["[0]" try]
    ["[0]" exception]]
   [math
    ["[0]" random]]
   [test
    ["_" property (.only Test)]
    ["[0]" unit]]]]
 [\\library
  ["[0]" / (.only)
   [//
    ["[0]" async]]]])

(def injection
  (Injection /.Process)
  (of /.monad in))

(def comparison
  (Comparison /.Process)
  (function (_ == left right)
    (io.run!
     (do io.monad
       [?left (async.value left)
        ?right (async.value right)]
       (in (when [?left ?right]
             [{.#Some {try.#Success left}}
              {.#Some {try.#Success right}}]
             (== left right)
             
             _
             false))))))

(def .public test
  Test
  (<| (_.covering /._)
      (do [! random.monad]
        [expected random.nat]
        (all _.and
             (_.for [/.Process]
                    (all _.and
                         (_.for [/.functor]
                                (functorT.spec ..injection ..comparison /.functor))
                         (_.for [/.monad]
                                ($monad.spec ..injection ..comparison /.monad))
                         ))
             (_.coverage [/.Channel /.Channel' /.Sink /.channel]
               ... This is already been tested for the FRP module.
               true)
             (in (do async.monad
                   [it (do /.monad
                         [.let [[channel sink] (/.channel [])]
                          _ (/.write expected sink)
                          [actual channel] (/.read channel)]
                         (in (same? expected actual)))]
                   (unit.coverage [/.read /.write]
                     (try.else false it))))
             (in (do async.monad
                   [it (do /.monad
                         [.let [[channel sink] (/.channel [])]
                          _ (/.close sink)
                          it (/.try (/.write expected sink))]
                         (in (when it
                               {try.#Failure _}
                               true

                               _
                               false)))]
                   (unit.coverage [/.close /.try]
                     (try.else false it))))
             (in (do async.monad
                   [it (do /.monad
                         [.let [[channel sink] (/.channel [])]
                          _ (/.close sink)
                          it (/.try (/.read channel))]
                         (in (when it
                               {try.#Failure error}
                               (exception.match? /.channel_has_been_closed error)

                               _
                               false)))]
                   (unit.coverage [/.channel_has_been_closed]
                     (try.else false it))))
             ))))