mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-27 00:07:58 +01:00
* Refactored test namespaces. Moved some tests that were in wrong project. Code cleanup * Parrallel -> Parallel
469 lines
16 KiB
C#
469 lines
16 KiB
C#
#nullable enable
|
|
using System.Collections.Concurrent;
|
|
using System.Reflection;
|
|
using System.Text.Json;
|
|
|
|
namespace UnitTests.ConfigurationTests;
|
|
|
|
public class ConfigPropertyTests
|
|
{
|
|
[Fact]
|
|
public void Apply_PropertyValueIsAppliedToStatic_String_Property ()
|
|
{
|
|
// Arrange
|
|
TestConfiguration.Reset ();
|
|
var propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = "UpdatedValue"
|
|
};
|
|
|
|
// Act
|
|
var result = configProperty.Apply ();
|
|
|
|
// Assert
|
|
Assert.Equal (1, TestConfiguration.TestStringPropertySetCount);
|
|
Assert.True (result);
|
|
Assert.Equal ("UpdatedValue", TestConfiguration.TestStringProperty);
|
|
TestConfiguration.Reset ();
|
|
}
|
|
|
|
[Fact]
|
|
public void Apply_PropertyValueIsAppliedToStatic_Key_Property ()
|
|
{
|
|
// Arrange
|
|
TestConfiguration.Reset ();
|
|
var propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestKeyProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = Key.Q.WithCtrl
|
|
};
|
|
|
|
// Act
|
|
var result = configProperty.Apply ();
|
|
|
|
// Assert
|
|
Assert.Equal (1, TestConfiguration.TestKeyPropertySetCount);
|
|
Assert.True (result);
|
|
Assert.Equal (Key.Q.WithCtrl, TestConfiguration.TestKeyProperty);
|
|
TestConfiguration.Reset ();
|
|
}
|
|
|
|
[Fact]
|
|
public void RetrieveValue_GetsCurrentValueOfStaticProperty ()
|
|
{
|
|
// Arrange
|
|
TestConfiguration.TestStringProperty = "CurrentValue";
|
|
var propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo
|
|
};
|
|
|
|
// Act
|
|
var value = configProperty.UpdateToCurrentValue ();
|
|
|
|
// Assert
|
|
Assert.Equal ("CurrentValue", value);
|
|
Assert.Equal ("CurrentValue", configProperty.PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void DeepCloneFrom_Updates_String_Property_Value ()
|
|
{
|
|
// Arrange
|
|
TestConfiguration.Reset ();
|
|
var propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = "InitialValue"
|
|
};
|
|
|
|
// Act
|
|
var updatedValue = configProperty.UpdateFrom ("NewValue");
|
|
|
|
// Assert
|
|
Assert.Equal (0, TestConfiguration.TestStringPropertySetCount);
|
|
Assert.Equal ("NewValue", updatedValue);
|
|
Assert.Equal ("NewValue", configProperty.PropertyValue);
|
|
TestConfiguration.Reset ();
|
|
}
|
|
|
|
//[Fact]
|
|
//public void UpdateValueFrom_InvalidType_ThrowsArgumentException()
|
|
//{
|
|
// // Arrange
|
|
// var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
// var configProperty = new ConfigProperty
|
|
// {
|
|
// PropertyInfo = propertyInfo
|
|
// };
|
|
|
|
// // Act & Assert
|
|
// Assert.Throws<ArgumentException>(() => configProperty.UpdateValueFrom(123));
|
|
//}
|
|
|
|
[Fact]
|
|
public void Apply_TargetInvocationException_ThrowsJsonException ()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = null // This will cause ArgumentNullException in the set accessor
|
|
};
|
|
|
|
// Act & Assert
|
|
var exception = Assert.Throws<JsonException> (() => configProperty.Apply ());
|
|
}
|
|
|
|
[Fact]
|
|
public void GetJsonPropertyName_ReturnsJsonPropertyNameAttributeValue ()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestStringProperty));
|
|
|
|
// Act
|
|
var jsonPropertyName = ConfigProperty.GetJsonPropertyName (propertyInfo!);
|
|
|
|
// Assert
|
|
Assert.Equal ("TestStringProperty", jsonPropertyName);
|
|
}
|
|
[Fact]
|
|
public void UpdateFrom_NullSource_ReturnsExistingValue()
|
|
{
|
|
// Arrange
|
|
TestConfiguration.TestStringProperty = "CurrentValue";
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = "ExistingValue"
|
|
};
|
|
|
|
// Act
|
|
var result = configProperty.UpdateFrom(null);
|
|
|
|
// Assert
|
|
Assert.Equal("ExistingValue", result);
|
|
Assert.Equal("ExistingValue", configProperty.PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_InvalidType_ThrowsArgumentException()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = "ExistingValue"
|
|
};
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentException>(() => configProperty.UpdateFrom(123));
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_ConfigPropertySource_CopiesValue()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = "ExistingValue"
|
|
};
|
|
|
|
var sourceConfigProperty = new ConfigProperty
|
|
{
|
|
PropertyValue = "SourceValue",
|
|
HasValue = true
|
|
};
|
|
|
|
// Act
|
|
var result = configProperty.UpdateFrom(sourceConfigProperty);
|
|
|
|
// Assert
|
|
Assert.Equal("SourceValue", result);
|
|
Assert.Equal("SourceValue", configProperty.PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_ConfigPropertySource_WithoutValue_KeepsExistingValue()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = "ExistingValue"
|
|
};
|
|
|
|
var sourceConfigProperty = new ConfigProperty
|
|
{
|
|
HasValue = false
|
|
};
|
|
|
|
// Act
|
|
var result = configProperty.UpdateFrom(sourceConfigProperty);
|
|
|
|
// Assert
|
|
Assert.Equal("ExistingValue", result);
|
|
Assert.Equal("ExistingValue", configProperty.PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_ConcurrentDictionaryOfThemeScopes_UpdatesValues()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestDictionaryProperty));
|
|
|
|
// Create a destination dictionary
|
|
var destinationDict = new ConcurrentDictionary<string, ThemeScope>(StringComparer.InvariantCultureIgnoreCase);
|
|
destinationDict.TryAdd("theme1", new ThemeScope());
|
|
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = destinationDict
|
|
};
|
|
|
|
// Create a source dictionary with one matching key and one new key
|
|
var sourceDict = new ConcurrentDictionary<string, ThemeScope>(StringComparer.InvariantCultureIgnoreCase);
|
|
var sourceTheme1 = new ThemeScope();
|
|
var sourceTheme2 = new ThemeScope();
|
|
|
|
// Add a property to sourceTheme1 to verify it gets updated
|
|
var keyProperty = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestKeyProperty));
|
|
if (sourceTheme1.TryAdd("TestKey", new ConfigProperty { PropertyInfo = keyProperty, PropertyValue = Key.A.WithCtrl, HasValue = true }))
|
|
{
|
|
// Successfully added
|
|
}
|
|
|
|
sourceDict.TryAdd("theme1", sourceTheme1);
|
|
sourceDict.TryAdd("theme2", sourceTheme2);
|
|
|
|
// Act
|
|
var result = configProperty.UpdateFrom(sourceDict);
|
|
|
|
// Assert
|
|
var resultDict = result as ConcurrentDictionary<string, ThemeScope>;
|
|
Assert.NotNull(resultDict);
|
|
Assert.Equal(2, resultDict.Count);
|
|
Assert.True(resultDict.ContainsKey("theme1"));
|
|
Assert.True(resultDict.ContainsKey("theme2"));
|
|
|
|
// Verify the theme1 was updated with the property
|
|
Assert.True(resultDict["theme1"].ContainsKey("TestKey"));
|
|
Assert.Equal(Key.A.WithCtrl, resultDict["theme1"]["TestKey"].PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_ConcurrentDictionaryOfConfigProperties_UpdatesValues()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestConfigDictionaryProperty));
|
|
|
|
// Create a destination dictionary
|
|
var destinationDict = new ConcurrentDictionary<string, ConfigProperty>(StringComparer.InvariantCultureIgnoreCase);
|
|
destinationDict.TryAdd("prop1", new ConfigProperty { PropertyValue = "Original", HasValue = true });
|
|
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = destinationDict
|
|
};
|
|
|
|
// Create a source dictionary with one matching key and one new key
|
|
var sourceDict = new ConcurrentDictionary<string, ConfigProperty>(StringComparer.InvariantCultureIgnoreCase);
|
|
sourceDict.TryAdd("prop1", new ConfigProperty { PropertyValue = "Updated", HasValue = true });
|
|
sourceDict.TryAdd("prop2", new ConfigProperty { PropertyValue = "New", HasValue = true });
|
|
|
|
// Act
|
|
var result = configProperty.UpdateFrom(sourceDict);
|
|
|
|
// Assert
|
|
var resultDict = result as ConcurrentDictionary<string, ConfigProperty>;
|
|
Assert.NotNull(resultDict);
|
|
Assert.Equal(2, resultDict.Count);
|
|
Assert.True(resultDict.ContainsKey("prop1"));
|
|
Assert.True(resultDict.ContainsKey("prop2"));
|
|
Assert.Equal("Updated", resultDict["prop1"].PropertyValue);
|
|
Assert.Equal("New", resultDict["prop2"].PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_DictionaryOfConfigProperties_UpdatesValues()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestConfigDictionaryProperty));
|
|
|
|
// Create a destination dictionary
|
|
var destinationDict = new Dictionary<string, ConfigProperty>(StringComparer.InvariantCultureIgnoreCase);
|
|
destinationDict.Add("prop1", new ConfigProperty { PropertyValue = "Original", HasValue = true });
|
|
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
PropertyValue = destinationDict
|
|
};
|
|
|
|
// Create a source dictionary with one matching key and one new key
|
|
var sourceDict = new Dictionary<string, ConfigProperty>(StringComparer.InvariantCultureIgnoreCase);
|
|
sourceDict.Add("prop1", new ConfigProperty { PropertyValue = "Updated", HasValue = true });
|
|
sourceDict.Add("prop2", new ConfigProperty { PropertyValue = "New", HasValue = true });
|
|
|
|
// Act
|
|
var result = configProperty.UpdateFrom(sourceDict);
|
|
|
|
// Assert
|
|
var resultDict = result as Dictionary<string, ConfigProperty>;
|
|
Assert.NotNull(resultDict);
|
|
Assert.Equal(2, resultDict.Count);
|
|
Assert.True(resultDict.ContainsKey("prop1"));
|
|
Assert.True(resultDict.ContainsKey("prop2"));
|
|
Assert.Equal("Updated", resultDict["prop1"].PropertyValue);
|
|
Assert.Equal("New", resultDict["prop2"].PropertyValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void PropertyValue_SetWhenImmutable_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo,
|
|
Immutable = true
|
|
};
|
|
|
|
// Act & Assert
|
|
var exception = Assert.Throws<InvalidOperationException>(() => configProperty.PropertyValue = "New Value");
|
|
Assert.Contains("immutable", exception.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateWithAttributeInfo_ReturnsConfigPropertyWithCorrectValues()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
|
|
// Act
|
|
var configProperty = ConfigProperty.CreateImmutableWithAttributeInfo(propertyInfo!);
|
|
|
|
// Assert
|
|
Assert.Equal(propertyInfo, configProperty.PropertyInfo);
|
|
Assert.False(configProperty.OmitClassName);
|
|
Assert.True(configProperty.Immutable);
|
|
Assert.Null(configProperty.PropertyValue);
|
|
Assert.False(configProperty.HasValue);
|
|
}
|
|
|
|
[Fact]
|
|
public void HasConfigurationPropertyAttribute_ReturnsTrue_ForDecoratedProperty()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringProperty));
|
|
|
|
// Act
|
|
var result = ConfigProperty.HasConfigurationPropertyAttribute(propertyInfo!);
|
|
|
|
// Assert
|
|
Assert.True(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void HasConfigurationPropertyAttribute_ReturnsFalse_ForNonDecoratedProperty()
|
|
{
|
|
// Arrange
|
|
var propertyInfo = typeof(TestConfiguration).GetProperty(nameof(TestConfiguration.TestStringPropertySetCount));
|
|
|
|
// Act
|
|
var result = ConfigProperty.HasConfigurationPropertyAttribute(propertyInfo!);
|
|
|
|
// Assert
|
|
Assert.False(result);
|
|
}
|
|
public class TestConfiguration
|
|
{
|
|
private static string _testStringProperty = "Default";
|
|
public static int TestStringPropertySetCount { get; set; }
|
|
|
|
[ConfigurationProperty]
|
|
public static string TestStringProperty
|
|
{
|
|
get => _testStringProperty;
|
|
set
|
|
{
|
|
TestStringPropertySetCount++;
|
|
_testStringProperty = value ?? throw new ArgumentNullException (nameof (value));
|
|
}
|
|
}
|
|
|
|
private static Key _testKeyProperty = Key.Esc;
|
|
public static int TestKeyPropertySetCount { get; set; }
|
|
|
|
[ConfigurationProperty]
|
|
public static Key TestKeyProperty
|
|
{
|
|
get => _testKeyProperty;
|
|
set
|
|
{
|
|
TestKeyPropertySetCount++;
|
|
_testKeyProperty = value ?? throw new ArgumentNullException (nameof (value));
|
|
}
|
|
}
|
|
|
|
// Add these new properties for testing dictionaries
|
|
[ConfigurationProperty]
|
|
public static ConcurrentDictionary<string, ThemeScope>? TestDictionaryProperty { get; set; }
|
|
|
|
[ConfigurationProperty]
|
|
public static Dictionary<string, ConfigProperty>? TestRegularDictionaryProperty { get; set; }
|
|
|
|
[ConfigurationProperty]
|
|
public static ConcurrentDictionary<string, ConfigProperty>? TestConfigDictionaryProperty { get; set; }
|
|
|
|
[ConfigurationProperty]
|
|
public static Scheme? TestSchemeProperty { get; set; }
|
|
|
|
|
|
public static void Reset ()
|
|
{
|
|
TestStringPropertySetCount = 0;
|
|
TestKeyPropertySetCount = 0;
|
|
TestDictionaryProperty = null;
|
|
TestRegularDictionaryProperty = null;
|
|
TestConfigDictionaryProperty = null;
|
|
TestSchemeProperty = null;
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void UpdateFrom_SchemeSource_UpdatesValue ()
|
|
{
|
|
// Arrange
|
|
PropertyInfo? propertyInfo = typeof (TestConfiguration).GetProperty (nameof (TestConfiguration.TestSchemeProperty));
|
|
Scheme sourceScheme = new (new Attribute (Color.Red, Color.Blue, TextStyle.Bold));
|
|
|
|
var configProperty = new ConfigProperty
|
|
{
|
|
PropertyInfo = propertyInfo!,
|
|
PropertyValue = new Scheme (new Attribute (Color.White, Color.Black, TextStyle.None))
|
|
};
|
|
|
|
// Act
|
|
object? result = configProperty.UpdateFrom (sourceScheme);
|
|
|
|
// Assert
|
|
Assert.Equal (sourceScheme, result);
|
|
Assert.Equal (sourceScheme, configProperty.PropertyValue);
|
|
Assert.NotSame (sourceScheme, configProperty.PropertyValue); // Prove it's a clone, not a ref
|
|
}
|
|
}
|