Skip to content

Commit 639e2a6

Browse files
committed
Add tests for do and do! and cleanup some helper functions
1 parent 0399f2e commit 639e2a6

File tree

5 files changed

+69
-14
lines changed

5 files changed

+69
-14
lines changed

src/FSharp.Control.TaskSeq.Test/FSharp.Control.TaskSeq.Test.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Compile Include="TaskSeq.Realworld.fs" />
4949
<Compile Include="TaskSeq.AsyncExtensions.Tests.fs" />
5050
<Compile Include="TaskSeq.TaskExtensions.Tests.fs" />
51+
<Compile Include="TaskSeq.Do.Tests.fs" />
5152
<Compile Include="TaskSeq.Using.Tests.fs" />
5253
<Compile Include="Program.fs" />
5354
</ItemGroup>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module TaskSeq.Tests.Do
2+
3+
open System
4+
open System.Threading.Tasks
5+
open FsUnit
6+
open Xunit
7+
8+
open FSharp.Control
9+
10+
[<Fact>]
11+
let ``CE taskSeq: use 'do'`` () =
12+
let mutable value = 0
13+
14+
taskSeq { do value <- value + 1 }
15+
16+
|> verifyEmpty
17+
18+
[<Fact>]
19+
let ``CE taskSeq: use 'do!' with a task<unit>`` () =
20+
let mutable value = 0
21+
22+
taskSeq { do! task { do value <- value + 1 } }
23+
24+
|> verifyEmpty
25+
26+
//[<Fact>]
27+
//let ``CE taskSeq: use 'do!' with a valuetask<unit>`` () =
28+
// let mutable value = 0
29+
30+
// taskSeq { do! ValueTask.ofIValueTaskSource (task { do value <- value + 1 }) }
31+
32+
// |> verifyEmpty
33+
34+
//[<Fact>]
35+
//let ``CE taskSeq: use 'do!' with a non-generic valuetask`` () =
36+
// let mutable value = 0
37+
38+
// taskSeq { do! ValueTask(task { do value <- value + 1 }) }
39+
40+
// |> verifyEmpty
41+
42+
//[<Fact>]
43+
//let ``CE taskSeq: use 'do!' with a non-generic task`` () =
44+
// let mutable value = 0
45+
46+
// taskSeq { do! (task { do value <- value + 1 }) |> Task.ignore }
47+
48+
// |> verifyEmpty

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module FSharp.Control.TaskSeq.Test
1+
module TaskSeq.Test.Using
22

33
open System
44
open System.Threading.Tasks
@@ -34,7 +34,7 @@ type private MultiDispose(disposed: int ref) =
3434
let private check = TaskSeq.length >> Task.map (should equal 1)
3535

3636
[<Fact>]
37-
let ``CE task: Using when type implements IDisposable`` () =
37+
let ``CE taskSeq: Using when type implements IDisposable`` () =
3838
let disposed = ref false
3939

