diff --git a/source/Ocl/Converters/EnumAttributeOclConverter.cs b/source/Ocl/Converters/EnumAttributeOclConverter.cs index 4b49009..ed186ad 100644 --- a/source/Ocl/Converters/EnumAttributeOclConverter.cs +++ b/source/Ocl/Converters/EnumAttributeOclConverter.cs @@ -33,7 +33,22 @@ public OclDocument ToDocument(OclConversionContext context, object obj) public IEnumerable ToElements(OclConversionContext context, PropertyInfo? propertyInfo, object obj) { - var isDefault = Activator.CreateInstance(obj.GetType()).Equals(obj); + var isDefault = false; + var defaultValueAttributeType = typeof(OclDefaultEnumValueAttribute); + var defaultValueAttribute = propertyInfo?.GetCustomAttribute(defaultValueAttributeType); + + if (defaultValueAttribute != null) + { + var defaultValueProperty = defaultValueAttributeType.GetProperty("DefaultValue"); + var defaultValue = defaultValueProperty?.GetValue(defaultValueAttribute); + + isDefault = Equals(obj, defaultValue); + } + else + { + isDefault = Activator.CreateInstance(obj.GetType()).Equals(obj); + } + if (!isDefault) yield return new OclAttribute(context.Namer.GetName(propertyInfo!), obj.ToString()); } diff --git a/source/Ocl/Converters/OclEnumDefaultValueAttribute.cs b/source/Ocl/Converters/OclEnumDefaultValueAttribute.cs new file mode 100644 index 0000000..ec0c28a --- /dev/null +++ b/source/Ocl/Converters/OclEnumDefaultValueAttribute.cs @@ -0,0 +1,20 @@ +using System; + +namespace Octopus.Ocl.Converters +{ + [AttributeUsage(AttributeTargets.Property)] + public class OclDefaultEnumValueAttribute : Attribute + { + public OclDefaultEnumValueAttribute(object defaultValue) + { + if (!(defaultValue is Enum)) + { + throw new ArgumentException("defaultValue must be an enum", nameof(defaultValue)); + } + + DefaultValue = defaultValue; + } + + public object DefaultValue { get; } + } +} \ No newline at end of file diff --git a/source/Tests/Converters/EnumAttributeConverterFixture.cs b/source/Tests/Converters/EnumAttributeConverterFixture.cs new file mode 100644 index 0000000..a83d6bf --- /dev/null +++ b/source/Tests/Converters/EnumAttributeConverterFixture.cs @@ -0,0 +1,83 @@ +using System; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using Octopus.Ocl; +using Octopus.Ocl.Converters; + +namespace Tests.Converters +{ + internal class EnumAttributeConverterFixture + { + [Test] + public void WhenConvertingEnum_ValueIsEnumDefault_ReturnsNull() + { + var context = new OclConversionContext(new OclSerializerOptions()); + + var result = (OclAttribute?)new EnumAttributeOclConverter().ToElements(context, typeof(Dummy).GetProperty(nameof(Dummy.TestProperty))!, Test.Value1).SingleOrDefault(); + + result.Should().BeNull(); + } + + [Test] + public void WhenConvertingEnum_ValueIsNotEnumDefault_ReturnsValueOfProperty() + { + var context = new OclConversionContext(new OclSerializerOptions()); + + var result = (OclAttribute?)new EnumAttributeOclConverter().ToElements(context, typeof(Dummy).GetProperty(nameof(Dummy.TestProperty))!, Test.Value2).SingleOrDefault(); + + result.Should().NotBeNull(); + result!.Value.Should().Be("Value2"); + } + + [Test] + public void WhenConvertingEnumWithDefaultAttribute_ValueIsEnumDefault_ReturnsValueOfProperty() + { + var context = new OclConversionContext(new OclSerializerOptions()); + + var result = (OclAttribute?)new EnumAttributeOclConverter().ToElements(context, typeof(DummyWithDefault).GetProperty(nameof(DummyWithDefault.TestProperty))!, Test.Value1).SingleOrDefault(); + + result.Should().NotBeNull(); + result!.Value.Should().Be("Value1"); + } + + [Test] + public void WhenConvertingEnumWithDefaultAttribute_ValueIsNotADefault_ReturnsValueOfProperty() + { + var context = new OclConversionContext(new OclSerializerOptions()); + + var result = (OclAttribute?)new EnumAttributeOclConverter().ToElements(context, typeof(DummyWithDefault).GetProperty(nameof(DummyWithDefault.TestProperty))!, Test.Value2).SingleOrDefault(); + + result.Should().NotBeNull(); + result!.Value.Should().Be("Value2"); + } + + [Test] + public void WhenConvertingEnumWithDefaultAttribute_ValueIstAttributedDefault_ReturnsNull() + { + var context = new OclConversionContext(new OclSerializerOptions()); + + var result = (OclAttribute?)new EnumAttributeOclConverter().ToElements(context, typeof(DummyWithDefault).GetProperty(nameof(DummyWithDefault.TestProperty))!, Test.Value3).SingleOrDefault(); + + result.Should().BeNull(); + } + + enum Test + { + Value1, + Value2, + Value3, + } + + class Dummy + { + public Test TestProperty { get; } = Test.Value1; + } + + class DummyWithDefault + { + [OclDefaultEnumValue(Test.Value3)] + public Test TestProperty { get; } = Test.Value1; + } + } +} \ No newline at end of file