Skip to content

Commit a538c8c

Browse files
[WIP, fixup] Add integration tests
1 parent 2d7c0d2 commit a538c8c

File tree

4 files changed

+169
-2
lines changed

4 files changed

+169
-2
lines changed

devbox.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"test": [
1616
"cd tests/",
1717
"./run-tests.sh"
18+
],
19+
"integration": [
20+
"cd integration_tests",
21+
"./run-tests.sh"
1822
]
1923
}
2024
}

integration_tests/run-tests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
set -e
2+
3+
gren make src/Main.gren
4+
node app

integration_tests/src/Main.gren

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ module Main exposing ( .. )
44
{-|-}
55

66
import Test.Crypto as Crypto
7-
import Test.Runner.Effectful
7+
import Test.Task as Task
8+
import Test.Runner.Effectful exposing (concat)
89
import Node
910

1011

@@ -13,5 +14,10 @@ import Node
1314
main : Test.Runner.Effectful.Program a
1415
main =
1516
Node.defineSimpleProgram (\env ->
16-
Test.Runner.Effectful.run env Crypto.tests
17+
Test.Runner.Effectful.run env
18+
(concat
19+
[ Crypto.tests
20+
, Task.tests
21+
]
22+
)
1723
)

integration_tests/src/Test/Task.gren

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
module Test.Task exposing (tests)
2+
3+
{-| -}
4+
5+
import Array exposing (..)
6+
import Basics exposing (..)
7+
import Bytes exposing (Bytes)
8+
import Bytes.Decode
9+
import Crypto
10+
import Expect exposing (Expectation)
11+
import Math
12+
import Maybe exposing (Maybe(..))
13+
import Process
14+
import Task exposing (Task)
15+
import Test.Runner.Effectful exposing (await, awaitError, concat, describe, fuzz, run, test)
16+
import Time
17+
18+
19+
{-| -}
20+
tests : Test.Runner.Effectful.Test
21+
tests =
22+
describe "Task.concurrent"
23+
[ let
24+
durations : Array Float
25+
durations =
26+
Array.range 1 1000 |> Array.map toFloat
27+
in
28+
await
29+
(durations
30+
|> Array.map sleep
31+
|> Task.concurrent
32+
|> withDuration
33+
)
34+
"concurrent array of tasks"
35+
(\res ->
36+
concat
37+
[ test "preserves order of results"
38+
(\_ -> Expect.equal durations res.val)
39+
, test "runs tasks concurrently"
40+
(\_ -> expectDurationLessThan 2000 res)
41+
]
42+
)
43+
, await
44+
(Array.repeat 1000000 (sleep 10)
45+
|> Task.concurrent
46+
|> withDuration
47+
)
48+
"large concurrent array of tasks"
49+
(\res ->
50+
test "completes in reasonable time"
51+
(\_ -> expectDurationLessThan 2000 res)
52+
)
53+
, await
54+
(Task.map2 (++)
55+
(Task.map2 (++)
56+
(Task.concurrent
57+
[ sleep 30
58+
, sleep 40
59+
]
60+
)
61+
(Task.concurrent
62+
[ sleep 50
63+
, Task.map2 (+)
64+
(sleep 100)
65+
(sleep 100)
66+
]
67+
)
68+
)
69+
(Task.concurrent
70+
[ sleep 150
71+
, sleep 80
72+
]
73+
)
74+
|> withDuration
75+
)
76+
"deeply nested concurrent task"
77+
(\res ->
78+
concat
79+
[ test "runs deeply nested concurrent tasks at the same time"
80+
(\_ -> expectDurationLessThan 500 res)
81+
, test "preserves result order"
82+
(\_ -> Expect.equal [ 30, 40, 50, 200, 150, 80 ] res.val)
83+
]
84+
)
85+
]
86+
87+
88+
sleep : Float -> Task x Float
89+
sleep ms =
90+
Process.sleep ms |> Task.map (\_ -> ms)
91+
92+
93+
94+
-- Timing helpers
95+
96+
97+
type alias Timed a =
98+
{ start : Time.Posix
99+
, end : Time.Posix
100+
, val : a
101+
}
102+
103+
104+
expectDurationLessThan : Int -> Timed a -> Expectation
105+
expectDurationLessThan ms a =
106+
if duration a < ms then
107+
Expect.pass
108+
109+
else
110+
Expect.fail
111+
("Duration was: "
112+
++ String.fromInt (duration a)
113+
++ ", Expected less than: "
114+
++ String.fromInt ms
115+
++ "ms"
116+
)
117+
118+
119+
duration : Timed a -> Int
120+
duration timed =
121+
Time.posixToMillis timed.end - Time.posixToMillis timed.start
122+
123+
124+
withDuration : Task x a -> Task (Timed x) (Timed a)
125+
withDuration task =
126+
Time.now
127+
|> Task.andThen
128+
(\start ->
129+
task
130+
|> Task.onError
131+
(\e ->
132+
Time.now
133+
|> Task.andThen
134+
(\end ->
135+
Task.fail
136+
{ start = start
137+
, end = end
138+
, val = e
139+
}
140+
)
141+
)
142+
|> Task.andThen
143+
(\a ->
144+
Time.now
145+
|> Task.map
146+
(\end ->
147+
{ start = start
148+
, end = end
149+
, val = a
150+
}
151+
)
152+
)
153+
)

0 commit comments

Comments
 (0)