diff --git a/NativeAot/Program.cs b/NativeAot/Program.cs
index 5ef38db05..4aae3c099 100644
--- a/NativeAot/Program.cs
+++ b/NativeAot/Program.cs
@@ -17,14 +17,14 @@ public static class Program
#region The code in this region is not intended for use in a native Aot self-contained. It's just here to make sure there is no functionality break with localization in Terminal.Gui using self-contained
- if (Equals(Thread.CurrentThread.CurrentUICulture, CultureInfo.InvariantCulture) && Application.SupportedCultures.Count == 0)
+ if (Equals(Thread.CurrentThread.CurrentUICulture, CultureInfo.InvariantCulture) && Application.SupportedCultures!.Count == 0)
{
// Only happens if the project has true
Debug.Assert (Application.SupportedCultures.Count == 0);
}
else
{
- Debug.Assert (Application.SupportedCultures.Count > 0);
+ Debug.Assert (Application.SupportedCultures!.Count > 0);
Debug.Assert (Equals (CultureInfo.CurrentCulture, Thread.CurrentThread.CurrentUICulture));
}
diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs
index 21e3df5ab..e60ed61d2 100644
--- a/Terminal.Gui/Application/Application.Keyboard.cs
+++ b/Terminal.Gui/Application/Application.Keyboard.cs
@@ -190,7 +190,7 @@ public static partial class Application // Keyboard handling
foreach (Command command in appBinding.Commands)
{
- if (!CommandImplementations.ContainsKey (command))
+ if (!CommandImplementations!.ContainsKey (command))
{
throw new NotSupportedException (
@$"A KeyBinding was set up for the command {command} ({keyEvent}) but that command is not supported by Application."
@@ -274,7 +274,7 @@ public static partial class Application // Keyboard handling
///
/// Commands for Application.
///
- private static Dictionary> CommandImplementations { get; set; }
+ private static Dictionary>? CommandImplementations { get; set; }
///
///
@@ -292,7 +292,7 @@ public static partial class Application // Keyboard handling
///
/// The command.
/// The function.
- private static void AddCommand (Command command, Func f) { CommandImplementations [command] = ctx => f (); }
+ private static void AddCommand (Command command, Func f) { CommandImplementations! [command] = ctx => f (); }
static Application () { AddApplicationKeyBindings (); }
@@ -432,31 +432,4 @@ public static partial class Application // Keyboard handling
.Distinct ()
.ToList ();
}
-
- /////
- ///// Gets the list of Views that have key bindings for the specified key.
- /////
- /////
- ///// This is an internal method used by the class to add Application key bindings.
- /////
- ///// The key to check.
- ///// Outputs the list of views bound to
- ///// if successful.
- //internal static bool TryGetKeyBindings (Key key, out List views) { return _keyBindings.TryGetValue (key, out views); }
-
- ///
- /// Removes all scoped key bindings for the specified view.
- ///
- ///
- /// This is an internal method used by the class to remove Application key bindings.
- ///
- /// The view that is bound to the key.
- internal static void RemoveKeyBindings (View view)
- {
- List list = KeyBindings.Bindings
- .Where (kv => kv.Value.Scope != KeyBindingScope.Application)
- .Select (kv => kv.Value)
- .Distinct ()
- .ToList ();
- }
}
diff --git a/Terminal.Gui/Application/Application.cs b/Terminal.Gui/Application/Application.cs
index fe1a5cd55..bcb8d5b3b 100644
--- a/Terminal.Gui/Application/Application.cs
+++ b/Terminal.Gui/Application/Application.cs
@@ -32,7 +32,7 @@ public static partial class Application
/// A string representation of the Application
public new static string ToString ()
{
- ConsoleDriver driver = Driver;
+ ConsoleDriver? driver = Driver;
if (driver is null)
{
@@ -47,13 +47,17 @@ public static partial class Application
///
/// The driver to use to render the contents.
/// A string representation of the Application
- public static string ToString (ConsoleDriver driver)
+ public static string ToString (ConsoleDriver? driver)
{
+ if (driver is null)
+ {
+ return string.Empty;
+ }
var sb = new StringBuilder ();
- Cell [,] contents = driver.Contents;
+ Cell [,] contents = driver?.Contents!;
- for (var r = 0; r < driver.Rows; r++)
+ for (var r = 0; r < driver!.Rows; r++)
{
for (var c = 0; c < driver.Cols; c++)
{
diff --git a/Terminal.Gui/Drawing/Thickness.cs b/Terminal.Gui/Drawing/Thickness.cs
index 8585ccb38..d96ab73ea 100644
--- a/Terminal.Gui/Drawing/Thickness.cs
+++ b/Terminal.Gui/Drawing/Thickness.cs
@@ -61,7 +61,7 @@ public record struct Thickness
[JsonInclude]
public int Bottom
{
- get => (int)_sides.W;
+ readonly get => (int)_sides.W;
set => _sides.W = value;
}
@@ -249,7 +249,7 @@ public record struct Thickness
[JsonInclude]
public int Left
{
- get => (int)_sides.X;
+ readonly get => (int)_sides.X;
set => _sides.X = value;
}
@@ -265,7 +265,7 @@ public record struct Thickness
[JsonInclude]
public int Right
{
- get => (int)_sides.Z;
+ readonly get => (int)_sides.Z;
set => _sides.Z = value;
}
@@ -273,7 +273,7 @@ public record struct Thickness
[JsonInclude]
public int Top
{
- get => (int)_sides.Y;
+ readonly get => (int)_sides.Y;
set => _sides.Y = value;
}
diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs
index 73625417a..7a7fd35c5 100644
--- a/Terminal.Gui/View/View.Keyboard.cs
+++ b/Terminal.Gui/View/View.Keyboard.cs
@@ -27,7 +27,6 @@ public partial class View // Keyboard APIs
private void DisposeKeyboard ()
{
TitleTextFormatter.HotKeyChanged -= TitleTextFormatter_HotKeyChanged;
- Application.RemoveKeyBindings (this);
}
#region HotKey Support
diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs
index b05593fda..55f174c34 100644
--- a/Terminal.Gui/Views/Label.cs
+++ b/Terminal.Gui/Views/Label.cs
@@ -51,9 +51,9 @@ public class Label : View
set => TextFormatter.HotKeySpecifier = base.HotKeySpecifier = value;
}
- private new bool? FocusNext ()
+ private bool? FocusNext ()
{
- var me = SuperView?.Subviews.IndexOf (this) ?? -1;
+ int me = SuperView?.Subviews.IndexOf (this) ?? -1;
if (me != -1 && me < SuperView?.Subviews.Count - 1)
{
SuperView?.Subviews [me + 1].SetFocus ();
diff --git a/Terminal.Gui/Views/NumericUpDown.cs b/Terminal.Gui/Views/NumericUpDown.cs
index 279cfd6cf..7ca7d463a 100644
--- a/Terminal.Gui/Views/NumericUpDown.cs
+++ b/Terminal.Gui/Views/NumericUpDown.cs
@@ -100,7 +100,7 @@ public class NumericUpDown : View where T : notnull
return false;
}
- if (Value is { })
+ if (Value is { } && Increment is { })
{
Value = (dynamic)Value + (dynamic)Increment;
}
@@ -117,11 +117,12 @@ public class NumericUpDown : View where T : notnull
return false;
}
- if (Value is { })
+ if (Value is { } && Increment is { })
{
Value = (dynamic)Value - (dynamic)Increment;
}
+
return true;
});
@@ -218,23 +219,23 @@ public class NumericUpDown : View where T : notnull
Text = _number.Text;
}
- private T _increment;
+ private T? _increment;
///
///
- public T Increment
+ public T? Increment
{
get => _increment;
set
{
- if ((dynamic)_increment == (dynamic)value)
+ if (_increment is { } && value is { } && (dynamic)_increment == (dynamic)value)
{
return;
}
_increment = value;
- IncrementChanged?.Invoke (this, new (value));
+ IncrementChanged?.Invoke (this, new (value!));
}
}
diff --git a/UICatalog/Scenarios/ListViewWithSelection.cs b/UICatalog/Scenarios/ListViewWithSelection.cs
index f9bb7ea03..e22b2e2ec 100644
--- a/UICatalog/Scenarios/ListViewWithSelection.cs
+++ b/UICatalog/Scenarios/ListViewWithSelection.cs
@@ -202,9 +202,11 @@ public class ListViewWithSelection : Scenario
return false;
}
-
+#pragma warning disable CS0067
///
public event NotifyCollectionChangedEventHandler CollectionChanged;
+#pragma warning restore CS0067
+
public int Count => Scenarios?.Count ?? 0;
public int Length { get; private set; }
public bool SuspendCollectionChangedEvent { get => throw new System.NotImplementedException (); set => throw new System.NotImplementedException (); }
diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs
index aff6dd975..14b06f6e5 100644
--- a/UICatalog/UICatalog.cs
+++ b/UICatalog/UICatalog.cs
@@ -643,7 +643,7 @@ public class UICatalogApp
Add (CategoryList);
Add (ScenarioList);
- Add (MenuBar);
+ Add (MenuBar!);
if (StatusBar is { })
{
diff --git a/UnitTests/Configuration/ConfigurationMangerTests.cs b/UnitTests/Configuration/ConfigurationMangerTests.cs
index 44b681d28..fbca323b5 100644
--- a/UnitTests/Configuration/ConfigurationMangerTests.cs
+++ b/UnitTests/Configuration/ConfigurationMangerTests.cs
@@ -389,6 +389,7 @@ public class ConfigurationManagerTests
)
);
+#pragma warning disable xUnit2029
Assert.Empty (
Settings.Where (
cp => cp.Value.PropertyInfo!.GetCustomAttribute (
@@ -397,6 +398,7 @@ public class ConfigurationManagerTests
== null
)
);
+#pragma warning restore xUnit2029
// Application is a static class
PropertyInfo pi = typeof (Application).GetProperty ("QuitKey");
diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs
index 31d2f59f0..109065302 100644
--- a/UnitTests/Text/TextFormatterTests.cs
+++ b/UnitTests/Text/TextFormatterTests.cs
@@ -1,4 +1,5 @@
using System.Text;
+using UICatalog;
using Xunit.Abstractions;
// Alias Console to MockConsole so we don't accidentally use Console
@@ -7,37 +8,8 @@ namespace Terminal.Gui.TextTests;
public class TextFormatterTests
{
- private readonly ITestOutputHelper _output;
public TextFormatterTests (ITestOutputHelper output) { _output = output; }
-
- public static IEnumerable CMGlyphs =>
- new List { new object [] { $"{CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}", 16, 15 } };
-
- public static IEnumerable FormatEnvironmentNewLine =>
- new List
- {
- new object []
- {
- $"Line1{Environment.NewLine}Line2{Environment.NewLine}Line3{Environment.NewLine}",
- 60,
- new [] { "Line1", "Line2", "Line3" }
- }
- };
-
- public static IEnumerable SplitEnvironmentNewLine =>
- new List
- {
- new object []
- {
- $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界",
- new [] { "First Line 界", "Second Line 界", "Third Line 界" }
- },
- new object []
- {
- $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界{Environment.NewLine}",
- new [] { "First Line 界", "Second Line 界", "Third Line 界", "" }
- }
- };
+ private readonly ITestOutputHelper _output;
[Theory]
[InlineData ("")]
@@ -262,2760 +234,8 @@ public class TextFormatterTests
);
}
- [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 (
- 4,
- 4,
- TextDirection.TopBottom_LeftRight,
- @"
-LMre
-eias
-ssb
- ęl "
- )]
- public void Draw_With_Combining_Runes (int width, int height, TextDirection textDirection, string expected)
- {
- var driver = new FakeDriver ();
- driver.Init ();
-
- var text = "Les Mise\u0328\u0301rables";
-
- var tf = new TextFormatter ();
- tf.Direction = textDirection;
- tf.Text = text;
-
- Assert.True (tf.WordWrap);
-
- tf.ConstrainToSize = new (width, height);
-
- tf.Draw (
- new (0, 0, width, height),
- new (ColorName.White, ColorName.Black),
- new (ColorName.Blue, ColorName.Black),
- default (Rectangle),
- driver
- );
- TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
-
- driver.End ();
- }
-
- [Fact]
- [SetupFakeDriver]
- public void FillRemaining_True_False ()
- {
- ((FakeDriver)Application.Driver!).SetBufferSize (22, 5);
-
- Attribute [] attrs =
- {
- Attribute.Default, new (ColorName.Green, ColorName.BrightMagenta),
- new (ColorName.Blue, ColorName.Cyan)
- };
- var tf = new TextFormatter { ConstrainToSize = new (14, 3), Text = "Test\nTest long\nTest long long\n", MultiLine = true };
-
- tf.Draw (
- new (1, 1, 19, 3),
- attrs [1],
- attrs [2]);
-
- Assert.False (tf.FillRemaining);
-
- TestHelpers.AssertDriverContentsWithFrameAre (
- @"
- Test
- Test long
- Test long long",
- _output);
-
- TestHelpers.AssertDriverAttributesAre (
- @"
-000000000000000000000
-011110000000000000000
-011111111100000000000
-011111111111111000000
-000000000000000000000",
- null,
- attrs);
-
- tf.FillRemaining = true;
-
- tf.Draw (
- new (1, 1, 19, 3),
- attrs [1],
- attrs [2]);
-
- TestHelpers.AssertDriverAttributesAre (
- @"
-000000000000000000000
-011111111111111111110
-011111111111111111110
-011111111111111111110
-000000000000000000000",
- null,
- attrs);
- }
-
- [Theory]
- [InlineData ("_k Before", true, 0, (KeyCode)'K')] // lower case should return uppercase Hotkey
- [InlineData ("a_k Second", true, 1, (KeyCode)'K')]
- [InlineData ("Last _k", true, 5, (KeyCode)'K')]
- [InlineData ("After k_", false, -1, KeyCode.Null)]
- [InlineData ("Multiple _k and _R", true, 9, (KeyCode)'K')]
- [InlineData ("Non-english: _кдать", true, 13, (KeyCode)'к')] // Lower case Cryllic K (к)
- [InlineData ("_k Before", true, 0, (KeyCode)'K', true)] // Turn on FirstUpperCase and verify same results
- [InlineData ("a_k Second", true, 1, (KeyCode)'K', true)]
- [InlineData ("Last _k", true, 5, (KeyCode)'K', true)]
- [InlineData ("After k_", false, -1, KeyCode.Null, true)]
- [InlineData ("Multiple _k and _r", true, 9, (KeyCode)'K', true)]
- [InlineData ("Non-english: _кдать", true, 13, (KeyCode)'к', true)] // Cryllic K (К)
- public void FindHotKey_AlphaLowerCase_Succeeds (
- string text,
- bool expectedResult,
- int expectedHotPos,
- KeyCode expectedKey,
- bool supportFirstUpperCase = false
- )
- {
- var hotKeySpecifier = (Rune)'_';
-
- bool result = TextFormatter.FindHotKey (
- text,
- hotKeySpecifier,
- out int hotPos,
- out Key hotKey,
- supportFirstUpperCase
- );
-
- if (expectedResult)
- {
- Assert.True (result);
- }
- else
- {
- Assert.False (result);
- }
-
- Assert.Equal (expectedResult, result);
- Assert.Equal (expectedHotPos, hotPos);
- Assert.Equal (expectedKey, hotKey);
- }
-
- [Theory]
- [InlineData ("_K Before", true, 0, (KeyCode)'K')]
- [InlineData ("a_K Second", true, 1, (KeyCode)'K')]
- [InlineData ("Last _K", true, 5, (KeyCode)'K')]
- [InlineData ("After K_", false, -1, KeyCode.Null)]
- [InlineData ("Multiple _K and _R", true, 9, (KeyCode)'K')]
- [InlineData ("Non-english: _Кдать", true, 13, (KeyCode)'К')] // Cryllic K (К)
- [InlineData ("_K Before", true, 0, (KeyCode)'K', true)] // Turn on FirstUpperCase and verify same results
- [InlineData ("a_K Second", true, 1, (KeyCode)'K', true)]
- [InlineData ("Last _K", true, 5, (KeyCode)'K', true)]
- [InlineData ("After K_", false, -1, KeyCode.Null, true)]
- [InlineData ("Multiple _K and _R", true, 9, (KeyCode)'K', true)]
- [InlineData ("Non-english: _Кдать", true, 13, (KeyCode)'К', true)] // Cryllic K (К)
- public void FindHotKey_AlphaUpperCase_Succeeds (
- string text,
- bool expectedResult,
- int expectedHotPos,
- KeyCode expectedKey,
- bool supportFirstUpperCase = false
- )
- {
- var hotKeySpecifier = (Rune)'_';
-
- bool result = TextFormatter.FindHotKey (
- text,
- hotKeySpecifier,
- out int hotPos,
- out Key hotKey,
- supportFirstUpperCase
- );
-
- if (expectedResult)
- {
- Assert.True (result);
- }
- else
- {
- Assert.False (result);
- }
-
- Assert.Equal (expectedResult, result);
- Assert.Equal (expectedHotPos, hotPos);
- Assert.Equal (expectedKey, hotKey);
- }
-
- [Theory]
- [InlineData (null)]
- [InlineData ("")]
- [InlineData ("no hotkey")]
- [InlineData ("No hotkey, Upper Case")]
- [InlineData ("Non-english: Сохранить")]
- public void FindHotKey_Invalid_ReturnsFalse (string text)
- {
- var hotKeySpecifier = (Rune)'_';
- var supportFirstUpperCase = false;
- var hotPos = 0;
- Key hotKey = KeyCode.Null;
- var result = false;
-
- result = TextFormatter.FindHotKey (
- text,
- hotKeySpecifier,
- out hotPos,
- out hotKey,
- supportFirstUpperCase
- );
- Assert.False (result);
- Assert.Equal (-1, hotPos);
- Assert.Equal (KeyCode.Null, hotKey);
- }
-
- [Theory]
- [InlineData ("\"k before")]
- [InlineData ("ak second")]
- [InlineData ("last k")]
- [InlineData ("multiple k and r")]
- [InlineData ("12345")]
- [InlineData ("`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?")] // punctuation
- [InlineData (" ~ s gui.cs master ↑10")] // ~IsLetterOrDigit + Unicode
- [InlineData ("non-english: кдать")] // Lower case Cryllic K (к)
- public void FindHotKey_Legacy_FirstUpperCase_NotFound_Returns_False (string text)
- {
- var supportFirstUpperCase = true;
-
- var hotKeySpecifier = (Rune)0;
-
- bool result = TextFormatter.FindHotKey (
- text,
- hotKeySpecifier,
- out int hotPos,
- out Key hotKey,
- supportFirstUpperCase
- );
- Assert.False (result);
- Assert.Equal (-1, hotPos);
- Assert.Equal (KeyCode.Null, hotKey);
- }
-
- [Theory]
- [InlineData ("K Before", true, 0, (KeyCode)'K')]
- [InlineData ("aK Second", true, 1, (KeyCode)'K')]
- [InlineData ("last K", true, 5, (KeyCode)'K')]
- [InlineData ("multiple K and R", true, 9, (KeyCode)'K')]
- [InlineData ("non-english: Кдать", true, 13, (KeyCode)'К')] // Cryllic K (К)
- public void FindHotKey_Legacy_FirstUpperCase_Succeeds (
- string text,
- bool expectedResult,
- int expectedHotPos,
- KeyCode expectedKey
- )
- {
- var supportFirstUpperCase = true;
-
- var hotKeySpecifier = (Rune)0;
-
- bool result = TextFormatter.FindHotKey (
- text,
- hotKeySpecifier,
- out int hotPos,
- out Key hotKey,
- supportFirstUpperCase
- );
-
- if (expectedResult)
- {
- Assert.True (result);
- }
- else
- {
- Assert.False (result);
- }
-
- Assert.Equal (expectedResult, result);
- Assert.Equal (expectedHotPos, hotPos);
- Assert.Equal (expectedKey, hotKey);
- }
-
- [Theory]
- [InlineData ("_1 Before", true, 0, (KeyCode)'1')] // Digits
- [InlineData ("a_1 Second", true, 1, (KeyCode)'1')]
- [InlineData ("Last _1", true, 5, (KeyCode)'1')]
- [InlineData ("After 1_", false, -1, KeyCode.Null)]
- [InlineData ("Multiple _1 and _2", true, 9, (KeyCode)'1')]
- [InlineData ("_1 Before", true, 0, (KeyCode)'1', true)] // Turn on FirstUpperCase and verify same results
- [InlineData ("a_1 Second", true, 1, (KeyCode)'1', true)]
- [InlineData ("Last _1", true, 5, (KeyCode)'1', true)]
- [InlineData ("After 1_", false, -1, KeyCode.Null, true)]
- [InlineData ("Multiple _1 and _2", true, 9, (KeyCode)'1', true)]
- public void FindHotKey_Numeric_Succeeds (
- string text,
- bool expectedResult,
- int expectedHotPos,
- KeyCode expectedKey,
- bool supportFirstUpperCase = false
- )
- {
- var hotKeySpecifier = (Rune)'_';
-
- bool result = TextFormatter.FindHotKey (
- text,
- hotKeySpecifier,
- out int hotPos,
- out Key hotKey,
- supportFirstUpperCase
- );
-
- if (expectedResult)
- {
- Assert.True (result);
- }
- else
- {
- Assert.False (result);
- }
-
- Assert.Equal (expectedResult, result);
- Assert.Equal (expectedHotPos, hotPos);
- Assert.Equal (expectedKey, hotKey);
- }
-
- [Theory]
- [InlineData ("_\"k before", true, (KeyCode)'"')] // BUGBUG: Not sure why this fails. " is a normal char
- [InlineData ("\"_k before", true, KeyCode.K)]
- [InlineData ("_`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", true, (KeyCode)'`')]
- [InlineData ("`_~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", true, (KeyCode)'~')]
- [InlineData (
- "`~!@#$%^&*()-__=+[{]}\\|;:'\",<.>/?",
- true,
- (KeyCode)'='
- )] // BUGBUG: Not sure why this fails. Ignore the first and consider the second
- [InlineData ("_ ~ s gui.cs master ↑10", true, (KeyCode)'')] // ~IsLetterOrDigit + Unicode
- [InlineData (" ~ s gui.cs _ master ↑10", true, (KeyCode)'')] // ~IsLetterOrDigit + Unicode
- [InlineData ("non-english: _кдать", true, (KeyCode)'к')] // Lower case Cryllic K (к)
- public void FindHotKey_Symbols_Returns_Symbol (string text, bool found, KeyCode expected)
- {
- var hotKeySpecifier = (Rune)'_';
-
- bool result = TextFormatter.FindHotKey (text, hotKeySpecifier, out int _, out Key hotKey);
- Assert.Equal (found, result);
- Assert.Equal (expected, hotKey);
- }
-
- [Fact]
- public void Format_Dont_Throw_ArgumentException_With_WordWrap_As_False_And_Keep_End_Spaces_As_True ()
- {
- Exception exception = Record.Exception (
- () =>
- TextFormatter.Format (
- "Some text",
- 4,
- Alignment.Start,
- false,
- true
- )
- );
- Assert.Null (exception);
- }
-
- [Theory]
- [InlineData (
- "Hello world, how are you today? Pretty neat!",
- 44,
- 80,
- "Hello world, how are you today? Pretty neat!"
- )]
- public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Horizontal (
- string text,
- int runeCount,
- int maxWidth,
- string justifiedText
- )
- {
- Assert.Equal (runeCount, text.GetRuneCount ());
-
- var fmtText = string.Empty;
-
- for (int i = text.GetRuneCount (); i < maxWidth; i++)
- {
- fmtText = TextFormatter.Format (text, i, Alignment.Fill, true) [0];
- Assert.Equal (i, fmtText.GetRuneCount ());
- char c = fmtText [^1];
- Assert.True (text.EndsWith (c));
- }
-
- Assert.Equal (justifiedText, fmtText);
- }
-
- [Theory]
- [InlineData (
- "Hello world, how are you today? Pretty neat!",
- 44,
- 80,
- "Hello world, how are you today? Pretty neat!"
- )]
- public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Vertical (
- string text,
- int runeCount,
- int maxWidth,
- string justifiedText
- )
- {
- Assert.Equal (runeCount, text.GetRuneCount ());
-
- var fmtText = string.Empty;
-
- for (int i = text.GetRuneCount (); i < maxWidth; i++)
- {
- fmtText = TextFormatter.Format (
- text,
- i,
- Alignment.Fill,
- false,
- true,
- 0,
- TextDirection.TopBottom_LeftRight
- ) [0];
- Assert.Equal (i, fmtText.GetRuneCount ());
- char c = fmtText [^1];
- Assert.True (text.EndsWith (c));
- }
-
- Assert.Equal (justifiedText, fmtText);
- }
-
- [Theory]
- [InlineData ("Truncate", 3, "Tru")]
- [InlineData ("デモエムポンズ", 3, "デ")]
- public void Format_Truncate_Simple_And_Wide_Runes (string text, int width, string expected)
- {
- List list = TextFormatter.Format (text, width, false, false);
- Assert.Equal (expected, list [^1]);
- }
-
- [Theory]
- [MemberData (nameof (FormatEnvironmentNewLine))]
- public void Format_With_PreserveTrailingSpaces_And_Without_PreserveTrailingSpaces (
- string text,
- int width,
- IEnumerable expected
- )
- {
- var preserveTrailingSpaces = false;
- List formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces);
- Assert.Equal (expected, formated);
-
- preserveTrailingSpaces = true;
- formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces);
- Assert.Equal (expected, formated);
- }
-
- [Theory]
- [InlineData (
- " A sentence has words. \n This is the second Line - 2. ",
- 4,
- -50,
- Alignment.Start,
- true,
- false,
- new [] { " A", "sent", "ence", "has", "word", "s. ", " Thi", "s is", "the", "seco", "nd", "Line", "- 2." },
- " Asentencehaswords. This isthesecondLine- 2."
- )]
- [InlineData (
- " A sentence has words. \n This is the second Line - 2. ",
- 4,
- -50,
- Alignment.Start,
- true,
- true,
- new []
- {
- " A ",
- "sent",
- "ence",
- " ",
- "has ",
- "word",
- "s. ",
- " ",
- "This",
- " is ",
- "the ",
- "seco",
- "nd ",
- "Line",
- " - ",
- "2. "
- },
- " A sentence has words. This is the second Line - 2. "
- )]
- public void Format_WordWrap_PreserveTrailingSpaces (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- bool preserveTrailingSpaces,
- IEnumerable resultLines,
- string expectedWrappedText
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
- Assert.Equal (list.Count, resultLines.Count ());
- Assert.Equal (resultLines, list);
- var wrappedText = string.Empty;
-
- foreach (string txt in list)
- {
- wrappedText += txt;
- }
-
- Assert.Equal (expectedWrappedText, wrappedText);
- }
-
- [Theory]
- [InlineData ("Hello World", 11)]
- [InlineData ("こんにちは世界", 14)]
- public void GetColumns_Simple_And_Wide_Runes (string text, int width) { Assert.Equal (width, text.GetColumns ()); }
-
- [Theory]
- [InlineData ("Hello World", 6, 6)]
- [InlineData ("こんにちは 世界", 6, 3)]
- [MemberData (nameof (CMGlyphs))]
- public void GetLengthThatFits_List_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
- {
- List runes = text.ToRuneList ();
- Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
- }
-
- [Theory]
- [InlineData ("test", 3, 3)]
- [InlineData ("test", 4, 4)]
- [InlineData ("test", 10, 4)]
- public void GetLengthThatFits_Runelist (string text, int columns, int expectedLength)
- {
- List runes = text.ToRuneList ();
-
- Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
- }
-
- [Theory]
- [InlineData ("Hello World", 6, 6)]
- [InlineData ("こんにちは 世界", 6, 3)]
- public void GetLengthThatFits_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
- {
- Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
- }
-
- [Theory]
- [InlineData ("test", 3, 3)]
- [InlineData ("test", 4, 4)]
- [InlineData ("test", 10, 4)]
- [InlineData ("test", 1, 1)]
- [InlineData ("test", 0, 0)]
- [InlineData ("test", -1, 0)]
- [InlineData (null, -1, 0)]
- [InlineData ("", -1, 0)]
- public void GetLengthThatFits_String (string text, int columns, int expectedLength)
- {
- Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
- }
-
- [Fact]
- public void GetLengthThatFits_With_Combining_Runes ()
- {
- var text = "Les Mise\u0328\u0301rables";
- Assert.Equal (16, TextFormatter.GetLengthThatFits (text, 14));
- }
-
- [Fact]
- public void GetMaxColsForWidth_With_Combining_Runes ()
- {
- List text = new () { "Les Mis", "e\u0328\u0301", "rables" };
- Assert.Equal (1, TextFormatter.GetMaxColsForWidth (text, 1));
- }
-
- [Theory]
- [InlineData (new [] { "0123456789" }, 1)]
- [InlineData (new [] { "Hello World" }, 1)]
- [InlineData (new [] { "Hello", "World" }, 2)]
- [InlineData (new [] { "こんにちは", "世界" }, 4)]
- public void GetColumnsRequiredForVerticalText_List_GetsWidth (IEnumerable text, int expectedWidth)
- {
- Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ()));
- }
-
- [Theory]
- [InlineData (new [] { "Hello World" }, 1, 0, 1, 1)]
- [InlineData (new [] { "Hello", "World" }, 2, 1, 1, 1)]
- [InlineData (new [] { "こんにちは", "世界" }, 4, 1, 1, 2)]
- public void GetColumnsRequiredForVerticalText_List_Simple_And_Wide_Runes (
- IEnumerable text,
- int expectedWidth,
- int index,
- int length,
- int expectedIndexWidth
- )
- {
- Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ()));
- Assert.Equal (expectedIndexWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList (), index, length));
- }
-
- [Fact]
- public void GetColumnsRequiredForVerticalText_List_With_Combining_Runes ()
- {
- List text = new () { "Les Mis", "e\u0328\u0301", "rables" };
- Assert.Equal (1, TextFormatter.GetColumnsRequiredForVerticalText (text, 1, 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 Internal_Tests ()
- {
- var tf = new TextFormatter ();
- Assert.Equal (KeyCode.Null, tf.HotKey);
- tf.HotKey = KeyCode.CtrlMask | KeyCode.Q;
- Assert.Equal (KeyCode.CtrlMask | KeyCode.Q, tf.HotKey);
- }
-
- [Theory]
- [InlineData ("")]
- [InlineData (null)]
- [InlineData ("test")]
- public void Justify_Invalid (string text)
- {
- Assert.Equal (text, TextFormatter.Justify (text, 0));
- Assert.Equal (text, TextFormatter.Justify (text, 0));
- Assert.Throws (() => TextFormatter.Justify (text, -1));
- }
-
- [Theory]
-
- // Even # of spaces
- // 0123456789
- [InlineData ("012 456 89", "012 456 89", 10, 0, "+", true)]
- [InlineData ("012 456 89", "012++456+89", 11, 1)]
- [InlineData ("012 456 89", "012 456 89", 12, 2, "++", true)]
- [InlineData ("012 456 89", "012+++456++89", 13, 3)]
- [InlineData ("012 456 89", "012 456 89", 14, 4, "+++", true)]
- [InlineData ("012 456 89", "012++++456+++89", 15, 5)]
- [InlineData ("012 456 89", "012 456 89", 16, 6, "++++", true)]
- [InlineData ("012 456 89", "012 456 89", 30, 20, "+++++++++++", true)]
- [InlineData ("012 456 89", "012+++++++++++++456++++++++++++89", 33, 23)]
-
- // Odd # of spaces
- // 01234567890123
- [InlineData ("012 456 89 end", "012 456 89 end", 14, 0, "+", true)]
- [InlineData ("012 456 89 end", "012++456+89+end", 15, 1)]
- [InlineData ("012 456 89 end", "012++456++89+end", 16, 2)]
- [InlineData ("012 456 89 end", "012 456 89 end", 17, 3, "++", true)]
- [InlineData ("012 456 89 end", "012+++456++89++end", 18, 4)]
- [InlineData ("012 456 89 end", "012+++456+++89++end", 19, 5)]
- [InlineData ("012 456 89 end", "012 456 89 end", 20, 6, "+++", true)]
- [InlineData ("012 456 89 end", "012++++++++456++++++++89+++++++end", 34, 20)]
- [InlineData ("012 456 89 end", "012+++++++++456+++++++++89++++++++end", 37, 23)]
-
- // Unicode
- // Even # of chars
- // 0123456789
- [InlineData ("пÑРвРÑ", "пÑРвРÑ", 10, 0, "+", true)]
- [InlineData ("пÑРвРÑ", "пÑÐ++вÐ+Ñ", 11, 1)]
- [InlineData ("пÑРвРÑ", "пÑРвРÑ", 12, 2, "++", true)]
- [InlineData ("пÑРвРÑ", "пÑÐ+++вÐ++Ñ", 13, 3)]
- [InlineData ("пÑРвРÑ", "пÑРвРÑ", 14, 4, "+++", true)]
- [InlineData ("пÑРвРÑ", "пÑÐ++++вÐ+++Ñ", 15, 5)]
- [InlineData ("пÑРвРÑ", "пÑРвРÑ", 16, 6, "++++", true)]
- [InlineData ("пÑРвРÑ", "пÑРвРÑ", 30, 20, "+++++++++++", true)]
- [InlineData ("пÑРвРÑ", "пÑÐ+++++++++++++вÐ++++++++++++Ñ", 33, 23)]
-
- // Unicode
- // Odd # of chars
- // 0123456789
- [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 10, 0, "+", true)]
- [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ+вÐ+Ñ", 11, 1)]
- [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ++вÐ+Ñ", 12, 2)]
- [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 13, 3, "++", true)]
- [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ++вÐ++Ñ", 14, 4)]
- [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ+++вÐ++Ñ", 15, 5)]
- [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 16, 6, "+++", true)]
- [InlineData ("Ð ÑРвРÑ", "Ð++++++++ÑÐ++++++++вÐ+++++++Ñ", 30, 20)]
- [InlineData ("Ð ÑРвРÑ", "Ð+++++++++ÑÐ+++++++++вÐ++++++++Ñ", 33, 23)]
- public void Justify_Sentence (
- string text,
- string justifiedText,
- int forceToWidth,
- int widthOffset,
- string replaceWith = null,
- bool replace = false
- )
- {
- var fillChar = '+';
-
- Assert.Equal (forceToWidth, text.GetRuneCount () + widthOffset);
-
- if (replace)
- {
- justifiedText = text.Replace (" ", replaceWith);
- }
-
- Assert.Equal (justifiedText, TextFormatter.Justify (text, forceToWidth, fillChar));
- Assert.True (Math.Abs (forceToWidth - justifiedText.GetRuneCount ()) < text.Count (s => s == ' '));
- Assert.True (Math.Abs (forceToWidth - justifiedText.GetColumns ()) < text.Count (s => s == ' '));
- }
-
- [Theory]
- [InlineData ("word")] // Even # of chars
- [InlineData ("word.")] // Odd # of chars
- [InlineData ("пÑивеÑ")] // Unicode (even #)
- [InlineData ("пÑивеÑ.")] // Unicode (odd # of chars)
- public void Justify_SingleWord (string text)
- {
- string justifiedText = text;
- var fillChar = '+';
-
- int width = text.GetRuneCount ();
- Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
- width = text.GetRuneCount () + 1;
- Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
- width = text.GetRuneCount () + 2;
- Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
- width = text.GetRuneCount () + 10;
- Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
- width = text.GetRuneCount () + 11;
- Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
- }
-
- [Theory]
- [InlineData ("Single Line 界", 14)]
- [InlineData ("First Line 界\nSecond Line 界\nThird Line 界\n", 14)]
- public void MaxWidthLine_With_And_Without_Newlines (string text, int expected) { Assert.Equal (expected, TextFormatter.GetWidestLineLength (text)); }
-
- [Theory]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 0,
- false,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 1,
- false,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 1,
- 0,
- false,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 0,
- true,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 1,
- true,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 1,
- 0,
- true,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 6,
- 5,
- false,
- new [] { "First " }
- )]
- [InlineData ("1\n2\n3\n4\n5\n6", 6, 5, false, new [] { "1 2 3 " })]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 6,
- 5,
- true,
- new [] { "First ", "Second", "Third ", "Forty ", "Fiftee" }
- )]
- [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, false, new [] { "第一" })]
- [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, true, new [] { "第一", "第二", "第三", "四十", "第十" })]
- public void MultiLine_WordWrap_False_Horizontal_Direction (
- string text,
- int maxWidth,
- int maxHeight,
- bool multiLine,
- IEnumerable resultLines
- )
- {
- var tf = new TextFormatter
- {
- Text = text, ConstrainToSize = new (maxWidth, maxHeight), WordWrap = false, MultiLine = multiLine
- };
-
- Assert.False (tf.WordWrap);
- Assert.True (tf.MultiLine == multiLine);
- Assert.Equal (TextDirection.LeftRight_TopBottom, tf.Direction);
-
- List splitLines = tf.GetLines ();
- Assert.Equal (splitLines.Count, resultLines.Count ());
- Assert.Equal (splitLines, resultLines);
- }
-
- [Theory]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 0,
- false,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 1,
- false,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 1,
- 0,
- false,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 0,
- true,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 0,
- 1,
- true,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 1,
- 0,
- true,
- new [] { "" }
- )]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 6,
- 5,
- false,
- new [] { "First" }
- )]
- [InlineData ("1\n2\n3\n4\n5\n6", 6, 5, false, new [] { "1 2 3" })]
- [InlineData (
- "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
- 6,
- 5,
- true,
- new [] { "First", "Secon", "Third", "Forty", "Fifte", "Seven" }
- )]
- [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, false, new [] { "第一行 第" })]
- [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, true, new [] { "第一行", "第二行" })]
- public void MultiLine_WordWrap_False_Vertical_Direction (
- string text,
- int maxWidth,
- int maxHeight,
- bool multiLine,
- IEnumerable resultLines
- )
- {
- var tf = new TextFormatter
- {
- Text = text,
- ConstrainToSize = new (maxWidth, maxHeight),
- WordWrap = false,
- MultiLine = multiLine,
- Direction = TextDirection.TopBottom_LeftRight
- };
-
- Assert.False (tf.WordWrap);
- Assert.True (tf.MultiLine == multiLine);
- Assert.Equal (TextDirection.TopBottom_LeftRight, tf.Direction);
-
- List splitLines = tf.GetLines ();
- Assert.Equal (splitLines.Count, resultLines.Count ());
- Assert.Equal (splitLines, resultLines);
- }
-
- [Fact]
- public void NeedsFormat_Sets ()
- {
- var testText = "test";
- var testBounds = new Rectangle (0, 0, 100, 1);
- var tf = new TextFormatter ();
-
- tf.Text = "test";
- Assert.True (tf.NeedsFormat); // get_Lines causes a Format
- Assert.NotEmpty (tf.GetLines ());
- Assert.False (tf.NeedsFormat); // get_Lines causes a Format
- Assert.Equal (testText, tf.Text);
- tf.Draw (testBounds, new (), new ());
- Assert.False (tf.NeedsFormat);
-
- tf.ConstrainToSize = new (1, 1);
- Assert.True (tf.NeedsFormat);
- Assert.NotEmpty (tf.GetLines ());
- Assert.False (tf.NeedsFormat); // get_Lines causes a Format
-
- tf.Alignment = Alignment.Center;
- Assert.True (tf.NeedsFormat);
- Assert.NotEmpty (tf.GetLines ());
- Assert.False (tf.NeedsFormat); // get_Lines causes a Format
- }
-
- [Theory]
- [InlineData ("", -1, Alignment.Start, false, 0)]
- [InlineData (null, 0, Alignment.Start, false, 1)]
- [InlineData (null, 0, Alignment.Start, true, 1)]
- [InlineData ("", 0, Alignment.Start, false, 1)]
- [InlineData ("", 0, Alignment.Start, true, 1)]
- public void Reformat_Invalid (string text, int maxWidth, Alignment alignment, bool wrap, int linesCount)
- {
- if (maxWidth < 0)
- {
- Assert.Throws (
- () =>
- TextFormatter.Format (text, maxWidth, alignment, wrap)
- );
- }
- else
- {
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap);
- Assert.NotEmpty (list);
- Assert.True (list.Count == linesCount);
- Assert.Equal (string.Empty, list [0]);
- }
- }
-
- [Theory]
- [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true)]
- [InlineData ("A sentence has words.\nLine 2.", 1, -28, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\nLine 2.", 5, -24, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\nLine 2.", 28, -1, Alignment.Start, false, 1, false)]
-
- // no clip
- [InlineData ("A sentence has words.\nLine 2.", 29, 0, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\nLine 2.", 30, 1, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true)]
- [InlineData ("A sentence has words.\r\nLine 2.", 1, -29, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\r\nLine 2.", 5, -25, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\r\nLine 2.", 29, -1, Alignment.Start, false, 1, false, 1)]
- [InlineData ("A sentence has words.\r\nLine 2.", 30, 0, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.\r\nLine 2.", 31, 1, Alignment.Start, false, 1, false)]
- public void Reformat_NoWordrap_NewLines_MultiLine_False (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- int linesCount,
- bool stringEmpty,
- int clipWidthOffset = 0
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth) + clipWidthOffset;
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap);
- Assert.NotEmpty (list);
- Assert.True (list.Count == linesCount);
-
- if (stringEmpty)
- {
- Assert.Equal (string.Empty, list [0]);
- }
- else
- {
- Assert.NotEqual (string.Empty, list [0]);
- }
-
- if (text.Contains ("\r\n") && maxWidth > 0)
- {
- Assert.Equal (
- StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth])
- .Replace ("\r\n", " "),
- list [0]
- );
- }
- else if (text.Contains ('\n') && maxWidth > 0)
- {
- Assert.Equal (
- StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth])
- .Replace ("\n", " "),
- list [0]
- );
- }
- else
- {
- Assert.Equal (StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]), list [0]);
- }
- }
-
- [Theory]
- [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true, new [] { "" })]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 1,
- -28,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A", "L" }
- )]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 5,
- -24,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sen", "Line " }
- )]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 28,
- -1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- //// no clip
- [InlineData (
- "A sentence has words.\nLine 2.",
- 29,
- 0,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 30,
- 1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true, new [] { "" })]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 1,
- -29,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A", "L" }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 5,
- -25,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sen", "Line " }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 29,
- -1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 30,
- 0,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 31,
- 1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- public void Reformat_NoWordrap_NewLines_MultiLine_True (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- int linesCount,
- bool stringEmpty,
- IEnumerable resultLines
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
-
- List list = TextFormatter.Format (
- text,
- maxWidth,
- alignment,
- wrap,
- false,
- 0,
- TextDirection.LeftRight_TopBottom,
- true
- );
- Assert.NotEmpty (list);
- Assert.True (list.Count == linesCount);
-
- if (stringEmpty)
- {
- Assert.Equal (string.Empty, list [0]);
- }
- else
- {
- Assert.NotEqual (string.Empty, list [0]);
- }
-
- Assert.Equal (list, resultLines);
- }
-
- [Theory]
- [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true, new [] { "" })]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 1,
- -28,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A", "L" }
- )]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 5,
- -24,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sen", "Line " }
- )]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 28,
- -1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- //// no clip
- [InlineData (
- "A sentence has words.\nLine 2.",
- 29,
- 0,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData (
- "A sentence has words.\nLine 2.",
- 30,
- 1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true, new [] { "" })]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 1,
- -29,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A", "L" }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 5,
- -25,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sen", "Line " }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 29,
- -1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 30,
- 0,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- [InlineData (
- "A sentence has words.\r\nLine 2.",
- 31,
- 1,
- Alignment.Start,
- false,
- 2,
- false,
- new [] { "A sentence has words.", "Line 2." }
- )]
- public void Reformat_NoWordrap_NewLines_MultiLine_True_Vertical (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- int linesCount,
- bool stringEmpty,
- IEnumerable resultLines
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
-
- List list = TextFormatter.Format (
- text,
- maxWidth,
- alignment,
- wrap,
- false,
- 0,
- TextDirection.TopBottom_LeftRight,
- true
- );
- Assert.NotEmpty (list);
- Assert.True (list.Count == linesCount);
-
- if (stringEmpty)
- {
- Assert.Equal (string.Empty, list [0]);
- }
- else
- {
- Assert.NotEqual (string.Empty, list [0]);
- }
-
- Assert.Equal (list, resultLines);
- }
-
- [Theory]
- [InlineData ("", 0, 0, Alignment.Start, false, 1, true)]
- [InlineData ("", 1, 1, Alignment.Start, false, 1, true)]
- [InlineData ("A sentence has words.", 0, -21, Alignment.Start, false, 1, true)]
- [InlineData ("A sentence has words.", 1, -20, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.", 5, -16, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.", 20, -1, Alignment.Start, false, 1, false)]
-
- // no clip
- [InlineData ("A sentence has words.", 21, 0, Alignment.Start, false, 1, false)]
- [InlineData ("A sentence has words.", 22, 1, Alignment.Start, false, 1, false)]
- public void Reformat_NoWordrap_SingleLine (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- int linesCount,
- bool stringEmpty
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap);
- Assert.NotEmpty (list);
- Assert.True (list.Count == linesCount);
-
- if (stringEmpty)
- {
- Assert.Equal (string.Empty, list [0]);
- }
- else
- {
- Assert.NotEqual (string.Empty, list [0]);
- }
-
- Assert.Equal (StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]), list [0]);
- }
-
- [Theory]
-
- // Unicode
- [InlineData (
- "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
- 8,
- -1,
- Alignment.Start,
- true,
- false,
- new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
- )]
-
- // no clip
- [InlineData (
- "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
- 9,
- 0,
- Alignment.Start,
- true,
- false,
- new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
- )]
- [InlineData (
- "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
- 10,
- 1,
- Alignment.Start,
- true,
- false,
- new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
- )]
- public void Reformat_Unicode_Wrap_Spaces_NewLines (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- bool preserveTrailingSpaces,
- IEnumerable resultLines
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
- Assert.Equal (list.Count, resultLines.Count ());
- Assert.Equal (resultLines, list);
- }
-
- [Theory]
-
- // Unicode
- // Even # of chars
- // 0123456789
- [InlineData ("\u2660пÑРвРÑ", 10, -1, Alignment.Start, true, false, new [] { "\u2660пÑРвÐ", "Ñ" })]
-
- // no clip
- [InlineData ("\u2660пÑРвРÑ", 11, 0, Alignment.Start, true, false, new [] { "\u2660пÑРвРÑ" })]
- [InlineData ("\u2660пÑРвРÑ", 12, 1, Alignment.Start, true, false, new [] { "\u2660пÑРвРÑ" })]
-
- // Unicode
- // Odd # of chars
- // 0123456789
- [InlineData ("\u2660 ÑРвРÑ", 9, -1, Alignment.Start, true, false, new [] { "\u2660 ÑРвÐ", "Ñ" })]
-
- // no clip
- [InlineData ("\u2660 ÑРвРÑ", 10, 0, Alignment.Start, true, false, new [] { "\u2660 ÑРвРÑ" })]
- [InlineData ("\u2660 ÑРвРÑ", 11, 1, Alignment.Start, true, false, new [] { "\u2660 ÑРвРÑ" })]
- public void Reformat_Unicode_Wrap_Spaces_No_NewLines (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- bool preserveTrailingSpaces,
- IEnumerable resultLines
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
- Assert.Equal (list.Count, resultLines.Count ());
- Assert.Equal (resultLines, list);
- }
-
- [Theory]
-
- // Even # of spaces
- // 0123456789
- [InlineData ("012 456 89", 0, -10, Alignment.Start, true, true, true, new [] { "" })]
- [InlineData (
- "012 456 89",
- 1,
- -9,
- Alignment.Start,
- true,
- true,
- false,
- new [] { "0", "1", "2", " ", "4", "5", "6", " ", "8", "9" },
- "01245689"
- )]
- [InlineData ("012 456 89", 5, -5, Alignment.Start, true, true, false, new [] { "012 ", "456 ", "89" })]
- [InlineData ("012 456 89", 9, -1, Alignment.Start, true, true, false, new [] { "012 456 ", "89" })]
-
- // no clip
- [InlineData ("012 456 89", 10, 0, Alignment.Start, true, true, false, new [] { "012 456 89" })]
- [InlineData ("012 456 89", 11, 1, Alignment.Start, true, true, false, new [] { "012 456 89" })]
-
- // Odd # of spaces
- // 01234567890123
- [InlineData ("012 456 89 end", 13, -1, Alignment.Start, true, true, false, new [] { "012 456 89 ", "end" })]
-
- // no clip
- [InlineData ("012 456 89 end", 14, 0, Alignment.Start, true, true, false, new [] { "012 456 89 end" })]
- [InlineData ("012 456 89 end", 15, 1, Alignment.Start, true, true, false, new [] { "012 456 89 end" })]
- public void Reformat_Wrap_Spaces_No_NewLines (
- string text,
- int maxWidth,
- int widthOffset,
- Alignment alignment,
- bool wrap,
- bool preserveTrailingSpaces,
- bool stringEmpty,
- IEnumerable resultLines,
- string noSpaceText = ""
- )
- {
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
- Assert.NotEmpty (list);
- Assert.True (list.Count == resultLines.Count ());
-
- if (stringEmpty)
- {
- Assert.Equal (string.Empty, list [0]);
- }
- else
- {
- Assert.NotEqual (string.Empty, list [0]);
- }
-
- Assert.Equal (resultLines, list);
-
- if (maxWidth > 0)
- {
- // remove whitespace chars
- if (maxWidth < 5)
- {
- expectedClippedWidth = text.GetRuneCount () - text.Sum (r => r == ' ' ? 1 : 0);
- }
- else
- {
- expectedClippedWidth = Math.Min (
- text.GetRuneCount (),
- maxWidth - text.Sum (r => r == ' ' ? 1 : 0)
- );
- }
-
- list = TextFormatter.Format (text, maxWidth, Alignment.Start, wrap);
-
- if (maxWidth == 1)
- {
- Assert.Equal (expectedClippedWidth, list.Count);
- Assert.Equal (noSpaceText, string.Concat (list.ToArray ()));
- }
-
- if (maxWidth > 1 && maxWidth < 10)
- {
- Assert.Equal (
- StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]),
- list [0]
- );
- }
- }
- }
-
- [Theory]
- [InlineData (null)]
- [InlineData ("")]
- [InlineData ("a")]
- public void RemoveHotKeySpecifier_InValid_ReturnsOriginal (string text)
- {
- var hotKeySpecifier = (Rune)'_';
-
- if (text == null)
- {
- Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier));
- Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier));
- Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier));
- }
- else
- {
- Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier));
- Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier));
- Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier));
- }
- }
-
- [Theory]
- [InlineData ("all lower case", 0)]
- [InlineData ("K Before", 0)]
- [InlineData ("aK Second", 1)]
- [InlineData ("Last K", 5)]
- [InlineData ("fter K", 7)]
- [InlineData ("Multiple K and R", 9)]
- [InlineData ("Non-english: Кдать", 13)]
- public void RemoveHotKeySpecifier_Valid_Legacy_ReturnsOriginal (string text, int hotPos)
- {
- var hotKeySpecifier = (Rune)'_';
-
- Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier));
- }
-
- [Theory]
- [InlineData ("_K Before", 0, "K Before")]
- [InlineData ("a_K Second", 1, "aK Second")]
- [InlineData ("Last _K", 5, "Last K")]
- [InlineData ("After K_", 7, "After K")]
- [InlineData ("Multiple _K and _R", 9, "Multiple K and _R")]
- [InlineData ("Non-english: _Кдать", 13, "Non-english: Кдать")]
- public void RemoveHotKeySpecifier_Valid_ReturnsStripped (string text, int hotPos, string expectedText)
- {
- var hotKeySpecifier = (Rune)'_';
-
- Assert.Equal (expectedText, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier));
- }
-
- [Theory]
- [InlineData ("test", 0, 't', "test")]
- [InlineData ("test", 1, 'e', "test")]
- [InlineData ("Ok", 0, 'O', "Ok")]
- [InlineData ("[◦ Ok ◦]", 3, 'O', "[◦ Ok ◦]")]
- [InlineData ("^k", 0, '^', "^k")]
- public void ReplaceHotKeyWithTag (string text, int hotPos, uint tag, string expected)
- {
- var tf = new TextFormatter ();
- List runes = text.ToRuneList ();
- Rune rune;
-
- if (Rune.TryGetRuneAt (text, hotPos, out rune))
- {
- Assert.Equal (rune, (Rune)tag);
- }
-
- string result = TextFormatter.ReplaceHotKeyWithTag (text, hotPos);
- Assert.Equal (result, expected);
- Assert.Equal ((Rune)tag, result.ToRunes () [hotPos]);
- Assert.Equal (text.GetRuneCount (), runes.Count);
- Assert.Equal (text, StringExtensions.ToString (runes));
- }
-
- [Theory]
- [MemberData (nameof (SplitEnvironmentNewLine))]
- public void SplitNewLine_Ending__With_Or_Without_NewLine_Probably_CRLF (
- string text,
- IEnumerable expected
- )
- {
- List splited = TextFormatter.SplitNewLine (text);
- Assert.Equal (expected, splited);
- }
-
- [Theory]
- [InlineData (
- "First Line 界\nSecond Line 界\nThird Line 界\n",
- new [] { "First Line 界", "Second Line 界", "Third Line 界", "" }
- )]
- public void SplitNewLine_Ending_With_NewLine_Only_LF (string text, IEnumerable expected)
- {
- List splited = TextFormatter.SplitNewLine (text);
- Assert.Equal (expected, splited);
- }
-
- [Theory]
- [InlineData (
- "First Line 界\nSecond Line 界\nThird Line 界",
- new [] { "First Line 界", "Second Line 界", "Third Line 界" }
- )]
- public void SplitNewLine_Ending_Without_NewLine_Only_LF (string text, IEnumerable expected)
- {
- List splited = TextFormatter.SplitNewLine (text);
- Assert.Equal (expected, splited);
- }
-
- [Theory]
- [InlineData ("New Test 你", 10, 10, 20320, 20320, 9, "你")]
- [InlineData ("New Test \U0001d539", 10, 11, 120121, 55349, 9, "𝔹")]
- public void String_Array_Is_Not_Always_Equal_ToRunes_Array (
- string text,
- int runesLength,
- int stringLength,
- int runeValue,
- int stringValue,
- int index,
- string expected
- )
- {
- Rune [] usToRunes = text.ToRunes ();
- Assert.Equal (runesLength, usToRunes.Length);
- Assert.Equal (stringLength, text.Length);
- Assert.Equal (runeValue, usToRunes [index].Value);
- Assert.Equal (stringValue, text [index]);
- Assert.Equal (expected, usToRunes [index].ToString ());
-
- if (char.IsHighSurrogate (text [index]))
- {
- // Rune array length isn't equal to string array
- Assert.Equal (expected, new (new [] { text [index], text [index + 1] }));
- }
- else
- {
- // Rune array length is equal to string array
- Assert.Equal (expected, text [index].ToString ());
- }
- }
-
- [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")]
- [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
- [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
- public void TabWith_PreserveTrailingSpaces_False (
- int width,
- int height,
- TextDirection textDirection,
- int tabWidth,
- string expected
- )
- {
- var driver = new FakeDriver ();
- driver.Init ();
-
- var text = "This is a \tTab";
- var tf = new TextFormatter ();
- tf.Direction = textDirection;
- tf.TabWidth = tabWidth;
- tf.Text = text;
- tf.ConstrainToWidth = 20;
- tf.ConstrainToHeight = 20;
-
- Assert.True (tf.WordWrap);
- Assert.False (tf.PreserveTrailingSpaces);
-
- tf.Draw (
- new (0, 0, width, height),
- new (ColorName.White, ColorName.Black),
- new (ColorName.Blue, ColorName.Black),
- default (Rectangle),
- driver
- );
- TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
-
- 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")]
- [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
- [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
- public void TabWith_PreserveTrailingSpaces_True (
- int width,
- int height,
- TextDirection textDirection,
- int tabWidth,
- string expected
- )
- {
- var driver = new FakeDriver ();
- driver.Init ();
-
- var text = "This is a \tTab";
- var tf = new TextFormatter ();
-
- tf.Direction = textDirection;
- tf.TabWidth = tabWidth;
- tf.PreserveTrailingSpaces = true;
- tf.Text = text;
- tf.ConstrainToWidth = 20;
- tf.ConstrainToHeight = 20;
-
- Assert.True (tf.WordWrap);
-
- tf.Draw (
- new (0, 0, width, height),
- new (ColorName.White, ColorName.Black),
- new (ColorName.Blue, ColorName.Black),
- default (Rectangle),
- driver
- );
- TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
-
- 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")]
- [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
- [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
- public void TabWith_WordWrap_True (
- int width,
- int height,
- TextDirection textDirection,
- int tabWidth,
- string expected
- )
- {
- var driver = new FakeDriver ();
- driver.Init ();
-
- var text = "This is a \tTab";
- var tf = new TextFormatter ();
-
- tf.Direction = textDirection;
- tf.TabWidth = tabWidth;
- tf.WordWrap = true;
- tf.Text = text;
- tf.ConstrainToWidth = 20;
- tf.ConstrainToHeight = 20;
-
- Assert.False (tf.PreserveTrailingSpaces);
-
- tf.Draw (
- new (0, 0, width, height),
- new (ColorName.White, ColorName.Black),
- new (ColorName.Blue, ColorName.Black),
- default (Rectangle),
- driver
- );
- TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
-
- driver.End ();
- }
-
- [Theory]
- [InlineData ("123456789", 3, "123")]
- [InlineData ("Hello World", 8, "Hello Wo")]
- public void TestClipOrPad_LongWord (string text, int fillPad, string expectedText)
- {
- // word is long but we want it to fill # space only
- Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad));
- }
-
- [Theory]
- [InlineData ("fff", 6, "fff ")]
- [InlineData ("Hello World", 16, "Hello World ")]
- public void TestClipOrPad_ShortWord (string text, int fillPad, string expectedText)
- {
- // word is short but we want it to fill # so it should be padded
- Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad));
- }
-
- [Theory]
- [InlineData ("你", TextDirection.LeftRight_TopBottom, 2, 1)]
- [InlineData ("你", TextDirection.TopBottom_LeftRight, 2, 1)]
- [InlineData ("你你", TextDirection.LeftRight_TopBottom, 4, 1)]
- [InlineData ("你你", TextDirection.TopBottom_LeftRight, 2, 2)]
- public void Text_Set_SizeIsCorrect (string text, TextDirection textDirection, int expectedWidth, int expectedHeight)
- {
- var tf = new TextFormatter { Direction = textDirection, Text = text };
- tf.ConstrainToWidth = 10;
- tf.ConstrainToHeight = 10;
-
- Assert.Equal (new (expectedWidth, expectedHeight), tf.FormatAndGetSize ());
- }
-
- [Fact]
- public void WordWrap_BigWidth ()
- {
- List wrappedLines;
-
- var text = "Constantinople";
- wrappedLines = TextFormatter.WordWrapText (text, 100);
- Assert.True (wrappedLines.Count == 1);
- Assert.Equal ("Constantinople", wrappedLines [0]);
- }
-
- [Fact]
- public void WordWrap_Invalid ()
- {
- var text = string.Empty;
- var width = 0;
-
- Assert.Empty (TextFormatter.WordWrapText (null, width));
- Assert.Empty (TextFormatter.WordWrapText (text, width));
- Assert.Throws (() => TextFormatter.WordWrapText (text, -1));
- }
-
- [Theory]
- [InlineData ("A sentence has words.", 3, -18, new [] { "A", "sen", "ten", "ce", "has", "wor", "ds." })]
- [InlineData (
- "A sentence has words.",
- 2,
- -19,
- new [] { "A", "se", "nt", "en", "ce", "ha", "s", "wo", "rd", "s." }
- )]
- [InlineData (
- "A sentence has words.",
- 1,
- -20,
- new [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." }
- )]
- public void WordWrap_Narrow_Default (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("A sentence has words.", 21, 0, new [] { "A sentence has words." })]
- [InlineData ("A sentence has words.", 20, -1, new [] { "A sentence has", "words." })]
- [InlineData ("A sentence has words.", 15, -6, new [] { "A sentence has", "words." })]
- [InlineData ("A sentence has words.", 14, -7, new [] { "A sentence has", "words." })]
- [InlineData ("A sentence has words.", 13, -8, new [] { "A sentence", "has words." })]
-
- // Unicode
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.",
- 42,
- 0,
- new [] { "A Unicode sentence (пÑивеÑ) has words." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.",
- 41,
- -1,
- new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.",
- 36,
- -6,
- new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.",
- 35,
- -7,
- new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.",
- 34,
- -8,
- new [] { "A Unicode sentence (пÑивеÑ)", "has words." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.",
- 25,
- -17,
- new [] { "A Unicode sentence", "(пÑивеÑ) has words." }
- )]
- public void WordWrap_NoNewLines_Default (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("これが最初の行です。 こんにちは世界。 これが2行目です。", 29, 0, new [] { "これが最初の行です。", "こんにちは世界。", "これが2行目です。" })]
- public void WordWrap_PreserveTrailingSpaces_False_Unicode_Wide_Runes (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("文に は言葉 があり ます。", 14, 0, new [] { "文に は言葉", "があり ます。" })]
- [InlineData ("文に は言葉 があり ます。", 3, -11, new [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })]
- [InlineData ("文に は言葉 があり ます。", 2, -12, new [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })]
- [InlineData (
- "文に は言葉 があり ます。",
- 1,
- -13,
- new [] { " ", " ", " " }
- )] // Just Spaces; should result in a single space for each line
- public void WordWrap_PreserveTrailingSpaces_False_Wide_Runes (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData (null, 1, new string [] { })] // null input
- [InlineData ("", 1, new string [] { })] // Empty input
- [InlineData ("1 34", 1, new [] { "1", "3", "4" })] // Single Spaces
- [InlineData ("1", 1, new [] { "1" })] // Short input
- [InlineData ("12", 1, new [] { "1", "2" })]
- [InlineData ("123", 1, new [] { "1", "2", "3" })]
- [InlineData ("123456", 1, new [] { "1", "2", "3", "4", "5", "6" })] // No spaces
- [InlineData (" ", 1, new [] { " " })] // Just Spaces; should result in a single space
- [InlineData (" ", 1, new [] { " " })]
- [InlineData (" ", 1, new [] { " ", " " })]
- [InlineData (" ", 1, new [] { " ", " " })]
- [InlineData ("12 456", 1, new [] { "1", "2", "4", "5", "6" })] // Single Spaces
- [InlineData (" 2 456", 1, new [] { " ", "2", "4", "5", "6" })] // Leading spaces should be preserved.
- [InlineData (" 2 456 8", 1, new [] { " ", "2", "4", "5", "6", "8" })]
- [InlineData (
- "A sentence has words. ",
- 1,
- new [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." }
- )] // Complex example
- [InlineData ("12 567", 1, new [] { "1", "2", " ", "5", "6", "7" })] // Double Spaces
- [InlineData (" 3 567", 1, new [] { " ", "3", "5", "6", "7" })] // Double Leading spaces should be preserved.
- [InlineData (" 3 678 1", 1, new [] { " ", "3", " ", "6", "7", "8", " ", "1" })]
- [InlineData ("1 456", 1, new [] { "1", " ", "4", "5", "6" })]
- [InlineData (
- "A sentence has words. ",
- 1,
- new []
- {
- "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", "w", "o", "r", "d", "s", ".", " "
- }
- )] // Double space Complex example
- public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_1 (
- string text,
- int width,
- IEnumerable resultLines
- )
- {
- List wrappedLines = TextFormatter.WordWrapText (text, width);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
- Assert.Equal (resultLines, wrappedLines);
- var breakLines = "";
-
- foreach (string line in wrappedLines)
- {
- breakLines += $"{line}{Environment.NewLine}";
- }
-
- var expected = string.Empty;
-
- foreach (string line in resultLines)
- {
- expected += $"{line}{Environment.NewLine}";
- }
-
- Assert.Equal (expected, breakLines);
- }
-
- [Theory]
- [InlineData (null, 3, new string [] { })] // null input
- [InlineData ("", 3, new string [] { })] // Empty input
- [InlineData ("1", 3, new [] { "1" })] // Short input
- [InlineData ("12", 3, new [] { "12" })]
- [InlineData ("123", 3, new [] { "123" })]
- [InlineData ("123456", 3, new [] { "123", "456" })] // No spaces
- [InlineData ("1234567", 3, new [] { "123", "456", "7" })] // No spaces
- [InlineData (" ", 3, new [] { " " })] // Just Spaces; should result in a single space
- [InlineData (" ", 3, new [] { " " })]
- [InlineData (" ", 3, new [] { " " })]
- [InlineData (" ", 3, new [] { " " })]
- [InlineData ("12 456", 3, new [] { "12", "456" })] // Single Spaces
- [InlineData (" 2 456", 3, new [] { " 2", "456" })] // Leading spaces should be preserved.
- [InlineData (" 2 456 8", 3, new [] { " 2", "456", "8" })]
- [InlineData (
- "A sentence has words. ",
- 3,
- new [] { "A", "sen", "ten", "ce", "has", "wor", "ds." }
- )] // Complex example
- [InlineData ("12 567", 3, new [] { "12 ", "567" })] // Double Spaces
- [InlineData (" 3 567", 3, new [] { " 3", "567" })] // Double Leading spaces should be preserved.
- [InlineData (" 3 678 1", 3, new [] { " 3", " 67", "8 ", "1" })]
- [InlineData ("1 456", 3, new [] { "1 ", "456" })]
- [InlineData (
- "A sentence has words. ",
- 3,
- new [] { "A ", "sen", "ten", "ce ", " ", "has", "wor", "ds.", " " }
- )] // Double space Complex example
- public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_3 (
- string text,
- int width,
- IEnumerable resultLines
- )
- {
- List wrappedLines = TextFormatter.WordWrapText (text, width);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
- Assert.Equal (resultLines, wrappedLines);
- var breakLines = "";
-
- foreach (string line in wrappedLines)
- {
- breakLines += $"{line}{Environment.NewLine}";
- }
-
- var expected = string.Empty;
-
- foreach (string line in resultLines)
- {
- expected += $"{line}{Environment.NewLine}";
- }
-
- Assert.Equal (expected, breakLines);
- }
-
- [Theory]
- [InlineData (null, 50, new string [] { })] // null input
- [InlineData ("", 50, new string [] { })] // Empty input
- [InlineData ("1", 50, new [] { "1" })] // Short input
- [InlineData ("12", 50, new [] { "12" })]
- [InlineData ("123", 50, new [] { "123" })]
- [InlineData ("123456", 50, new [] { "123456" })] // No spaces
- [InlineData ("1234567", 50, new [] { "1234567" })] // No spaces
- [InlineData (" ", 50, new [] { " " })] // Just Spaces; should result in a single space
- [InlineData (" ", 50, new [] { " " })]
- [InlineData (" ", 50, new [] { " " })]
- [InlineData ("12 456", 50, new [] { "12 456" })] // Single Spaces
- [InlineData (" 2 456", 50, new [] { " 2 456" })] // Leading spaces should be preserved.
- [InlineData (" 2 456 8", 50, new [] { " 2 456 8" })]
- [InlineData ("A sentence has words. ", 50, new [] { "A sentence has words. " })] // Complex example
- [InlineData ("12 567", 50, new [] { "12 567" })] // Double Spaces
- [InlineData (" 3 567", 50, new [] { " 3 567" })] // Double Leading spaces should be preserved.
- [InlineData (" 3 678 1", 50, new [] { " 3 678 1" })]
- [InlineData ("1 456", 50, new [] { "1 456" })]
- [InlineData (
- "A sentence has words. ",
- 50,
- new [] { "A sentence has words. " }
- )] // Double space Complex example
- public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_50 (
- string text,
- int width,
- IEnumerable resultLines
- )
- {
- List wrappedLines = TextFormatter.WordWrapText (text, width);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
- Assert.Equal (resultLines, wrappedLines);
- var breakLines = "";
-
- foreach (string line in wrappedLines)
- {
- breakLines += $"{line}{Environment.NewLine}";
- }
-
- var expected = string.Empty;
-
- foreach (string line in resultLines)
- {
- expected += $"{line}{Environment.NewLine}";
- }
-
- Assert.Equal (expected, breakLines);
- }
-
- [Theory]
- [InlineData ("A sentence has words.", 14, -7, new [] { "A sentence ", "has words." })]
- [InlineData ("A sentence has words.", 8, -13, new [] { "A ", "sentence", " has ", "words." })]
- [InlineData ("A sentence has words.", 6, -15, new [] { "A ", "senten", "ce ", "has ", "words." })]
- [InlineData ("A sentence has words.", 3, -18, new [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds." })]
- [InlineData (
- "A sentence has words.",
- 2,
- -19,
- new [] { "A ", "se", "nt", "en", "ce", " ", "ha", "s ", "wo", "rd", "s." }
- )]
- [InlineData (
- "A sentence has words.",
- 1,
- -20,
- new []
- {
- "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", " ", "w", "o", "r", "d", "s", "."
- }
- )]
- public void WordWrap_PreserveTrailingSpaces_True (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("文に は言葉 があり ます。", 14, 0, new [] { "文に は言葉 ", "があり ます。" })]
- [InlineData ("文に は言葉 があり ます。", 3, -11, new [] { "文", "に ", "は", "言", "葉 ", "が", "あ", "り ", "ま", "す", "。" })]
- [InlineData (
- "文に は言葉 があり ます。",
- 2,
- -12,
- new [] { "文", "に", " ", "は", "言", "葉", " ", "が", "あ", "り", " ", "ま", "す", "。" }
- )]
- [InlineData ("文に は言葉 があり ます。", 1, -13, new string [] { })]
- public void WordWrap_PreserveTrailingSpaces_True_Wide_Runes (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("A sentence has words. ", 3, new [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds.", " " })]
- [InlineData (
- "A sentence has words. ",
- 3,
- new [] { "A ", " ", "sen", "ten", "ce ", " ", " ", " ", "has", " ", "wor", "ds.", " " }
- )]
- public void WordWrap_PreserveTrailingSpaces_True_With_Simple_Runes_Width_3 (
- string text,
- int width,
- IEnumerable resultLines
- )
- {
- List wrappedLines = TextFormatter.WordWrapText (text, width, true);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
- Assert.Equal (resultLines, wrappedLines);
- var breakLines = "";
-
- foreach (string line in wrappedLines)
- {
- breakLines += $"{line}{Environment.NewLine}";
- }
-
- var expected = string.Empty;
-
- foreach (string line in resultLines)
- {
- expected += $"{line}{Environment.NewLine}";
- }
-
- Assert.Equal (expected, breakLines);
-
- // Double space Complex example - this is how VS 2022 does it
- //text = "A sentence has words. ";
- //breakLines = "";
- //wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: true);
- //foreach (var line in wrappedLines) {
- // breakLines += $"{line}{Environment.NewLine}";
- //}
- //expected = "A " + Environment.NewLine +
- // " se" + Environment.NewLine +
- // " nt" + Environment.NewLine +
- // " en" + Environment.NewLine +
- // " ce" + Environment.NewLine +
- // " " + Environment.NewLine +
- // " " + Environment.NewLine +
- // " " + Environment.NewLine +
- // " ha" + Environment.NewLine +
- // " s " + Environment.NewLine +
- // " wo" + Environment.NewLine +
- // " rd" + Environment.NewLine +
- // " s." + Environment.NewLine;
- //Assert.Equal (expected, breakLines);
- }
-
- [Theory]
- [InlineData ("A sentence\t\t\t has words.", 14, -10, new [] { "A sentence\t", "\t\t has ", "words." })]
- [InlineData (
- "A sentence\t\t\t has words.",
- 8,
- -16,
- new [] { "A ", "sentence", "\t\t", "\t ", "has ", "words." }
- )]
- [InlineData (
- "A sentence\t\t\t has words.",
- 3,
- -21,
- new [] { "A ", "sen", "ten", "ce", "\t", "\t", "\t", " ", "has", " ", "wor", "ds." }
- )]
- [InlineData (
- "A sentence\t\t\t has words.",
- 2,
- -22,
- new [] { "A ", "se", "nt", "en", "ce", "\t", "\t", "\t", " ", "ha", "s ", "wo", "rd", "s." }
- )]
- [InlineData (
- "A sentence\t\t\t has words.",
- 1,
- -23,
- new []
- {
- "A",
- " ",
- "s",
- "e",
- "n",
- "t",
- "e",
- "n",
- "c",
- "e",
- "\t",
- "\t",
- "\t",
- " ",
- "h",
- "a",
- "s",
- " ",
- "w",
- "o",
- "r",
- "d",
- "s",
- "."
- }
- )]
- public void WordWrap_PreserveTrailingSpaces_True_With_Tab (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines,
- int tabWidth = 4
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("Constantinople", 14, 0, new [] { "Constantinople" })]
- [InlineData ("Constantinople", 12, -2, new [] { "Constantinop", "le" })]
- [InlineData ("Constantinople", 9, -5, new [] { "Constanti", "nople" })]
- [InlineData ("Constantinople", 7, -7, new [] { "Constan", "tinople" })]
- [InlineData ("Constantinople", 5, -9, new [] { "Const", "antin", "ople" })]
- [InlineData ("Constantinople", 4, -10, new [] { "Cons", "tant", "inop", "le" })]
- [InlineData (
- "Constantinople",
- 1,
- -13,
- new [] { "C", "o", "n", "s", "t", "a", "n", "t", "i", "n", "o", "p", "l", "e" }
- )]
- public void WordWrap_SingleWordLine (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 20, 0, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
- [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 19, -1, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
- [InlineData (
- "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence.",
- 19,
- 0,
- new [] { "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence." }
- )]
- public void WordWrap_Unicode_2LinesWithNonBreakingSpace (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 19, 0, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
- [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 18, -1, new [] { "This\u00A0is\u00A0a\u00A0sentence", "." })]
- [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 17, -2, new [] { "This\u00A0is\u00A0a\u00A0sentenc", "e." })]
- [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 14, -5, new [] { "This\u00A0is\u00A0a\u00A0sent", "ence." })]
- [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 10, -9, new [] { "This\u00A0is\u00A0a\u00A0", "sentence." })]
- [InlineData (
- "This\u00A0is\u00A0a\u00A0sentence.",
- 7,
- -12,
- new [] { "This\u00A0is", "\u00A0a\u00A0sent", "ence." }
- )]
- [InlineData (
- "This\u00A0is\u00A0a\u00A0sentence.",
- 5,
- -14,
- new [] { "This\u00A0", "is\u00A0a\u00A0", "sente", "nce." }
- )]
- [InlineData (
- "This\u00A0is\u00A0a\u00A0sentence.",
- 1,
- -18,
- new []
- {
- "T", "h", "i", "s", "\u00A0", "i", "s", "\u00A0", "a", "\u00A0", "s", "e", "n", "t", "e", "n", "c", "e", "."
- }
- )]
- public void WordWrap_Unicode_LineWithNonBreakingSpace (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [Theory]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 51,
- 0,
- new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
- )]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 50,
- -1,
- new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
- )]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 46,
- -5,
- new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ", "ฯะัาำ" }
- )]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 26,
- -25,
- new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
- )]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 17,
- -34,
- new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑ", "ฒณดตถทธนบปผฝพฟภมย", "รฤลฦวศษสหฬอฮฯะัาำ" }
- )]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 13,
- -38,
- new [] { "กขฃคฅฆงจฉชซฌญ", "ฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦว", "ศษสหฬอฮฯะัาำ" }
- )]
- [InlineData (
- "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
- 1,
- -50,
- new []
- {
- "ก",
- "ข",
- "ฃ",
- "ค",
- "ฅ",
- "ฆ",
- "ง",
- "จ",
- "ฉ",
- "ช",
- "ซ",
- "ฌ",
- "ญ",
- "ฎ",
- "ฏ",
- "ฐ",
- "ฑ",
- "ฒ",
- "ณ",
- "ด",
- "ต",
- "ถ",
- "ท",
- "ธ",
- "น",
- "บ",
- "ป",
- "ผ",
- "ฝ",
- "พ",
- "ฟ",
- "ภ",
- "ม",
- "ย",
- "ร",
- "ฤ",
- "ล",
- "ฦ",
- "ว",
- "ศ",
- "ษ",
- "ส",
- "ห",
- "ฬ",
- "อ",
- "ฮ",
- "ฯ",
- "ะั",
- "า",
- "ำ"
- }
- )]
- public void WordWrap_Unicode_SingleWordLine (
- string text,
- int maxWidth,
- int widthOffset,
- IEnumerable resultLines
- )
- {
- List wrappedLines;
-
- IEnumerable zeroWidth = text.EnumerateRunes ().Where (r => r.GetColumns () == 0);
- Assert.Single (zeroWidth);
- Assert.Equal ('ั', zeroWidth.ElementAt (0).Value);
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth
- >= (wrappedLines.Count > 0
- ? wrappedLines.Max (
- l => l.GetRuneCount ()
- + zeroWidth.Count ()
- - 1
- + widthOffset
- )
- : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- /// WordWrap strips CRLF
- [Theory]
- [InlineData (
- "A sentence has words.\nA paragraph has lines.",
- 44,
- 0,
- new [] { "A sentence has words.A paragraph has lines." }
- )]
- [InlineData (
- "A sentence has words.\nA paragraph has lines.",
- 43,
- -1,
- new [] { "A sentence has words.A paragraph has lines." }
- )]
- [InlineData (
- "A sentence has words.\nA paragraph has lines.",
- 38,
- -6,
- new [] { "A sentence has words.A paragraph has", "lines." }
- )]
- [InlineData (
- "A sentence has words.\nA paragraph has lines.",
- 34,
- -10,
- new [] { "A sentence has words.A paragraph", "has lines." }
- )]
- [InlineData (
- "A sentence has words.\nA paragraph has lines.",
- 27,
- -17,
- new [] { "A sentence has words.A", "paragraph has lines." }
- )]
-
- // Unicode
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
- 69,
- 0,
- new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
- 68,
- -1,
- new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
- 63,
- -6,
- new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has", "Линии." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
- 59,
- -10,
- new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт", "has Линии." }
- )]
- [InlineData (
- "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
- 52,
- -17,
- new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode", "Пункт has Линии." }
- )]
- public void WordWrap_WithNewLines (string text, int maxWidth, int widthOffset, IEnumerable resultLines)
- {
- List wrappedLines;
-
- Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
- int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
- wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
- Assert.Equal (wrappedLines.Count, resultLines.Count ());
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
- );
-
- Assert.True (
- expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
- );
- Assert.Equal (resultLines, wrappedLines);
- }
-
- [SetupFakeDriver]
- [Theory]
- [InlineData ("A", 0, "")]
- [InlineData ("A", 1, "A")]
- [InlineData ("A", 2, "A")]
- [InlineData ("AB", 1, "A")]
- [InlineData ("AB", 2, "AB")]
- [InlineData ("ABC", 3, "ABC")]
- [InlineData ("ABC", 4, "ABC")]
- [InlineData ("ABC", 6, "ABC")]
- public void Draw_Horizontal_Left (string text, int width, string expectedText)
-
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Alignment = Alignment.Start
- };
-
- tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = 1;
- tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default);
-
- TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- }
-
- [SetupFakeDriver]
- [Theory]
- [InlineData ("A", 0, "")]
- [InlineData ("A", 1, "A")]
- [InlineData ("A", 2, " A")]
- [InlineData ("AB", 1, "B")]
- [InlineData ("AB", 2, "AB")]
- [InlineData ("ABC", 3, "ABC")]
- [InlineData ("ABC", 4, " ABC")]
- [InlineData ("ABC", 6, " ABC")]
- public void Draw_Horizontal_Right (string text, int width, string expectedText)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Alignment = Alignment.End
- };
-
- tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = 1;
-
- tf.Draw (new (Point.Empty, new (width, 1)), Attribute.Default, Attribute.Default);
- TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- }
+ public static IEnumerable CMGlyphs =>
+ new List { new object [] { $"{CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}", 16, 15 } };
[SetupFakeDriver]
[Theory]
@@ -3075,340 +295,52 @@ ssb
[SetupFakeDriver]
[Theory]
- [InlineData ("A", 5, 5, "A")]
- [InlineData (
- "AB12",
- 5,
- 5,
- @"
-A
-B
-1
-2")]
- [InlineData (
- "AB\n12",
- 5,
- 5,
- @"
-A1
-B2")]
- [InlineData ("", 5, 1, "")]
- [InlineData (
- "Hello Worlds",
- 1,
- 12,
- @"
-H
-e
-l
-l
-o
-
-W
-o
-r
-l
-d
-s")]
- [InlineData (
- "Hello Worlds",
- 1,
- 12,
- @"
-H
-e
-l
-l
-o
-
-W
-o
-r
-l
-d
-s")]
- [InlineData ("Hello Worlds", 12, 1, @"HelloWorlds")]
- public void Draw_Vertical_TopBottom_LeftRight (string text, int width, int height, string expectedText)
+ [InlineData ("A", 0, "")]
+ [InlineData ("A", 1, "A")]
+ [InlineData ("A", 2, "A")]
+ [InlineData ("AB", 1, "A")]
+ [InlineData ("AB", 2, "AB")]
+ [InlineData ("ABC", 3, "ABC")]
+ [InlineData ("ABC", 4, "ABC")]
+ [InlineData ("ABC", 6, "ABC")]
+ public void Draw_Horizontal_Left (string text, int width, string expectedText)
+
{
TextFormatter tf = new ()
{
Text = text,
- Direction = TextDirection.TopBottom_LeftRight
+ Alignment = Alignment.Start
};
tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = height;
- tf.Draw (new (0, 0, 20, 20), Attribute.Default, Attribute.Default);
+ tf.ConstrainToHeight = 1;
+ tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default);
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
}
[SetupFakeDriver]
[Theory]
- [InlineData ("Hello World", 15, 1, "Hello World")]
- [InlineData (
- "Well Done\nNice Work",
- 15,
- 2,
- @"
-Well Done
-Nice Work")]
- [InlineData ("你好 世界", 15, 1, "你好 世界")]
- [InlineData (
- "做 得好\n幹 得好",
- 15,
- 2,
- @"
-做 得好
-幹 得好")]
- public void Justify_Horizontal (string text, int width, int height, string expectedText)
+ [InlineData ("A", 0, "")]
+ [InlineData ("A", 1, "A")]
+ [InlineData ("A", 2, " A")]
+ [InlineData ("AB", 1, "B")]
+ [InlineData ("AB", 2, "AB")]
+ [InlineData ("ABC", 3, "ABC")]
+ [InlineData ("ABC", 4, " ABC")]
+ [InlineData ("ABC", 6, " ABC")]
+ public void Draw_Horizontal_Right (string text, int width, string expectedText)
{
TextFormatter tf = new ()
{
Text = text,
- Alignment = Alignment.Fill,
- ConstrainToSize = new Size (width, height),
- MultiLine = true
- };
-
- tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
-
- TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- }
-
- [SetupFakeDriver]
- [Theory]
- [InlineData ("Hello World", 1, 15, "H\ne\nl\nl\no\n \n \n \n \n \nW\no\nr\nl\nd")]
- [InlineData (
- "Well Done\nNice Work",
- 2,
- 15,
- @"
-WN
-ei
-lc
-le
-
-
-
-
-
-
-
-DW
-oo
-nr
-ek")]
- [InlineData ("你好 世界", 2, 15, "你\n好\n \n \n \n \n \n \n \n \n \n \n \n世\n界")]
- [InlineData (
- "做 得好\n幹 得好",
- 4,
- 15,
- @"
-做幹
-
-
-
-
-
-
-
-
-
-
-
-
-得得
-好好")]
- public void Justify_Vertical (string text, int width, int height, string expectedText)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Direction = TextDirection.TopBottom_LeftRight,
- VerticalAlignment = Alignment.Fill,
- ConstrainToSize = new Size (width, height),
- MultiLine = true
- };
-
- tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
-
- TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- }
-
- [SetupFakeDriver]
- [Theory]
- [InlineData ("A", 0, 1, "", 0)]
- [InlineData ("A", 1, 1, "A", 0)]
- [InlineData ("A", 2, 2, " A", 1)]
- [InlineData ("AB", 1, 1, "B", 0)]
- [InlineData ("AB", 2, 2, " A\n B", 0)]
- [InlineData ("ABC", 3, 2, " B\n C", 0)]
- [InlineData ("ABC", 4, 2, " B\n C", 0)]
- [InlineData ("ABC", 6, 2, " B\n C", 0)]
- [InlineData ("こんにちは", 0, 1, "", 0)]
- [InlineData ("こんにちは", 1, 0, "", 0)]
- [InlineData ("こんにちは", 1, 1, "", 0)]
- [InlineData ("こんにちは", 2, 1, "は", 0)]
- [InlineData ("こんにちは", 2, 2, "ち\nは", 0)]
- [InlineData ("こんにちは", 2, 3, "に\nち\nは", 0)]
- [InlineData ("こんにちは", 2, 4, "ん\nに\nち\nは", 0)]
- [InlineData ("こんにちは", 2, 5, "こ\nん\nに\nち\nは", 0)]
- [InlineData ("こんにちは", 2, 6, "こ\nん\nに\nち\nは", 1)]
- [InlineData ("ABCD\nこんにちは", 4, 7, " こ\n Aん\n Bに\n Cち\n Dは", 2)]
- [InlineData ("こんにちは\nABCD", 3, 7, "こ \nんA\nにB\nちC\nはD", 2)]
- public void Draw_Vertical_Bottom_Horizontal_Right (string text, int width, int height, string expectedText, int expectedY)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Alignment = Alignment.End,
- Direction = TextDirection.TopBottom_LeftRight,
- VerticalAlignment = Alignment.End
+ Alignment = Alignment.End
};
tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = height;
-
- tf.Draw (new (Point.Empty, new (width, height)), Attribute.Default, Attribute.Default);
- Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- Assert.Equal (expectedY, rect.Y);
- }
-
- [SetupFakeDriver]
- [Theory]
- [InlineData ("A", 5, "A")]
- [InlineData (
- "AB12",
- 5,
- @"
-A
-B
-1
-2")]
- [InlineData (
- "AB\n12",
- 5,
- @"
-A1
-B2")]
- [InlineData ("", 1, "")]
- [InlineData (
- "AB1 2",
- 2,
- @"
-A12
-B ")]
- [InlineData (
- "こんにちは",
- 1,
- @"
-こん")]
- [InlineData (
- "こんにちは",
- 2,
- @"
-こに
-んち")]
- [InlineData (
- "こんにちは",
- 5,
- @"
-こ
-ん
-に
-ち
-は")]
- public void Draw_Vertical_TopBottom_LeftRight_Top (string text, int height, string expectedText)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Direction = TextDirection.TopBottom_LeftRight
- };
-
- tf.ConstrainToWidth = 5;
- tf.ConstrainToHeight = height;
- tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default);
-
- TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- }
-
- [SetupFakeDriver]
- [Theory]
-
- // The expectedY param is to probe that the expectedText param start at that Y coordinate
- [InlineData ("A", 0, "", 0)]
- [InlineData ("A", 1, "A", 0)]
- [InlineData ("A", 2, "A", 0)]
- [InlineData ("A", 3, "A", 1)]
- [InlineData ("AB", 1, "A", 0)]
- [InlineData ("AB", 2, "A\nB", 0)]
- [InlineData ("ABC", 2, "A\nB", 0)]
- [InlineData ("ABC", 3, "A\nB\nC", 0)]
- [InlineData ("ABC", 4, "A\nB\nC", 0)]
- [InlineData ("ABC", 5, "A\nB\nC", 1)]
- [InlineData ("ABC", 6, "A\nB\nC", 1)]
- [InlineData ("ABC", 9, "A\nB\nC", 3)]
- [InlineData ("ABCD", 2, "B\nC", 0)]
- [InlineData ("こんにちは", 0, "", 0)]
- [InlineData ("こんにちは", 1, "に", 0)]
- [InlineData ("こんにちは", 2, "ん\nに", 0)]
- [InlineData ("こんにちは", 3, "ん\nに\nち", 0)]
- [InlineData ("こんにちは", 4, "こ\nん\nに\nち", 0)]
- [InlineData ("こんにちは", 5, "こ\nん\nに\nち\nは", 0)]
- [InlineData ("こんにちは", 6, "こ\nん\nに\nち\nは", 0)]
- [InlineData ("ABCD\nこんにちは", 7, "Aこ\nBん\nCに\nDち\n は", 1)]
- [InlineData ("こんにちは\nABCD", 7, "こA\nんB\nにC\nちD\nは ", 1)]
- public void Draw_Vertical_TopBottom_LeftRight_Middle (string text, int height, string expectedText, int expectedY)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Direction = TextDirection.TopBottom_LeftRight,
- VerticalAlignment = Alignment.Center
- };
-
- int width = text.ToRunes ().Max (r => r.GetColumns ());
-
- if (text.Contains ("\n"))
- {
- width++;
- }
-
- tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = height;
- tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default);
-
- Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- Assert.Equal (expectedY, rect.Y);
- }
-
- [SetupFakeDriver]
- [Theory]
- [InlineData ("A", 1, 0, "")]
- [InlineData ("A", 0, 1, "")]
- [InlineData ("AB1 2", 2, 1, "2")]
- [InlineData ("AB12", 5, 1, "21BA")]
- [InlineData ("AB\n12", 5, 2, "BA\n21")]
- [InlineData ("ABC 123 456", 7, 2, "654 321\nCBA ")]
- [InlineData ("こんにちは", 1, 1, "")]
- [InlineData ("こんにちは", 2, 1, "は")]
- [InlineData ("こんにちは", 5, 1, "はち")]
- [InlineData ("こんにちは", 10, 1, "はちにんこ")]
- [InlineData ("こんにちは\nAB\n12", 10, 3, "はちにんこ\nBA \n21 ")]
- public void Draw_Horizontal_RightLeft_TopBottom (string text, int width, int height, string expectedText)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Direction = TextDirection.RightLeft_TopBottom
- };
-
- tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = height;
- tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
+ tf.ConstrainToHeight = 1;
+ tf.Draw (new (Point.Empty, new (width, 1)), Attribute.Default, Attribute.Default);
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
}
@@ -3444,21 +376,21 @@ B ")]
[Theory]
[InlineData ("A", 1, 0, "")]
[InlineData ("A", 0, 1, "")]
- [InlineData ("AB1 2", 1, 2, "2")]
- [InlineData ("AB12", 1, 5, "2\n1\nB\nA")]
- [InlineData ("AB\n12", 2, 5, "B2\nA1")]
- [InlineData ("ABC 123 456", 2, 7, "6C\n5B\n4A\n \n3 \n2 \n1 ")]
+ [InlineData ("AB1 2", 2, 1, "2")]
+ [InlineData ("AB12", 5, 1, "21BA")]
+ [InlineData ("AB\n12", 5, 2, "BA\n21")]
+ [InlineData ("ABC 123 456", 7, 2, "654 321\nCBA ")]
[InlineData ("こんにちは", 1, 1, "")]
[InlineData ("こんにちは", 2, 1, "は")]
- [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")]
- [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")]
- [InlineData ("こんにちは\nAB\n12", 4, 10, "はB2\nちA1\nに \nん \nこ ")]
- public void Draw_Vertical_BottomTop_LeftRight (string text, int width, int height, string expectedText)
+ [InlineData ("こんにちは", 5, 1, "はち")]
+ [InlineData ("こんにちは", 10, 1, "はちにんこ")]
+ [InlineData ("こんにちは\nAB\n12", 10, 3, "はちにんこ\nBA \n21 ")]
+ public void Draw_Horizontal_RightLeft_TopBottom (string text, int width, int height, string expectedText)
{
TextFormatter tf = new ()
{
Text = text,
- Direction = TextDirection.BottomTop_LeftRight
+ Direction = TextDirection.RightLeft_TopBottom
};
tf.ConstrainToWidth = width;
@@ -3468,70 +400,6 @@ B ")]
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
}
- [SetupFakeDriver]
- [Theory]
- [InlineData ("A", 1, 0, "")]
- [InlineData ("A", 0, 1, "")]
- [InlineData ("AB1 2", 1, 2, "2")]
- [InlineData ("AB12", 1, 5, "2\n1\nB\nA")]
- [InlineData ("AB\n12", 2, 5, "2B\n1A")]
- [InlineData ("ABC 123 456", 2, 7, "C6\nB5\nA4\n \n 3\n 2\n 1")]
- [InlineData ("こんにちは", 1, 1, "")]
- [InlineData ("こんにちは", 2, 1, "は")]
- [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")]
- [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")]
- [InlineData ("こんにちは\nAB\n12", 4, 10, "2Bは\n1Aち\n に\n ん\n こ")]
- public void Draw_Vertical_BottomTop_RightLeft (string text, int width, int height, string expectedText)
- {
- TextFormatter tf = new ()
- {
- Text = text,
- Direction = TextDirection.BottomTop_RightLeft
- };
-
- tf.ConstrainToWidth = width;
- tf.ConstrainToHeight = height;
- tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
-
- TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
- }
-
- // Draw tests - Note that these depend on View
-
- [Fact]
- [TestRespondersDisposed]
- public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
- {
- Application.Init (new FakeDriver ());
-
- Toplevel top = new ();
-
- var view = new View { Y = -2, Height = 10, TextDirection = TextDirection.TopBottom_LeftRight, Text = "view" };
- top.Add (view);
-
- Application.Iteration += (s, a) =>
- {
- Assert.Equal (-2, view.Y);
-
- Application.RequestStop ();
- };
-
- try
- {
- Application.Run (top);
- }
- catch (IndexOutOfRangeException ex)
- {
- // After the fix this exception will not be caught.
- Assert.IsType (ex);
- }
-
- top.Dispose ();
-
- // Shutdown must be called to safely clean up Application if Init has been called
- Application.Shutdown ();
- }
-
[SetupFakeDriver]
[Theory]
@@ -6950,6 +3818,1334 @@ B ")]
TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
}
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("A", 0, 1, "", 0)]
+ [InlineData ("A", 1, 1, "A", 0)]
+ [InlineData ("A", 2, 2, " A", 1)]
+ [InlineData ("AB", 1, 1, "B", 0)]
+ [InlineData ("AB", 2, 2, " A\n B", 0)]
+ [InlineData ("ABC", 3, 2, " B\n C", 0)]
+ [InlineData ("ABC", 4, 2, " B\n C", 0)]
+ [InlineData ("ABC", 6, 2, " B\n C", 0)]
+ [InlineData ("こんにちは", 0, 1, "", 0)]
+ [InlineData ("こんにちは", 1, 0, "", 0)]
+ [InlineData ("こんにちは", 1, 1, "", 0)]
+ [InlineData ("こんにちは", 2, 1, "は", 0)]
+ [InlineData ("こんにちは", 2, 2, "ち\nは", 0)]
+ [InlineData ("こんにちは", 2, 3, "に\nち\nは", 0)]
+ [InlineData ("こんにちは", 2, 4, "ん\nに\nち\nは", 0)]
+ [InlineData ("こんにちは", 2, 5, "こ\nん\nに\nち\nは", 0)]
+ [InlineData ("こんにちは", 2, 6, "こ\nん\nに\nち\nは", 1)]
+ [InlineData ("ABCD\nこんにちは", 4, 7, " こ\n Aん\n Bに\n Cち\n Dは", 2)]
+ [InlineData ("こんにちは\nABCD", 3, 7, "こ \nんA\nにB\nちC\nはD", 2)]
+ public void Draw_Vertical_Bottom_Horizontal_Right (string text, int width, int height, string expectedText, int expectedY)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Alignment = Alignment.End,
+ Direction = TextDirection.TopBottom_LeftRight,
+ VerticalAlignment = Alignment.End
+ };
+
+ tf.ConstrainToWidth = width;
+ tf.ConstrainToHeight = height;
+
+ tf.Draw (new (Point.Empty, new (width, height)), Attribute.Default, Attribute.Default);
+ Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ Assert.Equal (expectedY, rect.Y);
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("A", 1, 0, "")]
+ [InlineData ("A", 0, 1, "")]
+ [InlineData ("AB1 2", 1, 2, "2")]
+ [InlineData ("AB12", 1, 5, "2\n1\nB\nA")]
+ [InlineData ("AB\n12", 2, 5, "B2\nA1")]
+ [InlineData ("ABC 123 456", 2, 7, "6C\n5B\n4A\n \n3 \n2 \n1 ")]
+ [InlineData ("こんにちは", 1, 1, "")]
+ [InlineData ("こんにちは", 2, 1, "は")]
+ [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")]
+ [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")]
+ [InlineData ("こんにちは\nAB\n12", 4, 10, "はB2\nちA1\nに \nん \nこ ")]
+ public void Draw_Vertical_BottomTop_LeftRight (string text, int width, int height, string expectedText)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Direction = TextDirection.BottomTop_LeftRight
+ };
+
+ tf.ConstrainToWidth = width;
+ tf.ConstrainToHeight = height;
+ tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("A", 1, 0, "")]
+ [InlineData ("A", 0, 1, "")]
+ [InlineData ("AB1 2", 1, 2, "2")]
+ [InlineData ("AB12", 1, 5, "2\n1\nB\nA")]
+ [InlineData ("AB\n12", 2, 5, "2B\n1A")]
+ [InlineData ("ABC 123 456", 2, 7, "C6\nB5\nA4\n \n 3\n 2\n 1")]
+ [InlineData ("こんにちは", 1, 1, "")]
+ [InlineData ("こんにちは", 2, 1, "は")]
+ [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")]
+ [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")]
+ [InlineData ("こんにちは\nAB\n12", 4, 10, "2Bは\n1Aち\n に\n ん\n こ")]
+ public void Draw_Vertical_BottomTop_RightLeft (string text, int width, int height, string expectedText)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Direction = TextDirection.BottomTop_RightLeft
+ };
+
+ tf.ConstrainToWidth = width;
+ tf.ConstrainToHeight = height;
+ tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
+
+ // Draw tests - Note that these depend on View
+
+ [Fact]
+ [TestRespondersDisposed]
+ public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
+ {
+ Application.Init (new FakeDriver ());
+
+ Toplevel top = new ();
+
+ var view = new View { Y = -2, Height = 10, TextDirection = TextDirection.TopBottom_LeftRight, Text = "view" };
+ top.Add (view);
+
+ Application.Iteration += (s, a) =>
+ {
+ Assert.Equal (-2, view.Y);
+
+ Application.RequestStop ();
+ };
+
+ try
+ {
+ Application.Run (top);
+ }
+ catch (IndexOutOfRangeException ex)
+ {
+ // After the fix this exception will not be caught.
+ Assert.IsType (ex);
+ }
+
+ top.Dispose ();
+
+ // Shutdown must be called to safely clean up Application if Init has been called
+ Application.Shutdown ();
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("A", 5, 5, "A")]
+ [InlineData (
+ "AB12",
+ 5,
+ 5,
+ @"
+A
+B
+1
+2")]
+ [InlineData (
+ "AB\n12",
+ 5,
+ 5,
+ @"
+A1
+B2")]
+ [InlineData ("", 5, 1, "")]
+ [InlineData (
+ "Hello Worlds",
+ 1,
+ 12,
+ @"
+H
+e
+l
+l
+o
+
+W
+o
+r
+l
+d
+s")]
+ [InlineData ("Hello Worlds", 12, 1, @"HelloWorlds")]
+ public void Draw_Vertical_TopBottom_LeftRight (string text, int width, int height, string expectedText)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Direction = TextDirection.TopBottom_LeftRight
+ };
+
+ tf.ConstrainToWidth = width;
+ tf.ConstrainToHeight = height;
+ tf.Draw (new (0, 0, 20, 20), Attribute.Default, Attribute.Default);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+
+ // The expectedY param is to probe that the expectedText param start at that Y coordinate
+ [InlineData ("A", 0, "", 0)]
+ [InlineData ("A", 1, "A", 0)]
+ [InlineData ("A", 2, "A", 0)]
+ [InlineData ("A", 3, "A", 1)]
+ [InlineData ("AB", 1, "A", 0)]
+ [InlineData ("AB", 2, "A\nB", 0)]
+ [InlineData ("ABC", 2, "A\nB", 0)]
+ [InlineData ("ABC", 3, "A\nB\nC", 0)]
+ [InlineData ("ABC", 4, "A\nB\nC", 0)]
+ [InlineData ("ABC", 5, "A\nB\nC", 1)]
+ [InlineData ("ABC", 6, "A\nB\nC", 1)]
+ [InlineData ("ABC", 9, "A\nB\nC", 3)]
+ [InlineData ("ABCD", 2, "B\nC", 0)]
+ [InlineData ("こんにちは", 0, "", 0)]
+ [InlineData ("こんにちは", 1, "に", 0)]
+ [InlineData ("こんにちは", 2, "ん\nに", 0)]
+ [InlineData ("こんにちは", 3, "ん\nに\nち", 0)]
+ [InlineData ("こんにちは", 4, "こ\nん\nに\nち", 0)]
+ [InlineData ("こんにちは", 5, "こ\nん\nに\nち\nは", 0)]
+ [InlineData ("こんにちは", 6, "こ\nん\nに\nち\nは", 0)]
+ [InlineData ("ABCD\nこんにちは", 7, "Aこ\nBん\nCに\nDち\n は", 1)]
+ [InlineData ("こんにちは\nABCD", 7, "こA\nんB\nにC\nちD\nは ", 1)]
+ public void Draw_Vertical_TopBottom_LeftRight_Middle (string text, int height, string expectedText, int expectedY)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Direction = TextDirection.TopBottom_LeftRight,
+ VerticalAlignment = Alignment.Center
+ };
+
+ int width = text.ToRunes ().Max (r => r.GetColumns ());
+
+ if (text.Contains ("\n"))
+ {
+ width++;
+ }
+
+ tf.ConstrainToWidth = width;
+ tf.ConstrainToHeight = height;
+ tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default);
+
+ Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ Assert.Equal (expectedY, rect.Y);
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("A", 5, "A")]
+ [InlineData (
+ "AB12",
+ 5,
+ @"
+A
+B
+1
+2")]
+ [InlineData (
+ "AB\n12",
+ 5,
+ @"
+A1
+B2")]
+ [InlineData ("", 1, "")]
+ [InlineData (
+ "AB1 2",
+ 2,
+ @"
+A12
+B ")]
+ [InlineData (
+ "こんにちは",
+ 1,
+ @"
+こん")]
+ [InlineData (
+ "こんにちは",
+ 2,
+ @"
+こに
+んち")]
+ [InlineData (
+ "こんにちは",
+ 5,
+ @"
+こ
+ん
+に
+ち
+は")]
+ public void Draw_Vertical_TopBottom_LeftRight_Top (string text, int height, string expectedText)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Direction = TextDirection.TopBottom_LeftRight
+ };
+
+ tf.ConstrainToWidth = 5;
+ tf.ConstrainToHeight = height;
+ tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
+
+ [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 (
+ 4,
+ 4,
+ TextDirection.TopBottom_LeftRight,
+ @"
+LMre
+eias
+ssb
+ ęl "
+ )]
+ public void Draw_With_Combining_Runes (int width, int height, TextDirection textDirection, string expected)
+ {
+ var driver = new FakeDriver ();
+ driver.Init ();
+
+ var text = "Les Mise\u0328\u0301rables";
+
+ var tf = new TextFormatter ();
+ tf.Direction = textDirection;
+ tf.Text = text;
+
+ Assert.True (tf.WordWrap);
+
+ tf.ConstrainToSize = new (width, height);
+
+ tf.Draw (
+ new (0, 0, width, height),
+ new (ColorName.White, ColorName.Black),
+ new (ColorName.Blue, ColorName.Black),
+ default (Rectangle),
+ driver
+ );
+ TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
+
+ driver.End ();
+ }
+
+ [Fact]
+ [SetupFakeDriver]
+ public void FillRemaining_True_False ()
+ {
+ ((FakeDriver)Application.Driver!).SetBufferSize (22, 5);
+
+ Attribute [] attrs =
+ {
+ Attribute.Default, new (ColorName.Green, ColorName.BrightMagenta),
+ new (ColorName.Blue, ColorName.Cyan)
+ };
+ var tf = new TextFormatter { ConstrainToSize = new (14, 3), Text = "Test\nTest long\nTest long long\n", MultiLine = true };
+
+ tf.Draw (
+ new (1, 1, 19, 3),
+ attrs [1],
+ attrs [2]);
+
+ Assert.False (tf.FillRemaining);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (
+ @"
+ Test
+ Test long
+ Test long long",
+ _output);
+
+ TestHelpers.AssertDriverAttributesAre (
+ @"
+000000000000000000000
+011110000000000000000
+011111111100000000000
+011111111111111000000
+000000000000000000000",
+ null,
+ attrs);
+
+ tf.FillRemaining = true;
+
+ tf.Draw (
+ new (1, 1, 19, 3),
+ attrs [1],
+ attrs [2]);
+
+ TestHelpers.AssertDriverAttributesAre (
+ @"
+000000000000000000000
+011111111111111111110
+011111111111111111110
+011111111111111111110
+000000000000000000000",
+ null,
+ attrs);
+ }
+
+ [Theory]
+ [InlineData ("_k Before", true, 0, (KeyCode)'K')] // lower case should return uppercase Hotkey
+ [InlineData ("a_k Second", true, 1, (KeyCode)'K')]
+ [InlineData ("Last _k", true, 5, (KeyCode)'K')]
+ [InlineData ("After k_", false, -1, KeyCode.Null)]
+ [InlineData ("Multiple _k and _R", true, 9, (KeyCode)'K')]
+ [InlineData ("Non-english: _кдать", true, 13, (KeyCode)'к')] // Lower case Cryllic K (к)
+ [InlineData ("_k Before", true, 0, (KeyCode)'K', true)] // Turn on FirstUpperCase and verify same results
+ [InlineData ("a_k Second", true, 1, (KeyCode)'K', true)]
+ [InlineData ("Last _k", true, 5, (KeyCode)'K', true)]
+ [InlineData ("After k_", false, -1, KeyCode.Null, true)]
+ [InlineData ("Multiple _k and _r", true, 9, (KeyCode)'K', true)]
+ [InlineData ("Non-english: _кдать", true, 13, (KeyCode)'к', true)] // Cryllic K (К)
+ public void FindHotKey_AlphaLowerCase_Succeeds (
+ string text,
+ bool expectedResult,
+ int expectedHotPos,
+ KeyCode expectedKey,
+ bool supportFirstUpperCase = false
+ )
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ bool result = TextFormatter.FindHotKey (
+ text,
+ hotKeySpecifier,
+ out int hotPos,
+ out Key hotKey,
+ supportFirstUpperCase
+ );
+
+ if (expectedResult)
+ {
+ Assert.True (result);
+ }
+ else
+ {
+ Assert.False (result);
+ }
+
+ Assert.Equal (expectedResult, result);
+ Assert.Equal (expectedHotPos, hotPos);
+ Assert.Equal (expectedKey, hotKey);
+ }
+
+ [Theory]
+ [InlineData ("_K Before", true, 0, (KeyCode)'K')]
+ [InlineData ("a_K Second", true, 1, (KeyCode)'K')]
+ [InlineData ("Last _K", true, 5, (KeyCode)'K')]
+ [InlineData ("After K_", false, -1, KeyCode.Null)]
+ [InlineData ("Multiple _K and _R", true, 9, (KeyCode)'K')]
+ [InlineData ("Non-english: _Кдать", true, 13, (KeyCode)'К')] // Cryllic K (К)
+ [InlineData ("_K Before", true, 0, (KeyCode)'K', true)] // Turn on FirstUpperCase and verify same results
+ [InlineData ("a_K Second", true, 1, (KeyCode)'K', true)]
+ [InlineData ("Last _K", true, 5, (KeyCode)'K', true)]
+ [InlineData ("After K_", false, -1, KeyCode.Null, true)]
+ [InlineData ("Multiple _K and _R", true, 9, (KeyCode)'K', true)]
+ [InlineData ("Non-english: _Кдать", true, 13, (KeyCode)'К', true)] // Cryllic K (К)
+ public void FindHotKey_AlphaUpperCase_Succeeds (
+ string text,
+ bool expectedResult,
+ int expectedHotPos,
+ KeyCode expectedKey,
+ bool supportFirstUpperCase = false
+ )
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ bool result = TextFormatter.FindHotKey (
+ text,
+ hotKeySpecifier,
+ out int hotPos,
+ out Key hotKey,
+ supportFirstUpperCase
+ );
+
+ if (expectedResult)
+ {
+ Assert.True (result);
+ }
+ else
+ {
+ Assert.False (result);
+ }
+
+ Assert.Equal (expectedResult, result);
+ Assert.Equal (expectedHotPos, hotPos);
+ Assert.Equal (expectedKey, hotKey);
+ }
+
+ [Theory]
+ [InlineData (null)]
+ [InlineData ("")]
+ [InlineData ("no hotkey")]
+ [InlineData ("No hotkey, Upper Case")]
+ [InlineData ("Non-english: Сохранить")]
+ public void FindHotKey_Invalid_ReturnsFalse (string text)
+ {
+ var hotKeySpecifier = (Rune)'_';
+ var supportFirstUpperCase = false;
+ var hotPos = 0;
+ Key hotKey = KeyCode.Null;
+ var result = false;
+
+ result = TextFormatter.FindHotKey (
+ text,
+ hotKeySpecifier,
+ out hotPos,
+ out hotKey,
+ supportFirstUpperCase
+ );
+ Assert.False (result);
+ Assert.Equal (-1, hotPos);
+ Assert.Equal (KeyCode.Null, hotKey);
+ }
+
+ [Theory]
+ [InlineData ("\"k before")]
+ [InlineData ("ak second")]
+ [InlineData ("last k")]
+ [InlineData ("multiple k and r")]
+ [InlineData ("12345")]
+ [InlineData ("`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?")] // punctuation
+ [InlineData (" ~ s gui.cs master ↑10")] // ~IsLetterOrDigit + Unicode
+ [InlineData ("non-english: кдать")] // Lower case Cryllic K (к)
+ public void FindHotKey_Legacy_FirstUpperCase_NotFound_Returns_False (string text)
+ {
+ var supportFirstUpperCase = true;
+
+ var hotKeySpecifier = (Rune)0;
+
+ bool result = TextFormatter.FindHotKey (
+ text,
+ hotKeySpecifier,
+ out int hotPos,
+ out Key hotKey,
+ supportFirstUpperCase
+ );
+ Assert.False (result);
+ Assert.Equal (-1, hotPos);
+ Assert.Equal (KeyCode.Null, hotKey);
+ }
+
+ [Theory]
+ [InlineData ("K Before", true, 0, (KeyCode)'K')]
+ [InlineData ("aK Second", true, 1, (KeyCode)'K')]
+ [InlineData ("last K", true, 5, (KeyCode)'K')]
+ [InlineData ("multiple K and R", true, 9, (KeyCode)'K')]
+ [InlineData ("non-english: Кдать", true, 13, (KeyCode)'К')] // Cryllic K (К)
+ public void FindHotKey_Legacy_FirstUpperCase_Succeeds (
+ string text,
+ bool expectedResult,
+ int expectedHotPos,
+ KeyCode expectedKey
+ )
+ {
+ var supportFirstUpperCase = true;
+
+ var hotKeySpecifier = (Rune)0;
+
+ bool result = TextFormatter.FindHotKey (
+ text,
+ hotKeySpecifier,
+ out int hotPos,
+ out Key hotKey,
+ supportFirstUpperCase
+ );
+
+ if (expectedResult)
+ {
+ Assert.True (result);
+ }
+ else
+ {
+ Assert.False (result);
+ }
+
+ Assert.Equal (expectedResult, result);
+ Assert.Equal (expectedHotPos, hotPos);
+ Assert.Equal (expectedKey, hotKey);
+ }
+
+ [Theory]
+ [InlineData ("_1 Before", true, 0, (KeyCode)'1')] // Digits
+ [InlineData ("a_1 Second", true, 1, (KeyCode)'1')]
+ [InlineData ("Last _1", true, 5, (KeyCode)'1')]
+ [InlineData ("After 1_", false, -1, KeyCode.Null)]
+ [InlineData ("Multiple _1 and _2", true, 9, (KeyCode)'1')]
+ [InlineData ("_1 Before", true, 0, (KeyCode)'1', true)] // Turn on FirstUpperCase and verify same results
+ [InlineData ("a_1 Second", true, 1, (KeyCode)'1', true)]
+ [InlineData ("Last _1", true, 5, (KeyCode)'1', true)]
+ [InlineData ("After 1_", false, -1, KeyCode.Null, true)]
+ [InlineData ("Multiple _1 and _2", true, 9, (KeyCode)'1', true)]
+ public void FindHotKey_Numeric_Succeeds (
+ string text,
+ bool expectedResult,
+ int expectedHotPos,
+ KeyCode expectedKey,
+ bool supportFirstUpperCase = false
+ )
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ bool result = TextFormatter.FindHotKey (
+ text,
+ hotKeySpecifier,
+ out int hotPos,
+ out Key hotKey,
+ supportFirstUpperCase
+ );
+
+ if (expectedResult)
+ {
+ Assert.True (result);
+ }
+ else
+ {
+ Assert.False (result);
+ }
+
+ Assert.Equal (expectedResult, result);
+ Assert.Equal (expectedHotPos, hotPos);
+ Assert.Equal (expectedKey, hotKey);
+ }
+
+ [Theory]
+ [InlineData ("_\"k before", true, (KeyCode)'"')] // BUGBUG: Not sure why this fails. " is a normal char
+ [InlineData ("\"_k before", true, KeyCode.K)]
+ [InlineData ("_`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", true, (KeyCode)'`')]
+ [InlineData ("`_~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", true, (KeyCode)'~')]
+ [InlineData (
+ "`~!@#$%^&*()-__=+[{]}\\|;:'\",<.>/?",
+ true,
+ (KeyCode)'='
+ )] // BUGBUG: Not sure why this fails. Ignore the first and consider the second
+ [InlineData ("_ ~ s gui.cs master ↑10", true, (KeyCode)'')] // ~IsLetterOrDigit + Unicode
+ [InlineData (" ~ s gui.cs _ master ↑10", true, (KeyCode)'')] // ~IsLetterOrDigit + Unicode
+ [InlineData ("non-english: _кдать", true, (KeyCode)'к')] // Lower case Cryllic K (к)
+ public void FindHotKey_Symbols_Returns_Symbol (string text, bool found, KeyCode expected)
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ bool result = TextFormatter.FindHotKey (text, hotKeySpecifier, out int _, out Key hotKey);
+ Assert.Equal (found, result);
+ Assert.Equal (expected, hotKey);
+ }
+
+ [Fact]
+ public void Format_Dont_Throw_ArgumentException_With_WordWrap_As_False_And_Keep_End_Spaces_As_True ()
+ {
+ Exception exception = Record.Exception (
+ () =>
+ TextFormatter.Format (
+ "Some text",
+ 4,
+ Alignment.Start,
+ false,
+ true
+ )
+ );
+ Assert.Null (exception);
+ }
+
+ [Theory]
+ [InlineData (
+ "Hello world, how are you today? Pretty neat!",
+ 44,
+ 80,
+ "Hello world, how are you today? Pretty neat!"
+ )]
+ public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Horizontal (
+ string text,
+ int runeCount,
+ int maxWidth,
+ string justifiedText
+ )
+ {
+ Assert.Equal (runeCount, text.GetRuneCount ());
+
+ var fmtText = string.Empty;
+
+ for (int i = text.GetRuneCount (); i < maxWidth; i++)
+ {
+ fmtText = TextFormatter.Format (text, i, Alignment.Fill, true) [0];
+ Assert.Equal (i, fmtText.GetRuneCount ());
+ char c = fmtText [^1];
+ Assert.True (text.EndsWith (c));
+ }
+
+ Assert.Equal (justifiedText, fmtText);
+ }
+
+ [Theory]
+ [InlineData (
+ "Hello world, how are you today? Pretty neat!",
+ 44,
+ 80,
+ "Hello world, how are you today? Pretty neat!"
+ )]
+ public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Vertical (
+ string text,
+ int runeCount,
+ int maxWidth,
+ string justifiedText
+ )
+ {
+ Assert.Equal (runeCount, text.GetRuneCount ());
+
+ var fmtText = string.Empty;
+
+ for (int i = text.GetRuneCount (); i < maxWidth; i++)
+ {
+ fmtText = TextFormatter.Format (
+ text,
+ i,
+ Alignment.Fill,
+ false,
+ true,
+ 0,
+ TextDirection.TopBottom_LeftRight
+ ) [0];
+ Assert.Equal (i, fmtText.GetRuneCount ());
+ char c = fmtText [^1];
+ Assert.True (text.EndsWith (c));
+ }
+
+ Assert.Equal (justifiedText, fmtText);
+ }
+
+ [Theory]
+ [InlineData ("Truncate", 3, "Tru")]
+ [InlineData ("デモエムポンズ", 3, "デ")]
+ public void Format_Truncate_Simple_And_Wide_Runes (string text, int width, string expected)
+ {
+ List list = TextFormatter.Format (text, width, false, false);
+ Assert.Equal (expected, list [^1]);
+ }
+
+ [Theory]
+ [MemberData (nameof (FormatEnvironmentNewLine))]
+ public void Format_With_PreserveTrailingSpaces_And_Without_PreserveTrailingSpaces (
+ string text,
+ int width,
+ IEnumerable expected
+ )
+ {
+ var preserveTrailingSpaces = false;
+ List formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces);
+ Assert.Equal (expected, formated);
+
+ preserveTrailingSpaces = true;
+ formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces);
+ Assert.Equal (expected, formated);
+ }
+
+ [Theory]
+ [InlineData (
+ " A sentence has words. \n This is the second Line - 2. ",
+ 4,
+ -50,
+ Alignment.Start,
+ true,
+ false,
+ new [] { " A", "sent", "ence", "has", "word", "s. ", " Thi", "s is", "the", "seco", "nd", "Line", "- 2." },
+ " Asentencehaswords. This isthesecondLine- 2."
+ )]
+ [InlineData (
+ " A sentence has words. \n This is the second Line - 2. ",
+ 4,
+ -50,
+ Alignment.Start,
+ true,
+ true,
+ new []
+ {
+ " A ",
+ "sent",
+ "ence",
+ " ",
+ "has ",
+ "word",
+ "s. ",
+ " ",
+ "This",
+ " is ",
+ "the ",
+ "seco",
+ "nd ",
+ "Line",
+ " - ",
+ "2. "
+ },
+ " A sentence has words. This is the second Line - 2. "
+ )]
+ public void Format_WordWrap_PreserveTrailingSpaces (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ bool preserveTrailingSpaces,
+ IEnumerable resultLines,
+ string expectedWrappedText
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
+ Assert.Equal (list.Count, resultLines.Count ());
+ Assert.Equal (resultLines, list);
+ var wrappedText = string.Empty;
+
+ foreach (string txt in list)
+ {
+ wrappedText += txt;
+ }
+
+ Assert.Equal (expectedWrappedText, wrappedText);
+ }
+
+ public static IEnumerable FormatEnvironmentNewLine =>
+ new List
+ {
+ new object []
+ {
+ $"Line1{Environment.NewLine}Line2{Environment.NewLine}Line3{Environment.NewLine}",
+ 60,
+ new [] { "Line1", "Line2", "Line3" }
+ }
+ };
+
+ [Theory]
+ [InlineData ("Hello World", 11)]
+ [InlineData ("こんにちは世界", 14)]
+ public void GetColumns_Simple_And_Wide_Runes (string text, int width) { Assert.Equal (width, text.GetColumns ()); }
+
+ [Theory]
+ [InlineData (new [] { "0123456789" }, 1)]
+ [InlineData (new [] { "Hello World" }, 1)]
+ [InlineData (new [] { "Hello", "World" }, 2)]
+ [InlineData (new [] { "こんにちは", "世界" }, 4)]
+ public void GetColumnsRequiredForVerticalText_List_GetsWidth (IEnumerable text, int expectedWidth)
+ {
+ Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ()));
+ }
+
+ [Theory]
+ [InlineData (new [] { "Hello World" }, 1, 0, 1, 1)]
+ [InlineData (new [] { "Hello", "World" }, 2, 1, 1, 1)]
+ [InlineData (new [] { "こんにちは", "世界" }, 4, 1, 1, 2)]
+ public void GetColumnsRequiredForVerticalText_List_Simple_And_Wide_Runes (
+ IEnumerable text,
+ int expectedWidth,
+ int index,
+ int length,
+ int expectedIndexWidth
+ )
+ {
+ Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ()));
+ Assert.Equal (expectedIndexWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList (), index, length));
+ }
+
+ [Fact]
+ public void GetColumnsRequiredForVerticalText_List_With_Combining_Runes ()
+ {
+ List text = new () { "Les Mis", "e\u0328\u0301", "rables" };
+ Assert.Equal (1, TextFormatter.GetColumnsRequiredForVerticalText (text, 1, 1));
+ }
+
+ [Theory]
+ [InlineData ("Hello World", 6, 6)]
+ [InlineData ("こんにちは 世界", 6, 3)]
+ [MemberData (nameof (CMGlyphs))]
+ public void GetLengthThatFits_List_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
+ {
+ List runes = text.ToRuneList ();
+ Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
+ }
+
+ [Theory]
+ [InlineData ("test", 3, 3)]
+ [InlineData ("test", 4, 4)]
+ [InlineData ("test", 10, 4)]
+ public void GetLengthThatFits_Runelist (string text, int columns, int expectedLength)
+ {
+ List runes = text.ToRuneList ();
+
+ Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
+ }
+
+ [Theory]
+ [InlineData ("Hello World", 6, 6)]
+ [InlineData ("こんにちは 世界", 6, 3)]
+ public void GetLengthThatFits_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
+ {
+ Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
+ }
+
+ [Theory]
+ [InlineData ("test", 3, 3)]
+ [InlineData ("test", 4, 4)]
+ [InlineData ("test", 10, 4)]
+ [InlineData ("test", 1, 1)]
+ [InlineData ("test", 0, 0)]
+ [InlineData ("test", -1, 0)]
+ [InlineData (null, -1, 0)]
+ [InlineData ("", -1, 0)]
+ public void GetLengthThatFits_String (string text, int columns, int expectedLength)
+ {
+ Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
+ }
+
+ [Fact]
+ public void GetLengthThatFits_With_Combining_Runes ()
+ {
+ var text = "Les Mise\u0328\u0301rables";
+ Assert.Equal (16, TextFormatter.GetLengthThatFits (text, 14));
+ }
+
+ [Fact]
+ public void GetMaxColsForWidth_With_Combining_Runes ()
+ {
+ List text = new () { "Les Mis", "e\u0328\u0301", "rables" };
+ Assert.Equal (1, TextFormatter.GetMaxColsForWidth (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 Internal_Tests ()
+ {
+ var tf = new TextFormatter ();
+ Assert.Equal (KeyCode.Null, tf.HotKey);
+ tf.HotKey = KeyCode.CtrlMask | KeyCode.Q;
+ Assert.Equal (KeyCode.CtrlMask | KeyCode.Q, tf.HotKey);
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("Hello World", 15, 1, "Hello World")]
+ [InlineData (
+ "Well Done\nNice Work",
+ 15,
+ 2,
+ @"
+Well Done
+Nice Work")]
+ [InlineData ("你好 世界", 15, 1, "你好 世界")]
+ [InlineData (
+ "做 得好\n幹 得好",
+ 15,
+ 2,
+ @"
+做 得好
+幹 得好")]
+ public void Justify_Horizontal (string text, int width, int height, string expectedText)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Alignment = Alignment.Fill,
+ ConstrainToSize = new Size (width, height),
+ MultiLine = true
+ };
+
+ tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
+
+ [Theory]
+ [InlineData ("")]
+ [InlineData (null)]
+ [InlineData ("test")]
+ public void Justify_Invalid (string text)
+ {
+ Assert.Equal (text, TextFormatter.Justify (text, 0));
+ Assert.Equal (text, TextFormatter.Justify (text, 0));
+ Assert.Throws (() => TextFormatter.Justify (text, -1));
+ }
+
+ [Theory]
+
+ // Even # of spaces
+ // 0123456789
+ [InlineData ("012 456 89", "012 456 89", 10, 0, "+", true)]
+ [InlineData ("012 456 89", "012++456+89", 11, 1)]
+ [InlineData ("012 456 89", "012 456 89", 12, 2, "++", true)]
+ [InlineData ("012 456 89", "012+++456++89", 13, 3)]
+ [InlineData ("012 456 89", "012 456 89", 14, 4, "+++", true)]
+ [InlineData ("012 456 89", "012++++456+++89", 15, 5)]
+ [InlineData ("012 456 89", "012 456 89", 16, 6, "++++", true)]
+ [InlineData ("012 456 89", "012 456 89", 30, 20, "+++++++++++", true)]
+ [InlineData ("012 456 89", "012+++++++++++++456++++++++++++89", 33, 23)]
+
+ // Odd # of spaces
+ // 01234567890123
+ [InlineData ("012 456 89 end", "012 456 89 end", 14, 0, "+", true)]
+ [InlineData ("012 456 89 end", "012++456+89+end", 15, 1)]
+ [InlineData ("012 456 89 end", "012++456++89+end", 16, 2)]
+ [InlineData ("012 456 89 end", "012 456 89 end", 17, 3, "++", true)]
+ [InlineData ("012 456 89 end", "012+++456++89++end", 18, 4)]
+ [InlineData ("012 456 89 end", "012+++456+++89++end", 19, 5)]
+ [InlineData ("012 456 89 end", "012 456 89 end", 20, 6, "+++", true)]
+ [InlineData ("012 456 89 end", "012++++++++456++++++++89+++++++end", 34, 20)]
+ [InlineData ("012 456 89 end", "012+++++++++456+++++++++89++++++++end", 37, 23)]
+
+ // Unicode
+ // Even # of chars
+ // 0123456789
+ [InlineData ("пÑРвРÑ", "пÑРвРÑ", 10, 0, "+", true)]
+ [InlineData ("пÑРвРÑ", "пÑÐ++вÐ+Ñ", 11, 1)]
+ [InlineData ("пÑРвРÑ", "пÑРвРÑ", 12, 2, "++", true)]
+ [InlineData ("пÑРвРÑ", "пÑÐ+++вÐ++Ñ", 13, 3)]
+ [InlineData ("пÑРвРÑ", "пÑРвРÑ", 14, 4, "+++", true)]
+ [InlineData ("пÑРвРÑ", "пÑÐ++++вÐ+++Ñ", 15, 5)]
+ [InlineData ("пÑРвРÑ", "пÑРвРÑ", 16, 6, "++++", true)]
+ [InlineData ("пÑРвРÑ", "пÑРвРÑ", 30, 20, "+++++++++++", true)]
+ [InlineData ("пÑРвРÑ", "пÑÐ+++++++++++++вÐ++++++++++++Ñ", 33, 23)]
+
+ // Unicode
+ // Odd # of chars
+ // 0123456789
+ [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 10, 0, "+", true)]
+ [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ+вÐ+Ñ", 11, 1)]
+ [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ++вÐ+Ñ", 12, 2)]
+ [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 13, 3, "++", true)]
+ [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ++вÐ++Ñ", 14, 4)]
+ [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ+++вÐ++Ñ", 15, 5)]
+ [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 16, 6, "+++", true)]
+ [InlineData ("Ð ÑРвРÑ", "Ð++++++++ÑÐ++++++++вÐ+++++++Ñ", 30, 20)]
+ [InlineData ("Ð ÑРвРÑ", "Ð+++++++++ÑÐ+++++++++вÐ++++++++Ñ", 33, 23)]
+ public void Justify_Sentence (
+ string text,
+ string justifiedText,
+ int forceToWidth,
+ int widthOffset,
+ string replaceWith = null,
+ bool replace = false
+ )
+ {
+ var fillChar = '+';
+
+ Assert.Equal (forceToWidth, text.GetRuneCount () + widthOffset);
+
+ if (replace)
+ {
+ justifiedText = text.Replace (" ", replaceWith);
+ }
+
+ Assert.Equal (justifiedText, TextFormatter.Justify (text, forceToWidth, fillChar));
+ Assert.True (Math.Abs (forceToWidth - justifiedText.GetRuneCount ()) < text.Count (s => s == ' '));
+ Assert.True (Math.Abs (forceToWidth - justifiedText.GetColumns ()) < text.Count (s => s == ' '));
+ }
+
+ [Theory]
+ [InlineData ("word")] // Even # of chars
+ [InlineData ("word.")] // Odd # of chars
+ [InlineData ("пÑивеÑ")] // Unicode (even #)
+ [InlineData ("пÑивеÑ.")] // Unicode (odd # of chars)
+ public void Justify_SingleWord (string text)
+ {
+ string justifiedText = text;
+ var fillChar = '+';
+
+ int width = text.GetRuneCount ();
+ Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
+ width = text.GetRuneCount () + 1;
+ Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
+ width = text.GetRuneCount () + 2;
+ Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
+ width = text.GetRuneCount () + 10;
+ Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
+ width = text.GetRuneCount () + 11;
+ Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
+ }
+
+ [SetupFakeDriver]
+ [Theory]
+ [InlineData ("Hello World", 1, 15, "H\ne\nl\nl\no\n \n \n \n \n \nW\no\nr\nl\nd")]
+ [InlineData (
+ "Well Done\nNice Work",
+ 2,
+ 15,
+ @"
+WN
+ei
+lc
+le
+
+
+
+
+
+
+
+DW
+oo
+nr
+ek")]
+ [InlineData ("你好 世界", 2, 15, "你\n好\n \n \n \n \n \n \n \n \n \n \n \n世\n界")]
+ [InlineData (
+ "做 得好\n幹 得好",
+ 4,
+ 15,
+ @"
+做幹
+
+
+
+
+
+
+
+
+
+
+
+
+得得
+好好")]
+ public void Justify_Vertical (string text, int width, int height, string expectedText)
+ {
+ TextFormatter tf = new ()
+ {
+ Text = text,
+ Direction = TextDirection.TopBottom_LeftRight,
+ VerticalAlignment = Alignment.Fill,
+ ConstrainToSize = new Size (width, height),
+ MultiLine = true
+ };
+
+ tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
+
+ TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
+ }
+
+ [Theory]
+ [InlineData ("Single Line 界", 14)]
+ [InlineData ("First Line 界\nSecond Line 界\nThird Line 界\n", 14)]
+ public void MaxWidthLine_With_And_Without_Newlines (string text, int expected) { Assert.Equal (expected, TextFormatter.GetWidestLineLength (text)); }
+
+ [Theory]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 0,
+ false,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 1,
+ false,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 1,
+ 0,
+ false,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 0,
+ true,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 1,
+ true,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 1,
+ 0,
+ true,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 6,
+ 5,
+ false,
+ new [] { "First " }
+ )]
+ [InlineData ("1\n2\n3\n4\n5\n6", 6, 5, false, new [] { "1 2 3 " })]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 6,
+ 5,
+ true,
+ new [] { "First ", "Second", "Third ", "Forty ", "Fiftee" }
+ )]
+ [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, false, new [] { "第一" })]
+ [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, true, new [] { "第一", "第二", "第三", "四十", "第十" })]
+ public void MultiLine_WordWrap_False_Horizontal_Direction (
+ string text,
+ int maxWidth,
+ int maxHeight,
+ bool multiLine,
+ IEnumerable resultLines
+ )
+ {
+ var tf = new TextFormatter
+ {
+ Text = text, ConstrainToSize = new (maxWidth, maxHeight), WordWrap = false, MultiLine = multiLine
+ };
+
+ Assert.False (tf.WordWrap);
+ Assert.True (tf.MultiLine == multiLine);
+ Assert.Equal (TextDirection.LeftRight_TopBottom, tf.Direction);
+
+ List splitLines = tf.GetLines ();
+ Assert.Equal (splitLines.Count, resultLines.Count ());
+ Assert.Equal (splitLines, resultLines);
+ }
+
+ [Theory]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 0,
+ false,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 1,
+ false,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 1,
+ 0,
+ false,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 0,
+ true,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 0,
+ 1,
+ true,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 1,
+ 0,
+ true,
+ new [] { "" }
+ )]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 6,
+ 5,
+ false,
+ new [] { "First" }
+ )]
+ [InlineData ("1\n2\n3\n4\n5\n6", 6, 5, false, new [] { "1 2 3" })]
+ [InlineData (
+ "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
+ 6,
+ 5,
+ true,
+ new [] { "First", "Secon", "Third", "Forty", "Fifte", "Seven" }
+ )]
+ [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, false, new [] { "第一行 第" })]
+ [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, true, new [] { "第一行", "第二行" })]
+ public void MultiLine_WordWrap_False_Vertical_Direction (
+ string text,
+ int maxWidth,
+ int maxHeight,
+ bool multiLine,
+ IEnumerable resultLines
+ )
+ {
+ var tf = new TextFormatter
+ {
+ Text = text,
+ ConstrainToSize = new (maxWidth, maxHeight),
+ WordWrap = false,
+ MultiLine = multiLine,
+ Direction = TextDirection.TopBottom_LeftRight
+ };
+
+ Assert.False (tf.WordWrap);
+ Assert.True (tf.MultiLine == multiLine);
+ Assert.Equal (TextDirection.TopBottom_LeftRight, tf.Direction);
+
+ List splitLines = tf.GetLines ();
+ Assert.Equal (splitLines.Count, resultLines.Count ());
+ Assert.Equal (splitLines, resultLines);
+ }
+
+ [Fact]
+ public void NeedsFormat_Sets ()
+ {
+ var testText = "test";
+ var testBounds = new Rectangle (0, 0, 100, 1);
+ var tf = new TextFormatter ();
+
+ tf.Text = "test";
+ Assert.True (tf.NeedsFormat); // get_Lines causes a Format
+ Assert.NotEmpty (tf.GetLines ());
+ Assert.False (tf.NeedsFormat); // get_Lines causes a Format
+ Assert.Equal (testText, tf.Text);
+ tf.Draw (testBounds, new (), new ());
+ Assert.False (tf.NeedsFormat);
+
+ tf.ConstrainToSize = new (1, 1);
+ Assert.True (tf.NeedsFormat);
+ Assert.NotEmpty (tf.GetLines ());
+ Assert.False (tf.NeedsFormat); // get_Lines causes a Format
+
+ tf.Alignment = Alignment.Center;
+ Assert.True (tf.NeedsFormat);
+ Assert.NotEmpty (tf.GetLines ());
+ Assert.False (tf.NeedsFormat); // get_Lines causes a Format
+ }
+
// Test that changing TextFormatter does not impact View dimensions if Dim.Auto is not in play
[Fact]
public void Not_Used_TextFormatter_Does_Not_Change_View_Size ()
@@ -6998,6 +5194,1835 @@ B ")]
Assert.Equal (Size.Empty, view.Frame.Size);
}
+ [Theory]
+ [InlineData ("", -1, Alignment.Start, false, 0)]
+ [InlineData (null, 0, Alignment.Start, false, 1)]
+ [InlineData (null, 0, Alignment.Start, true, 1)]
+ [InlineData ("", 0, Alignment.Start, false, 1)]
+ [InlineData ("", 0, Alignment.Start, true, 1)]
+ public void Reformat_Invalid (string text, int maxWidth, Alignment alignment, bool wrap, int linesCount)
+ {
+ if (maxWidth < 0)
+ {
+ Assert.Throws (
+ () =>
+ TextFormatter.Format (text, maxWidth, alignment, wrap)
+ );
+ }
+ else
+ {
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap);
+ Assert.NotEmpty (list);
+ Assert.True (list.Count == linesCount);
+ Assert.Equal (string.Empty, list [0]);
+ }
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true)]
+ [InlineData ("A sentence has words.\nLine 2.", 1, -28, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\nLine 2.", 5, -24, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\nLine 2.", 28, -1, Alignment.Start, false, 1, false)]
+
+ // no clip
+ [InlineData ("A sentence has words.\nLine 2.", 29, 0, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\nLine 2.", 30, 1, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true)]
+ [InlineData ("A sentence has words.\r\nLine 2.", 1, -29, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\r\nLine 2.", 5, -25, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\r\nLine 2.", 29, -1, Alignment.Start, false, 1, false, 1)]
+ [InlineData ("A sentence has words.\r\nLine 2.", 30, 0, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.\r\nLine 2.", 31, 1, Alignment.Start, false, 1, false)]
+ public void Reformat_NoWordrap_NewLines_MultiLine_False (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ int linesCount,
+ bool stringEmpty,
+ int clipWidthOffset = 0
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth) + clipWidthOffset;
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap);
+ Assert.NotEmpty (list);
+ Assert.True (list.Count == linesCount);
+
+ if (stringEmpty)
+ {
+ Assert.Equal (string.Empty, list [0]);
+ }
+ else
+ {
+ Assert.NotEqual (string.Empty, list [0]);
+ }
+
+ if (text.Contains ("\r\n") && maxWidth > 0)
+ {
+ Assert.Equal (
+ StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth])
+ .Replace ("\r\n", " "),
+ list [0]
+ );
+ }
+ else if (text.Contains ('\n') && maxWidth > 0)
+ {
+ Assert.Equal (
+ StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth])
+ .Replace ("\n", " "),
+ list [0]
+ );
+ }
+ else
+ {
+ Assert.Equal (StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]), list [0]);
+ }
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true, new [] { "" })]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 1,
+ -28,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A", "L" }
+ )]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 5,
+ -24,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sen", "Line " }
+ )]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 28,
+ -1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ //// no clip
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 29,
+ 0,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 30,
+ 1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true, new [] { "" })]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 1,
+ -29,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A", "L" }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 5,
+ -25,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sen", "Line " }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 29,
+ -1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 30,
+ 0,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 31,
+ 1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ public void Reformat_NoWordrap_NewLines_MultiLine_True (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ int linesCount,
+ bool stringEmpty,
+ IEnumerable resultLines
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+
+ List list = TextFormatter.Format (
+ text,
+ maxWidth,
+ alignment,
+ wrap,
+ false,
+ 0,
+ TextDirection.LeftRight_TopBottom,
+ true
+ );
+ Assert.NotEmpty (list);
+ Assert.True (list.Count == linesCount);
+
+ if (stringEmpty)
+ {
+ Assert.Equal (string.Empty, list [0]);
+ }
+ else
+ {
+ Assert.NotEqual (string.Empty, list [0]);
+ }
+
+ Assert.Equal (list, resultLines);
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true, new [] { "" })]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 1,
+ -28,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A", "L" }
+ )]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 5,
+ -24,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sen", "Line " }
+ )]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 28,
+ -1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ //// no clip
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 29,
+ 0,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData (
+ "A sentence has words.\nLine 2.",
+ 30,
+ 1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true, new [] { "" })]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 1,
+ -29,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A", "L" }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 5,
+ -25,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sen", "Line " }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 29,
+ -1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 30,
+ 0,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ [InlineData (
+ "A sentence has words.\r\nLine 2.",
+ 31,
+ 1,
+ Alignment.Start,
+ false,
+ 2,
+ false,
+ new [] { "A sentence has words.", "Line 2." }
+ )]
+ public void Reformat_NoWordrap_NewLines_MultiLine_True_Vertical (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ int linesCount,
+ bool stringEmpty,
+ IEnumerable resultLines
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+
+ List list = TextFormatter.Format (
+ text,
+ maxWidth,
+ alignment,
+ wrap,
+ false,
+ 0,
+ TextDirection.TopBottom_LeftRight,
+ true
+ );
+ Assert.NotEmpty (list);
+ Assert.True (list.Count == linesCount);
+
+ if (stringEmpty)
+ {
+ Assert.Equal (string.Empty, list [0]);
+ }
+ else
+ {
+ Assert.NotEqual (string.Empty, list [0]);
+ }
+
+ Assert.Equal (list, resultLines);
+ }
+
+ [Theory]
+ [InlineData ("", 0, 0, Alignment.Start, false, 1, true)]
+ [InlineData ("", 1, 1, Alignment.Start, false, 1, true)]
+ [InlineData ("A sentence has words.", 0, -21, Alignment.Start, false, 1, true)]
+ [InlineData ("A sentence has words.", 1, -20, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.", 5, -16, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.", 20, -1, Alignment.Start, false, 1, false)]
+
+ // no clip
+ [InlineData ("A sentence has words.", 21, 0, Alignment.Start, false, 1, false)]
+ [InlineData ("A sentence has words.", 22, 1, Alignment.Start, false, 1, false)]
+ public void Reformat_NoWordrap_SingleLine (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ int linesCount,
+ bool stringEmpty
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap);
+ Assert.NotEmpty (list);
+ Assert.True (list.Count == linesCount);
+
+ if (stringEmpty)
+ {
+ Assert.Equal (string.Empty, list [0]);
+ }
+ else
+ {
+ Assert.NotEqual (string.Empty, list [0]);
+ }
+
+ Assert.Equal (StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]), list [0]);
+ }
+
+ [Theory]
+
+ // Unicode
+ [InlineData (
+ "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
+ 8,
+ -1,
+ Alignment.Start,
+ true,
+ false,
+ new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
+ )]
+
+ // no clip
+ [InlineData (
+ "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
+ 9,
+ 0,
+ Alignment.Start,
+ true,
+ false,
+ new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
+ )]
+ [InlineData (
+ "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
+ 10,
+ 1,
+ Alignment.Start,
+ true,
+ false,
+ new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
+ )]
+ public void Reformat_Unicode_Wrap_Spaces_NewLines (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ bool preserveTrailingSpaces,
+ IEnumerable resultLines
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
+ Assert.Equal (list.Count, resultLines.Count ());
+ Assert.Equal (resultLines, list);
+ }
+
+ [Theory]
+
+ // Unicode
+ // Even # of chars
+ // 0123456789
+ [InlineData ("\u2660пÑРвРÑ", 10, -1, Alignment.Start, true, false, new [] { "\u2660пÑРвÐ", "Ñ" })]
+
+ // no clip
+ [InlineData ("\u2660пÑРвРÑ", 11, 0, Alignment.Start, true, false, new [] { "\u2660пÑРвРÑ" })]
+ [InlineData ("\u2660пÑРвРÑ", 12, 1, Alignment.Start, true, false, new [] { "\u2660пÑРвРÑ" })]
+
+ // Unicode
+ // Odd # of chars
+ // 0123456789
+ [InlineData ("\u2660 ÑРвРÑ", 9, -1, Alignment.Start, true, false, new [] { "\u2660 ÑРвÐ", "Ñ" })]
+
+ // no clip
+ [InlineData ("\u2660 ÑРвРÑ", 10, 0, Alignment.Start, true, false, new [] { "\u2660 ÑРвРÑ" })]
+ [InlineData ("\u2660 ÑРвРÑ", 11, 1, Alignment.Start, true, false, new [] { "\u2660 ÑРвРÑ" })]
+ public void Reformat_Unicode_Wrap_Spaces_No_NewLines (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ bool preserveTrailingSpaces,
+ IEnumerable resultLines
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
+ Assert.Equal (list.Count, resultLines.Count ());
+ Assert.Equal (resultLines, list);
+ }
+
+ [Theory]
+
+ // Even # of spaces
+ // 0123456789
+ [InlineData ("012 456 89", 0, -10, Alignment.Start, true, true, true, new [] { "" })]
+ [InlineData (
+ "012 456 89",
+ 1,
+ -9,
+ Alignment.Start,
+ true,
+ true,
+ false,
+ new [] { "0", "1", "2", " ", "4", "5", "6", " ", "8", "9" },
+ "01245689"
+ )]
+ [InlineData ("012 456 89", 5, -5, Alignment.Start, true, true, false, new [] { "012 ", "456 ", "89" })]
+ [InlineData ("012 456 89", 9, -1, Alignment.Start, true, true, false, new [] { "012 456 ", "89" })]
+
+ // no clip
+ [InlineData ("012 456 89", 10, 0, Alignment.Start, true, true, false, new [] { "012 456 89" })]
+ [InlineData ("012 456 89", 11, 1, Alignment.Start, true, true, false, new [] { "012 456 89" })]
+
+ // Odd # of spaces
+ // 01234567890123
+ [InlineData ("012 456 89 end", 13, -1, Alignment.Start, true, true, false, new [] { "012 456 89 ", "end" })]
+
+ // no clip
+ [InlineData ("012 456 89 end", 14, 0, Alignment.Start, true, true, false, new [] { "012 456 89 end" })]
+ [InlineData ("012 456 89 end", 15, 1, Alignment.Start, true, true, false, new [] { "012 456 89 end" })]
+ public void Reformat_Wrap_Spaces_No_NewLines (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ Alignment alignment,
+ bool wrap,
+ bool preserveTrailingSpaces,
+ bool stringEmpty,
+ IEnumerable resultLines,
+ string noSpaceText = ""
+ )
+ {
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ List list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
+ Assert.NotEmpty (list);
+ Assert.True (list.Count == resultLines.Count ());
+
+ if (stringEmpty)
+ {
+ Assert.Equal (string.Empty, list [0]);
+ }
+ else
+ {
+ Assert.NotEqual (string.Empty, list [0]);
+ }
+
+ Assert.Equal (resultLines, list);
+
+ if (maxWidth > 0)
+ {
+ // remove whitespace chars
+ if (maxWidth < 5)
+ {
+ expectedClippedWidth = text.GetRuneCount () - text.Sum (r => r == ' ' ? 1 : 0);
+ }
+ else
+ {
+ expectedClippedWidth = Math.Min (
+ text.GetRuneCount (),
+ maxWidth - text.Sum (r => r == ' ' ? 1 : 0)
+ );
+ }
+
+ list = TextFormatter.Format (text, maxWidth, Alignment.Start, wrap);
+
+ if (maxWidth == 1)
+ {
+ Assert.Equal (expectedClippedWidth, list.Count);
+ Assert.Equal (noSpaceText, string.Concat (list.ToArray ()));
+ }
+
+ if (maxWidth > 1 && maxWidth < 10)
+ {
+ Assert.Equal (
+ StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]),
+ list [0]
+ );
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData (null)]
+ [InlineData ("")]
+ [InlineData ("a")]
+ public void RemoveHotKeySpecifier_InValid_ReturnsOriginal (string text)
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ if (text == null)
+ {
+ Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier));
+ Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier));
+ Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier));
+ }
+ else
+ {
+ Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier));
+ Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier));
+ Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier));
+ }
+ }
+
+ [Theory]
+ [InlineData ("all lower case", 0)]
+ [InlineData ("K Before", 0)]
+ [InlineData ("aK Second", 1)]
+ [InlineData ("Last K", 5)]
+ [InlineData ("fter K", 7)]
+ [InlineData ("Multiple K and R", 9)]
+ [InlineData ("Non-english: Кдать", 13)]
+ public void RemoveHotKeySpecifier_Valid_Legacy_ReturnsOriginal (string text, int hotPos)
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier));
+ }
+
+ [Theory]
+ [InlineData ("_K Before", 0, "K Before")]
+ [InlineData ("a_K Second", 1, "aK Second")]
+ [InlineData ("Last _K", 5, "Last K")]
+ [InlineData ("After K_", 7, "After K")]
+ [InlineData ("Multiple _K and _R", 9, "Multiple K and _R")]
+ [InlineData ("Non-english: _Кдать", 13, "Non-english: Кдать")]
+ public void RemoveHotKeySpecifier_Valid_ReturnsStripped (string text, int hotPos, string expectedText)
+ {
+ var hotKeySpecifier = (Rune)'_';
+
+ Assert.Equal (expectedText, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier));
+ }
+
+ [Theory]
+ [InlineData ("test", 0, 't', "test")]
+ [InlineData ("test", 1, 'e', "test")]
+ [InlineData ("Ok", 0, 'O', "Ok")]
+ [InlineData ("[◦ Ok ◦]", 3, 'O', "[◦ Ok ◦]")]
+ [InlineData ("^k", 0, '^', "^k")]
+ public void ReplaceHotKeyWithTag (string text, int hotPos, uint tag, string expected)
+ {
+ var tf = new TextFormatter ();
+ List runes = text.ToRuneList ();
+ Rune rune;
+
+ if (Rune.TryGetRuneAt (text, hotPos, out rune))
+ {
+ Assert.Equal (rune, (Rune)tag);
+ }
+
+ string result = TextFormatter.ReplaceHotKeyWithTag (text, hotPos);
+ Assert.Equal (result, expected);
+ Assert.Equal ((Rune)tag, result.ToRunes () [hotPos]);
+ Assert.Equal (text.GetRuneCount (), runes.Count);
+ Assert.Equal (text, StringExtensions.ToString (runes));
+ }
+
+ public static IEnumerable SplitEnvironmentNewLine =>
+ new List
+ {
+ new object []
+ {
+ $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界",
+ new [] { "First Line 界", "Second Line 界", "Third Line 界" }
+ },
+ new object []
+ {
+ $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界{Environment.NewLine}",
+ new [] { "First Line 界", "Second Line 界", "Third Line 界", "" }
+ }
+ };
+
+ [Theory]
+ [MemberData (nameof (SplitEnvironmentNewLine))]
+ public void SplitNewLine_Ending__With_Or_Without_NewLine_Probably_CRLF (
+ string text,
+ IEnumerable expected
+ )
+ {
+ List splited = TextFormatter.SplitNewLine (text);
+ Assert.Equal (expected, splited);
+ }
+
+ [Theory]
+ [InlineData (
+ "First Line 界\nSecond Line 界\nThird Line 界\n",
+ new [] { "First Line 界", "Second Line 界", "Third Line 界", "" }
+ )]
+ public void SplitNewLine_Ending_With_NewLine_Only_LF (string text, IEnumerable expected)
+ {
+ List splited = TextFormatter.SplitNewLine (text);
+ Assert.Equal (expected, splited);
+ }
+
+ [Theory]
+ [InlineData (
+ "First Line 界\nSecond Line 界\nThird Line 界",
+ new [] { "First Line 界", "Second Line 界", "Third Line 界" }
+ )]
+ public void SplitNewLine_Ending_Without_NewLine_Only_LF (string text, IEnumerable expected)
+ {
+ List splited = TextFormatter.SplitNewLine (text);
+ Assert.Equal (expected, splited);
+ }
+
+ [Theory]
+ [InlineData ("New Test 你", 10, 10, 20320, 20320, 9, "你")]
+ [InlineData ("New Test \U0001d539", 10, 11, 120121, 55349, 9, "𝔹")]
+ public void String_Array_Is_Not_Always_Equal_ToRunes_Array (
+ string text,
+ int runesLength,
+ int stringLength,
+ int runeValue,
+ int stringValue,
+ int index,
+ string expected
+ )
+ {
+ Rune [] usToRunes = text.ToRunes ();
+ Assert.Equal (runesLength, usToRunes.Length);
+ Assert.Equal (stringLength, text.Length);
+ Assert.Equal (runeValue, usToRunes [index].Value);
+ Assert.Equal (stringValue, text [index]);
+ Assert.Equal (expected, usToRunes [index].ToString ());
+
+ if (char.IsHighSurrogate (text [index]))
+ {
+ // Rune array length isn't equal to string array
+ Assert.Equal (expected, new (new [] { text [index], text [index + 1] }));
+ }
+ else
+ {
+ // Rune array length is equal to string array
+ Assert.Equal (expected, text [index].ToString ());
+ }
+ }
+
+ [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")]
+ [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
+ [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
+ public void TabWith_PreserveTrailingSpaces_False (
+ int width,
+ int height,
+ TextDirection textDirection,
+ int tabWidth,
+ string expected
+ )
+ {
+ var driver = new FakeDriver ();
+ driver.Init ();
+
+ var text = "This is a \tTab";
+ var tf = new TextFormatter ();
+ tf.Direction = textDirection;
+ tf.TabWidth = tabWidth;
+ tf.Text = text;
+ tf.ConstrainToWidth = 20;
+ tf.ConstrainToHeight = 20;
+
+ Assert.True (tf.WordWrap);
+ Assert.False (tf.PreserveTrailingSpaces);
+
+ tf.Draw (
+ new (0, 0, width, height),
+ new (ColorName.White, ColorName.Black),
+ new (ColorName.Blue, ColorName.Black),
+ default (Rectangle),
+ driver
+ );
+ TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
+
+ 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")]
+ [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
+ [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
+ public void TabWith_PreserveTrailingSpaces_True (
+ int width,
+ int height,
+ TextDirection textDirection,
+ int tabWidth,
+ string expected
+ )
+ {
+ var driver = new FakeDriver ();
+ driver.Init ();
+
+ var text = "This is a \tTab";
+ var tf = new TextFormatter ();
+
+ tf.Direction = textDirection;
+ tf.TabWidth = tabWidth;
+ tf.PreserveTrailingSpaces = true;
+ tf.Text = text;
+ tf.ConstrainToWidth = 20;
+ tf.ConstrainToHeight = 20;
+
+ Assert.True (tf.WordWrap);
+
+ tf.Draw (
+ new (0, 0, width, height),
+ new (ColorName.White, ColorName.Black),
+ new (ColorName.Blue, ColorName.Black),
+ default (Rectangle),
+ driver
+ );
+ TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
+
+ 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")]
+ [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
+ [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
+ public void TabWith_WordWrap_True (
+ int width,
+ int height,
+ TextDirection textDirection,
+ int tabWidth,
+ string expected
+ )
+ {
+ var driver = new FakeDriver ();
+ driver.Init ();
+
+ var text = "This is a \tTab";
+ var tf = new TextFormatter ();
+
+ tf.Direction = textDirection;
+ tf.TabWidth = tabWidth;
+ tf.WordWrap = true;
+ tf.Text = text;
+ tf.ConstrainToWidth = 20;
+ tf.ConstrainToHeight = 20;
+
+ Assert.False (tf.PreserveTrailingSpaces);
+
+ tf.Draw (
+ new (0, 0, width, height),
+ new (ColorName.White, ColorName.Black),
+ new (ColorName.Blue, ColorName.Black),
+ default (Rectangle),
+ driver
+ );
+ TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
+
+ driver.End ();
+ }
+
+ [Theory]
+ [InlineData ("123456789", 3, "123")]
+ [InlineData ("Hello World", 8, "Hello Wo")]
+ public void TestClipOrPad_LongWord (string text, int fillPad, string expectedText)
+ {
+ // word is long but we want it to fill # space only
+ Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad));
+ }
+
+ [Theory]
+ [InlineData ("fff", 6, "fff ")]
+ [InlineData ("Hello World", 16, "Hello World ")]
+ public void TestClipOrPad_ShortWord (string text, int fillPad, string expectedText)
+ {
+ // word is short but we want it to fill # so it should be padded
+ Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad));
+ }
+
+ [Theory]
+ [InlineData ("你", TextDirection.LeftRight_TopBottom, 2, 1)]
+ [InlineData ("你", TextDirection.TopBottom_LeftRight, 2, 1)]
+ [InlineData ("你你", TextDirection.LeftRight_TopBottom, 4, 1)]
+ [InlineData ("你你", TextDirection.TopBottom_LeftRight, 2, 2)]
+ public void Text_Set_SizeIsCorrect (string text, TextDirection textDirection, int expectedWidth, int expectedHeight)
+ {
+ var tf = new TextFormatter { Direction = textDirection, Text = text };
+ tf.ConstrainToWidth = 10;
+ tf.ConstrainToHeight = 10;
+
+ Assert.Equal (new (expectedWidth, expectedHeight), tf.FormatAndGetSize ());
+ }
+
+ [Fact]
+ [SetupFakeDriver]
+ public void UICatalog_AboutBox_Text ()
+ {
+ TextFormatter tf = new ()
+ {
+ Text = UICatalogApp.GetAboutBoxMessage (),
+ Alignment = Alignment.Center,
+ VerticalAlignment = Alignment.Start,
+ WordWrap = false,
+ MultiLine = true,
+ HotKeySpecifier = (Rune)0xFFFF
+ };
+
+ Size tfSize = tf.FormatAndGetSize ();
+ Assert.Equal (new (58, 13), tfSize);
+
+ ((FakeDriver)Application.Driver).SetBufferSize (tfSize.Width, tfSize.Height);
+
+ Application.Driver.FillRect (Application.Screen, (Rune)'*');
+ tf.Draw (Application.Screen, Attribute.Default, Attribute.Default);
+
+ var expectedText = """
+ ******UI Catalog: A comprehensive sample library for******
+ **********************************************************
+ _______ _ _ _____ _
+ |__ __| (_) | | / ____| (_)
+ | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _
+ | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | |
+ | | __/ | | | | | | | | | | | (_| | || |__| | |_| | |
+ |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_|
+ **********************************************************
+ **********************v2 - Pre-Alpha**********************
+ **********************************************************
+ **********https://github.com/gui-cs/Terminal.Gui**********
+ **********************************************************
+ """;
+
+ TestHelpers.AssertDriverContentsAre (expectedText.ReplaceLineEndings (), _output);
+ }
+
+ [Fact]
+ public void WordWrap_BigWidth ()
+ {
+ List wrappedLines;
+
+ var text = "Constantinople";
+ wrappedLines = TextFormatter.WordWrapText (text, 100);
+ Assert.True (wrappedLines.Count == 1);
+ Assert.Equal ("Constantinople", wrappedLines [0]);
+ }
+
+ [Fact]
+ public void WordWrap_Invalid ()
+ {
+ var text = string.Empty;
+ var width = 0;
+
+ Assert.Empty (TextFormatter.WordWrapText (null, width));
+ Assert.Empty (TextFormatter.WordWrapText (text, width));
+ Assert.Throws (() => TextFormatter.WordWrapText (text, -1));
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words.", 3, -18, new [] { "A", "sen", "ten", "ce", "has", "wor", "ds." })]
+ [InlineData (
+ "A sentence has words.",
+ 2,
+ -19,
+ new [] { "A", "se", "nt", "en", "ce", "ha", "s", "wo", "rd", "s." }
+ )]
+ [InlineData (
+ "A sentence has words.",
+ 1,
+ -20,
+ new [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." }
+ )]
+ public void WordWrap_Narrow_Default (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words.", 21, 0, new [] { "A sentence has words." })]
+ [InlineData ("A sentence has words.", 20, -1, new [] { "A sentence has", "words." })]
+ [InlineData ("A sentence has words.", 15, -6, new [] { "A sentence has", "words." })]
+ [InlineData ("A sentence has words.", 14, -7, new [] { "A sentence has", "words." })]
+ [InlineData ("A sentence has words.", 13, -8, new [] { "A sentence", "has words." })]
+
+ // Unicode
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.",
+ 42,
+ 0,
+ new [] { "A Unicode sentence (пÑивеÑ) has words." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.",
+ 41,
+ -1,
+ new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.",
+ 36,
+ -6,
+ new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.",
+ 35,
+ -7,
+ new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.",
+ 34,
+ -8,
+ new [] { "A Unicode sentence (пÑивеÑ)", "has words." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.",
+ 25,
+ -17,
+ new [] { "A Unicode sentence", "(пÑивеÑ) has words." }
+ )]
+ public void WordWrap_NoNewLines_Default (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("これが最初の行です。 こんにちは世界。 これが2行目です。", 29, 0, new [] { "これが最初の行です。", "こんにちは世界。", "これが2行目です。" })]
+ public void WordWrap_PreserveTrailingSpaces_False_Unicode_Wide_Runes (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("文に は言葉 があり ます。", 14, 0, new [] { "文に は言葉", "があり ます。" })]
+ [InlineData ("文に は言葉 があり ます。", 3, -11, new [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })]
+ [InlineData ("文に は言葉 があり ます。", 2, -12, new [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })]
+ [InlineData (
+ "文に は言葉 があり ます。",
+ 1,
+ -13,
+ new [] { " ", " ", " " }
+ )] // Just Spaces; should result in a single space for each line
+ public void WordWrap_PreserveTrailingSpaces_False_Wide_Runes (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData (null, 1, new string [] { })] // null input
+ [InlineData ("", 1, new string [] { })] // Empty input
+ [InlineData ("1 34", 1, new [] { "1", "3", "4" })] // Single Spaces
+ [InlineData ("1", 1, new [] { "1" })] // Short input
+ [InlineData ("12", 1, new [] { "1", "2" })]
+ [InlineData ("123", 1, new [] { "1", "2", "3" })]
+ [InlineData ("123456", 1, new [] { "1", "2", "3", "4", "5", "6" })] // No spaces
+ [InlineData (" ", 1, new [] { " " })] // Just Spaces; should result in a single space
+ [InlineData (" ", 1, new [] { " " })]
+ [InlineData (" ", 1, new [] { " ", " " })]
+ [InlineData (" ", 1, new [] { " ", " " })]
+ [InlineData ("12 456", 1, new [] { "1", "2", "4", "5", "6" })] // Single Spaces
+ [InlineData (" 2 456", 1, new [] { " ", "2", "4", "5", "6" })] // Leading spaces should be preserved.
+ [InlineData (" 2 456 8", 1, new [] { " ", "2", "4", "5", "6", "8" })]
+ [InlineData (
+ "A sentence has words. ",
+ 1,
+ new [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." }
+ )] // Complex example
+ [InlineData ("12 567", 1, new [] { "1", "2", " ", "5", "6", "7" })] // Double Spaces
+ [InlineData (" 3 567", 1, new [] { " ", "3", "5", "6", "7" })] // Double Leading spaces should be preserved.
+ [InlineData (" 3 678 1", 1, new [] { " ", "3", " ", "6", "7", "8", " ", "1" })]
+ [InlineData ("1 456", 1, new [] { "1", " ", "4", "5", "6" })]
+ [InlineData (
+ "A sentence has words. ",
+ 1,
+ new []
+ {
+ "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", "w", "o", "r", "d", "s", ".", " "
+ }
+ )] // Double space Complex example
+ public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_1 (
+ string text,
+ int width,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines = TextFormatter.WordWrapText (text, width);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+ Assert.Equal (resultLines, wrappedLines);
+ var breakLines = "";
+
+ foreach (string line in wrappedLines)
+ {
+ breakLines += $"{line}{Environment.NewLine}";
+ }
+
+ var expected = string.Empty;
+
+ foreach (string line in resultLines)
+ {
+ expected += $"{line}{Environment.NewLine}";
+ }
+
+ Assert.Equal (expected, breakLines);
+ }
+
+ [Theory]
+ [InlineData (null, 3, new string [] { })] // null input
+ [InlineData ("", 3, new string [] { })] // Empty input
+ [InlineData ("1", 3, new [] { "1" })] // Short input
+ [InlineData ("12", 3, new [] { "12" })]
+ [InlineData ("123", 3, new [] { "123" })]
+ [InlineData ("123456", 3, new [] { "123", "456" })] // No spaces
+ [InlineData ("1234567", 3, new [] { "123", "456", "7" })] // No spaces
+ [InlineData (" ", 3, new [] { " " })] // Just Spaces; should result in a single space
+ [InlineData (" ", 3, new [] { " " })]
+ [InlineData (" ", 3, new [] { " " })]
+ [InlineData (" ", 3, new [] { " " })]
+ [InlineData ("12 456", 3, new [] { "12", "456" })] // Single Spaces
+ [InlineData (" 2 456", 3, new [] { " 2", "456" })] // Leading spaces should be preserved.
+ [InlineData (" 2 456 8", 3, new [] { " 2", "456", "8" })]
+ [InlineData (
+ "A sentence has words. ",
+ 3,
+ new [] { "A", "sen", "ten", "ce", "has", "wor", "ds." }
+ )] // Complex example
+ [InlineData ("12 567", 3, new [] { "12 ", "567" })] // Double Spaces
+ [InlineData (" 3 567", 3, new [] { " 3", "567" })] // Double Leading spaces should be preserved.
+ [InlineData (" 3 678 1", 3, new [] { " 3", " 67", "8 ", "1" })]
+ [InlineData ("1 456", 3, new [] { "1 ", "456" })]
+ [InlineData (
+ "A sentence has words. ",
+ 3,
+ new [] { "A ", "sen", "ten", "ce ", " ", "has", "wor", "ds.", " " }
+ )] // Double space Complex example
+ public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_3 (
+ string text,
+ int width,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines = TextFormatter.WordWrapText (text, width);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+ Assert.Equal (resultLines, wrappedLines);
+ var breakLines = "";
+
+ foreach (string line in wrappedLines)
+ {
+ breakLines += $"{line}{Environment.NewLine}";
+ }
+
+ var expected = string.Empty;
+
+ foreach (string line in resultLines)
+ {
+ expected += $"{line}{Environment.NewLine}";
+ }
+
+ Assert.Equal (expected, breakLines);
+ }
+
+ [Theory]
+ [InlineData (null, 50, new string [] { })] // null input
+ [InlineData ("", 50, new string [] { })] // Empty input
+ [InlineData ("1", 50, new [] { "1" })] // Short input
+ [InlineData ("12", 50, new [] { "12" })]
+ [InlineData ("123", 50, new [] { "123" })]
+ [InlineData ("123456", 50, new [] { "123456" })] // No spaces
+ [InlineData ("1234567", 50, new [] { "1234567" })] // No spaces
+ [InlineData (" ", 50, new [] { " " })] // Just Spaces; should result in a single space
+ [InlineData (" ", 50, new [] { " " })]
+ [InlineData (" ", 50, new [] { " " })]
+ [InlineData ("12 456", 50, new [] { "12 456" })] // Single Spaces
+ [InlineData (" 2 456", 50, new [] { " 2 456" })] // Leading spaces should be preserved.
+ [InlineData (" 2 456 8", 50, new [] { " 2 456 8" })]
+ [InlineData ("A sentence has words. ", 50, new [] { "A sentence has words. " })] // Complex example
+ [InlineData ("12 567", 50, new [] { "12 567" })] // Double Spaces
+ [InlineData (" 3 567", 50, new [] { " 3 567" })] // Double Leading spaces should be preserved.
+ [InlineData (" 3 678 1", 50, new [] { " 3 678 1" })]
+ [InlineData ("1 456", 50, new [] { "1 456" })]
+ [InlineData (
+ "A sentence has words. ",
+ 50,
+ new [] { "A sentence has words. " }
+ )] // Double space Complex example
+ public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_50 (
+ string text,
+ int width,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines = TextFormatter.WordWrapText (text, width);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+ Assert.Equal (resultLines, wrappedLines);
+ var breakLines = "";
+
+ foreach (string line in wrappedLines)
+ {
+ breakLines += $"{line}{Environment.NewLine}";
+ }
+
+ var expected = string.Empty;
+
+ foreach (string line in resultLines)
+ {
+ expected += $"{line}{Environment.NewLine}";
+ }
+
+ Assert.Equal (expected, breakLines);
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words.", 14, -7, new [] { "A sentence ", "has words." })]
+ [InlineData ("A sentence has words.", 8, -13, new [] { "A ", "sentence", " has ", "words." })]
+ [InlineData ("A sentence has words.", 6, -15, new [] { "A ", "senten", "ce ", "has ", "words." })]
+ [InlineData ("A sentence has words.", 3, -18, new [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds." })]
+ [InlineData (
+ "A sentence has words.",
+ 2,
+ -19,
+ new [] { "A ", "se", "nt", "en", "ce", " ", "ha", "s ", "wo", "rd", "s." }
+ )]
+ [InlineData (
+ "A sentence has words.",
+ 1,
+ -20,
+ new []
+ {
+ "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", " ", "w", "o", "r", "d", "s", "."
+ }
+ )]
+ public void WordWrap_PreserveTrailingSpaces_True (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("文に は言葉 があり ます。", 14, 0, new [] { "文に は言葉 ", "があり ます。" })]
+ [InlineData ("文に は言葉 があり ます。", 3, -11, new [] { "文", "に ", "は", "言", "葉 ", "が", "あ", "り ", "ま", "す", "。" })]
+ [InlineData (
+ "文に は言葉 があり ます。",
+ 2,
+ -12,
+ new [] { "文", "に", " ", "は", "言", "葉", " ", "が", "あ", "り", " ", "ま", "す", "。" }
+ )]
+ [InlineData ("文に は言葉 があり ます。", 1, -13, new string [] { })]
+ public void WordWrap_PreserveTrailingSpaces_True_Wide_Runes (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("A sentence has words. ", 3, new [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds.", " " })]
+ [InlineData (
+ "A sentence has words. ",
+ 3,
+ new [] { "A ", " ", "sen", "ten", "ce ", " ", " ", " ", "has", " ", "wor", "ds.", " " }
+ )]
+ public void WordWrap_PreserveTrailingSpaces_True_With_Simple_Runes_Width_3 (
+ string text,
+ int width,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines = TextFormatter.WordWrapText (text, width, true);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+ Assert.Equal (resultLines, wrappedLines);
+ var breakLines = "";
+
+ foreach (string line in wrappedLines)
+ {
+ breakLines += $"{line}{Environment.NewLine}";
+ }
+
+ var expected = string.Empty;
+
+ foreach (string line in resultLines)
+ {
+ expected += $"{line}{Environment.NewLine}";
+ }
+
+ Assert.Equal (expected, breakLines);
+
+ // Double space Complex example - this is how VS 2022 does it
+ //text = "A sentence has words. ";
+ //breakLines = "";
+ //wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: true);
+ //foreach (var line in wrappedLines) {
+ // breakLines += $"{line}{Environment.NewLine}";
+ //}
+ //expected = "A " + Environment.NewLine +
+ // " se" + Environment.NewLine +
+ // " nt" + Environment.NewLine +
+ // " en" + Environment.NewLine +
+ // " ce" + Environment.NewLine +
+ // " " + Environment.NewLine +
+ // " " + Environment.NewLine +
+ // " " + Environment.NewLine +
+ // " ha" + Environment.NewLine +
+ // " s " + Environment.NewLine +
+ // " wo" + Environment.NewLine +
+ // " rd" + Environment.NewLine +
+ // " s." + Environment.NewLine;
+ //Assert.Equal (expected, breakLines);
+ }
+
+ [Theory]
+ [InlineData ("A sentence\t\t\t has words.", 14, -10, new [] { "A sentence\t", "\t\t has ", "words." })]
+ [InlineData (
+ "A sentence\t\t\t has words.",
+ 8,
+ -16,
+ new [] { "A ", "sentence", "\t\t", "\t ", "has ", "words." }
+ )]
+ [InlineData (
+ "A sentence\t\t\t has words.",
+ 3,
+ -21,
+ new [] { "A ", "sen", "ten", "ce", "\t", "\t", "\t", " ", "has", " ", "wor", "ds." }
+ )]
+ [InlineData (
+ "A sentence\t\t\t has words.",
+ 2,
+ -22,
+ new [] { "A ", "se", "nt", "en", "ce", "\t", "\t", "\t", " ", "ha", "s ", "wo", "rd", "s." }
+ )]
+ [InlineData (
+ "A sentence\t\t\t has words.",
+ 1,
+ -23,
+ new []
+ {
+ "A",
+ " ",
+ "s",
+ "e",
+ "n",
+ "t",
+ "e",
+ "n",
+ "c",
+ "e",
+ "\t",
+ "\t",
+ "\t",
+ " ",
+ "h",
+ "a",
+ "s",
+ " ",
+ "w",
+ "o",
+ "r",
+ "d",
+ "s",
+ "."
+ }
+ )]
+ public void WordWrap_PreserveTrailingSpaces_True_With_Tab (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines,
+ int tabWidth = 4
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("Constantinople", 14, 0, new [] { "Constantinople" })]
+ [InlineData ("Constantinople", 12, -2, new [] { "Constantinop", "le" })]
+ [InlineData ("Constantinople", 9, -5, new [] { "Constanti", "nople" })]
+ [InlineData ("Constantinople", 7, -7, new [] { "Constan", "tinople" })]
+ [InlineData ("Constantinople", 5, -9, new [] { "Const", "antin", "ople" })]
+ [InlineData ("Constantinople", 4, -10, new [] { "Cons", "tant", "inop", "le" })]
+ [InlineData (
+ "Constantinople",
+ 1,
+ -13,
+ new [] { "C", "o", "n", "s", "t", "a", "n", "t", "i", "n", "o", "p", "l", "e" }
+ )]
+ public void WordWrap_SingleWordLine (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 20, 0, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
+ [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 19, -1, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
+ [InlineData (
+ "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence.",
+ 19,
+ 0,
+ new [] { "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence." }
+ )]
+ public void WordWrap_Unicode_2LinesWithNonBreakingSpace (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 19, 0, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
+ [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 18, -1, new [] { "This\u00A0is\u00A0a\u00A0sentence", "." })]
+ [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 17, -2, new [] { "This\u00A0is\u00A0a\u00A0sentenc", "e." })]
+ [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 14, -5, new [] { "This\u00A0is\u00A0a\u00A0sent", "ence." })]
+ [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 10, -9, new [] { "This\u00A0is\u00A0a\u00A0", "sentence." })]
+ [InlineData (
+ "This\u00A0is\u00A0a\u00A0sentence.",
+ 7,
+ -12,
+ new [] { "This\u00A0is", "\u00A0a\u00A0sent", "ence." }
+ )]
+ [InlineData (
+ "This\u00A0is\u00A0a\u00A0sentence.",
+ 5,
+ -14,
+ new [] { "This\u00A0", "is\u00A0a\u00A0", "sente", "nce." }
+ )]
+ [InlineData (
+ "This\u00A0is\u00A0a\u00A0sentence.",
+ 1,
+ -18,
+ new []
+ {
+ "T", "h", "i", "s", "\u00A0", "i", "s", "\u00A0", "a", "\u00A0", "s", "e", "n", "t", "e", "n", "c", "e", "."
+ }
+ )]
+ public void WordWrap_Unicode_LineWithNonBreakingSpace (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ [Theory]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 51,
+ 0,
+ new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
+ )]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 50,
+ -1,
+ new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
+ )]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 46,
+ -5,
+ new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ", "ฯะัาำ" }
+ )]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 26,
+ -25,
+ new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
+ )]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 17,
+ -34,
+ new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑ", "ฒณดตถทธนบปผฝพฟภมย", "รฤลฦวศษสหฬอฮฯะัาำ" }
+ )]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 13,
+ -38,
+ new [] { "กขฃคฅฆงจฉชซฌญ", "ฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦว", "ศษสหฬอฮฯะัาำ" }
+ )]
+ [InlineData (
+ "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
+ 1,
+ -50,
+ new []
+ {
+ "ก",
+ "ข",
+ "ฃ",
+ "ค",
+ "ฅ",
+ "ฆ",
+ "ง",
+ "จ",
+ "ฉ",
+ "ช",
+ "ซ",
+ "ฌ",
+ "ญ",
+ "ฎ",
+ "ฏ",
+ "ฐ",
+ "ฑ",
+ "ฒ",
+ "ณ",
+ "ด",
+ "ต",
+ "ถ",
+ "ท",
+ "ธ",
+ "น",
+ "บ",
+ "ป",
+ "ผ",
+ "ฝ",
+ "พ",
+ "ฟ",
+ "ภ",
+ "ม",
+ "ย",
+ "ร",
+ "ฤ",
+ "ล",
+ "ฦ",
+ "ว",
+ "ศ",
+ "ษ",
+ "ส",
+ "ห",
+ "ฬ",
+ "อ",
+ "ฮ",
+ "ฯ",
+ "ะั",
+ "า",
+ "ำ"
+ }
+ )]
+ public void WordWrap_Unicode_SingleWordLine (
+ string text,
+ int maxWidth,
+ int widthOffset,
+ IEnumerable resultLines
+ )
+ {
+ List wrappedLines;
+
+ IEnumerable zeroWidth = text.EnumerateRunes ().Where (r => r.GetColumns () == 0);
+ Assert.Single (zeroWidth);
+ Assert.Equal ('ั', zeroWidth.ElementAt (0).Value);
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth
+ >= (wrappedLines.Count > 0
+ ? wrappedLines.Max (
+ l => l.GetRuneCount ()
+ + zeroWidth.Count ()
+ - 1
+ + widthOffset
+ )
+ : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
+ /// WordWrap strips CRLF
+ [Theory]
+ [InlineData (
+ "A sentence has words.\nA paragraph has lines.",
+ 44,
+ 0,
+ new [] { "A sentence has words.A paragraph has lines." }
+ )]
+ [InlineData (
+ "A sentence has words.\nA paragraph has lines.",
+ 43,
+ -1,
+ new [] { "A sentence has words.A paragraph has lines." }
+ )]
+ [InlineData (
+ "A sentence has words.\nA paragraph has lines.",
+ 38,
+ -6,
+ new [] { "A sentence has words.A paragraph has", "lines." }
+ )]
+ [InlineData (
+ "A sentence has words.\nA paragraph has lines.",
+ 34,
+ -10,
+ new [] { "A sentence has words.A paragraph", "has lines." }
+ )]
+ [InlineData (
+ "A sentence has words.\nA paragraph has lines.",
+ 27,
+ -17,
+ new [] { "A sentence has words.A", "paragraph has lines." }
+ )]
+
+ // Unicode
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
+ 69,
+ 0,
+ new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
+ 68,
+ -1,
+ new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
+ 63,
+ -6,
+ new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has", "Линии." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
+ 59,
+ -10,
+ new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт", "has Линии." }
+ )]
+ [InlineData (
+ "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
+ 52,
+ -17,
+ new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode", "Пункт has Линии." }
+ )]
+ public void WordWrap_WithNewLines (string text, int maxWidth, int widthOffset, IEnumerable resultLines)
+ {
+ List wrappedLines;
+
+ Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
+ int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
+ wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
+ Assert.Equal (wrappedLines.Count, resultLines.Count ());
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
+ );
+
+ Assert.True (
+ expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
+ );
+ Assert.Equal (resultLines, wrappedLines);
+ }
+
#region FormatAndGetSizeTests
// TODO: Add multi-line examples
@@ -7193,46 +7218,4 @@ B ")]
}
#endregion
-
- [Fact]
- [SetupFakeDriver]
- public void UICatalog_AboutBox_Text ()
- {
- TextFormatter tf = new ()
- {
- Text = UICatalog.UICatalogApp.GetAboutBoxMessage (),
- Alignment = Alignment.Center,
- VerticalAlignment = Alignment.Start,
- WordWrap = false,
- MultiLine = true,
- HotKeySpecifier = (Rune)0xFFFF
- };
-
- Size tfSize = tf.FormatAndGetSize ();
- Assert.Equal (new Size (58, 13), tfSize);
-
- ((FakeDriver)Application.Driver).SetBufferSize (tfSize.Width, tfSize.Height);
-
- Application.Driver.FillRect (Application.Screen, (Rune)'*');
- tf.Draw (Application.Screen, Attribute.Default, Attribute.Default);
-
- string expectedText = """
- ******UI Catalog: A comprehensive sample library for******
- **********************************************************
- _______ _ _ _____ _
- |__ __| (_) | | / ____| (_)
- | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _
- | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | |
- | | __/ | | | | | | | | | | | (_| | || |__| | |_| | |
- |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_|
- **********************************************************
- **********************v2 - Pre-Alpha**********************
- **********************************************************
- **********https://github.com/gui-cs/Terminal.Gui**********
- **********************************************************
- """;
-
- TestHelpers.AssertDriverContentsAre (expectedText.ReplaceLineEndings (), _output);
-
- }
}
diff --git a/UnitTests/View/TitleTests.cs b/UnitTests/View/TitleTests.cs
index 0c2a6a5b7..c808e66e4 100644
--- a/UnitTests/View/TitleTests.cs
+++ b/UnitTests/View/TitleTests.cs
@@ -3,7 +3,7 @@ using Xunit.Abstractions;
namespace Terminal.Gui.ViewTests;
-public class TitleTests (ITestOutputHelper output)
+public class TitleTests
{
// Unit tests that verify look & feel of title are in BorderTests.cs
diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs
index 049c5f7e1..6d2e5decc 100644
--- a/UnitTests/Views/ListViewTests.cs
+++ b/UnitTests/Views/ListViewTests.cs
@@ -674,8 +674,10 @@ Item 6",
private class NewListDataSource : IListDataSource
{
+#pragma warning disable CS0067
///
public event NotifyCollectionChangedEventHandler CollectionChanged;
+#pragma warning restore CS0067
public int Count => 0;
public int Length => 0;
diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs
index ac8de4db0..9b1067290 100644
--- a/UnitTests/Views/MenuBarTests.cs
+++ b/UnitTests/Views/MenuBarTests.cs
@@ -3800,7 +3800,7 @@ Edit
menuItem.RemoveMenuItem ();
Assert.Single (menuBar.Menus);
- Assert.Equal (null, menuBar.Menus [0].Children);
+ Assert.Null (menuBar.Menus [0].Children);
Assert.Contains (Key.N.WithAlt, menuBar.KeyBindings.Bindings);
Assert.DoesNotContain (Key.I, menuBar.KeyBindings.Bindings);
diff --git a/UnitTests/Views/NumericUpDownTests.cs b/UnitTests/Views/NumericUpDownTests.cs
index 9743de019..571a9fab4 100644
--- a/UnitTests/Views/NumericUpDownTests.cs
+++ b/UnitTests/Views/NumericUpDownTests.cs
@@ -3,7 +3,7 @@ using Xunit.Abstractions;
namespace Terminal.Gui.ViewsTests;
-public class NumericUpDownTests (ITestOutputHelper _output)
+public class NumericUpDownTests
{
[Fact]
public void WhenCreated_ShouldHaveDefaultValues_int ()
diff --git a/UnitTests/Views/StatusBarTests.cs b/UnitTests/Views/StatusBarTests.cs
index 6f6f93061..14866a154 100644
--- a/UnitTests/Views/StatusBarTests.cs
+++ b/UnitTests/Views/StatusBarTests.cs
@@ -1,7 +1,7 @@
using Xunit.Abstractions;
namespace Terminal.Gui.ViewsTests;
-public class StatusBarTests (ITestOutputHelper output)
+public class StatusBarTests
{
[Fact]
public void AddItemAt_RemoveItem_Replacing ()
diff --git a/UnitTests/Views/TableViewTests.cs b/UnitTests/Views/TableViewTests.cs
index 2a3397491..61deab69c 100644
--- a/UnitTests/Views/TableViewTests.cs
+++ b/UnitTests/Views/TableViewTests.cs
@@ -2582,7 +2582,9 @@ A B C
TestHelpers.AssertDriverContentsAre (expected, output);
+#pragma warning disable xUnit2029
Assert.Empty (pets.Where (p => p.IsPicked));
+#pragma warning restore xUnit2029
tv.NewKeyDownEvent (Key.Space);
@@ -2795,7 +2797,9 @@ A B C
tv.NewKeyDownEvent (Key.Space);
+#pragma warning disable xUnit2029
Assert.Empty (pets.Where (p => p.IsPicked));
+#pragma warning restore xUnit2029
tv.Draw ();
@@ -2924,7 +2928,9 @@ A B C
TestHelpers.AssertDriverContentsAre (expected, output);
+#pragma warning disable xUnit2029
Assert.Empty (pets.Where (p => p.IsPicked));
+#pragma warning restore xUnit2029
tv.NewKeyDownEvent (Key.Space);
@@ -3089,7 +3095,9 @@ A B C
// Can untoggle at 1,0 even though 0,0 was initial toggle because FullRowSelect is on
tableView.NewKeyDownEvent (new() { KeyCode = KeyCode.Space });
+#pragma warning disable xUnit2029
Assert.Empty (tableView.MultiSelectedRegions.Where (r => r.IsToggled));
+#pragma warning restore xUnit2029
}
[Fact]