mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fixed linux unit tests.
Backed out change that registered quitkey as application scope. Beefed up tons of tests
This commit is contained in:
@@ -38,7 +38,7 @@ public class KeyBindings
|
||||
else
|
||||
{
|
||||
Bindings.Add (key, binding);
|
||||
if (binding.Scope.FastHasFlags (KeyBindingScope.Application))
|
||||
if (binding.Scope.HasFlag (KeyBindingScope.Application))
|
||||
{
|
||||
Application.AddKeyBinding (key, BoundView);
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ public class ScrollView : View
|
||||
return true;
|
||||
}
|
||||
|
||||
bool? result = InvokeKeyBindings (a, KeyBindingScope.HotKey);
|
||||
bool? result = InvokeKeyBindings (a, KeyBindingScope.HotKey | KeyBindingScope.Focused);
|
||||
|
||||
if (result is { })
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ public partial class Toplevel : View
|
||||
);
|
||||
|
||||
// Default keybindings for this view
|
||||
KeyBindings.Add (Application.QuitKey, KeyBindingScope.Application, Command.QuitToplevel);
|
||||
KeyBindings.Add (Application.QuitKey, Command.QuitToplevel);
|
||||
|
||||
KeyBindings.Add (Key.CursorRight, Command.NextView);
|
||||
KeyBindings.Add (Key.CursorDown, Command.NextView);
|
||||
@@ -119,7 +119,7 @@ public partial class Toplevel : View
|
||||
KeyBindings.Add (Key.Tab.WithShift.WithCtrl, Command.PreviousViewOrTop);
|
||||
|
||||
// TODO: Refresh Key should be configurable
|
||||
KeyBindings.Add (Key.F5, KeyBindingScope.Application, Command.Refresh);
|
||||
KeyBindings.Add (Key.F5, Command.Refresh);
|
||||
KeyBindings.Add (Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix
|
||||
KeyBindings.Add (Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Xunit.Abstractions;
|
||||
using Microsoft.VisualBasic;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
// Alias Console to MockConsole so we don't accidentally use Console
|
||||
|
||||
@@ -147,8 +148,12 @@ public class ApplicationTests
|
||||
Shutdown ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Init_ResetState_Resets_Properties ()
|
||||
[Theory]
|
||||
[InlineData (typeof (FakeDriver))]
|
||||
[InlineData (typeof (NetDriver))]
|
||||
[InlineData (typeof (WindowsDriver))]
|
||||
[InlineData (typeof (CursesDriver))]
|
||||
public void Init_ResetState_Resets_Properties (Type driverType)
|
||||
{
|
||||
ConfigurationManager.ThrowOnJsonErrors = true;
|
||||
|
||||
@@ -156,7 +161,7 @@ public class ApplicationTests
|
||||
|
||||
// Set some values
|
||||
|
||||
Application.Init ();
|
||||
Application.Init (driverName: driverType.Name);
|
||||
Application._initialized = true;
|
||||
|
||||
// Reset
|
||||
@@ -228,7 +233,7 @@ public class ApplicationTests
|
||||
Application.AlternateBackwardKey = Key.A;
|
||||
Application.AlternateForwardKey = Key.B;
|
||||
Application.QuitKey = Key.C;
|
||||
Application.AddKeyBinding(Key.A, new View ());
|
||||
Application.AddKeyBinding (Key.A, new View ());
|
||||
|
||||
//Application.OverlappedChildren = new List<View> ();
|
||||
//Application.OverlappedTop =
|
||||
@@ -266,6 +271,71 @@ public class ApplicationTests
|
||||
#endif
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (typeof (FakeDriver))]
|
||||
[InlineData (typeof (NetDriver))]
|
||||
[InlineData (typeof (WindowsDriver))]
|
||||
[InlineData (typeof (CursesDriver))]
|
||||
public void Init_Shutdown_Fire_InitializedChanged (Type driverType)
|
||||
{
|
||||
bool initialized = false;
|
||||
bool shutdown = false;
|
||||
|
||||
Application.InitializedChanged += OnApplicationOnInitializedChanged;
|
||||
|
||||
Application.Init (driverName: driverType.Name);
|
||||
Assert.True (initialized);
|
||||
Assert.False (shutdown);
|
||||
|
||||
Application.Shutdown ();
|
||||
Assert.True (initialized);
|
||||
Assert.True (shutdown);
|
||||
|
||||
Application.InitializedChanged -= OnApplicationOnInitializedChanged;
|
||||
|
||||
return;
|
||||
|
||||
void OnApplicationOnInitializedChanged (object s, StateEventArgs<bool> a)
|
||||
{
|
||||
if (a.NewValue)
|
||||
{
|
||||
initialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Run_Iteration_Fires ()
|
||||
{
|
||||
int iteration = 0;
|
||||
|
||||
Application.Init (new FakeDriver ());
|
||||
|
||||
Application.Iteration += Application_Iteration;
|
||||
Application.Run<Toplevel> ().Dispose ();
|
||||
|
||||
Assert.Equal (1, iteration);
|
||||
Application.Shutdown ();
|
||||
|
||||
return;
|
||||
|
||||
void Application_Iteration (object sender, IterationEventArgs e)
|
||||
{
|
||||
if (iteration > 0)
|
||||
{
|
||||
Assert.Fail ();
|
||||
}
|
||||
iteration++;
|
||||
Application.RequestStop ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Init_Unbalanced_Throws ()
|
||||
{
|
||||
@@ -826,10 +896,10 @@ public class ApplicationTests
|
||||
|
||||
Application.OnMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
|
||||
Assert.Equal (w.Border, Application.MouseGrabView);
|
||||
Assert.Equal (new Point (0,0), w.Frame.Location);
|
||||
Assert.Equal (new Point (0, 0), w.Frame.Location);
|
||||
|
||||
// Move down and to the right.
|
||||
Application.OnMouseEvent (new () { Position = new (1,1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
|
||||
Application.OnMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
|
||||
Assert.Equal (new Point (1, 1), w.Frame.Location);
|
||||
|
||||
Application.End (rs);
|
||||
@@ -1024,4 +1094,123 @@ public class ApplicationTests
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private object _timeoutLock;
|
||||
|
||||
[Fact]
|
||||
public void AddTimeout_Fires ()
|
||||
{
|
||||
Assert.Null (_timeoutLock);
|
||||
_timeoutLock = new object ();
|
||||
|
||||
uint timeoutTime = 250;
|
||||
bool initialized = false;
|
||||
int iteration = 0;
|
||||
bool shutdown = false;
|
||||
object timeout = null;
|
||||
int timeoutCount = 0;
|
||||
|
||||
Application.InitializedChanged += OnApplicationOnInitializedChanged;
|
||||
|
||||
Application.Init (new FakeDriver ());
|
||||
Assert.True (initialized);
|
||||
Assert.False (shutdown);
|
||||
|
||||
_output.WriteLine ("Application.Run<Toplevel> ().Dispose ()..");
|
||||
Application.Run<Toplevel> ().Dispose ();
|
||||
_output.WriteLine ("Back from Application.Run<Toplevel> ().Dispose ()");
|
||||
|
||||
Assert.True (initialized);
|
||||
Assert.False (shutdown);
|
||||
|
||||
Assert.Equal (1, timeoutCount);
|
||||
Application.Shutdown ();
|
||||
|
||||
Application.InitializedChanged -= OnApplicationOnInitializedChanged;
|
||||
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
if (timeout is { })
|
||||
{
|
||||
Application.RemoveTimeout (timeout);
|
||||
timeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True (initialized);
|
||||
Assert.True (shutdown);
|
||||
|
||||
#if DEBUG_IDISPOSABLE
|
||||
Assert.Empty (Responder.Instances);
|
||||
#endif
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
_timeoutLock = null;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
void OnApplicationOnInitializedChanged (object s, StateEventArgs<bool> a)
|
||||
{
|
||||
if (a.NewValue)
|
||||
{
|
||||
Application.Iteration += OnApplicationOnIteration;
|
||||
initialized = true;
|
||||
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
_output.WriteLine ($"Setting timeout for {timeoutTime}ms");
|
||||
timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (timeoutTime), TimeoutCallback);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Iteration -= OnApplicationOnIteration;
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool TimeoutCallback ()
|
||||
{
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
_output.WriteLine ($"TimeoutCallback. Count: {++timeoutCount}. Application Iteration: {iteration}");
|
||||
if (timeout is { })
|
||||
{
|
||||
_output.WriteLine ($" Nulling timeout.");
|
||||
timeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
// False means "don't re-do timer and remove it"
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnApplicationOnIteration (object s, IterationEventArgs a)
|
||||
{
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
if (timeoutCount > 0)
|
||||
{
|
||||
_output.WriteLine ($"Iteration #{iteration} - Timeout fired. Calling Application.RequestStop.");
|
||||
Application.RequestStop ();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
iteration++;
|
||||
|
||||
// Simulate a delay
|
||||
Thread.Sleep ((int)timeoutTime / 10);
|
||||
|
||||
// Worst case scenario - something went wrong
|
||||
if (Application._initialized && iteration > 25)
|
||||
{
|
||||
_output.WriteLine ($"Too many iterations ({iteration}): Calling Application.RequestStop.");
|
||||
Application.RequestStop ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Xunit.Abstractions;
|
||||
using UICatalog;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Terminal.Gui.ApplicationTests;
|
||||
|
||||
@@ -58,6 +59,123 @@ public class KeyboardTests
|
||||
top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QuitKey_Default_Is_CtrlQ ()
|
||||
{
|
||||
Application.ResetState (true);
|
||||
// Before Init
|
||||
Assert.Equal (Key.Empty, Application.QuitKey);
|
||||
|
||||
Application.Init (new FakeDriver ());
|
||||
// After Init
|
||||
Assert.Equal (Key.Q.WithCtrl, Application.QuitKey);
|
||||
|
||||
Application.Shutdown();
|
||||
}
|
||||
|
||||
private object _timeoutLock;
|
||||
|
||||
[Fact]
|
||||
public void QuitKey_Quits ()
|
||||
{
|
||||
Assert.Null (_timeoutLock);
|
||||
_timeoutLock = new object ();
|
||||
|
||||
uint abortTime = 500;
|
||||
bool initialized = false;
|
||||
int iteration = 0;
|
||||
bool shutdown = false;
|
||||
object timeout = null;
|
||||
|
||||
Application.InitializedChanged += OnApplicationOnInitializedChanged;
|
||||
|
||||
Application.Init (new FakeDriver ());
|
||||
Assert.True (initialized);
|
||||
Assert.False (shutdown);
|
||||
|
||||
_output.WriteLine ("Application.Run<Toplevel> ().Dispose ()..");
|
||||
Application.Run<Toplevel> ().Dispose ();
|
||||
_output.WriteLine ("Back from Application.Run<Toplevel> ().Dispose ()");
|
||||
|
||||
Assert.True (initialized);
|
||||
Assert.False (shutdown);
|
||||
|
||||
Assert.Equal (1, iteration);
|
||||
|
||||
Application.Shutdown ();
|
||||
|
||||
Application.InitializedChanged -= OnApplicationOnInitializedChanged;
|
||||
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
if (timeout is { })
|
||||
{
|
||||
Application.RemoveTimeout (timeout);
|
||||
timeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True (initialized);
|
||||
Assert.True (shutdown);
|
||||
|
||||
#if DEBUG_IDISPOSABLE
|
||||
Assert.Empty (Responder.Instances);
|
||||
#endif
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
_timeoutLock = null;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
void OnApplicationOnInitializedChanged (object s, StateEventArgs<bool> a)
|
||||
{
|
||||
_output.WriteLine ("OnApplicationOnInitializedChanged: {0}", a.NewValue);
|
||||
if (a.NewValue)
|
||||
{
|
||||
Application.Iteration += OnApplicationOnIteration;
|
||||
initialized = true;
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Iteration -= OnApplicationOnIteration;
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ForceCloseCallback ()
|
||||
{
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
_output.WriteLine ($"ForceCloseCallback. iteration: {iteration}");
|
||||
if (timeout is { })
|
||||
{
|
||||
timeout = null;
|
||||
}
|
||||
}
|
||||
Application.ResetState (true);
|
||||
Assert.Fail ($"Failed to Quit with {Application.QuitKey} after {abortTime}ms. Force quit.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnApplicationOnIteration (object s, IterationEventArgs a)
|
||||
{
|
||||
_output.WriteLine ("Iteration: {0}", iteration);
|
||||
iteration++;
|
||||
Assert.True (iteration < 2, "Too many iterations, something is wrong.");
|
||||
if (Application._initialized)
|
||||
{
|
||||
_output.WriteLine (" Pressing QuitKey");
|
||||
Application.OnKeyDown (Application.QuitKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AlternateForwardKey_AlternateBackwardKey_Tests ()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
// Alias Console to MockConsole so we don't accidentally use Console
|
||||
|
||||
@@ -619,16 +620,22 @@ public class MainLoopTests
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokeLeakTest ()
|
||||
[Theory]
|
||||
[InlineData (typeof (FakeDriver))]
|
||||
//[InlineData (typeof (NetDriver))] // BUGBUG: NetDriver never exits in this test
|
||||
|
||||
//[InlineData (typeof (ANSIDriver))]
|
||||
//[InlineData (typeof (WindowsDriver))] // BUGBUG: NetDriver never exits in this test
|
||||
//[InlineData (typeof (CursesDriver))] // BUGBUG: CursesDriver never exits in this test
|
||||
public async Task InvokeLeakTest (Type driverType)
|
||||
{
|
||||
Application.Init ();
|
||||
Application.Init (driverName: driverType.Name);
|
||||
Random r = new ();
|
||||
TextField tf = new ();
|
||||
var top = new Toplevel ();
|
||||
top.Add (tf);
|
||||
|
||||
const int numPasses = 5;
|
||||
const int numPasses = 2;
|
||||
const int numIncrements = 500;
|
||||
const int pollMs = 2500;
|
||||
|
||||
@@ -658,7 +665,8 @@ public class MainLoopTests
|
||||
int pfour
|
||||
)
|
||||
{
|
||||
Application.Init ();
|
||||
// TODO: Expand this test to test all drivers
|
||||
Application.Init (new FakeDriver());
|
||||
|
||||
total = 0;
|
||||
btn = null;
|
||||
|
||||
@@ -18,10 +18,14 @@ public class SyncrhonizationContextTests
|
||||
Application.Shutdown ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SynchronizationContext_Post ()
|
||||
[Theory]
|
||||
[InlineData (typeof (FakeDriver))]
|
||||
//[InlineData (typeof (NetDriver))]
|
||||
[InlineData (typeof (WindowsDriver))]
|
||||
//[InlineData (typeof (CursesDriver))]
|
||||
public void SynchronizationContext_Post (Type driverType)
|
||||
{
|
||||
Application.Init ();
|
||||
Application.Init (driverName: driverType.Name);
|
||||
SynchronizationContext context = SynchronizationContext.Current;
|
||||
|
||||
var success = false;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using Xunit.Abstractions;
|
||||
using static Terminal.Gui.ConfigurationManager;
|
||||
#pragma warning disable IDE1006
|
||||
|
||||
@@ -7,6 +8,13 @@ namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class ConfigurationManagerTests
|
||||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
public ConfigurationManagerTests (ITestOutputHelper output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
public static readonly JsonSerializerOptions _jsonOptions = new ()
|
||||
{
|
||||
Converters = { new AttributeJsonConverter (), new ColorJsonConverter () }
|
||||
@@ -402,6 +410,7 @@ public class ConfigurationManagerTests
|
||||
// Application is a static class
|
||||
PropertyInfo pi = typeof (Application).GetProperty ("QuitKey");
|
||||
Assert.Equal (pi, Settings ["Application.QuitKey"].PropertyInfo);
|
||||
|
||||
|
||||
// FrameView is not a static class and DefaultBorderStyle is Scope.Scheme
|
||||
pi = typeof (FrameView).GetProperty ("DefaultBorderStyle");
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ScenarioTests : TestsAllViews
|
||||
.Where (type => type.IsClass && !type.IsAbstract && type.IsSubclassOf (typeof (Scenario)))
|
||||
.Select (type => new object [] { type });
|
||||
|
||||
private readonly object _timeoutLock = new object ();
|
||||
private object _timeoutLock;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This runs through all Scenarios defined in UI Catalog, calling Init, Setup, and Run.</para>
|
||||
@@ -33,41 +33,27 @@ public class ScenarioTests : TestsAllViews
|
||||
[MemberData (nameof (AllScenarioTypes))]
|
||||
public void All_Scenarios_Quit_And_Init_Shutdown_Properly (Type scenarioType)
|
||||
{
|
||||
Assert.Null (_timeoutLock);
|
||||
_timeoutLock = new object ();
|
||||
|
||||
// If a previous test failed, this will ensure that the Application is in a clean state
|
||||
Application.ResetState (true);
|
||||
|
||||
_output.WriteLine ($"Running Scenario '{scenarioType}'");
|
||||
Scenario scenario = (Scenario)Activator.CreateInstance (scenarioType);
|
||||
|
||||
uint abortTime = 500;
|
||||
uint abortTime = 1500;
|
||||
bool initialized = false;
|
||||
bool shutdown = false;
|
||||
object timeout = null;
|
||||
|
||||
void OnApplicationOnInitializedChanged (object s, StateEventArgs<bool> a)
|
||||
{
|
||||
if (a.NewValue)
|
||||
{
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback);
|
||||
}
|
||||
|
||||
Application.Iteration += OnApplicationOnIteration;
|
||||
initialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Iteration -= OnApplicationOnIteration;
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
Application.InitializedChanged += OnApplicationOnInitializedChanged;
|
||||
|
||||
Application.ForceDriver = "FakeDriver";
|
||||
scenario.Main ();
|
||||
scenario.Dispose ();
|
||||
scenario = null;
|
||||
Application.ForceDriver = string.Empty;
|
||||
|
||||
Application.InitializedChanged -= OnApplicationOnInitializedChanged;
|
||||
|
||||
@@ -75,7 +61,6 @@ public class ScenarioTests : TestsAllViews
|
||||
{
|
||||
if (timeout is { })
|
||||
{
|
||||
Application.RemoveTimeout (timeout);
|
||||
timeout = null;
|
||||
}
|
||||
}
|
||||
@@ -87,8 +72,40 @@ public class ScenarioTests : TestsAllViews
|
||||
#if DEBUG_IDISPOSABLE
|
||||
Assert.Empty (Responder.Instances);
|
||||
#endif
|
||||
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
_timeoutLock = null;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
|
||||
void OnApplicationOnInitializedChanged (object s, StateEventArgs<bool> a)
|
||||
{
|
||||
if (a.NewValue)
|
||||
{
|
||||
Assert.Equal (Key.Q.WithCtrl, Application.QuitKey);
|
||||
|
||||
Application.Iteration += OnApplicationOnIteration;
|
||||
initialized = true;
|
||||
lock (_timeoutLock)
|
||||
{
|
||||
timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback);
|
||||
}
|
||||
_output.WriteLine ($"Initialized '{Application.Driver}'");
|
||||
//Dictionary<Key, List<View>> bindings = Application.GetKeyBindings ();
|
||||
//Assert.NotEmpty (bindings);
|
||||
//_output.WriteLine ($"bindings: {string.Join (",", bindings.Keys)}");
|
||||
//Assert.True (bindings.ContainsKey (Application.QuitKey));
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Iteration -= OnApplicationOnIteration;
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the scenario doesn't close within 500ms, this will force it to quit
|
||||
bool ForceCloseCallback ()
|
||||
{
|
||||
@@ -96,14 +113,13 @@ public class ScenarioTests : TestsAllViews
|
||||
{
|
||||
if (timeout is { })
|
||||
{
|
||||
Application.RemoveTimeout (timeout);
|
||||
timeout = null;
|
||||
}
|
||||
}
|
||||
Application.ResetState (true);
|
||||
Assert.Fail (
|
||||
$"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms. Force quit.");
|
||||
|
||||
Application.ResetState (true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -112,6 +128,7 @@ public class ScenarioTests : TestsAllViews
|
||||
if (Application._initialized)
|
||||
{
|
||||
// Press QuitKey
|
||||
//_output.WriteLine ($"Forcing Quit with {Application.QuitKey}");
|
||||
Application.OnKeyDown (Application.QuitKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +258,93 @@ public class ButtonTests (ITestOutputHelper output)
|
||||
Assert.True (clicked);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (false, 0)]
|
||||
[InlineData (true, 1)]
|
||||
public void Space_Fires_Accept (bool focused, int expected)
|
||||
{
|
||||
View superView = new View ()
|
||||
{
|
||||
CanFocus = true,
|
||||
};
|
||||
|
||||
Button button = new ();
|
||||
|
||||
button.CanFocus = focused;
|
||||
|
||||
int acceptInvoked = 0;
|
||||
button.Accept += (s, e) => acceptInvoked++;
|
||||
|
||||
superView.Add (button);
|
||||
button.SetFocus ();
|
||||
Assert.Equal (focused, button.HasFocus);
|
||||
|
||||
superView.NewKeyDownEvent (Key.Space);
|
||||
|
||||
Assert.Equal (expected, acceptInvoked);
|
||||
|
||||
superView.Dispose ();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (false, 0)]
|
||||
[InlineData (true, 1)]
|
||||
public void Enter_Fires_Accept (bool focused, int expected)
|
||||
{
|
||||
View superView = new View ()
|
||||
{
|
||||
CanFocus = true,
|
||||
};
|
||||
|
||||
Button button = new ();
|
||||
|
||||
button.CanFocus = focused;
|
||||
|
||||
int acceptInvoked = 0;
|
||||
button.Accept += (s, e) => acceptInvoked++;
|
||||
|
||||
superView.Add (button);
|
||||
button.SetFocus ();
|
||||
Assert.Equal (focused, button.HasFocus);
|
||||
|
||||
superView.NewKeyDownEvent (Key.Enter);
|
||||
|
||||
Assert.Equal (expected, acceptInvoked);
|
||||
|
||||
superView.Dispose ();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (false, 1)]
|
||||
[InlineData (true, 1)]
|
||||
public void HotKey_Fires_Accept (bool focused, int expected)
|
||||
{
|
||||
View superView = new View ()
|
||||
{
|
||||
CanFocus = true,
|
||||
};
|
||||
|
||||
Button button = new ()
|
||||
{
|
||||
HotKey = Key.A
|
||||
};
|
||||
|
||||
button.CanFocus = focused;
|
||||
|
||||
int acceptInvoked = 0;
|
||||
button.Accept += (s, e) => acceptInvoked++;
|
||||
|
||||
superView.Add (button);
|
||||
button.SetFocus ();
|
||||
Assert.Equal (focused, button.HasFocus);
|
||||
|
||||
superView.NewKeyDownEvent (Key.A);
|
||||
|
||||
Assert.Equal (expected, acceptInvoked);
|
||||
|
||||
superView.Dispose ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This test demonstrates how to change the activation key for Button as described in the README.md keyboard
|
||||
/// handling section
|
||||
@@ -279,7 +366,9 @@ public class ButtonTests (ITestOutputHelper output)
|
||||
top.Add (btn);
|
||||
Application.Begin (top);
|
||||
|
||||
// default keybinding is Space which results in keypress
|
||||
Assert.True (btn.HasFocus);
|
||||
|
||||
// default keybinding is Space which results in Command.Accept (when focused)
|
||||
Application.OnKeyDown (new ((KeyCode)' '));
|
||||
Assert.Equal (1, pressed);
|
||||
|
||||
@@ -292,8 +381,7 @@ public class ButtonTests (ITestOutputHelper output)
|
||||
Assert.Equal (1, pressed);
|
||||
|
||||
// Set a new binding of b for the click (Accept) event
|
||||
btn.KeyBindings.Add (Key.B, Command.HotKey);
|
||||
btn.KeyBindings.Add (Key.B, Command.Accept);
|
||||
btn.KeyBindings.Add (Key.B, Command.HotKey); // b will now trigger the Accept command (when focused or not)
|
||||
|
||||
// now pressing B should call the button click event
|
||||
Application.OnKeyDown (Key.B);
|
||||
|
||||
@@ -627,42 +627,40 @@ public class ToplevelTests (ITestOutputHelper output)
|
||||
Assert.Equal (win1, Application.Current);
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
win1.Running = true;
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.QuitKey));
|
||||
Assert.True (Application.OnKeyDown (Application.QuitKey));
|
||||
Assert.False (isRunning);
|
||||
Assert.False (win1.Running);
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
|
||||
Assert.True (
|
||||
Application.OverlappedChildren [0].NewKeyDownEvent (Key.Z.WithCtrl)
|
||||
Application.OnKeyDown (Key.Z.WithCtrl)
|
||||
);
|
||||
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.F5)); // refresh
|
||||
Assert.True (Application.OnKeyDown (Key.F5)); // refresh
|
||||
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
|
||||
Assert.True (Application.OnKeyDown (Key.Tab));
|
||||
Assert.True (win1.IsCurrentTop);
|
||||
Assert.Equal (tvW1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
|
||||
Assert.True (Application.OnKeyDown (Key.Tab));
|
||||
Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
|
||||
|
||||
Assert.True (
|
||||
Application.OverlappedChildren [0]
|
||||
.NewKeyDownEvent (Key.Tab.WithShift)
|
||||
Application.OnKeyDown (Key.Tab.WithShift)
|
||||
);
|
||||
Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text);
|
||||
|
||||
Assert.True (
|
||||
Application.OverlappedChildren [0]
|
||||
.NewKeyDownEvent (Key.Tab.WithCtrl)
|
||||
Application.OnKeyDown (Key.Tab.WithCtrl)
|
||||
);
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf2W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
|
||||
Assert.True (Application.OnKeyDown (Key.Tab));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorRight));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorRight));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorDown));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tvW1, win1.MostFocused);
|
||||
#if UNIX_KEY_BINDINGS
|
||||
@@ -676,13 +674,13 @@ public class ToplevelTests (ITestOutputHelper output)
|
||||
);
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tvW1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorLeft));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorLeft));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorUp));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorUp));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf2W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.Tab));
|
||||
Assert.True (Application.OnKeyDown (Key.Tab));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
|
||||
@@ -701,23 +699,23 @@ public class ToplevelTests (ITestOutputHelper output)
|
||||
);
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateForwardKey));
|
||||
Assert.True (Application.OnKeyDown (Application.AlternateForwardKey));
|
||||
Assert.Equal (win2, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf2W2, win2.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Application.AlternateBackwardKey));
|
||||
Assert.True (Application.OnKeyDown (Application.AlternateBackwardKey));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorDown));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tvW1, win1.MostFocused);
|
||||
#if UNIX_KEY_BINDINGS
|
||||
Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.B.WithCtrl)));
|
||||
#else
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorLeft));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorLeft));
|
||||
#endif
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf1W1, win1.MostFocused);
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorDown));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorDown));
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tvW1, win1.MostFocused);
|
||||
Assert.Equal (Point.Empty, tvW1.CursorPosition);
|
||||
@@ -732,7 +730,7 @@ public class ToplevelTests (ITestOutputHelper output)
|
||||
#if UNIX_KEY_BINDINGS
|
||||
Assert.True (Application.OverlappedChildren [0].ProcessKeyDown (new (Key.F.WithCtrl)));
|
||||
#else
|
||||
Assert.True (Application.OverlappedChildren [0].NewKeyDownEvent (Key.CursorRight));
|
||||
Assert.True (Application.OnKeyDown (Key.CursorRight));
|
||||
#endif
|
||||
Assert.Equal (win1, Application.OverlappedChildren [0]);
|
||||
Assert.Equal (tf2W1, win1.MostFocused);
|
||||
|
||||
Reference in New Issue
Block a user