Files
Terminal.Gui/UnitTests/Views/TextFieldTests.cs
Tig 0df485a890 Fixes #666. Refactor ConsoleDrivers to simplify and remove duplicated code (#2612)
* Added ClipRegion; cleaned up driver code

* clip region unit tests

* api docs

* Moved color stuff from ConsoleDriver to Color.cs

* Removes unused ConsoleDriver APIs

* Code cleanup and Removes unused ConsoleDriver APIs

* Code cleanup and Removes unused ConsoleDriver APIs

* Work around https://github.com/gui-cs/Terminal.Gui/issues/2610

* adjusted unit tests

* initial commit

* Made Rows, Cols, Top, Left virtual

* Made Clipboard non-virtual

* Made EnableConsoleScrolling  non-virtual

* Made Contents non-virtual

* Pulled Row/Col up

* Made MoveTo virtual; fixed stupid FakeDriver cursor issue

* Made CurrentAttribute non-virtual

* Made SetAttribute  non-virtual

* Moved clipboard code out

* Code cleanup

* Removes dependecy on NStack from ConsoleDrivers - WIP

* Fixed unit tests

* Fixed unit tests

* Added list of unit tests needed

* Did some perf testing; tweaked code and charmap to address

* Brough in code from PR #2264 (but commented)

* Tons of code cleanup

* Fighting with ScrollView

* Fixing bugs

* Fixed TabView tests

* Fixed View.Visible test that was not really working

* Fixed unit tests

* Cleaned up clipboard APIs in attempt to track down unit test failure

* Add Cut_Preserves_Selection test

* Removed invalid code

* Removed invalid test code; unit tests now pass

* EscSeq* - Adjusted naming, added more sequences, made code more consistent, simplified, etc...

* Added CSI_SetGraphicsRendition

* NetDriver code cleanup

* code cleanup

* Cleaned up color handling in NetDriver

* refixed tabview unit test

* WindowsDriver color code cleanup

* WindowsDriver color code cleanup

* CursesDriver color code cleanup

* CursesDriver - Adding _BOLD has no effect. Further up the stack we cast the return of ColorToCursesColor from int to short and the _BOLD values don't fit in a short.

* CursesDriver color code - make code more accurate

* CursesDriver color code - make code more accurate

* Simplified ConsoleDriver.GetColors API

* Simplified ConsoleDriver.GetColors API further

* Improved encapslation of Attribute; prep for TrueColor & other attributes like blink

* Fixes #2249. CharacterMap isn't refreshing well non-BMP code points on scroll.

* Use GetRange to take some of the runes before convert to string.

* Attempting to fix unit tests not being cleaned up

* Fixes #2658 - ConsoleDriver.IsRuneSupported

* Fixes #2658 - ConsoleDriver.IsRuneSupported (for WindowsDriver)

* Check all the range values and not only the max value.

* Reducing code.

* Fixes #2674 - Unit test process doesn't exit

* Changed Cell to support IsDirty and list of Runes

* add support for rendering TrueColor output on Windows merging veeman & tznind code

* add colorconverter changes

* fixed merged v2_develop

* Fixing merge bugs

* Fixed merge bugs

* Fixed merge bugs - all unit tests pass

* Debugging netdriver

* More netdriver diag

* API docs for escutils

* Update unicode scenario to stress more stuff

* Contents: Now a 2D array of Cells; WIP

* AddRune and ClearContents no longer virtual/abstract

* WindowsDriver renders correctly again

* Progress on Curses

* Progress on Curses

* broke windowsdriver

* Cleaned up FakeMainLoop

* Cleaned up some build warnings

* Removed _init from AutoInitShutdown as it's not needed anymore

* Removed unused var

* Removed unused var

* Fixed nullabiltiy warning in LineCanvas

* Fixed charmap crash

* Fixes #2758 in v2

* Port testonfail fix to v2

* Remove EnableConsoleScrolling

* Backport #2764 from develop (clear last line)

* Remove uneeded usings

* Progress on unicode

* Merged in changes from PR #2786, Fixes #2784

* revamp charmap rendering

* Charmap option to show glyph widths

* Fixed issue with wide glpyhs being overwritten

* Fixed charmap startcodepoint change issue

* Added abiltiy to see ncurses verison/lib

* Fought with CursesDriver; giving up for now. See notes.

* Leverage Wcwidth nuget library instaed of our own tables

* enhanced charmap Details dialog

* Final attempt at fixing curses

---------

Co-authored-by: BDisp <bd.bdisp@gmail.com>
Co-authored-by: adstep <stephensonadamj@gmail.com>
2023-08-09 14:28:36 -06:00

