From 5eac02a79756357fcf4d5c477e5faad90c5fc5b0 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 19 Aug 2019 12:57:09 +1200 Subject: [PATCH] Run unit tests on .NET Core 3.0 and fix Enumerable.Empty (#2137) --- Build/build.ps1 | 4 +- .../Newtonsoft.Json.TestConsole.csproj | 2 +- .../Converters/StringEnumConverterTests.cs | 4 +- .../ExceptionHandlingTests.cs | 3 +- .../JsonTextReaderTests/ParseAsyncTests.cs | 12 ++ .../JsonTextReaderTests/ParseTests.cs | 12 ++ .../JsonTextReaderTests/ReadAsyncTests.cs | 3 +- .../JsonTextReaderTests/ReadTests.cs | 3 +- .../JsonTextWriterAsyncTests.cs | 6 +- .../JsonTextWriterTest.cs | 7 +- Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs | 40 ++++-- .../Linq/JObjectTests.cs | 18 ++- .../Newtonsoft.Json.Tests.csproj | 8 +- .../Schema/JsonSchemaGeneratorTests.cs | 4 +- .../JsonSerializerCollectionsTests.cs | 24 ++++ .../Serialization/JsonSerializerTest.cs | 27 +++- .../Serialization/TraceWriterTests.cs | 58 +++++---- .../Serialization/TypeNameHandlingTests.cs | 16 +-- Src/Newtonsoft.Json.Tests/TestFixtureBase.cs | 4 +- .../TestObjects/VersionOld.cs | 117 ++++++++++++++++++ .../Serialization/JsonArrayContract.cs | 7 +- Src/global.json | 2 +- 22 files changed, 300 insertions(+), 81 deletions(-) create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/VersionOld.cs diff --git a/Build/build.ps1 b/Build/build.ps1 index 2c379a5d..27983674 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -14,7 +14,7 @@ $workingName = if ($workingName) {$workingName} else {"Working"} $assemblyVersion = if ($assemblyVersion) {$assemblyVersion} else {$majorVersion + '.0.0'} $netCliChannel = "2.0" - $netCliVersion = "3.0.100-preview8-013317" + $netCliVersion = "3.0.100-preview9-013927" $nugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" $baseDir = resolve-path .. @@ -31,7 +31,7 @@ $nunitConsolePath = "$buildDir\Temp\NUnit.ConsoleRunner.$nunitConsoleVersion" $builds = @( - @{Framework = "netstandard2.0"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp2.2"; Enabled=$true}, + @{Framework = "netstandard2.0"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp3.0"; Enabled=$true}, @{Framework = "netstandard1.3"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp1.1"; Enabled=$true}, @{Framework = "netstandard1.0"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp1.0"; Enabled=$true}, @{Framework = "net45"; TestsFunction = "NUnitTests"; TestFramework = "net46"; NUnitFramework="net-4.0"; Enabled=$true}, diff --git a/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj b/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj index 97a67d43..a60bfbca 100644 --- a/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj +++ b/Src/Newtonsoft.Json.TestConsole/Newtonsoft.Json.TestConsole.csproj @@ -1,7 +1,7 @@  Exe - net46;netcoreapp2.2 + net46;netcoreapp3.0 latest Newtonsoft.Json.TestConsole Newtonsoft.Json.TestConsole diff --git a/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs index 2a6e1dc8..2e1b0af0 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs @@ -255,7 +255,7 @@ namespace Newtonsoft.Json.Tests.Converters ExceptionAssert.Throws( () => new StringEnumConverter(null), @"Value cannot be null. -Parameter name: namingStrategyType"); +Parameter name: namingStrategyType", "Value cannot be null. (Parameter 'namingStrategyType')"); } [Test] @@ -264,7 +264,7 @@ Parameter name: namingStrategyType"); ExceptionAssert.Throws( () => new StringEnumConverter(null, new object[] { true, true, true }, false), @"Value cannot be null. -Parameter name: namingStrategyType"); +Parameter name: namingStrategyType", "Value cannot be null. (Parameter 'namingStrategyType')"); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ExceptionHandlingTests.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ExceptionHandlingTests.cs index 830deb55..da47b2f6 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ExceptionHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ExceptionHandlingTests.cs @@ -363,7 +363,8 @@ namespace Newtonsoft.Json.Tests.JsonTextReaderTests new string[] { "Value cannot be null." + Environment.NewLine + "Parameter name: reader", - "Argument cannot be null." + Environment.NewLine + "Parameter name: reader" // Mono + "Argument cannot be null." + Environment.NewLine + "Parameter name: reader", // Mono + "Value cannot be null. (Parameter 'reader')" }); } diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseAsyncTests.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseAsyncTests.cs index e1a6c69c..09e2aab2 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseAsyncTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseAsyncTests.cs @@ -200,10 +200,22 @@ namespace Newtonsoft.Json.Tests.JsonTextReaderTests Assert.AreEqual(Double.MinValue, reader.Value); reader = new JsonTextReader(new StringReader("1E+309")); +#if !NETSTANDARD2_0 await ExceptionAssert.ThrowsAsync(async () => await reader.ReadAsync(), "Input string '1E+309' is not a valid number. Path '', line 1, position 6."); +#else + Assert.IsTrue(await reader.ReadAsync()); + Assert.AreEqual(typeof(double), reader.ValueType); + Assert.AreEqual(Double.PositiveInfinity, reader.Value); +#endif reader = new JsonTextReader(new StringReader("-1E+5000")); +#if !NETSTANDARD2_0 await ExceptionAssert.ThrowsAsync(async () => await reader.ReadAsync(), "Input string '-1E+5000' is not a valid number. Path '', line 1, position 8."); +#else + Assert.IsTrue(await reader.ReadAsync()); + Assert.AreEqual(typeof(double), reader.ValueType); + Assert.AreEqual(Double.NegativeInfinity, reader.Value); +#endif reader = new JsonTextReader(new StringReader("5.1231231E")); await ExceptionAssert.ThrowsAsync(async () => await reader.ReadAsync(), "Input string '5.1231231E' is not a valid number. Path '', line 1, position 10."); diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseTests.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseTests.cs index 5b18955a..aff080da 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ParseTests.cs @@ -220,10 +220,22 @@ namespace Newtonsoft.Json.Tests.JsonTextReaderTests Assert.AreEqual(Double.MinValue, reader.Value); reader = new JsonTextReader(new StringReader("1E+309")); +#if !NETSTANDARD2_0 ExceptionAssert.Throws(() => reader.Read(), "Input string '1E+309' is not a valid number. Path '', line 1, position 6."); +#else + Assert.IsTrue(reader.Read()); + Assert.AreEqual(typeof(double), reader.ValueType); + Assert.AreEqual(Double.PositiveInfinity, reader.Value); +#endif reader = new JsonTextReader(new StringReader("-1E+5000")); +#if !NETSTANDARD2_0 ExceptionAssert.Throws(() => reader.Read(), "Input string '-1E+5000' is not a valid number. Path '', line 1, position 8."); +#else + Assert.IsTrue(reader.Read()); + Assert.AreEqual(typeof(double), reader.ValueType); + Assert.AreEqual(Double.NegativeInfinity, reader.Value); +#endif reader = new JsonTextReader(new StringReader("5.1231231E")); ExceptionAssert.Throws(() => reader.Read(), "Input string '5.1231231E' is not a valid number. Path '', line 1, position 10."); diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadAsyncTests.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadAsyncTests.cs index ccbe8fde..7f23c53d 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadAsyncTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadAsyncTests.cs @@ -84,7 +84,8 @@ namespace Newtonsoft.Json.Tests.JsonTextReaderTests await ExceptionAssert.ThrowsAsync( () => token.CreateReader().ReadAsDecimalAsync(), - "Could not convert to decimal: 1.79769313486232E+308. Path ''." + "Could not convert to decimal: 1.79769313486232E+308. Path ''.", + "Could not convert to decimal: 1.7976931348623157E+308. Path ''." ); } diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadTests.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadTests.cs index ce96f3d3..905dbbed 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTests/ReadTests.cs @@ -89,7 +89,8 @@ namespace Newtonsoft.Json.Tests.JsonTextReaderTests ExceptionAssert.Throws( () => token.CreateReader().ReadAsDecimal(), - "Could not convert to decimal: 1.79769313486232E+308. Path ''." + "Could not convert to decimal: 1.79769313486232E+308. Path ''.", + "Could not convert to decimal: 1.7976931348623157E+308. Path ''." ); } diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterAsyncTests.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterAsyncTests.cs index 11b111dc..56d9b8c8 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextWriterAsyncTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterAsyncTests.cs @@ -1018,7 +1018,11 @@ namespace Newtonsoft.Json.Tests await jsonWriter.WriteEndArrayAsync(); } +#if !NETSTANDARD2_0 Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString()); +#else + Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,5E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString()); +#endif } [Test] @@ -1094,7 +1098,7 @@ namespace Newtonsoft.Json.Tests await ExceptionAssert.ThrowsAsync(async () => { await jsonWriter.WriteTokenAsync(JsonToken.Integer, "three"); }, "Input string was not in a correct format."); await ExceptionAssert.ThrowsAsync(async () => { await jsonWriter.WriteTokenAsync(JsonToken.Integer); }, @"Value cannot be null. -Parameter name: value"); +Parameter name: value", "Value cannot be null. (Parameter 'value')"); } } diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs index 570d66fb..d463ddc3 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs @@ -880,7 +880,12 @@ namespace Newtonsoft.Json.Tests jsonWriter.WriteEndArray(); } +#if !NETSTANDARD2_0 Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString()); +#else + Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,5E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString()); +#endif + } [Test] @@ -962,7 +967,7 @@ namespace Newtonsoft.Json.Tests ExceptionAssert.Throws(() => { jsonWriter.WriteToken(JsonToken.Integer, "three"); }, "Input string was not in a correct format."); ExceptionAssert.Throws(() => { jsonWriter.WriteToken(JsonToken.Integer); }, @"Value cannot be null. -Parameter name: value"); +Parameter name: value", "Value cannot be null. (Parameter 'value')"); } } diff --git a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs index 735ed36c..1f35f666 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs @@ -127,8 +127,10 @@ namespace Newtonsoft.Json.Tests.Linq { JArray j = new JArray(); - ExceptionAssert.Throws(() => { ((ICollection)j).CopyTo(null, 0); }, @"Value cannot be null. -Parameter name: array"); + ExceptionAssert.Throws(() => { ((ICollection)j).CopyTo(null, 0); }, + @"Value cannot be null. +Parameter name: array", + "Value cannot be null. (Parameter 'array')"); } [Test] @@ -136,8 +138,10 @@ Parameter name: array"); { JArray j = new JArray(); - ExceptionAssert.Throws(() => { ((ICollection)j).CopyTo(new JToken[1], -1); }, @"arrayIndex is less than 0. -Parameter name: arrayIndex"); + ExceptionAssert.Throws(() => { ((ICollection)j).CopyTo(new JToken[1], -1); }, + @"arrayIndex is less than 0. +Parameter name: arrayIndex", + "arrayIndex is less than 0. (Parameter 'arrayIndex')"); } [Test] @@ -232,8 +236,11 @@ Parameter name: arrayIndex"); { JArray j = new JArray(); - ExceptionAssert.Throws(() => { j.RemoveAt(0); }, @"Index is equal to or greater than Count. -Parameter name: index"); + ExceptionAssert.Throws( + () => { j.RemoveAt(0); }, + @"Index is equal to or greater than Count. +Parameter name: index", + "Index is equal to or greater than Count. (Parameter 'index')"); } [Test] @@ -241,8 +248,11 @@ Parameter name: index"); { JArray j = new JArray(); - ExceptionAssert.Throws(() => { j.RemoveAt(-1); }, @"Index is less than 0. -Parameter name: index"); + ExceptionAssert.Throws( + () => { j.RemoveAt(-1); }, + @"Index is less than 0. +Parameter name: index", + "Index is less than 0. (Parameter 'index')"); } [Test] @@ -320,8 +330,11 @@ Parameter name: index"); { JArray j = new JArray(); - ExceptionAssert.Throws(() => { j.Insert(-1, new JValue(1)); }, @"Index was out of range. Must be non-negative and less than the size of the collection. -Parameter name: index"); + ExceptionAssert.Throws( + () => { j.Insert(-1, new JValue(1)); }, + @"Index was out of range. Must be non-negative and less than the size of the collection. +Parameter name: index", + "Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')"); } [Test] @@ -329,8 +342,11 @@ Parameter name: index"); { JArray j = new JArray(); - ExceptionAssert.Throws(() => { j.Insert(2, new JValue(1)); }, @"Index must be within the bounds of the List. -Parameter name: index"); + ExceptionAssert.Throws( + () => { j.Insert(2, new JValue(1)); }, + @"Index must be within the bounds of the List. +Parameter name: index", + "Index must be within the bounds of the List. (Parameter 'index')"); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs index 9afb4265..03f69e08 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs @@ -310,8 +310,10 @@ namespace Newtonsoft.Json.Tests.Linq { contains = o.ContainsKey(null); Assert.AreEqual(false, contains); - }, @"Value cannot be null. -Parameter name: propertyName"); + }, + @"Value cannot be null. +Parameter name: propertyName", + "Value cannot be null. (Parameter 'propertyName')"); } [Test] @@ -359,8 +361,10 @@ Parameter name: propertyName"); { JObject o = new JObject(); ((ICollection>)o).CopyTo(null, 0); - }, @"Value cannot be null. -Parameter name: array"); + }, + @"Value cannot be null. +Parameter name: array", + "Value cannot be null. (Parameter 'array')"); } [Test] @@ -370,8 +374,10 @@ Parameter name: array"); { JObject o = new JObject(); ((ICollection>)o).CopyTo(new KeyValuePair[1], -1); - }, @"arrayIndex is less than 0. -Parameter name: arrayIndex"); + }, + @"arrayIndex is less than 0. +Parameter name: arrayIndex", + "arrayIndex is less than 0. (Parameter 'arrayIndex')"); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index 1c8db22a..8d0dd585 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -1,6 +1,6 @@  - net46;net451;net452;net40;net35;net20;netcoreapp2.2;netcoreapp1.1;netcoreapp1.0 + net46;net451;net452;net40;net35;net20;netcoreapp3.0;netcoreapp1.1;netcoreapp1.0 $(TestFrameworks) latest 1.0 @@ -13,7 +13,7 @@ Newtonsoft.Json.Tests false - Full + Full false @@ -153,7 +153,7 @@ NET20;$(AdditionalConstants) - + @@ -168,7 +168,7 @@ - + Json.NET Tests .NET Standard 2.0 .NETStandard,Version=v2.0 NETSTANDARD2_0;DNXCORE50;PORTABLE;HAVE_BENCHMARKS;$(AdditionalConstants) diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs index e98489f6..bf8d5b1b 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs @@ -381,12 +381,12 @@ namespace Newtonsoft.Json.Tests.Schema #endif }; - JsonSchema schema = generator.Generate(typeof(Version), true); + JsonSchema schema = generator.Generate(typeof(VersionOld), true); string json = schema.ToString(); StringAssert.AreEqual(@"{ - ""id"": ""System.Version"", + ""id"": ""Newtonsoft.Json.Tests.TestObjects.VersionOld"", ""type"": [ ""object"", ""null"" diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs index a7b64590..c3678e56 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs @@ -164,7 +164,11 @@ namespace Newtonsoft.Json.Tests.Serialization { Dictionary dictionary = new Dictionary { { float.MaxValue, 1 } }; string output = JsonConvert.SerializeObject(dictionary); +#if !NETSTANDARD2_0 Assert.AreEqual(@"{""3.40282347E+38"":1}", output); +#else + Assert.AreEqual(@"{""3.4028235E+38"":1}", output); +#endif Dictionary deserializedValue = JsonConvert.DeserializeObject>(output); Assert.AreEqual(float.MaxValue, deserializedValue.First().Key); @@ -2108,6 +2112,26 @@ namespace Newtonsoft.Json.Tests.Serialization } #endif + [Test] + public void DeserializeEmptyEnumerable_NoItems() + { + ValuesClass c = JsonConvert.DeserializeObject(@"{""Values"":[]}"); + Assert.AreEqual(0, c.Values.Count()); + } + + [Test] + public void DeserializeEmptyEnumerable_HasItems() + { + ValuesClass c = JsonConvert.DeserializeObject(@"{""Values"":[""hello""]}"); + Assert.AreEqual(1, c.Values.Count()); + Assert.AreEqual("hello", c.Values.ElementAt(0)); + } + + public class ValuesClass + { + public IEnumerable Values { get; set; } = Enumerable.Empty(); + } + [Test] public void DeserializeConstructorWithReadonlyArrayProperty() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 80d77bc5..805bcfdf 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -2258,7 +2258,24 @@ keyword such as type of business."" string json = JsonConvert.SerializeObject(new ConverableMembers(), Formatting.Indented); string expected = null; -#if !(PORTABLE || DNXCORE50) || NETSTANDARD2_0 +#if NETSTANDARD2_0 + expected = @"{ + ""String"": ""string"", + ""Int32"": 2147483647, + ""UInt32"": 4294967295, + ""Byte"": 255, + ""SByte"": 127, + ""Short"": 32767, + ""UShort"": 65535, + ""Long"": 9223372036854775807, + ""ULong"": 9223372036854775807, + ""Double"": 1.7976931348623157E+308, + ""Float"": 3.4028235E+38, + ""DBNull"": null, + ""Bool"": true, + ""Char"": ""\u0000"" +}"; +#elif !(PORTABLE || DNXCORE50) expected = @"{ ""String"": ""string"", ""Int32"": 2147483647, @@ -2276,7 +2293,7 @@ keyword such as type of business."" ""Char"": ""\u0000"" }"; #else - expected = @"{ + expected = @"{ ""String"": ""string"", ""Int32"": 2147483647, ""UInt32"": 4294967295, @@ -5884,7 +5901,8 @@ Path '', line 1, position 1."); new[] { "Value cannot be null." + Environment.NewLine + "Parameter name: value", - "Argument cannot be null." + Environment.NewLine + "Parameter name: value" // mono + "Argument cannot be null." + Environment.NewLine + "Parameter name: value", // mono + "Value cannot be null. (Parameter 'value')" }); } @@ -5896,7 +5914,8 @@ Path '', line 1, position 1."); new[] { "Value cannot be null." + Environment.NewLine + "Parameter name: value", - "Argument cannot be null." + Environment.NewLine + "Parameter name: value" // mono + "Argument cannot be null." + Environment.NewLine + "Parameter name: value", // mono + "Value cannot be null. (Parameter 'value')" }); } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs index eaab7dec..8d8aa65d 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs @@ -468,7 +468,7 @@ Newtonsoft.Json Error: 0 : Error! { StringArray = new[] { "1", "2" }, IntList = new List { 1, 2 }, - Version = new Version(1, 2, 3, 4), + Version = new VersionOld(1, 2, 3, 4), StringDictionary = new Dictionary { @@ -489,8 +489,8 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.Int32]. Path 'IntList'.", traceWriter.TraceRecords[2].Message); Assert.AreEqual("Started serializing System.String[]. Path 'StringArray'.", traceWriter.TraceRecords[3].Message); Assert.AreEqual("Finished serializing System.String[]. Path 'StringArray'.", traceWriter.TraceRecords[4].Message); - Assert.AreEqual("Started serializing System.Version. Path 'Version'.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Finished serializing System.Version. Path 'Version'.", traceWriter.TraceRecords[6].Message); + Assert.AreEqual("Started serializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'Version'.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Finished serializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'Version'.", traceWriter.TraceRecords[6].Message); Assert.AreEqual("Started serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path 'StringDictionary'.", traceWriter.TraceRecords[7].Message); Assert.AreEqual("Finished serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path 'StringDictionary'.", traceWriter.TraceRecords[8].Message); Assert.AreEqual("Finished serializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path ''.", traceWriter.TraceRecords[9].Message); @@ -548,9 +548,9 @@ Newtonsoft.Json Error: 0 : Error! Assert.IsTrue(traceWriter.TraceRecords[2].Message.StartsWith("Finished deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList'")); Assert.AreEqual("Started deserializing System.String[]. Path 'StringArray', line 6, position 18.", traceWriter.TraceRecords[3].Message); Assert.IsTrue(traceWriter.TraceRecords[4].Message.StartsWith("Finished deserializing System.String[]. Path 'StringArray'")); - Assert.AreEqual("Deserializing System.Version using creator with parameters: Major, Minor, Build, Revision. Path 'Version.Major', line 11, position 12.", traceWriter.TraceRecords[5].Message); - Assert.IsTrue(traceWriter.TraceRecords[6].Message.StartsWith("Started deserializing System.Version. Path 'Version'")); - Assert.IsTrue(traceWriter.TraceRecords[7].Message.StartsWith("Finished deserializing System.Version. Path 'Version'")); + Assert.AreEqual("Deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld using creator with parameters: Major, Minor, Build, Revision. Path 'Version.Major', line 11, position 12.", traceWriter.TraceRecords[5].Message); + Assert.IsTrue(traceWriter.TraceRecords[6].Message.StartsWith("Started deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'Version'")); + Assert.IsTrue(traceWriter.TraceRecords[7].Message.StartsWith("Finished deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'Version'")); Assert.AreEqual("Started deserializing System.Collections.Generic.IDictionary`2[System.String,System.String]. Path 'StringDictionary.1', line 19, position 8.", traceWriter.TraceRecords[8].Message); Assert.IsTrue(traceWriter.TraceRecords[9].Message.StartsWith("Finished deserializing System.Collections.Generic.IDictionary`2[System.String,System.String]. Path 'StringDictionary'")); Assert.IsTrue(traceWriter.TraceRecords[10].Message.StartsWith("Finished deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path ''")); @@ -611,9 +611,9 @@ Newtonsoft.Json Error: 0 : Error! Assert.IsTrue(traceWriter.TraceRecords[2].Message.StartsWith("Finished deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList'")); Assert.AreEqual("Started deserializing System.String[]. Path 'StringArray', line 6, position 18.", traceWriter.TraceRecords[3].Message); Assert.IsTrue(traceWriter.TraceRecords[4].Message.StartsWith("Finished deserializing System.String[]. Path 'StringArray'")); - Assert.AreEqual("Deserializing System.Version using creator with parameters: Major, Minor, Build, Revision. Path 'Version.Major', line 11, position 12.", traceWriter.TraceRecords[5].Message); - Assert.IsTrue(traceWriter.TraceRecords[6].Message.StartsWith("Started deserializing System.Version. Path 'Version'")); - Assert.IsTrue(traceWriter.TraceRecords[7].Message.StartsWith("Finished deserializing System.Version. Path 'Version'")); + Assert.AreEqual("Deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld using creator with parameters: Major, Minor, Build, Revision. Path 'Version.Major', line 11, position 12.", traceWriter.TraceRecords[5].Message); + Assert.IsTrue(traceWriter.TraceRecords[6].Message.StartsWith("Started deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'Version'")); + Assert.IsTrue(traceWriter.TraceRecords[7].Message.StartsWith("Finished deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'Version'")); Assert.AreEqual("Started deserializing System.Collections.Generic.IDictionary`2[System.String,System.String]. Path 'StringDictionary.1', line 19, position 8.", traceWriter.TraceRecords[8].Message); Assert.IsTrue(traceWriter.TraceRecords[9].Message.StartsWith("Finished deserializing System.Collections.Generic.IDictionary`2[System.String,System.String]. Path 'StringDictionary'")); Assert.IsTrue(traceWriter.TraceRecords[10].Message.StartsWith("Finished deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path ''")); @@ -751,7 +751,7 @@ Newtonsoft.Json Error: 0 : Error! IList l = new List { new Dictionary { { "key!", "value!" } }, - new Version(1, 2, 3, 4) + new VersionOld(1, 2, 3, 4) }; JsonConvert.SerializeObject(l, Formatting.Indented, new JsonSerializerSettings @@ -765,9 +765,9 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual("Started serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values'.", traceWriter.TraceRecords[2].Message); Assert.AreEqual("Writing type name '" + ReflectionUtils.GetTypeName(typeof(Dictionary), 0, DefaultSerializationBinder.Instance) + "' for System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'.", traceWriter.TraceRecords[3].Message); Assert.AreEqual("Finished serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'.", traceWriter.TraceRecords[4].Message); - Assert.AreEqual("Started serializing System.Version. Path '$values[0]'.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Writing type name '" + ReflectionUtils.GetTypeName(typeof(Version), 0, DefaultSerializationBinder.Instance) + "' for System.Version. Path '$values[1]'.", traceWriter.TraceRecords[6].Message); - Assert.AreEqual("Finished serializing System.Version. Path '$values[1]'.", traceWriter.TraceRecords[7].Message); + Assert.AreEqual("Started serializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path '$values[0]'.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Writing type name '" + ReflectionUtils.GetTypeName(typeof(VersionOld), 0, DefaultSerializationBinder.Instance) + "' for Newtonsoft.Json.Tests.TestObjects.VersionOld. Path '$values[1]'.", traceWriter.TraceRecords[6].Message); + Assert.AreEqual("Finished serializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path '$values[1]'.", traceWriter.TraceRecords[7].Message); Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[8].Message); } @@ -837,7 +837,7 @@ Newtonsoft.Json Error: 0 : Error! ""key!"": ""value!"" }, { - ""$type"": ""System.Version, mscorlib"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.VersionOld, Newtonsoft.Json.Tests"", ""Major"": 1, ""Minor"": 2, ""Build"": 3, @@ -860,10 +860,10 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual("Resolved type 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib' to System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0].$type', line 5, position 119.", traceWriter.TraceRecords[2].Message); Assert.AreEqual("Started deserializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0].key!', line 6, position 13.", traceWriter.TraceRecords[3].Message); Assert.IsTrue(traceWriter.TraceRecords[4].Message.StartsWith("Finished deserializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'")); - Assert.AreEqual("Resolved type 'System.Version, mscorlib' to System.Version. Path '$values[1].$type', line 9, position 41.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Deserializing System.Version using creator with parameters: Major, Minor, Build, Revision. Path '$values[1].Major', line 10, position 14.", traceWriter.TraceRecords[6].Message); - Assert.IsTrue(traceWriter.TraceRecords[7].Message.StartsWith("Started deserializing System.Version. Path '$values[1]'")); - Assert.IsTrue(traceWriter.TraceRecords[8].Message.StartsWith("Finished deserializing System.Version. Path '$values[1]'")); + Assert.AreEqual("Resolved type 'Newtonsoft.Json.Tests.TestObjects.VersionOld, Newtonsoft.Json.Tests' to Newtonsoft.Json.Tests.TestObjects.VersionOld. Path '$values[1].$type', line 9, position 84.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld using creator with parameters: Major, Minor, Build, Revision. Path '$values[1].Major', line 10, position 14.", traceWriter.TraceRecords[6].Message); + Assert.IsTrue(traceWriter.TraceRecords[7].Message.StartsWith("Started deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path '$values[1]'")); + Assert.IsTrue(traceWriter.TraceRecords[8].Message.StartsWith("Finished deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path '$values[1]'")); Assert.IsTrue(traceWriter.TraceRecords[9].Message.StartsWith("Finished deserializing System.Collections.Generic.List`1[System.Object]. Path '$values'")); } @@ -884,11 +884,19 @@ Newtonsoft.Json Error: 0 : Error! { TraceWriter = traceWriter }); - }, "Member 'ClassName' was not found."); + }, + "Member 'ClassName' was not found.", + "Member 'Message' was not found."); Assert.IsTrue(traceWriter.TraceRecords[0].Message.StartsWith("Deserializing System.Exception using ISerializable constructor. Path ''")); Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); + +#if !NETSTANDARD2_0 Assert.AreEqual("Error deserializing System.Exception. Member 'ClassName' was not found. Path '', line 1, position 2.", traceWriter.TraceRecords[1].Message); +#else + Assert.AreEqual("Error deserializing System.Exception. Member 'Message' was not found. Path '', line 1, position 2.", traceWriter.TraceRecords[1].Message); +#endif + Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[1].Level); } #endif @@ -931,15 +939,15 @@ Newtonsoft.Json Error: 0 : Error! ""MissingMemberProperty"": null }"; - JsonConvert.DeserializeObject(json, new JsonSerializerSettings + JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TraceWriter = traceWriter }); - Assert.AreEqual("Deserializing System.Version using creator with parameters: Major, Minor, Build, Revision. Path 'Major', line 2, position 10.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Could not find member 'MissingMemberProperty' on System.Version. Path 'MissingMemberProperty', line 8, position 31.", traceWriter.TraceRecords[1].Message); - Assert.IsTrue(traceWriter.TraceRecords[2].Message.StartsWith("Started deserializing System.Version. Path ''")); - Assert.IsTrue(traceWriter.TraceRecords[3].Message.StartsWith("Finished deserializing System.Version. Path ''")); + Assert.AreEqual("Deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld using creator with parameters: Major, Minor, Build, Revision. Path 'Major', line 2, position 10.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Could not find member 'MissingMemberProperty' on Newtonsoft.Json.Tests.TestObjects.VersionOld. Path 'MissingMemberProperty', line 8, position 31.", traceWriter.TraceRecords[1].Message); + Assert.IsTrue(traceWriter.TraceRecords[2].Message.StartsWith("Started deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path ''")); + Assert.IsTrue(traceWriter.TraceRecords[3].Message.StartsWith("Finished deserializing Newtonsoft.Json.Tests.TestObjects.VersionOld. Path ''")); } [Test] @@ -1402,7 +1410,7 @@ Newtonsoft.Json Error: 0 : Error! { public IList IntList { get; set; } public string[] StringArray { get; set; } - public Version Version { get; set; } + public VersionOld Version { get; set; } public IDictionary StringDictionary { get; set; } public double Double { get; set; } } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs index b83b87b8..2b65d0aa 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -1406,19 +1406,9 @@ namespace Newtonsoft.Json.Tests.Serialization } }); - StringAssert.AreEqual(@"{ - ""$type"": "":::MESSAGE:::, AssemblyName"", - ""Address"": ""jamesnk@testtown.com"", - ""Body"": { - ""$type"": "":::VERSION:::, AssemblyName"", - ""Major"": 1, - ""Minor"": 2, - ""Build"": 3, - ""Revision"": 4, - ""MajorRevision"": 0, - ""MinorRevision"": 4 - } -}", json); + JObject o = JObject.Parse(json); + + Assert.AreEqual(":::MESSAGE:::, AssemblyName", (string)o["$type"]); } public class MetroBinder : SerializationBinder diff --git a/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs b/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs index 41c58138..52c5ed35 100644 --- a/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs +++ b/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs @@ -373,7 +373,7 @@ namespace Newtonsoft.Json.Tests { action(); - Assert.Fail("Exception of type {0} expected. No exception thrown.", typeof(TException).Name); + Assert.Fail("Exception of type " + typeof(TException).Name + " expected. No exception thrown."); return null; } catch (TException ex) @@ -406,7 +406,7 @@ namespace Newtonsoft.Json.Tests { await action(); - Assert.Fail("Exception of type {0} expected. No exception thrown.", typeof(TException).Name); + Assert.Fail("Exception of type " + typeof(TException).Name + " expected. No exception thrown."); return null; } catch (TException ex) diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/VersionOld.cs b/Src/Newtonsoft.Json.Tests/TestObjects/VersionOld.cs new file mode 100644 index 00000000..67216e4a --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/VersionOld.cs @@ -0,0 +1,117 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +using System; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + [Serializable] + public sealed class VersionOld : IComparable, IComparable, IEquatable + { + // AssemblyName depends on the order staying the same + private readonly int _Major; // Do not rename (binary serialization) + private readonly int _Minor; // Do not rename (binary serialization) + private readonly int _Build = -1; // Do not rename (binary serialization) + private readonly int _Revision = -1; // Do not rename (binary serialization) + + [JsonConstructor] + public VersionOld(int major, int minor, int build, int revision) + { + _Major = major; + _Minor = minor; + _Build = build; + _Revision = revision; + } + + public VersionOld(int major, int minor, int build) + { + _Major = major; + _Minor = minor; + _Build = build; + } + + public VersionOld(int major, int minor) + { + _Major = major; + _Minor = minor; + } + + public VersionOld() + { + _Major = 0; + _Minor = 0; + } + + // Properties for setting and getting version numbers + public int Major => _Major; + + public int Minor => _Minor; + + public int Build => _Build; + + public int Revision => _Revision; + + public short MajorRevision => (short)(_Revision >> 16); + + public short MinorRevision => (short)(_Revision & 0xFFFF); + + public int CompareTo(object version) + { + if (version == null) + { + return 1; + } + + if (version is VersionOld v) + { + return CompareTo(v); + } + + throw new ArgumentException(); + } + + public int CompareTo(VersionOld value) + { + return + object.ReferenceEquals(value, this) ? 0 : + value is null ? 1 : + _Major != value._Major ? (_Major > value._Major ? 1 : -1) : + _Minor != value._Minor ? (_Minor > value._Minor ? 1 : -1) : + _Build != value._Build ? (_Build > value._Build ? 1 : -1) : + _Revision != value._Revision ? (_Revision > value._Revision ? 1 : -1) : + 0; + } + + public bool Equals(VersionOld obj) + { + return object.ReferenceEquals(obj, this) || + (!(obj is null) && + _Major == obj._Major && + _Minor == obj._Minor && + _Build == obj._Build && + _Revision == obj._Revision); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs index d0944684..615b2421 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs @@ -117,7 +117,10 @@ namespace Newtonsoft.Json.Serialization : base(underlyingType) { ContractType = JsonContractType.Array; - IsArray = CreatedType.IsArray; + + // netcoreapp3.0 uses EmptyPartition for empty enumerable. Treat as an empty array. + IsArray = CreatedType.IsArray || + (NonNullableUnderlyingType.IsGenericType() && NonNullableUnderlyingType.GetGenericTypeDefinition().FullName == "System.Linq.EmptyPartition`1"); bool canDeserialize; @@ -129,7 +132,7 @@ namespace Newtonsoft.Json.Serialization _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); canDeserialize = true; - IsMultidimensionalArray = (IsArray && UnderlyingType.GetArrayRank() > 1); + IsMultidimensionalArray = (CreatedType.IsArray && UnderlyingType.GetArrayRank() > 1); } else if (typeof(IList).IsAssignableFrom(NonNullableUnderlyingType)) { diff --git a/Src/global.json b/Src/global.json index 543cd347..3ba8ad57 100644 --- a/Src/global.json +++ b/Src/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "3.0.100-preview8-013317" + "version": "3.0.100-preview9-013927" } } \ No newline at end of file