Skip to content

Commit

Permalink
Support null and empty values (#412)
Browse files Browse the repository at this point in the history
* Add support for null or empty values

* Add additional test
  • Loading branch information
MisinformedDNA authored Aug 11, 2023
1 parent 3178f13 commit 2d1bcc7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
24 changes: 16 additions & 8 deletions src/SmartEnum/SmartEnum.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices.ComTypes;

namespace Ardalis.SmartEnum
{
Expand Down Expand Up @@ -55,7 +55,7 @@ public abstract class SmartEnum<TEnum, TValue> :
var dictionary = new Dictionary<TValue, TEnum>();
foreach (var item in _enumOptions.Value)
{
if (!dictionary.ContainsKey(item._value))
if (item._value != null && !dictionary.ContainsKey(item._value))
dictionary.Add(item._value, item);
}
return dictionary;
Expand Down Expand Up @@ -90,8 +90,6 @@ protected SmartEnum(string name, TValue value)
{
if (String.IsNullOrEmpty(name))
ThrowHelper.ThrowArgumentNullOrEmptyException(nameof(name));
if (value == null)
ThrowHelper.ThrowArgumentNullException(nameof(value));

_name = name;
_value = value;
Expand Down Expand Up @@ -203,12 +201,22 @@ public static bool TryFromName(string name, bool ignoreCase, out TEnum result)
/// <seealso cref="SmartEnum{TEnum, TValue}.TryFromValue(TValue, out TEnum)"/>
public static TEnum FromValue(TValue value)
{
if (value == null)
ThrowHelper.ThrowArgumentNullException(nameof(value));
TEnum result;

if (!_fromValue.Value.TryGetValue(value, out var result))
if (value != null)
{
if (!_fromValue.Value.TryGetValue(value, out result))
{
ThrowHelper.ThrowValueNotFoundException<TEnum, TValue>(value);
}
}
else
{
ThrowHelper.ThrowValueNotFoundException<TEnum, TValue>(value);
result = _enumOptions.Value.FirstOrDefault(x => x.Value == null);
if (result == null)
{
ThrowHelper.ThrowValueNotFoundException<TEnum, TValue>(value);
}
}
return result;
}
Expand Down
17 changes: 13 additions & 4 deletions test/SmartEnum.UnitTests/SmartEnumStringFromValue.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Ardalis.SmartEnum.UnitTests
namespace Ardalis.SmartEnum.UnitTests
{
using FluentAssertions;
using System;
Expand All @@ -23,10 +23,18 @@ public void ReturnsEnumGivenMatchingValue(string value, TestStringEnum expected)
}

[Fact]
public void ThrowsGivenNonMatchingValue()
public void ReturnsEnumGivenMatchingNullValue()
{
var value = string.Empty;
var result = TestNullableStringEnum.FromValue(null);

result.Should().BeSameAs(TestNullableStringEnum.None);
}

[Theory]
[InlineData("invalid")]
[InlineData(null)]
public void ThrowsGivenNonMatchingValue(string value)
{
Action action = () => TestStringEnum.FromValue(value);

action.Should()
Expand All @@ -38,14 +46,15 @@ public void ThrowsGivenNonMatchingValue()
[Fact]
public void ReturnsDefaultEnumGivenNonMatchingValue()
{
var value = string.Empty;
var value = "invalid";
var defaultEnum = TestStringEnum.One;

var result = TestStringEnum.FromValue(value, defaultEnum);

result.Should().BeSameAs(defaultEnum);
}


[Fact]
public void ReturnsDerivedEnumByValue()
{
Expand Down
12 changes: 11 additions & 1 deletion test/SmartEnum.UnitTests/TestEnum.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;

namespace Ardalis.SmartEnum.UnitTests
{
Expand Down Expand Up @@ -46,12 +46,22 @@ public class TestStringEnum : SmartEnum<TestStringEnum, string>
public static readonly TestStringEnum One = new TestStringEnum(nameof(One), nameof(One));
public static readonly TestStringEnum Two = new TestStringEnum(nameof(Two), nameof(Two));
public static readonly TestStringEnum Three = new TestStringEnum(nameof(Three), nameof(Three));
public static readonly TestStringEnum Empty = new TestStringEnum(nameof(Empty), string.Empty);

protected TestStringEnum(string name, string value) : base(name, value)
{
}
}

public class TestNullableStringEnum : SmartEnum<TestNullableStringEnum, string>
{
public static readonly TestNullableStringEnum None = new TestNullableStringEnum(nameof(None), null);

protected TestNullableStringEnum(string name, string value) : base(name, value)
{
}
}

public class TestBaseEnumWithDerivedValues : SmartEnum<TestBaseEnumWithDerivedValues>
{
protected TestBaseEnumWithDerivedValues(string name, int value) : base(name, value)
Expand Down

0 comments on commit 2d1bcc7

Please sign in to comment.