mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 16:59:35 +01:00
* Add a native AOT project. * Fixes Text.Json to work with native AOT. * Fix silent errors on unit tests when testing the Red color which has a length of 3. * Allowing test custom configuration without the config.json file match the unit tests configurations. * Fix unit test if tested alone. * Add native project into solution. * Fix merge errors. * Setting ConfigurationManager.ThrowOnJsonErrors as true to throw any serialization issue when published file runs. * Remove unnecessary using's. * Added unit test to ensure all serialization is properly configured. * Fix warnings. * Remove ThrowOnJsonErrors. * Fix warnings. --------- Co-authored-by: Tig <tig@users.noreply.github.com>
This commit is contained in:
@@ -38,7 +38,7 @@ public class ConfigurationManagerTests
|
||||
}
|
||||
|
||||
// act
|
||||
Settings ["Application.QuitKey"].PropertyValue = Key.Q;
|
||||
Settings! ["Application.QuitKey"].PropertyValue = Key.Q;
|
||||
Settings ["Application.NextTabGroupKey"].PropertyValue = Key.F;
|
||||
Settings ["Application.PrevTabGroupKey"].PropertyValue = Key.B;
|
||||
|
||||
@@ -130,7 +130,7 @@ public class ConfigurationManagerTests
|
||||
{ "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) }
|
||||
};
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberWiseCopy (dictSrc, dictDest);
|
||||
Assert.Equal (2, dictCopy.Count);
|
||||
Assert.Equal (2, dictCopy!.Count);
|
||||
Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
|
||||
Assert.Equal (dictSrc ["Normal"], dictCopy ["Normal"]);
|
||||
|
||||
@@ -141,7 +141,7 @@ public class ConfigurationManagerTests
|
||||
};
|
||||
dictSrc = new Dictionary<string, Attribute> { { "Disabled", new Attribute (Color.White) } };
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberWiseCopy (dictSrc, dictDest);
|
||||
Assert.Equal (2, dictCopy.Count);
|
||||
Assert.Equal (2, dictCopy!.Count);
|
||||
Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
|
||||
Assert.Equal (dictDest ["Normal"], dictCopy ["Normal"]);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public class ConfigurationManagerTests
|
||||
{
|
||||
Reset ();
|
||||
|
||||
Settings ["Application.QuitKey"].PropertyValue = Key.Q;
|
||||
Settings! ["Application.QuitKey"].PropertyValue = Key.Q;
|
||||
Settings ["Application.NextTabGroupKey"].PropertyValue = Key.F;
|
||||
Settings ["Application.PrevTabGroupKey"].PropertyValue = Key.B;
|
||||
|
||||
@@ -163,16 +163,16 @@ public class ConfigurationManagerTests
|
||||
fired = true;
|
||||
|
||||
// assert
|
||||
Assert.Equal (Key.Esc, ((Key)Settings ["Application.QuitKey"].PropertyValue).KeyCode);
|
||||
Assert.Equal (Key.Esc, (((Key)Settings! ["Application.QuitKey"].PropertyValue)!).KeyCode);
|
||||
|
||||
Assert.Equal (
|
||||
KeyCode.F6,
|
||||
((Key)Settings ["Application.NextTabGroupKey"].PropertyValue).KeyCode
|
||||
(((Key)Settings ["Application.NextTabGroupKey"].PropertyValue)!).KeyCode
|
||||
);
|
||||
|
||||
Assert.Equal (
|
||||
KeyCode.F6 | KeyCode.ShiftMask,
|
||||
((Key)Settings ["Application.PrevTabGroupKey"].PropertyValue).KeyCode
|
||||
(((Key)Settings ["Application.PrevTabGroupKey"].PropertyValue)!).KeyCode
|
||||
);
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public class ConfigurationManagerTests
|
||||
|
||||
// arrange
|
||||
Reset ();
|
||||
Settings ["Application.QuitKey"].PropertyValue = Key.Q;
|
||||
Settings! ["Application.QuitKey"].PropertyValue = Key.Q;
|
||||
Settings ["Application.NextTabGroupKey"].PropertyValue = Key.F;
|
||||
Settings ["Application.PrevTabGroupKey"].PropertyValue = Key.B;
|
||||
Settings.Apply ();
|
||||
@@ -242,7 +242,7 @@ public class ConfigurationManagerTests
|
||||
Reset ();
|
||||
|
||||
// assert
|
||||
Assert.NotEmpty (Themes);
|
||||
Assert.NotEmpty (Themes!);
|
||||
Assert.Equal ("Default", Themes.Theme);
|
||||
Assert.Equal (Key.Esc, Application.QuitKey);
|
||||
Assert.Equal (Key.F6, Application.NextTabGroupKey);
|
||||
@@ -274,7 +274,7 @@ public class ConfigurationManagerTests
|
||||
{
|
||||
Locations = ConfigLocations.DefaultOnly;
|
||||
Reset ();
|
||||
Assert.NotEmpty (Themes);
|
||||
Assert.NotEmpty (Themes!);
|
||||
Assert.Equal ("Default", Themes.Theme);
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ public class ConfigurationManagerTests
|
||||
// Serialize to a JSON string
|
||||
string json = ToJson ();
|
||||
|
||||
// Write the JSON string to the file
|
||||
// Write the JSON string to the file
|
||||
File.WriteAllText ("config.json", json);
|
||||
}
|
||||
|
||||
@@ -377,23 +377,23 @@ public class ConfigurationManagerTests
|
||||
Locations = ConfigLocations.All;
|
||||
Reset ();
|
||||
|
||||
Assert.NotEmpty (Settings);
|
||||
Assert.NotEmpty (Settings!);
|
||||
|
||||
// test that all ConfigProperties have our attribute
|
||||
Assert.All (
|
||||
Settings,
|
||||
item => Assert.NotEmpty (
|
||||
item.Value.PropertyInfo.CustomAttributes.Where (
|
||||
a => a.AttributeType == typeof (SerializableConfigurationProperty)
|
||||
)
|
||||
item.Value.PropertyInfo!.CustomAttributes.Where (
|
||||
a => a.AttributeType == typeof (SerializableConfigurationProperty)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
Assert.Empty (
|
||||
Settings.Where (
|
||||
cp => cp.Value.PropertyInfo.GetCustomAttribute (
|
||||
typeof (SerializableConfigurationProperty)
|
||||
)
|
||||
cp => cp.Value.PropertyInfo!.GetCustomAttribute (
|
||||
typeof (SerializableConfigurationProperty)
|
||||
)
|
||||
== null
|
||||
)
|
||||
);
|
||||
@@ -401,12 +401,12 @@ public class ConfigurationManagerTests
|
||||
// Application is a static class
|
||||
PropertyInfo pi = typeof (Application).GetProperty ("QuitKey");
|
||||
Assert.Equal (pi, Settings ["Application.QuitKey"].PropertyInfo);
|
||||
|
||||
|
||||
// FrameView is not a static class and DefaultBorderStyle is Scope.Scheme
|
||||
pi = typeof (FrameView).GetProperty ("DefaultBorderStyle");
|
||||
Assert.False (Settings.ContainsKey ("FrameView.DefaultBorderStyle"));
|
||||
Assert.True (Themes ["Default"].ContainsKey ("FrameView.DefaultBorderStyle"));
|
||||
Assert.True (Themes! ["Default"].ContainsKey ("FrameView.DefaultBorderStyle"));
|
||||
Assert.Equal (pi, Themes! ["Default"] ["FrameView.DefaultBorderStyle"].PropertyInfo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -414,31 +414,31 @@ public class ConfigurationManagerTests
|
||||
{
|
||||
// Color.ColorSchemes is serialized as "ColorSchemes", not "Colors.ColorSchemes"
|
||||
PropertyInfo pi = typeof (Colors).GetProperty ("ColorSchemes");
|
||||
var scp = (SerializableConfigurationProperty)pi.GetCustomAttribute (typeof (SerializableConfigurationProperty));
|
||||
Assert.True (scp.Scope == typeof (ThemeScope));
|
||||
var scp = (SerializableConfigurationProperty)pi!.GetCustomAttribute (typeof (SerializableConfigurationProperty));
|
||||
Assert.True (scp!.Scope == typeof (ThemeScope));
|
||||
Assert.True (scp.OmitClassName);
|
||||
|
||||
Reset ();
|
||||
Assert.Equal (pi, Themes ["Default"] ["ColorSchemes"].PropertyInfo);
|
||||
Assert.Equal (pi, Themes! ["Default"] ["ColorSchemes"].PropertyInfo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown (configLocation: ConfigLocations.DefaultOnly)]
|
||||
public void TestConfigurationManagerInitDriver ()
|
||||
{
|
||||
Assert.Equal ("Default", Themes.Theme);
|
||||
Assert.Equal ("Default", Themes!.Theme);
|
||||
|
||||
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
|
||||
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"]!.Normal.Foreground);
|
||||
Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
|
||||
|
||||
// Change Base
|
||||
Stream json = ToStream ();
|
||||
|
||||
Settings.Update (json, "TestConfigurationManagerInitDriver");
|
||||
Settings!.Update (json, "TestConfigurationManagerInitDriver");
|
||||
|
||||
Dictionary<string, ColorScheme> colorSchemes =
|
||||
(Dictionary<string, ColorScheme>)Themes [Themes.Theme] ["ColorSchemes"].PropertyValue;
|
||||
Assert.Equal (Colors.ColorSchemes ["Base"], colorSchemes ["Base"]);
|
||||
Assert.Equal (Colors.ColorSchemes ["Base"], colorSchemes! ["Base"]);
|
||||
Assert.Equal (Colors.ColorSchemes ["TopLevel"], colorSchemes ["TopLevel"]);
|
||||
Assert.Equal (Colors.ColorSchemes ["Error"], colorSchemes ["Error"]);
|
||||
Assert.Equal (Colors.ColorSchemes ["Dialog"], colorSchemes ["Dialog"]);
|
||||
@@ -489,7 +489,7 @@ public class ConfigurationManagerTests
|
||||
}
|
||||
}";
|
||||
|
||||
Settings.Update (json, "test");
|
||||
Settings!.Update (json, "test");
|
||||
|
||||
// AbNormal is not a ColorScheme attribute
|
||||
json = @"
|
||||
@@ -514,7 +514,7 @@ public class ConfigurationManagerTests
|
||||
|
||||
Settings.Update (json, "test");
|
||||
|
||||
// Modify hotNormal background only
|
||||
// Modify hotNormal background only
|
||||
json = @"
|
||||
{
|
||||
""Themes"" : [
|
||||
@@ -572,7 +572,7 @@ public class ConfigurationManagerTests
|
||||
]
|
||||
}";
|
||||
|
||||
var jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
|
||||
var jsonException = Assert.Throws<JsonException> (() => Settings!.Update (json, "test"));
|
||||
Assert.Equal ("Unexpected color name: brown.", jsonException.Message);
|
||||
|
||||
// AbNormal is not a ColorScheme attribute
|
||||
@@ -596,10 +596,10 @@ public class ConfigurationManagerTests
|
||||
]
|
||||
}";
|
||||
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings!.Update (json, "test"));
|
||||
Assert.Equal ("Unrecognized ColorScheme Attribute name: AbNormal.", jsonException.Message);
|
||||
|
||||
// Modify hotNormal background only
|
||||
// Modify hotNormal background only
|
||||
json = @"
|
||||
{
|
||||
""Themes"" : [
|
||||
@@ -619,7 +619,7 @@ public class ConfigurationManagerTests
|
||||
]
|
||||
}";
|
||||
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings!.Update (json, "test"));
|
||||
Assert.Equal ("Both Foreground and Background colors must be provided.", jsonException.Message);
|
||||
|
||||
// Unknown property
|
||||
@@ -628,7 +628,7 @@ public class ConfigurationManagerTests
|
||||
""Unknown"" : ""Not known""
|
||||
}";
|
||||
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings!.Update (json, "test"));
|
||||
Assert.StartsWith ("Unknown property", jsonException.Message);
|
||||
|
||||
Assert.Equal (0, _jsonErrors.Length);
|
||||
@@ -644,7 +644,7 @@ public class ConfigurationManagerTests
|
||||
GetHardCodedDefaults ();
|
||||
Stream stream = ToStream ();
|
||||
|
||||
Settings.Update (stream, "TestConfigurationManagerToJson");
|
||||
Settings!.Update (stream, "TestConfigurationManagerToJson");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -790,19 +790,19 @@ public class ConfigurationManagerTests
|
||||
Reset ();
|
||||
ThrowOnJsonErrors = true;
|
||||
|
||||
Settings.Update (json, "TestConfigurationManagerUpdateFromJson");
|
||||
Settings!.Update (json, "TestConfigurationManagerUpdateFromJson");
|
||||
|
||||
Assert.Equal (KeyCode.Esc, Application.QuitKey.KeyCode);
|
||||
Assert.Equal (KeyCode.Z | KeyCode.AltMask, ((Key)Settings ["Application.QuitKey"].PropertyValue).KeyCode);
|
||||
Assert.Equal (KeyCode.Z | KeyCode.AltMask, ((Key)Settings ["Application.QuitKey"].PropertyValue)!.KeyCode);
|
||||
|
||||
Assert.Equal ("Default", Themes.Theme);
|
||||
Assert.Equal ("Default", Themes!.Theme);
|
||||
|
||||
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
|
||||
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"]!.Normal.Foreground);
|
||||
Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
|
||||
|
||||
Dictionary<string, ColorScheme> colorSchemes =
|
||||
(Dictionary<string, ColorScheme>)Themes.First ().Value ["ColorSchemes"].PropertyValue;
|
||||
Assert.Equal (new Color (Color.White), colorSchemes ["Base"].Normal.Foreground);
|
||||
Assert.Equal (new Color (Color.White), colorSchemes! ["Base"].Normal.Foreground);
|
||||
Assert.Equal (new Color (Color.Blue), colorSchemes ["Base"].Normal.Background);
|
||||
|
||||
// Now re-apply
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#nullable enable
|
||||
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
public class SerializableConfigurationPropertyTests
|
||||
{
|
||||
[Fact]
|
||||
public void Test_SerializableConfigurationProperty_Types_Added_To_JsonSerializerContext ()
|
||||
{
|
||||
// The assembly containing the types to inspect
|
||||
var assembly = Assembly.GetAssembly (typeof (SourceGenerationContext));
|
||||
|
||||
// Get all types from the assembly
|
||||
var types = assembly!.GetTypes ();
|
||||
|
||||
// Find all properties with the SerializableConfigurationProperty attribute
|
||||
var properties = new List<PropertyInfo> ();
|
||||
foreach (var type in types)
|
||||
{
|
||||
properties.AddRange (type.GetProperties ().Where (p =>
|
||||
p.GetCustomAttributes (typeof (SerializableConfigurationProperty), false).Any ()));
|
||||
}
|
||||
|
||||
// Get the types of the properties
|
||||
var propertyTypes = properties.Select (p => p.PropertyType).Distinct ();
|
||||
|
||||
// Get the types registered in the JsonSerializerContext derived class
|
||||
var contextType = typeof (SourceGenerationContext);
|
||||
var contextTypes = GetRegisteredTypes (contextType);
|
||||
|
||||
// Ensure all property types are included in the JsonSerializerContext derived class
|
||||
IEnumerable<Type> collection = contextTypes as Type [] ?? contextTypes.ToArray ();
|
||||
|
||||
foreach (var type in propertyTypes)
|
||||
{
|
||||
Assert.Contains (type, collection);
|
||||
}
|
||||
|
||||
// Ensure no property has the generic JsonStringEnumConverter<>
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var jsonConverterAttributes = property.GetCustomAttributes (typeof (JsonConverterAttribute), false)
|
||||
.Cast<JsonConverterAttribute> ();
|
||||
|
||||
foreach (var attribute in jsonConverterAttributes)
|
||||
{
|
||||
Assert.False (attribute.ConverterType!.IsGenericType &&
|
||||
attribute.ConverterType.GetGenericTypeDefinition () == typeof (JsonStringEnumConverter<>));
|
||||
}
|
||||
}
|
||||
|
||||
// Find all classes with the JsonConverter attribute of type ScopeJsonConverter<>
|
||||
var classesWithScopeJsonConverter = types.Where (t =>
|
||||
t.GetCustomAttributes (typeof (JsonConverterAttribute), false)
|
||||
.Any (attr => ((JsonConverterAttribute)attr).ConverterType!.IsGenericType &&
|
||||
((JsonConverterAttribute)attr).ConverterType!.GetGenericTypeDefinition () == typeof (ScopeJsonConverter<>)));
|
||||
|
||||
// Ensure all these classes are included in the JsonSerializerContext derived class
|
||||
foreach (var type in classesWithScopeJsonConverter)
|
||||
{
|
||||
Assert.Contains (type, collection);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> GetRegisteredTypes (Type contextType)
|
||||
{
|
||||
// Use reflection to find which types are registered in the JsonSerializerContext
|
||||
var registeredTypes = new List<Type> ();
|
||||
|
||||
var properties = contextType.GetProperties (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||
foreach (var property in properties)
|
||||
{
|
||||
if (property.PropertyType.IsGenericType &&
|
||||
property.PropertyType.GetGenericTypeDefinition () == typeof (JsonTypeInfo<>))
|
||||
{
|
||||
registeredTypes.Add (property.PropertyType.GetGenericArguments () [0]);
|
||||
}
|
||||
}
|
||||
|
||||
return registeredTypes.Distinct ();
|
||||
}
|
||||
}
|
||||
@@ -29,13 +29,18 @@ public class ThemeScopeTests
|
||||
{
|
||||
Reset ();
|
||||
Assert.NotEmpty (Themes);
|
||||
Assert.Equal (Alignment.End, Dialog.DefaultButtonAlignment);
|
||||
Alignment savedValue = Dialog.DefaultButtonAlignment;
|
||||
Alignment newValue = Alignment.Center != savedValue ? Alignment.Center : Alignment.Start;
|
||||
|
||||
Themes ["Default"] ["Dialog.DefaultButtonAlignment"].PropertyValue = Alignment.Center;
|
||||
Themes ["Default"] ["Dialog.DefaultButtonAlignment"].PropertyValue = newValue;
|
||||
|
||||
ThemeManager.Themes! [ThemeManager.SelectedTheme]!.Apply ();
|
||||
Assert.Equal (Alignment.Center, Dialog.DefaultButtonAlignment);
|
||||
Reset ();
|
||||
Assert.Equal (newValue, Dialog.DefaultButtonAlignment);
|
||||
|
||||
// Replace with the savedValue to avoid failures on other unit tests that rely on the default value
|
||||
Themes ["Default"] ["Dialog.DefaultButtonAlignment"].PropertyValue = savedValue;
|
||||
ThemeManager.Themes! [ThemeManager.SelectedTheme]!.Apply ();
|
||||
Assert.Equal (savedValue, Dialog.DefaultButtonAlignment);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -76,6 +76,9 @@ public class ThemeTests
|
||||
[Fact]
|
||||
public void TestSerialize_RoundTrip ()
|
||||
{
|
||||
// This is needed to test only this alone
|
||||
Reset ();
|
||||
|
||||
var theme = new ThemeScope ();
|
||||
theme ["Dialog.DefaultButtonAlignment"].PropertyValue = Alignment.End;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user