mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-27 00:07:58 +01:00
Code cleanup
This commit is contained in:
@@ -41,7 +41,7 @@ public class ConfigProperty
|
||||
{
|
||||
if (PropertyInfo?.GetValue (null) is { })
|
||||
{
|
||||
PropertyInfo?.SetValue (null, DeepMemberwiseCopy (PropertyValue, PropertyInfo?.GetValue (null)));
|
||||
PropertyInfo?.SetValue (null, DeepMemberWiseCopy (PropertyValue, PropertyInfo?.GetValue (null)));
|
||||
}
|
||||
}
|
||||
catch (TargetInvocationException tie)
|
||||
@@ -82,9 +82,9 @@ public class ConfigProperty
|
||||
/// <returns></returns>
|
||||
public static string GetJsonPropertyName (PropertyInfo pi)
|
||||
{
|
||||
var jpna = pi.GetCustomAttribute (typeof (JsonPropertyNameAttribute)) as JsonPropertyNameAttribute;
|
||||
var attr = pi.GetCustomAttribute (typeof (JsonPropertyNameAttribute)) as JsonPropertyNameAttribute;
|
||||
|
||||
return jpna?.Name ?? pi.Name;
|
||||
return attr?.Name ?? pi.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -118,7 +118,7 @@ public class ConfigProperty
|
||||
|
||||
if (PropertyValue is { })
|
||||
{
|
||||
PropertyValue = DeepMemberwiseCopy (source, PropertyValue);
|
||||
PropertyValue = DeepMemberWiseCopy (source, PropertyValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
global using CM = Terminal.Gui.ConfigurationManager;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
@@ -33,19 +34,19 @@ namespace Terminal.Gui;
|
||||
/// Settings are applied using the following precedence (higher precedence settings overwrite lower precedence
|
||||
/// settings):
|
||||
/// <para>
|
||||
/// 1. Application configuration found in the users's home directory (<c>~/.tui/appname.config.json</c>) --
|
||||
/// 1. Application configuration found in the users' home directory (<c>~/.tui/appname.config.json</c>) --
|
||||
/// Highest precedence
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// 2. Application configuration found in the directory the app was launched from (
|
||||
/// <c>./.tui/appname.config.json</c>).
|
||||
/// </para>
|
||||
/// <para>3. Application configuration found in the applications's resources (<c>Resources/config.json</c>).</para>
|
||||
/// <para>3. Application configuration found in the applications' resources (<c>Resources/config.json</c>).</para>
|
||||
/// <para>4. Global configuration found in the user's home directory (<c>~/.tui/config.json</c>).</para>
|
||||
/// <para>5. Global configuration found in the directory the app was launched from (<c>./.tui/config.json</c>).</para>
|
||||
/// <para>
|
||||
/// 6. Global configuration in <c>Terminal.Gui.dll</c>'s resources (<c>Terminal.Gui.Resources.config.json</c>) --
|
||||
/// Lowest Precidence.
|
||||
/// Lowest Precedence.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static class ConfigurationManager
|
||||
@@ -82,10 +83,10 @@ public static class ConfigurationManager
|
||||
/// <see cref="ConfigurationManager"/> to get and set the property's value.
|
||||
/// </summary>
|
||||
/// <remarks>Is <see langword="null"/> until <see cref="Initialize"/> is called.</remarks>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
internal static Dictionary<string, ConfigProperty>? _allConfigProperties;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
internal static readonly JsonSerializerOptions _serializerOptions = new ()
|
||||
{
|
||||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
@@ -106,10 +107,10 @@ public static class ConfigurationManager
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
internal static StringBuilder _jsonErrors = new ();
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
|
||||
private static readonly string _configFilename = "config.json";
|
||||
|
||||
/// <summary>The backing property for <see cref="Settings"/>.</summary>
|
||||
@@ -284,7 +285,7 @@ public static class ConfigurationManager
|
||||
public static void OnApplied ()
|
||||
{
|
||||
Debug.WriteLine ("ConfigurationManager.OnApplied()");
|
||||
Applied?.Invoke (null, new ConfigurationManagerEventArgs ());
|
||||
Applied?.Invoke (null, new ());
|
||||
|
||||
// TODO: Refactor ConfigurationManager to not use an event handler for this.
|
||||
// Instead, have it call a method on any class appropriately attributed
|
||||
@@ -298,7 +299,7 @@ public static class ConfigurationManager
|
||||
public static void OnUpdated ()
|
||||
{
|
||||
Debug.WriteLine (@"ConfigurationManager.OnApplied()");
|
||||
Updated?.Invoke (null, new ConfigurationManagerEventArgs ());
|
||||
Updated?.Invoke (null, new ());
|
||||
}
|
||||
|
||||
/// <summary>Prints any Json deserialization errors that occurred during deserialization to the console.</summary>
|
||||
@@ -330,9 +331,9 @@ public static class ConfigurationManager
|
||||
|
||||
ClearJsonErrors ();
|
||||
|
||||
Settings = new SettingsScope ();
|
||||
Settings = new ();
|
||||
ThemeManager.Reset ();
|
||||
AppSettings = new AppScope ();
|
||||
AppSettings = new ();
|
||||
|
||||
// To enable some unit tests, we only load from resources if the flag is set
|
||||
if (Locations.HasFlag (ConfigLocations.DefaultOnly))
|
||||
@@ -359,18 +360,15 @@ public static class ConfigurationManager
|
||||
|
||||
/// <summary>
|
||||
/// System.Text.Json does not support copying a deserialized object to an existing instance. To work around this,
|
||||
/// we implement a 'deep, memberwise copy' method.
|
||||
/// we implement a 'deep, member-wise copy' method.
|
||||
/// </summary>
|
||||
/// <remarks>TOOD: When System.Text.Json implements `PopulateObject` revisit https://github.com/dotnet/corefx/issues/37627</remarks>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="destination"></param>
|
||||
/// <returns><paramref name="destination"/> updated from <paramref name="source"/></returns>
|
||||
internal static object? DeepMemberwiseCopy (object? source, object? destination)
|
||||
internal static object? DeepMemberWiseCopy (object? source, object? destination)
|
||||
{
|
||||
if (destination is null)
|
||||
{
|
||||
throw new ArgumentNullException (nameof (destination));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull (destination);
|
||||
|
||||
if (source is null)
|
||||
{
|
||||
@@ -410,7 +408,7 @@ public static class ConfigurationManager
|
||||
if (((IDictionary)destination).Contains (srcKey))
|
||||
{
|
||||
((IDictionary)destination) [srcKey] =
|
||||
DeepMemberwiseCopy (((IDictionary)source) [srcKey], ((IDictionary)destination) [srcKey]);
|
||||
DeepMemberWiseCopy (((IDictionary)source) [srcKey], ((IDictionary)destination) [srcKey]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -442,7 +440,7 @@ public static class ConfigurationManager
|
||||
if (destVal is { })
|
||||
{
|
||||
// Recurse
|
||||
destProp.SetValue (destination, DeepMemberwiseCopy (sourceVal, destVal));
|
||||
destProp.SetValue (destination, DeepMemberWiseCopy (sourceVal, destVal));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -482,7 +480,7 @@ public static class ConfigurationManager
|
||||
throw new InvalidOperationException ("Initialize must be called first.");
|
||||
}
|
||||
|
||||
Settings = new SettingsScope ();
|
||||
Settings = new ();
|
||||
ThemeManager.GetHardCodedDefaults ();
|
||||
AppSettings?.RetrieveValues ();
|
||||
|
||||
@@ -498,7 +496,7 @@ public static class ConfigurationManager
|
||||
/// </summary>
|
||||
internal static void Initialize ()
|
||||
{
|
||||
_allConfigProperties = new Dictionary<string, ConfigProperty> ();
|
||||
_allConfigProperties = new ();
|
||||
_settings = null;
|
||||
|
||||
Dictionary<string, Type> classesWithConfigProps = new (StringComparer.InvariantCultureIgnoreCase);
|
||||
@@ -553,18 +551,18 @@ public static class ConfigurationManager
|
||||
scp.OmitClassName
|
||||
? ConfigProperty.GetJsonPropertyName (p)
|
||||
: $"{p.DeclaringType?.Name}.{p.Name}",
|
||||
new ConfigProperty { PropertyInfo = p, PropertyValue = null }
|
||||
new() { PropertyInfo = p, PropertyValue = null }
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception (
|
||||
$"Property {
|
||||
p.Name
|
||||
} in class {
|
||||
p.DeclaringType?.Name
|
||||
} is not static. All SerializableConfigurationProperty properties must be static."
|
||||
);
|
||||
throw new (
|
||||
$"Property {
|
||||
p.Name
|
||||
} in class {
|
||||
p.DeclaringType?.Name
|
||||
} is not static. All SerializableConfigurationProperty properties must be static."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,7 +578,7 @@ public static class ConfigurationManager
|
||||
|
||||
//_allConfigProperties.ToList ().ForEach (x => Debug.WriteLine ($" Property: {x.Key}"));
|
||||
|
||||
AppSettings = new AppScope ();
|
||||
AppSettings = new ();
|
||||
}
|
||||
|
||||
/// <summary>Creates a JSON document with the configuration specified.</summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using static Terminal.Gui.ConfigurationManager;
|
||||
#pragma warning disable IDE1006
|
||||
|
||||
namespace Terminal.Gui.ConfigurationTests;
|
||||
|
||||
@@ -45,65 +46,65 @@ public class ConfigurationManagerTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeepMemberwiseCopyTest ()
|
||||
public void DeepMemberWiseCopyTest ()
|
||||
{
|
||||
// Value types
|
||||
var stringDest = "Destination";
|
||||
var stringSrc = "Source";
|
||||
object stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
|
||||
object stringCopy = DeepMemberWiseCopy (stringSrc, stringDest);
|
||||
Assert.Equal (stringSrc, stringCopy);
|
||||
|
||||
stringDest = "Destination";
|
||||
stringSrc = "Destination";
|
||||
stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
|
||||
stringCopy = DeepMemberWiseCopy (stringSrc, stringDest);
|
||||
Assert.Equal (stringSrc, stringCopy);
|
||||
|
||||
stringDest = "Destination";
|
||||
stringSrc = null;
|
||||
stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
|
||||
stringCopy = DeepMemberWiseCopy (stringSrc, stringDest);
|
||||
Assert.Equal (stringSrc, stringCopy);
|
||||
|
||||
stringDest = "Destination";
|
||||
stringSrc = string.Empty;
|
||||
stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
|
||||
stringCopy = DeepMemberWiseCopy (stringSrc, stringDest);
|
||||
Assert.Equal (stringSrc, stringCopy);
|
||||
|
||||
var boolDest = true;
|
||||
var boolSrc = false;
|
||||
object boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
|
||||
object boolCopy = DeepMemberWiseCopy (boolSrc, boolDest);
|
||||
Assert.Equal (boolSrc, boolCopy);
|
||||
|
||||
boolDest = false;
|
||||
boolSrc = true;
|
||||
boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
|
||||
boolCopy = DeepMemberWiseCopy (boolSrc, boolDest);
|
||||
Assert.Equal (boolSrc, boolCopy);
|
||||
|
||||
boolDest = true;
|
||||
boolSrc = true;
|
||||
boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
|
||||
boolCopy = DeepMemberWiseCopy (boolSrc, boolDest);
|
||||
Assert.Equal (boolSrc, boolCopy);
|
||||
|
||||
boolDest = false;
|
||||
boolSrc = false;
|
||||
boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
|
||||
boolCopy = DeepMemberWiseCopy (boolSrc, boolDest);
|
||||
Assert.Equal (boolSrc, boolCopy);
|
||||
|
||||
// Structs
|
||||
var attrDest = new Attribute (Color.Black);
|
||||
var attrSrc = new Attribute (Color.White);
|
||||
object attrCopy = DeepMemberwiseCopy (attrSrc, attrDest);
|
||||
object attrCopy = DeepMemberWiseCopy (attrSrc, attrDest);
|
||||
Assert.Equal (attrSrc, attrCopy);
|
||||
|
||||
// Classes
|
||||
var colorschemeDest = new ColorScheme { Disabled = new Attribute (Color.Black) };
|
||||
var colorschemeSrc = new ColorScheme { Disabled = new Attribute (Color.White) };
|
||||
object colorschemeCopy = DeepMemberwiseCopy (colorschemeSrc, colorschemeDest);
|
||||
object colorschemeCopy = DeepMemberWiseCopy (colorschemeSrc, colorschemeDest);
|
||||
Assert.Equal (colorschemeSrc, colorschemeCopy);
|
||||
|
||||
// Dictionaries
|
||||
Dictionary<string, Attribute> dictDest = new () { { "Disabled", new Attribute (Color.Black) } };
|
||||
Dictionary<string, Attribute> dictSrc = new () { { "Disabled", new Attribute (Color.White) } };
|
||||
Dictionary<string, Attribute> dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
|
||||
Dictionary<string, Attribute> dictCopy = (Dictionary<string, Attribute>)DeepMemberWiseCopy (dictSrc, dictDest);
|
||||
Assert.Equal (dictSrc, dictCopy);
|
||||
|
||||
dictDest = new Dictionary<string, Attribute> { { "Disabled", new Attribute (Color.Black) } };
|
||||
@@ -112,7 +113,7 @@ public class ConfigurationManagerTests
|
||||
{
|
||||
{ "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) }
|
||||
};
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberWiseCopy (dictSrc, dictDest);
|
||||
Assert.Equal (dictSrc, dictCopy);
|
||||
|
||||
// src adds an item
|
||||
@@ -122,7 +123,7 @@ public class ConfigurationManagerTests
|
||||
{
|
||||
{ "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) }
|
||||
};
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberWiseCopy (dictSrc, dictDest);
|
||||
Assert.Equal (2, dictCopy.Count);
|
||||
Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
|
||||
Assert.Equal (dictSrc ["Normal"], dictCopy ["Normal"]);
|
||||
@@ -133,7 +134,7 @@ public class ConfigurationManagerTests
|
||||
{ "Disabled", new Attribute (Color.Black) }, { "Normal", new Attribute (Color.White) }
|
||||
};
|
||||
dictSrc = new Dictionary<string, Attribute> { { "Disabled", new Attribute (Color.White) } };
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
|
||||
dictCopy = (Dictionary<string, Attribute>)DeepMemberWiseCopy (dictSrc, dictDest);
|
||||
Assert.Equal (2, dictCopy.Count);
|
||||
Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
|
||||
Assert.Equal (dictDest ["Normal"], dictCopy ["Normal"]);
|
||||
@@ -379,7 +380,7 @@ public class ConfigurationManagerTests
|
||||
|
||||
Assert.NotEmpty (Settings);
|
||||
|
||||
// test that all ConfigProperites have our attribute
|
||||
// test that all ConfigProperties have our attribute
|
||||
Assert.All (
|
||||
Settings,
|
||||
item => Assert.NotEmpty (
|
||||
@@ -411,7 +412,7 @@ public class ConfigurationManagerTests
|
||||
[Fact]
|
||||
public void TestConfigPropertyOmitClassName ()
|
||||
{
|
||||
// Color.ColorShemes is serialzied as "ColorSchemes", not "Colors.ColorSchemes"
|
||||
// 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));
|
||||
@@ -624,7 +625,7 @@ public class ConfigurationManagerTests
|
||||
jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
|
||||
Assert.Equal ("Both Foreground and Background colors must be provided.", jsonException.Message);
|
||||
|
||||
// Unknown proeprty
|
||||
// Unknown property
|
||||
json = @"
|
||||
{
|
||||
""Unknown"" : ""Not known""
|
||||
|
||||
Reference in New Issue
Block a user