Skip to content

Commit

Permalink
Honors any attribute with a string Description property - fixes #97
Browse files Browse the repository at this point in the history
  • Loading branch information
MehdiK committed Mar 26, 2014
1 parent fbf238c commit b67c7cf
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 30 deletions.
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ EnumUnderTest.MemberWithoutDescriptionAttribute.Humanize() => "Member without de
EnumUnderTest.MemberWithoutDescriptionAttribute.Humanize().Transform(To.TitleCase) => "Member Without Description Attribute"
```

You are not limited to `DescriptionAttribute` for custom description. Any attribute applied on enum members with a string `Description` field counts.
This is to help with platforms with missing `DescriptionAttribute` and also for using subclasses of the attribute.

Hopefully this will help avoid littering enums with unnecessary attributes!

###<a id="dehumanize-enums">Dehumanize Enums</a>
Expand Down
29 changes: 22 additions & 7 deletions src/Humanizer.Tests/DehumanizeToEnumTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,43 @@ public class DehumanizeToEnumTests
[Fact]
public void ThrowsForNonEnums()
{
Assert.Throws<ArgumentException>(() => EnumTestsResources.CustomDescription.DehumanizeTo<DummyStructWithEnumInterfaces>());
Assert.Throws<ArgumentException>(() => EnumTestsResources.CustomDescription.DehumanizeTo(typeof(DummyStructWithEnumInterfaces)));
Assert.Throws<ArgumentException>(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo<DummyStructWithEnumInterfaces>());
Assert.Throws<ArgumentException>(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo(typeof(DummyStructWithEnumInterfaces)));
}

[Fact]
public void ThrowsForEnumNoMatch()
{
Assert.Throws<NoMatchFoundException>(() => EnumTestsResources.CustomDescription.DehumanizeTo<DummyEnum>());
Assert.Throws<NoMatchFoundException>(() => EnumTestsResources.CustomDescription.DehumanizeTo(typeof(DummyEnum)));
Assert.Throws<NoMatchFoundException>(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo<DummyEnum>());
Assert.Throws<NoMatchFoundException>(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo(typeof(DummyEnum)));
}

[Fact]
public void CanReturnNullForEnumNoMatch()
{
Assert.Null(EnumTestsResources.CustomDescription.DehumanizeTo(typeof(DummyEnum), OnNoMatch.ReturnsNull));
Assert.Null(EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo(typeof(DummyEnum), OnNoMatch.ReturnsNull));
}

[Fact]
public void HonorsDescriptionAttribute()
{
Assert.Equal(EnumUnderTest.MemberWithDescriptionAttribute, EnumTestsResources.CustomDescription.DehumanizeTo<EnumUnderTest>());
Assert.Equal(EnumUnderTest.MemberWithDescriptionAttribute, EnumTestsResources.CustomDescription.DehumanizeTo(typeof(EnumUnderTest)));
Assert.Equal(EnumUnderTest.MemberWithDescriptionAttribute, EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo<EnumUnderTest>());
Assert.Equal(EnumUnderTest.MemberWithDescriptionAttribute, EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo(typeof(EnumUnderTest)));
}

[Fact]
public void HonorsDescriptionAttributeSubclasses()
{
const string calculatedDescription = "Overridden " + EnumTestsResources.MemberWithDescriptionAttributeSubclass;
Assert.Equal(EnumUnderTest.MemberWithDescriptionAttributeSubclass, calculatedDescription.DehumanizeTo<EnumUnderTest>());
Assert.Equal(EnumUnderTest.MemberWithDescriptionAttributeSubclass, calculatedDescription.DehumanizeTo(typeof(EnumUnderTest)));
}

[Fact]
public void HonorsAnyAttributeWithDescriptionStringProperty()
{
Assert.Equal(EnumUnderTest.MemberWithCustomDescriptionAttribute, EnumTestsResources.MemberWithCustomDescriptionAttribute.DehumanizeTo<EnumUnderTest>());
Assert.Equal(EnumUnderTest.MemberWithCustomDescriptionAttribute, EnumTestsResources.MemberWithCustomDescriptionAttribute.DehumanizeTo(typeof(EnumUnderTest)));
}

[Fact]
Expand Down
20 changes: 19 additions & 1 deletion src/Humanizer.Tests/EnumHumanizeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,25 @@ public class EnumHumanizeTests
[Fact]
public void HonorsDescriptionAttribute()
{
Assert.Equal(EnumTestsResources.CustomDescription, EnumUnderTest.MemberWithDescriptionAttribute.Humanize());
Assert.Equal(EnumTestsResources.MemberWithDescriptionAttribute, EnumUnderTest.MemberWithDescriptionAttribute.Humanize());
}

[Fact]
public void HonorsDescriptionAttributeSubclasses()
{
Assert.Equal("Overridden " + EnumTestsResources.MemberWithDescriptionAttributeSubclass, EnumUnderTest.MemberWithDescriptionAttributeSubclass.Humanize());
}

[Fact]
public void HonorsAnyAttributeWithDescriptionStringProperty()
{
Assert.Equal(EnumTestsResources.MemberWithCustomDescriptionAttribute, EnumUnderTest.MemberWithCustomDescriptionAttribute.Humanize());
}

[Fact]
public void OnlyStringDescriptionsApply()
{
Assert.Equal(EnumTestsResources.MemberWithImposterDescriptionAttribute, EnumUnderTest.MemberWithImposterDescriptionAttribute.Humanize());
}

[Fact]
Expand Down
10 changes: 0 additions & 10 deletions src/Humanizer.Tests/EnumTestsResources.cs

This file was deleted.

54 changes: 52 additions & 2 deletions src/Humanizer.Tests/EnumUnderTest.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,62 @@
using System.ComponentModel;
using System;
using System.ComponentModel;

namespace Humanizer.Tests
{
public enum EnumUnderTest
{
[Description(EnumTestsResources.CustomDescription)]
[Description(EnumTestsResources.MemberWithDescriptionAttribute)]
MemberWithDescriptionAttribute,
[DescriptionSubclass(EnumTestsResources.MemberWithDescriptionAttributeSubclass)]
MemberWithDescriptionAttributeSubclass,
[CustomDescription(EnumTestsResources.MemberWithCustomDescriptionAttribute)]
MemberWithCustomDescriptionAttribute,
[ImposterDescription(42)]
MemberWithImposterDescriptionAttribute,
MemberWithoutDescriptionAttribute,
ALLCAPITALS
}

public class EnumTestsResources
{
public const string MemberWithDescriptionAttribute = "Some Description";
public const string MemberWithDescriptionAttributeSubclass = "Description in Description subclass";
public const string MemberWithCustomDescriptionAttribute = "Description in custom Description attribute";
public const string MemberWithImposterDescriptionAttribute = "Member with imposter description attribute";
public const string MemberWithoutDescriptionAttributeSentence = "Member without description attribute";
public const string MemberWithoutDescriptionAttributeTitle = "Member Without Description Attribute";
public const string MemberWithoutDescriptionAttributeLowerCase = "member without description attribute";
}

public class ImposterDescriptionAttribute : Attribute
{
public int Description { get; set; }

public ImposterDescriptionAttribute(int description)
{
Description = description;
}
}

public class CustomDescriptionAttribute : Attribute
{
public string Description { get; set; }

public CustomDescriptionAttribute(string description)
{
Description = description;
}
}

public class DescriptionSubclassAttribute : DescriptionAttribute
{
public DescriptionSubclassAttribute(string description):base(description)
{
}

public override string Description
{
get { return "Overridden " + base.Description; }
}
}
}
1 change: 0 additions & 1 deletion src/Humanizer.Tests/Humanizer.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
<Compile Include="DateHumanizeTests.cs" />
<Compile Include="DehumanizeToEnumTests.cs" />
<Compile Include="EnumHumanizeTests.cs" />
<Compile Include="EnumTestsResources.cs" />
<Compile Include="EnumUnderTest.cs" />
<Compile Include="FluentDate\InTests.cs" />
<Compile Include="FluentDate\OnTests.cs" />
Expand Down
12 changes: 3 additions & 9 deletions src/Humanizer/EnumHumanizeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,9 @@ private static string GetCustomDescription(MemberInfo memberInfo)
foreach (var attr in attrs)
{
var attrType = attr.GetType();
if (attrType.FullName == "System.ComponentModel.DescriptionAttribute")
{
var descriptionProperty = attrType.GetProperties().FirstOrDefault(DescriptionProperty);
if (descriptionProperty != null)
{
//we have a hit
return descriptionProperty.GetValue(attr, null).ToString();
}
}
var descriptionProperty = attrType.GetProperties().FirstOrDefault(DescriptionProperty);
if (descriptionProperty != null)
return descriptionProperty.GetValue(attr, null).ToString();
}

return null;
Expand Down

0 comments on commit b67c7cf

Please sign in to comment.