mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Fixes #2680. Make the TextView API more extensible. * Remove unnecessary using. * Add GetLine method. * Change RuneCell Attribute property to ColorScheme property. * Add LoadRuneCells method and unit test. * Add helper method to set all the Colors.ColorSchemes with the same attribute. * Change RuneCell to class. * Add IEquatable<RuneCell> interface. * Fix unit test. * Still fixing unit test. * Fixes #2688. ReadOnly TextView's broken scrolling after version update. * keyModifiers must be reset after key up was been processed. * Trying fix server unit test error. * Prevents throw an exception if RuneCell is null. * Still trying fix this unit test. * Cleaning code. * Fix when the RuneCell is null. * Fix throwing an exception if current column position is greater than the line length. * Fixes #2689. Autocomplete doesn't popup after typing the first character. * Fix Used on TextField. * Always use the original ColorScheme if RuneCell.ColorScheme is null. * Fix Used on TextView. * Add RuneCellEventArgs and draw colors events. * Add two more samples to the scenario. * Fix a bug which was causing unit tests with ColorScheme fail. * Fix a issue when WordWrap is true by always loading the old text. * Improves debugging in RuneCell. * WordWrap is now preserving the ColorScheme of the unwrapped lines. * Simplifying unit test. * Ensures the foreground and background colors are never the same if Used is false. * Remove nullable from the parameter. * Merge syntax highlighting of quotes and keywords together * Add IdxRow property into the RuneCellEventArgs. * Fix pos calculation on windows (where newline in Text is \r\n not \n) * Fix events not being cleared when toggling samples. * Change Undo and Redo to a public method. * Changes some methods names to be more explicit. * Call OnContentsChanged on needed methods and fix some more bugs. * Adds InheritsPreviousColorScheme to allow LoadRuneCells uses personalized color schemes. * Serializes and deserializes RuneCell to a .rce extension file. * Prevents throwing if column is bigger than the line. * Avoids create a color attribute without one of the foreground or background values. In Linux using -1 throws an exception. * Replace SetAllAttributesBasedOn method with a ColorScheme constructor. * Move RuneCell string extensions to TextView.cs * Reverted parameter name from cell to rune. * Change Row to UnwrappedPosition which provide the real unwrapped text position within the Col. * Add brackets to Undo and Redo methods. * Replace all the LoadXXX with Load and rely on the param type to differentiate. * Open a file inside a using. * Proves that the events run twice for WordWrap disabled and the enabled. * Remove GetColumns extension for RuneCell. * Add braces to Undo an Redo. * Change comment. * Add braces. * Delete remarks tag. * Explaining used color and ProcessInheritsPreviousColorScheme. * Fix comment. * Created a RuneCellTests.cs file. * Rename to StringToLinesOfRuneCells. * Make ToRuneCells private. --------- Co-authored-by: Thomas <tznind@dundee.ac.uk> Co-authored-by: Thomas Nind <31306100+tznind@users.noreply.github.com>
250 lines
6.3 KiB
C#
250 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace Terminal.Gui.ViewsTests {
|
|
public class RuneCellTests {
|
|
readonly ITestOutputHelper _output;
|
|
|
|
public RuneCellTests (ITestOutputHelper output)
|
|
{
|
|
_output = output;
|
|
}
|
|
|
|
[Fact]
|
|
public void Constructor_Defaults ()
|
|
{
|
|
var rc = new RuneCell ();
|
|
Assert.NotNull (rc);
|
|
Assert.Equal (0, rc.Rune.Value);
|
|
Assert.Null (rc.ColorScheme);
|
|
}
|
|
|
|
[Fact]
|
|
public void Equals_True ()
|
|
{
|
|
var rc1 = new RuneCell ();
|
|
var rc2 = new RuneCell ();
|
|
Assert.True (rc1.Equals (rc2));
|
|
Assert.True (rc2.Equals (rc1));
|
|
|
|
rc1.Rune = new Rune ('a');
|
|
rc1.ColorScheme = new ColorScheme ();
|
|
rc2.Rune = new Rune ('a');
|
|
rc2.ColorScheme = new ColorScheme ();
|
|
Assert.True (rc1.Equals (rc2));
|
|
Assert.True (rc2.Equals (rc1));
|
|
}
|
|
|
|
[Fact]
|
|
public void Equals_False ()
|
|
{
|
|
var rc1 = new RuneCell ();
|
|
var rc2 = new RuneCell () {
|
|
Rune = new Rune ('a'),
|
|
ColorScheme = new ColorScheme () { Normal = new Attribute (Color.Red) }
|
|
};
|
|
Assert.False (rc1.Equals (rc2));
|
|
Assert.False (rc2.Equals (rc1));
|
|
|
|
rc1.Rune = new Rune ('a');
|
|
rc1.ColorScheme = new ColorScheme ();
|
|
Assert.Equal (rc1.Rune, rc2.Rune);
|
|
Assert.False (rc1.Equals (rc2));
|
|
Assert.False (rc2.Equals (rc1));
|
|
}
|
|
|
|
[Fact]
|
|
public void ToString_Override ()
|
|
{
|
|
var rc1 = new RuneCell ();
|
|
var rc2 = new RuneCell () {
|
|
Rune = new Rune ('a'),
|
|
ColorScheme = new ColorScheme () { Normal = new Attribute (Color.Red) }
|
|
};
|
|
Assert.Equal ("U+0000 '\0'; null", rc1.ToString ());
|
|
Assert.Equal ("U+0061 'a'; Normal: Red,Red; Focus: White,Black; HotNormal: White,Black; HotFocus: White,Black; Disabled: White,Black", rc2.ToString ());
|
|
}
|
|
|
|
private TextView CreateTextView ()
|
|
{
|
|
return new TextView () { Width = 30, Height = 10 };
|
|
}
|
|
|
|
[Fact, AutoInitShutdown]
|
|
public void RuneCell_LoadRuneCells_InheritsPreviousColorScheme ()
|
|
{
|
|
List<RuneCell> runeCells = new List<RuneCell> ();
|
|
foreach (var color in Colors.ColorSchemes) {
|
|
string csName = color.Key;
|
|
foreach (var rune in csName.EnumerateRunes ()) {
|
|
runeCells.Add (new RuneCell { Rune = rune, ColorScheme = color.Value });
|
|
}
|
|
runeCells.Add (new RuneCell { Rune = (Rune)'\n', ColorScheme = color.Value });
|
|
}
|
|
|
|
var tv = CreateTextView ();
|
|
tv.Load (runeCells);
|
|
Application.Top.Add (tv);
|
|
var rs = Application.Begin (Application.Top);
|
|
Assert.True (tv.InheritsPreviousColorScheme);
|
|
var expectedText = @"
|
|
TopLevel
|
|
Base
|
|
Dialog
|
|
Menu
|
|
Error ";
|
|
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
|
|
|
|
var attributes = new Attribute [] {
|
|
// 0
|
|
Colors.TopLevel.Focus,
|
|
// 1
|
|
Colors.Base.Focus,
|
|
// 2
|
|
Colors.Dialog.Focus,
|
|
// 3
|
|
Colors.Menu.Focus,
|
|
// 4
|
|
Colors.Error.Focus
|
|
};
|
|
var expectedColor = @"
|
|
0000000000
|
|
1111000000
|
|
2222220000
|
|
3333000000
|
|
4444400000";
|
|
TestHelpers.AssertDriverColorsAre (expectedColor, attributes);
|
|
|
|
tv.WordWrap = true;
|
|
Application.Refresh ();
|
|
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
|
|
TestHelpers.AssertDriverColorsAre (expectedColor, attributes);
|
|
|
|
tv.CursorPosition = new Point (6, 2);
|
|
tv.SelectionStartColumn = 0;
|
|
tv.SelectionStartRow = 0;
|
|
Assert.Equal ($"TopLevel{Environment.NewLine}Base{Environment.NewLine}Dialog", tv.SelectedText);
|
|
tv.Copy ();
|
|
tv.Selecting = false;
|
|
tv.CursorPosition = new Point (2, 4);
|
|
tv.Paste ();
|
|
Application.Refresh ();
|
|
expectedText = @"
|
|
TopLevel
|
|
Base
|
|
Dialog
|
|
Menu
|
|
ErTopLevel
|
|
Base
|
|
Dialogror ";
|
|
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
|
|
expectedColor = @"
|
|
0000000000
|
|
1111000000
|
|
2222220000
|
|
3333000000
|
|
4444444444
|
|
4444000000
|
|
4444444440";
|
|
TestHelpers.AssertDriverColorsAre (expectedColor, attributes);
|
|
|
|
tv.Undo ();
|
|
tv.CursorPosition = new Point (0, 3);
|
|
tv.SelectionStartColumn = 0;
|
|
tv.SelectionStartRow = 0;
|
|
Assert.Equal ($"TopLevel{Environment.NewLine}Base{Environment.NewLine}Dialog{Environment.NewLine}", tv.SelectedText);
|
|
tv.Copy ();
|
|
tv.Selecting = false;
|
|
tv.CursorPosition = new Point (2, 4);
|
|
tv.Paste ();
|
|
Application.Refresh ();
|
|
expectedText = @"
|
|
TopLevel
|
|
Base
|
|
Dialog
|
|
Menu
|
|
ErTopLevel
|
|
Base
|
|
Dialog
|
|
ror ";
|
|
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
|
|
expectedColor = @"
|
|
0000000000
|
|
1111000000
|
|
2222220000
|
|
3333000000
|
|
4444444444
|
|
4444000000
|
|
4444440000
|
|
4440000000";
|
|
TestHelpers.AssertDriverColorsAre (expectedColor, attributes);
|
|
|
|
Application.End (rs);
|
|
}
|
|
|
|
[Fact, AutoInitShutdown]
|
|
public void RuneCell_LoadRuneCells_Without_ColorScheme_Is_Never_Null ()
|
|
{
|
|
var cells = new List<RuneCell> {
|
|
new RuneCell{Rune = new Rune ('T')},
|
|
new RuneCell{Rune = new Rune ('e')},
|
|
new RuneCell{Rune = new Rune ('s')},
|
|
new RuneCell{Rune = new Rune ('t')}
|
|
};
|
|
var tv = CreateTextView ();
|
|
Application.Top.Add (tv);
|
|
tv.Load (cells);
|
|
|
|
for (int i = 0; i < tv.Lines; i++) {
|
|
var line = tv.GetLine (i);
|
|
foreach (var rc in line) {
|
|
Assert.NotNull (rc.ColorScheme);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact, AutoInitShutdown]
|
|
public void RuneCellEventArgs_WordWrap_True ()
|
|
{
|
|
var eventCount = 0;
|
|
var text = new List<List<RuneCell>> () { TextModel.ToRuneCells ("This is the first line.".ToRunes ()), TextModel.ToRuneCells ("This is the second line.".ToRunes ()) };
|
|
var tv = CreateTextView ();
|
|
tv.DrawNormalColor += _textView_DrawColor;
|
|
tv.DrawReadOnlyColor += _textView_DrawColor;
|
|
tv.DrawSelectionColor += _textView_DrawColor;
|
|
tv.DrawUsedColor += _textView_DrawColor;
|
|
void _textView_DrawColor (object sender, RuneCellEventArgs e)
|
|
{
|
|
Assert.Equal (e.Line [e.Col], text [e.UnwrappedPosition.Row] [e.UnwrappedPosition.Col]);
|
|
eventCount++;
|
|
}
|
|
tv.Text = $"{TextModel.ToString (text [0])}\n{TextModel.ToString (text [1])}\n";
|
|
Assert.False (tv.WordWrap);
|
|
Application.Top.Add (tv);
|
|
Application.Begin (Application.Top);
|
|
TestHelpers.AssertDriverContentsWithFrameAre (@"
|
|
This is the first line.
|
|
This is the second line.", _output);
|
|
|
|
tv.Width = 10;
|
|
tv.Height = 25;
|
|
tv.WordWrap = true;
|
|
Application.Refresh ();
|
|
TestHelpers.AssertDriverContentsWithFrameAre (@"
|
|
This is
|
|
the
|
|
first
|
|
line.
|
|
This is
|
|
the
|
|
second
|
|
line. ", _output);
|
|
|
|
Assert.Equal (eventCount, (text [0].Count + text [1].Count) * 2);
|
|
}
|
|
}
|
|
}
|