Skip to content

Commit 5f855b2

Browse files
committed
Improve tests to ensure the Dispose/DisposeAsync is actually called
1 parent 7179648 commit 5f855b2

File tree

1 file changed

+38
-29
lines changed

1 file changed

+38
-29
lines changed

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

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,88 +10,97 @@ open Xunit
1010
type private OneGetter() =
1111
member _.Get1() = 1
1212

13-
type private Disposable() =
13+
type private Disposable(disposed: bool ref) =
1414
inherit OneGetter()
1515

1616
interface IDisposable with
17-
member _.Dispose() = ()
17+
member _.Dispose() = disposed.Value <- true
1818

19-
type private AsyncDisposable() =
19+
type private AsyncDisposable(disposed: bool ref) =
2020
inherit OneGetter()
2121

2222
interface IAsyncDisposable with
23-
member _.DisposeAsync() = ValueTask()
23+
member _.DisposeAsync() = ValueTask(task { do disposed.Value <- true })
2424

25-
type private MultiDispose() =
25+
type private MultiDispose(disposed: int ref) =
2626
inherit OneGetter()
2727

2828
interface IDisposable with
29-
member _.Dispose() =
30-
()
29+
member _.Dispose() = disposed.Value <- !disposed + 1
3130

3231
interface IAsyncDisposable with
33-
member _.DisposeAsync() =
34-
ValueTask()
32+
member _.DisposeAsync() = ValueTask(task { do disposed.Value <- !disposed + 1 })
3533

36-
let private check ts = task {
37-
let! length = ts |> TaskSeq.length
38-
length |> should equal 1
39-
}
34+
let private check = TaskSeq.length >> Task.map (should equal 1)
4035

4136
[<Fact>]
42-
let ``CE task: Using when type implements IDisposable``() =
43-
let ts = taskSeq {
44-
use x = new Disposable()
37+
let ``CE task: Using when type implements IDisposable`` () =
38+
let disposed = ref false
4539

40+
let ts = taskSeq {
41+
use x = new Disposable(disposed)
4642
yield x.Get1()
4743
}
4844

4945
check ts
46+
|> Task.map (fun _ -> disposed.Value |> should be True)
5047

5148
[<Fact>]
52-
let ``CE task: Using when type implements IAsyncDisposable``() =
49+
let ``CE task: Using when type implements IAsyncDisposable`` () =
50+
let disposed = ref false
51+
5352
let ts = taskSeq {
54-
use x = AsyncDisposable()
53+
use x = AsyncDisposable(disposed)
5554
yield x.Get1()
5655
}
5756

5857
check ts
59-
58+
|> Task.map (fun _ -> disposed.Value |> should be True)
6059

6160
[<Fact>]
62-
let ``CE task: Using when type implements IDisposable and IAsyncDisposable``() =
61+
let ``CE task: Using when type implements IDisposable and IAsyncDisposable`` () =
62+
let disposed = ref 0
63+
6364
let ts = taskSeq {
64-
use x = new MultiDispose() // Fails to compile
65+
use x = new MultiDispose(disposed) // Used to fail to compile (see #97)
6566
yield x.Get1()
6667
}
6768

6869
check ts
70+
|> Task.map (fun _ -> disposed.Value |> should equal 1) // only one of the two dispose method should fire
6971

7072
[<Fact>]
71-
let ``CE task: Using! when type implements IDisposable``() =
73+
let ``CE task: Using! when type implements IDisposable`` () =
74+
let disposed = ref false
75+
7276
let ts = taskSeq {
73-
use! x = task { return new Disposable() }
77+
use! x = task { return new Disposable(disposed) }
7478
yield x.Get1()
7579
}
7680

7781
check ts
78-
82+
|> Task.map (fun _ -> disposed.Value |> should be True)
7983

8084
[<Fact>]
81-
let ``CE task: Using! when type implements IAsyncDisposable``() =
85+
let ``CE task: Using! when type implements IAsyncDisposable`` () =
86+
let disposed = ref false
87+
8288
let ts = taskSeq {
83-
use! x = task { return AsyncDisposable() }
89+
use! x = task { return AsyncDisposable(disposed) }
8490
yield x.Get1()
8591
}
8692

8793
check ts
88-
94+
|> Task.map (fun _ -> disposed.Value |> should be True)
8995

9096
[<Fact>]
91-
let ``CE task: Using! when type implements IDisposable and IAsyncDisposable``() =
97+
let ``CE task: Using! when type implements IDisposable and IAsyncDisposable`` () =
98+
let disposed = ref 0
99+
92100
let ts = taskSeq {
93-
use! x = task { return new MultiDispose() } // Fails to compile
101+
use! x = task { return new MultiDispose(disposed) } // Used to fail to compile (see #97)
94102
yield x.Get1()
95103
}
96104

97105
check ts
106+
|> Task.map (fun _ -> disposed.Value |> should equal 1) // only one of the two dispose method should fire

0 commit comments

Comments
 (0)