From 6965fcfa46ee009826ea7f9f5a96150edecca71f Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 31 Mar 2014 15:47:36 +1300 Subject: [PATCH] -Fixed potential race condition serializing F# objects -Fixed schema divisible sometimes incorrectly validating to false -Fixed not calling virtual ShouldSerialize methods --- .../Bson/BsonReaderTests.cs | 1 + .../Converters/XmlNodeConverterTest.cs | 16 + .../Samples/Schema/JTokenIsValid.cs | 4 +- Src/Newtonsoft.Json.Tests/JsonConvertTest.cs | 2 +- Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs | 1 + .../Newtonsoft.Json.Tests.Net20.csproj | 41 + .../Newtonsoft.Json.Tests.Net35.csproj | 40 + .../Newtonsoft.Json.Tests.Net40.csproj | 40 + .../Newtonsoft.Json.Tests.Portable.csproj | 40 + .../Newtonsoft.Json.Tests.Portable40.csproj | 42 + .../Newtonsoft.Json.Tests.csproj | 40 + .../Properties/AssemblyInfo.cs | 2 +- .../Schema/ExtensionsTests.cs | 10 + .../Serialization/ExtensionDataTests.cs | 599 +++ .../JsonSerializerCollectionsTests.cs | 1604 ++++++++ .../Serialization/JsonSerializerTest.cs | 3257 +---------------- .../Serialization/ShouldSerializeTests.cs | 543 +++ .../Serialization/TypeNameHandlingTests.cs | 28 +- Src/Newtonsoft.Json.Tests/TestObjects/Aa.cs | 32 + .../TestObjects/AnswerFilterModel.cs | 93 + .../TestObjects/Antworten.cs | 33 + Src/Newtonsoft.Json.Tests/TestObjects/Bb.cs | 32 + .../TestObjects/Component.cs | 40 + ...ataContractSerializationAttributesClass.cs | 47 + .../TestObjects/DateTimeWrapper.cs | 34 + .../TestObjects/DecimalTestClass.cs | 33 + .../TestObjects/DirectoryAccount.cs | 60 + .../TestObjects/Event1.cs | 40 + .../TestObjects/GameObject.cs | 49 + .../TestObjects/IMyInterface.cs | 160 + .../TestObjects/IdReferenceResolver.cs | 68 + .../TestObjects/IntToFloatConverter.cs | 47 + Src/Newtonsoft.Json.Tests/TestObjects/Item.cs | 41 + .../TestObjects/MetroPropertyNameResolver.cs | 42 + .../TestObjects/MetroStringConverter.cs | 60 + .../TestObjects/NullableGuid.cs | 34 + .../TestObjects/ParticipantEntity.cs | 56 + .../TestObjects/PersonReference.cs | 37 + .../TestObjects/PersonSerializable.cs | 56 + .../PersonWithPrivateConstructor.cs | 43 + ...ataContractSerializationAttributesClass.cs | 46 + .../TestObjects/PropertyItemConverter.cs | 35 + .../TestObjects/Ratio.cs | 236 ++ .../TestObjects/RequiredObject.cs | 45 + .../TestObjects/SelectListItem.cs | 34 + .../TestObjects/TestComponent.cs | 40 + .../TestObjects/TestComponentSimple.cs | 38 + .../TestObjects/TestObject.cs | 43 + .../TestObjects/UriGuidTimeSpanTestClass.cs | 38 + .../TestObjects/Widget.cs | 32 + .../TestObjects/Widget1.cs | 32 + .../TestObjects/WidgetId.cs | 32 + .../TestObjects/WidgetId1.cs | 33 + .../TestObjects/WidgetIdJsonConverter.cs | 50 + .../TestObjects/WithEnums.cs | 40 + .../Converters/DiscriminatedUnionConverter.cs | 1 + Src/Newtonsoft.Json/JsonConvert.cs | 16 +- Src/Newtonsoft.Json/JsonValidatingReader.cs | 2 +- Src/Newtonsoft.Json/Linq/JObject.cs | 1 - .../Properties/AssemblyInfo.cs | 2 +- .../DynamicReflectionDelegateFactory.cs | 2 +- Src/Newtonsoft.Json/Utilities/FSharpUtils.cs | 46 +- .../Utilities/ReflectionUtils.cs | 3 + 63 files changed, 4992 insertions(+), 3302 deletions(-) create mode 100644 Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs create mode 100644 Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs create mode 100644 Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Aa.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/AnswerFilterModel.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Antworten.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Bb.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Component.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/DataContractSerializationAttributesClass.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/DateTimeWrapper.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/DecimalTestClass.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/DirectoryAccount.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Event1.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/GameObject.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/IMyInterface.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/IdReferenceResolver.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/IntToFloatConverter.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Item.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/MetroPropertyNameResolver.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/MetroStringConverter.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/NullableGuid.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/ParticipantEntity.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/PersonReference.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/PersonSerializable.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/PersonWithPrivateConstructor.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/PocoDataContractSerializationAttributesClass.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/PropertyItemConverter.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Ratio.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/RequiredObject.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/SelectListItem.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/TestComponent.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/TestComponentSimple.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/TestObject.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/UriGuidTimeSpanTestClass.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Widget.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/Widget1.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/WidgetId.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/WidgetId1.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/WidgetIdJsonConverter.cs create mode 100644 Src/Newtonsoft.Json.Tests/TestObjects/WithEnums.cs diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs index 3595ae4b..81a497a9 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs @@ -29,6 +29,7 @@ using System.Globalization; using System.Reflection; using System.Runtime.Serialization; using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Tests.TestObjects; #if !(NET20 || NET35 || PORTABLE) using System.Numerics; #endif diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs index 619636b4..c6b07a8c 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs @@ -115,6 +115,22 @@ namespace Newtonsoft.Json.Tests.Converters } #if !NET20 + [Test] + public void GroupElementsOfTheSameName() + { + string xml = "

Text1Span1 Span2 Text2