1614 lines
54 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text;
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Xunit;
using Xunit.Abstractions;
namespace Terminal.Gui.ViewsTests {
public class TextFieldTests {
readonly ITestOutputHelper output;
public TextFieldTests (ITestOutputHelper output)
{
this.output = output;
}
// This class enables test functions annotated with the [InitShutdown] attribute
// to have a function called before the test function is called and after.
//
// This is necessary because a) Application is a singleton and Init/Shutdown must be called
// as a pair, and b) all unit test functions should be atomic.
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class TextFieldTestsAutoInitShutdown : AutoInitShutdownAttribute {
public override void Before (MethodInfo methodUnderTest)
{
base.Before (methodUnderTest);
// 1 2 3
// 01234567890123456789012345678901=32 (Length)
TextFieldTests._textField = new TextField ("TAB to jump between text fields.");
}
public override void After (MethodInfo methodUnderTest)
{
TextFieldTests._textField = null;
base.After (methodUnderTest);
}
}
private static TextField _textField;
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Changing_SelectedStart_Or_CursorPosition_Update_SelectedLength_And_SelectedText ()
{
_textField.SelectedStart = 2;
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (30, _textField.SelectedLength);
Assert.Equal ("B to jump between text fields.", _textField.SelectedText);
_textField.CursorPosition = 20;
Assert.Equal (2, _textField.SelectedStart);
Assert.Equal (18, _textField.SelectedLength);
Assert.Equal ("B to jump between ", _textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void SelectedStart_With_Value_Less_Than_Minus_One_Changes_To_Minus_One ()
{
_textField.SelectedStart = -2;
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void SelectedStart_With_Value_Greater_Than_Text_Length_Changes_To_Text_Length ()
{
_textField.CursorPosition = 2;
_textField.SelectedStart = 33;
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (30, _textField.SelectedLength);
Assert.Equal ("B to jump between text fields.", _textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void SelectedStart_And_CursorPosition_With_Value_Greater_Than_Text_Length_Changes_Both_To_Text_Length ()
{
_textField.CursorPosition = 33;
_textField.SelectedStart = 33;
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void SelectedStart_Greater_Than_CursorPosition_All_Selection_Is_Overwritten_On_Typing ()
{
_textField.SelectedStart = 19;
_textField.CursorPosition = 12;
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u
Assert.Equal ("TAB to jump u text fields.", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void CursorPosition_With_Value_Less_Than_Zero_Changes_To_Zero ()
{
_textField.CursorPosition = -1;
Assert.Equal (0, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void CursorPosition_With_Value_Greater_Than_Text_Length_Changes_To_Text_Length ()
{
_textField.CursorPosition = 33;
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordForward_With_No_Selection ()
{
_textField.CursorPosition = 0;
var iteration = 0;
while (_textField.CursorPosition < _textField.Text.Length) {
_textField.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (4, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 1:
Assert.Equal (7, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 2:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 3:
Assert.Equal (20, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 4:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 5:
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordBackward_With_No_Selection ()
{
_textField.CursorPosition = _textField.Text.Length;
var iteration = 0;
while (_textField.CursorPosition > 0) {
_textField.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (31, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 1:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 2:
Assert.Equal (20, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 3:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 4:
Assert.Equal (7, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 5:
Assert.Equal (4, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 6:
Assert.Equal (0, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordForward_With_Selection ()
{
_textField.CursorPosition = 0;
_textField.SelectedStart = 0;
var iteration = 0;
while (_textField.CursorPosition < _textField.Text.Length) {
_textField.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (4, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedStart);
Assert.Equal (4, _textField.SelectedLength);
Assert.Equal ("TAB ", _textField.SelectedText);
break;
case 1:
Assert.Equal (7, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedStart);
Assert.Equal (7, _textField.SelectedLength);
Assert.Equal ("TAB to ", _textField.SelectedText);
break;
case 2:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedStart);
Assert.Equal (12, _textField.SelectedLength);
Assert.Equal ("TAB to jump ", _textField.SelectedText);
break;
case 3:
Assert.Equal (20, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedStart);
Assert.Equal (20, _textField.SelectedLength);
Assert.Equal ("TAB to jump between ", _textField.SelectedText);
break;
case 4:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedStart);
Assert.Equal (25, _textField.SelectedLength);
Assert.Equal ("TAB to jump between text ", _textField.SelectedText);
break;
case 5:
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedStart);
Assert.Equal (32, _textField.SelectedLength);
Assert.Equal ("TAB to jump between text fields.", _textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordBackward_With_Selection ()
{
_textField.CursorPosition = _textField.Text.Length;
_textField.SelectedStart = _textField.Text.Length;
var iteration = 0;
while (_textField.CursorPosition > 0) {
_textField.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (31, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (1, _textField.SelectedLength);
Assert.Equal (".", _textField.SelectedText);
break;
case 1:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (7, _textField.SelectedLength);
Assert.Equal ("fields.", _textField.SelectedText);
break;
case 2:
Assert.Equal (20, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (12, _textField.SelectedLength);
Assert.Equal ("text fields.", _textField.SelectedText);
break;
case 3:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (20, _textField.SelectedLength);
Assert.Equal ("between text fields.", _textField.SelectedText);
break;
case 4:
Assert.Equal (7, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (25, _textField.SelectedLength);
Assert.Equal ("jump between text fields.", _textField.SelectedText);
break;
case 5:
Assert.Equal (4, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (28, _textField.SelectedLength);
Assert.Equal ("to jump between text fields.", _textField.SelectedText);
break;
case 6:
Assert.Equal (0, _textField.CursorPosition);
Assert.Equal (32, _textField.SelectedStart);
Assert.Equal (32, _textField.SelectedLength);
Assert.Equal ("TAB to jump between text fields.", _textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordForward_With_The_Same_Values_For_SelectedStart_And_CursorPosition_And_Not_Starting_At_Beginning_Of_The_Text ()
{
_textField.CursorPosition = 10;
_textField.SelectedStart = 10;
var iteration = 0;
while (_textField.CursorPosition < _textField.Text.Length) {
_textField.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (2, _textField.SelectedLength);
Assert.Equal ("p ", _textField.SelectedText);
break;
case 1:
Assert.Equal (20, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (10, _textField.SelectedLength);
Assert.Equal ("p between ", _textField.SelectedText);
break;
case 2:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (15, _textField.SelectedLength);
Assert.Equal ("p between text ", _textField.SelectedText);
break;
case 3:
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (22, _textField.SelectedLength);
Assert.Equal ("p between text fields.", _textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordBackward_With_The_Same_Values_For_SelectedStart_And_CursorPosition_And_Not_Starting_At_Beginning_Of_The_Text ()
{
_textField.CursorPosition = 10;
_textField.SelectedStart = 10;
var iteration = 0;
while (_textField.CursorPosition > 0) {
_textField.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (7, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (3, _textField.SelectedLength);
Assert.Equal ("jum", _textField.SelectedText);
break;
case 1:
Assert.Equal (4, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (6, _textField.SelectedLength);
Assert.Equal ("to jum", _textField.SelectedText);
break;
case 2:
Assert.Equal (0, _textField.CursorPosition);
Assert.Equal (10, _textField.SelectedStart);
Assert.Equal (10, _textField.SelectedLength);
Assert.Equal ("TAB to jum", _textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordForward_With_No_Selection_And_With_More_Than_Only_One_Whitespace_And_With_Only_One_Letter ()
{
// 1 2 3 4 5
// 0123456789012345678901234567890123456789012345678901234=55 (Length)
_textField.Text = "TAB t o jump b etween t ext f ields .";
_textField.CursorPosition = 0;
var iteration = 0;
while (_textField.CursorPosition < _textField.Text.Length) {
_textField.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (6, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 1:
Assert.Equal (9, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 2:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 3:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 4:
Assert.Equal (28, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 5:
Assert.Equal (38, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 6:
Assert.Equal (40, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 7:
Assert.Equal (46, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 8:
Assert.Equal (48, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 9:
Assert.Equal (54, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 10:
Assert.Equal (55, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void WordBackward_With_No_Selection_And_With_More_Than_Only_One_Whitespace_And_With_Only_One_Letter ()
{
// 1 2 3 4 5
// 0123456789012345678901234567890123456789012345678901234=55 (Length)
_textField.Text = "TAB t o jump b etween t ext f ields .";
_textField.CursorPosition = _textField.Text.Length;
var iteration = 0;
while (_textField.CursorPosition > 0) {
_textField.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask, new KeyModifiers ()));
switch (iteration) {
case 0:
Assert.Equal (54, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 1:
Assert.Equal (48, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 2:
Assert.Equal (46, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 3:
Assert.Equal (40, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 4:
Assert.Equal (38, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 5:
Assert.Equal (28, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 6:
Assert.Equal (25, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 7:
Assert.Equal (12, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 8:
Assert.Equal (9, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 9:
Assert.Equal (6, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
case 10:
Assert.Equal (0, _textField.CursorPosition);
Assert.Equal (-1, _textField.SelectedStart);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
break;
}
iteration++;
}
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Copy_Or_Cut_Null_If_No_Selection ()
{
_textField.SelectedStart = -1;
_textField.Copy ();
Assert.Null (_textField.SelectedText);
_textField.Cut ();
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Copy_Or_Cut_Not_Null_If_Has_Selection ()
{
_textField.SelectedStart = 20;
_textField.CursorPosition = 24;
_textField.Copy ();
Assert.Equal ("text", _textField.SelectedText);
_textField.Cut ();
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Copy_Or_Cut_And_Paste_With_Selection ()
{
_textField.SelectedStart = 20;
_textField.CursorPosition = 24;
_textField.Copy ();
Assert.Equal ("text", _textField.SelectedText);
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.Paste ();
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.SelectedStart = 20;
_textField.Cut ();
_textField.Paste ();
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Copy_Or_Cut_And_Paste_With_No_Selection ()
{
_textField.SelectedStart = 20;
_textField.CursorPosition = 24;
_textField.Copy ();
Assert.Equal ("text", _textField.SelectedText);
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.SelectedStart = -1;
_textField.Paste ();
Assert.Equal ("TAB to jump between texttext fields.", _textField.Text);
_textField.SelectedStart = 24;
_textField.Cut ();
Assert.Null (_textField.SelectedText);
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.SelectedStart = -1;
_textField.Paste ();
Assert.Equal ("TAB to jump between texttext fields.", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Copy_Or_Cut__Not_Allowed_If_Secret_Is_True ()
{
_textField.Secret = true;
_textField.SelectedStart = 20;
_textField.CursorPosition = 24;
_textField.Copy ();
Assert.Null (_textField.SelectedText);
_textField.Cut ();
Assert.Null (_textField.SelectedText);
_textField.Secret = false;
_textField.Copy ();
Assert.Equal ("text", _textField.SelectedText);
_textField.Cut ();
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Paste_Always_Clear_The_SelectedText ()
{
_textField.SelectedStart = 20;
_textField.CursorPosition = 24;
_textField.Copy ();
Assert.Equal ("text", _textField.SelectedText);
_textField.Paste ();
Assert.Null (_textField.SelectedText);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void TextChanging_Event ()
{
bool cancel = true;
_textField.TextChanging += (s, e) => {
Assert.Equal ("changing", e.NewText);
if (cancel) {
e.Cancel = true;
}
};
_textField.Text = "changing";
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
cancel = false;
_textField.Text = "changing";
Assert.Equal ("changing", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void TextChanged_Event ()
{
_textField.TextChanged += (s, e) => {
Assert.Equal ("TAB to jump between text fields.", e.OldValue);
};
_textField.Text = "changed";
Assert.Equal ("changed", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Used_Is_True_By_Default ()
{
_textField.CursorPosition = 10;
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u
Assert.Equal ("TAB to jumup between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x73, new KeyModifiers ())); // s
Assert.Equal ("TAB to jumusp between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x65, new KeyModifiers ())); // e
Assert.Equal ("TAB to jumusep between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x64, new KeyModifiers ())); // d
Assert.Equal ("TAB to jumusedp between text fields.", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Used_Is_False ()
{
_textField.Used = false;
_textField.CursorPosition = 10;
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u
Assert.Equal ("TAB to jumu between text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x73, new KeyModifiers ())); // s
Assert.Equal ("TAB to jumusbetween text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x65, new KeyModifiers ())); // e
Assert.Equal ("TAB to jumuseetween text fields.", _textField.Text);
_textField.ProcessKey (new KeyEvent ((Key)0x64, new KeyModifiers ())); // d
Assert.Equal ("TAB to jumusedtween text fields.", _textField.Text);
}
[Fact]
public void ProcessKey_Backspace_From_End ()
{
var tf = new TextField ("ABC");
tf.EnsureFocus ();
Assert.Equal ("ABC", tf.Text);
Assert.Equal (3, tf.CursorPosition);
// now delete the C
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("AB", tf.Text);
Assert.Equal (2, tf.CursorPosition);
// then delete the B
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("A", tf.Text);
Assert.Equal (1, tf.CursorPosition);
// then delete the A
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("", tf.Text);
Assert.Equal (0, tf.CursorPosition);
}
[Fact]
public void ProcessKey_Backspace_From_Middle ()
{
var tf = new TextField ("ABC");
tf.EnsureFocus ();
tf.CursorPosition = 2;
Assert.Equal ("ABC", tf.Text);
// now delete the B
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("AC", tf.Text);
// then delete the A
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("C", tf.Text);
// then delete nothing
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("C", tf.Text);
// now delete the C
tf.CursorPosition = 1;
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("", tf.Text);
}
[Fact]
public void Cancel_TextChanging_ThenBackspace ()
{
var tf = new TextField ();
tf.EnsureFocus ();
tf.ProcessKey (new KeyEvent (Key.A, new KeyModifiers ()));
Assert.Equal ("A", tf.Text);
// cancel the next keystroke
tf.TextChanging += (s, e) => e.Cancel = e.NewText == "AB";
tf.ProcessKey (new KeyEvent (Key.B, new KeyModifiers ()));
// B was canceled so should just be A
Assert.Equal ("A", tf.Text);
// now delete the A
tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()));
Assert.Equal ("", tf.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void Text_Replaces_Tabs_With_Empty_String ()
{
_textField.Text = "\t\tTAB to jump between text fields.";
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
_textField.Text = "";
Clipboard.Contents = "\t\tTAB to jump between text fields.";
_textField.Paste ();
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void TextField_SpaceHandling ()
{
var tf = new TextField () {
Width = 10,
Text = " "
};
MouseEvent ev = new MouseEvent () {
X = 0,
Y = 0,
Flags = MouseFlags.Button1DoubleClicked,
};
tf.MouseEvent (ev);
Assert.Equal (1, tf.SelectedLength);
ev = new MouseEvent () {
X = 1,
Y = 0,
Flags = MouseFlags.Button1DoubleClicked,
};
tf.MouseEvent (ev);
Assert.Equal (1, tf.SelectedLength);
}
[Fact]
[TextFieldTestsAutoInitShutdown]
public void CanFocus_False_Wont_Focus_With_Mouse ()
{
var top = Application.Top;
var tf = new TextField () {
Width = Dim.Fill (),
CanFocus = false,
ReadOnly = true,
Text = "some text"
};
var fv = new FrameView ("I shouldn't get focus") {
Width = Dim.Fill (),
Height = Dim.Fill (),
CanFocus = false,
};
fv.Add (tf);
top.Add (fv);
Application.Begin (top);
Assert.False (tf.CanFocus);
Assert.False (tf.HasFocus);
Assert.False (fv.CanFocus);
Assert.False (fv.HasFocus);
tf.MouseEvent (new MouseEvent () {
X = 1,
Y = 0,
Flags = MouseFlags.Button1DoubleClicked
});
Assert.Null (tf.SelectedText);
Assert.False (tf.CanFocus);
Assert.False (tf.HasFocus);
Assert.False (fv.CanFocus);
Assert.False (fv.HasFocus);
Assert.Throws<InvalidOperationException> (() => tf.CanFocus = true);
fv.CanFocus = true;
tf.CanFocus = true;
tf.MouseEvent (new MouseEvent () {
X = 1,
Y = 0,
Flags = MouseFlags.Button1DoubleClicked
});
Assert.Equal ("some ", tf.SelectedText);
Assert.True (tf.CanFocus);
Assert.True (tf.HasFocus);
Assert.True (fv.CanFocus);
Assert.True (fv.HasFocus);
fv.CanFocus = false;
tf.MouseEvent (new MouseEvent () {
X = 1,
Y = 0,
Flags = MouseFlags.Button1DoubleClicked
});
Assert.Equal ("some ", tf.SelectedText); // Setting CanFocus to false don't change the SelectedText
Assert.False (tf.CanFocus);
Assert.False (tf.HasFocus);
Assert.False (fv.CanFocus);
Assert.False (fv.HasFocus);
}
[Fact]
[AutoInitShutdown (useFakeClipboard: true)]
public void KeyBindings_Command ()
{
var tf = new TextField ("This is a test.") { Width = 20 };
Assert.Equal (15, tf.Text.Length);
Assert.Equal (15, tf.CursorPosition);
Assert.False (tf.ReadOnly);
Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ())));
Assert.Equal ("This is a test.", tf.Text);
tf.CursorPosition = 0;
Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ())));
Assert.Equal ("his is a test.", tf.Text);
tf.ReadOnly = true;
Assert.True (tf.ProcessKey (new KeyEvent (Key.D | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("his is a test.", tf.Text);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Delete, new KeyModifiers ())));
Assert.Equal ("his is a test.", tf.Text);
tf.ReadOnly = false;
tf.CursorPosition = 1;
Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
tf.CursorPosition = 5;
Assert.True (tf.ProcessKey (new KeyEvent (Key.Home | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is is", tf.SelectedText);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Home | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is is", tf.SelectedText);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.A | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is is", tf.SelectedText);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.End | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (" a test.", tf.SelectedText);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.End | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (" a test.", tf.SelectedText);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.E | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (" a test.", tf.SelectedText);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Home, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (0, tf.CursorPosition);
tf.CursorPosition = 5;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Home | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (0, tf.CursorPosition);
tf.CursorPosition = 5;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.A | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (0, tf.CursorPosition);
tf.CursorPosition = 5;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("s", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorUp | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("s", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorDown | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Null (tf.SelectedText);
tf.CursorPosition = 7;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("a", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorUp | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is a", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'B' + Key.ShiftMask | Key.AltMask), new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is is a", tf.SelectedText);
tf.CursorPosition = 3;
tf.SelectedStart = -1;
Assert.Null (tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is ", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorDown | Key.ShiftMask | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is a ", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'F' + Key.ShiftMask | Key.AltMask), new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal ("is a test.", tf.SelectedText);
Assert.Equal (13, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Null (tf.SelectedText);
Assert.Equal (12, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (11, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.End, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (13, tf.CursorPosition);
tf.CursorPosition = 0;
Assert.True (tf.ProcessKey (new KeyEvent (Key.End | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (13, tf.CursorPosition);
tf.CursorPosition = 0;
Assert.True (tf.ProcessKey (new KeyEvent (Key.E | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (13, tf.CursorPosition);
tf.CursorPosition = 0;
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (1, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.F | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.Equal (2, tf.CursorPosition);
tf.CursorPosition = 9;
tf.ReadOnly = true;
Assert.True (tf.ProcessKey (new KeyEvent (Key.K | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
tf.ReadOnly = false;
Assert.True (tf.ProcessKey (new KeyEvent (Key.K | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal ("est.", Clipboard.Contents);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Z | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Y | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace | Key.AltMask, new KeyModifiers ())));
Assert.Equal ("is is a test.", tf.Text);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Y | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (8, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorUp | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (6, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'B' + Key.AltMask), new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (3, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (6, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.CursorDown | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (8, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent ((Key)((int)'F' + Key.AltMask), new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (9, tf.CursorPosition);
Assert.True (tf.Used);
Assert.True (tf.ProcessKey (new KeyEvent (Key.InsertChar, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal (9, tf.CursorPosition);
Assert.False (tf.Used);
tf.SelectedStart = 3;
tf.CursorPosition = 7;
Assert.Equal ("is a", tf.SelectedText);
Assert.Equal ("est.", Clipboard.Contents);
Assert.True (tf.ProcessKey (new KeyEvent (Key.C | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal ("is a", Clipboard.Contents);
Assert.True (tf.ProcessKey (new KeyEvent (Key.X | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is t", tf.Text);
Assert.Equal ("is a", Clipboard.Contents);
Assert.True (tf.ProcessKey (new KeyEvent (Key.V | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("is is a t", tf.Text);
Assert.Equal ("is a", Clipboard.Contents);
Assert.Equal (7, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.K | Key.AltMask, new KeyModifiers ())));
Assert.Equal (" t", tf.Text);
Assert.Equal ("is is a", Clipboard.Contents);
tf.Text = "TAB to jump between text fields.";
Assert.Equal (0, tf.CursorPosition);
Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("to jump between text fields.", tf.Text);
tf.CursorPosition = tf.Text.Length;
Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("to jump between text fields", tf.Text);
Assert.True (tf.ProcessKey (new KeyEvent (Key.T | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("to jump between text fields", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.D | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ())));
Assert.Equal ("", tf.Text);
}
[Fact]
[AutoInitShutdown]
public void Adjust_First ()
{
TextField tf = new TextField () {
Width = Dim.Fill (),
Text = "This is a test."
};
Application.Top.Add (tf);
Application.Begin (Application.Top);
Assert.Equal ("This is a test. ", GetContents ());
string GetContents ()
{
var item = "";
for (int i = 0; i < 16; i++) {
item += Application.Driver.Contents [0, i].Runes [0];
}
return item;
}
}
[Fact, AutoInitShutdown]
public void DeleteSelectedText_InsertText_DeleteCharLeft_DeleteCharRight_Cut ()
{
var newText = "";
var oldText = "";
var tf = new TextField () { Width = 10, Text = "-1" };
tf.TextChanging += (s, e) => newText = e.NewText;
tf.TextChanged += (s, e) => oldText = e.OldValue;
Application.Top.Add (tf);
Application.Begin (Application.Top);
Assert.Equal ("-1", tf.Text);
// InsertText
tf.SelectedStart = 1;
tf.CursorPosition = 2;
Assert.Equal (1, tf.SelectedLength);
Assert.Equal ("1", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.D2, new KeyModifiers ())));
Assert.Equal ("-2", newText);
Assert.Equal ("-1", oldText);
Assert.Equal ("-2", tf.Text);
// DeleteCharLeft
tf.SelectedStart = 1;
tf.CursorPosition = 2;
Assert.Equal (1, tf.SelectedLength);
Assert.Equal ("2", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ())));
Assert.Equal ("-", newText);
Assert.Equal ("-2", oldText);
Assert.Equal ("-", tf.Text);
// DeleteCharRight
tf.Text = "-1";
tf.SelectedStart = 1;
tf.CursorPosition = 2;
Assert.Equal (1, tf.SelectedLength);
Assert.Equal ("1", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.DeleteChar, new KeyModifiers ())));
Assert.Equal ("-", newText);
Assert.Equal ("-1", oldText);
Assert.Equal ("-", tf.Text);
// Cut
tf.Text = "-1";
tf.SelectedStart = 1;
tf.CursorPosition = 2;
Assert.Equal (1, tf.SelectedLength);
Assert.Equal ("1", tf.SelectedText);
Assert.True (tf.ProcessKey (new KeyEvent (Key.X | Key.CtrlMask, new KeyModifiers ())));
Assert.Equal ("-", newText);
Assert.Equal ("-1", oldText);
Assert.Equal ("-", tf.Text);
// Delete word with accented char
tf.Text = "Les Misérables movie.";
Assert.True (tf.MouseEvent (new MouseEvent {
X = 7,
Y = 1,
Flags = MouseFlags.Button1DoubleClicked,
View = tf
}));
Assert.Equal ("Misérables ", tf.SelectedText);
Assert.Equal (11, tf.SelectedLength);
Assert.True (tf.ProcessKey (new KeyEvent (Key.Delete, new KeyModifiers ())));
Assert.Equal ("Les movie.", newText);
Assert.Equal ("Les Misérables movie.", oldText);
Assert.Equal ("Les movie.", tf.Text);
}
[Fact]
[AutoInitShutdown]
public void Test_RootKeyEvent_Cancel ()
{
Application.RootKeyEvent += SuppressKey;
var tf = new TextField ();
Application.Top.Add (tf);
Application.Begin (Application.Top);
Application.Driver.SendKeys ('a', ConsoleKey.A, false, false, false);
Assert.Equal ("a", tf.Text);
// SuppressKey suppresses the 'j' key
Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false);
Assert.Equal ("a", tf.Text);
Application.RootKeyEvent -= SuppressKey;
// Now that the delegate has been removed we can type j again
Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false);
Assert.Equal ("aj", tf.Text);
}
[Fact]
[AutoInitShutdown]
public void Test_RootMouseKeyEvent_Cancel ()
{
Application.RootMouseEvent += SuppressRightClick;
var tf = new TextField () { Width = 10 };
int clickCounter = 0;
tf.MouseClick += (s, m) => { clickCounter++; };
Application.Top.Add (tf);
Application.Begin (Application.Top);
var processMouseEventMethod = typeof (Application).GetMethod ("ProcessMouseEvent", BindingFlags.Static | BindingFlags.NonPublic)
?? throw new Exception ("Expected private method not found 'ProcessMouseEvent', this method was used for testing mouse behaviours");
var mouseEvent = new MouseEvent {
Flags = MouseFlags.Button1Clicked,
View = tf
};
processMouseEventMethod.Invoke (null, new object [] { mouseEvent });
Assert.Equal (1, clickCounter);
// Get a fresh instance that represents a right click.
// Should be ignored because of SuppressRightClick callback
mouseEvent = new MouseEvent {
Flags = MouseFlags.Button3Clicked,
View = tf
};
processMouseEventMethod.Invoke (null, new object [] { mouseEvent });
Assert.Equal (1, clickCounter);
Application.RootMouseEvent -= SuppressRightClick;
// Get a fresh instance that represents a right click.
// Should no longer be ignored as the callback was removed
mouseEvent = new MouseEvent {
Flags = MouseFlags.Button3Clicked,
View = tf
};
processMouseEventMethod.Invoke (null, new object [] { mouseEvent });
Assert.Equal (2, clickCounter);
}
private bool SuppressKey (KeyEvent arg)
{
if (arg.KeyValue == 'j')
return true;
return false;
}
private void SuppressRightClick (MouseEvent arg)
{
if (arg.Flags.HasFlag (MouseFlags.Button3Clicked))
arg.Handled = true;
}
[Fact, AutoInitShutdown]
public void ScrollOffset_Initialize ()
{
var tf = new TextField ("Testing Scrolls.") {
X = 1,
Y = 1,
Width = 20
};
Assert.Equal (0, tf.ScrollOffset);
Assert.Equal (16, tf.CursorPosition);
Application.Top.Add (tf);
Application.Begin (Application.Top);
Assert.Equal (0, tf.ScrollOffset);
Assert.Equal (16, tf.CursorPosition);
}
[Fact]
public void HistoryText_IsDirty_ClearHistoryChanges ()
{
var text = "Testing";
var tf = new TextField (text);
Assert.Equal (text, tf.Text);
tf.ClearHistoryChanges ();
Assert.False (tf.IsDirty);
Assert.True (tf.ProcessKey (new KeyEvent (Key.A, new KeyModifiers ())));
Assert.Equal ($"{text}A", tf.Text);
Assert.True (tf.IsDirty);
}
[InlineData ("a")] // Lower than selection
[InlineData ("aaaaaaaaaaa")] // Greater than selection
[InlineData ("aaaa")] // Equal than selection
[Theory]
public void TestSetTextAndMoveCursorToEnd_WhenExistingSelection (string newText)
{
var tf = new TextField ();
tf.Text = "fish";
tf.CursorPosition = tf.Text.Length;
tf.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()));
tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.ShiftMask, new KeyModifiers { Shift = true }));
tf.ProcessKey (new KeyEvent (Key.CursorLeft | Key.ShiftMask, new KeyModifiers { Shift = true }));
Assert.Equal (1, tf.CursorPosition);
Assert.Equal (2, tf.SelectedLength);
Assert.Equal ("is", tf.SelectedText);
tf.Text = newText;
tf.CursorPosition = tf.Text.Length;
Assert.Equal (newText.Length, tf.CursorPosition);
Assert.Equal (0, tf.SelectedLength);
Assert.Null (tf.SelectedText);
}
[Fact]
public void WordBackward_WordForward_SelectedText_With_Accent ()
{
string text = "Les Misérables movie.";
var tf = new TextField (text) { Width = 30 };
Assert.Equal (21, text.Length);
Assert.Equal (21, tf.Text.GetRuneCount ());
Assert.Equal (21, tf.Text.GetColumns ());
var runes = tf.Text.ToRuneList ();
Assert.Equal (21, runes.Count);
Assert.Equal (21, tf.Text.Length);
for (int i = 0; i < runes.Count; i++) {
var cs = text [i];
var cus = (char)runes [i].Value;
Assert.Equal (cs, cus);
}
var idx = 15;
Assert.Equal ('m', text [idx]);
Assert.Equal ('m', (char)runes [idx].Value);
Assert.Equal ("m", runes [idx].ToString ());
Assert.True (tf.MouseEvent (new MouseEvent {
X = idx,
Y = 1,
Flags = MouseFlags.Button1DoubleClicked,
View = tf
}));
Assert.Equal ("movie.", tf.SelectedText);
Assert.True (tf.MouseEvent (new MouseEvent {
X = idx + 1,
Y = 1,
Flags = MouseFlags.Button1DoubleClicked,
View = tf
}));
Assert.Equal ("movie.", tf.SelectedText);
}
[Fact, AutoInitShutdown]
public void Words_With_Accents_Incorrect_Order_Will_Result_With_Wrong_Accent_Place ()
{
var tf = new TextField ("Les Misérables") { Width = 30 };
var top = Application.Top;
top.Add (tf);
Application.Begin (top);
TestHelpers.AssertDriverContentsWithFrameAre (@"
Les Misérables", output);
tf.Text = "Les Mise" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "rables";
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
Les Misérables", output);
// incorrect order will result with a wrong accent place
tf.Text = "Les Mis" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "erables";
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
Les Miśerables", output);
}
[Fact, AutoInitShutdown]
public void Accented_Letter_With_Three_Combining_Unicode_Chars ()
{
var tf = new TextField ("ắ") { Width = 3 };
var top = Application.Top;
top.Add (tf);
Application.Begin (top);
TestHelpers.AssertDriverContentsWithFrameAre (@"
ắ", output);
tf.Text = "\u1eaf";
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
ắ", output);
tf.Text = "\u0103\u0301";
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
ắ", output);
tf.Text = "\u0061\u0306\u0301";
Application.Refresh ();
TestHelpers.AssertDriverContentsWithFrameAre (@"
ắ", output);
}
[Fact, AutoInitShutdown]
public void CaptionedTextField_RendersCaption_WhenNotFocused ()
{
var tf = GetTextFieldsInView ();
tf.Draw ();
TestHelpers.AssertDriverContentsAre ("", output);
// Caption has no effect when focused
tf.Caption = "Enter txt";
Assert.True (tf.HasFocus);
tf.Draw ();
TestHelpers.AssertDriverContentsAre ("", output);
Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
Assert.False (tf.HasFocus);
tf.Draw ();
TestHelpers.AssertDriverContentsAre ("Enter txt", output);
}
[Theory, AutoInitShutdown]
[InlineData ("blah")]
[InlineData (" ")]
public void CaptionedTextField_DoNotRenderCaption_WhenTextPresent (string content)
{
var tf = GetTextFieldsInView ();
tf.Draw ();
TestHelpers.AssertDriverContentsAre ("", output);
tf.Caption = "Enter txt";
Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
// Caption should appear when not focused and no text
Assert.False (tf.HasFocus);
tf.Draw ();
TestHelpers.AssertDriverContentsAre ("Enter txt", output);
// but disapear when text is added
tf.Text = content;
tf.Draw ();
TestHelpers.AssertDriverContentsAre (content, output);
}
[Fact, AutoInitShutdown]
public void CaptionedTextField_DoesNotOverspillBounds_Unicode ()
{
var caption = "Mise" + Char.ConvertFromUtf32 (Int32.Parse ("0301", NumberStyles.HexNumber)) + "rables";
Assert.Equal (11, caption.Length);
Assert.Equal (10, caption.EnumerateRunes ().Sum (c => c.GetColumns ()));
var tf = GetTextFieldsInView ();
tf.Caption = caption;
Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
Assert.False (tf.HasFocus);
tf.Draw ();
TestHelpers.AssertDriverContentsAre ("Misérables", output);
}
[Theory, AutoInitShutdown]
[InlineData ("0123456789", "0123456789")]
[InlineData ("01234567890", "0123456789")]
public void CaptionedTextField_DoesNotOverspillBounds (string caption, string expectedRender)
{
var tf = GetTextFieldsInView ();
// Caption has no effect when focused
tf.Caption = caption;
Application.Driver.SendKeys ('\t', ConsoleKey.Tab, false, false, false);
Assert.False (tf.HasFocus);
tf.Draw ();
TestHelpers.AssertDriverContentsAre (expectedRender, output);
}
private TextField GetTextFieldsInView ()
{
var tf = new TextField {
Width = 10
};
var tf2 = new TextField {
Y = 1,
Width = 10
};
var top = Application.Top;
top.Add (tf);
top.Add (tf2);
Application.Begin (top);
Assert.Same (tf, top.Focused);
return tf;
}
[Fact]
public void OnEnter_Does_Not_Throw_If_Not_IsInitialized_SetCursorVisibility ()
{
var top = new Toplevel ();
var tf = new TextField () { Width = 10 };
top.Add (tf);
var exception = Record.Exception (tf.SetFocus);
Assert.Null (exception);
}
[Fact]
public void WordBackward_WordForward_Mixed ()
{
var tf = new TextField ("Test with0. and!.?;-@+") { Width = 30 };
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorLeft, new KeyModifiers () { Ctrl = true }));
Assert.Equal (15, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorLeft, new KeyModifiers () { Ctrl = true }));
Assert.Equal (12, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorLeft, new KeyModifiers () { Ctrl = true }));
Assert.Equal (10, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorLeft, new KeyModifiers () { Ctrl = true }));
Assert.Equal (5, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorLeft, new KeyModifiers () { Ctrl = true }));
Assert.Equal (0, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorRight, new KeyModifiers () { Ctrl = true }));
Assert.Equal (5, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorRight, new KeyModifiers () { Ctrl = true }));
Assert.Equal (10, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorRight, new KeyModifiers () { Ctrl = true }));
Assert.Equal (12, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorRight, new KeyModifiers () { Ctrl = true }));
Assert.Equal (15, tf.CursorPosition);
tf.ProcessKey (new KeyEvent (Key.CtrlMask | Key.CursorRight, new KeyModifiers () { Ctrl = true }));
Assert.Equal (22, tf.CursorPosition);
}
[Fact, TextFieldTestsAutoInitShutdown]
public void Cursor_Position_Initialization ()
{
Assert.False (_textField.IsInitialized);
Assert.Equal (32, _textField.CursorPosition);
Assert.Equal (0, _textField.SelectedLength);
Assert.Null (_textField.SelectedText);
Assert.Equal ("TAB to jump between text fields.", _textField.Text);
}
[Fact, TextFieldTestsAutoInitShutdown]
public void Copy_Paste_Surrogate_Pairs ()
{
_textField.Text = "TextField with some more test text. Unicode shouldn't 𝔹A𝔽!";
_textField.SelectAll ();
_textField.Cut ();
Assert.Equal ("TextField with some more test text. Unicode shouldn't 𝔹A𝔽!", Application.Driver.Clipboard.GetClipboardData ());
Assert.Equal (string.Empty, _textField.Text);
_textField.Paste ();
Assert.Equal ("TextField with some more test text. Unicode shouldn't 𝔹A𝔽!", _textField.Text);
}
}
}