From 1b972cd65f89211bdf18aced82e38544ca901e16 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 9 Jun 2012 13:54:30 +1200 Subject: [PATCH] -Fixed DefaultValueHandling.Ignore with decimal properties -Fixed approximate floating point comparisons --- .../Converters/DataTableConverterTests.cs | 37 +++++++++++++++++++ .../Converters/XmlNodeConverterTest.cs | 21 +++++++++++ .../Properties/AssemblyInfo.cs | 2 +- .../DefaultValueHandlingTests.cs | 21 +++++++++++ .../Properties/AssemblyInfo.cs | 2 +- Src/Newtonsoft.Json/Utilities/MathUtils.cs | 11 +++++- 6 files changed, 90 insertions(+), 4 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs index e0263a56..2e1b9e3b 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs @@ -26,6 +26,7 @@ #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) using System; #if !NETFX_CORE +using System.Collections.Generic; using NUnit.Framework; #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; @@ -233,6 +234,42 @@ namespace Newtonsoft.Json.Tests.Converters Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01); Assert.IsInstanceOfType(typeof(System.DBNull), table.Rows[2]["price"]); } + + [Test] + public void SerializeKeyValuePairWithDataTableKey() + { + DataTable table = new DataTable(); + DataColumn idColumn = new DataColumn("id", typeof(int)); + idColumn.AutoIncrement = true; + + DataColumn itemColumn = new DataColumn("item"); + table.Columns.Add(idColumn); + table.Columns.Add(itemColumn); + + DataRow r = table.NewRow(); + r["item"] = "item!"; + r.EndEdit(); + table.Rows.Add(r); + + KeyValuePair pair = new KeyValuePair(table, 1); + string serializedpair = JsonConvert.SerializeObject(pair, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Key"": [ + { + ""id"": 0, + ""item"": ""item!"" + } + ], + ""Value"": 1 +}", serializedpair); + + var pair2 = (KeyValuePair)JsonConvert.DeserializeObject(serializedpair, typeof(KeyValuePair)); + + Assert.AreEqual(1, pair2.Value); + Assert.AreEqual(1, pair2.Key.Rows.Count); + Assert.AreEqual("item!", pair2.Key.Rows[0]["item"]); + } } } #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs index 3b4cacfd..b398a88f 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs @@ -1314,6 +1314,27 @@ namespace Newtonsoft.Json.Tests.Converters }", json); } + [Test] + public void EmtpyElementWithArrayAttributeShouldWriteElement() + { + string xml = @" + +"; + + XmlDocument d = new XmlDocument(); + d.LoadXml(xml); + + string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented); + + Assert.AreEqual(@"{ + ""root"": { + ""Reports"": [ + {} + ] + } +}", json); + } + [Test] public void DeserializeNonInt64IntegerValues() { diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index c83ccf1d..aa711e8f 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -72,5 +72,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.6.15008")] +[assembly: AssemblyFileVersion("4.5.6.15009")] #endif diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs index 96c6f131..d7e11efe 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs @@ -33,6 +33,7 @@ using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; #endif +using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Serialization { @@ -123,6 +124,14 @@ namespace Newtonsoft.Json.Tests.Serialization [DefaultValue(-1)] public long GlobalId { get; set; } + [JsonProperty(PropertyName = "age")] + [DefaultValue(0)] + public int Age { get; set; } + + [JsonProperty(PropertyName = "amount")] + [DefaultValue(0.0)] + public decimal Amount { get; set; } + [JsonProperty(PropertyName = "floatUserId")] [DefaultValue(-1.0d)] public float FloatGlobalId { get; set; } @@ -136,6 +145,8 @@ namespace Newtonsoft.Json.Tests.Serialization { GlobalId = -1; FloatGlobalId = -1.0f; + Amount = 0.0m; + Age = 0; } } @@ -151,5 +162,15 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(@"{""firstName"":""blub""}", json); } + + [Test] + public void ApproxEquals() + { + Assert.IsTrue(MathUtils.ApproxEquals(0.0, 0.0)); + Assert.IsTrue(MathUtils.ApproxEquals(1000.0, 1000.0000000000001)); + + Assert.IsFalse(MathUtils.ApproxEquals(1000.0, 1000.000000000001)); + Assert.IsFalse(MathUtils.ApproxEquals(0.0, 0.00001)); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index b7e67a0e..0480a78a 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -90,7 +90,7 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.6.15008")] +[assembly: AssemblyFileVersion("4.5.6.15009")] #endif [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Utilities/MathUtils.cs b/Src/Newtonsoft.Json/Utilities/MathUtils.cs index 3ccfb581..366f6283 100644 --- a/Src/Newtonsoft.Json/Utilities/MathUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/MathUtils.cs @@ -83,8 +83,15 @@ namespace Newtonsoft.Json.Utilities public static bool ApproxEquals(double d1, double d2) { - // are values equal to within 6 (or so) digits of precision? - return Math.Abs(d1 - d2) < (Math.Abs(d1) * 1e-6); + const double epsilon = 2.2204460492503131E-16; + + if (d1 == d2) + return true; + + double tolerance = ((Math.Abs(d1) + Math.Abs(d2)) + 10.0) * epsilon; + double difference = d1 - d2; + + return (-tolerance < difference && tolerance > difference); } } } \ No newline at end of file