Casting enums to it's base type in QML.

This commit is contained in:
Paul Knopf 2019-01-03 16:33:23 -05:00
parent ac81a06787
commit e969704be1
2 changed files with 176 additions and 28 deletions

View file

@ -0,0 +1,135 @@
using System.Runtime.CompilerServices;
using Moq;
using Xunit;
namespace Qml.Net.Tests.Qml
{
public class EnumTests : BaseQmlTests<EnumTests.EnumTestsObject>
{
public class EnumTestsObject
{
public enum TestEnum
{
Value1,
Value2,
Value3
}
public virtual TestEnum Value { get; set; }
public virtual TestEnum? ValueNullable { get; set; }
public virtual void Test(string value)
{
}
}
[Fact]
public void Can_use_enum()
{
Mock.Setup(x => x.Value).Returns(EnumTestsObject.TestEnum.Value2);
RunQmlTest(
"test",
@"
test.value = test.value
");
Mock.VerifyGet(x => x.Value, Times.Once);
Mock.VerifySet(x => x.Value = EnumTestsObject.TestEnum.Value2, Times.Once);
}
[Fact]
public void Can_set_enum_to_int()
{
Mock.Setup(x => x.Value);
RunQmlTest(
"test",
@"
test.value = 2
");
Mock.VerifySet(x => x.Value = EnumTestsObject.TestEnum.Value3, Times.Once);
}
[Fact]
public void Can_use_nullable_enum()
{
Mock.Setup(x => x.ValueNullable).Returns(EnumTestsObject.TestEnum.Value2);
RunQmlTest(
"test",
@"
test.valueNullable = test.valueNullable
");
Mock.VerifyGet(x => x.ValueNullable, Times.Once);
Mock.VerifySet(x => x.ValueNullable = EnumTestsObject.TestEnum.Value2, Times.Once);
}
[Fact]
public void Can_use_nullable_enum_with_null()
{
Mock.Setup(x => x.ValueNullable).Returns((EnumTestsObject.TestEnum?)null);
RunQmlTest(
"test",
@"
test.valueNullable = test.valueNullable
");
Mock.VerifyGet(x => x.ValueNullable, Times.Once);
Mock.VerifySet(x => x.ValueNullable = null, Times.Once);
}
[Fact]
public void Enum_is_int_type_is_js()
{
Mock.Setup(x => x.Value).Returns(EnumTestsObject.TestEnum.Value1);
Mock.Setup(x => x.Test(It.IsAny<string>()));
RunQmlTest(
"test",
@"
test.test(typeof test.value)
");
Mock.VerifyGet(x => x.Value, Times.Once);
Mock.Verify(x => x.Test(It.Is<string>(value => value == "number")), Times.Once);
}
[Fact]
public void Nullable_enum_is_int_type_is_js()
{
Mock.Setup(x => x.ValueNullable).Returns(EnumTestsObject.TestEnum.Value1);
Mock.Setup(x => x.Test(It.IsAny<string>()));
RunQmlTest(
"test",
@"
test.test(typeof test.valueNullable)
");
Mock.VerifyGet(x => x.ValueNullable, Times.Once);
Mock.Verify(x => x.Test(It.Is<string>(value => value == "number")), Times.Once);
}
[Fact]
public void Nullable_enum_is_null_type_is_js_when_null()
{
Mock.Setup(x => x.ValueNullable).Returns((EnumTestsObject.TestEnum?)null);
Mock.Setup(x => x.Test(It.IsAny<string>()));
RunQmlTest(
"test",
@"
test.test(test.valueNullable == null)
");
Mock.VerifyGet(x => x.ValueNullable, Times.Once);
Mock.Verify(x => x.Test(It.Is<string>(value => value == "true")), Times.Once);
}
}
}

View file

@ -19,18 +19,56 @@ namespace Qml.Net.Internal
{
return false;
}
if (type.Name == "Array")
{
return false;
}
return true;
}
return false;
}
public static void Pack(object source, NetVariant destination, Type type)
{
if (type == typeof(bool))
destination.Bool = (bool)source;
else if (type == typeof(char))
destination.Char = (char)source;
else if (type == typeof(float))
destination.Float = (float)source;
else if (type == typeof(double))
destination.Double = (double)source;
else if (type == typeof(int))
destination.Int = (int)source;
else if (type == typeof(uint))
destination.UInt = (uint)source;
else if (type == typeof(long))
destination.Long = (long)source;
else if (type == typeof(ulong))
destination.ULong = (ulong)source;
else if (type == typeof(string))
destination.String = (string)source;
else if (type == typeof(DateTimeOffset))
destination.DateTime = ((DateTimeOffset)source).DateTime;
else if (typeof(INetJsValue).IsAssignableFrom(type))
destination.JsValue = ((NetJsValue.NetJsValueDynamic)source).JsValue;
else
{
if (type.IsEnum)
{
Pack(source, destination, type.GetEnumUnderlyingType());
}
else
{
destination.Instance = NetReference.CreateForObject(source);
}
}
}
public static void PackValue(object source, NetVariant destination)
{
if (source == null)
@ -40,32 +78,7 @@ namespace Qml.Net.Internal
else
{
var type = source.GetType();
if (type == typeof(bool))
destination.Bool = (bool)source;
else if (type == typeof(char))
destination.Char = (char)source;
else if (type == typeof(float))
destination.Float = (float)source;
else if (type == typeof(double))
destination.Double = (double)source;
else if (type == typeof(int))
destination.Int = (int)source;
else if (type == typeof(uint))
destination.UInt = (uint)source;
else if (type == typeof(long))
destination.Long = (long)source;
else if (type == typeof(ulong))
destination.ULong = (ulong)source;
else if (type == typeof(string))
destination.String = (string)source;
else if (type == typeof(DateTimeOffset))
destination.DateTime = ((DateTimeOffset)source).DateTime;
else if (typeof(INetJsValue).IsAssignableFrom(type))
destination.JsValue = ((NetJsValue.NetJsValueDynamic)source).JsValue;
else
{
destination.Instance = NetReference.CreateForObject(source);
}
Pack(source, destination, type);
}
}