Skip to content

Commit 5f1ec87

Browse files
Merge pull request #48 from andrewMacmurray/helpers
Add speed and time related helpers
2 parents baabc41 + 69373de commit 5f1ec87

File tree

9 files changed

+438
-355
lines changed

9 files changed

+438
-355
lines changed

integration/src/Integration/Spec.elm

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,18 @@ module Integration.Spec exposing
77
, assertSuccess
88
, describe
99
, describeUnexpected
10-
, duration
1110
, fail
1211
, failWith
1312
, pass
1413
, report
1514
, shouldBeFasterThan
1615
, shouldEqual
1716
, shouldHaveDurationLessThan
18-
, timeExecution
1917
)
2018

2119
import ConcurrentTask as Task exposing (ConcurrentTask, UnexpectedError)
2220
import ConcurrentTask.Time
2321
import Console
24-
import Time
2522

2623

2724
{-| Task Spec
@@ -99,66 +96,27 @@ assertAll xs =
9996

10097

10198

102-
-- Time a Task
99+
-- Timed expectations
103100

104101

105-
type alias Timed a =
106-
{ start : Time.Posix
107-
, finish : Time.Posix
108-
, result : a
109-
}
110-
111-
112-
timeExecution : ConcurrentTask x a -> ConcurrentTask (Timed x) (Timed a)
113-
timeExecution task =
114-
ConcurrentTask.Time.now
115-
|> Task.andThen
116-
(\start ->
117-
task
118-
|> Task.onError
119-
(\x ->
120-
ConcurrentTask.Time.now
121-
|> Task.andThen
122-
(\finish ->
123-
Task.fail
124-
{ start = start
125-
, finish = finish
126-
, result = x
127-
}
128-
)
129-
)
130-
|> Task.andThen
131-
(\a ->
132-
ConcurrentTask.Time.now
133-
|> Task.map
134-
(\finish ->
135-
{ start = start
136-
, finish = finish
137-
, result = a
138-
}
139-
)
140-
)
141-
)
142-
143-
144-
shouldHaveDurationLessThan : Int -> Timed a -> Expect
102+
shouldHaveDurationLessThan : Int -> ConcurrentTask.Time.Duration a -> Expect
145103
shouldHaveDurationLessThan ms a =
146-
if duration a < ms then
104+
if ConcurrentTask.Time.duration a < ms then
147105
Pass
148106

149107
else
150108
Fail
151109
("Duration was: "
152-
++ String.fromInt (duration a)
110+
++ String.fromInt (ConcurrentTask.Time.duration a)
153111
++ ", Expected less than: "
154112
++ String.fromInt ms
155113
++ "ms"
156114
)
157115

158116

159-
shouldBeFasterThan : Timed b -> Timed a -> Expect
117+
shouldBeFasterThan : ConcurrentTask.Time.Duration b -> ConcurrentTask.Time.Duration a -> Expect
160118
shouldBeFasterThan b a =
161-
if duration a < duration b then
119+
if ConcurrentTask.Time.duration a < ConcurrentTask.Time.duration b then
162120
Pass
163121

164122
else
@@ -174,11 +132,6 @@ shouldEqual a b =
174132
Fail ("\n Expected: " ++ Debug.toString a ++ ",\n Got: " ++ Debug.toString b)
175133

176134

177-
duration : Timed a -> Int
178-
duration timed =
179-
Time.posixToMillis timed.finish - Time.posixToMillis timed.start
180-
181-
182135
describe :
183136
String
184137
-> String

integration/src/Main.elm

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ specs =
4141
[ largeBatchSpec
4242
, batchAndSequenceSpec
4343
, complexResponseSpec
44+
, raceSpec
45+
, raceFailSpec
46+
, raceQuickFailSpec
47+
, withTimeoutQuickSpec
48+
, withTimeoutSlowSpec
4449
, missingFunctionSpec
4550
, httpJsonBodySpec
4651
, httpHeadersSpec
@@ -71,7 +76,7 @@ largeBatchSpec =
7176
Spec.describe
7277
"large batches"
7378
"large batches should complete in reasonable time"
74-
(Spec.timeExecution
79+
(ConcurrentTask.Time.withDuration
7580
(ConcurrentTask.Process.sleep 100
7681
|> List.repeat batchSize
7782
|> Task.batch
@@ -81,7 +86,7 @@ largeBatchSpec =
8186
(\res ->
8287
Spec.assertAll
8388
[ Spec.shouldHaveDurationLessThan 5000 res
84-
, res.result |> Spec.shouldEqual (List.repeat batchSize ())
89+
, res.value |> Spec.shouldEqual (List.repeat batchSize ())
8590
]
8691
)
8792
)
@@ -93,7 +98,7 @@ batchAndSequenceSpec =
9398
"batch and sequence speed"
9499
"the batched branch should be faster than the sequential branch"
95100
(Task.map2 Tuple.pair
96-
(Spec.timeExecution
101+
(ConcurrentTask.Time.withDuration
97102
(Task.batch
98103
[ longRequest 100
99104
, longRequest 100
@@ -102,7 +107,7 @@ batchAndSequenceSpec =
102107
]
103108
)
104109
)
105-
(Spec.timeExecution
110+
(ConcurrentTask.Time.withDuration
106111
(Task.sequence
107112
[ longRequest 100
108113
, longRequest 100
@@ -116,7 +121,7 @@ batchAndSequenceSpec =
116121
(\( batched, sequential ) ->
117122
Spec.assertAll
118123
[ batched |> Spec.shouldBeFasterThan sequential
119-
, batched.result |> Spec.shouldEqual sequential.result
124+
, batched.value |> Spec.shouldEqual sequential.value
120125
]
121126
)
122127
)
@@ -181,6 +186,82 @@ complexResponseSpec =
181186
)
182187

183188

189+
raceSpec : Spec
190+
raceSpec =
191+
Spec.describe
192+
"racing tasks"
193+
"should return the fastest task to complete"
194+
(Task.race (longRequest 300)
195+
[ longRequest 1300
196+
, longRequest 600
197+
, longRequest 42
198+
, longRequest 900
199+
]
200+
)
201+
(Spec.assertSuccess
202+
(Spec.shouldEqual "done:42")
203+
)
204+
205+
206+
raceFailSpec : Spec
207+
raceFailSpec =
208+
Spec.describe
209+
"racing tasks with some failures"
210+
"should return the fastest task to complete even if later tasks will fail"
211+
(Task.race (longRequestWithFail 300)
212+
[ longRequest 42
213+
, longRequestWithFail 1300
214+
, longRequestWithFail 600
215+
, longRequestWithFail 900
216+
]
217+
)
218+
(Spec.assertSuccess
219+
(Spec.shouldEqual "done:42")
220+
)
221+
222+
223+
raceQuickFailSpec : Spec
224+
raceQuickFailSpec =
225+
Spec.describe
226+
"racing tasks with a fast failure"
227+
"should return the fastest task to fail"
228+
(Task.race (longRequestWithFail 100)
229+
[ longRequest 600
230+
, longRequest 300
231+
, longRequest 500
232+
]
233+
)
234+
(Spec.assertError
235+
(Spec.shouldEqual (Http.BadUrl "100"))
236+
)
237+
238+
239+
withTimeoutQuickSpec : Spec
240+
withTimeoutQuickSpec =
241+
Spec.describe
242+
"withTimeout quick"
243+
"should return the task value if the task completes before the timeout"
244+
(longRequest 300
245+
|> ConcurrentTask.Process.withTimeout 1000 "timeout"
246+
)
247+
(Spec.assertSuccess
248+
(Spec.shouldEqual "done:300")
249+
)
250+
251+
252+
withTimeoutSlowSpec : Spec
253+
withTimeoutSlowSpec =
254+
Spec.describe
255+
"withTimeout slow"
256+
"should return the timeout value if the task doesn't complete before the timeout"
257+
(longRequest 1000
258+
|> ConcurrentTask.Process.withTimeout 300 "timeout"
259+
)
260+
(Spec.assertSuccess
261+
(Spec.shouldEqual "timeout")
262+
)
263+
264+
184265
missingFunctionSpec : Spec
185266
missingFunctionSpec =
186267
Spec.describeUnexpected
@@ -329,7 +410,7 @@ httpTimeoutSpec =
329410
Spec.describe
330411
"http timeout"
331412
"http requests should abort if request takes longer than given timeout"
332-
(Spec.timeExecution
413+
(ConcurrentTask.Time.withDuration
333414
(Http.get
334415
{ url = waitThenRespond 10000
335416
, headers = []
@@ -341,7 +422,7 @@ httpTimeoutSpec =
341422
(Spec.assertError
342423
(\err ->
343424
Spec.assertAll
344-
[ Spec.shouldEqual Http.Timeout err.result
425+
[ Spec.shouldEqual Http.Timeout err.value
345426
, err |> Spec.shouldHaveDurationLessThan 3000 -- account for test flake
346427
]
347428
)
@@ -510,6 +591,11 @@ longRequest ms =
510591
}
511592

512593

594+
longRequestWithFail : Int -> ConcurrentTask Http.Error a
595+
longRequestWithFail ms =
596+
longRequest ms |> Task.andThen (\_ -> Task.fail (Http.BadUrl (String.fromInt ms)))
597+
598+
513599
waitThenRespond : Int -> String
514600
waitThenRespond ms =
515601
baseUrl ++ "/wait-then-respond/" ++ String.fromInt ms

0 commit comments

Comments
 (0)