Fixes #4076 cursor text field (#4077)

* Add test for TextField cursor position

* Add comment and one more assert

* Fix cursor position at the end

* Remove unused local field

---------

Co-authored-by: BDisp <bd.bdisp@gmail.com>
This commit is contained in:
Thomas Nind
2025-05-11 23:29:22 +01:00
committed by Tig
parent 6f6c2d3320
commit 38c6f385f1
6 changed files with 97 additions and 5 deletions

View File

@@ -10,7 +10,6 @@ namespace Terminal.Gui;
public class FileDialogStyle
{
private readonly IFileSystem _fileSystem;
private bool _preserveFilenameOnDirectoryChanges;
/// <summary>Creates a new instance of the <see cref="FileDialogStyle"/> class.</summary>
public FileDialogStyle (IFileSystem fileSystem)

View File

@@ -1110,7 +1110,7 @@ public class TextField : View
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);

View File

@@ -0,0 +1,51 @@
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)
{
// Simulates typing abcd into a TextField with width 3 (wide enough to render 2 characters only)
using var c = With.A<Window> (100, 20, d)
.Add (new TextField () { Width = 3 })
.Focus<TextField> ()
.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
.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 ();
}
}

View File

@@ -24,5 +24,10 @@ internal class FakeOutput : IConsoleOutput
public void SetCursorVisibility (CursorVisibility visibility) { }
/// <inheritdoc/>
public void SetCursorPosition (int col, int row) { }
public void SetCursorPosition (int col, int row) { CursorPosition = new Point (col, row); }
/// <summary>
/// The last value set by calling <see cref="SetCursorPosition"/>
/// </summary>
public Point CursorPosition { get; private set; }
}

View File

@@ -706,10 +706,14 @@ public class GuiTestContext : IDisposable
/// is found (of Type T) or all views are looped through (back to the beginning)
/// in which case triggers hard stop and Exception
/// </summary>
/// <param name="evaluator">Delegate that returns true if the passed View is the one
/// you are trying to focus. Leave <see langword="null"/> to focus the first view of type
/// <typeparamref name="T"/></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public GuiTestContext Focus<T> (Func<T, bool> evaluator) where T : View
public GuiTestContext Focus<T> (Func<T, bool>? evaluator = null) where T : View
{
evaluator ??= _ => true;
Toplevel? t = Application.Top;
HashSet<View> seen = new ();
@@ -816,4 +820,13 @@ public class GuiTestContext : IDisposable
return this;
}
/// <summary>
/// Returns the last set position of the cursor.
/// </summary>
/// <returns></returns>
public Point GetCursorPosition ()
{
return _output.CursorPosition;
}
}

View File

@@ -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
/// <summary>
/// Asserts that the last set cursor position matches <paramref name="expected"/>
/// </summary>
/// <param name="context"></param>
/// <param name="expected"></param>
/// <returns></returns>
public static GuiTestContext AssertCursorPosition (this GuiTestContext context, Point expected)
{
try
{
Assert.Equal (expected, context.GetCursorPosition ());
}
catch (Exception)
{
context.HardStop ();
throw;
}
return context;
}
}