Permalink
Browse files

Fixes issue #182, hydrating Nullable Enums

  • Loading branch information...
1 parent 19d5d78 commit efd1b347f159fbb154d676345705af167654d296 @markrendle committed May 13, 2012
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <connectionStrings>
+ <add name="Test" connectionString="data source=.;initial catalog=simpletest;integrated security=true" />
+ </connectionStrings>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="MongoDB.Bson" publicKeyToken="f686731cfb9cc103" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.3.1.4349" newVersion="1.3.1.4349" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="MongoDB.Driver" publicKeyToken="f686731cfb9cc103" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-1.3.1.4349" newVersion="1.3.1.4349" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
@@ -45,6 +45,18 @@ public void CanConvertInt32ToEnum()
Assert.IsInstanceOf<Int32ToEnum>(actual);
Assert.AreEqual(expected, ((Int32ToEnum)actual).Value);
}
+
+ [Test]
+ public void CanConvertInt32ToNullableEnum()
+ {
+ Int32ToNullableEnum.Numbers? expected = Int32ToNullableEnum.Numbers.One;
+ var source = new Dictionary<string, object> { { "Value", (int)expected } };
+ var target = ConcreteTypeCreator.Get(typeof(Int32ToNullableEnum));
+ object actual;
+ Assert.IsTrue(target.TryCreate(source, out actual));
+ Assert.IsInstanceOf<Int32ToNullableEnum>(actual);
+ Assert.AreEqual(expected, ((Int32ToNullableEnum)actual).Value);
+ }
[Test]
public void CanConvertStringToEnum()
@@ -63,6 +75,16 @@ public class DecimalToDouble
public double Value { get; set; }
}
+ public class Int32ToNullableEnum
+ {
+ public Numbers? Value { get; set; }
+ public enum Numbers
+ {
+ One = 1,
+ Two = 2
+ }
+ }
+
public class DateTimeToNullableDateTime
{
public DateTime? Value { get; set; }
@@ -0,0 +1,39 @@
+namespace Simple.Data.UnitTest
+{
+ using System;
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class PropertySetterBuilderTest
+ {
+ [Test]
+ public void ConvertsInt32ToNullableEnum()
+ {
+ var actual = PropertySetterBuilder.SafeConvertNullable<TestInt32Enum>(1);
+ Assert.True(actual.HasValue);
+ Assert.AreEqual(TestInt32Enum.One, actual.Value);
+ }
+
+ [Test]
+ public void ConvertsByteToNullableEnum()
+ {
+ const byte b = 1;
+ var actual = PropertySetterBuilder.SafeConvertNullable<TestByteEnum>(b);
+ Assert.True(actual.HasValue);
+ Assert.AreEqual(TestByteEnum.One, actual.Value);
+ }
+
+ public enum TestInt32Enum
+ {
+ Zero = 0,
+ One = 1,
+ Two = 2
+ }
+ public enum TestByteEnum : byte
+ {
+ Zero = 0,
+ One = 1,
+ Two = 2
+ }
+ }
+}
@@ -93,6 +93,7 @@
<Compile Include="MethodNameParserTest.cs" />
<Compile Include="ObjectReferenceTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="PropertySetterBuilderTest.cs" />
<Compile Include="RangeTest.cs" />
<Compile Include="SimpleDataExceptionTest.cs" />
<Compile Include="SimpleExpressionTest.cs" />
@@ -285,22 +285,26 @@ private BinaryExpression CreateComplexAssign()
private TryExpression CreateTrySimpleAssign()
{
- var changeTypeMethod = typeof (PropertySetterBuilder).GetMethod("SafeConvert",
- BindingFlags.Static | BindingFlags.NonPublic);
-
MethodCallExpression callConvert;
if (_property.PropertyType.IsEnum)
{
+ var changeTypeMethod = typeof (PropertySetterBuilder).GetMethod("SafeConvert",
+ BindingFlags.Static | BindingFlags.NonPublic);
callConvert = Expression.Call(changeTypeMethod, _itemProperty,
Expression.Constant(_property.PropertyType.GetEnumUnderlyingType()));
}
else if (_property.PropertyType.IsGenericType && _property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
- callConvert = Expression.Call(changeTypeMethod, _itemProperty,
- Expression.Constant(_property.PropertyType.GetGenericArguments().Single()));
+ var changeTypeMethod = typeof (PropertySetterBuilder)
+ .GetMethod("SafeConvertNullable", BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod(_property.PropertyType.GetGenericArguments().Single());
+
+ callConvert = Expression.Call(changeTypeMethod, _itemProperty);
}
else
{
+ var changeTypeMethod = typeof (PropertySetterBuilder).GetMethod("SafeConvert",
+ BindingFlags.Static | BindingFlags.NonPublic);
callConvert = Expression.Call(changeTypeMethod, _itemProperty,
Expression.Constant(_property.PropertyType));
}
@@ -342,13 +346,20 @@ private TryExpression CreateTrySimpleArrayAssign()
// ReSharper disable UnusedMember.Local
// Because they're used from runtime-generated code, you see.
- private static object SafeConvert(object source, Type targetType)
+ internal static object SafeConvert(object source, Type targetType)
{
if (ReferenceEquals(source, null)) return null;
if (targetType.IsInstanceOfType(source)) return source;
return Convert.ChangeType(source, targetType);
}
+ internal static T? SafeConvertNullable<T>(object source)
+ where T : struct
+ {
+ if (ReferenceEquals(source, null)) return default(T);
+ return (T) source;
+ }
+
private static T[] CreateArray<T>(object source)
{
if (ReferenceEquals(source, null)) return null;

0 comments on commit efd1b34

Please sign in to comment.