mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 07:47:54 +01:00
* Add comprehensive unit tests for WindowsKeyConverter - Implement 118 parallelizable unit tests for WindowsKeyConverter - Cover ToKey and ToKeyInfo methods with full bidirectional testing - Test basic characters, modifiers, special keys, function keys - Test VK_PACKET Unicode/IME input - Test OEM keys, NumPad keys, and lock states - Include round-trip conversion tests - All tests passing successfully Fixes #4389 * Add test documenting VK_PACKET surrogate pair limitation VK_PACKET sends surrogate pairs (e.g., emoji) as two separate events. Current WindowsKeyConverter processes each independently without combining. Test documents this limitation for future fix at InputProcessor level. * Mark WindowsKeyConverterTests as Windows-only Tests now skip on non-Windows platforms using SkipException in constructor. This prevents CI failures on macOS and Linux where Windows Console API is not available. * Properly mark WindowsKeyConverter tests as Windows-only Created custom xUnit attributes SkipOnNonWindowsFact and SkipOnNonWindowsTheory that automatically skip tests on non-Windows platforms. This prevents CI failures on macOS and Linux. * Refactor and enhance test coverage for input processors Refactored `ApplicationImpl.cs` to simplify its structure by removing the `_stopAfterFirstIteration` field. Reintroduced and modernized test files with improved structure and coverage: - `NetInputProcessorTests.cs`: Added tests for `ConsoleKeyInfo` to `Rune`/`Key` conversion and queue processing. - `WindowSizeMonitorTests.cs`: Added tests for size change event handling. - `WindowsInputProcessorTests.cs`: Added tests for keyboard and mouse input processing, including mouse flag mapping. - `WindowsKeyConverterTests.cs`: Added comprehensive tests for `InputRecord` to `Key` conversion, covering OEM keys, modifiers, Unicode, and round-trip integrity. Improved test coverage for edge cases, introduced parameterized tests, and documented known limitations for future improvements. * Use Trait-based platform filtering for WindowsKeyConverter tests Added [Trait('Platform', 'Windows')] and [Collection('Global Test Setup')] attributes. Tests will run on Windows but can be filtered in CI on other platforms using --filter 'Platform!=Windows' if needed. This approach doesn't interfere with GlobalTestSetup and works correctly with xUnit. * Filter Windows-specific tests on non-Windows CI platforms Added --filter 'Platform!=Windows' for Linux and macOS runners to exclude WindowsKeyConverterTests which require Windows Console APIs. Windows runner runs all tests normally. * Fix log path typo and remove Codecov upload step Corrected a typo in the log directory path from `logs/UnitTestsParallelable/` to `logs/UnitTestsParallelizable/`. Removed the "Upload Parallelizable UnitTests Coverage to Codecov" step, which was conditional on `matrix.os == 'ubuntu-latest'` and used the `codecov/codecov-action@v4` action. This change improves log handling and removes the Codecov integration. * Refactor application reset logic Replaced `Application.ResetState(true)` with a more explicit reset mechanism. Introduced `ApplicationImpl.SetInstance(null)` to clear the application instance and added `CM.Disable(true)` to disable specific components. This change improves control over the reset process and ensures a more granular approach to application state management. * Improve null safety with ?. and ! operators Enhanced null safety across the codebase by introducing the null-conditional operator (`?.`) and null-forgiving operator (`!`) where appropriate. - Updated `app` and `driver` method calls to use `?.` to prevent potential `NullReferenceException` errors. - Added `!` to assert non-nullability in cases like `e.Value!.ToString()` and `app.Driver?.Contents!`. - Modified `lv.SelectedItemChanged` event handler to ensure safe handling of nullable values. - Updated `app.Shutdown()`, `app.LayoutAndDraw()`, and mouse event handling to use `?.`. - Ensured `driver.SetScreenSize` is invoked only when `driver` is not null. - Improved string concatenation logic with null-forgiving operator for `Contents`. - General improvements to null safety to make the code more robust and resilient to null references. * Improve Unicode tests and clarify surrogate pair handling Updated `WindowsKeyConverterTests` to enhance readability, improve test data, and clarify comments. Key changes include: - Reformatted `[Collection]` and `[Trait]` attributes for consistency. - Replaced placeholder Unicode characters with meaningful examples: - Chinese: `中`, Japanese: `日`, Korean: `한`, Accented: `é`, Euro: `€`, Greek: `Ω`. - Updated comments to replace placeholder emojis (`??`) with `😀` (U+1F600) for clarity. - Adjusted surrogate pair test data to accurately reflect `😀`. - Improved documentation of current limitations and future fixes for surrogate pair handling. These changes ensure more accurate and meaningful test cases while improving code clarity. * Ensure platform-specific test execution on Windows Added `System.Runtime.InteropServices` and `Xunit.Sdk` namespaces to `WindowsKeyConverterTests.cs` to support platform checks and test setup. Marked the test class with `[Collection("Global Test Setup")]` to enable shared test setup. Updated the `ToKey_NumPadKeys_ReturnsExpectedKeyCode` method to include a platform check, ensuring the test only runs on Windows platforms. * Integrate TrueColor support into ColorPicker Merged TrueColors functionality into ColorPicker, enhancing the scenario with TrueColor demonstration and gradient features. Updated `ColorPicker.cs` to include driver information, TrueColor support indicators, and a toggle for `Force16Colors`. Removed `TrueColors.cs` as its functionality is now consolidated. Refined `ColorBar` to use dynamic height with `Dim.Auto` for better flexibility. Added documentation to `HueBar` to clarify its role in representing the Hue component in HSL color space. * Revert workflow change. * Reverted attribute that didn't actualy work.
This commit is contained in:
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace UICatalog.Scenarios;
|
||||
|
||||
[ScenarioMetadata ("ColorPicker", "Color Picker.")]
|
||||
[ScenarioMetadata ("ColorPicker", "Color Picker and TrueColor demonstration.")]
|
||||
[ScenarioCategory ("Colors")]
|
||||
[ScenarioCategory ("Controls")]
|
||||
public class ColorPickers : Scenario
|
||||
@@ -220,6 +220,33 @@ public class ColorPickers : Scenario
|
||||
};
|
||||
app.Add (cbShowName);
|
||||
|
||||
var lblDriverName = new Label
|
||||
{
|
||||
Y = Pos.Bottom (cbShowName) + 1, Text = $"Driver is `{Application.Driver?.GetName ()}`:"
|
||||
};
|
||||
bool canTrueColor = Application.Driver?.SupportsTrueColor ?? false;
|
||||
|
||||
var cbSupportsTrueColor = new CheckBox
|
||||
{
|
||||
X = Pos.Right (lblDriverName) + 1,
|
||||
Y = Pos.Top (lblDriverName),
|
||||
CheckedState = canTrueColor ? CheckState.Checked : CheckState.UnChecked,
|
||||
CanFocus = false,
|
||||
Enabled = false,
|
||||
Text = "SupportsTrueColor"
|
||||
};
|
||||
app.Add (cbSupportsTrueColor);
|
||||
|
||||
var cbUseTrueColor = new CheckBox
|
||||
{
|
||||
X = Pos.Right (cbSupportsTrueColor) + 1,
|
||||
Y = Pos.Top (lblDriverName),
|
||||
CheckedState = Application.Force16Colors ? CheckState.Checked : CheckState.UnChecked,
|
||||
Enabled = canTrueColor,
|
||||
Text = "Force16Colors"
|
||||
};
|
||||
cbUseTrueColor.CheckedStateChanging += (_, evt) => { Application.Force16Colors = evt.Result == CheckState.Checked; };
|
||||
app.Add (lblDriverName, cbSupportsTrueColor, cbUseTrueColor);
|
||||
// Set default colors.
|
||||
foregroundColorPicker.SelectedColor = _demoView.SuperView!.GetAttributeForRole (VisualRole.Normal).Foreground.GetClosestNamedColor16 ();
|
||||
backgroundColorPicker.SelectedColor = _demoView.SuperView.GetAttributeForRole (VisualRole.Normal).Background.GetClosestNamedColor16 ();
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace UICatalog.Scenarios;
|
||||
|
||||
[ScenarioMetadata ("True Colors", "Demonstration of true color support.")]
|
||||
[ScenarioCategory ("Colors")]
|
||||
public class TrueColors : Scenario
|
||||
{
|
||||
public override void Main ()
|
||||
{
|
||||
Application.Init ();
|
||||
|
||||
Window app = new ()
|
||||
{
|
||||
Title = GetQuitKeyAndName ()
|
||||
};
|
||||
|
||||
var x = 2;
|
||||
var y = 1;
|
||||
|
||||
bool canTrueColor = Application.Driver?.SupportsTrueColor ?? false;
|
||||
|
||||
var lblDriverName = new Label
|
||||
{
|
||||
X = x, Y = y++, Text = $"Current driver is {Application.Driver?.GetType ().Name}"
|
||||
};
|
||||
app.Add (lblDriverName);
|
||||
y++;
|
||||
|
||||
var cbSupportsTrueColor = new CheckBox
|
||||
{
|
||||
X = x,
|
||||
Y = y++,
|
||||
CheckedState = canTrueColor ? CheckState.Checked : CheckState.UnChecked,
|
||||
CanFocus = false,
|
||||
Enabled = false,
|
||||
Text = "Driver supports true color "
|
||||
};
|
||||
app.Add (cbSupportsTrueColor);
|
||||
|
||||
var cbUseTrueColor = new CheckBox
|
||||
{
|
||||
X = x,
|
||||
Y = y++,
|
||||
CheckedState = Application.Force16Colors ? CheckState.Checked : CheckState.UnChecked,
|
||||
Enabled = canTrueColor,
|
||||
Text = "Force 16 colors"
|
||||
};
|
||||
cbUseTrueColor.CheckedStateChanging += (_, evt) => { Application.Force16Colors = evt.Result == CheckState.Checked; };
|
||||
app.Add (cbUseTrueColor);
|
||||
|
||||
y += 2;
|
||||
SetupGradient ("Red gradient", x, ref y, i => new (i, 0));
|
||||
SetupGradient ("Green gradient", x, ref y, i => new (0, i));
|
||||
SetupGradient ("Blue gradient", x, ref y, i => new (0, 0, i));
|
||||
SetupGradient ("Yellow gradient", x, ref y, i => new (i, i));
|
||||
SetupGradient ("Magenta gradient", x, ref y, i => new (i, 0, i));
|
||||
SetupGradient ("Cyan gradient", x, ref y, i => new (0, i, i));
|
||||
SetupGradient ("Gray gradient", x, ref y, i => new (i, i, i));
|
||||
|
||||
app.Add (
|
||||
new Label { X = Pos.AnchorEnd (44), Y = 2, Text = "Mouse over to get the gradient view color:" }
|
||||
);
|
||||
|
||||
app.Add (
|
||||
new Label { X = Pos.AnchorEnd (44), Y = 4, Text = "Red:" }
|
||||
);
|
||||
|
||||
app.Add (
|
||||
new Label { X = Pos.AnchorEnd (44), Y = 5, Text = "Green:" }
|
||||
);
|
||||
|
||||
app.Add (
|
||||
new Label { X = Pos.AnchorEnd (44), Y = 6, Text = "Blue:" }
|
||||
);
|
||||
|
||||
app.Add (
|
||||
new Label { X = Pos.AnchorEnd (44), Y = 8, Text = "Darker:" }
|
||||
);
|
||||
|
||||
app.Add (
|
||||
new Label { X = Pos.AnchorEnd (44), Y = 9, Text = "Lighter:" }
|
||||
);
|
||||
|
||||
var lblRed = new Label { X = Pos.AnchorEnd (32), Y = 4, Text = "na" };
|
||||
app.Add (lblRed);
|
||||
var lblGreen = new Label { X = Pos.AnchorEnd (32), Y = 5, Text = "na" };
|
||||
app.Add (lblGreen);
|
||||
var lblBlue = new Label { X = Pos.AnchorEnd (32), Y = 6, Text = "na" };
|
||||
app.Add (lblBlue);
|
||||
|
||||
var lblDarker = new Label { X = Pos.AnchorEnd (32), Y = 8, Text = " " };
|
||||
app.Add (lblDarker);
|
||||
|
||||
var lblLighter = new Label { X = Pos.AnchorEnd (32), Y = 9, Text = " " };
|
||||
app.Add (lblLighter);
|
||||
|
||||
Application.MouseEvent += (s, e) =>
|
||||
{
|
||||
if (e.View == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Flags == MouseFlags.Button1Clicked)
|
||||
{
|
||||
Attribute normal = e.View.GetAttributeForRole (VisualRole.Normal);
|
||||
|
||||
lblLighter.SetScheme (new (e.View.GetScheme ())
|
||||
{
|
||||
Normal = new (
|
||||
normal.Foreground,
|
||||
normal.Background.GetBrighterColor ()
|
||||
)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Attribute normal = e.View.GetAttributeForRole (VisualRole.Normal);
|
||||
lblRed.Text = normal.Foreground.R.ToString ();
|
||||
lblGreen.Text = normal.Foreground.G.ToString ();
|
||||
lblBlue.Text = normal.Foreground.B.ToString ();
|
||||
}
|
||||
};
|
||||
Application.Run (app);
|
||||
app.Dispose ();
|
||||
|
||||
Application.Shutdown ();
|
||||
|
||||
return;
|
||||
|
||||
void SetupGradient (string name, int x, ref int y, Func<int, Color> colorFunc)
|
||||
{
|
||||
var gradient = new Label { X = x, Y = y++, Text = name };
|
||||
app.Add (gradient);
|
||||
|
||||
for (int dx = x, i = 0; i <= 256; i += 4)
|
||||
{
|
||||
var l = new Label
|
||||
{
|
||||
X = dx++,
|
||||
Y = y
|
||||
};
|
||||
l.SetScheme (new ()
|
||||
{
|
||||
Normal = new (
|
||||
colorFunc (Math.Clamp (i, 0, 255)),
|
||||
colorFunc (Math.Clamp (i, 0, 255))
|
||||
)
|
||||
});
|
||||
app.Add (l);
|
||||
}
|
||||
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user