Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/Core/ExistForAll.SimpleSettings/BindingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ public BindingContext(string section,
{
if (section == null) throw new ArgumentNullException(nameof(section));
if (key == null) throw new ArgumentNullException(nameof(key));
if (string.Equals(section, null, StringComparison.Ordinal)) throw new ArgumentNullException(nameof(section));
if (string.Equals(key, null, StringComparison.Ordinal)) throw new ArgumentNullException(nameof(key));

Section = section;
Key = key;
SettingsType = settingsType ?? throw new ArgumentNullException(nameof(settingsType));
PropertyInfo = propertyInfo ?? throw new ArgumentNullException(nameof(propertyInfo));
PropertyType = propertyInfo.DeclaringType!;
PropertyType = propertyInfo.PropertyType;
CurrentValue = currentValue;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Globalization;

namespace ExistForAll.SimpleSettings.Conversion
{
Expand All @@ -11,7 +12,7 @@ public bool CanConvert(Type settingsType)

public object Convert(object value, Type settingsType)
{
return System.Convert.ChangeType(value, settingsType);
return System.Convert.ChangeType(value, settingsType, CultureInfo.InvariantCulture);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public TypeConvertersCollections(SettingsOptions settingsOptions)
AddLast(new UriTypeConvertor());
AddLast(new ArrayTypeConverter(settingsOptions, this));
AddLast(new EnumerableTypeConverter(settingsOptions, this));
AddLast(new EnumTypeConverter());
AddLast(new DefaultTypeConverter());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ public void ValidateOptions(SettingsOptions settingsOptions)
throw new SettingsOptionsArgumentNullException();
}

if (!typeof(Attribute).GetTypeInfo().IsAssignableFrom(settingsOptions.AttributeType))
throw new SettingsOptionNonAttributeException(settingsOptions.AttributeType!);
if (settingsOptions.AttributeType != null &&
!typeof(Attribute).GetTypeInfo().IsAssignableFrom(settingsOptions.AttributeType))
throw new SettingsOptionNonAttributeException(settingsOptions.AttributeType);


if (string.IsNullOrWhiteSpace(settingsOptions.ArraySplitDelimiter))
Expand Down
4 changes: 2 additions & 2 deletions src/Core/ExistForAll.SimpleSettings/Resources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public static string PropertyNotAllowNullMessage(string propertyName) =>
$@"[{propertyName}] is marked as Null not allowed, yet the value is null. please provide value via binder or attribute";

public static string TypeIsNotInterface(string typeName) =>
@"[{typeName}] is not an interface, SimpleSettings supports only interfaces";
$@"[{typeName}] is not an interface, SimpleSettings supports only interfaces";

public static string SettingsOptionAttributeTypeMessage(Type type) =>
$"SimpleSettings support Attribute indication of interfaces, the type provided [${type.FullName}] is not an attribute.";
$"SimpleSettings support Attribute indication of interfaces, the type provided [{type.FullName}] is not an attribute.";

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Globalization;
using ExistForAll.SimpleSettings.Binder;

namespace ExistForAll.SimpleSettings.UnitTests.Conversion
{
public class DefaultTypeConverterTests
{
// The default SectionNameFormatter strips the leading "I": INumericSettings -> "NumericSettings".
private const string Section = "NumericSettings";

[Test]
[NotInParallel]
public async Task Build_DoubleFromString_UnderGermanCulture_ParsesInvariant()
{
var original = CultureInfo.CurrentCulture;
try
{
// In de-DE '.' is the group separator, so a culture-sensitive parse of "1.5" yields 15.
CultureInfo.CurrentCulture = new CultureInfo("de-DE");

var settings = BuildWith(nameof(INumericSettings.Value), "1.5")
.GetSettings<INumericSettings>();

await Assert.That(settings.Value).IsEqualTo(1.5d);
}
finally
{
CultureInfo.CurrentCulture = original;
}
}

[Test]
[NotInParallel]
public async Task Build_DecimalFromString_UnderGermanCulture_ParsesInvariant()
{
var original = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = new CultureInfo("de-DE");

var settings = BuildWith(nameof(INumericSettings.Amount), "1234.56")
.GetSettings<INumericSettings>();

await Assert.That(settings.Amount).IsEqualTo(1234.56m);
}
finally
{
CultureInfo.CurrentCulture = original;
}
}

[Test]
public async Task Build_IntFromString_BindsValue()
{
var settings = BuildWith(nameof(INumericSettings.Count), "42")
.GetSettings<INumericSettings>();

await Assert.That(settings.Count).IsEqualTo(42);
}

private static SettingsBuilder BuildWith(string key, string value)
{
var collection = new InMemoryCollection();
collection.Add(Section, key, value);
return SettingsBuilder.CreateBuilder(x => x.AddSectionBinder(new InMemoryBinder(collection)));
}

public interface INumericSettings
{
double Value { get; set; }
decimal Amount { get; set; }
int Count { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using ExistForAll.SimpleSettings.Binder;

namespace ExistForAll.SimpleSettings.UnitTests.Conversion
{
public class EnumConversionTests
{
// The default SectionNameFormatter strips the leading "I": IEnumSettings -> "EnumSettings".
private const string Section = "EnumSettings";

[Test]
public async Task Build_EnumPropertyFromStringValue_BindsEnum()
{
var settings = BuildWith(nameof(IEnumSettings.Day), "Monday")
.GetSettings<IEnumSettings>();

await Assert.That(settings.Day).IsEqualTo(DayOfWeek.Monday);
}

[Test]
public async Task Build_EnumPropertyFromDefaultValue_BindsEnum()
{
// No binder: the value comes from the attribute default and is already the target type,
// so this path works even without the EnumTypeConverter registered — it guards the fix.
var settings = SettingsBuilder.CreateBuilder()
.GetSettings<IEnumWithDefault>();

await Assert.That(settings.Day).IsEqualTo(DayOfWeek.Friday);
}

private static SettingsBuilder BuildWith(string key, string value)
{
var collection = new InMemoryCollection();
collection.Add(Section, key, value);
return SettingsBuilder.CreateBuilder(x => x.AddSectionBinder(new InMemoryBinder(collection)));
}

public interface IEnumSettings
{
DayOfWeek Day { get; set; }
}

public interface IEnumWithDefault
{
[SettingsProperty(DefaultValue = DayOfWeek.Friday)]
DayOfWeek Day { get; set; }
}
}
}
Loading