Merge branch 'v2_develop' into fs

This commit is contained in:
Thomas Nind
2023-03-17 21:13:56 +00:00
committed by GitHub
57 changed files with 524 additions and 216 deletions

View File

@@ -560,16 +560,16 @@ namespace Terminal.Gui.ApplicationTests {
var input = "Tests";
// Put a control-q in at the end
Console.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true));
FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true));
foreach (var c in input.Reverse ()) {
if (char.IsLetter (c)) {
Console.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false));
FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false));
} else {
Console.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false));
FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false));
}
}
int stackSize = Console.MockKeyPresses.Count;
int stackSize = FakeConsole.MockKeyPresses.Count;
int iterations = 0;
Application.Iteration = () => {

View File

@@ -121,7 +121,7 @@ namespace Terminal.Gui.DriverTests {
var rText = "";
var idx = 0;
view.KeyPress += (e) => {
top.KeyPress += (e) => {
Assert.Equal (text [idx], (char)e.KeyEvent.Key);
rText += (char)e.KeyEvent.Key;
Assert.Equal (rText, text.Substring (0, idx + 1));
@@ -142,6 +142,63 @@ namespace Terminal.Gui.DriverTests {
Application.Shutdown ();
}
//[Theory]
//[InlineData (typeof (FakeDriver))]
//public void FakeDriver_MockKeyPresses_Press_AfterTimeOut (Type driverType)
//{
// var driver = (ConsoleDriver)Activator.CreateInstance (driverType);
// Application.Init (driver);
// // Simulating pressing of QuitKey after a short period of time
// uint quitTime = 100;
// Func<MainLoop, bool> closeCallback = (MainLoop loop) => {
// // Prove the scenario is using Application.QuitKey correctly
// output.WriteLine ($" {quitTime}ms elapsed; Simulating keypresses...");
// FakeConsole.PushMockKeyPress (Key.F);
// FakeConsole.PushMockKeyPress (Key.U);
// FakeConsole.PushMockKeyPress (Key.C);
// FakeConsole.PushMockKeyPress (Key.K);
// return false;
// };
// output.WriteLine ($"Add timeout to simulate key presses after {quitTime}ms");
// _ = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (quitTime), closeCallback);
// // If Top doesn't quit within abortTime * 5 (500ms), this will force it
// uint abortTime = quitTime * 5;
// Func<MainLoop, bool> forceCloseCallback = (MainLoop loop) => {
// Application.RequestStop ();
// Assert.Fail ($" failed to Quit after {abortTime}ms. Force quit.");
// return false;
// };
// output.WriteLine ($"Add timeout to force quit after {abortTime}ms");
// _ = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback);
// Key key = Key.Unknown;
// Application.Top.KeyPress += (e) => {
// key = e.KeyEvent.Key;
// output.WriteLine ($" Application.Top.KeyPress: {key}");
// e.Handled = true;
// };
// int iterations = 0;
// Application.Iteration += () => {
// output.WriteLine ($" iteration {++iterations}");
// if (Console.MockKeyPresses.Count == 0) {
// output.WriteLine ($" No more MockKeyPresses; RequestStop");
// Application.RequestStop ();
// }
// };
// Application.Run ();
// // Shutdown must be called to safely clean up Application if Init has been called
// Application.Shutdown ();
//}
[Theory]
[InlineData (typeof (FakeDriver))]
public void TerminalResized_Simulation (Type driverType)
@@ -319,7 +376,7 @@ namespace Terminal.Gui.DriverTests {
Application.Shutdown ();
}
[Fact, AutoInitShutdown]
public void AddRune_On_Clip_Left_Or_Right_Replace_Previous_Or_Next_Wide_Rune_With_Space ()
{
@@ -441,7 +498,7 @@ namespace Terminal.Gui.DriverTests {
}
private static object packetLock = new object ();
/// <summary>
/// Sometimes when using remote tools EventKeyRecord sends 'virtual keystrokes'.
/// These are indicated with the wVirtualKeyCode of 231. When we see this code

View File

@@ -123,7 +123,7 @@ namespace Terminal.Gui.DriverTests {
Assert.Equal ("Y, CtrlMask", key.ToString ());
// This will be well compared, because the Key.CtrlMask have a high value.
Assert.False (key == (Key.Q | Key.CtrlMask));
Assert.False (key == Application.QuitKey);
switch (key) {
case Key.Q | Key.CtrlMask:
// Never goes here.

View File

@@ -640,8 +640,8 @@ namespace Terminal.Gui.MenuTests {
win.Add (label, tf);
var statusBar = new StatusBar (new StatusItem [] {
new StatusItem(Key.F1, "~F1~ Help", null),
new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
new StatusItem (Key.F1, "~F1~ Help", null),
new StatusItem (Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
});
Application.Top.Add (menu, win, statusBar);

View File

@@ -157,7 +157,7 @@ namespace Terminal.Gui.TopLevelTests {
}
[Fact, AutoInitShutdown]
public void MessageBox_With_A_Label_Without_Spaces ()
public void MessageBox_With_A_Label_Without_Spaces_WrapMessagge_True ()
{
var iterations = -1;
Application.Begin (Application.Top);
@@ -196,8 +196,7 @@ namespace Terminal.Gui.TopLevelTests {
│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│
│ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff│
│ [◦ ok ◦] │
└──────────────────────────────────────────────────────────────────────────────┘
", output);
└──────────────────────────────────────────────────────────────────────────────┘", output);
Application.RequestStop ();
}
@@ -207,7 +206,7 @@ namespace Terminal.Gui.TopLevelTests {
}
[Fact, AutoInitShutdown]
public void MessageBox_With_A_Label_With_Spaces ()
public void MessageBox_With_A_Label_With_Spaces_WrapMessagge_True ()
{
var iterations = -1;
Application.Begin (Application.Top);
@@ -250,8 +249,102 @@ namespace Terminal.Gui.TopLevelTests {
│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │
│ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff │
│ [◦ ok ◦] │
└──────────────────────────────────────────────────────────────────────────────┘
", output);
└──────────────────────────────────────────────────────────────────────────────┘", output);
Application.RequestStop ();
}
};
Application.Run ();
}
[Fact, AutoInitShutdown]
public void MessageBox_With_A_Label_Without_Spaces_WrapMessagge_False ()
{
var iterations = -1;
Application.Begin (Application.Top);
Application.Iteration += () => {
iterations++;
if (iterations == 0) {
MessageBox.Query ("mywindow", new string ('f', 2000), 0, null, false, "ok");
Application.RequestStop ();
} else if (iterations == 1) {
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
────────────────────────────────────────────────────────────────────────────────
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[◦ ok ◦]
────────────────────────────────────────────────────────────────────────────────", output);
Application.RequestStop ();
}
};
Application.Run ();
}
[Fact, AutoInitShutdown]
public void MessageBox_With_A_Label_With_Spaces_WrapMessagge_False ()
{
var iterations = -1;
Application.Begin (Application.Top);
Application.Iteration += () => {
iterations++;
if (iterations == 0) {
var sb = new StringBuilder ();
for (int i = 0; i < 1000; i++)
sb.Append ("ff ");
MessageBox.Query ("mywindow", sb.ToString (), 0, null, false, "ok");
Application.RequestStop ();
} else if (iterations == 1) {
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
────────────────────────────────────────────────────────────────────────────────
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff f
[◦ ok ◦]
────────────────────────────────────────────────────────────────────────────────", output);
Application.RequestStop ();
}
};
Application.Run ();
}
[Theory, AutoInitShutdown]
[InlineData ("", true)]
[InlineData ("", false)]
[InlineData ("\n", true)]
[InlineData ("\n", false)]
public void MessageBox_With_A_Empty_Message_Or_A_NewLline_WrapMessagge_True_Or_False (string message, bool wrapMessage)
{
var iterations = -1;
Application.Begin (Application.Top);
Application.Iteration += () => {
iterations++;
if (iterations == 0) {
MessageBox.Query ("mywindow", message, 0, null, wrapMessage, "ok");
Application.RequestStop ();
} else if (iterations == 1) {
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
┌ mywindow ────────────────────────────────────┐
│ │
│ │
│ [◦ ok ◦] │
└──────────────────────────────────────────────┘", output);
Application.RequestStop ();
}

View File

@@ -106,7 +106,7 @@ namespace Terminal.Gui.TopLevelTests {
var statusBar = new StatusBar (new [] {
new StatusItem(Key.CtrlMask | Key.R, "~^R~ Run Top2", () => Application.Run (Top2 ())),
new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => Application.RequestStop())
new StatusItem(Application.QuitKey, $"{Application.QuitKey} to Quit", () => Application.RequestStop())
});
top.Add (statusBar);

View File

@@ -1,10 +1,12 @@
using NStack;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Terminal.Gui;
using UICatalog;
using UICatalog.Scenarios;
using Xunit;
using Xunit.Abstractions;
@@ -25,14 +27,17 @@ namespace UICatalog.Tests {
int CreateInput (string input)
{
// Put a control-q in at the end
FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true));
FakeConsole.MockKeyPresses.Clear ();
// Put a QuitKey in at the end
FakeConsole.PushMockKeyPress (Application.QuitKey);
foreach (var c in input.Reverse ()) {
Key key = Key.Unknown;
if (char.IsLetter (c)) {
FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (char.ToLower (c), (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false));
key = (Key)char.ToUpper (c) | (char.IsUpper (c) ? Key.ShiftMask : (Key)0);
} else {
FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false));
key = (Key)c;
}
FakeConsole.PushMockKeyPress (key);
}
return FakeConsole.MockKeyPresses.Count;
}
@@ -53,24 +58,47 @@ namespace UICatalog.Tests {
Assert.NotEmpty (scenarios);
foreach (var scenario in scenarios) {
output.WriteLine ($"Running Scenario '{scenario}'");
Func<MainLoop, bool> closeCallback = (MainLoop loop) => {
Application.RequestStop ();
return false;
};
output.WriteLine ($"Running Scenario '{scenario.GetName ()}'");
Application.Init (new FakeDriver ());
// Close after a short period of time
var token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), closeCallback);
// Press QuitKey
Assert.Empty (FakeConsole.MockKeyPresses);
// BUGBUG: For some reason ReadKey is not returning the QuitKey for some Scenarios
// by adding this Space it seems to work.
FakeConsole.PushMockKeyPress (Key.Space);
FakeConsole.PushMockKeyPress (Application.QuitKey);
scenario.Init (Colors.Base);
// The only key we care about is the QuitKey
Application.Top.KeyPress += (View.KeyEventEventArgs args) => {
output.WriteLine ($" Keypress: {args.KeyEvent.Key}");
Assert.Equal (Application.QuitKey, args.KeyEvent.Key);
args.Handled = false;
};
uint abortTime = 500;
// If the scenario doesn't close within 500ms, this will force it to quit
Func<MainLoop, bool> forceCloseCallback = (MainLoop loop) => {
Application.RequestStop ();
Assert.Fail ($"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms. Force quit.");
return false;
};
//output.WriteLine ($" Add timeout to force quit after {abortTime}ms");
_ = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback);
int iterations = 0;
Application.Iteration += () => {
//output.WriteLine ($" iteration {++iterations}");
if (FakeConsole.MockKeyPresses.Count == 0) {
Application.RequestStop ();
//Assert.Fail ($"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey}. Force quit.");
}
};
scenario.Init ();
scenario.Setup ();
scenario.Run ();
scenario.Dispose();
scenario.Dispose ();
Application.Shutdown ();
#if DEBUG_IDISPOSABLE
@@ -96,51 +124,49 @@ namespace UICatalog.Tests {
var item = scenarios.FindIndex (s => s.GetName ().Equals ("Generic", StringComparison.OrdinalIgnoreCase));
var generic = scenarios [item];
// Setup some fake keypresses
// Passing empty string will cause just a ctrl-q to be fired
int stackSize = CreateInput ("");
Application.Init (new FakeDriver ());
Application.QuitKey = Key.CtrlMask | Key.Q; // Config manager may have set this to a different key
// BUGBUG: For some reason ReadKey is not
// returning the QuitKey for some Scenarios
// by adding this Space it seems to work.
FakeConsole.PushMockKeyPress (Key.Space);
FakeConsole.PushMockKeyPress (Application.QuitKey);
int iterations = 0;
Application.Iteration = () => {
iterations++;
output.WriteLine ($"'Generic' iteration {iterations}");
// Stop if we run out of control...
if (iterations == 10) {
output.WriteLine ($"'Generic' had to be force quit!");
Application.RequestStop ();
}
};
var ms = 1000;
var ms = 100;
var abortCount = 0;
Func<MainLoop, bool> abortCallback = (MainLoop loop) => {
abortCount++;
output.WriteLine ($"'Generic' abortCount {abortCount}");
Application.RequestStop ();
return false;
};
var token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback);
Application.Top.KeyPress += (View.KeyEventEventArgs args) => {
Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key);
output.WriteLine ($"'Generic' KeyPress {args.KeyEvent.Key}");
Assert.Equal (Application.QuitKey, args.KeyEvent.Key);
};
generic.Init (Colors.Base);
generic.Init ();
generic.Setup ();
// There is no need to call Application.Begin because Init already creates the Application.Top
// If Application.RunState is used then the Application.RunLoop must also be used instead Application.Run.
//var rs = Application.Begin (Application.Top);
generic.Run ();
//Application.End (rs);
Assert.Equal (0, abortCount);
// # of key up events should match # of iterations
Assert.Equal (1, iterations);
// Using variable in the left side of Assert.Equal/NotEqual give error. Must be used literals values.
//Assert.Equal (stackSize, iterations);
generic.Dispose();
generic.Dispose ();
// Shutdown must be called to safely clean up Application if Init has been called
Application.Shutdown ();

View File

@@ -14,11 +14,11 @@ namespace Terminal.Gui.ViewTests {
[Fact]
public void StatusItem_Constructor ()
{
var si = new StatusItem (Key.CtrlMask | Key.Q, "~^Q~ Quit", null);
var si = new StatusItem (Application.QuitKey, $"{Application.QuitKey} to Quit", null);
Assert.Equal (Key.CtrlMask | Key.Q, si.Shortcut);
Assert.Equal ("~^Q~ Quit", si.Title);
Assert.Equal ($"{Application.QuitKey} to Quit", si.Title);
Assert.Null (si.Action);
si = new StatusItem (Key.CtrlMask | Key.Q, "~^Q~ Quit", () => { });
si = new StatusItem (Application.QuitKey, $"{Application.QuitKey} to Quit", () => { });
Assert.NotNull (si.Action);
}
@@ -72,7 +72,7 @@ namespace Terminal.Gui.ViewTests {
public void Run_Action_With_Key_And_Mouse ()
{
var msg = "";
var sb = new StatusBar (new StatusItem [] { new StatusItem (Key.CtrlMask | Key.Q, "~^Q~ Quit", () => msg = "Quiting...") });
var sb = new StatusBar (new StatusItem [] { new StatusItem (Application.QuitKey, $"{Application.QuitKey} to Quit", () => msg = "Quiting...") });
Application.Top.Add (sb);
var iteration = 0;
@@ -101,26 +101,31 @@ namespace Terminal.Gui.ViewTests {
public void Redraw_Output ()
{
var sb = new StatusBar (new StatusItem [] {
new StatusItem (Key.CtrlMask | Key.Q, "~^O~ Open", null),
new StatusItem (Key.CtrlMask | Key.Q, "~^Q~ Quit", null)
new StatusItem (Key.CtrlMask | Key.O, "~^O~ Open", null),
new StatusItem (Application.QuitKey, $"{Application.QuitKey} to Quit!", null)
});
Application.Top.Add (sb);
sb.Redraw (sb.Bounds);
string expected = @$"
^O Open {Application.Driver.VLine} ^Q Quit
^O Open {Application.Driver.VLine} Q, CtrlMask to Quit!
";
TestHelpers.AssertDriverContentsAre (expected, output);
sb = new StatusBar (new StatusItem [] {
new StatusItem (Key.CtrlMask | Key.Q, "~CTRL-O~ Open", null),
}
[Fact]
[AutoInitShutdown]
public void Redraw_Output_CTRLQ ()
{
var sb = new StatusBar (new StatusItem [] {
new StatusItem (Key.CtrlMask | Key.O, "~CTRL-O~ Open", null),
new StatusItem (Key.CtrlMask | Key.Q, "~CTRL-Q~ Quit", null)
});
Application.Top.Add (sb);
sb.Redraw (sb.Bounds);
expected = @$"
string expected = @$"
CTRL-O Open {Application.Driver.VLine} CTRL-Q Quit
";