From b2f25e93c96a080619bb9c6a740ae241008651a8 Mon Sep 17 00:00:00 2001 From: tznind Date: Sat, 10 May 2025 04:49:29 +0100 Subject: [PATCH 1/4] Add test for TextField cursor position --- .../FluentTests/TextFieldFluentTests.cs | 46 +++++++++++++++++++ Tests/TerminalGuiFluentTesting/FakeOutput.cs | 7 ++- .../GuiTestContext.cs | 15 +++++- .../XunitContextExtensions.cs | 26 ++++++++++- 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs diff --git a/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs b/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs new file mode 100644 index 0000000000..ef9694ed3b --- /dev/null +++ b/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO.Abstractions; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terminal.Gui; +using TerminalGuiFluentTesting; +using TerminalGuiFluentTestingXunit; +using Xunit.Abstractions; + +namespace IntegrationTests.FluentTests; +public class TextFieldFluentTests +{ + private readonly TextWriter _out; + + public TextFieldFluentTests (ITestOutputHelper outputHelper) + { + _out = new TestOutputWriter (outputHelper); + } + + [Theory] + [ClassData (typeof (V2TestDrivers))] + public void TextField_Cursor_AtEnd_WhenTyping (V2TestDriver d) + { + using var c = With.A (100, 20, d) + .Add (new TextField () { Width = 3 }) + .Focus () + .WaitIteration () + .AssertCursorPosition (new Point (1, 1)) // Initial cursor position (because Window has border) + .RaiseKeyDownEvent (Key.A) + .WaitIteration () + .ScreenShot ("After typing first letter", _out) + .AssertCursorPosition (new Point (2, 1)) // Cursor moves along as letter is pressed + .RaiseKeyDownEvent (Key.B) + .WaitIteration () + .AssertCursorPosition (new Point (3, 1)) // Cursor moves along as letter is pressed + .RaiseKeyDownEvent (Key.C) + .WaitIteration () + .ScreenShot ("After typing all letters",_out) + .AssertCursorPosition (new Point (3, 1)) // Cursor stays where it is because we are at end of TextField + .WriteOutLogs (_out) + .Stop (); + } +} diff --git a/Tests/TerminalGuiFluentTesting/FakeOutput.cs b/Tests/TerminalGuiFluentTesting/FakeOutput.cs index 5f2b43bce5..b20f91fa4f 100644 --- a/Tests/TerminalGuiFluentTesting/FakeOutput.cs +++ b/Tests/TerminalGuiFluentTesting/FakeOutput.cs @@ -24,5 +24,10 @@ public void Write (ReadOnlySpan text) { } public void SetCursorVisibility (CursorVisibility visibility) { } /// - public void SetCursorPosition (int col, int row) { } + public void SetCursorPosition (int col, int row) { CursorPosition = new Point (col, row); } + + /// + /// The last value set by calling + /// + public Point CursorPosition { get; private set; } } diff --git a/Tests/TerminalGuiFluentTesting/GuiTestContext.cs b/Tests/TerminalGuiFluentTesting/GuiTestContext.cs index 5efc590e79..29083ffab7 100644 --- a/Tests/TerminalGuiFluentTesting/GuiTestContext.cs +++ b/Tests/TerminalGuiFluentTesting/GuiTestContext.cs @@ -706,10 +706,14 @@ public GuiTestContext Focus (View toFocus) /// is found (of Type T) or all views are looped through (back to the beginning) /// in which case triggers hard stop and Exception /// + /// Delegate that returns true if the passed View is the one + /// you are trying to focus. Leave to focus the first view of type + /// /// /// - public GuiTestContext Focus (Func evaluator) where T : View + public GuiTestContext Focus (Func? evaluator = null) where T : View { + evaluator ??= _ => true; Toplevel? t = Application.Top; HashSet seen = new (); @@ -816,4 +820,13 @@ public GuiTestContext Send (Key key) return this; } + + /// + /// Returns the last set position of the cursor. + /// + /// + public Point GetCursorPosition () + { + return _output.CursorPosition; + } } diff --git a/Tests/TerminalGuiFluentTestingXunit/XunitContextExtensions.cs b/Tests/TerminalGuiFluentTestingXunit/XunitContextExtensions.cs index a007dbbc1b..e1da262cfe 100644 --- a/Tests/TerminalGuiFluentTestingXunit/XunitContextExtensions.cs +++ b/Tests/TerminalGuiFluentTestingXunit/XunitContextExtensions.cs @@ -1,4 +1,5 @@ -using TerminalGuiFluentTesting; +using System.Drawing; +using TerminalGuiFluentTesting; using Xunit; namespace TerminalGuiFluentTestingXunit; @@ -6,4 +7,27 @@ namespace TerminalGuiFluentTestingXunit; public static partial class XunitContextExtensions { // Placeholder + + + /// + /// Asserts that the last set cursor position matches + /// + /// + /// + /// + public static GuiTestContext AssertCursorPosition (this GuiTestContext context, Point expected) + { + try + { + Assert.Equal (expected, context.GetCursorPosition ()); + } + catch (Exception) + { + context.HardStop (); + + throw; + } + + return context; + } } From d24302c545bfbd9203f7a0a7f72e9aa3066b9cd6 Mon Sep 17 00:00:00 2001 From: tznind Date: Sat, 10 May 2025 04:52:22 +0100 Subject: [PATCH 2/4] Add comment and one more assert --- Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs b/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs index ef9694ed3b..0197f7f249 100644 --- a/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs +++ b/Tests/IntegrationTests/FluentTests/TextFieldFluentTests.cs @@ -24,6 +24,7 @@ public TextFieldFluentTests (ITestOutputHelper outputHelper) [ClassData (typeof (V2TestDrivers))] public void TextField_Cursor_AtEnd_WhenTyping (V2TestDriver d) { + // Simulates typing abcd into a TextField with width 3 (wide enough to render 2 characters only) using var c = With.A (100, 20, d) .Add (new TextField () { Width = 3 }) .Focus () @@ -40,6 +41,10 @@ public void TextField_Cursor_AtEnd_WhenTyping (V2TestDriver d) .WaitIteration () .ScreenShot ("After typing all letters",_out) .AssertCursorPosition (new Point (3, 1)) // Cursor stays where it is because we are at end of TextField + .RaiseKeyDownEvent (Key.D) + .WaitIteration () + .ScreenShot ("Typing one more letter", _out) + .AssertCursorPosition (new Point (3, 1)) // Cursor still stays at end of TextField .WriteOutLogs (_out) .Stop (); } From 6805ed48d65fa11cb23d160e975368ce04ae3469 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 10 May 2025 11:59:35 +0100 Subject: [PATCH 3/4] Fix cursor position at the end --- Terminal.Gui/Views/TextField.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 07adca2193..97c7154cd9 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -1110,7 +1110,7 @@ public virtual void Paste () TextModel.SetCol (ref col, Viewport.Width - 1, cols); } - int pos = col - ScrollOffset + Math.Min (Viewport.X, 0); + int pos = col + Math.Min (Viewport.X, 0); Move (pos, 0); return new Point (pos, 0); From f681e02c8095bd7a9f7334f6ad62e9c0a6b2dd6c Mon Sep 17 00:00:00 2001 From: tznind Date: Sat, 10 May 2025 15:00:03 +0100 Subject: [PATCH 4/4] Remove unused local field --- Terminal.Gui/FileServices/FileDialogStyle.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Terminal.Gui/FileServices/FileDialogStyle.cs b/Terminal.Gui/FileServices/FileDialogStyle.cs index 761af2e64c..9726d99598 100644 --- a/Terminal.Gui/FileServices/FileDialogStyle.cs +++ b/Terminal.Gui/FileServices/FileDialogStyle.cs @@ -10,7 +10,6 @@ namespace Terminal.Gui; public class FileDialogStyle { private readonly IFileSystem _fileSystem; - private bool _preserveFilenameOnDirectoryChanges; /// Creates a new instance of the class. public FileDialogStyle (IFileSystem fileSystem)