diff --git a/readme.md b/readme.md index ee54438e1..87946dc57 100644 --- a/readme.md +++ b/readme.md @@ -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` property counts. +This is to help with platforms with missing `DescriptionAttribute` and also for allowing subclasses of the `DescriptionAttribute`. + Hopefully this will help avoid littering enums with unnecessary attributes! ###Dehumanize Enums diff --git a/src/Humanizer.Tests/DehumanizeToEnumTests.cs b/src/Humanizer.Tests/DehumanizeToEnumTests.cs index ddd72ef2b..5faaa7d62 100644 --- a/src/Humanizer.Tests/DehumanizeToEnumTests.cs +++ b/src/Humanizer.Tests/DehumanizeToEnumTests.cs @@ -9,28 +9,43 @@ public class DehumanizeToEnumTests [Fact] public void ThrowsForNonEnums() { - Assert.Throws(() => EnumTestsResources.CustomDescription.DehumanizeTo()); - Assert.Throws(() => EnumTestsResources.CustomDescription.DehumanizeTo(typeof(DummyStructWithEnumInterfaces))); + Assert.Throws(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo()); + Assert.Throws(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo(typeof(DummyStructWithEnumInterfaces))); } [Fact] public void ThrowsForEnumNoMatch() { - Assert.Throws(() => EnumTestsResources.CustomDescription.DehumanizeTo()); - Assert.Throws(() => EnumTestsResources.CustomDescription.DehumanizeTo(typeof(DummyEnum))); + Assert.Throws(() => EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo()); + Assert.Throws(() => 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()); - Assert.Equal(EnumUnderTest.MemberWithDescriptionAttribute, EnumTestsResources.CustomDescription.DehumanizeTo(typeof(EnumUnderTest))); + Assert.Equal(EnumUnderTest.MemberWithDescriptionAttribute, EnumTestsResources.MemberWithDescriptionAttribute.DehumanizeTo()); + 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()); + Assert.Equal(EnumUnderTest.MemberWithDescriptionAttributeSubclass, calculatedDescription.DehumanizeTo(typeof(EnumUnderTest))); + } + + [Fact] + public void HonorsAnyAttributeWithDescriptionStringProperty() + { + Assert.Equal(EnumUnderTest.MemberWithCustomDescriptionAttribute, EnumTestsResources.MemberWithCustomDescriptionAttribute.DehumanizeTo()); + Assert.Equal(EnumUnderTest.MemberWithCustomDescriptionAttribute, EnumTestsResources.MemberWithCustomDescriptionAttribute.DehumanizeTo(typeof(EnumUnderTest))); } [Fact] diff --git a/src/Humanizer.Tests/EnumHumanizeTests.cs b/src/Humanizer.Tests/EnumHumanizeTests.cs index 5fed047bc..c47d7c41b 100644 --- a/src/Humanizer.Tests/EnumHumanizeTests.cs +++ b/src/Humanizer.Tests/EnumHumanizeTests.cs @@ -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] diff --git a/src/Humanizer.Tests/EnumTestsResources.cs b/src/Humanizer.Tests/EnumTestsResources.cs deleted file mode 100644 index ee4d8878c..000000000 --- a/src/Humanizer.Tests/EnumTestsResources.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Humanizer.Tests -{ - public class EnumTestsResources - { - public const string CustomDescription = "Some Description"; - public const string MemberWithoutDescriptionAttributeSentence = "Member without description attribute"; - public const string MemberWithoutDescriptionAttributeTitle = "Member Without Description Attribute"; - public const string MemberWithoutDescriptionAttributeLowerCase = "member without description attribute"; - } -} \ No newline at end of file diff --git a/src/Humanizer.Tests/EnumUnderTest.cs b/src/Humanizer.Tests/EnumUnderTest.cs index f5bf2727d..1d7cd06fd 100644 --- a/src/Humanizer.Tests/EnumUnderTest.cs +++ b/src/Humanizer.Tests/EnumUnderTest.cs @@ -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; } + } + } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index f581b5fae..22f33efcd 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -93,7 +93,6 @@ - diff --git a/src/Humanizer/EnumHumanizeExtensions.cs b/src/Humanizer/EnumHumanizeExtensions.cs index 93ee2d15a..4fd2327ce 100644 --- a/src/Humanizer/EnumHumanizeExtensions.cs +++ b/src/Humanizer/EnumHumanizeExtensions.cs @@ -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;