@@ -10,6 +10,8 @@ open FSharp.Control
10
10
//
11
11
// TaskSeq.takeWhile
12
12
// TaskSeq.takeWhileAsync
13
+ // TaskSeq.takeWhileInclusive
14
+ // TaskSeq.takeWhileInclusiveAsync
13
15
//
14
16
15
17
module EmptySeq =
@@ -28,46 +30,61 @@ module EmptySeq =
28
30
|> Task.map ( List.isEmpty >> should be True)
29
31
30
32
// 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 }
35
42
|> TaskSeq.ofSeq
36
- |> TaskSeq.takeWhile ( fun x -> x <= 2 )
43
+ |> f ( fun x -> x <= 2 )
37
44
|> TaskSeq.map char
38
45
|> TaskSeq.map ((+) '@' )
39
46
|> TaskSeq.toArrayAsync
40
- |> Task.map ( String >> should equal " AB " )
47
+ |> Task.map ( String >> should equal expected )
41
48
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 })
46
57
|> TaskSeq.map char
47
58
|> TaskSeq.map ((+) '@' )
48
59
|> TaskSeq.toArrayAsync
49
- |> Task.map ( String >> should equal " AB " )
60
+ |> Task.map ( String >> should equal expected )
50
61
51
62
// 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" }
56
70
|> TaskSeq.ofSeq
57
- |> TaskSeq.takeWhile ( fun x -> x <= 2 )
71
+ |> f ( fun x -> x <= 2 )
58
72
|> TaskSeq.map char
59
73
|> TaskSeq.map ((+) '@' )
60
74
|> TaskSeq.toArrayAsync
61
- |> Task.map ( String >> should equal " AB " )
75
+ |> Task.map ( String >> should equal expected )
62
76
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 })
67
84
|> TaskSeq.map char
68
85
|> TaskSeq.map ((+) '@' )
69
86
|> TaskSeq.toArrayAsync
70
- |> Task.map ( String >> should equal " AB " )
87
+ |> Task.map ( String >> should equal expected )
71
88
72
89
// This is the base condition as one would expect in actual code
73
90
let inline cond x = x <> 6
0 commit comments