Skip to content

Commit 8ea6b10

Browse files
authored
Fixes gui-cs#2923. Ensures only clear Instances if they really was disposed. (gui-cs#2924)
* Fixes gui-cs#2923. Ensures only clear Instances if they really was disposed and fix unit tests. * Add Ubuntu-20.04. * xunit nuget package update.
1 parent 56a31f1 commit 8ea6b10

File tree

8 files changed

+52
-43
lines changed

8 files changed

+52
-43
lines changed

Terminal.Gui/Input/Responder.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
using System;
1717
using System.Collections.Generic;
18-
using System.Diagnostics;
18+
using System.Linq;
1919
using System.Reflection;
2020

2121
namespace Terminal.Gui {
@@ -256,7 +256,7 @@ internal static bool IsOverridden (Responder subclass, string method)
256256
}
257257
return m.GetBaseDefinition ().DeclaringType != m.DeclaringType;
258258
}
259-
259+
260260
/// <summary>
261261
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
262262
/// </summary>
@@ -266,7 +266,7 @@ internal static bool IsOverridden (Responder subclass, string method)
266266
/// can be disposed.
267267
/// If disposing equals false, the method has been called by the
268268
/// runtime from inside the finalizer and you should not reference
269-
/// other objects. Only unmanaged resources can be disposed.
269+
/// other objects. Only unmanaged resources can be disposed.
270270
/// </remarks>
271271
/// <param name="disposing"></param>
272272
protected virtual void Dispose (bool disposing)
@@ -276,13 +276,10 @@ protected virtual void Dispose (bool disposing)
276276
// TODO: dispose managed state (managed objects)
277277
}
278278

279-
#if DEBUG_IDISPOSABLE
280-
Instances.Remove (this);
281-
#endif
282279
disposedValue = true;
283280
}
284281
}
285-
282+
286283
/// <summary>
287284
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource.
288285
/// </summary>
@@ -293,6 +290,10 @@ public void Dispose ()
293290
GC.SuppressFinalize (this);
294291
#if DEBUG_IDISPOSABLE
295292
WasDisposed = true;
293+
294+
foreach (var instance in Instances.Where (x => x.WasDisposed).ToList ()) {
295+
Instances.Remove (instance);
296+
}
296297
#endif
297298
}
298299
}

UnitTests/Application/ApplicationTests.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ public void Init_Shutdown_Cleans_Up ()
7777
// Validate there are no outstanding Responder-based instances
7878
// after a scenario was selected to run. This proves the main UI Catalog
7979
// 'app' closed cleanly.
80-
//foreach (var inst in Responder.Instances) {
81-
//Assert.True (inst.WasDisposed);
82-
//}
80+
Assert.Empty (Responder.Instances);
8381
#endif
8482
}
8583

UnitTests/Input/ResponderTests.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ public void Dispose_Works ()
5454
#endif
5555

5656
r.Dispose ();
57-
57+
#if DEBUG_IDISPOSABLE
58+
Assert.Empty (Responder.Instances);
59+
#endif
5860
}
5961

6062
public class DerivedView : View {

UnitTests/TestHelpers.cs

+13-8
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,13 @@ public override void Before (MethodInfo methodUnderTest)
6262
{
6363
Debug.WriteLine ($"Before: {methodUnderTest.Name}");
6464
if (AutoInit) {
65-
#if DEBUG_IDISPOSABLE && FORCE_RESPONDER_DISPOSE
65+
#if DEBUG_IDISPOSABLE
6666
// Clear out any lingering Responder instances from previous tests
67-
Responder.Instances.Clear ();
68-
Assert.Equal (0, Responder.Instances.Count);
67+
if (Responder.Instances.Count == 0) {
68+
Assert.Empty (Responder.Instances);
69+
} else {
70+
Responder.Instances.Clear ();
71+
}
6972
#endif
7073
Application.Init ((ConsoleDriver)Activator.CreateInstance (_driverType));
7174
}
@@ -76,8 +79,12 @@ public override void After (MethodInfo methodUnderTest)
7679
Debug.WriteLine ($"After: {methodUnderTest.Name}");
7780
if (AutoInit) {
7881
Application.Shutdown ();
79-
#if DEBUG_IDISPOSABLE && FORCE_RESPONDER_DISPOSE
80-
Assert.Equal (0, Responder.Instances.Count);
82+
#if DEBUG_IDISPOSABLE
83+
if (Responder.Instances.Count == 0) {
84+
Assert.Empty (Responder.Instances);
85+
} else {
86+
Responder.Instances.Clear ();
87+
}
8188
#endif
8289
}
8390
}
@@ -104,9 +111,7 @@ public override void After (MethodInfo methodUnderTest)
104111
{
105112
Debug.WriteLine ($"After: {methodUnderTest.Name}");
106113
#if DEBUG_IDISPOSABLE
107-
#pragma warning disable xUnit2013 // Do not use equality check to check for collection size.
108-
Assert.Equal (0, Responder.Instances.Count);
109-
#pragma warning restore xUnit2013 // Do not use equality check to check for collection size.
114+
Assert.Empty (Responder.Instances);
110115
#endif
111116
}
112117
}

