Files
Terminal.Gui/Tests/UnitTestsParallelizable/Drivers/FakeDriverTests.cs
BDisp cd75a20c60 Fixes #4387. Runes should not be used on a cell, but rather should use a single grapheme rendering 1 or 2 columns (#4388)
* Fixes #4382. StringExtensions.GetColumns method should only return the total text width and not the sum of all runes width

* Trying to fix unit test error

* Update StringExtensions.cs

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

* Resolving merge conflicts

* Prevents Runes throwing if Grapheme is null

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

* Fix unit test failure

* Fix IsValidLocation for wide graphemes

* Add more combining

* Prevent set invalid graphemes

* Fix unit tests

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

* Fixes more unit tests

* Fix unit test

* Seems all test are fixed now

* Adjust CharMap scenario with graphemes

* Upgrade Wcwidth to version 4.0.0

* Reformat

* Trying fix CheckDefaultState assertion

* Revert "Trying fix CheckDefaultState assertion"

This reverts commit c9b46b796a.

* Forgot to include driver.End in the test

* Reapply "Trying fix CheckDefaultState assertion"

This reverts commit 1060ac9b63.

* Remove ToString

* Fix merge errors

* Change to conditional expression

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

* Remove unnecessary assignment

* Remove assignment to end

* Replace string concatenation with 'StringBuilder'.

* Replace more string concatenation with 'StringBuilder'

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

* Replace foreach loop with Sum linq

---------

Co-authored-by: Tig <tig@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-20 13:45:13 -05:00

287 lines
7.6 KiB
C#

