Skip to content

Commit c139108

Browse files
committed
Added check for duplicate keys and a few unit tests
1 parent d62a497 commit c139108

File tree

5 files changed

+76
-15
lines changed

5 files changed

+76
-15
lines changed

src/Thinktecture.Runtime.Extensions/Enum.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,23 +116,34 @@ private static Dictionary<TKey, TEnum> GetItems()
116116
if (fields.Any())
117117
fields.First().GetValue(null);
118118

119-
return fields.Where(f => f.FieldType == _type)
120-
.Select(f =>
121-
{
122-
if (!f.IsInitOnly)
123-
throw new Exception($"The field \"{f.Name}\" of enumeration type \"{_type.FullName}\" must be read-only.");
119+
var items = fields.Where(f => f.FieldType == _type)
120+
.Select(f =>
121+
{
122+
if (!f.IsInitOnly)
123+
throw new Exception($"The field \"{f.Name}\" of enumeration type \"{_type.FullName}\" must be read-only.");
124124

125-
var item = (TEnum)f.GetValue(null);
125+
var item = (TEnum)f.GetValue(null);
126126

127-
if (item == null)
128-
throw new Exception($"The field \"{f.Name}\" of enumeration type \"{_type.FullName}\" is not initialized.");
127+
if (item == null)
128+
throw new Exception($"The field \"{f.Name}\" of enumeration type \"{_type.FullName}\" is not initialized.");
129129

130-
if (!item.IsValid)
131-
throw new Exception($"The field \"{f.Name}\" of enumeration type \"{_type.FullName}\" is not valid.");
130+
if (!item.IsValid)
131+
throw new Exception($"The field \"{f.Name}\" of enumeration type \"{_type.FullName}\" is not valid.");
132132

133-
return item;
134-
})
135-
.ToDictionary(i => i.Key, KeyEqualityComparer);
133+
return item;
134+
});
135+
136+
var lookup = new Dictionary<TKey, TEnum>(KeyEqualityComparer);
137+
138+
foreach (var item in items)
139+
{
140+
if (lookup.ContainsKey(item.Key))
141+
throw new ArgumentException($"The enumeration of type \"{_type.FullName}\" has multiple items with the key \"{item.Key}\".");
142+
143+
lookup.Add(item.Key, item);
144+
}
145+
146+
return lookup;
136147
}
137148

138149
/// <summary>

test/Thinktecture.Runtime.Extensions.Tests/EnumTests/Equals.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void Should_return_false_if_item_is_null()
1616
public void Should_return_false_if_item_is_of_different_type()
1717
{
1818
// ReSharper disable once SuspiciousTypeConversion.Global
19-
TestEnum.Item1.Equals(TestEnumWithNonDefaultComparer.Item1).Should().BeFalse();
19+
TestEnum.Item1.Equals(TestEnumWithNonDefaultComparer.Item).Should().BeFalse();
2020
}
2121

2222
[Fact]
@@ -36,5 +36,11 @@ public void Should_return_false_if_both_items_are_invalid_and_have_different_key
3636
{
3737
TestEnum.Get("unknown").Equals(TestEnum.Get("other")).Should().BeFalse();
3838
}
39+
40+
[Fact]
41+
public void Should_return_false_if_both_items_are_invalid_and_have_keys_that_differ_in_casing_if_comparer_honors_casing()
42+
{
43+
TestEnumWithNonDefaultComparer.Get("Item").Equals(TestEnumWithNonDefaultComparer.Get("item")).Should().BeFalse();
44+
}
3945
}
4046
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using FluentAssertions;
3+
using Thinktecture.TestEnums;
4+
using Xunit;
5+
6+
namespace Thinktecture.EnumTests
7+
{
8+
public class Initialization
9+
{
10+
[Fact]
11+
public void Should_throw_if_enum_has_duplicate_key()
12+
{
13+
Action action = () => EnumWithDuplicateKey.GetAll();
14+
action.Should().Throw<ArgumentException>()
15+
.WithMessage($"The enumeration of type \"{typeof(EnumWithDuplicateKey).FullName}\" has multiple items with the key \"item\".");
16+
}
17+
18+
[Fact]
19+
public void Should_not_throw_if_enum_has_2_keys_that_differs_in_casing_only_if_comparer_honors_casing()
20+
{
21+
Action action = () => TestEnumWithNonDefaultComparer.GetAll();
22+
action.Should().NotThrow<Exception>();
23+
}
24+
}
25+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Thinktecture.TestEnums
2+
{
3+
public class EnumWithDuplicateKey : Enum<EnumWithDuplicateKey>
4+
{
5+
public static readonly EnumWithDuplicateKey Item = new EnumWithDuplicateKey("Item");
6+
public static readonly EnumWithDuplicateKey Duplicate = new EnumWithDuplicateKey("item");
7+
8+
public EnumWithDuplicateKey(string key)
9+
: base(key)
10+
{
11+
}
12+
13+
protected override EnumWithDuplicateKey CreateInvalid(string key)
14+
{
15+
return new EnumWithDuplicateKey(key);
16+
}
17+
}
18+
}

test/Thinktecture.Runtime.Extensions.Tests/TestEnums/TestEnumWithNonDefaultComparer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ namespace Thinktecture.TestEnums
44
{
55
public class TestEnumWithNonDefaultComparer : Enum<TestEnumWithNonDefaultComparer>
66
{
7-
public static readonly TestEnumWithNonDefaultComparer Item1 = new TestEnumWithNonDefaultComparer("item1");
7+
public static readonly TestEnumWithNonDefaultComparer Item = new TestEnumWithNonDefaultComparer("item");
8+
public static readonly TestEnumWithNonDefaultComparer AnotherItem = new TestEnumWithNonDefaultComparer("Item");
89

910
static TestEnumWithNonDefaultComparer()
1011
{

0 commit comments

Comments
 (0)