From 17b59cc20fd69f8ea207856116b2ec5ceb2f3684 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 9 Feb 2018 10:02:51 +1100 Subject: [PATCH] Updates the ObjectExtensions TryConvertTo code and moved all unit tests to ObjectExtensionsTests which now all pass --- src/Umbraco.Core/ObjectExtensions.cs | 22 +-- src/Umbraco.Tests/ObjectExtensionsTests.cs | 160 +++++++++++++++++++-- src/Umbraco.Tests/TryConvertToTests.cs | 141 ------------------ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 - 4 files changed, 164 insertions(+), 160 deletions(-) delete mode 100644 src/Umbraco.Tests/TryConvertToTests.cs diff --git a/src/Umbraco.Core/ObjectExtensions.cs b/src/Umbraco.Core/ObjectExtensions.cs index 24c74e2887..7185a19853 100644 --- a/src/Umbraco.Core/ObjectExtensions.cs +++ b/src/Umbraco.Core/ObjectExtensions.cs @@ -143,6 +143,7 @@ namespace Umbraco.Core var inputString = input as string; if (inputString != null) { + //TODO: Why the check against only bool/date when a string is null/empty? In what scenario can we convert to another type when the string is null or empty other than just being null? if (string.IsNullOrEmpty(inputString) && (underlying == typeof(DateTime) || underlying == typeof(bool))) { return Attempt.Succeed(null); @@ -156,11 +157,6 @@ namespace Umbraco.Core if (inner.Success) { input = inner.Result; // Now fall on through... - - if (input is decimal) - { - target = underlying; - } } else { @@ -213,11 +209,19 @@ namespace Umbraco.Core return Attempt.Succeed(outputConverter.ConvertFrom(input)); } + if (target.IsGenericType && GetCachedGenericNullableType(target) != null) + { + // cannot Convert.ChangeType as that does not work with nullable + // input has already been converted to the underlying type - just + // return input, there's an implicit conversion from T to T? anyways + return Attempt.Succeed(input); + } + // Re-check convertables since we altered the input through recursion var convertible2 = input as IConvertible; if (convertible2 != null) { - return Attempt.Succeed(Convert.ChangeType(convertible2, target)); + return Attempt.Succeed(Convert.ChangeType(convertible2, Nullable.GetUnderlyingType(target) ?? target)); } } catch (Exception e) @@ -750,9 +754,9 @@ namespace Umbraco.Core if (AssignableTypeCache.TryGetValue(key, out canConvert)) { return canConvert; - } - - // "object is" is faster than "Type.IsAssignableFrom. + } + + // "object is" is faster than "Type.IsAssignableFrom. // We can use it to very quickly determine whether true/false if (input is IConvertible && target.IsAssignableFrom(source)) { diff --git a/src/Umbraco.Tests/ObjectExtensionsTests.cs b/src/Umbraco.Tests/ObjectExtensionsTests.cs index a2d27b4181..b3b27e30a7 100644 --- a/src/Umbraco.Tests/ObjectExtensionsTests.cs +++ b/src/Umbraco.Tests/ObjectExtensionsTests.cs @@ -6,6 +6,10 @@ using System.Threading; using System.Web.UI.WebControls; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.ObjectResolution; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Strings; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests { @@ -155,7 +159,7 @@ namespace Umbraco.Tests Assert.AreEqual("Hello world", result.Result); } - [Test] + [Test] public virtual void CanConvertObjectToSameObject() { var obj = new MyTestObject(); @@ -164,7 +168,142 @@ namespace Umbraco.Tests Assert.AreEqual(obj, result.Result); } - private CultureInfo savedCulture; + [Test] + public void ConvertToIntegerTest() + { + var conv = "100".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + + conv = "100.000".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + + conv = "100,000".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + + // oops + conv = "100.001".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + + conv = 100m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + + conv = 100.000m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + + // oops + conv = 100.001m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100, conv.Result); + } + + [Test] + public void ConvertToDecimalTest() + { + var conv = "100".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = "100.000".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = "100,000".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = "100.001".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100.001m, conv.Result); + + conv = 100m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = 100.000m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = 100.001m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100.001m, conv.Result); + + conv = 100.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + } + + [Test] + public void ConvertToNullableDecimalTest() + { + var conv = "100".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = "100.000".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = "100,000".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = "100.001".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100.001m, conv.Result); + + conv = 100m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = 100.000m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + + conv = 100.001m.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100.001m, conv.Result); + + conv = 100.TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(100m, conv.Result); + } + + [Test] + public void ConvertToDateTimeTest() + { + var conv = "2016-06-07".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(new DateTime(2016, 6, 7), conv.Result); + } + + [Test] + public void ConvertToNullableDateTimeTest() + { + var conv = "2016-06-07".TryConvertTo(); + Assert.IsTrue(conv); + Assert.AreEqual(new DateTime(2016, 6, 7), conv.Result); + } + + [Test] + public void Value_Editor_Can_Convert_Decimal_To_Decimal_Clr_Type() + { + var valueEditor = new PropertyValueEditor + { + ValueType = PropertyEditorValueTypes.Decimal + }; + + var result = valueEditor.TryConvertValueToCrlType(12.34d); + Assert.IsTrue(result.Success); + Assert.AreEqual(12.34d, result.Result); + } + + private CultureInfo _savedCulture; /// /// Run once before each test in derived test fixtures. @@ -172,10 +311,13 @@ namespace Umbraco.Tests [SetUp] public void TestSetup() { - savedCulture = Thread.CurrentThread.CurrentCulture; + _savedCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); // make sure the dates parse correctly - return; - } + + var settings = SettingsForTests.GetDefault(); + ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(settings).WithDefaultConfig()); + Resolution.Freeze(); + } /// /// Run once after each test in derived test fixtures. @@ -183,9 +325,9 @@ namespace Umbraco.Tests [TearDown] public void TestTearDown() { - Thread.CurrentThread.CurrentCulture = savedCulture; - return; - } + Thread.CurrentThread.CurrentCulture = _savedCulture; + ShortStringHelperResolver.Reset(); + } private class MyTestObject { @@ -195,4 +337,4 @@ namespace Umbraco.Tests } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Tests/TryConvertToTests.cs b/src/Umbraco.Tests/TryConvertToTests.cs deleted file mode 100644 index ee9fd0870b..0000000000 --- a/src/Umbraco.Tests/TryConvertToTests.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.ObjectResolution; -using Umbraco.Core.Strings; -using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests -{ - [TestFixture] - public class TryConvertToTests - { - [SetUp] - public void SetUp() - { - var settings = SettingsForTests.GetDefault(); - ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(settings).WithDefaultConfig()); - Resolution.Freeze(); - } - - [TearDown] - public void TearDown() - { - ShortStringHelperResolver.Reset(); - } - - [Test] - public void ConvertToIntegerTest() - { - var conv = "100".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - - conv = "100.000".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - - conv = "100,000".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - - // oops - conv = "100.001".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - - conv = 100m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - - conv = 100.000m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - - // oops - conv = 100.001m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100, conv.Result); - } - - [Test] - public void ConvertToDecimalTest() - { - var conv = "100".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = "100.000".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = "100,000".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = "100.001".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100.001m, conv.Result); - - conv = 100m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = 100.000m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = 100.001m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100.001m, conv.Result); - - conv = 100.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - } - - [Test] - public void ConvertToNullableDecimalTest() - { - var conv = "100".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = "100.000".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = "100,000".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = "100.001".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100.001m, conv.Result); - - conv = 100m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = 100.000m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - - conv = 100.001m.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100.001m, conv.Result); - - conv = 100.TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(100m, conv.Result); - } - - [Test] - public void ConvertToDateTimeTest() - { - var conv = "2016-06-07".TryConvertTo(); - Assert.IsTrue(conv); - Assert.AreEqual(new DateTime(2016, 6, 7), conv.Result); - } - } -} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 2811ef715f..2e7b1b5e42 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -231,7 +231,6 @@ -