-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathTaskSeq.Filter.Tests.fs
More file actions
159 lines (129 loc) · 4.86 KB
/
TaskSeq.Filter.Tests.fs
File metadata and controls
159 lines (129 loc) · 4.86 KB
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
module TaskSeq.Tests.Filter
open Xunit
open FsUnit.Xunit
open FSharp.Control
//
// TaskSeq.filter
// TaskSeq.filterAsync
// TaskSeq.where
// TaskSeq.whereAsync
//
module EmptySeq =
[<Fact>]
let ``TaskSeq-filter or where with null source raises`` () =
assertNullArg
<| fun () -> TaskSeq.filter (fun _ -> false) null
assertNullArg
<| fun () -> TaskSeq.filterAsync (fun _ -> Task.fromResult false) null
assertNullArg
<| fun () -> TaskSeq.where (fun _ -> false) null
assertNullArg
<| fun () -> TaskSeq.whereAsync (fun _ -> Task.fromResult false) null
[<Theory; ClassData(typeof<TestEmptyVariants>)>]
let ``TaskSeq-filter or where has no effect`` variant = task {
do!
Gen.getEmptyVariant variant
|> TaskSeq.filter ((=) 12)
|> TaskSeq.toListAsync
|> Task.map (List.isEmpty >> should be True)
do!
Gen.getEmptyVariant variant
|> TaskSeq.where ((=) 12)
|> TaskSeq.toListAsync
|> Task.map (List.isEmpty >> should be True)
}
[<Theory; ClassData(typeof<TestEmptyVariants>)>]
let ``TaskSeq-filterAsync or whereAsync has no effect`` variant = task {
do!
Gen.getEmptyVariant variant
|> TaskSeq.filterAsync (fun x -> task { return x = 12 })
|> TaskSeq.toListAsync
|> Task.map (List.isEmpty >> should be True)
do!
Gen.getEmptyVariant variant
|> TaskSeq.whereAsync (fun x -> task { return x = 12 })
|> TaskSeq.toListAsync
|> Task.map (List.isEmpty >> should be True)
}
module Immutable =
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
let ``TaskSeq-filter or where filters correctly`` variant = task {
do!
Gen.getSeqImmutable variant
|> TaskSeq.filter ((<=) 5) // greater than
|> verifyDigitsAsString "EFGHIJ"
do!
Gen.getSeqImmutable variant
|> TaskSeq.where ((>) 5) // greater than
|> verifyDigitsAsString "ABCD"
}
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
let ``TaskSeq-filterAsync or whereAsync filters correctly`` variant = task {
do!
Gen.getSeqImmutable variant
|> TaskSeq.filterAsync (fun x -> task { return x <= 5 })
|> verifyDigitsAsString "ABCDE"
do!
Gen.getSeqImmutable variant
|> TaskSeq.whereAsync (fun x -> task { return x > 5 })
|> verifyDigitsAsString "FGHIJ"
}
module Immutable2 =
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
let ``TaskSeq-filter keeps all when predicate is always true`` variant =
Gen.getSeqImmutable variant
|> TaskSeq.filter (fun _ -> true)
|> verify1To10
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
let ``TaskSeq-filterAsync keeps all when predicate is always true`` variant =
Gen.getSeqImmutable variant
|> TaskSeq.filterAsync (fun _ -> Task.fromResult true)
|> verify1To10
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
let ``TaskSeq-filter returns empty when predicate is always false`` variant =
Gen.getSeqImmutable variant
|> TaskSeq.filter (fun _ -> false)
|> verifyEmpty
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
let ``TaskSeq-filterAsync returns empty when predicate is always false`` variant =
Gen.getSeqImmutable variant
|> TaskSeq.filterAsync (fun _ -> Task.fromResult false)
|> verifyEmpty
[<Fact>]
let ``TaskSeq-filter evaluates each element exactly once`` () = task {
let mutable count = 0
let ts = taskSeq {
for i in 1..5 do
count <- count + 1
yield i
}
let! xs =
ts
|> TaskSeq.filter (fun x -> x % 2 = 0)
|> TaskSeq.toListAsync
count |> should equal 5
xs |> should equal [ 2; 4 ]
}
module SideEffects =
[<Theory; ClassData(typeof<TestSideEffectTaskSeq>)>]
let ``TaskSeq-filter filters correctly`` variant = task {
do!
Gen.getSeqWithSideEffect variant
|> TaskSeq.filter ((<=) 5) // greater than or equal
|> verifyDigitsAsString "EFGHIJ"
do!
Gen.getSeqWithSideEffect variant
|> TaskSeq.where ((>) 5) // less than
|> verifyDigitsAsString "ABCD"
}
[<Theory; ClassData(typeof<TestSideEffectTaskSeq>)>]
let ``TaskSeq-filterAsync filters correctly`` variant = task {
do!
Gen.getSeqWithSideEffect variant
|> TaskSeq.filterAsync (fun x -> task { return x <= 5 })
|> verifyDigitsAsString "ABCDE"
do!
Gen.getSeqWithSideEffect variant
|> TaskSeq.whereAsync (fun x -> task { return x > 5 && x < 9 })
|> verifyDigitsAsString "FGH"
}