Skip to content

Commit

Permalink
Code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tig committed Mar 29, 2024
1 parent 57a5737 commit e7a116e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 52 deletions.
8 changes: 4 additions & 4 deletions Terminal.Gui/Configuration/ConfigProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public bool Apply ()
{
if (PropertyInfo?.GetValue (null) is { })
{
PropertyInfo?.SetValue (null, DeepMemberwiseCopy (PropertyValue, PropertyInfo?.GetValue (null)));
PropertyInfo?.SetValue (null, DeepMemberWiseCopy (PropertyValue, PropertyInfo?.GetValue (null)));
}
}
catch (TargetInvocationException tie)
Expand Down Expand Up @@ -82,9 +82,9 @@ public bool Apply ()
/// <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>
Expand Down Expand Up @@ -118,7 +118,7 @@ public static string GetJsonPropertyName (PropertyInfo pi)

if (PropertyValue is { })
{
PropertyValue = DeepMemberwiseCopy (source, PropertyValue);
PropertyValue = DeepMemberWiseCopy (source, PropertyValue);
}
else
{
Expand Down
58 changes: 28 additions & 30 deletions Terminal.Gui/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -82,10 +83,10 @@ public enum ConfigLocations
/// <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,
Expand All @@ -106,10 +107,10 @@ public enum ConfigLocations
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>
Expand Down Expand Up @@ -284,7 +285,7 @@ public static void Load (bool reset = false)
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
Expand All @@ -298,7 +299,7 @@ public static void OnApplied ()
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>
Expand Down Expand Up @@ -330,9 +331,9 @@ public static void Reset ()

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))
Expand All @@ -359,18 +360,15 @@ internal static void AddJsonError (string error)

/// <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)
{
Expand Down Expand Up @@ -410,7 +408,7 @@ internal static void AddJsonError (string error)
if (((IDictionary)destination).Contains (srcKey))
{
((IDictionary)destination) [srcKey] =
DeepMemberwiseCopy (((IDictionary)source) [srcKey], ((IDictionary)destination) [srcKey]);
DeepMemberWiseCopy (((IDictionary)source) [srcKey], ((IDictionary)destination) [srcKey]);
}
else
{
Expand Down Expand Up @@ -442,7 +440,7 @@ where destProp.CanWrite
if (destVal is { })
{
// Recurse
destProp.SetValue (destination, DeepMemberwiseCopy (sourceVal, destVal));
destProp.SetValue (destination, DeepMemberWiseCopy (sourceVal, destVal));
}
else
{
Expand Down Expand Up @@ -482,7 +480,7 @@ internal static void GetHardCodedDefaults ()
throw new InvalidOperationException ("Initialize must be called first.");
}

Settings = new SettingsScope ();
Settings = new ();
ThemeManager.GetHardCodedDefaults ();
AppSettings?.RetrieveValues ();

Expand All @@ -498,7 +496,7 @@ internal static void GetHardCodedDefaults ()
/// </summary>
internal static void Initialize ()
{
_allConfigProperties = new Dictionary<string, ConfigProperty> ();
_allConfigProperties = new ();
_settings = null;

Dictionary<string, Type> classesWithConfigProps = new (StringComparer.InvariantCultureIgnoreCase);
Expand Down Expand Up @@ -553,18 +551,18 @@ from p in enumerable
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."
);
}
}
}
Expand All @@ -580,7 +578,7 @@ from p in enumerable

//_allConfigProperties.ToList ().ForEach (x => Debug.WriteLine ($" Property: {x.Key}"));

AppSettings = new AppScope ();
AppSettings = new ();
}

/// <summary>Creates a JSON document with the configuration specified.</summary>
Expand Down
37 changes: 19 additions & 18 deletions UnitTests/Configuration/ConfigurationMangerTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using System.Text.Json;
using static Terminal.Gui.ConfigurationManager;
#pragma warning disable IDE1006

namespace Terminal.Gui.ConfigurationTests;

Expand Down Expand Up @@ -45,65 +46,65 @@ void ConfigurationManager_Applied (object sender, ConfigurationManagerEventArgs
}

[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) } };
Expand All @@ -112,7 +113,7 @@ public void DeepMemberwiseCopyTest ()
{
{ "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
Expand All @@ -122,7 +123,7 @@ public void DeepMemberwiseCopyTest ()
{
{ "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"]);
Expand All @@ -133,7 +134,7 @@ public void DeepMemberwiseCopyTest ()
{ "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"]);
Expand Down Expand Up @@ -379,7 +380,7 @@ public void TestConfigProperties ()

Assert.NotEmpty (Settings);

// test that all ConfigProperites have our attribute
// test that all ConfigProperties have our attribute
Assert.All (
Settings,
item => Assert.NotEmpty (
Expand Down Expand Up @@ -411,7 +412,7 @@ public void TestConfigProperties ()
[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));
Expand Down Expand Up @@ -624,7 +625,7 @@ public void TestConfigurationManagerInvalidJsonThrows ()
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""
Expand Down

0 comments on commit e7a116e

Please sign in to comment.