Skip to content

Commit 400584a

Browse files
committed
Cover inclusive variants
1 parent 8894fed commit 400584a

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

src/FSharp.Control.TaskSeq.Test/TaskSeq.TakeWhile.Tests.fs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ open FSharp.Control
1010
//
1111
// TaskSeq.takeWhile
1212
// TaskSeq.takeWhileAsync
13+
// TaskSeq.takeWhileInclusive
14+
// TaskSeq.takeWhileInclusiveAsync
1315
//
1416

1517
module EmptySeq =
@@ -28,46 +30,61 @@ module EmptySeq =
2830
|> Task.map (List.isEmpty >> should be True)
2931

3032
// The primary requirement is that items after the item failing the predicate must be excluded
31-
module TakeWhileExcludesEverythingAfterFail =
32-
[<Fact>]
33-
let ``TaskSeq-takeWhile excludes all items after predicate fails`` () =
34-
seq { 1; 2; 2; 3; 2; 1 }
33+
module FiltersAfterFail =
34+
[<Theory; InlineData false; InlineData true>]
35+
let ``TaskSeq-takeWhile(Inclusive)? excludes all items after predicate fails`` inclusive =
36+
// The only real difference in semantics between the base and the *Inclusive variant lies in whether the final item is returned
37+
// NOTE the semantics are very clear on only propagating a single failing item in the inclusive case
38+
let f, expected =
39+
if inclusive then TaskSeq.takeWhileInclusive, "ABBC"
40+
else TaskSeq.takeWhile, "ABB"
41+
seq { 1; 2; 2; 3; 3; 2; 1 }
3542
|> TaskSeq.ofSeq
36-
|> TaskSeq.takeWhile (fun x -> x <= 2)
43+
|> f (fun x -> x <= 2)
3744
|> TaskSeq.map char
3845
|> TaskSeq.map ((+) '@')
3946
|> TaskSeq.toArrayAsync
40-
|> Task.map (String >> should equal "AB")
47+
|> Task.map (String >> should equal expected)
4148

42-
[<Fact>]
43-
let ``TaskSeq-takeWhileAsync excludes all items after after predicate fails`` () =
44-
taskSeq { 1; 2; 2; 3; 2; 1 }
45-
|> TaskSeq.takeWhileAsync (fun x -> task { return x <= 2 })
49+
// Same as preceding test, just with Async functions
50+
[<Theory; InlineData false; InlineData true>]
51+
let ``TaskSeq-takeWhile(Inclusive)?Async excludes all items after after predicate fails`` inclusive =
52+
let f, expected =
53+
if inclusive then TaskSeq.takeWhileInclusiveAsync, "ABBC"
54+
else TaskSeq.takeWhileAsync, "ABB"
55+
taskSeq { 1; 2; 2; 3; 3; 2; 1 }
56+
|> f (fun x -> task { return x <= 2 })
4657
|> TaskSeq.map char
4758
|> TaskSeq.map ((+) '@')
4859
|> TaskSeq.toArrayAsync
49-
|> Task.map (String >> should equal "AB")
60+
|> Task.map (String >> should equal expected)
5061

5162
// Covers the fact that it's not sufficient to merely exclude successor items - it's also critical that the enumeration terminates
52-
module TakeWhileTerminatesOnFail =
53-
[<Fact>]
54-
let ``TaskSeq-takeWhile stops consuming after predicate fails`` () =
55-
seq { 1; 2; 3; failwith "Too far" }
63+
module StopsEnumeratingAfterFail =
64+
[<Theory; InlineData false; InlineData true>]
65+
let ``TaskSeq-takeWhile(Inclusive)? stops consuming after predicate fails`` inclusive =
66+
let f, expected =
67+
if inclusive then TaskSeq.takeWhileInclusive, "ABBC"
68+
else TaskSeq.takeWhile, "ABB"
69+
seq { 1; 2; 2; 3; 3; failwith "Too far" }
5670
|> TaskSeq.ofSeq
57-
|> TaskSeq.takeWhile (fun x -> x <= 2)
71+
|> f (fun x -> x <= 2)
5872
|> TaskSeq.map char
5973
|> TaskSeq.map ((+) '@')
6074
|> TaskSeq.toArrayAsync
61-
|> Task.map (String >> should equal "AB")
75+
|> Task.map (String >> should equal expected)
6276

63-
[<Fact>]
64-
let ``TaskSeq-takeWhileAsync stops consuming after predicate fails`` () =
65-
taskSeq { 1; 2; 3; failwith "Too far" }
66-
|> TaskSeq.takeWhileAsync (fun x -> task { return x <= 2 })
77+
[<Theory; InlineData false; InlineData true>]
78+
let ``TaskSeq-takeWhile(Inclusive)?Async stops consuming after predicate fails`` inclusive =
79+
let f, expected =
80+
if inclusive then TaskSeq.takeWhileInclusiveAsync, "ABBC"
81+
else TaskSeq.takeWhileAsync, "ABB"
82+
taskSeq { 1; 2; 2; 3; 3; failwith "Too far" }
83+
|> f (fun x -> task { return x <= 2 })
6784
|> TaskSeq.map char
6885
|> TaskSeq.map ((+) '@')
6986
|> TaskSeq.toArrayAsync
70-
|> Task.map (String >> should equal "AB")
87+
|> Task.map (String >> should equal expected)
7188

7289
// This is the base condition as one would expect in actual code
7390
let inline cond x = x <> 6

0 commit comments

Comments
 (0)