Skip to content

Commit 219f89d

Browse files
committed
Fix some naming and test comments in TaskSeq.exists tests
1 parent 15b9649 commit 219f89d

File tree

2 files changed

+91
-119
lines changed

2 files changed

+91
-119
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ module Immutable =
8282

8383
module SideEffects =
8484
[<Theory; ClassData(typeof<TestSideEffectTaskSeq>)>]
85-
let ``TaskSeq-exists KeyNotFoundException only sometimes for mutated state`` variant = task {
85+
let ``TaskSeq-exists success only sometimes for mutated state`` variant = task {
8686
let ts = Gen.getSeqWithSideEffect variant
8787
let finder = (=) 11
8888

@@ -100,7 +100,7 @@ module SideEffects =
100100
}
101101

102102
[<Theory; ClassData(typeof<TestSideEffectTaskSeq>)>]
103-
let ``TaskSeq-existsAsync KeyNotFoundException only sometimes for mutated state`` variant = task {
103+
let ``TaskSeq-existsAsync success only sometimes for mutated state`` variant = task {
104104
let ts = Gen.getSeqWithSideEffect variant
105105
let finder x = task { return x = 11 }
106106

@@ -201,7 +201,7 @@ module SideEffects =
201201
found |> should be True
202202
i |> should equal 0 // notice that it should be one higher if the statement after 'yield' is evaluated
203203

204-
// find some next item. We do get a new iterator, but mutable state is now starting at '1'
204+
// find some next item. We do get a new iterator, but mutable state is now still starting at '0'
205205
let! found = ts |> TaskSeq.exists ((=) 4)
206206
found |> should be True
207207
i |> should equal 4 // only partial evaluation!
@@ -221,7 +221,7 @@ module SideEffects =
221221
found |> should be True
222222
i |> should equal 0 // notice that it should be one higher if the statement after 'yield' is evaluated
223223

224-
// find some next item. We do get a new iterator, but mutable state is now starting at '1'
224+
// find some next item. We do get a new iterator, but mutable state is now still starting at '0'
225225
let! found = ts |> TaskSeq.existsAsync (fun x -> task { return x = 4 })
226226
found |> should be True
227227
i |> should equal 4 // only partial evaluation!
Lines changed: 87 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,122 @@
1-
module TaskSeq.Tests.Exists
1+
module TaskSeq.Tests.Forall
22

33
open Xunit
44
open FsUnit.Xunit
55

66
open FSharp.Control
77

88
//
9-
// TaskSeq.exists
10-
// TaskSeq.existsAsyncc
9+
// TaskSeq.forall
10+
// TaskSeq.forallAsyncc
1111
//
1212

1313
module EmptySeq =
1414
[<Fact>]
1515
let ``Null source is invalid`` () =
1616
assertNullArg
17-
<| fun () -> TaskSeq.exists (fun _ -> false) null
17+
<| fun () -> TaskSeq.forall (fun _ -> false) null
1818

1919
assertNullArg
20-
<| fun () -> TaskSeq.existsAsync (fun _ -> Task.fromResult false) null
20+
<| fun () -> TaskSeq.forallAsync (fun _ -> Task.fromResult false) null
2121

2222
[<Theory; ClassData(typeof<TestEmptyVariants>)>]
23-
let ``TaskSeq-exists returns false`` variant =
23+
let ``TaskSeq-forall always returns true`` variant =
2424
Gen.getEmptyVariant variant
25-
|> TaskSeq.exists ((=) 12)
26-
|> Task.map (should be False)
25+
|> TaskSeq.forall ((=) 12)
26+
|> Task.map (should be True)
2727

2828
[<Theory; ClassData(typeof<TestEmptyVariants>)>]
29-
let ``TaskSeq-existsAsync returns false`` variant =
29+
let ``TaskSeq-forallAsync always returns true`` variant =
3030
Gen.getEmptyVariant variant
31-
|> TaskSeq.existsAsync (fun x -> task { return x = 12 })
32-
|> Task.map (should be False)
33-
34-
module Immutable =
35-
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
36-
let ``TaskSeq-exists sad path returns false`` variant =
37-
Gen.getSeqImmutable variant
38-
|> TaskSeq.exists ((=) 0)
39-
|> Task.map (should be False)
40-
41-
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
42-
let ``TaskSeq-existsAsync sad path return false`` variant =
43-
Gen.getSeqImmutable variant
44-
|> TaskSeq.existsAsync (fun x -> task { return x = 0 })
45-
|> Task.map (should be False)
46-
47-
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
48-
let ``TaskSeq-exists happy path middle of seq`` variant =
49-
Gen.getSeqImmutable variant
50-
|> TaskSeq.exists (fun x -> x < 6 && x > 4)
51-
|> Task.map (should be True)
52-
53-
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
54-
let ``TaskSeq-existsAsync happy path middle of seq`` variant =
55-
Gen.getSeqImmutable variant
56-
|> TaskSeq.existsAsync (fun x -> task { return x < 6 && x > 4 })
31+
|> TaskSeq.forallAsync (fun x -> task { return x = 12 })
5732
|> Task.map (should be True)
5833

34+
module Immutable =
5935
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
60-
let ``TaskSeq-exists happy path first item of seq`` variant =
61-
Gen.getSeqImmutable variant
62-
|> TaskSeq.exists ((=) 1)
63-
|> Task.map (should be True)
36+
let ``TaskSeq-forall sad path returns false`` variant = task {
37+
do!
38+
Gen.getSeqImmutable variant
39+
|> TaskSeq.forall ((=) 0)
40+
|> Task.map (should be False)
41+
42+
do!
43+
Gen.getSeqImmutable variant
44+
|> TaskSeq.forall ((>) 9) // lt
45+
|> Task.map (should be False)
46+
}
6447

6548
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
66-
let ``TaskSeq-existsAsync happy path first item of seq`` variant =
67-
Gen.getSeqImmutable variant
68-
|> TaskSeq.existsAsync (fun x -> task { return x = 1 })
69-
|> Task.map (should be True)
49+
let ``TaskSeq-forallAsync sad path returns false`` variant = task {
50+
do!
51+
Gen.getSeqImmutable variant
52+
|> TaskSeq.forallAsync (fun x -> task { return x = 0 })
53+
|> Task.map (should be False)
54+
55+
do!
56+
Gen.getSeqImmutable variant
57+
|> TaskSeq.forallAsync (fun x -> task { return x < 9 })
58+
|> Task.map (should be False)
59+
}
7060

7161
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
72-
let ``TaskSeq-exists happy path last item of seq`` variant =
62+
let ``TaskSeq-forall happy path whole seq true`` variant =
7363
Gen.getSeqImmutable variant
74-
|> TaskSeq.exists ((=) 10)
64+
|> TaskSeq.forall (fun x -> x < 6 || x > 5)
7565
|> Task.map (should be True)
7666

7767
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
78-
let ``TaskSeq-existsAsync happy path last item of seq`` variant =
68+
let ``TaskSeq-forallAsync happy path whole seq true`` variant =
7969
Gen.getSeqImmutable variant
80-
|> TaskSeq.existsAsync (fun x -> task { return x = 10 })
70+
|> TaskSeq.forallAsync (fun x -> task { return x <= 10 && x >= 0 })
8171
|> Task.map (should be True)
8272

8373
module SideEffects =
8474
[<Theory; ClassData(typeof<TestSideEffectTaskSeq>)>]
85-
let ``TaskSeq-exists KeyNotFoundException only sometimes for mutated state`` variant = task {
75+
let ``TaskSeq-forall mutated state can change result`` variant = task {
8676
let ts = Gen.getSeqWithSideEffect variant
87-
let finder = (=) 11
77+
let predicate x = x > 10
8878

8979
// first: false
90-
let! found = TaskSeq.exists finder ts
91-
found |> should be False
80+
let! found = TaskSeq.forall predicate ts
81+
found |> should be False // fails on first item, not many side effects yet
82+
83+
// ensure side effects executes
84+
do! consumeTaskSeq ts
9285

9386
// find again: found now, because of side effects
94-
let! found = TaskSeq.exists finder ts
87+
let! found = TaskSeq.forall predicate ts
9588
found |> should be True
9689

97-
// find once more: false
98-
let! found = TaskSeq.exists finder ts
99-
found |> should be False
90+
// find once more, still true, as numbers increase
91+
do! consumeTaskSeq ts // ensure side effects executes
92+
let! found = TaskSeq.forall predicate ts
93+
found |> should be True
10094
}
10195

10296
[<Theory; ClassData(typeof<TestSideEffectTaskSeq>)>]
103-
let ``TaskSeq-existsAsync KeyNotFoundException only sometimes for mutated state`` variant = task {
97+
let ``TaskSeq-forallAsync mutated state can change result`` variant = task {
10498
let ts = Gen.getSeqWithSideEffect variant
105-
let finder x = task { return x = 11 }
99+
let predicate x = Task.fromResult (x > 10)
106100

107101
// first: false
108-
let! found = TaskSeq.existsAsync finder ts
109-
found |> should be False
102+
let! found = TaskSeq.forallAsync predicate ts
103+
found |> should be False // fails on first item, not many side effects yet
104+
105+
// ensure side effects executes
106+
do! consumeTaskSeq ts
110107

111108
// find again: found now, because of side effects
112-
let! found = TaskSeq.existsAsync finder ts
109+
let! found = TaskSeq.forallAsync predicate ts
113110
found |> should be True
114111

115-
// find once more: false
116-
let! found = TaskSeq.existsAsync finder ts
117-
found |> should be False
112+
// find once more, still true, as numbers increase
113+
do! consumeTaskSeq ts // ensure side effects executes
114+
let! found = TaskSeq.forallAsync predicate ts
115+
found |> should be True
118116
}
119117

120118
[<Fact>]
121-
let ``TaskSeq-exists _specialcase_ prove we don't read past the found item`` () = task {
119+
let ``TaskSeq-forall _specialcase_ prove we don't read past the first failing item`` () = task {
122120
let mutable i = 0
123121

124122
let ts = taskSeq {
@@ -127,18 +125,18 @@ module SideEffects =
127125
yield i
128126
}
129127

130-
let! found = ts |> TaskSeq.exists ((=) 3)
131-
found |> should be True
128+
let! found = ts |> TaskSeq.forall ((>) 3)
129+
found |> should be False
132130
i |> should equal 3 // only partial evaluation!
133131

134132
// find next item. We do get a new iterator, but mutable state is now starting at '3', so first item now returned is '4'.
135-
let! found = ts |> TaskSeq.exists ((=) 4)
133+
let! found = ts |> TaskSeq.forall ((<=) 4)
136134
found |> should be True
137-
i |> should equal 4 // only partial evaluation!
135+
i |> should equal 13 // we evaluated to the end
138136
}
139137

140138
[<Fact>]
141-
let ``TaskSeq-existsAsync _specialcase_ prove we don't read past the found item`` () = task {
139+
let ``TaskSeq-forallAsync _specialcase_ prove we don't read past the first failing item`` () = task {
142140
let mutable i = 0
143141

144142
let ts = taskSeq {
@@ -147,48 +145,22 @@ module SideEffects =
147145
yield i
148146
}
149147

150-
let! found = ts |> TaskSeq.existsAsync (fun x -> task { return x = 3 })
151-
found |> should be True
148+
let! found = ts |> TaskSeq.forallAsync (fun x -> Task.fromResult (x < 3))
149+
found |> should be False
152150
i |> should equal 3 // only partial evaluation!
153151

154152
// find next item. We do get a new iterator, but mutable state is now starting at '3', so first item now returned is '4'.
155-
let! found = ts |> TaskSeq.existsAsync (fun x -> task { return x = 4 })
156-
found |> should be True
157-
i |> should equal 4
158-
}
153+
let! found =
154+
ts
155+
|> TaskSeq.forallAsync (fun x -> Task.fromResult (x >= 4))
159156

160-
[<Fact>]
161-
let ``TaskSeq-exists _specialcase_ prove we don't read past the found item v2`` () = task {
162-
let mutable i = 0
163-
164-
let ts = taskSeq {
165-
yield 42
166-
i <- i + 1
167-
i <- i + 1
168-
}
169-
170-
let! found = ts |> TaskSeq.exists ((=) 42)
171157
found |> should be True
172-
i |> should equal 0 // because no MoveNext after found item, the last statements are not executed
158+
i |> should equal 13 // we evaluated to the end
173159
}
174160

175-
[<Fact>]
176-
let ``TaskSeq-existsAsync _specialcase_ prove we don't read past the found item v2`` () = task {
177-
let mutable i = 0
178-
179-
let ts = taskSeq {
180-
yield 42
181-
i <- i + 1
182-
i <- i + 1
183-
}
184-
185-
let! found = ts |> TaskSeq.existsAsync (fun x -> task { return x = 42 })
186-
found |> should be True
187-
i |> should equal 0 // because no MoveNext after found item, the last statements are not executed
188-
}
189161

190162
[<Fact>]
191-
let ``TaskSeq-exists _specialcase_ prove statement after yield is not evaluated`` () = task {
163+
let ``TaskSeq-forall _specialcase_ prove statement after first false result is not evaluated`` () = task {
192164
let mutable i = 0
193165

194166
let ts = taskSeq {
@@ -197,18 +169,18 @@ module SideEffects =
197169
i <- i + 1
198170
}
199171

200-
let! found = ts |> TaskSeq.exists ((=) 0)
201-
found |> should be True
202-
i |> should equal 0 // notice that it should be one higher if the statement after 'yield' is evaluated
172+
let! found = ts |> TaskSeq.forall ((>) 0)
173+
found |> should be False
174+
i |> should equal 0 // notice that it should be one higher if the statement after 'yield' was evaluated
203175

204-
// find some next item. We do get a new iterator, but mutable state is now starting at '1'
205-
let! found = ts |> TaskSeq.exists ((=) 4)
206-
found |> should be True
176+
// find some next item. We do get a new iterator, but mutable state is still starting at '0'
177+
let! found = ts |> TaskSeq.forall ((>) 4)
178+
found |> should be False
207179
i |> should equal 4 // only partial evaluation!
208180
}
209181

210182
[<Fact>]
211-
let ``TaskSeq-existsAsync _specialcase_ prove statement after yield is not evaluated`` () = task {
183+
let ``TaskSeq-forallAsync _specialcase_ prove statement after first false result is not evaluated`` () = task {
212184
let mutable i = 0
213185

214186
let ts = taskSeq {
@@ -217,12 +189,12 @@ module SideEffects =
217189
i <- i + 1
218190
}
219191

220-
let! found = ts |> TaskSeq.existsAsync (fun x -> task { return x = 0 })
221-
found |> should be True
222-
i |> should equal 0 // notice that it should be one higher if the statement after 'yield' is evaluated
192+
let! found = ts |> TaskSeq.forallAsync (fun x -> Task.fromResult (x < 0))
193+
found |> should be False
194+
i |> should equal 0 // notice that it should be one higher if the statement after 'yield' was evaluated
223195

224-
// find some next item. We do get a new iterator, but mutable state is now starting at '1'
225-
let! found = ts |> TaskSeq.existsAsync (fun x -> task { return x = 4 })
226-
found |> should be True
196+
// find some next item. We do get a new iterator, but mutable state is still starting at '0'
197+
let! found = ts |> TaskSeq.forallAsync (fun x -> Task.fromResult (x < 4))
198+
found |> should be False
227199
i |> should equal 4 // only partial evaluation!
228200
}

0 commit comments

Comments
 (0)