-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDisposableBaseTests.cs
More file actions
165 lines (136 loc) · 5.59 KB
/
DisposableBaseTests.cs
File metadata and controls
165 lines (136 loc) · 5.59 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
160
161
162
163
164
165
using System;
using Xunit;
using Platform.Exceptions;
namespace Platform.Disposables.Tests
{
public class DisposableBaseTests
{
private class TestDisposable : DisposableBase
{
public bool DisposeMethodCalled { get; private set; }
public bool DisposalWasManual { get; private set; }
public bool PreviouslyDisposed { get; private set; }
public int DisposeCallCount { get; private set; }
protected override void Dispose(bool manual, bool wasDisposed)
{
DisposeMethodCalled = true;
DisposalWasManual = manual;
PreviouslyDisposed = wasDisposed;
DisposeCallCount++;
}
}
private class TestDisposableAllowMultipleCalls : DisposableBase
{
public int DisposeCallCount { get; private set; }
protected override bool AllowMultipleDisposeCalls => true;
protected override void Dispose(bool manual, bool wasDisposed)
{
DisposeCallCount++;
}
}
private class TestDisposableAllowMultipleAttempts : DisposableBase
{
public int DisposeCallCount { get; private set; }
protected override bool AllowMultipleDisposeAttempts => true;
protected override bool AllowMultipleDisposeCalls => true; // Need this too to prevent exception
protected override void Dispose(bool manual, bool wasDisposed)
{
DisposeCallCount++;
}
}
[Fact]
public void Constructor_SetsIsDisposedToFalse()
{
using var disposable = new TestDisposable();
Assert.False(disposable.IsDisposed);
}
[Fact]
public void Dispose_CallsDisposeMethodWithManualTrue()
{
var disposable = new TestDisposable();
disposable.Dispose();
Assert.True(disposable.DisposeMethodCalled);
Assert.True(disposable.DisposalWasManual);
Assert.False(disposable.PreviouslyDisposed);
Assert.True(disposable.IsDisposed);
}
[Fact]
public void Dispose_MultipleCalls_ThrowsObjectDisposedException()
{
var disposable = new TestDisposable();
disposable.Dispose();
var exception = Assert.Throws<ObjectDisposedException>(() => disposable.Dispose());
Assert.Contains("Multiple dispose calls are not allowed", exception.Message);
}
[Fact]
public void Dispose_WithAllowMultipleDisposeCalls_DoesNotThrow()
{
var disposable = new TestDisposableAllowMultipleCalls();
disposable.Dispose();
disposable.Dispose(); // Should not throw
// AllowMultipleDisposeCalls only prevents exception, but without AllowMultipleDisposeAttempts,
// the Dispose method is only called once (when !wasDisposed)
Assert.Equal(1, disposable.DisposeCallCount);
}
[Fact]
public void Dispose_WithAllowMultipleDisposeAttempts_CallsDisposeMultipleTimes()
{
var disposable = new TestDisposableAllowMultipleAttempts();
disposable.Dispose();
disposable.Dispose();
Assert.Equal(2, disposable.DisposeCallCount);
}
[Fact]
public void Destruct_CallsDisposeMethodWithManualFalse()
{
var disposable = new TestDisposable();
disposable.Destruct();
Assert.True(disposable.DisposeMethodCalled);
Assert.False(disposable.DisposalWasManual);
Assert.False(disposable.PreviouslyDisposed);
Assert.True(disposable.IsDisposed);
}
[Fact]
public void Destruct_WhenAlreadyDisposed_DoesNotCallDispose()
{
var disposable = new TestDisposable();
disposable.Dispose();
disposable.Destruct(); // Should not call dispose again
Assert.Equal(1, disposable.DisposeCallCount);
}
[Fact]
public void ObjectName_ReturnsTypeName()
{
var disposable = new TestDisposable();
// ObjectName is protected, so we can't access it directly, but we can test indirectly
// by causing a multiple dispose exception and checking the object name in the exception
disposable.Dispose();
var exception = Assert.Throws<ObjectDisposedException>(() => disposable.Dispose());
Assert.Equal(nameof(TestDisposable), exception.ObjectName);
}
[Fact]
public void IsDisposed_ReturnsTrueAfterDispose()
{
var disposable = new TestDisposable();
Assert.False(disposable.IsDisposed);
disposable.Dispose();
Assert.True(disposable.IsDisposed);
}
[Fact]
public void IsDisposed_ReturnsTrueAfterDestruct()
{
var disposable = new TestDisposable();
Assert.False(disposable.IsDisposed);
disposable.Destruct();
Assert.True(disposable.IsDisposed);
}
[Fact]
public void Dispose_WithWasDisposedTrue_PassesCorrectFlag()
{
var disposable = new TestDisposableAllowMultipleAttempts();
disposable.Dispose(); // First call: wasDisposed = false
disposable.Dispose(); // Second call: wasDisposed = true
Assert.Equal(2, disposable.DisposeCallCount);
}
}
}