mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fixed a bunch of Key related issues
This commit is contained in:
@@ -4,7 +4,16 @@ using ColorHelper;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
/// <summary>Json converter for the <see cref="Color"/> class.</summary>
|
||||
/// <summary>
|
||||
/// Json converter for the <see cref="Color"/> class.
|
||||
/// <para>
|
||||
/// Serialization outputs a string with the color name if the color matches a name in <see cref="ColorStrings"/>
|
||||
/// or the "#RRGGBB" hexadecimal representation (e.g. "#FF0000" for red).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Deserialization formats supported are "#RGB", "#RRGGBB", "#ARGB", "#AARRGGBB", "rgb(r,g,b)",
|
||||
/// "rgb(r,g,b,a)", "rgba(r,g,b)", "rgba(r,g,b,a)", or any W3C color name.</para>
|
||||
/// </summary>
|
||||
internal class ColorJsonConverter : JsonConverter<Color>
|
||||
{
|
||||
private static ColorJsonConverter _instance;
|
||||
|
||||
@@ -501,7 +501,7 @@ public readonly partial record struct Color
|
||||
/// </summary>
|
||||
/// <param name="text">
|
||||
/// The text to analyze. Formats supported are "#RGB", "#RRGGBB", "#ARGB", "#AARRGGBB", "rgb(r,g,b)",
|
||||
/// "rgb(r,g,b,a)", "rgba(r,g,b)", "rgba(r,g,b,a)", and any of the <see cref="GetClosestNamedColor16(Terminal.Gui.Color)"/> string
|
||||
/// "rgb(r,g,b,a)", "rgba(r,g,b)", "rgba(r,g,b,a)", and any W3C color name."/> string
|
||||
/// values.
|
||||
/// </param>
|
||||
/// <param name="formatProvider">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
@@ -80,7 +79,7 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
public Key (KeyCode k) { KeyCode = k; }
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor.
|
||||
/// Copy constructor.
|
||||
/// </summary>
|
||||
/// <param name="key">The Key to copy</param>
|
||||
public Key (Key key)
|
||||
@@ -155,18 +154,13 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
/// </remarks>
|
||||
public Rune AsRune => ToRune (KeyCode);
|
||||
|
||||
private bool _handled = false;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current Key event has already been processed and the driver should stop notifying any other
|
||||
/// event subscriber. It's important to set this value to true specially when updating any View's layout from inside the
|
||||
/// event subscriber. It's important to set this value to true specially when updating any View's layout from inside
|
||||
/// the
|
||||
/// subscriber method.
|
||||
/// </summary>
|
||||
public bool Handled
|
||||
{
|
||||
get => _handled;
|
||||
set => _handled = value;
|
||||
}
|
||||
public bool Handled { get; set; }
|
||||
|
||||
/// <summary>Gets a value indicating whether the Alt key was pressed (real or synthesized)</summary>
|
||||
/// <value><see langword="true"/> if is alternate; otherwise, <see langword="false"/>.</value>
|
||||
@@ -339,11 +333,11 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
switch (baseKey)
|
||||
{
|
||||
case >= KeyCode.A and <= KeyCode.Z when !key.HasFlag (KeyCode.ShiftMask):
|
||||
return new Rune ((uint)(baseKey + 32));
|
||||
return new ((uint)(baseKey + 32));
|
||||
case >= KeyCode.A and <= KeyCode.Z when key.HasFlag (KeyCode.ShiftMask):
|
||||
return new Rune ((uint)baseKey);
|
||||
return new ((uint)baseKey);
|
||||
case > KeyCode.Null and < KeyCode.A:
|
||||
return new Rune ((uint)baseKey);
|
||||
return new ((uint)baseKey);
|
||||
}
|
||||
|
||||
if (Enum.IsDefined (typeof (KeyCode), baseKey))
|
||||
@@ -351,7 +345,7 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
return default (Rune);
|
||||
}
|
||||
|
||||
return new Rune ((uint)baseKey);
|
||||
return new ((uint)baseKey);
|
||||
}
|
||||
|
||||
#region Operators
|
||||
@@ -381,17 +375,17 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
|
||||
/// <summary>Cast <see cref="KeyCode"/> to a <see cref="Key"/>.</summary>
|
||||
/// <param name="keyCode"></param>
|
||||
public static implicit operator Key (KeyCode keyCode) { return new Key (keyCode); }
|
||||
public static implicit operator Key (KeyCode keyCode) { return new (keyCode); }
|
||||
|
||||
/// <summary>Cast <see langword="char"/> to a <see cref="Key"/>.</summary>
|
||||
/// <remarks>See <see cref="Key(char)"/> for more information.</remarks>
|
||||
/// <param name="ch"></param>
|
||||
public static implicit operator Key (char ch) { return new Key (ch); }
|
||||
public static implicit operator Key (char ch) { return new (ch); }
|
||||
|
||||
/// <summary>Cast <see langword="string"/> to a <see cref="Key"/>.</summary>
|
||||
/// <remarks>See <see cref="Key(string)"/> for more information.</remarks>
|
||||
/// <param name="str"></param>
|
||||
public static implicit operator Key (string str) { return new Key (str); }
|
||||
public static implicit operator Key (string str) { return new (str); }
|
||||
|
||||
/// <summary>Cast a <see cref="Key"/> to a <see langword="string"/>.</summary>
|
||||
/// <remarks>See <see cref="Key(string)"/> for more information.</remarks>
|
||||
@@ -399,10 +393,7 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
public static implicit operator string (Key key) { return key.ToString (); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals (object obj)
|
||||
{
|
||||
return obj is Key k && k.KeyCode == KeyCode && k.Handled == Handled;
|
||||
}
|
||||
public override bool Equals (object obj) { return obj is Key k && k.KeyCode == KeyCode && k.Handled == Handled; }
|
||||
|
||||
bool IEquatable<Key>.Equals (Key other) { return Equals (other); }
|
||||
|
||||
@@ -568,7 +559,10 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
/// <summary>Converts the provided string to a new <see cref="Key"/> instance.</summary>
|
||||
/// <param name="text">
|
||||
/// The text to analyze. Formats supported are "Ctrl+X", "Alt+X", "Shift+X", "Ctrl+Alt+X",
|
||||
/// "Ctrl+Shift+X", "Alt+Shift+X", "Ctrl+Alt+Shift+X", and "X".
|
||||
/// "Ctrl+Shift+X", "Alt+Shift+X", "Ctrl+Alt+Shift+X", "X", and "120" (Unicode codepoint).
|
||||
/// <para>
|
||||
/// The separator can be any character, not just <see cref="Key.Separator"/> (e.g. "Ctrl@Alt@X").
|
||||
/// </para>
|
||||
/// </param>
|
||||
/// <param name="key">The parsed value.</param>
|
||||
/// <returns>A boolean value indicating whether parsing was successful.</returns>
|
||||
@@ -577,38 +571,88 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
{
|
||||
if (string.IsNullOrEmpty (text))
|
||||
{
|
||||
key = Key.Empty;
|
||||
key = Empty;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (text)
|
||||
{
|
||||
case "Ctrl":
|
||||
key = KeyCode.CtrlMask;
|
||||
|
||||
return true;
|
||||
case "Alt":
|
||||
key = KeyCode.AltMask;
|
||||
|
||||
return true;
|
||||
case "Shift":
|
||||
key = KeyCode.ShiftMask;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
key = null;
|
||||
|
||||
// Split the string into parts
|
||||
string [] parts = text.Split ('+', '-', (char)Separator.Value);
|
||||
Rune separator = Separator;
|
||||
|
||||
if (parts.Length is 0 or > 4 || parts.Any (string.IsNullOrEmpty))
|
||||
// Perhaps the separator was written using a different Key.Separator? Does the string
|
||||
// start with "Ctrl", "Alt" or "Shift"? If so, get the char after the modifier string and use that as the separator.
|
||||
if (text.StartsWith ("Ctrl", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
separator = (Rune)text [4];
|
||||
}
|
||||
else if (text.StartsWith ("Alt", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
separator = (Rune)text [3];
|
||||
}
|
||||
else if (text.StartsWith ("Shift", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
separator = (Rune)text [5];
|
||||
}
|
||||
else if (text.EndsWith ("Ctrl", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
separator = (Rune)text [^5];
|
||||
}
|
||||
else if (text.EndsWith ("Alt", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
separator = (Rune)text [^4];
|
||||
}
|
||||
else if (text.EndsWith ("Shift", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
separator = (Rune)text [^6];
|
||||
}
|
||||
|
||||
// Split the string into parts using the set Separator
|
||||
string [] parts = text.Split ((char)separator.Value);
|
||||
|
||||
if (parts.Length is > 4)
|
||||
{
|
||||
// Invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
// if it's just a shift key
|
||||
if (parts.Length == 1)
|
||||
// e.g. "Ctrl++"
|
||||
if ((Rune)text [^1] != separator && parts.Any (string.IsNullOrEmpty))
|
||||
{
|
||||
switch (parts [0])
|
||||
// Invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((Rune)text [^1] == separator)
|
||||
{
|
||||
parts [^1] = separator.Value.ToString ();
|
||||
key = (char)separator.Value;
|
||||
}
|
||||
|
||||
if (separator != Separator && (parts.Length is 1 || (key is { } && parts.Length is 2)))
|
||||
{
|
||||
parts = text.Split ((char)separator.Value);
|
||||
|
||||
if (parts.Length is 0 or > 4 || parts.Any (string.IsNullOrEmpty))
|
||||
{
|
||||
case "Ctrl":
|
||||
key = KeyCode.CtrlMask;
|
||||
|
||||
return true;
|
||||
case "Alt":
|
||||
key = KeyCode.AltMask;
|
||||
|
||||
return true;
|
||||
case "Shift":
|
||||
key = KeyCode.ShiftMask;
|
||||
|
||||
return true;
|
||||
// Invalid
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,12 +693,12 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
{
|
||||
if (parsedKeyCode is >= KeyCode.A and <= KeyCode.Z && modifiers == 0)
|
||||
{
|
||||
key = new Key (parsedKeyCode | KeyCode.ShiftMask);
|
||||
key = new (parsedKeyCode | KeyCode.ShiftMask);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
key = new Key (parsedKeyCode | modifiers);
|
||||
key = new (parsedKeyCode | modifiers);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -664,7 +708,8 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
{
|
||||
keyCode = keyCode & ~KeyCode.Space;
|
||||
}
|
||||
key = new Key (keyCode | modifiers);
|
||||
|
||||
key = new (keyCode | modifiers);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -675,7 +720,7 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
{
|
||||
if (parsedKeyCode is >= KeyCode.A and <= KeyCode.Z && modifiers == 0)
|
||||
{
|
||||
key = new Key (parsedKeyCode | KeyCode.ShiftMask);
|
||||
key = new (parsedKeyCode | KeyCode.ShiftMask);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -684,7 +729,8 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
{
|
||||
parsedKeyCode = parsedKeyCode & ~KeyCode.Space;
|
||||
}
|
||||
key = new Key (parsedKeyCode | modifiers);
|
||||
|
||||
key = new (parsedKeyCode | modifiers);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -705,12 +751,12 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
|
||||
if ((KeyCode)parsedInt is >= KeyCode.A and <= KeyCode.Z && modifiers == 0)
|
||||
{
|
||||
key = new Key ((KeyCode)parsedInt | KeyCode.ShiftMask);
|
||||
key = new ((KeyCode)parsedInt | KeyCode.ShiftMask);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
key = new Key ((KeyCode)parsedInt);
|
||||
key = new ((KeyCode)parsedInt);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -722,7 +768,7 @@ public class Key : EventArgs, IEquatable<Key>
|
||||
|
||||
if (GetIsKeyCodeAtoZ (parsedKeyCode))
|
||||
{
|
||||
key = new Key (parsedKeyCode | (modifiers & ~KeyCode.Space));
|
||||
key = new (parsedKeyCode | (modifiers & ~KeyCode.Space));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
32
UnitTests/Configuration/AttributeJsonConverterTests.cs
Normal file
32
UnitTests/Configuration/AttributeJsonConverterTests.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class AttributeJsonConverterTests
|
||||
{
|
||||
[Fact]
|
||||
public void TestDeserialize ()
|
||||
{
|
||||
// Test deserializing from human-readable color names
|
||||
var json = "{\"Foreground\":\"Blue\",\"Background\":\"Green\"}";
|
||||
var attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
|
||||
Assert.Equal (Color.Blue, attribute.Foreground.GetClosestNamedColor16 ());
|
||||
Assert.Equal (Color.Green, attribute.Background.GetClosestNamedColor16 ());
|
||||
|
||||
// Test deserializing from RGB values
|
||||
json = "{\"Foreground\":\"rgb(255,0,0)\",\"Background\":\"rgb(0,255,0)\"}";
|
||||
attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
|
||||
Assert.Equal (Color.Red, attribute.Foreground.GetClosestNamedColor16 ());
|
||||
Assert.Equal (Color.BrightGreen, attribute.Background.GetClosestNamedColor16 ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void TestSerialize ()
|
||||
{
|
||||
// Test serializing to human-readable color names
|
||||
var attribute = new Attribute (Color.Blue, Color.Green);
|
||||
string json = JsonSerializer.Serialize (attribute, ConfigurationManagerTests._jsonOptions);
|
||||
Assert.Equal ("{\"Foreground\":\"Blue\",\"Background\":\"Green\"}", json);
|
||||
}
|
||||
}
|
||||
180
UnitTests/Configuration/ColorJsonConverterTests.cs
Normal file
180
UnitTests/Configuration/ColorJsonConverterTests.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class ColorJsonConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData ("\"#000000\"", 0, 0, 0)]
|
||||
public void DeserializesFromHexCode (string hexCode, int r, int g, int b)
|
||||
{
|
||||
// Arrange
|
||||
var expected = new Color (r, g, b);
|
||||
|
||||
// Act
|
||||
var actual = JsonSerializer.Deserialize<Color> (
|
||||
hexCode,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
//Assert
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("\"rgb(0,0,0)\"", 0, 0, 0)]
|
||||
public void DeserializesFromRgb (string rgb, int r, int g, int b)
|
||||
{
|
||||
// Arrange
|
||||
var expected = new Color (r, g, b);
|
||||
|
||||
// Act
|
||||
var actual = JsonSerializer.Deserialize<Color> (
|
||||
rgb,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
//Assert
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (ColorName16.Black, "Black")]
|
||||
[InlineData (ColorName16.Blue, "Blue")]
|
||||
[InlineData (ColorName16.Green, "Green")]
|
||||
[InlineData (ColorName16.Cyan, "Cyan")]
|
||||
[InlineData (ColorName16.Gray, "Gray")]
|
||||
[InlineData (ColorName16.Red, "Red")]
|
||||
[InlineData (ColorName16.Magenta, "Magenta")]
|
||||
[InlineData (ColorName16.Yellow, "Yellow")]
|
||||
[InlineData (ColorName16.DarkGray, "DarkGray")]
|
||||
[InlineData (ColorName16.BrightBlue, "BrightBlue")]
|
||||
[InlineData (ColorName16.BrightGreen, "BrightGreen")]
|
||||
[InlineData (ColorName16.BrightCyan, "BrightCyan")]
|
||||
[InlineData (ColorName16.BrightRed, "BrightRed")]
|
||||
[InlineData (ColorName16.BrightMagenta, "BrightMagenta")]
|
||||
[InlineData (ColorName16.BrightYellow, "BrightYellow")]
|
||||
[InlineData (ColorName16.White, "White")]
|
||||
public void SerializesColorName16ValuesAsStrings (ColorName16 colorName, string expectedJson)
|
||||
{
|
||||
var converter = new ColorJsonConverter ();
|
||||
var options = new JsonSerializerOptions { Converters = { converter } };
|
||||
|
||||
string serialized = JsonSerializer.Serialize (new Color (colorName), options);
|
||||
|
||||
Assert.Equal ($"\"{expectedJson}\"", serialized);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (1, 0, 0, "\"#010000\"")]
|
||||
[InlineData (0, 0, 1, "\"#000001\"")]
|
||||
public void SerializesToHexCode (int r, int g, int b, string expected)
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
string actual = JsonSerializer.Serialize (
|
||||
new Color (r, g, b),
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
//Assert
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("Black", Color.Black)]
|
||||
[InlineData ("Blue", Color.Blue)]
|
||||
[InlineData ("BrightBlue", Color.BrightBlue)]
|
||||
[InlineData ("BrightCyan", Color.BrightCyan)]
|
||||
[InlineData ("BrightGreen", Color.BrightGreen)]
|
||||
[InlineData ("BrightMagenta", Color.BrightMagenta)]
|
||||
[InlineData ("BrightRed", Color.BrightRed)]
|
||||
[InlineData ("BrightYellow", Color.BrightYellow)]
|
||||
[InlineData ("Yellow", Color.Yellow)]
|
||||
[InlineData ("Cyan", Color.Cyan)]
|
||||
[InlineData ("DarkGray", Color.DarkGray)]
|
||||
[InlineData ("Gray", Color.Gray)]
|
||||
[InlineData ("Green", Color.Green)]
|
||||
[InlineData ("Magenta", Color.Magenta)]
|
||||
[InlineData ("Red", Color.Red)]
|
||||
[InlineData ("White", Color.White)]
|
||||
public void TestColorDeserializationFromHumanReadableColorName16 (string colorName, ColorName16 expectedColor)
|
||||
{
|
||||
// Arrange
|
||||
var json = $"\"{colorName}\"";
|
||||
|
||||
// Act
|
||||
var actualColor = JsonSerializer.Deserialize<Color> (json, ConfigurationManagerTests._jsonOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (new Color (expectedColor), actualColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDeserializeColor_Black ()
|
||||
{
|
||||
// Arrange
|
||||
var json = "\"Black\"";
|
||||
var expectedColor = new Color ("Black");
|
||||
|
||||
// Act
|
||||
var color = JsonSerializer.Deserialize<Color> (
|
||||
json,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColor, color);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDeserializeColor_BrightRed ()
|
||||
{
|
||||
// Arrange
|
||||
var json = "\"BrightRed\"";
|
||||
var expectedColor = Color.BrightRed;
|
||||
|
||||
// Act
|
||||
var color = JsonSerializer.Deserialize<Color> (
|
||||
json,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColor, color);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSerializeColor_Black ()
|
||||
{
|
||||
// Arrange
|
||||
var expectedJson = "\"Black\"";
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (
|
||||
new Color (Color.Black),
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedJson, json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSerializeColor_BrightRed ()
|
||||
{
|
||||
// Arrange
|
||||
var expectedJson = "\"BrightRed\"";
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (
|
||||
new Color (Color.BrightRed),
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedJson, json);
|
||||
}
|
||||
}
|
||||
58
UnitTests/Configuration/ColorSchemeJsonConverterTests.cs
Normal file
58
UnitTests/Configuration/ColorSchemeJsonConverterTests.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class ColorSchemeJsonConverterTests
|
||||
{
|
||||
//string json = @"
|
||||
// {
|
||||
// ""ColorSchemes"": {
|
||||
// ""Base"": {
|
||||
// ""normal"": {
|
||||
// ""foreground"": ""White"",
|
||||
// ""background"": ""Blue""
|
||||
// },
|
||||
// ""focus"": {
|
||||
// ""foreground"": ""Black"",
|
||||
// ""background"": ""Gray""
|
||||
// },
|
||||
// ""hotNormal"": {
|
||||
// ""foreground"": ""BrightCyan"",
|
||||
// ""background"": ""Blue""
|
||||
// },
|
||||
// ""hotFocus"": {
|
||||
// ""foreground"": ""BrightBlue"",
|
||||
// ""background"": ""Gray""
|
||||
// },
|
||||
// ""disabled"": {
|
||||
// ""foreground"": ""DarkGray"",
|
||||
// ""background"": ""Blue""
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }";
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void TestColorSchemesSerialization ()
|
||||
{
|
||||
// Arrange
|
||||
var expectedColorScheme = new ColorScheme
|
||||
{
|
||||
Normal = new Attribute (Color.White, Color.Blue),
|
||||
Focus = new Attribute (Color.Black, Color.Gray),
|
||||
HotNormal = new Attribute (Color.BrightCyan, Color.Blue),
|
||||
HotFocus = new Attribute (Color.BrightBlue, Color.Gray),
|
||||
Disabled = new Attribute (Color.DarkGray, Color.Blue)
|
||||
};
|
||||
|
||||
string serializedColorScheme =
|
||||
JsonSerializer.Serialize (expectedColorScheme, ConfigurationManagerTests._jsonOptions);
|
||||
|
||||
// Act
|
||||
var actualColorScheme =
|
||||
JsonSerializer.Deserialize<ColorScheme> (serializedColorScheme, ConfigurationManagerTests._jsonOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColorScheme, actualColorScheme);
|
||||
}
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Unicode;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class ColorJsonConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData ("\"#000000\"", 0, 0, 0)]
|
||||
public void DeserializesFromHexCode (string hexCode, int r, int g, int b)
|
||||
{
|
||||
// Arrange
|
||||
var expected = new Color (r, g, b);
|
||||
|
||||
// Act
|
||||
var actual = JsonSerializer.Deserialize<Color> (
|
||||
hexCode,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
//Assert
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("\"rgb(0,0,0)\"", 0, 0, 0)]
|
||||
public void DeserializesFromRgb (string rgb, int r, int g, int b)
|
||||
{
|
||||
// Arrange
|
||||
var expected = new Color (r, g, b);
|
||||
|
||||
// Act
|
||||
var actual = JsonSerializer.Deserialize<Color> (
|
||||
rgb,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
//Assert
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (ColorName16.Black, "Black")]
|
||||
[InlineData (ColorName16.Blue, "Blue")]
|
||||
[InlineData (ColorName16.Green, "Green")]
|
||||
[InlineData (ColorName16.Cyan, "Cyan")]
|
||||
[InlineData (ColorName16.Gray, "Gray")]
|
||||
[InlineData (ColorName16.Red, "Red")]
|
||||
[InlineData (ColorName16.Magenta, "Magenta")]
|
||||
[InlineData (ColorName16.Yellow, "Yellow")]
|
||||
[InlineData (ColorName16.DarkGray, "DarkGray")]
|
||||
[InlineData (ColorName16.BrightBlue, "BrightBlue")]
|
||||
[InlineData (ColorName16.BrightGreen, "BrightGreen")]
|
||||
[InlineData (ColorName16.BrightCyan, "BrightCyan")]
|
||||
[InlineData (ColorName16.BrightRed, "BrightRed")]
|
||||
[InlineData (ColorName16.BrightMagenta, "BrightMagenta")]
|
||||
[InlineData (ColorName16.BrightYellow, "BrightYellow")]
|
||||
[InlineData (ColorName16.White, "White")]
|
||||
public void SerializesEnumValuesAsStrings (ColorName16 colorName, string expectedJson)
|
||||
{
|
||||
var converter = new ColorJsonConverter ();
|
||||
var options = new JsonSerializerOptions { Converters = { converter } };
|
||||
|
||||
string serialized = JsonSerializer.Serialize (new Color (colorName), options);
|
||||
|
||||
Assert.Equal ($"\"{expectedJson}\"", serialized);
|
||||
}
|
||||
|
||||
[Theory (Skip = "Not anymore. If a W3C color matches, that's used")]
|
||||
[InlineData (0, 0, 0, "\"#000000\"")]
|
||||
[InlineData (0, 0, 1, "\"#000001\"")]
|
||||
public void SerializesToHexCode (int r, int g, int b, string expected)
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
string actual = JsonSerializer.Serialize (
|
||||
new Color (r, g, b),
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
//Assert
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("Black", Color.Black)]
|
||||
[InlineData ("Blue", Color.Blue)]
|
||||
[InlineData ("BrightBlue", Color.BrightBlue)]
|
||||
[InlineData ("BrightCyan", Color.BrightCyan)]
|
||||
[InlineData ("BrightGreen", Color.BrightGreen)]
|
||||
[InlineData ("BrightMagenta", Color.BrightMagenta)]
|
||||
[InlineData ("BrightRed", Color.BrightRed)]
|
||||
[InlineData ("BrightYellow", Color.BrightYellow)]
|
||||
[InlineData ("Yellow", Color.Yellow)]
|
||||
[InlineData ("Cyan", Color.Cyan)]
|
||||
[InlineData ("DarkGray", Color.DarkGray)]
|
||||
[InlineData ("Gray", Color.Gray)]
|
||||
[InlineData ("Green", Color.Green)]
|
||||
[InlineData ("Magenta", Color.Magenta)]
|
||||
[InlineData ("Red", Color.Red)]
|
||||
[InlineData ("White", Color.White)]
|
||||
public void TestColorDeserializationFromHumanReadableColorName16 (string colorName, ColorName16 expectedColor)
|
||||
{
|
||||
// Arrange
|
||||
var json = $"\"{colorName}\"";
|
||||
|
||||
// Act
|
||||
var actualColor = JsonSerializer.Deserialize<Color> (json, ConfigurationManagerTests._jsonOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (new Color (expectedColor), actualColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDeserializeColor_Black ()
|
||||
{
|
||||
// Arrange
|
||||
var json = "\"Black\"";
|
||||
var expectedColor = new Color ("Black");
|
||||
|
||||
// Act
|
||||
var color = JsonSerializer.Deserialize<Color> (
|
||||
json,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColor, color);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDeserializeColor_BrightRed ()
|
||||
{
|
||||
// Arrange
|
||||
var json = "\"BrightRed\"";
|
||||
var expectedColor = Color.BrightRed;
|
||||
|
||||
// Act
|
||||
var color = JsonSerializer.Deserialize<Color> (
|
||||
json,
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColor, color);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSerializeColor_Black ()
|
||||
{
|
||||
// Arrange
|
||||
var expectedJson = "\"Black\"";
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (
|
||||
new Color (Color.Black),
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedJson, json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSerializeColor_BrightRed ()
|
||||
{
|
||||
// Arrange
|
||||
var expectedJson = "\"BrightRed\"";
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (
|
||||
new Color (Color.BrightRed),
|
||||
new JsonSerializerOptions { Converters = { new ColorJsonConverter () } }
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedJson, json);
|
||||
}
|
||||
}
|
||||
|
||||
public class AttributeJsonConverterTests
|
||||
{
|
||||
[Fact]
|
||||
public void TestDeserialize ()
|
||||
{
|
||||
// Test deserializing from human-readable color names
|
||||
var json = "{\"Foreground\":\"Blue\",\"Background\":\"Green\"}";
|
||||
var attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
|
||||
Assert.Equal (Color.Blue, attribute.Foreground.GetClosestNamedColor16 ());
|
||||
Assert.Equal (Color.Green, attribute.Background.GetClosestNamedColor16 ());
|
||||
|
||||
// Test deserializing from RGB values
|
||||
json = "{\"Foreground\":\"rgb(255,0,0)\",\"Background\":\"rgb(0,255,0)\"}";
|
||||
attribute = JsonSerializer.Deserialize<Attribute> (json, ConfigurationManagerTests._jsonOptions);
|
||||
Assert.Equal (Color.Red, attribute.Foreground.GetClosestNamedColor16 ());
|
||||
Assert.Equal (Color.BrightGreen, attribute.Background.GetClosestNamedColor16 ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void TestSerialize ()
|
||||
{
|
||||
// Test serializing to human-readable color names
|
||||
var attribute = new Attribute (Color.Blue, Color.Green);
|
||||
string json = JsonSerializer.Serialize (attribute, ConfigurationManagerTests._jsonOptions);
|
||||
Assert.Equal ("{\"Foreground\":\"Blue\",\"Background\":\"Green\"}", json);
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorSchemeJsonConverterTests
|
||||
{
|
||||
//string json = @"
|
||||
// {
|
||||
// ""ColorSchemes"": {
|
||||
// ""Base"": {
|
||||
// ""normal"": {
|
||||
// ""foreground"": ""White"",
|
||||
// ""background"": ""Blue""
|
||||
// },
|
||||
// ""focus"": {
|
||||
// ""foreground"": ""Black"",
|
||||
// ""background"": ""Gray""
|
||||
// },
|
||||
// ""hotNormal"": {
|
||||
// ""foreground"": ""BrightCyan"",
|
||||
// ""background"": ""Blue""
|
||||
// },
|
||||
// ""hotFocus"": {
|
||||
// ""foreground"": ""BrightBlue"",
|
||||
// ""background"": ""Gray""
|
||||
// },
|
||||
// ""disabled"": {
|
||||
// ""foreground"": ""DarkGray"",
|
||||
// ""background"": ""Blue""
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }";
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void TestColorSchemesSerialization ()
|
||||
{
|
||||
// Arrange
|
||||
var expectedColorScheme = new ColorScheme
|
||||
{
|
||||
Normal = new Attribute (Color.White, Color.Blue),
|
||||
Focus = new Attribute (Color.Black, Color.Gray),
|
||||
HotNormal = new Attribute (Color.BrightCyan, Color.Blue),
|
||||
HotFocus = new Attribute (Color.BrightBlue, Color.Gray),
|
||||
Disabled = new Attribute (Color.DarkGray, Color.Blue)
|
||||
};
|
||||
|
||||
string serializedColorScheme =
|
||||
JsonSerializer.Serialize (expectedColorScheme, ConfigurationManagerTests._jsonOptions);
|
||||
|
||||
// Act
|
||||
var actualColorScheme =
|
||||
JsonSerializer.Deserialize<ColorScheme> (serializedColorScheme, ConfigurationManagerTests._jsonOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedColorScheme, actualColorScheme);
|
||||
}
|
||||
}
|
||||
|
||||
public class KeyCodeJsonConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData (KeyCode.A, "A")]
|
||||
[InlineData (KeyCode.A | KeyCode.ShiftMask, "A, ShiftMask")]
|
||||
[InlineData (KeyCode.A | KeyCode.CtrlMask, "A, CtrlMask")]
|
||||
[InlineData (KeyCode.A | KeyCode.AltMask | KeyCode.CtrlMask, "A, CtrlMask, AltMask")]
|
||||
[InlineData ((KeyCode)'a' | KeyCode.AltMask | KeyCode.CtrlMask, "Space, A, CtrlMask, AltMask")]
|
||||
[InlineData ((KeyCode)'a' | KeyCode.ShiftMask, "Space, A, ShiftMask")]
|
||||
[InlineData (KeyCode.Delete | KeyCode.AltMask | KeyCode.CtrlMask, "Delete, CtrlMask, AltMask")]
|
||||
[InlineData (KeyCode.D4, "D4")]
|
||||
[InlineData (KeyCode.Esc, "Esc")]
|
||||
public void TestKeyRoundTripConversion (KeyCode key, string expectedStringTo)
|
||||
{
|
||||
// Arrange
|
||||
var options = new JsonSerializerOptions ();
|
||||
options.Converters.Add (new KeyCodeJsonConverter ());
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (key, options);
|
||||
var deserializedKey = JsonSerializer.Deserialize<KeyCode> (json, options);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedStringTo, deserializedKey.ToString ());
|
||||
}
|
||||
}
|
||||
|
||||
public class KeyJsonConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData (KeyCode.A, "\"a\"")]
|
||||
[InlineData ((KeyCode)'â', "\"â\"")]
|
||||
[InlineData (KeyCode.A | KeyCode.ShiftMask, "\"A\"")]
|
||||
[InlineData (KeyCode.A | KeyCode.CtrlMask, "\"Ctrl+A\"")]
|
||||
[InlineData (KeyCode.A | KeyCode.AltMask | KeyCode.CtrlMask, "\"Ctrl+Alt+A\"")]
|
||||
[InlineData (KeyCode.Delete | KeyCode.AltMask | KeyCode.CtrlMask, "\"Ctrl+Alt+Delete\"")]
|
||||
[InlineData (KeyCode.D4, "\"4\"")]
|
||||
[InlineData (KeyCode.Esc, "\"Esc\"")]
|
||||
public void TestKey_Serialize (KeyCode key, string expected)
|
||||
{
|
||||
// Arrange
|
||||
var options = new JsonSerializerOptions ();
|
||||
options.Converters.Add (new KeyJsonConverter ());
|
||||
options.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize ((Key)key, options);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expected, json);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (KeyCode.A, "a")]
|
||||
[InlineData (KeyCode.A | KeyCode.ShiftMask, "A")]
|
||||
[InlineData (KeyCode.A | KeyCode.CtrlMask, "Ctrl+A")]
|
||||
[InlineData (KeyCode.A | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+A")]
|
||||
[InlineData (KeyCode.Delete | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+Delete")]
|
||||
[InlineData (KeyCode.D4, "4")]
|
||||
[InlineData (KeyCode.Esc, "Esc")]
|
||||
public void TestKeyRoundTripConversion (KeyCode key, string expectedStringTo)
|
||||
{
|
||||
// Arrange
|
||||
var options = new JsonSerializerOptions ();
|
||||
options.Converters.Add (new KeyJsonConverter ());
|
||||
var encoderSettings = new TextEncoderSettings ();
|
||||
encoderSettings.AllowCharacters ('+', '-');
|
||||
encoderSettings.AllowRange (UnicodeRanges.BasicLatin);
|
||||
options.Encoder = JavaScriptEncoder.Create (encoderSettings);
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize ((Key)key, options);
|
||||
var deserializedKey = JsonSerializer.Deserialize<Key> (json, options);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedStringTo, deserializedKey.ToString ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Separator_Property_Serializes_As_Glyph ()
|
||||
{
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (Key.Separator, ConfigurationManager._serializerOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal ("\"+\"", json);
|
||||
}
|
||||
}
|
||||
30
UnitTests/Configuration/KeyCodeJsonConverterTests.cs
Normal file
30
UnitTests/Configuration/KeyCodeJsonConverterTests.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class KeyCodeJsonConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData (KeyCode.A, "A")]
|
||||
[InlineData (KeyCode.A | KeyCode.ShiftMask, "A, ShiftMask")]
|
||||
[InlineData (KeyCode.A | KeyCode.CtrlMask, "A, CtrlMask")]
|
||||
[InlineData (KeyCode.A | KeyCode.AltMask | KeyCode.CtrlMask, "A, CtrlMask, AltMask")]
|
||||
[InlineData ((KeyCode)'a' | KeyCode.AltMask | KeyCode.CtrlMask, "Space, A, CtrlMask, AltMask")]
|
||||
[InlineData ((KeyCode)'a' | KeyCode.ShiftMask, "Space, A, ShiftMask")]
|
||||
[InlineData (KeyCode.Delete | KeyCode.AltMask | KeyCode.CtrlMask, "Delete, CtrlMask, AltMask")]
|
||||
[InlineData (KeyCode.D4, "D4")]
|
||||
[InlineData (KeyCode.Esc, "Esc")]
|
||||
public void TestKeyRoundTripConversion (KeyCode key, string expectedStringTo)
|
||||
{
|
||||
// Arrange
|
||||
var options = new JsonSerializerOptions ();
|
||||
options.Converters.Add (new KeyCodeJsonConverter ());
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (key, options);
|
||||
var deserializedKey = JsonSerializer.Deserialize<KeyCode> (json, options);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedStringTo, deserializedKey.ToString ());
|
||||
}
|
||||
}
|
||||
127
UnitTests/Configuration/KeyJsonConverterTests.cs
Normal file
127
UnitTests/Configuration/KeyJsonConverterTests.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Unicode;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class KeyJsonConverterTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData (KeyCode.A, "\"a\"")]
|
||||
[InlineData ((KeyCode)'â', "\"â\"")]
|
||||
[InlineData (KeyCode.A | KeyCode.ShiftMask, "\"A\"")]
|
||||
[InlineData (KeyCode.A | KeyCode.CtrlMask, "\"Ctrl+A\"")]
|
||||
[InlineData (KeyCode.A | KeyCode.AltMask | KeyCode.CtrlMask, "\"Ctrl+Alt+A\"")]
|
||||
[InlineData (KeyCode.Delete | KeyCode.AltMask | KeyCode.CtrlMask, "\"Ctrl+Alt+Delete\"")]
|
||||
[InlineData (KeyCode.D4, "\"4\"")]
|
||||
[InlineData (KeyCode.Esc, "\"Esc\"")]
|
||||
[InlineData ((KeyCode)'+' | KeyCode.AltMask | KeyCode.CtrlMask, "\"Ctrl+Alt++\"")]
|
||||
public void TestKey_Serialize (KeyCode key, string expected)
|
||||
{
|
||||
// Arrange
|
||||
var options = new JsonSerializerOptions ();
|
||||
options.Converters.Add (new KeyJsonConverter ());
|
||||
options.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize ((Key)key, options);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expected, json);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (KeyCode.A, "a")]
|
||||
[InlineData (KeyCode.A | KeyCode.ShiftMask, "A")]
|
||||
[InlineData (KeyCode.A | KeyCode.CtrlMask, "Ctrl+A")]
|
||||
[InlineData (KeyCode.A | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+A")]
|
||||
[InlineData (KeyCode.Delete | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt+Delete")]
|
||||
[InlineData (KeyCode.D4, "4")]
|
||||
[InlineData (KeyCode.Esc, "Esc")]
|
||||
[InlineData ((KeyCode)'+' | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt++")]
|
||||
[InlineData ((KeyCode)'+' | KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt++")]
|
||||
public void TestKeyRoundTripConversion (KeyCode key, string expectedStringTo)
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize ((Key)key, ConfigurationManager._serializerOptions);
|
||||
var deserializedKey = JsonSerializer.Deserialize<Key> (json, ConfigurationManager._serializerOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (expectedStringTo, deserializedKey.ToString ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Separator_Property_Serializes_As_Glyph ()
|
||||
{
|
||||
// Act
|
||||
string json = JsonSerializer.Serialize (Key.Separator, ConfigurationManager._serializerOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal ($"\"{Key.Separator}\"", json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Separator_Property_Set_Changes_Serialization_Format ()
|
||||
{
|
||||
Rune savedSeparator = Key.Separator;
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
Key.Separator = (Rune)'*';
|
||||
string json = JsonSerializer.Serialize (Key.Separator, ConfigurationManager._serializerOptions);
|
||||
|
||||
// Assert
|
||||
Assert.Equal ("\"*\"", json);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Key.Separator = savedSeparator;
|
||||
}
|
||||
|
||||
Key.Separator = savedSeparator;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ('A', '+', "\"Ctrl+Alt+A\"")]
|
||||
[InlineData ('A', '-', "\"Ctrl+Alt+A\"")]
|
||||
[InlineData ('A', '*', "\"Ctrl+Alt+A\"")]
|
||||
[InlineData ('A', '@', "\"Ctrl+Alt+A\"")]
|
||||
[InlineData ('A', '+', "\"Ctrl@Alt@A\"")]
|
||||
[InlineData ('A', '-', "\"Ctrl@Alt@A\"")]
|
||||
[InlineData ('A', '*', "\"Ctrl@Alt@A\"")]
|
||||
[InlineData ('A', '@', "\"Ctrl@Alt@A\"")]
|
||||
[InlineData ('+', '+', "\"Ctrl+Alt++\"")]
|
||||
[InlineData ('+', '-', "\"Ctrl+Alt++\"")]
|
||||
[InlineData ('+', '*', "\"Ctrl+Alt++\"")]
|
||||
[InlineData ('+', '@', "\"Ctrl+Alt++\"")]
|
||||
[InlineData ('+', '+', "\"Ctrl@Alt@+\"")]
|
||||
[InlineData ('+', '-', "\"Ctrl@Alt@+\"")]
|
||||
[InlineData ('+', '*', "\"Ctrl@Alt@+\"")]
|
||||
[InlineData ('+', '@', "\"Ctrl@Alt@+\"")]
|
||||
public void Separator_Property_Set_Deserialization_Works_With_Any (char keyChar, char separator, string json)
|
||||
{
|
||||
Rune savedSeparator = Key.Separator;
|
||||
|
||||
try
|
||||
{
|
||||
// Act
|
||||
Key.Separator = (Rune)separator;
|
||||
|
||||
Key deserializedKey = JsonSerializer.Deserialize<Key> (json, ConfigurationManager._serializerOptions);
|
||||
|
||||
Key expectedKey = new Key ((KeyCode)keyChar).WithCtrl.WithAlt;
|
||||
// Assert
|
||||
Assert.Equal (expectedKey, deserializedKey);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Key.Separator = savedSeparator;
|
||||
}
|
||||
|
||||
Key.Separator = savedSeparator;
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@ public class KeyTests
|
||||
{ "Alt+A", Key.A.WithAlt },
|
||||
{ "Shift+A", Key.A.WithShift },
|
||||
{ "A", Key.A.WithShift },
|
||||
{ "â", new Key ((KeyCode)'â') },
|
||||
{ "Shift+â", new Key ((KeyCode)'â' | KeyCode.ShiftMask) },
|
||||
{ "Shift+Â", new Key ((KeyCode)'Â' | KeyCode.ShiftMask) },
|
||||
{ "â", new ((KeyCode)'â') },
|
||||
{ "Shift+â", new ((KeyCode)'â' | KeyCode.ShiftMask) },
|
||||
{ "Shift+Â", new ((KeyCode)'Â' | KeyCode.ShiftMask) },
|
||||
{ "Ctrl+Shift+CursorUp", Key.CursorUp.WithShift.WithCtrl },
|
||||
{ "Ctrl+Alt+Shift+CursorUp", Key.CursorUp.WithShift.WithCtrl.WithAlt },
|
||||
{ "ctrl+alt+shift+cursorup", Key.CursorUp.WithShift.WithCtrl.WithAlt },
|
||||
@@ -439,7 +439,7 @@ public class KeyTests
|
||||
[Fact]
|
||||
public void ToString_ShouldReturnReadableString ()
|
||||
{
|
||||
var eventArgs = Key.A.WithCtrl;
|
||||
Key eventArgs = Key.A.WithCtrl;
|
||||
Assert.Equal ("Ctrl+A", eventArgs.ToString ());
|
||||
}
|
||||
|
||||
@@ -454,8 +454,6 @@ public class KeyTests
|
||||
[Theory]
|
||||
[InlineData ("aa")]
|
||||
[InlineData ("-1")]
|
||||
[InlineData ("Crtl-A")]
|
||||
[InlineData ("Ctrl=A")]
|
||||
[InlineData ("Crtl")]
|
||||
[InlineData ("99a")]
|
||||
[InlineData ("a99")]
|
||||
@@ -508,6 +506,8 @@ public class KeyTests
|
||||
[InlineData ("Alt-A", KeyCode.A | KeyCode.AltMask)]
|
||||
[InlineData ("A-Ctrl", KeyCode.A | KeyCode.CtrlMask)]
|
||||
[InlineData ("Alt-A-Ctrl", KeyCode.A | KeyCode.CtrlMask | KeyCode.AltMask)]
|
||||
[InlineData ("120", KeyCode.X)]
|
||||
[InlineData ("Ctrl@A", KeyCode.A | KeyCode.CtrlMask)]
|
||||
public void TryParse_ShouldReturnTrue_WhenValidKey (string keyString, KeyCode expected)
|
||||
{
|
||||
Assert.True (Key.TryParse (keyString, out Key key));
|
||||
@@ -518,7 +518,7 @@ public class KeyTests
|
||||
[Fact]
|
||||
public void WithShift_ShouldReturnCorrectValue ()
|
||||
{
|
||||
var a = Key.A;
|
||||
Key a = Key.A;
|
||||
Assert.Equal (KeyCode.A | KeyCode.ShiftMask, a.WithShift);
|
||||
|
||||
Key CAD = Key.Delete.WithCtrl.WithAlt;
|
||||
@@ -529,17 +529,17 @@ public class KeyTests
|
||||
[Fact]
|
||||
public void Equals_ShouldReturnTrue_WhenEqual ()
|
||||
{
|
||||
var a = Key.A;
|
||||
var b = Key.A;
|
||||
Key a = Key.A;
|
||||
Key b = Key.A;
|
||||
Assert.True (a.Equals (b));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equals_Handled_Changed_ShouldReturnTrue_WhenEqual ()
|
||||
{
|
||||
var a = Key.A;
|
||||
Key a = Key.A;
|
||||
a.Handled = true;
|
||||
var b = Key.A;
|
||||
Key b = Key.A;
|
||||
b.Handled = true;
|
||||
Assert.True (a.Equals (b));
|
||||
}
|
||||
@@ -547,9 +547,9 @@ public class KeyTests
|
||||
[Fact]
|
||||
public void Equals_Handled_Changed_ShouldReturnFalse_WhenNotEqual ()
|
||||
{
|
||||
var a = Key.A;
|
||||
Key a = Key.A;
|
||||
a.Handled = true;
|
||||
var b = Key.A;
|
||||
Key b = Key.A;
|
||||
Assert.False (a.Equals (b));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user