-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathTaskSeq.Let.Tests.fs
152 lines (127 loc) · 3.78 KB
/
TaskSeq.Let.Tests.fs
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
module TaskSeq.Tests.Let
open System.Threading.Tasks
open FsUnit
open Xunit
open FSharp.Control
[<Fact>]
let ``CE taskSeq: use 'let'`` () =
let mutable value = 0
taskSeq {
let value1 = value + 1
let value2 = value1 + 1
yield value2
}
|> TaskSeq.exactlyOne
|> Task.map (should equal 2)
[<Fact>]
let ``CE taskSeq: use 'let!' with a task<unit>`` () =
let mutable value = 0
taskSeq {
let! unit' = task { do value <- value + 1 }
do unit'
}
|> verifyEmpty
|> Task.map (fun _ -> value |> should equal 1)
[<Fact>]
let ``CE taskSeq: use 'let!' with a task<string>`` () =
taskSeq {
let! test = task { return "test" }
yield test
}
|> TaskSeq.exactlyOne
|> Task.map (should equal "test")
[<Fact>]
let ``CE taskSeq: use 'let!' with a ValueTask<unit>`` () =
let mutable value = 0
taskSeq {
let! unit' = ValueTask.ofTask (task { do value <- value + 1 })
do unit'
}
|> verifyEmpty
|> Task.map (fun _ -> value |> should equal 1)
[<Fact>]
let ``CE taskSeq: use 'let!' with a ValueTask<string>`` () =
taskSeq {
let! test = ValueTask.ofTask (task { return "test" })
yield test
}
|> TaskSeq.exactlyOne
|> Task.map (should equal "test")
[<Fact>]
let ``CE taskSeq: use 'let!' with a non-generic ValueTask`` () =
let mutable value = 0
taskSeq {
let! unit' = ValueTask(task { do value <- value + 1 })
do unit'
}
|> verifyEmpty
|> Task.map (fun _ -> value |> should equal 1)
[<Fact>]
let ``CE taskSeq: use 'let!' with a non-generic task`` () =
let mutable value = 0
taskSeq {
let! unit' = (task { do value <- value + 1 }) |> Task.ignore
do unit'
}
|> verifyEmpty
|> Task.map (fun _ -> value |> should equal 1)
[<Fact>]
let ``CE taskSeq: use 'let!' with Async`` () =
let mutable value = 0
taskSeq {
do value <- value + 1
let! _ = Async.Sleep 50
do value <- value + 1
}
|> verifyEmpty
|> Task.map (fun _ -> value |> should equal 2)
[<Fact>]
let ``CE taskSeq: use 'let!' with Async - mutables`` () =
let mutable value = 0
taskSeq {
do! async { value <- value + 1 }
do value |> should equal 1
let! x = async { return value + 1 }
do x |> should equal 2
do! Async.Sleep 50
do! async { value <- value + 1 }
do value |> should equal 2
let! ret = async { return value + 1 }
do value |> should equal 2
do ret |> should equal 3
yield x + ret // eq 5
}
|> TaskSeq.exactlyOne
|> Task.map (should equal 5)
[<Fact>]
let ``CE taskSeq: use 'let!' with all kinds of overloads at once`` () =
let mutable value = 0
// this test should be expanded in case any new overload is added
// that is supported by `let!`, to ensure the high/low priority
// overloads still work properly
taskSeq {
let! a = task { // eq 1
do! Task.Delay 10
do value <- value + 1
return value
}
let! b = // eq 2
task {
do! Task.Delay 50
do value <- value + 1
return value
}
|> ValueTask<int>
let! c = ValueTask<_>(4) // ValueTask that completes immediately
let! _ = Task.Factory.StartNew(fun () -> value <- value + 1) // non-generic Task with side effect
let! d = Task.fromResult 99 // normal Task that completes immediately
let! _ = Async.Sleep 0 // unit Async
let! e = async {
do! Async.Sleep 40
do value <- value + 1 // eq 4 now
return value
}
yield! [ a; b; c; d; e ]
}
|> TaskSeq.toListAsync
|> Task.map (should equal [ 1; 2; 4; 99; 4 ])