Fixes #4387. Runes should not be used on a cell, but rather should use a single grapheme rendering 1 or 2 columns (#4388)

* Fixes #4382. StringExtensions.GetColumns method should only return the total text width and not the sum of all runes width

* Trying to fix unit test error

* Update StringExtensions.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Resolving merge conflicts

* Prevents Runes throwing if Grapheme is null

* Add unit test to prove that null and empty string doesn't not throws anything.

* Fix unit test failure

* Fix IsValidLocation for wide graphemes

* Add more combining

* Prevent set invalid graphemes

* Fix unit tests

* Grapheme doesn't support invalid code points like lone surrogates

* Fixes more unit tests

* Fix unit test

* Seems all test are fixed now

* Adjust CharMap scenario with graphemes

* Upgrade Wcwidth to version 4.0.0

* Reformat

* Trying fix CheckDefaultState assertion

* Revert "Trying fix CheckDefaultState assertion"

This reverts commit c9b46b796a.

* Forgot to include driver.End in the test

* Reapply "Trying fix CheckDefaultState assertion"

This reverts commit 1060ac9b63.

* Remove ToString

* Fix merge errors

* Change to conditional expression

* Assertion to prove that no exception throws during cell initialization.

* Remove unnecessary assignment

* Remove assignment to end

* Replace string concatenation with 'StringBuilder'.

* Replace more string concatenation with 'StringBuilder'

* Remove redundant call to 'ToString' because Rune cast to a String object.

* Replace foreach loop with Sum linq

---------

Co-authored-by: Tig <tig@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
BDisp
2025-11-20 18:45:13 +00:00
committed by GitHub
parent 726b15dd28
commit cd75a20c60
53 changed files with 2654 additions and 2145 deletions

View File

@@ -792,19 +792,16 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
[MemberData (nameof (CMGlyphs))]
public void GetLengthThatFits_List_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
{
List<Rune> runes = text.ToRuneList ();
Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
}
[Theory]
[InlineData ("test", 3, 3)]
[InlineData ("test", 4, 4)]
[InlineData ("test", 10, 4)]
public void GetLengthThatFits_Runelist (string text, int columns, int expectedLength)
public void GetLengthThatFits_For_String (string text, int columns, int expectedLength)
{
List<Rune> runes = text.ToRuneList ();
Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
}
[Theory]
@@ -833,7 +830,8 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
public void GetLengthThatFits_With_Combining_Runes ()
{
var text = "Les Mise\u0328\u0301rables";
Assert.Equal (16, TextFormatter.GetLengthThatFits (text, 14));
Assert.Equal (14, TextFormatter.GetLengthThatFits (text, 14));
Assert.Equal ("Les Misę́rables", text);
}
[Fact]
@@ -841,14 +839,18 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
{
List<string> text = new () { "Les Mis", "e\u0328\u0301", "rables" };
Assert.Equal (1, TextFormatter.GetMaxColsForWidth (text, 1));
Assert.Equal ("Les Mis", text [0]);
Assert.Equal ("ę́", text [1]);
Assert.Equal ("rables", text [^1]);
}
//[Fact]
//public void GetWidestLineLength_With_Combining_Runes ()
//{
// var text = "Les Mise\u0328\u0301rables";
// Assert.Equal (1, TextFormatter.GetWidestLineLength (text, 1, 1));
//}
[Fact]
public void GetWidestLineLength_With_Combining_Runes ()
{
var text = "Les Mise\u0328\u0301rables";
Assert.Equal (14, TextFormatter.GetWidestLineLength (text, 1));
Assert.Equal ("Les Misę́rables", text);
}
[Fact]
public void Internal_Tests ()
@@ -2451,6 +2453,7 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
Assert.Equal (expected, breakLines);
// Double space Complex example - this is how VS 2022 does it
// which I think is not correct.
//text = "A sentence has words. ";
//breakLines = "";
//wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: true);
@@ -2762,8 +2765,7 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
"ฮ",
"ฯ",
"ะั",
"า",
"ำ"
"า"
}
)]
public void WordWrap_Unicode_SingleWordLine (
@@ -2798,7 +2800,17 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
Assert.True (
expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
);
Assert.Equal (resultLines, wrappedLines);
if (maxWidth == 1)
{
List<string> newResultLines = resultLines.ToList ();
newResultLines [^1] = "";
Assert.Equal (newResultLines, wrappedLines);
}
else
{
Assert.Equal (resultLines, wrappedLines);
}
}
/// <summary>WordWrap strips CRLF</summary>
@@ -3075,8 +3087,8 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
}
[Theory]
[InlineData (14, 1, TextDirection.LeftRight_TopBottom, "Les Misęrables")]
[InlineData (1, 14, TextDirection.TopBottom_LeftRight, "L\ne\ns\n \nM\ni\ns\nę\nr\na\nb\nl\ne\ns")]
[InlineData (14, 1, TextDirection.LeftRight_TopBottom, "Les Misę́rables")]
[InlineData (1, 14, TextDirection.TopBottom_LeftRight, "L\ne\ns\n \nM\ni\ns\nę́\nr\na\nb\nl\ne\ns")]
[InlineData (
4,
4,
@@ -3085,7 +3097,7 @@ public class TextFormatterTests (ITestOutputHelper output) : FakeDriverBase
LMre
eias
ssb
ęl "
ę́l "
)]
public void Draw_With_Combining_Runes (int width, int height, TextDirection textDirection, string expected)
{
@@ -3111,7 +3123,6 @@ ssb
driver.End ();
}
[Theory]
[InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")]
[InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")]
@@ -3187,7 +3198,6 @@ ssb
driver.End ();
}
[Theory]
[InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")]
[InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")]
@@ -3224,5 +3234,4 @@ ssb
driver.End ();
}
}