UnitTests/UICatalog/ScenarioTests.cs

+17-23
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,11 @@ public void Run_All_Scenarios ()
105105

106106
Application.Shutdown ();
107107
#if DEBUG_IDISPOSABLE
108-
foreach (var inst in Responder.Instances) {
109-
Assert.True (inst.WasDisposed);
110-
}
111-
Responder.Instances.Clear ();
108+
Assert.Empty (Responder.Instances);
112109
#endif
113110
}
114111
#if DEBUG_IDISPOSABLE
115-
foreach (var inst in Responder.Instances) {
116-
Assert.True (inst.WasDisposed);
117-
}
118-
Responder.Instances.Clear ();
112+
Assert.Empty (Responder.Instances);
119113
#endif
120114
}
121115

@@ -132,11 +126,24 @@ public void Run_Generic ()
132126
// BUGBUG: (#2474) For some reason ReadKey is not returning the QuitKey for some Scenarios
133127
// by adding this Space it seems to work.
134128

135-
FakeConsole.PushMockKeyPress (Key.Space);
136129
FakeConsole.PushMockKeyPress (Application.QuitKey);
137130

131+
var ms = 100;
132+
var abortCount = 0;
133+
Func<MainLoop, bool> abortCallback = (MainLoop loop) => {
134+
abortCount++;
135+
output.WriteLine ($"'Generic' abortCount {abortCount}");
136+
Application.RequestStop ();
137+
return false;
138+
};
139+
138140
int iterations = 0;
141+
object token = null;
139142
Application.Iteration = () => {
143+
if (token == null) {
144+
// Timeout only must start at first iteration
145+
token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback);
146+
}
140147
iterations++;
141148
output.WriteLine ($"'Generic' iteration {iterations}");
142149
// Stop if we run out of control...
@@ -146,16 +153,6 @@ public void Run_Generic ()
146153
}
147154
};
148155

149-
var ms = 100;
150-
var abortCount = 0;
151-
Func<MainLoop, bool> abortCallback = (MainLoop loop) => {
152-
abortCount++;
153-
output.WriteLine ($"'Generic' abortCount {abortCount}");
154-
Application.RequestStop ();
155-
return false;
156-
};
157-
var token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback);
158-
159156
Application.Top.KeyPress += (object sender, KeyEventEventArgs args) => {
160157
// See #2474 for why this is commented out
161158
Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key);
@@ -175,10 +172,7 @@ public void Run_Generic ()
175172
Application.Shutdown ();
176173

177174
#if DEBUG_IDISPOSABLE
178-
foreach (var inst in Responder.Instances) {
179-
Assert.True (inst.WasDisposed);
180-
}
181-
Responder.Instances.Clear ();
175+
Assert.Empty (Responder.Instances);
182176
#endif
183177
}
184178

UnitTests/UnitTests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<PackageReference Include="ReportGenerator" Version="5.1.26" />
2626
<PackageReference Include="System.Collections" Version="4.3.0" />
2727
<PackageReference Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="19.2.69" />
28-
<PackageReference Include="xunit" Version="2.5.2" />
28+
<PackageReference Include="xunit" Version="2.5.3" />
2929
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
3030
<PrivateAssets>all</PrivateAssets>
3131
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

UnitTests/Views/OverlappedTests.cs

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public void Dispose_Toplevel_IsOverlappedContainer_False_With_Begin_End ()
3232

3333
Application.End (rs);
3434
Application.Shutdown ();
35+
36+
#if DEBUG_IDISPOSABLE
37+
Assert.Empty (Responder.Instances);
38+
#endif
3539
}
3640

3741
[Fact, TestRespondersDisposed]

testenvironments.json

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
"type": "wsl",
1111
"wslDistribution": "Ubuntu"
1212
},
13+
{
14+
"name": "WSL-Ubuntu-20.04",
15+
"type": "wsl",
16+
"wslDistribution": "Ubuntu-20.04"
17+
},
1318
{
1419
"name": "WSL-Debian",
1520
"type": "wsl",

0 commit comments

Comments
 (0)