4040
let ts = taskSeq {
@@ -46,7 +46,7 @@ let ``CE task: Using when type implements IDisposable`` () =
4646
|> Task.map (fun _ -> disposed.Value |> should be True)
4747

4848
[<Fact>]
49-
let ``CE task: Using when type implements IAsyncDisposable`` () =
49+
let ``CE taskSeq: Using when type implements IAsyncDisposable`` () =
5050
let disposed = ref false
5151

5252
let ts = taskSeq {
@@ -58,7 +58,7 @@ let ``CE task: Using when type implements IAsyncDisposable`` () =
5858
|> Task.map (fun _ -> disposed.Value |> should be True)
5959

6060
[<Fact>]
61-
let ``CE task: Using when type implements IDisposable and IAsyncDisposable`` () =
61+
let ``CE taskSeq: Using when type implements IDisposable and IAsyncDisposable`` () =
6262
let disposed = ref 0
6363

6464
let ts = taskSeq {
@@ -70,7 +70,7 @@ let ``CE task: Using when type implements IDisposable and IAsyncDisposable`` ()
7070
|> Task.map (fun _ -> disposed.Value |> should equal -1) // should prefer IAsyncDisposable, which returns -1
7171

7272
[<Fact>]
73-
let ``CE task: Using! when type implements IDisposable`` () =
73+
let ``CE taskSeq: Using! when type implements IDisposable`` () =
7474
let disposed = ref false
7575

7676
let ts = taskSeq {
@@ -82,7 +82,7 @@ let ``CE task: Using! when type implements IDisposable`` () =
8282
|> Task.map (fun _ -> disposed.Value |> should be True)
8383

8484
[<Fact>]
85-
let ``CE task: Using! when type implements IAsyncDisposable`` () =
85+
let ``CE taskSeq: Using! when type implements IAsyncDisposable`` () =
8686
let disposed = ref false
8787

8888
let ts = taskSeq {
@@ -94,7 +94,7 @@ let ``CE task: Using! when type implements IAsyncDisposable`` () =
9494
|> Task.map (fun _ -> disposed.Value |> should be True)
9595

9696
[<Fact>]
97-
let ``CE task: Using! when type implements IDisposable and IAsyncDisposable`` () =
97+
let ``CE taskSeq: Using! when type implements IDisposable and IAsyncDisposable`` () =
9898
let disposed = ref 0
9999

100100
let ts = taskSeq {

src/FSharp.Control.TaskSeq.Test/TestUtils.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,13 @@ type DummyTaskFactory(µsecMin: int64<µs>, µsecMax: int64<µs>) =
136136

137137
[<AutoOpen>]
138138
module TestUtils =
139+
/// Verifies that a task sequence is empty by converting to an array and checking emptiness.
139140
let verifyEmpty ts =
140141
ts
141142
|> TaskSeq.toArrayAsync
142143
|> Task.map (Array.isEmpty >> should be True)
143144

145+
/// Verifies that a task sequence contains integers 1-10, by converting to an array and comparing.
144146
let verify1To10 ts =
145147
ts
146148
|> TaskSeq.toArrayAsync

src/FSharp.Control.TaskSeq/Utils.fs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ module ValueTask =
2828
/// Creates a ValueTask with an IValueTaskSource representing the operation
2929
let inline ofIValueTaskSource taskSource version = ValueTask<bool>(taskSource, version)
3030

31+
/// Creates a ValueTask form a Task<'T>
32+
let inline ofTask (task: Task<'T>) = ValueTask<'T>(task)
33+
34+
/// Ignore a ValueTask<'T>, returns a non-generic ValueTask.
35+
let inline ignore (vtask: ValueTask<'T>) =
36+
if vtask.IsCompleted then
37+
ValueTask()
38+
else
39+
ValueTask(vtask.AsTask())
40+
3141
module Task =
3242
/// Convert an Async<'T> into a Task<'T>
3343
let inline ofAsync (async: Async<'T>) = task { return! async }
@@ -41,22 +51,16 @@ module Task =
4151
/// Convert a Task<'T> into an Async<'T>
4252
let inline toAsync (task: Task<'T>) = Async.AwaitTask task
4353

44-
/// Convert a Task<unit> into a Task
45-
let inline toTask (task: Task<unit>) = task :> Task
46-
4754
/// Convert a Task<'T> into a ValueTask<'T>
4855
let inline toValueTask (task: Task<'T>) = ValueTask<'T> task
4956

50-
/// Convert a Task<unit> into a non-generic ValueTask
51-
let inline toIgnoreValueTask (task: Task<unit>) = ValueTask(task :> Task)
52-
5357
/// <summary>
5458
/// Convert a ValueTask&lt;'T> to a Task&lt;'T>. To use a non-generic ValueTask,
5559
/// consider using: <paramref name="myValueTask |> Task.ofValueTask |> Task.ofTask" />.
5660
/// </summary>
5761
let inline ofValueTask (valueTask: ValueTask<'T>) = task { return! valueTask }
5862

59-
/// Convert a Task<'T> into a Task, ignoring the result
63+
/// Convert a Task<'T> into a non-generic Task, ignoring the result
6064
let inline ignore (task: Task<'T>) =
6165
TaskBuilder.task {
6266
let! _ = task

0 commit comments

Comments
 (0)