mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-28 00:38:00 +01:00
* Reduces indentation by remove the namespace braces. * Reduces indentation and removes unused using. * Ensures clear selection if it isn't selecting. * Turn on nullability context for TryParse and update usages as needed. * Use IsNullOrWhiteSpace, which includes IsNullOrEmpty All-whitespace values are also illegal, so may as well handle that here too * Respect the nullable here * It's a struct * Use byte.MaxValue and add remark * Just use the bytes directly * Must respect endianness * Add uint constructor so consumers don't have to do unchecked math * Completely re-work parsing and implement ISpanParsable<Color> All parsing is now almost-0 allocation, and is significantly faster than before * Extension methods required by new code * Use standard Math.Clamp method here * Add some new unit tests for TryParse * De-duplicate code and handle more cases * Enable nullability context for the file * Go ahead and enable the language features and analysis * Implicit usings remove a lot of boilerplate usings. * Add these to the dictionary to shut spell check up * Make this thing a record struct and a union, and update constructors This commit won't build. I'm just breaking out changes a little bit. * Some additional XmlDoc standardizing * Make FindClosestColor and CalculateColorDistance use the vector for SIMD * Add a TryFormat method for support of I*Formattable * Add an interface for support of custom formatting of Colors * Pass by in reference * Parse string delegates to Parse span * Parse now does all the work * Remove the old new code from TryParse * Some new cast operators * Add IFormattable.ToString implementation * Add the rest of the code for Color in its current (unfinished) state * Move that interface to its own file * Add ColorParseException class * Move Attribute to its own file, too. * Re-implement these operators as explicit methods * Get rid of fuzzy equality operators and update tests to use the named methods that replace them * Add an explicit test case for ToString with null format string and explicitly specified Invariant culture * Fix byte orders for hex format to be standard ARGB * Prove that ToString and Parse can round-trip values * Unroll this test into parameterized cases * Fix a couple of comments to match byte order * Update R# dictionary to match correct byte orders * Remove stray comment * Separate all types in this to their own files * Convert this one to use the handy extension * Add test for Argb property * Add a file nesting rule to make some incoming file changes display nicely * Move constructor tests to their own file and add some new tests * Add implicit cast from uint * More constructor tests * Since this is now a record, the equality operators are compiler generated Still spot-checking a few arbitrary values for completeness * Override ToString to delegate to Attribute * Simplify and clean up ToString. Delegate to ColorScheme * Update the test to match new output * These should be fields, really. It's a value type. * Add some type checks for change control * Allow unsafe and turn on implicit usings * Make this one better * Rename tests and remove redundant checks (the type checks already guarantee field consistency) * Reorganize a bit * Make these test 16 random values * Existing operator tests converted * That one is now redundant with both of the other tests that check all the named colors * Move this to type checks and simplify a little bit * These lambdas can be static * Move operators to another file. * Add global using for System.Text because it's EVERYWHERE * Reorganization of Color and some related types. Updated usages to reflect changes * Update tests to reflect changes in Terminal.Gui * Add missing keyword * Add entry to dictionary * Add dotsettings for Terminal.Gui Only specifies language level * Commit unsaved changes for usings here * Implement last remaining TryFormat method * A little cleanup/formality * Sorting rules Sort methods by name and interface they implement * Sort code * Match namespace for tests None! * Unroll ordinal check and reorganize. * Sort before writing new tests * These got reversed... * Add test to prove explicit cast to Vector3 works properly * Sort these too * Add test for uint->Color implicit operator * Add test for Color->uint implicit operator * Correct this test name and re-order * Add test for implicit conversion from Vector3 to Color * Add test for implicit conversion from Vector4 to Color * These also got reversed, like with Vector3 * Add test for implicit conversion from Color to Vector4 * Add test for GetHashCode * Make sure these are all under the same namespace * Remove a now-redundant test * Reorganize formatting and parsing tests to another type part * Tests moved back to Terminal.Gui.DrawingTests namespace as before. * Add tests for the constructor taking 3 or 4 integers and sort * Cleanup - Renamed some tests - Make a test even clearer - Removed redundant code - Got rid of unused parameter in Constructor_WithColorName_AllChannelsCorrect * That needs to be from the reverse map Not broken - just was sub-optimal due to my error. * Enable nullability context in this file Not sure how it got removed but whatev * Respect nullability context in this file now that it's on 🤦♂️ * Add tests for expected exceptions with whitespace or null values * Add test for parameterless constructor * A couple more places for reference passing and some SkipLocalsInit attributes. * Some XmlDoc corrections to reflect the final implementation * Remove namespace qualifier * Can't use these because of lambdas :( * Removed a collection that never ended up being needed. * Add bracing, newline, and modifier style rules * Add spacing rules inside parens/brackets * This was still under the Terminal.Gui.Drawing namespace. Revert that. * Applied updated formatting settings and addressed XmlDoc reviews in #3204 * More places where spaces got added in dependent code. Also a couple of null checks fixed to not use the equality operator * More dependent code format fixes * Finished re-formatting modified code that got spaces added everywhere * Visual studio didn't actually write this file to disk til I closed out of VS... Grr * Delete the ReSharper settings files from this branch. --------- Co-authored-by: BDisp <bd.bdisp@gmail.com>
253 lines
6.6 KiB
C#
253 lines
6.6 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 ());
|
|
}
|
|
|
|
|
|
// TODO: Move the tests below to View or Color - they test ColorScheme, not RuneCell primitives.
|
|
|
|
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.ColorSchemes ["TopLevel"].Focus,
|
|
// 1
|
|
Colors.ColorSchemes ["Base"].Focus,
|
|
// 2
|
|
Colors.ColorSchemes ["Dialog"].Focus,
|
|
// 3
|
|
Colors.ColorSchemes ["Menu"].Focus,
|
|
// 4
|
|
Colors.ColorSchemes ["Error"].Focus
|
|
};
|
|
var expectedColor = @"
|
|
0000000000
|
|
1111000000
|
|
2222220000
|
|
3333000000
|
|
4444400000";
|
|
TestHelpers.AssertDriverAttributesAre (expectedColor, driver: Application.Driver, attributes);
|
|
|
|
tv.WordWrap = true;
|
|
Application.Refresh ();
|
|
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
|
|
TestHelpers.AssertDriverAttributesAre (expectedColor, driver: Application.Driver, 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.AssertDriverAttributesAre (expectedColor, driver: Application.Driver, 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.AssertDriverAttributesAre (expectedColor, driver: Application.Driver, 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);
|
|
}
|
|
}
|
|
}
|