using System.Text;
using UnitTests;
using Xunit.Abstractions;
namespace UnitTests_Parallelizable.DriverTests;
/// <summary>
/// Tests for the FakeDriver to ensure it works properly with the modern component factory architecture.
/// </summary>
public class FakeDriverTests (ITestOutputHelper output) : FakeDriverBase
{
private readonly ITestOutputHelper _output = output;
#region Basic FakeDriver Tests
[Fact]
public void FakeDriver_Init_Works ()
{
IDriver driver = CreateFakeDriver ();
Assert.IsAssignableFrom<IDriver> (driver);
_output.WriteLine ($"Driver type: {driver.GetType ().Name}");
_output.WriteLine ($"Screen size: {driver.Screen}");
}
[Fact]
public void FakeDriver_Screen_Has_Default_Size ()
{
IDriver driver = CreateFakeDriver ();
// Default size should be 80x25
Assert.Equal (new (0, 0, 80, 25), driver.Screen);
Assert.Equal (80, driver.Cols);
Assert.Equal (25, driver.Rows);
}
[Fact]
public void FakeDriver_Can_Resize ()
{
IDriver driver = CreateFakeDriver ();
// Start with default size
Assert.Equal (80, driver.Cols);
Assert.Equal (25, driver.Rows);
// Resize to 100x30
driver?.SetScreenSize (100, 30);
// Verify new size
Assert.Equal (100, driver.Cols);
Assert.Equal (30, driver.Rows);
Assert.Equal (new (0, 0, 100, 30), driver.Screen);
}
#endregion
#region CreateFakeDriver Tests
[Fact]
public void SetupFakeDriver_Initializes_Driver_With_80x25 ()
{
IDriver driver = CreateFakeDriver ();
Assert.NotNull (driver);
Assert.Equal (new (0, 0, 80, 25), driver.Screen);
Assert.Equal (80, driver.Cols);
Assert.Equal (25, driver.Rows);
}
[Fact]
public void SetupFakeDriver_Driver_Is_IDriver ()
{
IDriver driver = CreateFakeDriver ();
Assert.NotNull (driver);
// Should be IDriver
Assert.IsAssignableFrom<IDriver> (driver);
_output.WriteLine ($"Driver type: {driver.GetType ().Name}");
}
[Fact]
public void SetupFakeDriver_Can_Set_Screen_Size ()
{
IDriver driver = CreateFakeDriver ();
IDriver fakeDriver = driver;
Assert.NotNull (fakeDriver);
fakeDriver!.SetScreenSize (100, 50);
Assert.Equal (100, driver.Cols);
Assert.Equal (50, driver.Rows);
}
#endregion
#region Clipboard Tests
[Fact]
public void FakeDriver_Clipboard_Works_When_Enabled ()
{
IDriver driver = CreateFakeDriver ();
Assert.NotNull (driver.Clipboard);
Assert.True (driver.Clipboard.IsSupported);
// Set clipboard content
driver.Clipboard.SetClipboardData ("Test content");
// Get clipboard content
string content = driver.Clipboard.GetClipboardData ();
Assert.Equal ("Test content", content);
}
[Fact]
public void FakeDriver_Clipboard_GetClipboarData_Works ()
{
IDriver driver = CreateFakeDriver ();
Assert.NotNull (driver.Clipboard);
driver.Clipboard.SetClipboardData ("test");
Assert.Equal ("test", driver.Clipboard.GetClipboardData ());
}
#endregion
#region Buffer and Fill Tests
[Fact]
public void FakeDriver_Can_Fill_Rectangle ()
{
IDriver driver = CreateFakeDriver ();
// Verify driver is initialized with buffers
Assert.NotNull (driver);
Assert.NotNull (driver.Contents);
// Fill a rectangle
var rect = new Rectangle (5, 5, 10, 5);
driver.FillRect (rect, (Rune)'X');
// Verify the rectangle was filled
for (int row = rect.Y; row < rect.Y + rect.Height; row++)
{
for (int col = rect.X; col < rect.X + rect.Width; col++)
{
Assert.Equal ("X", driver.Contents [row, col].Grapheme);
}
}
}
[Fact]
public void FakeDriver_Buffer_Integrity_After_Multiple_Resizes ()
{
IDriver driver = CreateFakeDriver ();
// Start with default size
Assert.Equal (80, driver.Cols);
Assert.Equal (25, driver.Rows);
// Fill with a pattern
driver.FillRect (new (0, 0, 10, 5), (Rune)'A');
// Resize
driver?.SetScreenSize (100, 30);
// Verify new size
Assert.Equal (100, driver.Cols);
Assert.Equal (30, driver.Rows);
// Verify buffer is clean (no stale runes from previous size)
Assert.NotNull (driver.Contents);
Assert.Equal (30, driver.Contents!.GetLength (0));
Assert.Equal (100, driver.Contents.GetLength (1));
// Fill with new pattern
driver.FillRect (new (0, 0, 20, 10), (Rune)'B');
// Resize back
driver?.SetScreenSize (80, 25);
// Verify size is back
Assert.Equal (80, driver.Cols);
Assert.Equal (25, driver.Rows);
// Verify buffer dimensions match
Assert.Equal (25, driver.Contents.GetLength (0));
Assert.Equal (80, driver.Contents.GetLength (1));
}
#endregion
#region ScreenChanged Event Tests
[Fact]
public void ScreenChanged_Event_Fires_On_SetScreenSize ()
{
IDriver driver = CreateFakeDriver ();
var screenChangedFired = false;
Size? newSize = null;
driver.SizeChanged += (sender, args) =>
{
screenChangedFired = true;
newSize = args.Size;
};
// Trigger resize using FakeResize which uses SetScreenSize internally
driver?.SetScreenSize (100, 30);
// Verify event fired
Assert.True (screenChangedFired);
Assert.NotNull (newSize);
Assert.Equal (100, newSize!.Value.Width);
Assert.Equal (30, newSize.Value.Height);
}
[Fact]
public void FakeResize_Triggers_ScreenChanged_And_Updates_Application_Screen ()
{
IDriver driver = CreateFakeDriver ();
var screenChangedFired = false;
Size? eventSize = null;
driver.SizeChanged += (sender, args) =>
{
screenChangedFired = true;
eventSize = args.Size;
};
// Use FakeResize helper
driver?.SetScreenSize (120, 40);
// Verify event fired
Assert.True (screenChangedFired);
Assert.NotNull (eventSize);
Assert.Equal (120, eventSize!.Value.Width);
Assert.Equal (40, eventSize.Value.Height);
// Verify driver.Screen was updated
Assert.Equal (new (0, 0, 120, 40), driver.Screen);
Assert.Equal (120, driver.Cols);
Assert.Equal (40, driver.Rows);
}
[Fact]
public void SizeChanged_Event_Still_Fires_For_Compatibility ()
{
IDriver driver = CreateFakeDriver ();
var sizeChangedFired = false;
var screenChangedFired = false;
#pragma warning disable CS0618 // Type or member is obsolete
driver.SizeChanged += (sender, args) => { sizeChangedFired = true; };
#pragma warning restore CS0618 // Type or member is obsolete
driver.SizeChanged += (sender, args) => { screenChangedFired = true; };
// Trigger resize using FakeResize
driver?.SetScreenSize (90, 35);
// Both events should fire for compatibility
Assert.True (sizeChangedFired);
Assert.True (screenChangedFired);
}
#endregion
}