-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathMain.purs
209 lines (190 loc) · 6.16 KB
/
Main.purs
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
module Test.Main where
import Prelude
import Effect (Effect)
import Effect.AVar as AVar
import Effect.Console (log)
import Effect.Exception (error, message)
import Effect.Ref as Ref
import Data.Either (Either(..))
import Data.Foldable (traverse_)
import Data.Maybe (Maybe(..))
import Test.Assert (assert')
test :: String -> Effect Boolean -> Effect Unit
test s k = k >>= \r -> assert' s r *> log ("[OK] " <> s)
test_tryRead_full :: Effect Unit
test_tryRead_full = test "tryRead/full" do
var <- AVar.new "foo"
val1 <- AVar.tryRead var
val2 <- AVar.tryRead var
pure (val1 == Just "foo" && val2 == Just "foo")
test_tryRead_empty :: Effect Unit
test_tryRead_empty = test "tryRead/empty" do
var <- AVar.empty
val1 :: Maybe Unit <- AVar.tryRead var
pure (val1 == Nothing)
test_tryPut_full :: Effect Unit
test_tryPut_full = test "tryPut/full" do
var <- AVar.new "foo"
res <- AVar.tryPut "bar" var
pure (not res)
test_tryPut_empty :: Effect Unit
test_tryPut_empty = test "tryPut/empty" do
var <- AVar.empty
res <- AVar.tryPut "foo" var
val <- AVar.tryRead var
pure (res && val == Just "foo")
test_tryTake_full :: Effect Unit
test_tryTake_full = test "tryTake/full" do
var <- AVar.new "foo"
res1 <- AVar.tryTake var
res2 <- AVar.tryTake var
pure (res1 == Just "foo" && res2 == Nothing)
test_tryTake_empty :: Effect Unit
test_tryTake_empty = test "tryTake/empty" do
var <- AVar.empty
res1 <- AVar.tryTake var
res2 <- AVar.tryPut "foo" var
res3 <- AVar.tryTake var
pure (res1 == Nothing && res2 && res3 == Just "foo")
test_put_take :: Effect Unit
test_put_take = test "put/take" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
_ <- AVar.take var $ traverse_ \val ->
void $ Ref.modify (_ <> val) ref
eq "barfoo" <$> Ref.read ref
test_put_read_take :: Effect Unit
test_put_read_take = test "put/read/take" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
_ <- AVar.read var $ traverse_ \val ->
void $ Ref.modify (_ <> val <> "baz") ref
_ <- AVar.take var $ traverse_ \val ->
void $ Ref.modify (_ <> val) ref
eq "barfoobazfoo" <$> Ref.read ref
test_take_put :: Effect Unit
test_take_put = test "take/put" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.take var $ traverse_ \val ->
void $ Ref.modify (_ <> val) ref
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
eq "foobar" <$> Ref.read ref
test_take_read_put :: Effect Unit
test_take_read_put = test "take/read/put" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.take var $ traverse_ \val ->
void $ Ref.modify (_ <> val) ref
_ <- AVar.read var $ traverse_ \val ->
void $ Ref.modify (_ <> val <> "baz") ref
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
eq "foobazfoobar" <$> Ref.read ref
test_read_put_take :: Effect Unit
test_read_put_take = test "read/put/take" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.read var $ traverse_ \val ->
void $ Ref.modify (_ <> val <> "baz") ref
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
_ <- AVar.take var $ traverse_ \val -> do
void $ Ref.modify (_ <> val) ref
eq "foobazbarfoo" <$> Ref.read ref
test_read_take_put :: Effect Unit
test_read_take_put = test "read/take/put" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.read var $ traverse_ \val -> do
void $ Ref.modify (_ <> val <> "baz") ref
void $ AVar.take var $ traverse_ \val' ->
void $ Ref.modify (_ <> val') ref
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
eq "foobazbarfoo" <$> Ref.read ref
test_kill_full :: Effect Unit
test_kill_full = test "kill/full" do
ref <- Ref.new ""
var <- AVar.empty
_ <- AVar.put "foo" var $ traverse_ \_ ->
void $ Ref.modify (_ <> "bar") ref
AVar.kill (error "Die.") var
_ <- AVar.read var case _ of
Left err -> void $ Ref.modify (_ <> message err) ref
Right _ -> void $ Ref.modify (_ <> "BAD") ref
eq "barDie." <$> Ref.read ref
test_kill_empty :: Effect Unit
test_kill_empty = test "kill/empty" do
ref <- Ref.new ""
var <- AVar.empty
AVar.kill (error "Die.") var
_ <- AVar.read var case _ of
Left err -> void $ Ref.modify (_ <> message err) ref
Right _ -> void $ Ref.modify (_ <> "BAD") ref
eq "Die." <$> Ref.read ref
test_kill_pending :: Effect Unit
test_kill_pending = test "kill/pending" do
ref <- Ref.new ""
var <- AVar.empty
let
cb s = case _ of
Left err -> void $ Ref.modify (_ <> s <> message err) ref
Right _ -> void $ Ref.modify (_ <> "BAD") ref
_ <- AVar.take var (cb "a")
_ <- AVar.take var (cb "b")
_ <- AVar.read var (cb "c")
_ <- AVar.read var (cb "d")
AVar.kill (error "-die.") var
eq "c-die.d-die.a-die.b-die." <$> Ref.read ref
test_cancel :: Effect Unit
test_cancel = test "cancel" do
ref <- Ref.new ""
v1 <- AVar.new ""
c1 <- AVar.put "a" v1 $ traverse_ \_ -> void $ Ref.modify (_ <> "a") ref
c2 <- AVar.put "b" v1 $ traverse_ \_ -> void $ Ref.modify (_ <> "b") ref
_ <- AVar.put "c" v1 $ traverse_ \_ -> void $ Ref.modify (_ <> "c") ref
c1
c2
_ <- AVar.tryTake v1
_ <- AVar.tryTake v1
_ <- AVar.tryTake v1
v2 <- AVar.empty
_ <- AVar.take v2 $ traverse_ \_ -> void $ Ref.modify (_ <> "d") ref
c5 <- AVar.take v2 $ traverse_ \_ -> void $ Ref.modify (_ <> "e") ref
_ <- AVar.take v2 $ traverse_ \_ -> void $ Ref.modify (_ <> "f") ref
c5
_ <- AVar.tryPut "a" v2
_ <- AVar.tryPut "b" v2
_ <- AVar.tryPut "c" v2
v3 <- AVar.empty
_ <- AVar.read v3 $ traverse_ \_ -> void $ Ref.modify (_ <> "g") ref
c8 <- AVar.read v3 $ traverse_ \_ -> void $ Ref.modify (_ <> "h") ref
c9 <- AVar.read v3 $ traverse_ \_ -> void $ Ref.modify (_ <> "i") ref
c8
c9
_ <- AVar.tryPut "a" v3
eq "cdfg" <$> Ref.read ref
main :: Effect Unit
main = do
test_tryRead_full
test_tryRead_empty
test_tryPut_full
test_tryPut_empty
test_tryTake_full
test_tryTake_empty
test_put_take
test_put_read_take
test_take_put
test_take_read_put
test_read_put_take
test_read_take_put
test_kill_full
test_kill_empty
test_kill_pending
test_cancel