"; + + string json = JsonConvert.SerializeXNode(XElement.Parse(xml)); + + Assert.AreEqual(@"{""root"":{""p"":{""#text"":[""Text1"","" Text2""],""span"":[""Span1"",""Span2""]}}}", json); + + XDocument doc = JsonConvert.DeserializeXNode(json); + + Assert.AreEqual(@" +

Text1 Text2Span1Span2

+
", doc.ToString()); + } + [Test] public void SerializeEmptyDocument() { diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs index f3063b57..5844862e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs @@ -13,7 +13,6 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { #region Usage JsonSchema schema = JsonSchema.Parse(@"{ - 'description': 'A person', 'type': 'object', 'properties': { 'name': {'type':'string'}, @@ -29,7 +28,8 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"); - bool valid = person.IsValid(schema); + IList errorMessages; + bool valid = person.IsValid(schema, out errorMessages); Console.WriteLine(valid); // true diff --git a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs index 34f4d5f2..9e32bea3 100644 --- a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs @@ -952,7 +952,7 @@ now brown cow?", '"', true); #pragma warning disable 612,618 Task taskVoid = JsonConvert.PopulateObjectAsync("{'Name':'Appended'}", p, new JsonSerializerSettings { - Converters = new List { new JsonSerializerTest.StringAppenderConverter() } + Converters = new List { new StringAppenderConverter() } }); #pragma warning restore 612,618 diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs index 1017ea95..d7975c89 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.IO; +using Newtonsoft.Json.Tests.TestObjects; #if !(NET20 || NET35 || PORTABLE) using System.Numerics; #endif diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj index bd3693d7..dbe0165e 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj @@ -98,15 +98,24 @@ + + + + + + + + + @@ -116,38 +125,59 @@ Component + + + + + + + + + + + + + + + + + + + + + @@ -157,6 +187,7 @@ + @@ -237,11 +268,21 @@ + + + + + + + + + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj index 05633c52..760b968e 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj @@ -140,16 +140,24 @@ + + + + + + + + @@ -158,15 +166,34 @@ Component + + + + + + + + + + + + + + + + + + + @@ -199,8 +226,15 @@ + + + + + + + @@ -285,6 +319,12 @@ + + + + + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj index d7fa9a92..f1e9baa4 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net40.csproj @@ -262,16 +262,24 @@ + + + + + + + + @@ -280,15 +288,33 @@ Component + + + + + + + + + + + + + + + + + + @@ -317,12 +343,20 @@ + + + + + + + + @@ -407,6 +441,12 @@ + + + + + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj index 73528136..667ead78 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable.csproj @@ -146,31 +146,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -199,12 +225,20 @@ + + + + + + + + @@ -289,6 +323,12 @@ + + + + + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj index e3293651..76808865 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Portable40.csproj @@ -142,29 +142,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -193,12 +221,20 @@ + + + + + + + + @@ -283,6 +319,12 @@ + + + + + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index fee4e78f..c28811c6 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -237,6 +237,7 @@ + @@ -248,17 +249,23 @@ + + + + + + @@ -266,6 +273,7 @@ + @@ -279,25 +287,35 @@ Component + + + + + + + + + + @@ -311,17 +329,25 @@ + + + + + + + + @@ -331,14 +357,18 @@ + + + + @@ -351,11 +381,21 @@ + + + + + + + + + + diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index 3ee5554b..91ba79cf 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -75,4 +75,4 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("6.0.0.0")] -[assembly: AssemblyFileVersion("6.0.1.17117")] +[assembly: AssemblyFileVersion("6.0.1.17131")] diff --git a/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs b/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs index 0f31119d..d9c40421 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs @@ -308,6 +308,16 @@ namespace Newtonsoft.Json.Tests.Schema }); } + [Test] + public void DivisibleBy_Approx() + { + JsonSchema schema = new JsonSchema(); + schema.DivisibleBy = 0.01; + + JValue v = new JValue(20.49); + v.Validate(schema); + } + [Test] public void UniqueItems_SimpleUnique() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs new file mode 100644 index 00000000..f9f3535a --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs @@ -0,0 +1,599 @@ +#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; +using System.Collections.Generic; +using System.Text; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Tests.TestObjects; +using NUnit.Framework; + +namespace Newtonsoft.Json.Tests.Serialization +{ + [TestFixture] + public class ExtensionDataTests : TestFixtureBase + { + public class ExtensionDataDeserializeWithNonDefaultConstructor + { + public ExtensionDataDeserializeWithNonDefaultConstructor(string name) + { + Name = name; + } + + [JsonExtensionData] + public IDictionary _extensionData; + + public string Name { get; set; } + } + + [Test] + public void ExtensionDataDeserializeWithNonDefaultConstructorTest() + { + ExtensionDataDeserializeWithNonDefaultConstructor c = new ExtensionDataDeserializeWithNonDefaultConstructor("Name!"); + c._extensionData = new Dictionary + { + { "Key!", "Value!" } + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Name"": ""Name!"", + ""Key!"": ""Value!"" +}", json); + + var c2 = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Name!", c2.Name); + Assert.IsNotNull(c2._extensionData); + Assert.AreEqual(1, c2._extensionData.Count); + Assert.AreEqual("Value!", (string)c2._extensionData["Key!"]); + } + + [Test] + public void ExtensionDataWithNull() + { + string json = @"{ + 'TaxRate': 0.125, + 'a':null + }"; + + var invoice = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(JTokenType.Null, invoice._additionalData["a"].Type); + Assert.AreEqual(typeof(double), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType()); + + string result = JsonConvert.SerializeObject(invoice); + + Assert.AreEqual(@"{""TaxRate"":0.125,""a"":null}", result); + } + + [Test] + public void ExtensionDataFloatParseHandling() + { + string json = @"{ + 'TaxRate': 0.125, + 'a':null + }"; + + var invoice = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + FloatParseHandling = FloatParseHandling.Decimal + }); + + Assert.AreEqual(typeof(decimal), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType()); + } + +#pragma warning disable 649 + class ExtendedObject + { + [JsonExtensionData] + internal IDictionary _additionalData; + } +#pragma warning restore 649 + +#pragma warning disable 169 + public class CustomerInvoice + { + // we're only modifing the tax rate + public decimal TaxRate { get; set; } + + // everything else gets stored here + [JsonExtensionData] + private IDictionary _additionalData; + } +#pragma warning restore 169 + + [Test] + public void ExtensionDataExample() + { + string json = @"{ + 'HourlyRate': 150, + 'Hours': 40, + 'TaxRate': 0.125 + }"; + + var invoice = JsonConvert.DeserializeObject(json); + + // increase tax to 15% + invoice.TaxRate = 0.15m; + + string result = JsonConvert.SerializeObject(invoice); + // { + // 'TaxRate': 0.15, + // 'HourlyRate': 150, + // 'Hours': 40 + // } + + Assert.AreEqual(@"{""TaxRate"":0.15,""HourlyRate"":150,""Hours"":40}", result); + } + + public class ExtensionDataTestClass + { + public string Name { get; set; } + + [JsonProperty("custom_name")] + public string CustomName { get; set; } + + [JsonIgnore] + public IList Ignored { get; set; } + + public bool GetPrivate { get; internal set; } + + public bool GetOnly + { + get { return true; } + } + + public readonly string Readonly = "Readonly"; + public IList Ints { get; set; } + + [JsonExtensionData] + internal IDictionary ExtensionData { get; set; } + + public ExtensionDataTestClass() + { + Ints = new List { 0 }; + } + } + + public class JObjectExtensionDataTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + public JObject ExtensionData { get; set; } + } + + [Test] + public void RoundTripJObjectExtensionData() + { + JObjectExtensionDataTestClass c = new JObjectExtensionDataTestClass(); + c.Name = "Name!"; + c.ExtensionData = new JObject + { + { "one", 1 }, + { "two", "II" }, + { "three", new JArray(1, 1, 1) } + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + JObjectExtensionDataTestClass c2 = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Name!", c2.Name); + Assert.IsTrue(JToken.DeepEquals(c.ExtensionData, c2.ExtensionData)); + } + + [Test] + public void ExtensionDataTest() + { + string json = @"{ + ""Ints"": [1,2,3], + ""Ignored"": [1,2,3], + ""Readonly"": ""Readonly"", + ""Name"": ""Actually set!"", + ""CustomName"": ""Wrong name!"", + ""GetPrivate"": true, + ""GetOnly"": true, + ""NewValueSimple"": true, + ""NewValueComplex"": [1,2,3] +}"; + + ExtensionDataTestClass c = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Actually set!", c.Name); + Assert.AreEqual(4, c.Ints.Count); + + Assert.AreEqual("Readonly", (string)c.ExtensionData["Readonly"]); + Assert.AreEqual("Wrong name!", (string)c.ExtensionData["CustomName"]); + Assert.AreEqual(true, (bool)c.ExtensionData["GetPrivate"]); + Assert.AreEqual(true, (bool)c.ExtensionData["GetOnly"]); + Assert.AreEqual(true, (bool)c.ExtensionData["NewValueSimple"]); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["NewValueComplex"])); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["Ignored"])); + + Assert.AreEqual(7, c.ExtensionData.Count); + } + + public class MultipleExtensionDataAttributesTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + internal IDictionary ExtensionData1 { get; set; } + + [JsonExtensionData] + internal IDictionary ExtensionData2 { get; set; } + } + + public class ExtensionDataAttributesInheritanceTestClass : MultipleExtensionDataAttributesTestClass + { + [JsonExtensionData] + internal IDictionary ExtensionData0 { get; set; } + } + + public class FieldExtensionDataAttributeTestClass + { + [JsonExtensionData] + internal IDictionary ExtensionData; + } + + public class PublicExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + public IDictionary ExtensionData; + } + + public class PublicExtensionDataAttributeTestClassWithNonDefaultConstructor + { + public string Name { get; set; } + + public PublicExtensionDataAttributeTestClassWithNonDefaultConstructor(string name) + { + Name = name; + } + + [JsonExtensionData] + public IDictionary ExtensionData; + } + + public class PublicNoReadExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData(ReadData = false)] + public IDictionary ExtensionData; + } + + public class PublicNoWriteExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData(WriteData = false)] + public IDictionary ExtensionData; + } + + public class PublicJTokenExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + public IDictionary ExtensionData; + } + + [Test] + public void DeserializeDirectoryAccount() + { + string json = @"{'DisplayName':'John Smith', 'SAMAccountName':'contoso\\johns'}"; + + DirectoryAccount account = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("John Smith", account.DisplayName); + Assert.AreEqual("contoso", account.Domain); + Assert.AreEqual("johns", account.UserName); + } + + [Test] + public void SerializePublicExtensionData() + { + string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { "Test", 1 } + } + }); + + Assert.AreEqual(@"{""Name"":""Name!"",""Test"":1}", json); + } + + [Test] + public void SerializePublicExtensionDataNull() + { + string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass + { + Name = "Name!" + }); + + Assert.AreEqual(@"{""Name"":""Name!""}", json); + } + + [Test] + public void SerializePublicNoWriteExtensionData() + { + string json = JsonConvert.SerializeObject(new PublicNoWriteExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { "Test", 1 } + } + }); + + Assert.AreEqual(@"{""Name"":""Name!""}", json); + } + + [Test] + public void DeserializeNoReadPublicExtensionData() + { + PublicNoReadExtensionDataAttributeTestClass c = JsonConvert.DeserializeObject(@"{""Name"":""Name!"",""Test"":1}"); + + Assert.AreEqual(null, c.ExtensionData); + } + + [Test] + public void SerializePublicExtensionDataCircularReference() + { + var c = new PublicExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { "Test", 1 } + } + }; + c.ExtensionData["Self"] = c; + + string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ + ""$id"": ""1"", + ""Name"": ""Name!"", + ""Test"": 1, + ""Self"": { + ""$ref"": ""1"" + } +}", json); + + var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }); + + Assert.AreEqual("Name!", c2.Name); + + PublicExtensionDataAttributeTestClass bizzaroC2 = (PublicExtensionDataAttributeTestClass)c2.ExtensionData["Self"]; + + Assert.AreEqual(c2, bizzaroC2); + Assert.AreEqual(1, (long)bizzaroC2.ExtensionData["Test"]); + } + + [Test] + public void DeserializePublicJTokenExtensionDataCircularReference() + { + string json = @"{ + ""$id"": ""1"", + ""Name"": ""Name!"", + ""Test"": 1, + ""Self"": { + ""$ref"": ""1"" + } +}"; + + var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }); + + Assert.AreEqual("Name!", c2.Name); + + JObject bizzaroC2 = (JObject)c2.ExtensionData["Self"]; + + Assert.AreEqual("Name!", (string)bizzaroC2["Name"]); + Assert.AreEqual(1, (int)bizzaroC2["Test"]); + + Assert.AreEqual(1, (int)c2.ExtensionData["Test"]); + } + + [Test] + public void DeserializePublicExtensionDataTypeNamdHandling() + { + string json = @"{ + ""$id"": ""1"", + ""Name"": ""Name!"", + ""Test"": 1, + ""Self"": { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", + ""HourlyWage"": 2.0, + ""Name"": null, + ""BirthDate"": ""0001-01-01T00:00:00"", + ""LastModified"": ""0001-01-01T00:00:00"" + } +}"; + + PublicExtensionDataAttributeTestClass c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + + Assert.AreEqual("Name!", c2.Name); + + WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"]; + + Assert.AreEqual(2m, bizzaroC2.HourlyWage); + } + + [Test] + public void DeserializePublicExtensionDataTypeNamdHandlingNonDefaultConstructor() + { + string json = @"{ + ""$id"": ""1"", + ""Name"": ""Name!"", + ""Test"": 1, + ""Self"": { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", + ""HourlyWage"": 2.0, + ""Name"": null, + ""BirthDate"": ""0001-01-01T00:00:00"", + ""LastModified"": ""0001-01-01T00:00:00"" + } +}"; + + PublicExtensionDataAttributeTestClassWithNonDefaultConstructor c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + + Assert.AreEqual("Name!", c2.Name); + + WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"]; + + Assert.AreEqual(2m, bizzaroC2.HourlyWage); + } + + [Test] + public void SerializePublicExtensionDataTypeNamdHandling() + { + PublicExtensionDataAttributeTestClass c = new PublicExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { + "Test", new WagePerson + { + HourlyWage = 2.1m + } + } + } + }; + + string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ + ""$type"": ""Newtonsoft.Json.Tests.Serialization.ExtensionDataTests+PublicExtensionDataAttributeTestClass, Newtonsoft.Json.Tests"", + ""Name"": ""Name!"", + ""Test"": { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", + ""HourlyWage"": 2.1, + ""Name"": null, + ""BirthDate"": ""0001-01-01T00:00:00"", + ""LastModified"": ""0001-01-01T00:00:00"" + } +}", json); + } + + [Test] + public void DeserializePublicExtensionData() + { + string json = @"{ + 'Name':'Name!', + 'NoMatch':'NoMatch!', + 'ExtensionData':{'HAI':true} +}"; + + var c = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Name!", c.Name); + Assert.AreEqual(2, c.ExtensionData.Count); + + Assert.AreEqual("NoMatch!", (string)c.ExtensionData["NoMatch"]); + + // the ExtensionData property is put into the extension data + // inception + var o = (JObject)c.ExtensionData["ExtensionData"]; + Assert.AreEqual(1, o.Count); + Assert.IsTrue(JToken.DeepEquals(new JObject { { "HAI", true } }, o)); + } + + [Test] + public void FieldExtensionDataAttributeTest_Serialize() + { + FieldExtensionDataAttributeTestClass c = new FieldExtensionDataAttributeTestClass + { + ExtensionData = new Dictionary() + }; + + string json = JsonConvert.SerializeObject(c); + + Assert.AreEqual("{}", json); + } + + [Test] + public void FieldExtensionDataAttributeTest_Deserialize() + { + var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); + + Assert.AreEqual(2, c.ExtensionData.Count); + Assert.AreEqual(1, (long)c.ExtensionData["first"]); + Assert.AreEqual(2, (long)c.ExtensionData["second"]); + } + + [Test] + public void MultipleExtensionDataAttributesTest() + { + var c = JsonConvert.DeserializeObject("{'first':[1],'second':[2]}"); + + Assert.AreEqual(null, c.ExtensionData1); + Assert.AreEqual(2, c.ExtensionData2.Count); + Assert.AreEqual(1, (int)((JArray)c.ExtensionData2["first"])[0]); + Assert.AreEqual(2, (int)((JArray)c.ExtensionData2["second"])[0]); + } + + [Test] + public void ExtensionDataAttributesInheritanceTest() + { + var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); + + Assert.AreEqual(null, c.ExtensionData1); + Assert.AreEqual(null, c.ExtensionData2); + Assert.AreEqual(2, c.ExtensionData0.Count); + Assert.AreEqual(1, (int)c.ExtensionData0["first"]); + Assert.AreEqual(2, (int)c.ExtensionData0["second"]); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs new file mode 100644 index 00000000..68e9fd31 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs @@ -0,0 +1,1604 @@ +#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; +using System.Collections; +#if !(NET35 || NET20 || PORTABLE || PORTABLE40) +using System.Collections.Concurrent; +#endif +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.IO; +#if NET20 +using Newtonsoft.Json.Utilities.LinqBridge; +#else +using System.Linq; +#endif +using System.Text; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Tests.TestObjects; +using NUnit.Framework; + +namespace Newtonsoft.Json.Tests.Serialization +{ + [TestFixture] + public class JsonSerializerCollectionsTests : TestFixtureBase + { + public class EnumerableClass : IEnumerable + { + private readonly IList _values; + + public EnumerableClass(IEnumerable values) + { + _values = new List(values); + } + + public IEnumerator GetEnumerator() + { + return _values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + [Test] + public void DeserializeIEnumerableFromConstructor() + { + string json = @"[ + 1, + 2, + null +]"; + + var result = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, result.Count()); + Assert.AreEqual(1, result.ElementAt(0)); + Assert.AreEqual(2, result.ElementAt(1)); + Assert.AreEqual(null, result.ElementAt(2)); + } + + public class EnumerableClassFailure : IEnumerable + { + private readonly IList _values; + + public EnumerableClassFailure() + { + _values = new List(); + } + + public IEnumerator GetEnumerator() + { + return _values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + [Test] + public void DeserializeIEnumerableFromConstructor_Failure() + { + string json = @"[ + ""One"", + ""II"", + ""3"" +]"; + + ExceptionAssert.Throws( + "Cannot create and populate list type Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+EnumerableClassFailure`1[System.String]. Path '', line 1, position 1.", + () => JsonConvert.DeserializeObject>(json)); + } + + public class PrivateDefaultCtorList : List + { + private PrivateDefaultCtorList() + { + } + } + + [Test] + public void DeserializePrivateListCtor() + { + ExceptionAssert.Throws( + "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+PrivateDefaultCtorList`1[System.Int32]. Path '', line 1, position 1.", + () => JsonConvert.DeserializeObject>("[1,2]") + ); + + var list = JsonConvert.DeserializeObject>("[1,2]", new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }); + + Assert.AreEqual(2, list.Count); + } + + public class PrivateDefaultCtorWithIEnumerableCtorList : List + { + private PrivateDefaultCtorWithIEnumerableCtorList() + { + } + + public PrivateDefaultCtorWithIEnumerableCtorList(IEnumerable values) + : base(values) + { + Add(default(T)); + } + } + + [Test] + public void DeserializePrivateListConstructor() + { + var list = JsonConvert.DeserializeObject>("[1,2]"); + + Assert.AreEqual(3, list.Count); + Assert.AreEqual(1, list[0]); + Assert.AreEqual(2, list[1]); + Assert.AreEqual(0, list[2]); + } + + [Test] + public void DeserializeNonIsoDateDictionaryKey() + { + Dictionary d = JsonConvert.DeserializeObject>(@"{""04/28/2013 00:00:00"":""test""}"); + + Assert.AreEqual(1, d.Count); + + DateTime key = DateTime.Parse("04/28/2013 00:00:00", CultureInfo.InvariantCulture); + Assert.AreEqual("test", d[key]); + } + + [Test] + public void DeserializeNonGenericList() + { + IList l = JsonConvert.DeserializeObject("['string!']"); + + Assert.AreEqual(typeof(List), l.GetType()); + Assert.AreEqual(1, l.Count); + Assert.AreEqual("string!", l[0]); + } + +#if !(NET40 || NET35 || NET20 || PORTABLE40) + [Test] + public void DeserializeReadOnlyListInterface() + { + IReadOnlyList list = JsonConvert.DeserializeObject>("[1,2,3]"); + + Assert.AreEqual(3, list.Count); + Assert.AreEqual(1, list[0]); + Assert.AreEqual(2, list[1]); + Assert.AreEqual(3, list[2]); + } + + [Test] + public void DeserializeReadOnlyCollectionInterface() + { + IReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); + + Assert.AreEqual(3, list.Count); + + Assert.AreEqual(1, list.ElementAt(0)); + Assert.AreEqual(2, list.ElementAt(1)); + Assert.AreEqual(3, list.ElementAt(2)); + } + + [Test] + public void DeserializeReadOnlyCollection() + { + ReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); + + Assert.AreEqual(3, list.Count); + + Assert.AreEqual(1, list[0]); + Assert.AreEqual(2, list[1]); + Assert.AreEqual(3, list[2]); + } + + [Test] + public void DeserializeReadOnlyDictionaryInterface() + { + IReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); + + Assert.AreEqual(2, dic.Count); + + Assert.AreEqual(1, dic["one"]); + Assert.AreEqual(2, dic["two"]); + + CustomAssert.IsInstanceOfType(typeof(ReadOnlyDictionary), dic); + } + + [Test] + public void DeserializeReadOnlyDictionary() + { + ReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); + + Assert.AreEqual(2, dic.Count); + + Assert.AreEqual(1, dic["one"]); + Assert.AreEqual(2, dic["two"]); + } + + public class CustomReadOnlyDictionary : IReadOnlyDictionary + { + private readonly IDictionary _dictionary; + + public CustomReadOnlyDictionary(IDictionary dictionary) + { + _dictionary = dictionary; + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public IEnumerable Keys + { + get { return _dictionary.Keys; } + } + + public bool TryGetValue(TKey key, out TValue value) + { + return _dictionary.TryGetValue(key, out value); + } + + public IEnumerable Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return _dictionary[key]; } + } + + public int Count + { + get { return _dictionary.Count; } + } + + public IEnumerator> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + + [Test] + public void SerializeCustomReadOnlyDictionary() + { + IDictionary d = new Dictionary + { + { "one", 1 }, + { "two", 2 } + }; + + CustomReadOnlyDictionary dic = new CustomReadOnlyDictionary(d); + + string json = JsonConvert.SerializeObject(dic, Formatting.Indented); + Assert.AreEqual(@"{ + ""one"": 1, + ""two"": 2 +}", json); + } + + public class CustomReadOnlyCollection : IReadOnlyCollection + { + private readonly IList _values; + + public CustomReadOnlyCollection(IList values) + { + _values = values; + } + + public int Count + { + get { return _values.Count; } + } + + public IEnumerator GetEnumerator() + { + return _values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _values.GetEnumerator(); + } + } + + [Test] + public void SerializeCustomReadOnlyCollection() + { + IList l = new List + { + 1, + 2, + 3 + }; + + CustomReadOnlyCollection list = new CustomReadOnlyCollection(l); + + string json = JsonConvert.SerializeObject(list, Formatting.Indented); + Assert.AreEqual(@"[ + 1, + 2, + 3 +]", json); + } +#endif + [Test] + public void TestEscapeDictionaryStrings() + { + const string s = @"host\user"; + string serialized = JsonConvert.SerializeObject(s); + Assert.AreEqual(@"""host\\user""", serialized); + + Dictionary d1 = new Dictionary(); + d1.Add(5, s); + Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1)); + + Dictionary d2 = new Dictionary(); + d2.Add(s, 5); + Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2)); + } + + public class GenericListTestClass + { + public List GenericList { get; set; } + + public GenericListTestClass() + { + GenericList = new List(); + } + } + + [Test] + public void DeserializeExistingGenericList() + { + GenericListTestClass c = new GenericListTestClass(); + c.GenericList.Add("1"); + c.GenericList.Add("2"); + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + GenericListTestClass newValue = JsonConvert.DeserializeObject(json); + Assert.AreEqual(2, newValue.GenericList.Count); + Assert.AreEqual(typeof(List), newValue.GenericList.GetType()); + } + + [Test] + public void DeserializeSimpleKeyValuePair() + { + List> list = new List>(); + list.Add(new KeyValuePair("key1", "value1")); + list.Add(new KeyValuePair("key2", "value2")); + + string json = JsonConvert.SerializeObject(list); + + Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json); + + List> result = JsonConvert.DeserializeObject>>(json); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("key1", result[0].Key); + Assert.AreEqual("value1", result[0].Value); + Assert.AreEqual("key2", result[1].Key); + Assert.AreEqual("value2", result[1].Value); + } + + [Test] + public void DeserializeComplexKeyValuePair() + { + DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc); + + List> list = new List>(); + list.Add(new KeyValuePair("key1", new WagePerson + { + BirthDate = dateTime, + Department = "Department1", + LastModified = dateTime, + HourlyWage = 1 + })); + list.Add(new KeyValuePair("key2", new WagePerson + { + BirthDate = dateTime, + Department = "Department2", + LastModified = dateTime, + HourlyWage = 2 + })); + + string json = JsonConvert.SerializeObject(list, Formatting.Indented); + + Assert.AreEqual(@"[ + { + ""Key"": ""key1"", + ""Value"": { + ""HourlyWage"": 1.0, + ""Name"": null, + ""BirthDate"": ""2000-12-01T23:01:01Z"", + ""LastModified"": ""2000-12-01T23:01:01Z"" + } + }, + { + ""Key"": ""key2"", + ""Value"": { + ""HourlyWage"": 2.0, + ""Name"": null, + ""BirthDate"": ""2000-12-01T23:01:01Z"", + ""LastModified"": ""2000-12-01T23:01:01Z"" + } + } +]", json); + + List> result = JsonConvert.DeserializeObject>>(json); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("key1", result[0].Key); + Assert.AreEqual(1, result[0].Value.HourlyWage); + Assert.AreEqual("key2", result[1].Key); + Assert.AreEqual(2, result[1].Value.HourlyWage); + } + + [Test] + public void StringListAppenderConverterTest() + { + Movie p = new Movie(); + p.ReleaseCountries = new List { "Existing" }; + + JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings + { + Converters = new List { new StringListAppenderConverter() } + }); + + Assert.AreEqual(2, p.ReleaseCountries.Count); + Assert.AreEqual("Existing", p.ReleaseCountries[0]); + Assert.AreEqual("Appended", p.ReleaseCountries[1]); + } + + [Test] + public void StringAppenderConverterTest() + { + Movie p = new Movie(); + p.Name = "Existing,"; + + JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings + { + Converters = new List { new StringAppenderConverter() } + }); + + Assert.AreEqual("Existing,Appended", p.Name); + } + + [Test] + public void DeserializeIDictionary() + { + IDictionary dictionary = JsonConvert.DeserializeObject("{'name':'value!'}"); + Assert.AreEqual(1, dictionary.Count); + Assert.AreEqual("value!", dictionary["name"]); + } + + [Test] + public void DeserializeIList() + { + IList list = JsonConvert.DeserializeObject("['1', 'two', 'III']"); + Assert.AreEqual(3, list.Count); + } + + [Test] + public void NullableValueGenericDictionary() + { + IDictionary v1 = new Dictionary + { + { "First", 1 }, + { "Second", null }, + { "Third", 3 } + }; + + string json = JsonConvert.SerializeObject(v1, Formatting.Indented); + + Assert.AreEqual(@"{ + ""First"": 1, + ""Second"": null, + ""Third"": 3 +}", json); + + IDictionary v2 = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(3, v2.Count); + Assert.AreEqual(1, v2["First"]); + Assert.AreEqual(null, v2["Second"]); + Assert.AreEqual(3, v2["Third"]); + } + +#if !(NET35 || NET20 || PORTABLE || PORTABLE40) + [Test] + public void DeserializeConcurrentDictionary() + { + IDictionary components = new Dictionary + { + { "Key!", new TestObjects.Component() } + }; + GameObject go = new GameObject + { + Components = new ConcurrentDictionary(components), + Id = "Id!", + Name = "Name!" + }; + + string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Components"": { + ""Key!"": {} + }, + ""Id"": ""Id!"", + ""Name"": ""Name!"" +}", originalJson); + + GameObject newObject = JsonConvert.DeserializeObject(originalJson); + + Assert.AreEqual(1, newObject.Components.Count); + Assert.AreEqual("Id!", newObject.Id); + Assert.AreEqual("Name!", newObject.Name); + } +#endif + + [Test] + public void DeserializeKeyValuePairArray() + { + string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; + + IList>> values = JsonConvert.DeserializeObject>>>(json); + + Assert.AreEqual(2, values.Count); + Assert.AreEqual("aaa", values[0].Key); + Assert.AreEqual(2, values[0].Value.Count); + Assert.AreEqual("1", values[0].Value[0]); + Assert.AreEqual("2", values[0].Value[1]); + Assert.AreEqual("bbb", values[1].Key); + Assert.AreEqual(2, values[1].Value.Count); + Assert.AreEqual("3", values[1].Value[0]); + Assert.AreEqual("4", values[1].Value[1]); + } + + [Test] + public void DeserializeNullableKeyValuePairArray() + { + string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; + + IList>?> values = JsonConvert.DeserializeObject>?>>(json); + + Assert.AreEqual(3, values.Count); + Assert.AreEqual("aaa", values[0].Value.Key); + Assert.AreEqual(2, values[0].Value.Value.Count); + Assert.AreEqual("1", values[0].Value.Value[0]); + Assert.AreEqual("2", values[0].Value.Value[1]); + Assert.AreEqual(null, values[1]); + Assert.AreEqual("bbb", values[2].Value.Key); + Assert.AreEqual(2, values[2].Value.Value.Count); + Assert.AreEqual("3", values[2].Value.Value[0]); + Assert.AreEqual("4", values[2].Value.Value[1]); + } + + [Test] + public void DeserializeNullToNonNullableKeyValuePairArray() + { + string json = @"[ null ]"; + + ExceptionAssert.Throws( + "Cannot convert null value to KeyValuePair. Path '[0]', line 1, position 6.", + () => { JsonConvert.DeserializeObject>>>(json); }); + } + +#if !(NET40 || NET35 || NET20 || PORTABLE40) + public class PopulateReadOnlyTestClass + { + public IList NonReadOnlyList { get; set; } + public IDictionary NonReadOnlyDictionary { get; set; } + + public IList Array { get; set; } + + public IList List { get; set; } + public IDictionary Dictionary { get; set; } + + public IReadOnlyCollection IReadOnlyCollection { get; set; } + public ReadOnlyCollection ReadOnlyCollection { get; set; } + public IReadOnlyList IReadOnlyList { get; set; } + + public IReadOnlyDictionary IReadOnlyDictionary { get; set; } + public ReadOnlyDictionary ReadOnlyDictionary { get; set; } + + public PopulateReadOnlyTestClass() + { + NonReadOnlyList = new List { 1 }; + NonReadOnlyDictionary = new Dictionary { { "first", 2 } }; + + Array = new[] { 3 }; + + List = new ReadOnlyCollection(new[] { 4 }); + Dictionary = new ReadOnlyDictionary(new Dictionary { { "first", 5 } }); + + IReadOnlyCollection = new ReadOnlyCollection(new[] { 6 }); + ReadOnlyCollection = new ReadOnlyCollection(new[] { 7 }); + IReadOnlyList = new ReadOnlyCollection(new[] { 8 }); + + IReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 9 } }); + ReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 10 } }); + } + } + + [Test] + public void SerializeReadOnlyCollections() + { + PopulateReadOnlyTestClass c1 = new PopulateReadOnlyTestClass(); + + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + + Assert.AreEqual(@"{ + ""NonReadOnlyList"": [ + 1 + ], + ""NonReadOnlyDictionary"": { + ""first"": 2 + }, + ""Array"": [ + 3 + ], + ""List"": [ + 4 + ], + ""Dictionary"": { + ""first"": 5 + }, + ""IReadOnlyCollection"": [ + 6 + ], + ""ReadOnlyCollection"": [ + 7 + ], + ""IReadOnlyList"": [ + 8 + ], + ""IReadOnlyDictionary"": { + ""first"": 9 + }, + ""ReadOnlyDictionary"": { + ""first"": 10 + } +}", json); + } + + [Test] + public void PopulateReadOnlyCollections() + { + string json = @"{ + ""NonReadOnlyList"": [ + 11 + ], + ""NonReadOnlyDictionary"": { + ""first"": 12 + }, + ""Array"": [ + 13 + ], + ""List"": [ + 14 + ], + ""Dictionary"": { + ""first"": 15 + }, + ""IReadOnlyCollection"": [ + 16 + ], + ""ReadOnlyCollection"": [ + 17 + ], + ""IReadOnlyList"": [ + 18 + ], + ""IReadOnlyDictionary"": { + ""first"": 19 + }, + ""ReadOnlyDictionary"": { + ""first"": 20 + } +}"; + + var c2 = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(1, c2.NonReadOnlyDictionary.Count); + Assert.AreEqual(12, c2.NonReadOnlyDictionary["first"]); + + Assert.AreEqual(2, c2.NonReadOnlyList.Count); + Assert.AreEqual(1, c2.NonReadOnlyList[0]); + Assert.AreEqual(11, c2.NonReadOnlyList[1]); + + Assert.AreEqual(1, c2.Array.Count); + Assert.AreEqual(13, c2.Array[0]); + } +#endif + + [Test] + public void SerializeArray2D() + { + Array2D aa = new Array2D(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[,] { { 1, 1 }, { 1, 2 }, { 2, 1 }, { 2, 2 } }; + + string json = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json); + } + + [Test] + public void SerializeArray3D() + { + Array3D aa = new Array3D(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[, ,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; + + string json = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json); + } + + [Test] + public void SerializeArray3DWithConverter() + { + Array3DWithConverter aa = new Array3DWithConverter(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[, ,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; + + string json = JsonConvert.SerializeObject(aa, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Before"": ""Before!"", + ""Coordinates"": [ + [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 2.0 + ] + ], + [ + [ + 1.0, + 2.0, + 1.0 + ], + [ + 1.0, + 2.0, + 2.0 + ] + ], + [ + [ + 2.0, + 1.0, + 1.0 + ], + [ + 2.0, + 1.0, + 2.0 + ] + ], + [ + [ + 2.0, + 2.0, + 1.0 + ], + [ + 2.0, + 2.0, + 2.0 + ] + ] + ], + ""After"": ""After!"" +}", json); + } + + [Test] + public void DeserializeArray3DWithConverter() + { + string json = @"{ + ""Before"": ""Before!"", + ""Coordinates"": [ + [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 2.0 + ] + ], + [ + [ + 1.0, + 2.0, + 1.0 + ], + [ + 1.0, + 2.0, + 2.0 + ] + ], + [ + [ + 2.0, + 1.0, + 1.0 + ], + [ + 2.0, + 1.0, + 2.0 + ] + ], + [ + [ + 2.0, + 2.0, + 1.0 + ], + [ + 2.0, + 2.0, + 2.0 + ] + ] + ], + ""After"": ""After!"" +}"; + + Array3DWithConverter aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.GetLength(0)); + Assert.AreEqual(2, aa.Coordinates.GetLength(1)); + Assert.AreEqual(3, aa.Coordinates.GetLength(2)); + Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); + Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); + } + + [Test] + public void DeserializeArray2D() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}"; + + Array2D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.GetLength(0)); + Assert.AreEqual(2, aa.Coordinates.GetLength(1)); + Assert.AreEqual(1, aa.Coordinates[0, 0]); + Assert.AreEqual(2, aa.Coordinates[1, 1]); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeArray2D_WithTooManyItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2,3],[2,1],[2,2]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray2D_WithTooFewItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1],[2,1],[2,2]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray3D() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.GetLength(0)); + Assert.AreEqual(2, aa.Coordinates.GetLength(1)); + Assert.AreEqual(3, aa.Coordinates.GetLength(2)); + Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); + Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeArray3D_WithTooManyItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray3D_WithBadItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],{}]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Unexpected token when deserializing multidimensional array: StartObject. Path 'Coordinates[3][1]', line 1, position 99.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray3D_WithTooFewItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void SerializeEmpty3DArray() + { + Array3D aa = new Array3D(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new int[0, 0, 0]; + + string json = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}", json); + } + + [Test] + public void DeserializeEmpty3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(0, aa.Coordinates.GetLength(0)); + Assert.AreEqual(0, aa.Coordinates.GetLength(1)); + Assert.AreEqual(0, aa.Coordinates.GetLength(2)); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeIncomplete3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1"; + + ExceptionAssert.Throws( + null, + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeIncompleteNotTopLevel3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/"; + + ExceptionAssert.Throws( + null, + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeNull3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":null,""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(null, aa.Coordinates); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeSemiEmpty3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[]],""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(1, aa.Coordinates.GetLength(0)); + Assert.AreEqual(0, aa.Coordinates.GetLength(1)); + Assert.AreEqual(0, aa.Coordinates.GetLength(2)); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void SerializeReferenceTracked3DArray() + { + Event1 e1 = new Event1 + { + EventName = "EventName!" + }; + Event1[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; + IList values1 = new List + { + array1, + array1 + }; + + string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ + ""$id"": ""1"", + ""$values"": [ + { + ""$id"": ""2"", + ""$values"": [ + [ + { + ""$id"": ""3"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + }, + { + ""$ref"": ""3"" + } + ], + [ + { + ""$ref"": ""3"" + }, + { + ""$ref"": ""3"" + } + ] + ] + }, + { + ""$ref"": ""2"" + } + ] +}", json); + } + + [Test] + public void SerializeTypeName3DArray() + { + Event1 e1 = new Event1 + { + EventName = "EventName!" + }; + Event1[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; + IList values1 = new List + { + array1, + array1 + }; + + string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ + ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.TestObjects.Event1[,], Newtonsoft.Json.Tests]], mscorlib"", + ""$values"": [ + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1[,], Newtonsoft.Json.Tests"", + ""$values"": [ + [ + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + }, + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + } + ], + [ + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + }, + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + } + ] + ] + }, + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1[,], Newtonsoft.Json.Tests"", + ""$values"": [ + [ + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + }, + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + } + ], + [ + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + }, + { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Event1, Newtonsoft.Json.Tests"", + ""EventName"": ""EventName!"", + ""Venue"": null, + ""Performances"": null + } + ] + ] + } + ] +}", json); + + IList values2 = (IList)JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All + }); + + Assert.AreEqual(2, values2.Count); + Assert.AreEqual("EventName!", values2[0][0, 0].EventName); + } + + [Test] + public void PrimitiveValuesInObjectArray() + { + string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}"; + + ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Router", o.Action); + Assert.AreEqual("Navigate", o.Method); + Assert.AreEqual(2, o.Data.Length); + Assert.AreEqual("dashboard", o.Data[0]); + Assert.AreEqual(null, o.Data[1]); + } + + [Test] + public void ComplexValuesInObjectArray() + { + string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}"; + + ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Router", o.Action); + Assert.AreEqual("Navigate", o.Method); + Assert.AreEqual(3, o.Data.Length); + Assert.AreEqual("dashboard", o.Data[0]); + CustomAssert.IsInstanceOfType(typeof(JArray), o.Data[1]); + Assert.AreEqual(4, ((JArray)o.Data[1]).Count); + CustomAssert.IsInstanceOfType(typeof(JObject), o.Data[2]); + Assert.AreEqual(1, ((JObject)o.Data[2]).Count); + Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]); + } + +#if !NETFX_CORE + [Test] + public void SerializeArrayAsArrayList() + { + string jsonText = @"[3, ""somestring"",[1,2,3],{}]"; + ArrayList o = JsonConvert.DeserializeObject(jsonText); + + Assert.AreEqual(4, o.Count); + Assert.AreEqual(3, ((JArray)o[2]).Count); + Assert.AreEqual(0, ((JObject)o[3]).Count); + } +#endif + + [Test] + public void SerializeMemberGenericList() + { + Name name = new Name("The Idiot in Next To Me"); + + PhoneNumber p1 = new PhoneNumber("555-1212"); + PhoneNumber p2 = new PhoneNumber("444-1212"); + + name.pNumbers.Add(p1); + name.pNumbers.Add(p2); + + string json = JsonConvert.SerializeObject(name, Formatting.Indented); + + Assert.AreEqual(@"{ + ""personsName"": ""The Idiot in Next To Me"", + ""pNumbers"": [ + { + ""phoneNumber"": ""555-1212"" + }, + { + ""phoneNumber"": ""444-1212"" + } + ] +}", json); + + Name newName = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("The Idiot in Next To Me", newName.personsName); + + // not passed in as part of the constructor but assigned to pNumbers property + Assert.AreEqual(2, newName.pNumbers.Count); + Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber); + Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber); + } + + [Test] + public void CustomCollectionSerialization() + { + ProductCollection collection = new ProductCollection() + { + new Product() { Name = "Test1" }, + new Product() { Name = "Test2" }, + new Product() { Name = "Test3" } + }; + + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + + StringWriter sw = new StringWriter(); + + jsonSerializer.Serialize(sw, collection); + + Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}]", + sw.GetStringBuilder().ToString()); + + ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection)); + + CollectionAssert.AreEqual(collection, collectionNew); + } + + [Test] + public void GenericCollectionInheritance() + { + string json; + + GenericClass, string> foo1 = new GenericClass, string>(); + foo1.Items.Add(new GenericItem { Value = "Hello" }); + + json = JsonConvert.SerializeObject(new { selectList = foo1 }); + Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); + + GenericClass foo2 = new GenericClass(); + foo2.Items.Add(new NonGenericItem { Value = "Hello" }); + + json = JsonConvert.SerializeObject(new { selectList = foo2 }); + Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); + + NonGenericClass foo3 = new NonGenericClass(); + foo3.Items.Add(new NonGenericItem { Value = "Hello" }); + + json = JsonConvert.SerializeObject(new { selectList = foo3 }); + Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); + } + + [Test] + public void InheritedListSerialize() + { + Article a1 = new Article("a1"); + Article a2 = new Article("a2"); + + ArticleCollection articles1 = new ArticleCollection(); + articles1.Add(a1); + articles1.Add(a2); + + string jsonText = JsonConvert.SerializeObject(articles1); + + ArticleCollection articles2 = JsonConvert.DeserializeObject(jsonText); + + Assert.AreEqual(articles1.Count, articles2.Count); + Assert.AreEqual(articles1[0].Name, articles2[0].Name); + } + + [Test] + public void ReadOnlyCollectionSerialize() + { + ReadOnlyCollection r1 = new ReadOnlyCollection(new int[] { 0, 1, 2, 3, 4 }); + + string jsonText = JsonConvert.SerializeObject(r1); + + Assert.AreEqual("[0,1,2,3,4]", jsonText); + + ReadOnlyCollection r2 = JsonConvert.DeserializeObject>(jsonText); + + CollectionAssert.AreEqual(r1, r2); + } + + [Test] + public void SerializeGenericList() + { + Product p1 = new Product + { + Name = "Product 1", + Price = 99.95m, + ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), + }; + Product p2 = new Product + { + Name = "Product 2", + Price = 12.50m, + ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), + }; + + List products = new List(); + products.Add(p1); + products.Add(p2); + + string json = JsonConvert.SerializeObject(products, Formatting.Indented); + //[ + // { + // "Name": "Product 1", + // "ExpiryDate": "\/Date(978048000000)\/", + // "Price": 99.95, + // "Sizes": null + // }, + // { + // "Name": "Product 2", + // "ExpiryDate": "\/Date(1248998400000)\/", + // "Price": 12.50, + // "Sizes": null + // } + //] + + Assert.AreEqual(@"[ + { + ""Name"": ""Product 1"", + ""ExpiryDate"": ""2000-12-29T00:00:00Z"", + ""Price"": 99.95, + ""Sizes"": null + }, + { + ""Name"": ""Product 2"", + ""ExpiryDate"": ""2009-07-31T00:00:00Z"", + ""Price"": 12.50, + ""Sizes"": null + } +]", json); + } + + [Test] + public void DeserializeGenericList() + { + string json = @"[ + { + ""Name"": ""Product 1"", + ""ExpiryDate"": ""\/Date(978048000000)\/"", + ""Price"": 99.95, + ""Sizes"": null + }, + { + ""Name"": ""Product 2"", + ""ExpiryDate"": ""\/Date(1248998400000)\/"", + ""Price"": 12.50, + ""Sizes"": null + } + ]"; + + List products = JsonConvert.DeserializeObject>(json); + + Console.WriteLine(products.Count); + // 2 + + Product p1 = products[0]; + + Console.WriteLine(p1.Name); + // Product 1 + + Assert.AreEqual(2, products.Count); + Assert.AreEqual("Product 1", products[0].Name); + } + } + + public class Array2D + { + public string Before { get; set; } + public int[,] Coordinates { get; set; } + public string After { get; set; } + } + + public class Array3D + { + public string Before { get; set; } + public int[, ,] Coordinates { get; set; } + public string After { get; set; } + } + + public class Array3DWithConverter + { + public string Before { get; set; } + + [JsonProperty(ItemConverterType = typeof(IntToFloatConverter))] + public int[, ,] Coordinates { get; set; } + + public string After { get; set; } + } + + public class GenericItem + { + public T Value { get; set; } + } + + public class NonGenericItem : GenericItem + { + } + + public class GenericClass : IEnumerable + where T : GenericItem, new() + { + public IList Items { get; set; } + + public GenericClass() + { + Items = new List(); + } + + public IEnumerator GetEnumerator() + { + if (Items != null) + { + foreach (T item in Items) + { + yield return item; + } + } + else + yield break; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + public class NonGenericClass : GenericClass, string> + { + } + + public class StringListAppenderConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue(value); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + List existingStrings = (List)existingValue; + List newStrings = new List(existingStrings); + + reader.Read(); + + while (reader.TokenType != JsonToken.EndArray) + { + string s = (string)reader.Value; + newStrings.Add(s); + + reader.Read(); + } + + return newStrings; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(List)); + } + } + + public class StringAppenderConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue(value); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + string existingString = (string)existingValue; + string newString = existingString + (string)reader.Value; + + return newString; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(string)); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index f6d0aabc..88b9af6b 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -91,183 +91,6 @@ namespace Newtonsoft.Json.Tests.Serialization [TestFixture] public class JsonSerializerTest : TestFixtureBase { - [Test] - public void ExtensionDataWithNull() - { - string json = @"{ - 'TaxRate': 0.125, - 'a':null - }"; - - var invoice = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(JTokenType.Null, invoice._additionalData["a"].Type); - Assert.AreEqual(typeof(double), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType()); - - string result = JsonConvert.SerializeObject(invoice); - - Assert.AreEqual(@"{""TaxRate"":0.125,""a"":null}", result); - } - - [Test] - public void ExtensionDataFloatParseHandling() - { - string json = @"{ - 'TaxRate': 0.125, - 'a':null - }"; - - var invoice = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - FloatParseHandling = FloatParseHandling.Decimal - }); - - Assert.AreEqual(typeof(decimal), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType()); - } - -#pragma warning disable 649 - class ExtendedObject - { - [JsonExtensionData] - internal IDictionary _additionalData; - } -#pragma warning restore 649 - - public class GenericItem - { - public T Value { get; set; } - } - - public class NonGenericItem : GenericItem - { - } - - public class GenericClass : IEnumerable - where T : GenericItem, new() - { - public IList Items { get; set; } - - public GenericClass() - { - Items = new List(); - } - - public IEnumerator GetEnumerator() - { - if (Items != null) - { - foreach (T item in Items) - { - yield return item; - } - } - else - yield break; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - - public class NonGenericClass : GenericClass, string> - { - } - -#pragma warning disable 169 - public class CustomerInvoice - { - // we're only modifing the tax rate - public decimal TaxRate { get; set; } - - // everything else gets stored here - [JsonExtensionData] - private IDictionary _additionalData; - } -#pragma warning restore 169 - - [Test] - public void ExtensionDataExample() - { - string json = @"{ - 'HourlyRate': 150, - 'Hours': 40, - 'TaxRate': 0.125 - }"; - - var invoice = JsonConvert.DeserializeObject(json); - - // increase tax to 15% - invoice.TaxRate = 0.15m; - - string result = JsonConvert.SerializeObject(invoice); - // { - // 'TaxRate': 0.15, - // 'HourlyRate': 150, - // 'Hours': 40 - // } - - Assert.AreEqual(@"{""TaxRate"":0.15,""HourlyRate"":150,""Hours"":40}", result); - } - - public class ExtensionDataTestClass - { - public string Name { get; set; } - - [JsonProperty("custom_name")] - public string CustomName { get; set; } - - [JsonIgnore] - public IList Ignored { get; set; } - - public bool GetPrivate { get; internal set; } - - public bool GetOnly - { - get { return true; } - } - - public readonly string Readonly = "Readonly"; - public IList Ints { get; set; } - - [JsonExtensionData] - internal IDictionary ExtensionData { get; set; } - - public ExtensionDataTestClass() - { - Ints = new List { 0 }; - } - } - - public class JObjectExtensionDataTestClass - { - public string Name { get; set; } - - [JsonExtensionData] - public JObject ExtensionData { get; set; } - } - - [Test] - public void RoundTripJObjectExtensionData() - { - JObjectExtensionDataTestClass c = new JObjectExtensionDataTestClass(); - c.Name = "Name!"; - c.ExtensionData = new JObject - { - { "one", 1 }, - { "two", "II" }, - { "three", new JArray(1, 1, 1) } - }; - - string json = JsonConvert.SerializeObject(c, Formatting.Indented); - - JObjectExtensionDataTestClass c2 = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Name!", c2.Name); - Assert.IsTrue(JToken.DeepEquals(c.ExtensionData, c2.ExtensionData)); - } - public class BaseClass { internal bool IsTransient { get; set; } @@ -725,419 +548,6 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options); } - [Test] - public void ExtensionDataTest() - { - string json = @"{ - ""Ints"": [1,2,3], - ""Ignored"": [1,2,3], - ""Readonly"": ""Readonly"", - ""Name"": ""Actually set!"", - ""CustomName"": ""Wrong name!"", - ""GetPrivate"": true, - ""GetOnly"": true, - ""NewValueSimple"": true, - ""NewValueComplex"": [1,2,3] -}"; - - ExtensionDataTestClass c = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Actually set!", c.Name); - Assert.AreEqual(4, c.Ints.Count); - - Assert.AreEqual("Readonly", (string)c.ExtensionData["Readonly"]); - Assert.AreEqual("Wrong name!", (string)c.ExtensionData["CustomName"]); - Assert.AreEqual(true, (bool)c.ExtensionData["GetPrivate"]); - Assert.AreEqual(true, (bool)c.ExtensionData["GetOnly"]); - Assert.AreEqual(true, (bool)c.ExtensionData["NewValueSimple"]); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["NewValueComplex"])); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["Ignored"])); - - Assert.AreEqual(7, c.ExtensionData.Count); - } - - public class MultipleExtensionDataAttributesTestClass - { - public string Name { get; set; } - - [JsonExtensionData] - internal IDictionary ExtensionData1 { get; set; } - - [JsonExtensionData] - internal IDictionary ExtensionData2 { get; set; } - } - - public class ExtensionDataAttributesInheritanceTestClass : MultipleExtensionDataAttributesTestClass - { - [JsonExtensionData] - internal IDictionary ExtensionData0 { get; set; } - } - - public class FieldExtensionDataAttributeTestClass - { - [JsonExtensionData] - internal IDictionary ExtensionData; - } - - public class PublicExtensionDataAttributeTestClass - { - public string Name { get; set; } - - [JsonExtensionData] - public IDictionary ExtensionData; - } - - public class PublicExtensionDataAttributeTestClassWithNonDefaultConstructor - { - public string Name { get; set; } - - public PublicExtensionDataAttributeTestClassWithNonDefaultConstructor(string name) - { - Name = name; - } - - [JsonExtensionData] - public IDictionary ExtensionData; - } - - public class PublicNoReadExtensionDataAttributeTestClass - { - public string Name { get; set; } - - [JsonExtensionData(ReadData = false)] - public IDictionary ExtensionData; - } - - public class PublicNoWriteExtensionDataAttributeTestClass - { - public string Name { get; set; } - - [JsonExtensionData(WriteData = false)] - public IDictionary ExtensionData; - } - - public class PublicJTokenExtensionDataAttributeTestClass - { - public string Name { get; set; } - - [JsonExtensionData] - public IDictionary ExtensionData; - } - - [Test] - public void DeserializeDirectoryAccount() - { - string json = @"{'DisplayName':'John Smith', 'SAMAccountName':'contoso\\johns'}"; - - DirectoryAccount account = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("John Smith", account.DisplayName); - Assert.AreEqual("contoso", account.Domain); - Assert.AreEqual("johns", account.UserName); - } - - [Test] - public void SerializePublicExtensionData() - { - string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass - { - Name = "Name!", - ExtensionData = new Dictionary - { - { "Test", 1 } - } - }); - - Assert.AreEqual(@"{""Name"":""Name!"",""Test"":1}", json); - } - - [Test] - public void SerializePublicExtensionDataNull() - { - string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass - { - Name = "Name!" - }); - - Assert.AreEqual(@"{""Name"":""Name!""}", json); - } - - [Test] - public void SerializePublicNoWriteExtensionData() - { - string json = JsonConvert.SerializeObject(new PublicNoWriteExtensionDataAttributeTestClass - { - Name = "Name!", - ExtensionData = new Dictionary - { - { "Test", 1 } - } - }); - - Assert.AreEqual(@"{""Name"":""Name!""}", json); - } - - [Test] - public void DeserializeNoReadPublicExtensionData() - { - PublicNoReadExtensionDataAttributeTestClass c = JsonConvert.DeserializeObject(@"{""Name"":""Name!"",""Test"":1}"); - - Assert.AreEqual(null, c.ExtensionData); - } - - [Test] - public void SerializePublicExtensionDataCircularReference() - { - var c = new PublicExtensionDataAttributeTestClass - { - Name = "Name!", - ExtensionData = new Dictionary - { - { "Test", 1 } - } - }; - c.ExtensionData["Self"] = c; - - string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All, - Formatting = Formatting.Indented - }); - - Assert.AreEqual(@"{ - ""$id"": ""1"", - ""Name"": ""Name!"", - ""Test"": 1, - ""Self"": { - ""$ref"": ""1"" - } -}", json); - - var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All - }); - - Assert.AreEqual("Name!", c2.Name); - - PublicExtensionDataAttributeTestClass bizzaroC2 = (PublicExtensionDataAttributeTestClass)c2.ExtensionData["Self"]; - - Assert.AreEqual(c2, bizzaroC2); - Assert.AreEqual(1, (long)bizzaroC2.ExtensionData["Test"]); - } - - [Test] - public void DeserializePublicJTokenExtensionDataCircularReference() - { - string json = @"{ - ""$id"": ""1"", - ""Name"": ""Name!"", - ""Test"": 1, - ""Self"": { - ""$ref"": ""1"" - } -}"; - - var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All - }); - - Assert.AreEqual("Name!", c2.Name); - - JObject bizzaroC2 = (JObject)c2.ExtensionData["Self"]; - - Assert.AreEqual("Name!", (string)bizzaroC2["Name"]); - Assert.AreEqual(1, (int)bizzaroC2["Test"]); - - Assert.AreEqual(1, (int)c2.ExtensionData["Test"]); - } - - [Test] - public void DeserializePublicExtensionDataTypeNamdHandling() - { - string json = @"{ - ""$id"": ""1"", - ""Name"": ""Name!"", - ""Test"": 1, - ""Self"": { - ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", - ""HourlyWage"": 2.0, - ""Name"": null, - ""BirthDate"": ""0001-01-01T00:00:00"", - ""LastModified"": ""0001-01-01T00:00:00"" - } -}"; - - PublicExtensionDataAttributeTestClass c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects - }); - - Assert.AreEqual("Name!", c2.Name); - - WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"]; - - Assert.AreEqual(2m, bizzaroC2.HourlyWage); - } - - [Test] - public void DeserializePublicExtensionDataTypeNamdHandlingNonDefaultConstructor() - { - string json = @"{ - ""$id"": ""1"", - ""Name"": ""Name!"", - ""Test"": 1, - ""Self"": { - ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", - ""HourlyWage"": 2.0, - ""Name"": null, - ""BirthDate"": ""0001-01-01T00:00:00"", - ""LastModified"": ""0001-01-01T00:00:00"" - } -}"; - - PublicExtensionDataAttributeTestClassWithNonDefaultConstructor c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects - }); - - Assert.AreEqual("Name!", c2.Name); - - WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"]; - - Assert.AreEqual(2m, bizzaroC2.HourlyWage); - } - - [Test] - public void SerializePublicExtensionDataTypeNamdHandling() - { - PublicExtensionDataAttributeTestClass c = new PublicExtensionDataAttributeTestClass - { - Name = "Name!", - ExtensionData = new Dictionary - { - { - "Test", new WagePerson - { - HourlyWage = 2.1m - } - } - } - }; - - string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects, - Formatting = Formatting.Indented - }); - - Assert.AreEqual(@"{ - ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PublicExtensionDataAttributeTestClass, Newtonsoft.Json.Tests"", - ""Name"": ""Name!"", - ""Test"": { - ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", - ""HourlyWage"": 2.1, - ""Name"": null, - ""BirthDate"": ""0001-01-01T00:00:00"", - ""LastModified"": ""0001-01-01T00:00:00"" - } -}", json); - } - - [Test] - public void DeserializePublicExtensionData() - { - string json = @"{ - 'Name':'Name!', - 'NoMatch':'NoMatch!', - 'ExtensionData':{'HAI':true} -}"; - - var c = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Name!", c.Name); - Assert.AreEqual(2, c.ExtensionData.Count); - - Assert.AreEqual("NoMatch!", (string)c.ExtensionData["NoMatch"]); - - // the ExtensionData property is put into the extension data - // inception - var o = (JObject)c.ExtensionData["ExtensionData"]; - Assert.AreEqual(1, o.Count); - Assert.IsTrue(JToken.DeepEquals(new JObject { { "HAI", true } }, o)); - } - - [Test] - public void FieldExtensionDataAttributeTest_Serialize() - { - FieldExtensionDataAttributeTestClass c = new FieldExtensionDataAttributeTestClass - { - ExtensionData = new Dictionary() - }; - - string json = JsonConvert.SerializeObject(c); - - Assert.AreEqual("{}", json); - } - - [Test] - public void FieldExtensionDataAttributeTest_Deserialize() - { - var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); - - Assert.AreEqual(2, c.ExtensionData.Count); - Assert.AreEqual(1, (long)c.ExtensionData["first"]); - Assert.AreEqual(2, (long)c.ExtensionData["second"]); - } - - [Test] - public void MultipleExtensionDataAttributesTest() - { - var c = JsonConvert.DeserializeObject("{'first':[1],'second':[2]}"); - - Assert.AreEqual(null, c.ExtensionData1); - Assert.AreEqual(2, c.ExtensionData2.Count); - Assert.AreEqual(1, (int)((JArray)c.ExtensionData2["first"])[0]); - Assert.AreEqual(2, (int)((JArray)c.ExtensionData2["second"])[0]); - } - - [Test] - public void ExtensionDataAttributesInheritanceTest() - { - var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); - - Assert.AreEqual(null, c.ExtensionData1); - Assert.AreEqual(null, c.ExtensionData2); - Assert.AreEqual(2, c.ExtensionData0.Count); - Assert.AreEqual(1, (int)c.ExtensionData0["first"]); - Assert.AreEqual(2, (int)c.ExtensionData0["second"]); - } - - [Test] - public void GenericCollectionInheritance() - { - string json; - - GenericClass, string> foo1 = new GenericClass, string>(); - foo1.Items.Add(new GenericItem { Value = "Hello" }); - - json = JsonConvert.SerializeObject(new { selectList = foo1 }); - Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); - - GenericClass foo2 = new GenericClass(); - foo2.Items.Add(new NonGenericItem { Value = "Hello" }); - - json = JsonConvert.SerializeObject(new { selectList = foo2 }); - Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); - - NonGenericClass foo3 = new NonGenericClass(); - foo3.Items.Add(new NonGenericItem { Value = "Hello" }); - - json = JsonConvert.SerializeObject(new { selectList = foo3 }); - Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); - } - #if !NET20 [DataContract] public class BaseDataContractWithHidden @@ -1706,39 +1116,6 @@ keyword such as type of business."" @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.", () => { JsonConvert.SerializeObject(new BadJsonPropertyClass()); }); } - - [Test] - public void InheritedListSerialize() - { - Article a1 = new Article("a1"); - Article a2 = new Article("a2"); - - ArticleCollection articles1 = new ArticleCollection(); - articles1.Add(a1); - articles1.Add(a2); - - string jsonText = JsonConvert.SerializeObject(articles1); - - ArticleCollection articles2 = JsonConvert.DeserializeObject(jsonText); - - Assert.AreEqual(articles1.Count, articles2.Count); - Assert.AreEqual(articles1[0].Name, articles2[0].Name); - } - - [Test] - public void ReadOnlyCollectionSerialize() - { - ReadOnlyCollection r1 = new ReadOnlyCollection(new int[] { 0, 1, 2, 3, 4 }); - - string jsonText = JsonConvert.SerializeObject(r1); - - Assert.AreEqual("[0,1,2,3,4]", jsonText); - - ReadOnlyCollection r2 = JsonConvert.DeserializeObject>(jsonText); - - CollectionAssert.AreEqual(r1, r2); - } - #if !NET20 [Test] public void Unicode() @@ -1908,31 +1285,6 @@ keyword such as type of business."" Assert.AreEqual(d, anonymous.DateValue); } - [Test] - public void CustomCollectionSerialization() - { - ProductCollection collection = new ProductCollection() - { - new Product() { Name = "Test1" }, - new Product() { Name = "Test2" }, - new Product() { Name = "Test3" } - }; - - JsonSerializer jsonSerializer = new JsonSerializer(); - jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - - StringWriter sw = new StringWriter(); - - jsonSerializer.Serialize(sw, collection); - - Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}]", - sw.GetStringBuilder().ToString()); - - ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection)); - - CollectionAssert.AreEqual(collection, collectionNew); - } - [Test] public void SerializeObject() { @@ -2149,54 +1501,6 @@ keyword such as type of business."" Assert.AreEqual(99, c.Field); } -#if !NETFX_CORE - [Test] - public void SerializeArrayAsArrayList() - { - string jsonText = @"[3, ""somestring"",[1,2,3],{}]"; - ArrayList o = JsonConvert.DeserializeObject(jsonText); - - Assert.AreEqual(4, o.Count); - Assert.AreEqual(3, ((JArray)o[2]).Count); - Assert.AreEqual(0, ((JObject)o[3]).Count); - } -#endif - - [Test] - public void SerializeMemberGenericList() - { - Name name = new Name("The Idiot in Next To Me"); - - PhoneNumber p1 = new PhoneNumber("555-1212"); - PhoneNumber p2 = new PhoneNumber("444-1212"); - - name.pNumbers.Add(p1); - name.pNumbers.Add(p2); - - string json = JsonConvert.SerializeObject(name, Formatting.Indented); - - Assert.AreEqual(@"{ - ""personsName"": ""The Idiot in Next To Me"", - ""pNumbers"": [ - { - ""phoneNumber"": ""555-1212"" - }, - { - ""phoneNumber"": ""444-1212"" - } - ] -}", json); - - Name newName = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("The Idiot in Next To Me", newName.personsName); - - // not passed in as part of the constructor but assigned to pNumbers property - Assert.AreEqual(2, newName.pNumbers.Count); - Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber); - Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber); - } - [Test] public void ConstructorCaseSensitivity() { @@ -3260,38 +2564,6 @@ keyword such as type of business."" Assert.AreEqual(RoleTransferDirection.First, r.Direction); } - [Test] - public void PrimitiveValuesInObjectArray() - { - string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}"; - - ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Router", o.Action); - Assert.AreEqual("Navigate", o.Method); - Assert.AreEqual(2, o.Data.Length); - Assert.AreEqual("dashboard", o.Data[0]); - Assert.AreEqual(null, o.Data[1]); - } - - [Test] - public void ComplexValuesInObjectArray() - { - string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}"; - - ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Router", o.Action); - Assert.AreEqual("Navigate", o.Method); - Assert.AreEqual(3, o.Data.Length); - Assert.AreEqual("dashboard", o.Data[0]); - CustomAssert.IsInstanceOfType(typeof(JArray), o.Data[1]); - Assert.AreEqual(4, ((JArray)o.Data[1]).Count); - CustomAssert.IsInstanceOfType(typeof(JObject), o.Data[2]); - Assert.AreEqual(1, ((JObject)o.Data[2]).Count); - Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]); - } - [Test] public void DeserializeGenericDictionary() { @@ -3310,90 +2582,6 @@ keyword such as type of business."" Assert.AreEqual("value2", values["key2"]); } - [Test] - public void SerializeGenericList() - { - Product p1 = new Product - { - Name = "Product 1", - Price = 99.95m, - ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), - }; - Product p2 = new Product - { - Name = "Product 2", - Price = 12.50m, - ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), - }; - - List products = new List(); - products.Add(p1); - products.Add(p2); - - string json = JsonConvert.SerializeObject(products, Formatting.Indented); - //[ - // { - // "Name": "Product 1", - // "ExpiryDate": "\/Date(978048000000)\/", - // "Price": 99.95, - // "Sizes": null - // }, - // { - // "Name": "Product 2", - // "ExpiryDate": "\/Date(1248998400000)\/", - // "Price": 12.50, - // "Sizes": null - // } - //] - - Assert.AreEqual(@"[ - { - ""Name"": ""Product 1"", - ""ExpiryDate"": ""2000-12-29T00:00:00Z"", - ""Price"": 99.95, - ""Sizes"": null - }, - { - ""Name"": ""Product 2"", - ""ExpiryDate"": ""2009-07-31T00:00:00Z"", - ""Price"": 12.50, - ""Sizes"": null - } -]", json); - } - - [Test] - public void DeserializeGenericList() - { - string json = @"[ - { - ""Name"": ""Product 1"", - ""ExpiryDate"": ""\/Date(978048000000)\/"", - ""Price"": 99.95, - ""Sizes"": null - }, - { - ""Name"": ""Product 2"", - ""ExpiryDate"": ""\/Date(1248998400000)\/"", - ""Price"": 12.50, - ""Sizes"": null - } - ]"; - - List products = JsonConvert.DeserializeObject>(json); - - Console.WriteLine(products.Count); - // 2 - - Product p1 = products[0]; - - Console.WriteLine(p1.Name); - // Product 1 - - Assert.AreEqual(2, products.Count); - Assert.AreEqual("Product 1", products[0].Name); - } - #if !NET20 [Test] public void DeserializeEmptyStringToNullableDateTime() @@ -4962,199 +4150,6 @@ To fix this error either change the environment to be fully trusted, change the } } - [Test] - public void TestEscapeDictionaryStrings() - { - const string s = @"host\user"; - string serialized = JsonConvert.SerializeObject(s); - Assert.AreEqual(@"""host\\user""", serialized); - - Dictionary d1 = new Dictionary(); - d1.Add(5, s); - Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1)); - - Dictionary d2 = new Dictionary(); - d2.Add(s, 5); - Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2)); - } - - public class GenericListTestClass - { - public List GenericList { get; set; } - - public GenericListTestClass() - { - GenericList = new List(); - } - } - - [Test] - public void DeserializeExistingGenericList() - { - GenericListTestClass c = new GenericListTestClass(); - c.GenericList.Add("1"); - c.GenericList.Add("2"); - - string json = JsonConvert.SerializeObject(c, Formatting.Indented); - - GenericListTestClass newValue = JsonConvert.DeserializeObject(json); - Assert.AreEqual(2, newValue.GenericList.Count); - Assert.AreEqual(typeof(List), newValue.GenericList.GetType()); - } - - [Test] - public void DeserializeSimpleKeyValuePair() - { - List> list = new List>(); - list.Add(new KeyValuePair("key1", "value1")); - list.Add(new KeyValuePair("key2", "value2")); - - string json = JsonConvert.SerializeObject(list); - - Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json); - - List> result = JsonConvert.DeserializeObject>>(json); - Assert.AreEqual(2, result.Count); - Assert.AreEqual("key1", result[0].Key); - Assert.AreEqual("value1", result[0].Value); - Assert.AreEqual("key2", result[1].Key); - Assert.AreEqual("value2", result[1].Value); - } - - [Test] - public void DeserializeComplexKeyValuePair() - { - DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc); - - List> list = new List>(); - list.Add(new KeyValuePair("key1", new WagePerson - { - BirthDate = dateTime, - Department = "Department1", - LastModified = dateTime, - HourlyWage = 1 - })); - list.Add(new KeyValuePair("key2", new WagePerson - { - BirthDate = dateTime, - Department = "Department2", - LastModified = dateTime, - HourlyWage = 2 - })); - - string json = JsonConvert.SerializeObject(list, Formatting.Indented); - - Assert.AreEqual(@"[ - { - ""Key"": ""key1"", - ""Value"": { - ""HourlyWage"": 1.0, - ""Name"": null, - ""BirthDate"": ""2000-12-01T23:01:01Z"", - ""LastModified"": ""2000-12-01T23:01:01Z"" - } - }, - { - ""Key"": ""key2"", - ""Value"": { - ""HourlyWage"": 2.0, - ""Name"": null, - ""BirthDate"": ""2000-12-01T23:01:01Z"", - ""LastModified"": ""2000-12-01T23:01:01Z"" - } - } -]", json); - - List> result = JsonConvert.DeserializeObject>>(json); - Assert.AreEqual(2, result.Count); - Assert.AreEqual("key1", result[0].Key); - Assert.AreEqual(1, result[0].Value.HourlyWage); - Assert.AreEqual("key2", result[1].Key); - Assert.AreEqual(2, result[1].Value.HourlyWage); - } - - public class StringListAppenderConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - writer.WriteValue(value); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - List existingStrings = (List)existingValue; - List newStrings = new List(existingStrings); - - reader.Read(); - - while (reader.TokenType != JsonToken.EndArray) - { - string s = (string)reader.Value; - newStrings.Add(s); - - reader.Read(); - } - - return newStrings; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(List)); - } - } - - [Test] - public void StringListAppenderConverterTest() - { - Movie p = new Movie(); - p.ReleaseCountries = new List { "Existing" }; - - JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings - { - Converters = new List { new StringListAppenderConverter() } - }); - - Assert.AreEqual(2, p.ReleaseCountries.Count); - Assert.AreEqual("Existing", p.ReleaseCountries[0]); - Assert.AreEqual("Appended", p.ReleaseCountries[1]); - } - - public class StringAppenderConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - writer.WriteValue(value); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - string existingString = (string)existingValue; - string newString = existingString + (string)reader.Value; - - return newString; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(string)); - } - } - - [Test] - public void StringAppenderConverterTest() - { - Movie p = new Movie(); - p.Name = "Existing,"; - - JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings - { - Converters = new List { new StringAppenderConverter() } - }); - - Assert.AreEqual("Existing,Appended", p.Name); - } - [Test] public void SerializeRefAdditionalContent() { @@ -5264,211 +4259,7 @@ To fix this error either change the environment to be fully trusted, change the Assert.AreEqual(9.9m, dic["value"]); } - [Test] - public void ShouldSerializeTest() - { - ShouldSerializeTestClass c = new ShouldSerializeTestClass(); - c.Name = "James"; - c.Age = 27; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Age"": 27 -}", json); - - c._shouldSerializeName = true; - json = JsonConvert.SerializeObject(c, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Name"": ""James"", - ""Age"": 27 -}", json); - - ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject(json); - Assert.AreEqual("James", deserialized.Name); - Assert.AreEqual(27, deserialized.Age); - } - - public class Employee - { - public string Name { get; set; } - public Employee Manager { get; set; } - - public bool ShouldSerializeManager() - { - return (Manager != this); - } - } - - [Test] - public void ShouldSerializeExample() - { - Employee joe = new Employee(); - joe.Name = "Joe Employee"; - Employee mike = new Employee(); - mike.Name = "Mike Manager"; - - joe.Manager = mike; - mike.Manager = mike; - - string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); - // [ - // { - // "Name": "Joe Employee", - // "Manager": { - // "Name": "Mike Manager" - // } - // }, - // { - // "Name": "Mike Manager" - // } - // ] - - Console.WriteLine(json); - } - - [Test] - public void SpecifiedTest() - { - SpecifiedTestClass c = new SpecifiedTestClass(); - c.Name = "James"; - c.Age = 27; - c.NameSpecified = false; - - string json = JsonConvert.SerializeObject(c, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Age"": 27 -}", json); - - SpecifiedTestClass deserialized = JsonConvert.DeserializeObject(json); - Assert.IsNull(deserialized.Name); - Assert.IsFalse(deserialized.NameSpecified); - Assert.IsFalse(deserialized.WeightSpecified); - Assert.IsFalse(deserialized.HeightSpecified); - Assert.IsFalse(deserialized.FavoriteNumberSpecified); - Assert.AreEqual(27, deserialized.Age); - - c.NameSpecified = true; - c.WeightSpecified = true; - c.HeightSpecified = true; - c.FavoriteNumber = 23; - json = JsonConvert.SerializeObject(c, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Name"": ""James"", - ""Age"": 27, - ""Weight"": 0, - ""Height"": 0, - ""FavoriteNumber"": 23 -}", json); - - deserialized = JsonConvert.DeserializeObject(json); - Assert.AreEqual("James", deserialized.Name); - Assert.IsTrue(deserialized.NameSpecified); - Assert.IsTrue(deserialized.WeightSpecified); - Assert.IsTrue(deserialized.HeightSpecified); - Assert.IsTrue(deserialized.FavoriteNumberSpecified); - Assert.AreEqual(27, deserialized.Age); - Assert.AreEqual(23, deserialized.FavoriteNumber); - } - - // [Test] - // public void XmlSerializerSpecifiedTrueTest() - // { - // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); - - // StringWriter sw = new StringWriter(); - // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true }); - - // Console.WriteLine(sw.ToString()); - - // string xml = @" - // - // First - //"; - - // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); - // Console.WriteLine(o.FirstOrder); - // Console.WriteLine(o.FirstOrderSpecified); - // } - - // [Test] - // public void XmlSerializerSpecifiedFalseTest() - // { - // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); - - // StringWriter sw = new StringWriter(); - // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false }); - - // Console.WriteLine(sw.ToString()); - - // // string xml = @" - // // - // // First - // //"; - - // // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); - // // Console.WriteLine(o.FirstOrder); - // // Console.WriteLine(o.FirstOrderSpecified); - // } - - public class OptionalOrder - { - // This field shouldn't be serialized - // if it is uninitialized. - public string FirstOrder; - // Use the XmlIgnoreAttribute to ignore the - // special field named "FirstOrderSpecified". - [System.Xml.Serialization.XmlIgnoreAttribute] - public bool FirstOrderSpecified; - } - - public class FamilyDetails - { - public string Name { get; set; } - public int NumberOfChildren { get; set; } - - [JsonIgnore] - public bool NumberOfChildrenSpecified { get; set; } - } - - [Test] - public void SpecifiedExample() - { - FamilyDetails joe = new FamilyDetails(); - joe.Name = "Joe Family Details"; - joe.NumberOfChildren = 4; - joe.NumberOfChildrenSpecified = true; - - FamilyDetails martha = new FamilyDetails(); - martha.Name = "Martha Family Details"; - martha.NumberOfChildren = 3; - martha.NumberOfChildrenSpecified = false; - - string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented); - //[ - // { - // "Name": "Joe Family Details", - // "NumberOfChildren": 4 - // }, - // { - // "Name": "Martha Family Details" - // } - //] - Console.WriteLine(json); - - string mikeString = "{\"Name\": \"Mike Person\"}"; - FamilyDetails mike = JsonConvert.DeserializeObject(mikeString); - - Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); - - string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}"; - mike = JsonConvert.DeserializeObject(mikeFullDisclosureString); - - Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); - } public class DictionaryKey { @@ -6773,19 +5564,7 @@ To fix this error either change the environment to be fully trusted, change the } #endif - public void DeserializeIDictionary() - { - IDictionary dictionary = JsonConvert.DeserializeObject("{'name':'value!'}"); - Assert.AreEqual(1, dictionary.Count); - Assert.AreEqual("value!", dictionary["name"]); - } - - public void DeserializeIList() - { - IList list = JsonConvert.DeserializeObject("['1', 'two', 'III']"); - Assert.AreEqual(3, list.Count); - } - + [Test] public void UriGuidTimeSpanTestClassEmptyTest() { UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); @@ -6807,6 +5586,7 @@ To fix this error either change the environment to be fully trusted, change the Assert.AreEqual(c1.Uri, c2.Uri); } + [Test] public void UriGuidTimeSpanTestClassValuesTest() { UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass @@ -6824,7 +5604,7 @@ To fix this error either change the environment to be fully trusted, change the ""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"", ""TimeSpan"": ""1.00:00:00"", ""NullableTimeSpan"": ""01:00:00"", - ""Uri"": ""http://testuri.com/"" + ""Uri"": ""http://testuri.com"" }", json); UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject(json); @@ -6835,31 +5615,6 @@ To fix this error either change the environment to be fully trusted, change the Assert.AreEqual(c1.Uri, c2.Uri); } - [Test] - public void NullableValueGenericDictionary() - { - IDictionary v1 = new Dictionary - { - { "First", 1 }, - { "Second", null }, - { "Third", 3 } - }; - - string json = JsonConvert.SerializeObject(v1, Formatting.Indented); - - Assert.AreEqual(@"{ - ""First"": 1, - ""Second"": null, - ""Third"": 3 -}", json); - - IDictionary v2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, v2.Count); - Assert.AreEqual(1, v2["First"]); - Assert.AreEqual(null, v2["Second"]); - Assert.AreEqual(3, v2["Third"]); - } - [Test] public void UsingJsonTextWriter() { @@ -6879,86 +5634,6 @@ To fix this error either change the environment to be fully trusted, change the } } -#if !(NET35 || NET20 || PORTABLE || PORTABLE40) - [Test] - public void DeserializeConcurrentDictionary() - { - IDictionary components = new Dictionary - { - { "Key!", new Component() } - }; - GameObject go = new GameObject - { - Components = new ConcurrentDictionary(components), - Id = "Id!", - Name = "Name!" - }; - - string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Components"": { - ""Key!"": {} - }, - ""Id"": ""Id!"", - ""Name"": ""Name!"" -}", originalJson); - - GameObject newObject = JsonConvert.DeserializeObject(originalJson); - - Assert.AreEqual(1, newObject.Components.Count); - Assert.AreEqual("Id!", newObject.Id); - Assert.AreEqual("Name!", newObject.Name); - } -#endif - - [Test] - public void DeserializeKeyValuePairArray() - { - string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; - - IList>> values = JsonConvert.DeserializeObject>>>(json); - - Assert.AreEqual(2, values.Count); - Assert.AreEqual("aaa", values[0].Key); - Assert.AreEqual(2, values[0].Value.Count); - Assert.AreEqual("1", values[0].Value[0]); - Assert.AreEqual("2", values[0].Value[1]); - Assert.AreEqual("bbb", values[1].Key); - Assert.AreEqual(2, values[1].Value.Count); - Assert.AreEqual("3", values[1].Value[0]); - Assert.AreEqual("4", values[1].Value[1]); - } - - [Test] - public void DeserializeNullableKeyValuePairArray() - { - string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; - - IList>?> values = JsonConvert.DeserializeObject>?>>(json); - - Assert.AreEqual(3, values.Count); - Assert.AreEqual("aaa", values[0].Value.Key); - Assert.AreEqual(2, values[0].Value.Value.Count); - Assert.AreEqual("1", values[0].Value.Value[0]); - Assert.AreEqual("2", values[0].Value.Value[1]); - Assert.AreEqual(null, values[1]); - Assert.AreEqual("bbb", values[2].Value.Key); - Assert.AreEqual(2, values[2].Value.Value.Count); - Assert.AreEqual("3", values[2].Value.Value[0]); - Assert.AreEqual("4", values[2].Value.Value[1]); - } - - [Test] - public void DeserializeNullToNonNullableKeyValuePairArray() - { - string json = @"[ null ]"; - - ExceptionAssert.Throws( - "Cannot convert null value to KeyValuePair. Path '[0]', line 1, position 6.", - () => { JsonConvert.DeserializeObject>>>(json); }); - } - [Test] public void SerializeUriWithQuotes() { @@ -7884,7 +6559,7 @@ Parameter name: value", [Test] public void PropertyItemConverter() { - Event e = new Event + Event1 e = new Event1 { EventName = "Blackadder III", Venue = "Gryphon Theatre", @@ -8133,77 +6808,6 @@ Parameter name: value", }", json); } - public class EnumerableClass : IEnumerable - { - private readonly IList _values; - - public EnumerableClass(IEnumerable values) - { - _values = new List(values); - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - - [Test] - public void DeserializeIEnumerableFromConstructor() - { - string json = @"[ - 1, - 2, - null -]"; - - var result = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, result.Count()); - Assert.AreEqual(1, result.ElementAt(0)); - Assert.AreEqual(2, result.ElementAt(1)); - Assert.AreEqual(null, result.ElementAt(2)); - } - - public class EnumerableClassFailure : IEnumerable - { - private readonly IList _values; - - public EnumerableClassFailure() - { - _values = new List(); - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - - [Test] - public void DeserializeIEnumerableFromConstructor_Failure() - { - string json = @"[ - ""One"", - ""II"", - ""3"" -]"; - - ExceptionAssert.Throws( - "Cannot create and populate list type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+EnumerableClassFailure`1[System.String]. Path '', line 1, position 1.", - () => JsonConvert.DeserializeObject>(json)); - } - [JsonObject(MemberSerialization.Fields)] public class MyTuple { @@ -8373,661 +6977,6 @@ Parameter name: value", } #endif -#if !(NET40 || NET35 || NET20 || PORTABLE40) - public class PopulateReadOnlyTestClass - { - public IList NonReadOnlyList { get; set; } - public IDictionary NonReadOnlyDictionary { get; set; } - - public IList Array { get; set; } - - public IList List { get; set; } - public IDictionary Dictionary { get; set; } - - public IReadOnlyCollection IReadOnlyCollection { get; set; } - public ReadOnlyCollection ReadOnlyCollection { get; set; } - public IReadOnlyList IReadOnlyList { get; set; } - - public IReadOnlyDictionary IReadOnlyDictionary { get; set; } - public ReadOnlyDictionary ReadOnlyDictionary { get; set; } - - public PopulateReadOnlyTestClass() - { - NonReadOnlyList = new List { 1 }; - NonReadOnlyDictionary = new Dictionary { { "first", 2 } }; - - Array = new[] { 3 }; - - List = new ReadOnlyCollection(new[] { 4 }); - Dictionary = new ReadOnlyDictionary(new Dictionary { { "first", 5 } }); - - IReadOnlyCollection = new ReadOnlyCollection(new[] { 6 }); - ReadOnlyCollection = new ReadOnlyCollection(new[] { 7 }); - IReadOnlyList = new ReadOnlyCollection(new[] { 8 }); - - IReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 9 } }); - ReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 10 } }); - } - } - - [Test] - public void SerializeReadOnlyCollections() - { - PopulateReadOnlyTestClass c1 = new PopulateReadOnlyTestClass(); - - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - - Assert.AreEqual(@"{ - ""NonReadOnlyList"": [ - 1 - ], - ""NonReadOnlyDictionary"": { - ""first"": 2 - }, - ""Array"": [ - 3 - ], - ""List"": [ - 4 - ], - ""Dictionary"": { - ""first"": 5 - }, - ""IReadOnlyCollection"": [ - 6 - ], - ""ReadOnlyCollection"": [ - 7 - ], - ""IReadOnlyList"": [ - 8 - ], - ""IReadOnlyDictionary"": { - ""first"": 9 - }, - ""ReadOnlyDictionary"": { - ""first"": 10 - } -}", json); - } - - [Test] - public void PopulateReadOnlyCollections() - { - string json = @"{ - ""NonReadOnlyList"": [ - 11 - ], - ""NonReadOnlyDictionary"": { - ""first"": 12 - }, - ""Array"": [ - 13 - ], - ""List"": [ - 14 - ], - ""Dictionary"": { - ""first"": 15 - }, - ""IReadOnlyCollection"": [ - 16 - ], - ""ReadOnlyCollection"": [ - 17 - ], - ""IReadOnlyList"": [ - 18 - ], - ""IReadOnlyDictionary"": { - ""first"": 19 - }, - ""ReadOnlyDictionary"": { - ""first"": 20 - } -}"; - - var c2 = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(1, c2.NonReadOnlyDictionary.Count); - Assert.AreEqual(12, c2.NonReadOnlyDictionary["first"]); - - Assert.AreEqual(2, c2.NonReadOnlyList.Count); - Assert.AreEqual(1, c2.NonReadOnlyList[0]); - Assert.AreEqual(11, c2.NonReadOnlyList[1]); - - Assert.AreEqual(1, c2.Array.Count); - Assert.AreEqual(13, c2.Array[0]); - } -#endif - - [Test] - public void SerializeArray2D() - { - Array2D aa = new Array2D(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[,] { { 1, 1 }, { 1, 2 }, { 2, 1 }, { 2, 2 } }; - - string json = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json); - } - - [Test] - public void SerializeArray3D() - { - Array3D aa = new Array3D(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; - - string json = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json); - } - - [Test] - public void SerializeArray3DWithConverter() - { - Array3DWithConverter aa = new Array3DWithConverter(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; - - string json = JsonConvert.SerializeObject(aa, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Before"": ""Before!"", - ""Coordinates"": [ - [ - [ - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 2.0 - ] - ], - [ - [ - 1.0, - 2.0, - 1.0 - ], - [ - 1.0, - 2.0, - 2.0 - ] - ], - [ - [ - 2.0, - 1.0, - 1.0 - ], - [ - 2.0, - 1.0, - 2.0 - ] - ], - [ - [ - 2.0, - 2.0, - 1.0 - ], - [ - 2.0, - 2.0, - 2.0 - ] - ] - ], - ""After"": ""After!"" -}", json); - } - - [Test] - public void DeserializeArray3DWithConverter() - { - string json = @"{ - ""Before"": ""Before!"", - ""Coordinates"": [ - [ - [ - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 2.0 - ] - ], - [ - [ - 1.0, - 2.0, - 1.0 - ], - [ - 1.0, - 2.0, - 2.0 - ] - ], - [ - [ - 2.0, - 1.0, - 1.0 - ], - [ - 2.0, - 1.0, - 2.0 - ] - ], - [ - [ - 2.0, - 2.0, - 1.0 - ], - [ - 2.0, - 2.0, - 2.0 - ] - ] - ], - ""After"": ""After!"" -}"; - - Array3DWithConverter aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.GetLength(0)); - Assert.AreEqual(2, aa.Coordinates.GetLength(1)); - Assert.AreEqual(3, aa.Coordinates.GetLength(2)); - Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); - Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); - } - - [Test] - public void DeserializeArray2D() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}"; - - Array2D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.GetLength(0)); - Assert.AreEqual(2, aa.Coordinates.GetLength(1)); - Assert.AreEqual(1, aa.Coordinates[0, 0]); - Assert.AreEqual(2, aa.Coordinates[1, 1]); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeArray2D_WithTooManyItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2,3],[2,1],[2,2]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray2D_WithTooFewItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1],[2,1],[2,2]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray3D() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.GetLength(0)); - Assert.AreEqual(2, aa.Coordinates.GetLength(1)); - Assert.AreEqual(3, aa.Coordinates.GetLength(2)); - Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); - Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeArray3D_WithTooManyItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray3D_WithBadItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],{}]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Unexpected token when deserializing multidimensional array: StartObject. Path 'Coordinates[3][1]', line 1, position 99.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray3D_WithTooFewItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void SerializeEmpty3DArray() - { - Array3D aa = new Array3D(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new int[0, 0, 0]; - - string json = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}", json); - } - - [Test] - public void DeserializeEmpty3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(0, aa.Coordinates.GetLength(0)); - Assert.AreEqual(0, aa.Coordinates.GetLength(1)); - Assert.AreEqual(0, aa.Coordinates.GetLength(2)); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeIncomplete3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1"; - - ExceptionAssert.Throws( - null, - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeIncompleteNotTopLevel3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/"; - - ExceptionAssert.Throws( - null, - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeNull3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":null,""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(null, aa.Coordinates); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeSemiEmpty3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[]],""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(1, aa.Coordinates.GetLength(0)); - Assert.AreEqual(0, aa.Coordinates.GetLength(1)); - Assert.AreEqual(0, aa.Coordinates.GetLength(2)); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void SerializeReferenceTracked3DArray() - { - Event e1 = new Event - { - EventName = "EventName!" - }; - Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; - IList values1 = new List - { - array1, - array1 - }; - - string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All, - Formatting = Formatting.Indented - }); - - Assert.AreEqual(@"{ - ""$id"": ""1"", - ""$values"": [ - { - ""$id"": ""2"", - ""$values"": [ - [ - { - ""$id"": ""3"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - }, - { - ""$ref"": ""3"" - } - ], - [ - { - ""$ref"": ""3"" - }, - { - ""$ref"": ""3"" - } - ] - ] - }, - { - ""$ref"": ""2"" - } - ] -}", json); - } - - [Test] - public void SerializeTypeName3DArray() - { - Event e1 = new Event - { - EventName = "EventName!" - }; - Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; - IList values1 = new List - { - array1, - array1 - }; - - string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - Formatting = Formatting.Indented - }); - - Assert.AreEqual(@"{ - ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests]], mscorlib"", - ""$values"": [ - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests"", - ""$values"": [ - [ - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - }, - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - } - ], - [ - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - }, - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - } - ] - ] - }, - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests"", - ""$values"": [ - [ - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - }, - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - } - ], - [ - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - }, - { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"", - ""EventName"": ""EventName!"", - ""Venue"": null, - ""Performances"": null - } - ] - ] - } - ] -}", json); - - IList values2 = (IList)JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All - }); - - Assert.AreEqual(2, values2.Count); - Assert.AreEqual("EventName!", values2[0][0, 0].EventName); - } - - public class ExtensionDataDeserializeWithNonDefaultConstructor - { - public ExtensionDataDeserializeWithNonDefaultConstructor(string name) - { - Name = name; - } - - [JsonExtensionData] - public IDictionary _extensionData; - - public string Name { get; set; } - } - - [Test] - public void ExtensionDataDeserializeWithNonDefaultConstructorTest() - { - ExtensionDataDeserializeWithNonDefaultConstructor c = new ExtensionDataDeserializeWithNonDefaultConstructor("Name!"); - c._extensionData = new Dictionary - { - { "Key!", "Value!" } - }; - - string json = JsonConvert.SerializeObject(c, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Name"": ""Name!"", - ""Key!"": ""Value!"" -}", json); - - var c2 = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Name!", c2.Name); - Assert.IsNotNull(c2._extensionData); - Assert.AreEqual(1, c2._extensionData.Count); - Assert.AreEqual("Value!", (string)c2._extensionData["Key!"]); - } - #if NETFX_CORE [Test] public void SerializeWinRTJsonObject() @@ -9363,50 +7312,6 @@ Parameter name: value", } #endif - public class NewEmployee : Employee - { - public int Age { get; set; } - - public bool ShouldSerializeName() - { - return false; - } - } - - [Test] - public void ShouldSerializeInheritedClassTest() - { - NewEmployee joe = new NewEmployee(); - joe.Name = "Joe Employee"; - joe.Age = 100; - - Employee mike = new Employee(); - mike.Name = "Mike Manager"; - mike.Manager = mike; - - joe.Manager = mike; - - //StringWriter sw = new StringWriter(); - - //XmlSerializer x = new XmlSerializer(typeof(NewEmployee)); - //x.Serialize(sw, joe); - - //Console.WriteLine(sw); - - //JavaScriptSerializer s = new JavaScriptSerializer(); - //Console.WriteLine(s.Serialize(new {html = @"; & ! ^ * ( ) ! @ # $ % ^ ' "" - , . / ; : [ { } ] ; ' - _ = + ? ` ~ \ |"})); - - string json = JsonConvert.SerializeObject(joe, Formatting.Indented); - - Assert.AreEqual(@"{ - ""Age"": 100, - ""Name"": ""Joe Employee"", - ""Manager"": { - ""Name"": ""Mike Manager"" - } -}", json); - } - [Test] public void DeserializeDecimal() { @@ -9442,16 +7347,6 @@ Parameter name: value", } #endif - [Test] - public void DeserializeNonGenericList() - { - IList l = JsonConvert.DeserializeObject("['string!']"); - - Assert.AreEqual(typeof(List), l.GetType()); - Assert.AreEqual(1, l.Count); - Assert.AreEqual("string!", l[0]); - } - #if !(NET20 || NET35 || PORTABLE || PORTABLE40) [Test] public void SerializeBigInteger() @@ -9466,275 +7361,6 @@ Parameter name: value", } #endif -#if !(NET40 || NET35 || NET20 || PORTABLE40) - [Test] - public void DeserializeReadOnlyListInterface() - { - IReadOnlyList list = JsonConvert.DeserializeObject>("[1,2,3]"); - - Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list[0]); - Assert.AreEqual(2, list[1]); - Assert.AreEqual(3, list[2]); - } - - [Test] - public void DeserializeReadOnlyCollectionInterface() - { - IReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); - - Assert.AreEqual(3, list.Count); - - Assert.AreEqual(1, list.ElementAt(0)); - Assert.AreEqual(2, list.ElementAt(1)); - Assert.AreEqual(3, list.ElementAt(2)); - } - - [Test] - public void DeserializeReadOnlyCollection() - { - ReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); - - Assert.AreEqual(3, list.Count); - - Assert.AreEqual(1, list[0]); - Assert.AreEqual(2, list[1]); - Assert.AreEqual(3, list[2]); - } - - [Test] - public void DeserializeReadOnlyDictionaryInterface() - { - IReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); - - Assert.AreEqual(2, dic.Count); - - Assert.AreEqual(1, dic["one"]); - Assert.AreEqual(2, dic["two"]); - - CustomAssert.IsInstanceOfType(typeof(ReadOnlyDictionary), dic); - } - - [Test] - public void DeserializeReadOnlyDictionary() - { - ReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); - - Assert.AreEqual(2, dic.Count); - - Assert.AreEqual(1, dic["one"]); - Assert.AreEqual(2, dic["two"]); - } - - public class CustomReadOnlyDictionary : IReadOnlyDictionary - { - private readonly IDictionary _dictionary; - - public CustomReadOnlyDictionary(IDictionary dictionary) - { - _dictionary = dictionary; - } - - public bool ContainsKey(TKey key) - { - return _dictionary.ContainsKey(key); - } - - public IEnumerable Keys - { - get { return _dictionary.Keys; } - } - - public bool TryGetValue(TKey key, out TValue value) - { - return _dictionary.TryGetValue(key, out value); - } - - public IEnumerable Values - { - get { return _dictionary.Values; } - } - - public TValue this[TKey key] - { - get { return _dictionary[key]; } - } - - public int Count - { - get { return _dictionary.Count; } - } - - public IEnumerator> GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - } - - [Test] - public void SerializeCustomReadOnlyDictionary() - { - IDictionary d = new Dictionary - { - { "one", 1 }, - { "two", 2 } - }; - - CustomReadOnlyDictionary dic = new CustomReadOnlyDictionary(d); - - string json = JsonConvert.SerializeObject(dic, Formatting.Indented); - Assert.AreEqual(@"{ - ""one"": 1, - ""two"": 2 -}", json); - } - - public class CustomReadOnlyCollection : IReadOnlyCollection - { - private readonly IList _values; - - public CustomReadOnlyCollection(IList values) - { - _values = values; - } - - public int Count - { - get { return _values.Count; } - } - - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _values.GetEnumerator(); - } - } - - [Test] - public void SerializeCustomReadOnlyCollection() - { - IList l = new List - { - 1, - 2, - 3 - }; - - CustomReadOnlyCollection list = new CustomReadOnlyCollection(l); - - string json = JsonConvert.SerializeObject(list, Formatting.Indented); - Assert.AreEqual(@"[ - 1, - 2, - 3 -]", json); - } -#endif - - public class PrivateDefaultCtorList : List - { - private PrivateDefaultCtorList() - { - } - } - - [Test] - public void DeserializePrivateListCtor() - { - ExceptionAssert.Throws( - "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PrivateDefaultCtorList`1[System.Int32]. Path '', line 1, position 1.", - () => JsonConvert.DeserializeObject>("[1,2]") - ); - - var list = JsonConvert.DeserializeObject>("[1,2]", new JsonSerializerSettings - { - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor - }); - - Assert.AreEqual(2, list.Count); - } - - public class PrivateDefaultCtorWithIEnumerableCtorList : List - { - private PrivateDefaultCtorWithIEnumerableCtorList() - { - } - - public PrivateDefaultCtorWithIEnumerableCtorList(IEnumerable values) - : base(values) - { - Add(default(T)); - } - } - - [Test] - public void DeserializePrivateListConstructor() - { - var list = JsonConvert.DeserializeObject>("[1,2]"); - - Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list[0]); - Assert.AreEqual(2, list[1]); - Assert.AreEqual(0, list[2]); - } - - [Test] - public void DeserializeNonIsoDateDictionaryKey() - { - Dictionary d = JsonConvert.DeserializeObject>(@"{""04/28/2013 00:00:00"":""test""}"); - - Assert.AreEqual(1, d.Count); - - DateTime key = DateTime.Parse("04/28/2013 00:00:00", CultureInfo.InvariantCulture); - Assert.AreEqual("test", d[key]); - } - - public class IdReferenceResolver : IReferenceResolver - { - private readonly IDictionary _people = new Dictionary(); - - public object ResolveReference(object context, string reference) - { - Guid id = new Guid(reference); - - PersonReference p; - _people.TryGetValue(id, out p); - - return p; - } - - public string GetReference(object context, object value) - { - PersonReference p = (PersonReference)value; - _people[p.Id] = p; - - return p.Id.ToString(); - } - - public bool IsReferenced(object context, object value) - { - PersonReference p = (PersonReference)value; - - return _people.ContainsKey(p.Id); - } - - public void AddReference(object context, string reference, object value) - { - Guid id = new Guid(reference); - - _people[id] = (PersonReference)value; - } - } - [Test] public void SerializeCustomReferenceResolver() { @@ -9838,126 +7464,6 @@ Parameter name: value", } #if !(NETFX_CORE || NET35 || NET20 || PORTABLE || PORTABLE40) - [TypeConverter(typeof(MyInterfaceConverter))] - internal interface IMyInterface - { - string Name { get; } - - string PrintTest(); - } - - internal class MyInterfaceConverter : TypeConverter - { - private readonly List _writers = new List - { - new ConsoleWriter(), - new TraceWriter() - }; - - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return destinationType == typeof(string); - } - - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string); - } - - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value == null) - return null; - - return (from w in _writers where w.Name == value.ToString() select w).FirstOrDefault(); - } - - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, - Type destinationType) - { - if (value == null) - return null; - return ((IMyInterface)value).Name; - } - } - - [TypeConverter(typeof(MyInterfaceConverter))] - internal class ConsoleWriter : IMyInterface - { - public string Name - { - get { return "Console Writer"; } - } - - public string PrintTest() - { - return "ConsoleWriter"; - } - - public override string ToString() - { - return Name; - } - } - - internal class TraceWriter : IMyInterface - { - public string Name - { - get { return "Trace Writer"; } - } - - public override string ToString() - { - return Name; - } - - public string PrintTest() - { - return "TraceWriter"; - } - } - - internal class TypeConverterJsonConverter : JsonConverter - { - private TypeConverter GetConverter(Type type) - { - var converters = type.GetCustomAttributes(typeof(TypeConverterAttribute), true).Union( - from t in type.GetInterfaces() - from c in t.GetCustomAttributes(typeof(TypeConverterAttribute), true) - select c).Distinct(); - - return - (from c in converters - let converter = - (TypeConverter)Activator.CreateInstance(Type.GetType(((TypeConverterAttribute)c).ConverterTypeName)) - where converter.CanConvertFrom(typeof(string)) - && converter.CanConvertTo(typeof(string)) - select converter) - .FirstOrDefault(); - } - - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var converter = GetConverter(value.GetType()); - var text = converter.ConvertToInvariantString(value); - - writer.WriteValue(text); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var converter = GetConverter(objectType); - return converter.ConvertFromInvariantString(reader.Value.ToString()); - } - - public override bool CanConvert(Type objectType) - { - return GetConverter(objectType) != null; - } - } - [Test] public void TypeConverterOnInterface() { @@ -10022,32 +7528,6 @@ Parameter name: value", ParticipantEntity deserializedProduct = JsonConvert.DeserializeObject(json); } - internal class ParticipantEntity - { - private Dictionary _properties; - - [JsonConstructor] - public ParticipantEntity() - { - } - - /// - /// Gets or sets the date and time that the participant was created in the CU. - /// - [JsonProperty(PropertyName = "pa_created", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)] - public DateTimeOffset CreationDate { get; internal set; } - - /// - /// Gets the properties of the participant. - /// - [JsonProperty(PropertyName = "pa_info")] - public Dictionary Properties - { - get { return _properties ?? (_properties = new Dictionary()); } - set { _properties = value; } - } - } - #if !(PORTABLE || NETFX_CORE) public class ConvertibleId : IConvertible { @@ -10187,733 +7667,4 @@ Parameter name: value", Assert.AreEqual(originalUri, uriWithPlus2.OriginalString); } } - - public class PersonReference - { - internal Guid Id { get; set; } - public string Name { get; set; } - public PersonReference Spouse { get; set; } - } - - public enum Antworten - { - First, - Second - } - - public class SelectListItem - { - public string Text { get; set; } - public string Value { get; set; } - public bool Selected { get; set; } - } - -#if !(NETFX_CORE || PORTABLE) - [Serializable] - public class AnswerFilterModel - { - [NonSerialized] - private readonly IList answerValues; - - /// - /// Initializes a new instance of the class. - /// - public AnswerFilterModel() - { - answerValues = (from answer in Enum.GetNames(typeof(Antworten)) - select new SelectListItem { Text = answer, Value = answer, Selected = false }) - .ToList(); - } - - /// - /// Gets or sets a value indicating whether active. - /// - public bool Active { get; set; } - - /// - /// Gets or sets a value indicating whether ja. - /// nach bisherigen Antworten. - /// - public bool Ja { get; set; } - - /// - /// Gets or sets a value indicating whether handlungsbedarf. - /// - public bool Handlungsbedarf { get; set; } - - /// - /// Gets or sets a value indicating whether beratungsbedarf. - /// - public bool Beratungsbedarf { get; set; } - - /// - /// Gets or sets a value indicating whether unzutreffend. - /// - public bool Unzutreffend { get; set; } - - /// - /// Gets or sets a value indicating whether unbeantwortet. - /// - public bool Unbeantwortet { get; set; } - - /// - /// Gets the answer values. - /// - public IEnumerable AnswerValues - { - get { return answerValues; } - } - } - - [Serializable] - public class PersonSerializable - { - public PersonSerializable() - { - } - - private string _name = ""; - - public string Name - { - get { return _name; } - set { _name = value; } - } - - [NonSerialized] - private int _age = 0; - - public int Age - { - get { return _age; } - set { _age = value; } - } - } -#endif - - public class Event - { - public string EventName { get; set; } - public string Venue { get; set; } - - [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] - public IList Performances { get; set; } - } - - public class PropertyItemConverter - { - [JsonProperty(ItemConverterType = typeof(MetroStringConverter))] - public IList Data { get; set; } - } - - public class PersonWithPrivateConstructor - { - private PersonWithPrivateConstructor() - { - } - - public static PersonWithPrivateConstructor CreatePerson() - { - return new PersonWithPrivateConstructor(); - } - - public string Name { get; set; } - - public int Age { get; set; } - } - - public class DateTimeWrapper - { - public DateTime Value { get; set; } - } - - public class Widget1 - { - public WidgetId1? Id { get; set; } - } - - [JsonConverter(typeof(WidgetIdJsonConverter))] - public struct WidgetId1 - { - public long Value { get; set; } - } - - public class WidgetIdJsonConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - return objectType == typeof(WidgetId1) || objectType == typeof(WidgetId1?); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - WidgetId1 id = (WidgetId1)value; - writer.WriteValue(id.Value.ToString()); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - return new WidgetId1 { Value = int.Parse(reader.Value.ToString()) }; - } - } - - - public enum MyEnum - { - Value1, - Value2, - Value3 - } - - public class WithEnums - { - public int Id { get; set; } - public MyEnum? NullableEnum { get; set; } - } - - public class Item - { - public Guid SourceTypeID { get; set; } - public Guid BrokerID { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } - public DateTime TimeStamp { get; set; } - - [JsonProperty(TypeNameHandling = TypeNameHandling.All)] - public object Payload { get; set; } - } - - public class NullableGuid - { - public Guid? Id { get; set; } - } - - public class Widget - { - public WidgetId? Id { get; set; } - } - - public struct WidgetId - { - public string Value { get; set; } - } - - public class DecimalTestClass - { - public decimal Quantity { get; set; } - public double OptionalQuantity { get; set; } - } - - public class TestObject - { - public TestObject() - { - } - - public TestObject(string name, byte[] data) - { - Name = name; - Data = data; - } - - public string Name { get; set; } - public byte[] Data { get; set; } - } - - public class UriGuidTimeSpanTestClass - { - public Guid Guid { get; set; } - public Guid? NullableGuid { get; set; } - public TimeSpan TimeSpan { get; set; } - public TimeSpan? NullableTimeSpan { get; set; } - public Uri Uri { get; set; } - } - - internal class Aa - { - public int no; - } - - internal class Bb : Aa - { - public new bool no; - } - -#if !(NET35 || NET20) - [JsonObject(MemberSerialization.OptIn)] - public class GameObject - { - [JsonProperty] - public string Id { get; set; } - - [JsonProperty] - public string Name { get; set; } - - [JsonProperty] - public ConcurrentDictionary Components; - - public GameObject() - { - Components = new ConcurrentDictionary(); - } - } - - [JsonObject(MemberSerialization.OptIn)] - public class Component - { - [JsonIgnore] // Ignore circular reference - public GameObject GameObject { get; set; } - - public Component() - { - } - } - - [JsonObject(MemberSerialization.OptIn)] - public class TestComponent : Component - { - [JsonProperty] - public int MyProperty { get; set; } - - public TestComponent() - { - } - } -#endif - - [JsonObject(MemberSerialization.OptIn)] - public class TestComponentSimple - { - [JsonProperty] - public int MyProperty { get; set; } - - public TestComponentSimple() - { - } - } - - [JsonObject(ItemRequired = Required.Always)] - public class RequiredObject - { - public int? NonAttributeProperty { get; set; } - - [JsonProperty] - public int? UnsetProperty { get; set; } - - [JsonProperty(Required = Required.Default)] - public int? DefaultProperty { get; set; } - - [JsonProperty(Required = Required.AllowNull)] - public int? AllowNullProperty { get; set; } - - [JsonProperty(Required = Required.Always)] - public int? AlwaysProperty { get; set; } - } - - public class MetroStringConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { -#if !(NETFX_CORE) - writer.WriteValue(":::" + value.ToString().ToUpper(CultureInfo.InvariantCulture) + ":::"); -#else - writer.WriteValue(":::" + value.ToString().ToUpper() + ":::"); -#endif - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - string s = (string)reader.Value; - if (s == null) - return null; - -#if !(NETFX_CORE) - return s.ToLower(CultureInfo.InvariantCulture).Trim(new[] { ':' }); -#else - return s.ToLower().Trim(new[] { ':' }); -#endif - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(string); - } - } - - public class MetroPropertyNameResolver : DefaultContractResolver - { - protected internal override string ResolvePropertyName(string propertyName) - { -#if !(NETFX_CORE) - return ":::" + propertyName.ToUpper(CultureInfo.InvariantCulture) + ":::"; -#else - return ":::" + propertyName.ToUpper() + ":::"; -#endif - } - } - -#if !(NET20 || NET35) - [DataContract] - public class DataContractSerializationAttributesClass - { - public string NoAttribute { get; set; } - - [IgnoreDataMember] - public string IgnoreDataMemberAttribute { get; set; } - - [DataMember] - public string DataMemberAttribute { get; set; } - - [IgnoreDataMember] - [DataMember] - public string IgnoreDataMemberAndDataMemberAttribute { get; set; } - } - - public class PocoDataContractSerializationAttributesClass - { - public string NoAttribute { get; set; } - - [IgnoreDataMember] - public string IgnoreDataMemberAttribute { get; set; } - - [DataMember] - public string DataMemberAttribute { get; set; } - - [IgnoreDataMember] - [DataMember] - public string IgnoreDataMemberAndDataMemberAttribute { get; set; } - } -#endif - - public class Array2D - { - public string Before { get; set; } - public int[,] Coordinates { get; set; } - public string After { get; set; } - } - - public class Array3D - { - public string Before { get; set; } - public int[,,] Coordinates { get; set; } - public string After { get; set; } - } - - public class Array3DWithConverter - { - public string Before { get; set; } - - [JsonProperty(ItemConverterType = typeof(IntToFloatConverter))] - public int[,,] Coordinates { get; set; } - - public string After { get; set; } - } - - public class IntToFloatConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - writer.WriteValue(Convert.ToDouble(value)); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return Convert.ToInt32(reader.Value); - } - - public override bool CanConvert(Type objectType) - { - return objectType == typeof(int); - } - } - - public class ShouldSerializeTestClass - { - internal bool _shouldSerializeName; - - public string Name { get; set; } - public int Age { get; set; } - - public void ShouldSerializeAge() - { - // dummy. should never be used because it doesn't return bool - } - - public bool ShouldSerializeName() - { - return _shouldSerializeName; - } - } - - public class SpecifiedTestClass - { - private bool _nameSpecified; - - public string Name { get; set; } - public int Age { get; set; } - public int Weight { get; set; } - public int Height { get; set; } - public int FavoriteNumber { get; set; } - - // dummy. should never be used because it isn't of type bool - [JsonIgnore] - public long AgeSpecified { get; set; } - - [JsonIgnore] - public bool NameSpecified - { - get { return _nameSpecified; } - set { _nameSpecified = value; } - } - - [JsonIgnore] - public bool WeightSpecified; - - [JsonIgnore] - [System.Xml.Serialization.XmlIgnoreAttribute] - public bool HeightSpecified; - - [JsonIgnore] - public bool FavoriteNumberSpecified - { - // get only example - get { return FavoriteNumber != 0; } - } - } - - public class DirectoryAccount - { - // normal deserialization - public string DisplayName { get; set; } - - // these properties are set in OnDeserialized - public string UserName { get; set; } - public string Domain { get; set; } - - [JsonExtensionData] - private IDictionary _additionalData; - - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - // SAMAccountName is not deserialized to any property - // and so it is added to the extension data dictionary - string samAccountName = (string)_additionalData["SAMAccountName"]; - - Domain = samAccountName.Split('\\')[0]; - UserName = samAccountName.Split('\\')[1]; - } - - public DirectoryAccount() - { - _additionalData = new Dictionary(); - } - } - -#if !NETFX_CORE - public struct Ratio : IConvertible, IFormattable, ISerializable - { - private readonly int _numerator; - private readonly int _denominator; - - public Ratio(int numerator, int denominator) - { - _numerator = numerator; - _denominator = denominator; - } - - #region Properties - public int Numerator - { - get { return _numerator; } - } - - public int Denominator - { - get { return _denominator; } - } - - public bool IsNan - { - get { return _denominator == 0; } - } - #endregion - - #region Serialization operations - public Ratio(SerializationInfo info, StreamingContext context) - { - _numerator = info.GetInt32("n"); - _denominator = info.GetInt32("d"); - } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("n", _numerator); - info.AddValue("d", _denominator); - } - #endregion - - #region IConvertible Members - public TypeCode GetTypeCode() - { - return TypeCode.Object; - } - - public bool ToBoolean(IFormatProvider provider) - { - return _numerator == 0; - } - - public byte ToByte(IFormatProvider provider) - { - return (byte)(_numerator / _denominator); - } - - public char ToChar(IFormatProvider provider) - { - return Convert.ToChar(_numerator / _denominator); - } - - public DateTime ToDateTime(IFormatProvider provider) - { - return Convert.ToDateTime(_numerator / _denominator); - } - - public decimal ToDecimal(IFormatProvider provider) - { - return (decimal)_numerator / _denominator; - } - - public double ToDouble(IFormatProvider provider) - { - return _denominator == 0 - ? double.NaN - : (double)_numerator / _denominator; - } - - public short ToInt16(IFormatProvider provider) - { - return (short)(_numerator / _denominator); - } - - public int ToInt32(IFormatProvider provider) - { - return _numerator / _denominator; - } - - public long ToInt64(IFormatProvider provider) - { - return _numerator / _denominator; - } - - public sbyte ToSByte(IFormatProvider provider) - { - return (sbyte)(_numerator / _denominator); - } - - public float ToSingle(IFormatProvider provider) - { - return _denominator == 0 - ? float.NaN - : (float)_numerator / _denominator; - } - - public string ToString(IFormatProvider provider) - { - return _denominator == 1 - ? _numerator.ToString(provider) - : _numerator.ToString(provider) + "/" + _denominator.ToString(provider); - } - - public object ToType(Type conversionType, IFormatProvider provider) - { - return Convert.ChangeType(ToDouble(provider), conversionType, provider); - } - - public ushort ToUInt16(IFormatProvider provider) - { - return (ushort)(_numerator / _denominator); - } - - public uint ToUInt32(IFormatProvider provider) - { - return (uint)(_numerator / _denominator); - } - - public ulong ToUInt64(IFormatProvider provider) - { - return (ulong)(_numerator / _denominator); - } - #endregion - - #region String operations - public override string ToString() - { - return ToString(CultureInfo.InvariantCulture); - } - - public string ToString(string format, IFormatProvider formatProvider) - { - return ToString(CultureInfo.InvariantCulture); - } - - public static Ratio Parse(string input) - { - return Parse(input, CultureInfo.InvariantCulture); - } - - public static Ratio Parse(string input, IFormatProvider formatProvider) - { - Ratio result; - if (!TryParse(input, formatProvider, out result)) - { - throw new FormatException( - string.Format( - CultureInfo.InvariantCulture, - "Text '{0}' is invalid text representation of ratio", - input)); - } - return result; - } - - public static bool TryParse(string input, out Ratio result) - { - return TryParse(input, CultureInfo.InvariantCulture, out result); - } - - public static bool TryParse(string input, IFormatProvider formatProvider, out Ratio result) - { - if (input != null) - { - var fractionIndex = input.IndexOf('/'); - - int numerator; - if (fractionIndex < 0) - { - if (int.TryParse(input, NumberStyles.Integer, formatProvider, out numerator)) - { - result = new Ratio(numerator, 1); - return true; - } - } - else - { - int denominator; - if (int.TryParse(input.Substring(0, fractionIndex), NumberStyles.Integer, formatProvider, out numerator) && - int.TryParse(input.Substring(fractionIndex + 1), NumberStyles.Integer, formatProvider, out denominator)) - { - result = new Ratio(numerator, denominator); - return true; - } - } - } - - result = default(Ratio); - return false; - } - #endregion - } -#endif } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs new file mode 100644 index 00000000..a163fbfa --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs @@ -0,0 +1,543 @@ +#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; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; +using Newtonsoft.Json.Serialization; +using NUnit.Framework; + +namespace Newtonsoft.Json.Tests.Serialization +{ + [TestFixture] + public class ShouldSerializeTests : TestFixtureBase + { + [Test] + public void VirtualShouldSerialize() + { + var setFoo = new Foo1() + { + name = Guid.NewGuid().ToString(), + myBar = new Bar1() + { + name = Guid.NewGuid().ToString(), + myBaz = new Baz1[] { + new Baz1(){ + name = Guid.NewGuid().ToString(), + myFrob = new Frob1[]{ + new Frob1{name = Guid.NewGuid().ToString()} + } + }, + new Baz1(){ + name = Guid.NewGuid().ToString(), + myFrob = new Frob1[]{ + new Frob1{name = Guid.NewGuid().ToString()} + } + }, + new Baz1(){ + name = Guid.NewGuid().ToString(), + myFrob = new Frob1[]{ + new Frob1{name = Guid.NewGuid().ToString()} + } + }, + } + } + }; + + var setFooJson = Serialize(setFoo); + var deserializedSetFoo = JsonConvert.DeserializeObject(setFooJson); + + Assert.AreEqual(setFoo.name, deserializedSetFoo.name); + Assert.NotNull(deserializedSetFoo.myBar); + Assert.AreEqual(setFoo.myBar.name, deserializedSetFoo.myBar.name); + Assert.NotNull(deserializedSetFoo.myBar.myBaz); + Assert.AreEqual(setFoo.myBar.myBaz.Length, deserializedSetFoo.myBar.myBaz.Length); + Assert.AreEqual(setFoo.myBar.myBaz[0].name, deserializedSetFoo.myBar.myBaz[0].name); + Assert.IsNotNull(deserializedSetFoo.myBar.myBaz[0].myFrob[0]); + Assert.AreEqual(setFoo.myBar.myBaz[0].myFrob[0].name, deserializedSetFoo.myBar.myBaz[0].myFrob[0].name); + Assert.AreEqual(setFoo.myBar.myBaz[1].name, deserializedSetFoo.myBar.myBaz[1].name); + Assert.IsNotNull(deserializedSetFoo.myBar.myBaz[2].myFrob[0]); + Assert.AreEqual(setFoo.myBar.myBaz[1].myFrob[0].name, deserializedSetFoo.myBar.myBaz[1].myFrob[0].name); + Assert.AreEqual(setFoo.myBar.myBaz[2].name, deserializedSetFoo.myBar.myBaz[2].name); + Assert.IsNotNull(deserializedSetFoo.myBar.myBaz[2].myFrob[0]); + Assert.AreEqual(setFoo.myBar.myBaz[2].myFrob[0].name, deserializedSetFoo.myBar.myBaz[2].myFrob[0].name); + + Assert.AreEqual(true, setFoo.myBar.ShouldSerializemyBazCalled); + } + + private string Serialize(Foo1 f) + { + //Code copied from JsonConvert.SerializeObject(), with addition of trace writing + JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(); + var traceWriter = new MemoryTraceWriter(); + jsonSerializer.TraceWriter = traceWriter; + + StringBuilder sb = new StringBuilder(256); + StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.None; + jsonSerializer.Serialize(jsonWriter, f, typeof(Foo1)); + } + + Console.Out.WriteLine("Trace output:\n{0}", traceWriter.ToString()); + + return sw.ToString(); + } + + [Test] + public void ShouldSerializeTest() + { + ShouldSerializeTestClass c = new ShouldSerializeTestClass(); + c.Name = "James"; + c.Age = 27; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Age"": 27 +}", json); + + c._shouldSerializeName = true; + json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Name"": ""James"", + ""Age"": 27 +}", json); + + ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("James", deserialized.Name); + Assert.AreEqual(27, deserialized.Age); + } + + [Test] + public void ShouldSerializeExample() + { + Employee joe = new Employee(); + joe.Name = "Joe Employee"; + Employee mike = new Employee(); + mike.Name = "Mike Manager"; + + joe.Manager = mike; + mike.Manager = mike; + + string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); + // [ + // { + // "Name": "Joe Employee", + // "Manager": { + // "Name": "Mike Manager" + // } + // }, + // { + // "Name": "Mike Manager" + // } + // ] + + Console.WriteLine(json); + } + + [Test] + public void SpecifiedTest() + { + SpecifiedTestClass c = new SpecifiedTestClass(); + c.Name = "James"; + c.Age = 27; + c.NameSpecified = false; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Age"": 27 +}", json); + + SpecifiedTestClass deserialized = JsonConvert.DeserializeObject(json); + Assert.IsNull(deserialized.Name); + Assert.IsFalse(deserialized.NameSpecified); + Assert.IsFalse(deserialized.WeightSpecified); + Assert.IsFalse(deserialized.HeightSpecified); + Assert.IsFalse(deserialized.FavoriteNumberSpecified); + Assert.AreEqual(27, deserialized.Age); + + c.NameSpecified = true; + c.WeightSpecified = true; + c.HeightSpecified = true; + c.FavoriteNumber = 23; + json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Name"": ""James"", + ""Age"": 27, + ""Weight"": 0, + ""Height"": 0, + ""FavoriteNumber"": 23 +}", json); + + deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("James", deserialized.Name); + Assert.IsTrue(deserialized.NameSpecified); + Assert.IsTrue(deserialized.WeightSpecified); + Assert.IsTrue(deserialized.HeightSpecified); + Assert.IsTrue(deserialized.FavoriteNumberSpecified); + Assert.AreEqual(27, deserialized.Age); + Assert.AreEqual(23, deserialized.FavoriteNumber); + } + + // [Test] + // public void XmlSerializerSpecifiedTrueTest() + // { + // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); + + // StringWriter sw = new StringWriter(); + // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true }); + + // Console.WriteLine(sw.ToString()); + + // string xml = @" + // + // First + //"; + + // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); + // Console.WriteLine(o.FirstOrder); + // Console.WriteLine(o.FirstOrderSpecified); + // } + + // [Test] + // public void XmlSerializerSpecifiedFalseTest() + // { + // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); + + // StringWriter sw = new StringWriter(); + // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false }); + + // Console.WriteLine(sw.ToString()); + + // // string xml = @" + // // + // // First + // //"; + + // // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); + // // Console.WriteLine(o.FirstOrder); + // // Console.WriteLine(o.FirstOrderSpecified); + // } + + public class OptionalOrder + { + // This field shouldn't be serialized + // if it is uninitialized. + public string FirstOrder; + // Use the XmlIgnoreAttribute to ignore the + // special field named "FirstOrderSpecified". + [System.Xml.Serialization.XmlIgnoreAttribute] + public bool FirstOrderSpecified; + } + + public class FamilyDetails + { + public string Name { get; set; } + public int NumberOfChildren { get; set; } + + [JsonIgnore] + public bool NumberOfChildrenSpecified { get; set; } + } + + [Test] + public void SpecifiedExample() + { + FamilyDetails joe = new FamilyDetails(); + joe.Name = "Joe Family Details"; + joe.NumberOfChildren = 4; + joe.NumberOfChildrenSpecified = true; + + FamilyDetails martha = new FamilyDetails(); + martha.Name = "Martha Family Details"; + martha.NumberOfChildren = 3; + martha.NumberOfChildrenSpecified = false; + + string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented); + //[ + // { + // "Name": "Joe Family Details", + // "NumberOfChildren": 4 + // }, + // { + // "Name": "Martha Family Details" + // } + //] + Console.WriteLine(json); + + string mikeString = "{\"Name\": \"Mike Person\"}"; + FamilyDetails mike = JsonConvert.DeserializeObject(mikeString); + + Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); + + string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}"; + mike = JsonConvert.DeserializeObject(mikeFullDisclosureString); + + Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); + } + + [Test] + public void ShouldSerializeInheritedClassTest() + { + NewEmployee joe = new NewEmployee(); + joe.Name = "Joe Employee"; + joe.Age = 100; + + Employee mike = new Employee(); + mike.Name = "Mike Manager"; + mike.Manager = mike; + + joe.Manager = mike; + + //StringWriter sw = new StringWriter(); + + //XmlSerializer x = new XmlSerializer(typeof(NewEmployee)); + //x.Serialize(sw, joe); + + //Console.WriteLine(sw); + + //JavaScriptSerializer s = new JavaScriptSerializer(); + //Console.WriteLine(s.Serialize(new {html = @"; & ! ^ * ( ) ! @ # $ % ^ ' "" - , . / ; : [ { } ] ; ' - _ = + ? ` ~ \ |"})); + + string json = JsonConvert.SerializeObject(joe, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Age"": 100, + ""Name"": ""Joe Employee"", + ""Manager"": { + ""Name"": ""Mike Manager"" + } +}", json); + } + + public class Employee + { + public string Name { get; set; } + public Employee Manager { get; set; } + + public bool ShouldSerializeManager() + { + return (Manager != this); + } + } + + public class NewEmployee : Employee + { + public int Age { get; set; } + + public bool ShouldSerializeName() + { + return false; + } + } + } + + public class ShouldSerializeTestClass + { + internal bool _shouldSerializeName; + + public string Name { get; set; } + public int Age { get; set; } + + public void ShouldSerializeAge() + { + // dummy. should never be used because it doesn't return bool + } + + public bool ShouldSerializeName() + { + return _shouldSerializeName; + } + } + + public class SpecifiedTestClass + { + private bool _nameSpecified; + + public string Name { get; set; } + public int Age { get; set; } + public int Weight { get; set; } + public int Height { get; set; } + public int FavoriteNumber { get; set; } + + // dummy. should never be used because it isn't of type bool + [JsonIgnore] + public long AgeSpecified { get; set; } + + [JsonIgnore] + public bool NameSpecified + { + get { return _nameSpecified; } + set { _nameSpecified = value; } + } + + [JsonIgnore] + public bool WeightSpecified; + + [JsonIgnore] + [System.Xml.Serialization.XmlIgnoreAttribute] + public bool HeightSpecified; + + [JsonIgnore] + public bool FavoriteNumberSpecified + { + // get only example + get { return FavoriteNumber != 0; } + } + } + + public class Foo1 + { + private Bar1 myBarField; + public Bar1 myBar + { + get + { + return myBarField; + } + set { myBarField = value; } + } + + private string nameField; + public string name + { + get + { + return nameField; + } + set + { + nameField = value; + } + } + + public virtual bool ShouldSerializemyBar() + { + return (myBar != null); + } + + public virtual bool ShouldSerializename() + { + return (name != null); + } + } + + public class Bar1 + { + [JsonIgnore] + public bool ShouldSerializemyBazCalled { get; set;} + + private Baz1[] myBazField; + public Baz1[] myBaz + { + get + { + return myBazField; + } + set { myBazField = value; } + } + + private string nameField; + public string name + { + get + { + return nameField; + } + set + { + nameField = value; + } + } + + public virtual bool ShouldSerializemyBaz() + { + ShouldSerializemyBazCalled = true; + return (myBaz != null); + } + + public virtual bool ShouldSerializename() + { + return (name != null); + } + } + + public class Baz1 + { + private Frob1[] myFrobField; + public Frob1[] myFrob + { + get + { + return myFrobField; + } + set { myFrobField = value; } + } + + private string nameField; + public string name + { + get + { + return nameField; + } + set { nameField = value; } + } + + public virtual bool ShouldSerializename() + { + return (name != null); + } + + public virtual bool ShouldSerializemyFrob() + { + return (myFrob != null); + } + } + + public class Frob1 + { + private string nameField; + public string name + { + get + { + return nameField; + } + set { nameField = value; } + } + + public virtual bool ShouldSerializename() + { + return (name != null); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs index eef960d9..c5c582dd 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -1173,7 +1173,7 @@ namespace Newtonsoft.Json.Tests.Serialization string json = JsonConvert.SerializeObject(l, Formatting.Indented); Assert.AreEqual(@"[ { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 0 }, { @@ -1208,7 +1208,7 @@ namespace Newtonsoft.Json.Tests.Serialization string json = JsonConvert.SerializeObject(l, Formatting.Indented); Assert.AreEqual(@"{ ""First"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""Second"": ""String!"", @@ -1238,7 +1238,7 @@ namespace Newtonsoft.Json.Tests.Serialization string json = JsonConvert.SerializeObject(o1, Formatting.Indented); string expected = @"{ ""Object1"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""Object2"": 123, @@ -1279,7 +1279,7 @@ namespace Newtonsoft.Json.Tests.Serialization 1, ""two"", { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 } ] @@ -1317,7 +1317,7 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(@"{ ""Data"": [ { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, { @@ -1342,14 +1342,14 @@ namespace Newtonsoft.Json.Tests.Serialization json = @"{ ""Data"": [ { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, { ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"", ""$values"": [ { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 } ] @@ -1396,7 +1396,7 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(@"{ ""Data"": { ""one"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""two"": { @@ -1419,13 +1419,13 @@ namespace Newtonsoft.Json.Tests.Serialization json = @"{ ""Data"": { ""one"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""two"": { ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"", ""one"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 } } @@ -1479,7 +1479,7 @@ namespace Newtonsoft.Json.Tests.Serialization ] }, ""Prop2"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""Prop3"": 3, @@ -1527,7 +1527,7 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(@"{ ""Data"": { ""one"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""two"": { @@ -1554,13 +1554,13 @@ namespace Newtonsoft.Json.Tests.Serialization json = @"{ ""Data"": { ""one"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 }, ""two"": { ""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"", ""one"": { - ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 2 } } diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Aa.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Aa.cs new file mode 100644 index 00000000..873c1c36 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Aa.cs @@ -0,0 +1,32 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + internal class Aa + { + public int no; + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/AnswerFilterModel.cs b/Src/Newtonsoft.Json.Tests/TestObjects/AnswerFilterModel.cs new file mode 100644 index 00000000..ed484a73 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/AnswerFilterModel.cs @@ -0,0 +1,93 @@ +#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; +using System.Collections; +#if NET20 +using Newtonsoft.Json.Utilities.LinqBridge; +#else +using System.Linq; +#endif + +namespace Newtonsoft.Json.Tests.TestObjects +{ +#if !(NETFX_CORE || PORTABLE) + [Serializable] + public class AnswerFilterModel + { + [NonSerialized] + private readonly IList answerValues; + + /// + /// Initializes a new instance of the class. + /// + public AnswerFilterModel() + { + answerValues = (from answer in Enum.GetNames(typeof(Antworten)) + select new SelectListItem { Text = answer, Value = answer, Selected = false }) + .ToList(); + } + + /// + /// Gets or sets a value indicating whether active. + /// + public bool Active { get; set; } + + /// + /// Gets or sets a value indicating whether ja. + /// nach bisherigen Antworten. + /// + public bool Ja { get; set; } + + /// + /// Gets or sets a value indicating whether handlungsbedarf. + /// + public bool Handlungsbedarf { get; set; } + + /// + /// Gets or sets a value indicating whether beratungsbedarf. + /// + public bool Beratungsbedarf { get; set; } + + /// + /// Gets or sets a value indicating whether unzutreffend. + /// + public bool Unzutreffend { get; set; } + + /// + /// Gets or sets a value indicating whether unbeantwortet. + /// + public bool Unbeantwortet { get; set; } + + /// + /// Gets the answer values. + /// + public IEnumerable AnswerValues + { + get { return answerValues; } + } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Antworten.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Antworten.cs new file mode 100644 index 00000000..80e56978 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Antworten.cs @@ -0,0 +1,33 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public enum Antworten + { + First, + Second + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Bb.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Bb.cs new file mode 100644 index 00000000..49373170 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Bb.cs @@ -0,0 +1,32 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + internal class Bb : Aa + { + public new bool no; + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Component.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Component.cs new file mode 100644 index 00000000..6082d35d --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Component.cs @@ -0,0 +1,40 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + #if !(NET35 || NET20) + [JsonObject(MemberSerialization.OptIn)] + public class Component + { + [JsonIgnore] // Ignore circular reference + public GameObject GameObject { get; set; } + + public Component() + { + } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DataContractSerializationAttributesClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DataContractSerializationAttributesClass.cs new file mode 100644 index 00000000..5c430241 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DataContractSerializationAttributesClass.cs @@ -0,0 +1,47 @@ +#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.Runtime.Serialization; + +namespace Newtonsoft.Json.Tests.TestObjects +{ +#if !(NET20 || NET35) + [DataContract] + public class DataContractSerializationAttributesClass + { + public string NoAttribute { get; set; } + + [IgnoreDataMember] + public string IgnoreDataMemberAttribute { get; set; } + + [DataMember] + public string DataMemberAttribute { get; set; } + + [IgnoreDataMember] + [DataMember] + public string IgnoreDataMemberAndDataMemberAttribute { get; set; } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeWrapper.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeWrapper.cs new file mode 100644 index 00000000..7d225e64 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeWrapper.cs @@ -0,0 +1,34 @@ +#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 +{ + public class DateTimeWrapper + { + public DateTime Value { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DecimalTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DecimalTestClass.cs new file mode 100644 index 00000000..e31a1702 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DecimalTestClass.cs @@ -0,0 +1,33 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class DecimalTestClass + { + public decimal Quantity { get; set; } + public double OptionalQuantity { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DirectoryAccount.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DirectoryAccount.cs new file mode 100644 index 00000000..f8d7777d --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DirectoryAccount.cs @@ -0,0 +1,60 @@ +#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.Collections.Generic; +using System.Runtime.Serialization; +using Newtonsoft.Json.Linq; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class DirectoryAccount + { + // normal deserialization + public string DisplayName { get; set; } + + // these properties are set in OnDeserialized + public string UserName { get; set; } + public string Domain { get; set; } + + [JsonExtensionData] + private IDictionary _additionalData; + + [OnDeserialized] + private void OnDeserialized(StreamingContext context) + { + // SAMAccountName is not deserialized to any property + // and so it is added to the extension data dictionary + string samAccountName = (string)_additionalData["SAMAccountName"]; + + Domain = samAccountName.Split('\\')[0]; + UserName = samAccountName.Split('\\')[1]; + } + + public DirectoryAccount() + { + _additionalData = new Dictionary(); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Event1.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Event1.cs new file mode 100644 index 00000000..ddd78f39 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Event1.cs @@ -0,0 +1,40 @@ +#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; +using System.Collections.Generic; +using Newtonsoft.Json.Converters; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class Event1 + { + public string EventName { get; set; } + public string Venue { get; set; } + + [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] + public IList Performances { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/GameObject.cs b/Src/Newtonsoft.Json.Tests/TestObjects/GameObject.cs new file mode 100644 index 00000000..e4a8ca44 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/GameObject.cs @@ -0,0 +1,49 @@ +#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 + +#if !(NET35 || NET20) +using System.Collections.Concurrent; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + [JsonObject(MemberSerialization.OptIn)] + public class GameObject + { + [JsonProperty] + public string Id { get; set; } + + [JsonProperty] + public string Name { get; set; } + + [JsonProperty] + public ConcurrentDictionary Components; + + public GameObject() + { + Components = new ConcurrentDictionary(); + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IMyInterface.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IMyInterface.cs new file mode 100644 index 00000000..725e79a2 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IMyInterface.cs @@ -0,0 +1,160 @@ +#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; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Text; +#if NET20 +using Newtonsoft.Json.Utilities.LinqBridge; +#else +using System.Linq; +#endif + +namespace Newtonsoft.Json.Tests.TestObjects +{ +#if !(NETFX_CORE || NET35 || NET20 || PORTABLE || PORTABLE40) + [TypeConverter(typeof(MyInterfaceConverter))] + internal interface IMyInterface + { + string Name { get; } + + string PrintTest(); + } + + internal class MyInterfaceConverter : TypeConverter + { + private readonly List _writers = new List + { + new ConsoleWriter(), + new TraceWriter() + }; + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(string); + } + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value == null) + return null; + + return (from w in _writers where w.Name == value.ToString() select w).FirstOrDefault(); + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, + Type destinationType) + { + if (value == null) + return null; + return ((IMyInterface)value).Name; + } + } + + [TypeConverter(typeof(MyInterfaceConverter))] + internal class ConsoleWriter : IMyInterface + { + public string Name + { + get { return "Console Writer"; } + } + + public string PrintTest() + { + return "ConsoleWriter"; + } + + public override string ToString() + { + return Name; + } + } + + internal class TraceWriter : IMyInterface + { + public string Name + { + get { return "Trace Writer"; } + } + + public override string ToString() + { + return Name; + } + + public string PrintTest() + { + return "TraceWriter"; + } + } + + internal class TypeConverterJsonConverter : JsonConverter + { + private TypeConverter GetConverter(Type type) + { + var converters = type.GetCustomAttributes(typeof(TypeConverterAttribute), true).Union( + from t in type.GetInterfaces() + from c in t.GetCustomAttributes(typeof(TypeConverterAttribute), true) + select c).Distinct(); + + return + (from c in converters + let converter = + (TypeConverter)Activator.CreateInstance(Type.GetType(((TypeConverterAttribute)c).ConverterTypeName)) + where converter.CanConvertFrom(typeof(string)) + && converter.CanConvertTo(typeof(string)) + select converter) + .FirstOrDefault(); + } + + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var converter = GetConverter(value.GetType()); + var text = converter.ConvertToInvariantString(value); + + writer.WriteValue(text); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var converter = GetConverter(objectType); + return converter.ConvertFromInvariantString(reader.Value.ToString()); + } + + public override bool CanConvert(Type objectType) + { + return GetConverter(objectType) != null; + } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IdReferenceResolver.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IdReferenceResolver.cs new file mode 100644 index 00000000..a7d88325 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IdReferenceResolver.cs @@ -0,0 +1,68 @@ +#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; +using System.Collections.Generic; +using Newtonsoft.Json.Serialization; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class IdReferenceResolver : IReferenceResolver + { + private readonly IDictionary _people = new Dictionary(); + + public object ResolveReference(object context, string reference) + { + Guid id = new Guid(reference); + + PersonReference p; + _people.TryGetValue(id, out p); + + return p; + } + + public string GetReference(object context, object value) + { + PersonReference p = (PersonReference)value; + _people[p.Id] = p; + + return p.Id.ToString(); + } + + public bool IsReferenced(object context, object value) + { + PersonReference p = (PersonReference)value; + + return _people.ContainsKey(p.Id); + } + + public void AddReference(object context, string reference, object value) + { + Guid id = new Guid(reference); + + _people[id] = (PersonReference)value; + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IntToFloatConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IntToFloatConverter.cs new file mode 100644 index 00000000..8ecce9f1 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IntToFloatConverter.cs @@ -0,0 +1,47 @@ +#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 +{ + public class IntToFloatConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue(Convert.ToDouble(value)); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return Convert.ToInt32(reader.Value); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(int); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Item.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Item.cs new file mode 100644 index 00000000..84cff96a --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Item.cs @@ -0,0 +1,41 @@ +#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 +{ + public class Item + { + public Guid SourceTypeID { get; set; } + public Guid BrokerID { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } + public DateTime TimeStamp { get; set; } + + [JsonProperty(TypeNameHandling = TypeNameHandling.All)] + public object Payload { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/MetroPropertyNameResolver.cs b/Src/Newtonsoft.Json.Tests/TestObjects/MetroPropertyNameResolver.cs new file mode 100644 index 00000000..45b86277 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/MetroPropertyNameResolver.cs @@ -0,0 +1,42 @@ +#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.Globalization; +using Newtonsoft.Json.Serialization; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class MetroPropertyNameResolver : DefaultContractResolver + { + protected internal override string ResolvePropertyName(string propertyName) + { +#if !(NETFX_CORE) + return ":::" + propertyName.ToUpper(CultureInfo.InvariantCulture) + ":::"; +#else + return ":::" + propertyName.ToUpper() + ":::"; +#endif + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/MetroStringConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/MetroStringConverter.cs new file mode 100644 index 00000000..d1488c0f --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/MetroStringConverter.cs @@ -0,0 +1,60 @@ +#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; +using System.Globalization; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class MetroStringConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { +#if !(NETFX_CORE) + writer.WriteValue(":::" + value.ToString().ToUpper(CultureInfo.InvariantCulture) + ":::"); +#else + writer.WriteValue(":::" + value.ToString().ToUpper() + ":::"); +#endif + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + string s = (string)reader.Value; + if (s == null) + return null; + +#if !(NETFX_CORE) + return s.ToLower(CultureInfo.InvariantCulture).Trim(new[] { ':' }); +#else + return s.ToLower().Trim(new[] { ':' }); +#endif + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(string); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/NullableGuid.cs b/Src/Newtonsoft.Json.Tests/TestObjects/NullableGuid.cs new file mode 100644 index 00000000..8fa939e0 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/NullableGuid.cs @@ -0,0 +1,34 @@ +#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 +{ + public class NullableGuid + { + public Guid? Id { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ParticipantEntity.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ParticipantEntity.cs new file mode 100644 index 00000000..875e27fc --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ParticipantEntity.cs @@ -0,0 +1,56 @@ +#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; +using System.Collections.Generic; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + internal class ParticipantEntity + { + private Dictionary _properties; + + [JsonConstructor] + public ParticipantEntity() + { + } + + /// + /// Gets or sets the date and time that the participant was created in the CU. + /// + [JsonProperty(PropertyName = "pa_created", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)] + public DateTimeOffset CreationDate { get; internal set; } + + /// + /// Gets the properties of the participant. + /// + [JsonProperty(PropertyName = "pa_info")] + public Dictionary Properties + { + get { return _properties ?? (_properties = new Dictionary()); } + set { _properties = value; } + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonReference.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonReference.cs new file mode 100644 index 00000000..7df34ca0 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonReference.cs @@ -0,0 +1,37 @@ +#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; +using System.Text; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class PersonReference + { + internal Guid Id { get; set; } + public string Name { get; set; } + public PersonReference Spouse { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonSerializable.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonSerializable.cs new file mode 100644 index 00000000..31679626 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonSerializable.cs @@ -0,0 +1,56 @@ +#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 +{ +#if !(NETFX_CORE || PORTABLE) + [Serializable] + public class PersonSerializable + { + public PersonSerializable() + { + } + + private string _name = ""; + + public string Name + { + get { return _name; } + set { _name = value; } + } + + [NonSerialized] + private int _age = 0; + + public int Age + { + get { return _age; } + set { _age = value; } + } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonWithPrivateConstructor.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonWithPrivateConstructor.cs new file mode 100644 index 00000000..f56d7986 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonWithPrivateConstructor.cs @@ -0,0 +1,43 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class PersonWithPrivateConstructor + { + private PersonWithPrivateConstructor() + { + } + + public static PersonWithPrivateConstructor CreatePerson() + { + return new PersonWithPrivateConstructor(); + } + + public string Name { get; set; } + + public int Age { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PocoDataContractSerializationAttributesClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PocoDataContractSerializationAttributesClass.cs new file mode 100644 index 00000000..3e4da6cf --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PocoDataContractSerializationAttributesClass.cs @@ -0,0 +1,46 @@ +#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.Runtime.Serialization; + +namespace Newtonsoft.Json.Tests.TestObjects +{ +#if !(NET20 || NET35) + public class PocoDataContractSerializationAttributesClass + { + public string NoAttribute { get; set; } + + [IgnoreDataMember] + public string IgnoreDataMemberAttribute { get; set; } + + [DataMember] + public string DataMemberAttribute { get; set; } + + [IgnoreDataMember] + [DataMember] + public string IgnoreDataMemberAndDataMemberAttribute { get; set; } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PropertyItemConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PropertyItemConverter.cs new file mode 100644 index 00000000..264540c3 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PropertyItemConverter.cs @@ -0,0 +1,35 @@ +#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.Collections.Generic; + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class PropertyItemConverter + { + [JsonProperty(ItemConverterType = typeof(MetroStringConverter))] + public IList Data { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Ratio.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Ratio.cs new file mode 100644 index 00000000..efa05540 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Ratio.cs @@ -0,0 +1,236 @@ +#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; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Newtonsoft.Json.Tests.TestObjects +{ +#if !NETFX_CORE + public struct Ratio : IConvertible, IFormattable, ISerializable + { + private readonly int _numerator; + private readonly int _denominator; + + public Ratio(int numerator, int denominator) + { + _numerator = numerator; + _denominator = denominator; + } + + #region Properties + public int Numerator + { + get { return _numerator; } + } + + public int Denominator + { + get { return _denominator; } + } + + public bool IsNan + { + get { return _denominator == 0; } + } + #endregion + + #region Serialization operations + public Ratio(SerializationInfo info, StreamingContext context) + { + _numerator = info.GetInt32("n"); + _denominator = info.GetInt32("d"); + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("n", _numerator); + info.AddValue("d", _denominator); + } + #endregion + + #region IConvertible Members + public TypeCode GetTypeCode() + { + return TypeCode.Object; + } + + public bool ToBoolean(IFormatProvider provider) + { + return _numerator == 0; + } + + public byte ToByte(IFormatProvider provider) + { + return (byte)(_numerator / _denominator); + } + + public char ToChar(IFormatProvider provider) + { + return Convert.ToChar(_numerator / _denominator); + } + + public DateTime ToDateTime(IFormatProvider provider) + { + return Convert.ToDateTime(_numerator / _denominator); + } + + public decimal ToDecimal(IFormatProvider provider) + { + return (decimal)_numerator / _denominator; + } + + public double ToDouble(IFormatProvider provider) + { + return _denominator == 0 + ? double.NaN + : (double)_numerator / _denominator; + } + + public short ToInt16(IFormatProvider provider) + { + return (short)(_numerator / _denominator); + } + + public int ToInt32(IFormatProvider provider) + { + return _numerator / _denominator; + } + + public long ToInt64(IFormatProvider provider) + { + return _numerator / _denominator; + } + + public sbyte ToSByte(IFormatProvider provider) + { + return (sbyte)(_numerator / _denominator); + } + + public float ToSingle(IFormatProvider provider) + { + return _denominator == 0 + ? float.NaN + : (float)_numerator / _denominator; + } + + public string ToString(IFormatProvider provider) + { + return _denominator == 1 + ? _numerator.ToString(provider) + : _numerator.ToString(provider) + "/" + _denominator.ToString(provider); + } + + public object ToType(Type conversionType, IFormatProvider provider) + { + return Convert.ChangeType(ToDouble(provider), conversionType, provider); + } + + public ushort ToUInt16(IFormatProvider provider) + { + return (ushort)(_numerator / _denominator); + } + + public uint ToUInt32(IFormatProvider provider) + { + return (uint)(_numerator / _denominator); + } + + public ulong ToUInt64(IFormatProvider provider) + { + return (ulong)(_numerator / _denominator); + } + #endregion + + #region String operations + public override string ToString() + { + return ToString(CultureInfo.InvariantCulture); + } + + public string ToString(string format, IFormatProvider formatProvider) + { + return ToString(CultureInfo.InvariantCulture); + } + + public static Ratio Parse(string input) + { + return Parse(input, CultureInfo.InvariantCulture); + } + + public static Ratio Parse(string input, IFormatProvider formatProvider) + { + Ratio result; + if (!TryParse(input, formatProvider, out result)) + { + throw new FormatException( + string.Format( + CultureInfo.InvariantCulture, + "Text '{0}' is invalid text representation of ratio", + input)); + } + return result; + } + + public static bool TryParse(string input, out Ratio result) + { + return TryParse(input, CultureInfo.InvariantCulture, out result); + } + + public static bool TryParse(string input, IFormatProvider formatProvider, out Ratio result) + { + if (input != null) + { + var fractionIndex = input.IndexOf('/'); + + int numerator; + if (fractionIndex < 0) + { + if (int.TryParse(input, NumberStyles.Integer, formatProvider, out numerator)) + { + result = new Ratio(numerator, 1); + return true; + } + } + else + { + int denominator; + if (int.TryParse(input.Substring(0, fractionIndex), NumberStyles.Integer, formatProvider, out numerator) && + int.TryParse(input.Substring(fractionIndex + 1), NumberStyles.Integer, formatProvider, out denominator)) + { + result = new Ratio(numerator, denominator); + return true; + } + } + } + + result = default(Ratio); + return false; + } + #endregion + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/RequiredObject.cs b/Src/Newtonsoft.Json.Tests/TestObjects/RequiredObject.cs new file mode 100644 index 00000000..c9b0d33e --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/RequiredObject.cs @@ -0,0 +1,45 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + [JsonObject(ItemRequired = Required.Always)] + public class RequiredObject + { + public int? NonAttributeProperty { get; set; } + + [JsonProperty] + public int? UnsetProperty { get; set; } + + [JsonProperty(Required = Required.Default)] + public int? DefaultProperty { get; set; } + + [JsonProperty(Required = Required.AllowNull)] + public int? AllowNullProperty { get; set; } + + [JsonProperty(Required = Required.Always)] + public int? AlwaysProperty { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SelectListItem.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SelectListItem.cs new file mode 100644 index 00000000..b082187a --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SelectListItem.cs @@ -0,0 +1,34 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class SelectListItem + { + public string Text { get; set; } + public string Value { get; set; } + public bool Selected { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/TestComponent.cs b/Src/Newtonsoft.Json.Tests/TestObjects/TestComponent.cs new file mode 100644 index 00000000..99e3e8db --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/TestComponent.cs @@ -0,0 +1,40 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ +#if !(NET35 || NET20) + [JsonObject(MemberSerialization.OptIn)] + public class TestComponent : Component + { + [JsonProperty] + public int MyProperty { get; set; } + + public TestComponent() + { + } + } +#endif +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/TestComponentSimple.cs b/Src/Newtonsoft.Json.Tests/TestObjects/TestComponentSimple.cs new file mode 100644 index 00000000..6c291f49 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/TestComponentSimple.cs @@ -0,0 +1,38 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + [JsonObject(MemberSerialization.OptIn)] + public class TestComponentSimple + { + [JsonProperty] + public int MyProperty { get; set; } + + public TestComponentSimple() + { + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/TestObject.cs b/Src/Newtonsoft.Json.Tests/TestObjects/TestObject.cs new file mode 100644 index 00000000..f35b9065 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/TestObject.cs @@ -0,0 +1,43 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class TestObject + { + public TestObject() + { + } + + public TestObject(string name, byte[] data) + { + Name = name; + Data = data; + } + + public string Name { get; set; } + public byte[] Data { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/UriGuidTimeSpanTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/UriGuidTimeSpanTestClass.cs new file mode 100644 index 00000000..3e500203 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/UriGuidTimeSpanTestClass.cs @@ -0,0 +1,38 @@ +#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 +{ + public class UriGuidTimeSpanTestClass + { + public Guid Guid { get; set; } + public Guid? NullableGuid { get; set; } + public TimeSpan TimeSpan { get; set; } + public TimeSpan? NullableTimeSpan { get; set; } + public Uri Uri { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Widget.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Widget.cs new file mode 100644 index 00000000..bf5bd3c9 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Widget.cs @@ -0,0 +1,32 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class Widget + { + public WidgetId? Id { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Widget1.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Widget1.cs new file mode 100644 index 00000000..55111a8c --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Widget1.cs @@ -0,0 +1,32 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class Widget1 + { + public WidgetId1? Id { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/WidgetId.cs b/Src/Newtonsoft.Json.Tests/TestObjects/WidgetId.cs new file mode 100644 index 00000000..8da9d501 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/WidgetId.cs @@ -0,0 +1,32 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public struct WidgetId + { + public string Value { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/WidgetId1.cs b/Src/Newtonsoft.Json.Tests/TestObjects/WidgetId1.cs new file mode 100644 index 00000000..494b0da6 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/WidgetId1.cs @@ -0,0 +1,33 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + [JsonConverter(typeof(WidgetIdJsonConverter))] + public struct WidgetId1 + { + public long Value { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/WidgetIdJsonConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/WidgetIdJsonConverter.cs new file mode 100644 index 00000000..e1f15309 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/WidgetIdJsonConverter.cs @@ -0,0 +1,50 @@ +#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 +{ + public class WidgetIdJsonConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(WidgetId1) || objectType == typeof(WidgetId1?); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + WidgetId1 id = (WidgetId1)value; + writer.WriteValue(id.Value.ToString()); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; + return new WidgetId1 { Value = int.Parse(reader.Value.ToString()) }; + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/WithEnums.cs b/Src/Newtonsoft.Json.Tests/TestObjects/WithEnums.cs new file mode 100644 index 00000000..47ef663e --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/TestObjects/WithEnums.cs @@ -0,0 +1,40 @@ +#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 + +namespace Newtonsoft.Json.Tests.TestObjects +{ + public class WithEnums + { + public int Id { get; set; } + public MyEnum? NullableEnum { get; set; } + } + + public enum MyEnum + { + Value1, + Value2, + Value3 + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs b/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs index 979fc38e..91b304dd 100644 --- a/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs @@ -146,6 +146,7 @@ namespace Newtonsoft.Json.Converters #else attributes = objectType.GetTypeInfo().GetCustomAttributes(true).ToArray(); #endif + bool isFSharpType = false; foreach (object attribute in attributes) { diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs index 3090bfd6..7a415d8a 100644 --- a/Src/Newtonsoft.Json/JsonConvert.cs +++ b/Src/Newtonsoft.Json/JsonConvert.cs @@ -642,7 +642,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. /// - [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => SerializeObject(value))")] + [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.SerializeObject(value))")] public static Task SerializeObjectAsync(object value) { return SerializeObjectAsync(value, Formatting.None, null); @@ -657,7 +657,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. /// - [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => SerializeObject(value, formatting))")] + [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.SerializeObject(value, formatting))")] public static Task SerializeObjectAsync(object value, Formatting formatting) { return SerializeObjectAsync(value, formatting, null); @@ -674,7 +674,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. /// - [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => SerializeObject(value, formatting, settings))")] + [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.SerializeObject(value, formatting, settings))")] public static Task SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); @@ -844,7 +844,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value))")] + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value))")] public static Task DeserializeObjectAsync(string value) { return DeserializeObjectAsync(value, null); @@ -863,7 +863,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value, settings))")] + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value, settings))")] public static Task DeserializeObjectAsync(string value, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => DeserializeObject(value, settings)); @@ -877,7 +877,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value))")] + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value))")] public static Task DeserializeObjectAsync(string value) { return DeserializeObjectAsync(value, null, null); @@ -896,7 +896,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// - [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value, type, settings))")] + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => JsonConvert.DeserializeObject(value, type, settings))")] public static Task DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => DeserializeObject(value, type, settings)); @@ -949,7 +949,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous populate operation. /// - [ObsoleteAttribute("PopulateObjectAsync is obsolete. Use the Task.Factory.StartNew method to populate an object with JSON values asynchronously: Task.Factory.StartNew(() => PopulateObject(value, target, settings))")] + [ObsoleteAttribute("PopulateObjectAsync is obsolete. Use the Task.Factory.StartNew method to populate an object with JSON values asynchronously: Task.Factory.StartNew(() => JsonConvert.PopulateObject(value, target, settings))")] public static Task PopulateObjectAsync(string value, object target, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => PopulateObject(value, target, settings)); diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs index 29b51c93..a39ed0c3 100644 --- a/Src/Newtonsoft.Json/JsonValidatingReader.cs +++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs @@ -822,7 +822,7 @@ namespace Newtonsoft.Json { const double epsilon = 2.2204460492503131e-016; - return Math.Abs(value) < 10.0 * epsilon; + return Math.Abs(value) < 20.0 * epsilon; } private void ValidatePropertyName(JsonSchemaModel schema) diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs index 9198237f..db4818bb 100644 --- a/Src/Newtonsoft.Json/Linq/JObject.cs +++ b/Src/Newtonsoft.Json/Linq/JObject.cs @@ -41,7 +41,6 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; - #endif namespace Newtonsoft.Json.Linq diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 39cb3234..8529473f 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -91,5 +91,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("6.0.0.0")] -[assembly: AssemblyFileVersion("6.0.1.17117")] +[assembly: AssemblyFileVersion("6.0.1.17131")] [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs index 0e531edd..7569e25d 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs @@ -89,7 +89,7 @@ namespace Newtonsoft.Json.Utilities if (method.IsConstructor) generator.Emit(OpCodes.Newobj, (ConstructorInfo)method); - else if (method.IsFinal || !method.IsVirtual) + else generator.CallMethod((MethodInfo)method); Type returnType = method.IsConstructor diff --git a/Src/Newtonsoft.Json/Utilities/FSharpUtils.cs b/Src/Newtonsoft.Json/Utilities/FSharpUtils.cs index 5c8e1d8e..ee6bb3ce 100644 --- a/Src/Newtonsoft.Json/Utilities/FSharpUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/FSharpUtils.cs @@ -35,6 +35,8 @@ namespace Newtonsoft.Json.Utilities { internal static class FSharpUtils { + private static readonly object Lock = new object(); + private static bool _initialized; private static MethodInfo _ofSeq; @@ -56,36 +58,42 @@ namespace Newtonsoft.Json.Utilities { if (!_initialized) { - FSharpCoreAssembly = fsharpCoreAssembly; + lock (Lock) + { + if (!_initialized) + { + FSharpCoreAssembly = fsharpCoreAssembly; - Type fsharpType = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpType"); + Type fsharpType = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpType"); - MethodInfo isUnionMethodInfo = fsharpType.GetMethod("IsUnion", BindingFlags.Public | BindingFlags.Static); - IsUnion = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(isUnionMethodInfo); + MethodInfo isUnionMethodInfo = fsharpType.GetMethod("IsUnion", BindingFlags.Public | BindingFlags.Static); + IsUnion = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(isUnionMethodInfo); - MethodInfo getUnionCasesMethodInfo = fsharpType.GetMethod("GetUnionCases", BindingFlags.Public | BindingFlags.Static); - GetUnionCases = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getUnionCasesMethodInfo); + MethodInfo getUnionCasesMethodInfo = fsharpType.GetMethod("GetUnionCases", BindingFlags.Public | BindingFlags.Static); + GetUnionCases = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getUnionCasesMethodInfo); - Type fsharpValue = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpValue"); + Type fsharpValue = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpValue"); - MethodInfo getUnionFieldsMethodInfo = fsharpValue.GetMethod("GetUnionFields", BindingFlags.Public | BindingFlags.Static); - GetUnionFields = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getUnionFieldsMethodInfo); + MethodInfo getUnionFieldsMethodInfo = fsharpValue.GetMethod("GetUnionFields", BindingFlags.Public | BindingFlags.Static); + GetUnionFields = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getUnionFieldsMethodInfo); - GetUnionCaseInfo = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(getUnionFieldsMethodInfo.ReturnType.GetProperty("Item1")); - GetUnionCaseFields = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(getUnionFieldsMethodInfo.ReturnType.GetProperty("Item2")); + GetUnionCaseInfo = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(getUnionFieldsMethodInfo.ReturnType.GetProperty("Item1")); + GetUnionCaseFields = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(getUnionFieldsMethodInfo.ReturnType.GetProperty("Item2")); - MethodInfo makeUnionMethodInfo = fsharpValue.GetMethod("MakeUnion", BindingFlags.Public | BindingFlags.Static); - MakeUnion = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(makeUnionMethodInfo); + MethodInfo makeUnionMethodInfo = fsharpValue.GetMethod("MakeUnion", BindingFlags.Public | BindingFlags.Static); + MakeUnion = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(makeUnionMethodInfo); - Type unionCaseInfo = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.UnionCaseInfo"); + Type unionCaseInfo = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.UnionCaseInfo"); - GetUnionCaseInfoName = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("Name")); - GetUnionCaseInfoFields = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(unionCaseInfo.GetMethod("GetFields")); + GetUnionCaseInfoName = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("Name")); + GetUnionCaseInfoFields = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(unionCaseInfo.GetMethod("GetFields")); - Type listModule = fsharpCoreAssembly.GetType("Microsoft.FSharp.Collections.ListModule"); - _ofSeq = listModule.GetMethod("OfSeq"); + Type listModule = fsharpCoreAssembly.GetType("Microsoft.FSharp.Collections.ListModule"); + _ofSeq = listModule.GetMethod("OfSeq"); - _initialized = true; + _initialized = true; + } + } } } diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs index c98f4cc8..a585cc7f 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs @@ -616,6 +616,9 @@ namespace Newtonsoft.Json.Utilities IList resolvedMembers = new List(); foreach (MemberInfo memberInfo in members) { + // this is a bit hacky + // if the hiding property is hiding a base property and it is virtual + // then this ensures the derived property gets used if (resolvedMembers.Count == 0) resolvedMembers.Add(memberInfo); else if (!IsOverridenGenericMember(memberInfo, bindingAttr) || memberInfo.Name == "Item")