diff options
author | Alexander Köplinger <alex.koeplinger@outlook.com> | 2015-10-31 03:10:35 +0300 |
---|---|---|
committer | Alexander Köplinger <alex.koeplinger@outlook.com> | 2015-10-31 03:10:35 +0300 |
commit | 308d25f67fa43c61339c320578c76d77e8b3d99d (patch) | |
tree | 1fcd063641b98ed1566358c6dd6e6c9f592560e5 /mcs/class/System.Runtime.Serialization | |
parent | 8c634bacbf1a0c8eb12d23ccfac98f4147cda6e7 (diff) |
[System.ServiceModel.Web] Move System.Runtime.Serialization.Json tests into System.Runtime.Serialization assembly
That's where they belong on .NET 4.5+
Additionally, add a test case from https://bugzilla.xamarin.com/show_bug.cgi?id=4230
Diffstat (limited to 'mcs/class/System.Runtime.Serialization')
5 files changed, 4463 insertions, 0 deletions
diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources index 448ad85b32e..3e9d83e63d7 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources @@ -1,3 +1,6 @@ +System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs +System.Runtime.Serialization.Json/JsonReaderTest.cs +System.Runtime.Serialization.Json/JsonWriterTest.cs System.Runtime.Serialization/Bug11916Test.cs System.Runtime.Serialization/Bug666333Test.cs System.Runtime.Serialization/Bug675144Test.cs diff --git a/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/ChangeLog b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/ChangeLog new file mode 100644 index 00000000000..532e1232d3a --- /dev/null +++ b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/ChangeLog @@ -0,0 +1,125 @@ +2010-07-06 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : add test for bug #615800. + +2010-07-06 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : add test for bug #615801. + +2010-04-05 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : don't use ToUniversalTime() + which makes test results timezone dependent. + +2010-03-10 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : oops, the test was careless. + Use fixed date. + +2010-03-09 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : add test for bug #586169. + * JsonWriterTest.cs : add standalone write case for "\/". + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : + enable TypeIsNotPartsOfKnownTypes(), and add more related tests. + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : make some tests narrow down + possible cause of errors to detect expected errors more precisely. + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : null-string case is working. + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : invalidate previous non-working + tests. + +2010-01-25 Sebastien Pouliot <sebastien@ximian.com> + + * DataContractJsonSerializerTest.cs: Add non-working test cases + for null-string, known types and handling floating point special + values + +2009-12-11 Chris Toshok <toshok@ximian.com> + + * DataContractJsonSerializerTest.cs: add a test case for + non-public properties. + +2009-12-11 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReaderTest.cs : another number parse case. + +2009-11-20 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : added ignored test case that + verifies 2.1 behavior (with another case that justifies removal + of the previous hack). + +2009-10-08 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : added test for + alwaysEmitTypeInformation argument. + +2009-09-07 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : fix non-datacontract + serialization test. It depended on IPAddress field internals + (runtime serialization incompatibility). + +2009-03-13 Andreia Gaita <avidigal@novell.com> + + * JsonReaderTest.cs: test for skip and depth (if depth fails, skip is affected) + +2009-02-02 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : fixed some tests to match + .NET RTM behavior. Added read-only collection case, (but [Ignore]d). + +2009-02-02 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : added test for contract-less + serialization. + +2008-02-18 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : added couple of DBNull tests. + +2008-01-30 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : added deserialization tests + for typed object with "__type". + +2008-01-30 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReaderTest.cs : test GetAttribute() for "__type". + +2008-01-30 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReaderTest.cs : added tests for "__type" attributes (some of + them are not working yet). + +2008-01-24 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReaderTest.cs : test "type" attribute in several nodes. + +2008-01-24 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : some more deserialization tests. + +2008-01-22 Atsushi Enomoto <atsushi@ximian.com> + + * JsonWriterTest.cs : added test for writing __type attribute. + * DataContractJsonSerializerTest.cs : added more random-ish tests. + +2007-12-05 Atsushi Enomoto <atsushi@ximian.com> + + * DataContractJsonSerializerTest.cs : + moved from Test/System.Runtime.Serialization and fixed some. + * JsonReaderTest.cs, JsonWriterTest.cs : moved from Test/System.Xml. + diff --git a/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs new file mode 100644 index 00000000000..96e7b26a05d --- /dev/null +++ b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs @@ -0,0 +1,2812 @@ +// +// DataContractJsonSerializerTest.cs +// +// Author: +// Atsushi Enomoto <atsushi@ximian.com> +// Ankit Jain <JAnkit@novell.com> +// Antoine Cailliau <antoinecailliau@gmail.com> +// +// Copyright (C) 2005-2007 Novell, Inc. http://www.novell.com + +// +// 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. +// + +// +// This test code contains tests for DataContractJsonSerializer, which is +// imported from DataContractSerializerTest.cs. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Net; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Xml; +using NUnit.Framework; + +namespace MonoTests.System.Runtime.Serialization.Json +{ + [TestFixture] + public class DataContractJsonSerializerTest + { + static readonly XmlWriterSettings settings; + + static DataContractJsonSerializerTest () + { + settings = new XmlWriterSettings (); + settings.OmitXmlDeclaration = true; + } + + [DataContract] + class Sample1 + { + [DataMember] + public string Member1; + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorTypeNull () + { + new DataContractJsonSerializer (null); + } + + [Test] + public void ConstructorKnownTypesNull () + { + // null knownTypes is allowed. + new DataContractJsonSerializer (typeof (Sample1), (IEnumerable<Type>) null); + new DataContractJsonSerializer (typeof (Sample1), "Foo", null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorNameNull () + { + new DataContractJsonSerializer (typeof (Sample1), (string) null); + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void ConstructorNegativeMaxObjects () + { + new DataContractJsonSerializer (typeof (Sample1), "Sample1", + null, -1, false, null, false); + } + + [Test] + public void ConstructorMisc () + { + new DataContractJsonSerializer (typeof (JsonGlobalSample1)).WriteObject (new MemoryStream (), new JsonGlobalSample1 ()); + } + + [Test] + public void WriteObjectContent () + { + StringWriter sw = new StringWriter (); + using (XmlWriter xw = XmlWriter.Create (sw, settings)) { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (string)); + xw.WriteStartElement ("my-element"); + ser.WriteObjectContent (xw, "TEST STRING"); + xw.WriteEndElement (); + } + Assert.AreEqual ("<my-element>TEST STRING</my-element>", + sw.ToString ()); + } + + // int + + [Test] + public void SerializeIntXml () + { + StringWriter sw = new StringWriter (); + SerializeInt (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">1</root>", + sw.ToString ()); + } + + [Test] + public void SerializeIntJson () + { + MemoryStream ms = new MemoryStream (); + SerializeInt (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "1", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeInt (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (int)); + using (XmlWriter w = writer) { + ser.WriteObject (w, 1); + } + } + + // int, with rootName + + [Test] + public void SerializeIntXmlWithRootName () + { + StringWriter sw = new StringWriter (); + SerializeIntWithRootName (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<myroot type=""number"">1</myroot>", + sw.ToString ()); + } + + [Test] + // since JsonWriter supports only "root" as the root name, using + // XmlWriter from JsonReaderWriterFactory will always fail with + // an explicit rootName. + [ExpectedException (typeof (SerializationException))] + public void SerializeIntJsonWithRootName () + { + MemoryStream ms = new MemoryStream (); + SerializeIntWithRootName (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "1", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeIntWithRootName (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (int), "myroot"); + using (XmlWriter w = writer) { + ser.WriteObject (w, 1); + } + } + + // pass typeof(DCEmpty), serialize int + + [Test] + public void SerializeIntForDCEmptyXml () + { + StringWriter sw = new StringWriter (); + SerializeIntForDCEmpty (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">1</root>", + sw.ToString ()); + } + + [Test] + public void SerializeIntForDCEmptyJson () + { + MemoryStream ms = new MemoryStream (); + SerializeIntForDCEmpty (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "1", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeIntForDCEmpty (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (DCEmpty)); + using (XmlWriter w = writer) { + ser.WriteObject (w, 1); + } + } + + // DCEmpty + + [Test] + public void SerializeEmptyClassXml () + { + StringWriter sw = new StringWriter (); + SerializeEmptyClass (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object"" />", + sw.ToString ()); + } + + [Test] + public void SerializeEmptyClassJson () + { + MemoryStream ms = new MemoryStream (); + SerializeEmptyClass (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "{}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeEmptyClass (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (DCEmpty)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new DCEmpty ()); + } + } + + // string (primitive) + + [Test] + public void SerializePrimitiveStringXml () + { + StringWriter sw = new StringWriter (); + SerializePrimitiveString (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + "<root>TEST</root>", + sw.ToString ()); + } + + [Test] + public void SerializePrimitiveStringJson () + { + MemoryStream ms = new MemoryStream (); + SerializePrimitiveString (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"""TEST""", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializePrimitiveString (XmlWriter writer) + { + XmlObjectSerializer ser = + new DataContractJsonSerializer (typeof (string)); + using (XmlWriter w = writer) { + ser.WriteObject (w, "TEST"); + } + } + + // QName (primitive but ...) + + [Test] + public void SerializePrimitiveQNameXml () + { + StringWriter sw = new StringWriter (); + SerializePrimitiveQName (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + "<root>foo:urn:foo</root>", + sw.ToString ()); + } + + [Test] + public void SerializePrimitiveQNameJson () + { + MemoryStream ms = new MemoryStream (); + SerializePrimitiveQName (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"""foo:urn:foo""", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializePrimitiveQName (XmlWriter writer) + { + XmlObjectSerializer ser = + new DataContractJsonSerializer (typeof (XmlQualifiedName)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new XmlQualifiedName ("foo", "urn:foo")); + } + } + + // DBNull (primitive) + + [Test] + public void SerializeDBNullXml () + { + StringWriter sw = new StringWriter (); + SerializeDBNull (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object"" />", + sw.ToString ()); + } + + [Test] + public void SerializeDBNullJson () + { + MemoryStream ms = new MemoryStream (); + SerializeDBNull (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "{}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeDBNull (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (DBNull)); + using (XmlWriter w = writer) { + ser.WriteObject (w, DBNull.Value); + } + } + + // DCSimple1 + + [Test] + public void SerializeSimpleClass1Xml () + { + StringWriter sw = new StringWriter (); + SerializeSimpleClass1 (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object""><Foo>TEST</Foo></root>", + sw.ToString ()); + } + + [Test] + public void SerializeSimpleClass1Json () + { + MemoryStream ms = new MemoryStream (); + SerializeSimpleClass1 (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"{""Foo"":""TEST""}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeSimpleClass1 (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (DCSimple1)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new DCSimple1 ()); + } + } + + // NonDC + + [Test] + // NonDC is not a DataContract type. + public void SerializeNonDCOnlyCtor () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (NonDC)); + } + + [Test] + //[ExpectedException (typeof (InvalidDataContractException))] + // NonDC is not a DataContract type. + // UPDATE: non-DataContract types are became valid in RTM. + public void SerializeNonDC () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (NonDC)); + using (XmlWriter w = XmlWriter.Create (TextWriter.Null, settings)) { + ser.WriteObject (w, new NonDC ()); + } + } + + // DCHasNonDC + + [Test] + //[ExpectedException (typeof (InvalidDataContractException))] + // DCHasNonDC itself is a DataContract type whose field is + // marked as DataMember but its type is not DataContract. + // UPDATE: non-DataContract types are became valid in RTM. + public void SerializeDCHasNonDC () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCHasNonDC)); + using (XmlWriter w = XmlWriter.Create (TextWriter.Null, settings)) { + ser.WriteObject (w, new DCHasNonDC ()); + } + } + + // DCHasSerializable + + [Test] + public void SerializeSimpleSerializable1Xml () + { + StringWriter sw = new StringWriter (); + SerializeSimpleSerializable1 (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object""><Ser type=""object""><Doh>doh!</Doh></Ser></root>", + sw.ToString ()); + } + + [Test] + public void SerializeSimpleSerializable1Json () + { + MemoryStream ms = new MemoryStream (); + SerializeSimpleSerializable1 (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"{""Ser"":{""Doh"":""doh!""}}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + // DCHasSerializable itself is DataContract and has a field + // whose type is not contract but serializable. + void SerializeSimpleSerializable1 (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCHasSerializable)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new DCHasSerializable ()); + } + } + + [Test] + public void SerializeDCWithNameXml () + { + StringWriter sw = new StringWriter (); + SerializeDCWithName (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object""><FooMember>value</FooMember></root>", + sw.ToString ()); + } + + [Test] + public void SerializeDCWithNameJson () + { + MemoryStream ms = new MemoryStream (); + SerializeDCWithName (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"{""FooMember"":""value""}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeDCWithName (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithName)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new DCWithName ()); + } + } + + [Test] + public void SerializeDCWithEmptyName1 () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithEmptyName)); + StringWriter sw = new StringWriter (); + DCWithEmptyName dc = new DCWithEmptyName (); + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + try { + ser.WriteObject (w, dc); + } catch (InvalidDataContractException) { + return; + } + } + Assert.Fail ("Expected InvalidDataContractException"); + } + + [Test] + public void SerializeDCWithEmptyName2 () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithName)); + StringWriter sw = new StringWriter (); + + /* DataContractAttribute.Name == "", not valid */ + DCWithEmptyName dc = new DCWithEmptyName (); + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + try { + ser.WriteObject (w, dc); + } catch (InvalidDataContractException) { + return; + } + } + Assert.Fail ("Expected InvalidDataContractException"); + } + + [Test] + [Category("NotWorking")] + public void SerializeDCWithNullName () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithNullName)); + StringWriter sw = new StringWriter (); + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + try { + /* DataContractAttribute.Name == "", not valid */ + ser.WriteObject (w, new DCWithNullName ()); + } catch (InvalidDataContractException) { + return; + } + } + Assert.Fail ("Expected InvalidDataContractException"); + } + + [Test] + public void SerializeDCWithEmptyNamespace1 () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithEmptyNamespace)); + StringWriter sw = new StringWriter (); + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + ser.WriteObject (w, new DCWithEmptyNamespace ()); + } + } + + [Test] + public void SerializeWrappedClassXml () + { + StringWriter sw = new StringWriter (); + SerializeWrappedClass (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object"" />", + sw.ToString ()); + } + + [Test] + public void SerializeWrappedClassJson () + { + MemoryStream ms = new MemoryStream (); + SerializeWrappedClass (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "{}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeWrappedClass (XmlWriter writer) + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (Wrapper.DCWrapped)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new Wrapper.DCWrapped ()); + } + } + + // CollectionContainer : Items must have a setter. (but became valid in RTM). + [Test] + public void SerializeReadOnlyCollectionMember () + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (CollectionContainer)); + StringWriter sw = new StringWriter (); + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + ser.WriteObject (w, null); + } + } + + // DataCollectionContainer : Items must have a setter. (but became valid in RTM). + [Test] + public void SerializeReadOnlyDataCollectionMember () + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (DataCollectionContainer)); + StringWriter sw = new StringWriter (); + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + ser.WriteObject (w, null); + } + } + + [Test] + [Ignore ("https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=409970")] + [ExpectedException (typeof (SerializationException))] + public void DeserializeReadOnlyDataCollection_NullCollection () + { + DataContractJsonSerializer ser = + new DataContractJsonSerializer (typeof (CollectionContainer)); + StringWriter sw = new StringWriter (); + var c = new CollectionContainer (); + c.Items.Add ("foo"); + c.Items.Add ("bar"); + using (XmlWriter w = XmlWriter.Create (sw, settings)) + ser.WriteObject (w, c); + // CollectionContainer.Items is null, so it cannot deserialize non-null collection. + using (XmlReader r = XmlReader.Create (new StringReader (sw.ToString ()))) + c = (CollectionContainer) ser.ReadObject (r); + } + + [Test] + public void SerializeGuidXml () + { + StringWriter sw = new StringWriter (); + SerializeGuid (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root>00000000-0000-0000-0000-000000000000</root>", + sw.ToString ()); + } + + [Test] + public void SerializeGuidJson () + { + MemoryStream ms = new MemoryStream (); + SerializeGuid (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"""00000000-0000-0000-0000-000000000000""", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeGuid (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (Guid)); + using (XmlWriter w = writer) { + ser.WriteObject (w, Guid.Empty); + } + } + + [Test] + public void SerializeEnumXml () + { + StringWriter sw = new StringWriter (); + SerializeEnum (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">0</root>", + sw.ToString ()); + } + + [Test] + public void SerializeEnumJson () + { + MemoryStream ms = new MemoryStream (); + SerializeEnum (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "0", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeEnum (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (Colors)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new Colors ()); + } + } + + [Test] + public void SerializeEnum2Xml () + { + StringWriter sw = new StringWriter (); + SerializeEnum2 (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">0</root>", + sw.ToString ()); + } + + [Test] + public void SerializeEnum2Json () + { + MemoryStream ms = new MemoryStream (); + SerializeEnum2 (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "0", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeEnum2 (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (Colors)); + using (XmlWriter w = writer) { + ser.WriteObject (w, 0); + } + } + + [Test] // so, DataContract does not affect here. + public void SerializeEnumWithDCXml () + { + StringWriter sw = new StringWriter (); + SerializeEnumWithDC (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">0</root>", + sw.ToString ()); + } + + [Test] + public void SerializeEnumWithDCJson () + { + MemoryStream ms = new MemoryStream (); + SerializeEnumWithDC (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "0", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeEnumWithDC (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (ColorsWithDC)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new ColorsWithDC ()); + } + } + + [Test] + public void SerializeEnumWithNoDCXml () + { + StringWriter sw = new StringWriter (); + SerializeEnumWithNoDC (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">0</root>", + sw.ToString ()); + } + + [Test] + public void SerializeEnumWithNoDCJson () + { + MemoryStream ms = new MemoryStream (); + SerializeEnumWithNoDC (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "0", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeEnumWithNoDC (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (ColorsEnumMemberNoDC)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new ColorsEnumMemberNoDC ()); + } + } + + [Test] + public void SerializeEnumWithDC2Xml () + { + StringWriter sw = new StringWriter (); + SerializeEnumWithDC2 (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""number"">3</root>", + sw.ToString ()); + } + + [Test] + public void SerializeEnumWithDC2Json () + { + MemoryStream ms = new MemoryStream (); + SerializeEnumWithDC2 (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + "3", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeEnumWithDC2 (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (ColorsWithDC)); + using (XmlWriter w = writer) { + ser.WriteObject (w, 3); + } + } + +/* + [Test] + [ExpectedException (typeof (SerializationException))] + public void SerializeEnumWithDCInvalid () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (ColorsWithDC)); + StringWriter sw = new StringWriter (); + ColorsWithDC cdc = ColorsWithDC.Blue; + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + ser.WriteObject (w, cdc); + } + } +*/ + + [Test] + public void SerializeDCWithEnumXml () + { + StringWriter sw = new StringWriter (); + SerializeDCWithEnum (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""object""><_colors type=""number"">0</_colors></root>", + sw.ToString ()); + } + + [Test] + public void SerializeDCWithEnumJson () + { + MemoryStream ms = new MemoryStream (); + SerializeDCWithEnum (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"{""_colors"":0}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializeDCWithEnum (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithEnum)); + using (XmlWriter w = writer) { + ser.WriteObject (w, new DCWithEnum ()); + } + } + + [Test] + public void SerializerDCArrayXml () + { + StringWriter sw = new StringWriter (); + SerializerDCArray (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""array""><item type=""object""><_colors type=""number"">0</_colors></item><item type=""object""><_colors type=""number"">1</_colors></item></root>", + sw.ToString ()); + } + + [Test] + public void SerializerDCArrayJson () + { + MemoryStream ms = new MemoryStream (); + SerializerDCArray (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"[{""_colors"":0},{""_colors"":1}]", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializerDCArray (XmlWriter writer) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (DCWithEnum [])); + DCWithEnum [] arr = new DCWithEnum [2]; + arr [0] = new DCWithEnum (); arr [0].colors = Colors.Red; + arr [1] = new DCWithEnum (); arr [1].colors = Colors.Green; + using (XmlWriter w = writer) { + ser.WriteObject (w, arr); + } + } + + [Test] + public void SerializerDCArray2Xml () + { + StringWriter sw = new StringWriter (); + SerializerDCArray2 (XmlWriter.Create (sw, settings)); + Assert.AreEqual ( + @"<root type=""array""><item __type=""DCWithEnum:#MonoTests.System.Runtime.Serialization.Json"" type=""object""><_colors type=""number"">0</_colors></item><item __type=""DCSimple1:#MonoTests.System.Runtime.Serialization.Json"" type=""object""><Foo>hello</Foo></item></root>", + sw.ToString ()); + } + + [Test] + public void SerializerDCArray2Json () + { + MemoryStream ms = new MemoryStream (); + SerializerDCArray2 (JsonReaderWriterFactory.CreateJsonWriter (ms)); + Assert.AreEqual ( + @"[{""__type"":""DCWithEnum:#MonoTests.System.Runtime.Serialization.Json"",""_colors"":0},{""__type"":""DCSimple1:#MonoTests.System.Runtime.Serialization.Json"",""Foo"":""hello""}]", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + void SerializerDCArray2 (XmlWriter writer) + { + List<Type> known = new List<Type> (); + known.Add (typeof (DCWithEnum)); + known.Add (typeof (DCSimple1)); + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (object []), known); + object [] arr = new object [2]; + arr [0] = new DCWithEnum (); ((DCWithEnum)arr [0]).colors = Colors.Red; + arr [1] = new DCSimple1 (); ((DCSimple1) arr [1]).Foo = "hello"; + + using (XmlWriter w = writer) { + ser.WriteObject (w, arr); + } + } + + [Test] + public void SerializerDCArray3Xml () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (int [])); + StringWriter sw = new StringWriter (); + int [] arr = new int [2]; + arr [0] = 1; arr [1] = 2; + + using (XmlWriter w = XmlWriter.Create (sw, settings)) { + ser.WriteObject (w, arr); + } + + Assert.AreEqual ( + @"<root type=""array""><item type=""number"">1</item><item type=""number"">2</item></root>", + sw.ToString ()); + } + + [Test] + public void SerializerDCArray3Json () + { + MemoryStream ms = new MemoryStream (); + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (int [])); + int [] arr = new int [2]; + arr [0] = 1; arr [1] = 2; + + using (XmlWriter w = JsonReaderWriterFactory.CreateJsonWriter (ms)) { + ser.WriteObject (w, arr); + } + + Assert.AreEqual ( + @"[1,2]", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + [Test] + // ... so, non-JSON XmlWriter is still accepted. + public void SerializeNonDCArrayXml () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (SerializeNonDCArrayType)); + StringWriter sw = new StringWriter (); + using (XmlWriter xw = XmlWriter.Create (sw, settings)) { + ser.WriteObject (xw, new SerializeNonDCArrayType ()); + } + Assert.AreEqual (@"<root type=""object""><IPAddresses type=""array"" /></root>", + sw.ToString ()); + } + + [Test] + public void SerializeNonDCArrayJson () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (SerializeNonDCArrayType)); + MemoryStream ms = new MemoryStream (); + using (XmlWriter xw = JsonReaderWriterFactory.CreateJsonWriter (ms)) { + ser.WriteObject (xw, new SerializeNonDCArrayType ()); + } + Assert.AreEqual (@"{""IPAddresses"":[]}", + Encoding.UTF8.GetString (ms.ToArray ())); + } + + [Test] + public void SerializeNonDCArrayItems () + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (SerializeNonDCArrayType)); + StringWriter sw = new StringWriter (); + using (XmlWriter xw = XmlWriter.Create (sw, settings)) { + SerializeNonDCArrayType obj = new SerializeNonDCArrayType (); + obj.IPAddresses = new NonDCItem [] {new NonDCItem () { Data = new byte [] {1, 2, 3, 4} } }; + ser.WriteObject (xw, obj); + } + + XmlDocument doc = new XmlDocument (); + doc.LoadXml (sw.ToString ()); + XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable); + nsmgr.AddNamespace ("s", "http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization"); + nsmgr.AddNamespace ("n", "http://schemas.datacontract.org/2004/07/System.Net"); + nsmgr.AddNamespace ("a", "http://schemas.microsoft.com/2003/10/Serialization/Arrays"); + + Assert.AreEqual (1, doc.SelectNodes ("/root/IPAddresses/item", nsmgr).Count, "#1"); + XmlElement el = doc.SelectSingleNode ("/root/IPAddresses/item/Data", nsmgr) as XmlElement; + Assert.IsNotNull (el, "#3"); + Assert.AreEqual (4, el.SelectNodes ("item", nsmgr).Count, "#4"); + } + + [Test] + public void MaxItemsInObjectGraph1 () + { + // object count == maximum + DataContractJsonSerializer s = new DataContractJsonSerializer (typeof (DCEmpty), null, 1, false, null, false); + s.WriteObject (XmlWriter.Create (TextWriter.Null), new DCEmpty ()); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void MaxItemsInObjectGraph2 () + { + // object count > maximum + DataContractJsonSerializer s = new DataContractJsonSerializer (typeof (DCSimple1), null, 1, false, null, false); + s.WriteObject (XmlWriter.Create (TextWriter.Null), new DCSimple1 ()); + } + + [Test] + public void DeserializeString () + { + Assert.AreEqual ("ABC", Deserialize ("\"ABC\"", typeof (string))); + } + + [Test] + public void DeserializeInt () + { + Assert.AreEqual (5, Deserialize ("5", typeof (int))); + } + + [Test] + public void DeserializeArray () + { + int [] ret = (int []) Deserialize ("[5,6,7]", typeof (int [])); + Assert.AreEqual (5, ret [0], "#1"); + Assert.AreEqual (6, ret [1], "#2"); + Assert.AreEqual (7, ret [2], "#3"); + } + + [Test] + public void DeserializeArrayUntyped () + { + object [] ret = (object []) Deserialize ("[5,6,7]", typeof (object [])); + Assert.AreEqual (5, ret [0], "#1"); + Assert.AreEqual (6, ret [1], "#2"); + Assert.AreEqual (7, ret [2], "#3"); + } + + [Test] + public void DeserializeMixedArray () + { + object [] ret = (object []) Deserialize ("[5,\"6\",false]", typeof (object [])); + Assert.AreEqual (5, ret [0], "#1"); + Assert.AreEqual ("6", ret [1], "#2"); + Assert.AreEqual (false, ret [2], "#3"); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void DeserializeEmptyAsString () + { + // it somehow expects "root" which should have been already consumed. + Deserialize ("", typeof (string)); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void DeserializeEmptyAsInt () + { + // it somehow expects "root" which should have been already consumed. + Deserialize ("", typeof (int)); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void DeserializeEmptyAsDBNull () + { + // it somehow expects "root" which should have been already consumed. + Deserialize ("", typeof (DBNull)); + } + + [Test] + public void DeserializeEmptyObjectAsString () + { + // looks like it is converted to "" + Assert.AreEqual (String.Empty, Deserialize ("{}", typeof (string))); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void DeserializeEmptyObjectAsInt () + { + Deserialize ("{}", typeof (int)); + } + + [Test] + public void DeserializeEmptyObjectAsDBNull () + { + Assert.AreEqual (DBNull.Value, Deserialize ("{}", typeof (DBNull))); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void DeserializeEnumByName () + { + // enum is parsed into long + Deserialize (@"""Red""", typeof (Colors)); + } + + [Test] + public void DeserializeEnum2 () + { + object o = Deserialize ("0", typeof (Colors)); + + Assert.AreEqual (typeof (Colors), o.GetType (), "#de3"); + Colors c = (Colors) o; + Assert.AreEqual (Colors.Red, c, "#de4"); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void DeserializeEnumInvalid () + { + Deserialize ("", typeof (Colors)); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + [Ignore ("NotDotNet")] // 0.0 is an invalid Colors value. + public void DeserializeEnumInvalid3 () + { + //"0.0" instead of "0" + Deserialize ( + "0.0", + typeof (Colors)); + } + + [Test] + public void DeserializeEnumWithDC () + { + object o = Deserialize ("0", typeof (ColorsWithDC)); + + Assert.AreEqual (typeof (ColorsWithDC), o.GetType (), "#de5"); + ColorsWithDC cdc = (ColorsWithDC) o; + Assert.AreEqual (ColorsWithDC.Red, o, "#de6"); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + [Ignore ("NotDotNet")] // 4 is an invalid Colors value. + [Category ("NotWorking")] + public void DeserializeEnumWithDCInvalid () + { + Deserialize ( + "4", + typeof (ColorsWithDC)); + } + + [Test] + public void DeserializeDCWithEnum () + { + object o = Deserialize ( + "{\"_colors\":0}", + typeof (DCWithEnum)); + + Assert.AreEqual (typeof (DCWithEnum), o.GetType (), "#de7"); + DCWithEnum dc = (DCWithEnum) o; + Assert.AreEqual (Colors.Red, dc.colors, "#de8"); + } + + [Test] + public void ReadObjectVerifyObjectNameFalse () + { + string xml = @"<any><Member1>bar</Member1></any>"; + object o = new DataContractJsonSerializer (typeof (VerifyObjectNameTestData)) + .ReadObject (XmlReader.Create (new StringReader (xml)), false); + Assert.IsTrue (o is VerifyObjectNameTestData, "#1"); + + string xml2 = @"<any><x:Member1 xmlns:x=""http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization"">bar</x:Member1></any>"; + o = new DataContractJsonSerializer (typeof (VerifyObjectNameTestData)) + .ReadObject (XmlReader.Create (new StringReader (xml2)), false); + Assert.IsTrue (o is VerifyObjectNameTestData, "#2"); + } + + [Test] + [ExpectedException (typeof (SerializationException))] + public void ReadObjectVerifyObjectNameTrue () + { + string xml = @"<any><Member1>bar</Member1></any>"; + new DataContractJsonSerializer (typeof (VerifyObjectNameTestData)) + .ReadObject (XmlReader.Create (new StringReader (xml)), true); + } + + [Test] // member name is out of scope + public void ReadObjectVerifyObjectNameTrue2 () + { + string xml = @"<root><Member2>bar</Member2></root>"; + new DataContractJsonSerializer (typeof (VerifyObjectNameTestData)) + .ReadObject (XmlReader.Create (new StringReader (xml)), true); + } + + [Test] + public void ReadTypedObjectJson () + { + object o = Deserialize (@"{""__type"":""DCWithEnum:#MonoTests.System.Runtime.Serialization.Json"",""_colors"":0}", typeof (DCWithEnum)); + Assert.AreEqual (typeof (DCWithEnum), o.GetType ()); + } + + [Test] + public void ReadObjectDCArrayJson () + { + object o = Deserialize (@"[{""__type"":""DCWithEnum:#MonoTests.System.Runtime.Serialization.Json"",""_colors"":0}]", + typeof (object []), typeof (DCWithEnum)); + Assert.AreEqual (typeof (object []), o.GetType (), "#1"); + object [] arr = (object []) o; + Assert.AreEqual (typeof (DCWithEnum), arr [0].GetType (), "#2"); + } + + [Test] + public void ReadObjectDCArray2Json () + { + object o = Deserialize (@"[{""__type"":""DCWithEnum:#MonoTests.System.Runtime.Serialization.Json"",""_colors"":0},{""__type"":""DCSimple1:#MonoTests.System.Runtime.Serialization.Json"",""Foo"":""hello""}]", + typeof (object []), typeof (DCWithEnum), typeof (DCSimple1)); + Assert.AreEqual (typeof (object []), o.GetType (), "#1"); + object [] arr = (object []) o; + Assert.AreEqual (typeof (DCWithEnum), arr [0].GetType (), "#2"); + Assert.AreEqual (typeof (DCSimple1), arr [1].GetType (), "#3"); + } + + private object Deserialize (string xml, Type type, params Type [] knownTypes) + { + DataContractJsonSerializer ser = new DataContractJsonSerializer (type, knownTypes); + XmlReader xr = JsonReaderWriterFactory.CreateJsonReader (Encoding.UTF8.GetBytes (xml), new XmlDictionaryReaderQuotas ()); + return ser.ReadObject (xr); + } + + public T Deserialize<T>(string json) + { + var bytes = Encoding.Unicode.GetBytes (json); + using (MemoryStream stream = new MemoryStream (bytes)) { + var serializer = new DataContractJsonSerializer (typeof(T)); + return (T)serializer.ReadObject (stream); + } + } + + [Test] + public void IsStartObject () + { + DataContractJsonSerializer s = new DataContractJsonSerializer (typeof (DCSimple1)); + Assert.IsTrue (s.IsStartObject (XmlReader.Create (new StringReader ("<root></root>"))), "#1"); + Assert.IsFalse (s.IsStartObject (XmlReader.Create (new StringReader ("<dummy></dummy>"))), "#2"); + Assert.IsFalse (s.IsStartObject (XmlReader.Create (new StringReader ("<Foo></Foo>"))), "#3"); + Assert.IsFalse (s.IsStartObject (XmlReader.Create (new StringReader ("<root xmlns='urn:foo'></root>"))), "#4"); + } + + [Test] + public void SerializeNonDC2 () + { + var ser = new DataContractJsonSerializer (typeof (TestData)); + StringWriter sw = new StringWriter (); + var obj = new TestData () { Foo = "foo", Bar = "bar", Baz = "baz" }; + + // XML + using (var xw = XmlWriter.Create (sw)) + ser.WriteObject (xw, obj); + var s = sw.ToString (); + // since the order is not preserved, we compare only contents. + Assert.IsTrue (s.IndexOf ("<Foo>foo</Foo>") > 0, "#1-1"); + Assert.IsTrue (s.IndexOf ("<Bar>bar</Bar>") > 0, "#1-2"); + Assert.IsFalse (s.IndexOf ("<Baz>baz</Baz>") > 0, "#1-3"); + + // JSON + MemoryStream ms = new MemoryStream (); + using (var xw = JsonReaderWriterFactory.CreateJsonWriter (ms)) + ser.WriteObject (ms, obj); + s = new StreamReader (new MemoryStream (ms.ToArray ())).ReadToEnd ().Replace ('"', '/'); + // since the order is not preserved, we compare only contents. + Assert.IsTrue (s.IndexOf ("/Foo/:/foo/") > 0, "#2-1"); + Assert.IsTrue (s.IndexOf ("/Bar/:/bar/") > 0, "#2-2"); + Assert.IsFalse (s.IndexOf ("/Baz/:/baz/") > 0, "#2-3"); + } + + [Test] + public void AlwaysEmitTypeInformation () + { + var ms = new MemoryStream (); + var ds = new DataContractJsonSerializer (typeof (string), "root", null, 10, false, null, true); + ds.WriteObject (ms, "foobar"); + var s = Encoding.UTF8.GetString (ms.ToArray ()); + Assert.AreEqual ("\"foobar\"", s, "#1"); + } + + [Test] + public void AlwaysEmitTypeInformation2 () + { + var ms = new MemoryStream (); + var ds = new DataContractJsonSerializer (typeof (TestData), "root", null, 10, false, null, true); + ds.WriteObject (ms, new TestData () { Foo = "foo"}); + var s = Encoding.UTF8.GetString (ms.ToArray ()); + Assert.AreEqual (@"{""__type"":""TestData:#MonoTests.System.Runtime.Serialization.Json"",""Bar"":null,""Foo"":""foo""}", s, "#1"); + } + + [Test] + public void AlwaysEmitTypeInformation3 () + { + var ms = new MemoryStream (); + var ds = new DataContractJsonSerializer (typeof (TestData), "root", null, 10, false, null, false); + ds.WriteObject (ms, new TestData () { Foo = "foo"}); + var s = Encoding.UTF8.GetString (ms.ToArray ()); + Assert.AreEqual (@"{""Bar"":null,""Foo"":""foo""}", s, "#1"); + } + + [Test] + public void TestNonpublicDeserialization () + { + string s1= @"{""Bar"":""bar"", ""Foo"":""foo"", ""Baz"":""baz""}"; + TestData o1 = ((TestData)(new DataContractJsonSerializer (typeof (TestData)).ReadObject (JsonReaderWriterFactory.CreateJsonReader (Encoding.UTF8.GetBytes (s1), new XmlDictionaryReaderQuotas ())))); + + Assert.AreEqual (null, o1.Baz, "#1"); + + string s2 = @"{""TestData"":[{""key"":""key1"",""value"":""value1""}]}"; + KeyValueTestData o2 = ((KeyValueTestData)(new DataContractJsonSerializer (typeof (KeyValueTestData)).ReadObject (JsonReaderWriterFactory.CreateJsonReader (Encoding.UTF8.GetBytes (s2), new XmlDictionaryReaderQuotas ())))); + + Assert.AreEqual (1, o2.TestData.Count, "#2"); + Assert.AreEqual ("key1", o2.TestData[0].Key, "#3"); + Assert.AreEqual ("value1", o2.TestData[0].Value, "#4"); + } + + // [Test] use this case if you want to check lame silverlight parser behavior. Seealso #549756 + public void QuotelessDeserialization () + { + string s1 = @"{FooMember:""value""}"; + var ds = new DataContractJsonSerializer (typeof (DCWithName)); + ds.ReadObject (new MemoryStream (Encoding.UTF8.GetBytes (s1))); + + string s2 = @"{FooMember:"" \""{dummy:string}\""""}"; + ds.ReadObject (new MemoryStream (Encoding.UTF8.GetBytes (s2))); + } + + [Test] + [Category ("NotWorking")] + public void TypeIsNotPartsOfKnownTypes () + { + var dcs = new DataContractSerializer (typeof (string)); + Assert.AreEqual (0, dcs.KnownTypes.Count, "KnownTypes #1"); + var dcjs = new DataContractJsonSerializer (typeof (string)); + Assert.AreEqual (0, dcjs.KnownTypes.Count, "KnownTypes #2"); + } + + [Test] + public void ReadWriteNullObject () + { + DataContractJsonSerializer dcjs = new DataContractJsonSerializer (typeof (string)); + using (MemoryStream ms = new MemoryStream ()) { + dcjs.WriteObject (ms, null); + ms.Position = 0; + using (StreamReader sr = new StreamReader (ms)) { + string data = sr.ReadToEnd (); + Assert.AreEqual ("null", data, "WriteObject(stream,null)"); + + ms.Position = 0; + Assert.IsNull (dcjs.ReadObject (ms), "ReadObject(stream)"); + } + }; + } + + object ReadWriteObject (Type type, object obj, string expected) + { + using (MemoryStream ms = new MemoryStream ()) { + DataContractJsonSerializer dcjs = new DataContractJsonSerializer (type); + dcjs.WriteObject (ms, obj); + ms.Position = 0; + using (StreamReader sr = new StreamReader (ms)) { + Assert.AreEqual (expected, sr.ReadToEnd (), "WriteObject"); + + ms.Position = 0; + return dcjs.ReadObject (ms); + } + } + } + + [Test] + [Ignore ("Wrong test case. See bug #573691")] + public void ReadWriteObject_Single_SpecialCases () + { + Assert.IsTrue (Single.IsNaN ((float) ReadWriteObject (typeof (float), Single.NaN, "NaN"))); + Assert.IsTrue (Single.IsNegativeInfinity ((float) ReadWriteObject (typeof (float), Single.NegativeInfinity, "-INF"))); + Assert.IsTrue (Single.IsPositiveInfinity ((float) ReadWriteObject (typeof (float), Single.PositiveInfinity, "INF"))); + } + + [Test] + [Ignore ("Wrong test case. See bug #573691")] + public void ReadWriteObject_Double_SpecialCases () + { + Assert.IsTrue (Double.IsNaN ((double) ReadWriteObject (typeof (double), Double.NaN, "NaN"))); + Assert.IsTrue (Double.IsNegativeInfinity ((double) ReadWriteObject (typeof (double), Double.NegativeInfinity, "-INF"))); + Assert.IsTrue (Double.IsPositiveInfinity ((double) ReadWriteObject (typeof (double), Double.PositiveInfinity, "INF"))); + } + + [Test] + public void ReadWriteDateTime () + { + var ms = new MemoryStream (); + DataContractJsonSerializer serializer = new DataContractJsonSerializer (typeof (Query)); + Query query = new Query () { + StartDate = DateTime.SpecifyKind (new DateTime (2010, 3, 4, 5, 6, 7), DateTimeKind.Utc), + EndDate = DateTime.SpecifyKind (new DateTime (2010, 4, 5, 6, 7, 8), DateTimeKind.Utc) + }; + serializer.WriteObject (ms, query); + Assert.AreEqual ("{\"StartDate\":\"\\/Date(1267679167000)\\/\",\"EndDate\":\"\\/Date(1270447628000)\\/\"}", Encoding.UTF8.GetString (ms.ToArray ()), "#1"); + ms.Position = 0; + Console.WriteLine (new StreamReader (ms).ReadToEnd ()); + ms.Position = 0; + var q = (Query) serializer.ReadObject(ms); + Assert.AreEqual (query.StartDate, q.StartDate, "#2"); + Assert.AreEqual (query.EndDate, q.EndDate, "#3"); + } + + [DataContract(Name = "DateTest")] + public class DateTest + { + [DataMember(Name = "should_have_value")] + public DateTime? ShouldHaveValue { get; set; } + } + + // + // This tests both the extended format "number-0500" as well + // as the nullable field in the structure + [Test] + public void BugXamarin163 () + { + string json = @"{""should_have_value"":""\/Date(1277355600000)\/""}"; + + byte[] bytes = global::System.Text.Encoding.UTF8.GetBytes(json); + Stream inputStream = new MemoryStream(bytes); + + DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DateTest)); + DateTest t = serializer.ReadObject(inputStream) as DateTest; + Assert.AreEqual (634129524000000000, t.ShouldHaveValue.Value.Ticks, "#1"); + } + + [Test] + public void NullableFieldsShouldSupportNullValue () + { + string json = @"{""should_have_value"":null}"; + var inputStream = new MemoryStream (Encoding.UTF8.GetBytes (json)); + DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DateTest)); + Console.WriteLine ("# serializer assembly: {0}", serializer.GetType ().Assembly.Location); + DateTest t = serializer.ReadObject (inputStream) as DateTest; + Assert.AreEqual (false, t.ShouldHaveValue.HasValue, "#2"); + } + + [Test] + public void DeserializeNullMember () + { + var ds = new DataContractJsonSerializer (typeof (ClassA)); + var stream = new MemoryStream (); + var a = new ClassA (); + ds.WriteObject (stream, a); + stream.Position = 0; + a = (ClassA) ds.ReadObject (stream); + Assert.IsNull (a.B, "#1"); + } + + [Test] + public void OnDeserializationMethods () + { + var ds = new DataContractJsonSerializer (typeof (GSPlayerListErg)); + var obj = new GSPlayerListErg (); + var ms = new MemoryStream (); + ds.WriteObject (ms, obj); + ms.Position = 0; + ds.ReadObject (ms); + Assert.IsTrue (GSPlayerListErg.A, "A"); + Assert.IsTrue (GSPlayerListErg.B, "B"); + Assert.IsTrue (GSPlayerListErg.C, "C"); + } + + [Test] + public void WriteChar () + { + DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (CharTest)); + using (MemoryStream ms = new MemoryStream()) { + serializer.WriteObject(ms, new CharTest ()); + ms.Position = 0L; + using (StreamReader reader = new StreamReader(ms)) { + reader.ReadToEnd(); + } + } + } + + [Test] + public void DictionarySerialization () + { + var dict = new JsonMyDictionary<string,string> (); + dict.Add ("key", "value"); + var serializer = new DataContractJsonSerializer (dict.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, dict); + stream.Position = 0; + + Assert.AreEqual ("[{\"Key\":\"key\",\"Value\":\"value\"}]", new StreamReader (stream).ReadToEnd (), "#1"); + stream.Position = 0; + dict = (JsonMyDictionary<string,string>) serializer.ReadObject (stream); + Assert.AreEqual (1, dict.Count, "#2"); + Assert.AreEqual ("value", dict ["key"], "#3"); + } + + [Test] + public void ExplicitCustomDictionarySerialization () + { + var dict = new MyExplicitDictionary<string,string> (); + dict.Add ("key", "value"); + var serializer = new DataContractJsonSerializer (dict.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, dict); + stream.Position = 0; + + Assert.AreEqual ("[{\"Key\":\"key\",\"Value\":\"value\"}]", new StreamReader (stream).ReadToEnd (), "#1"); + stream.Position = 0; + dict = (MyExplicitDictionary<string,string>) serializer.ReadObject (stream); + Assert.AreEqual (1, dict.Count, "#2"); + Assert.AreEqual ("value", dict ["key"], "#3"); + } + + [Test] + public void Bug13485 () + { + const string json = "{ \"Name\" : \"Test\", \"Value\" : \"ValueA\" }"; + + string result = string.Empty; + var serializer = new DataContractJsonSerializer (typeof (Bug13485Type)); + Bug13485Type entity; + using (var stream = new MemoryStream (Encoding.UTF8.GetBytes (json))) + entity = (Bug13485Type) serializer.ReadObject (stream); + + result = entity.GetValue; + Assert.AreEqual ("ValueA", result, "#1"); + } + + [DataContract(Name = "UriTest")] + public class UriTest + { + [DataMember(Name = "members")] + public Uri MembersRelativeLink { get; set; } + } + + [Test] + public void Bug15169 () + { + const string json = "{\"members\":\"foo/bar/members\"}"; + var serializer = new DataContractJsonSerializer (typeof (UriTest)); + UriTest entity; + using (var stream = new MemoryStream (Encoding.UTF8.GetBytes (json))) + entity = (UriTest) serializer.ReadObject (stream); + + Assert.AreEqual ("foo/bar/members", entity.MembersRelativeLink.ToString ()); + } + + #region Test methods for collection serialization + + [Test] + public void TestArrayListSerialization () + { + var collection = new ArrayListContainer (); + var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}"; + var expectedItemsCount = 4; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + + stream.Position = 0; + collection = (ArrayListContainer) serializer.ReadObject (stream); + + Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2"); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestBitArraySerialization () + { + var collection = new BitArrayContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + public void TestHashtableSerialization () + { + var collection = new HashtableContainer (); + var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}"; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void TestHashtableDeserialization () + { + var collection = new HashtableContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + serializer.ReadObject (stream); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestQueueSerialization () + { + var collection = new QueueContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + public void TestSortedListSerialization () + { + var collection = new SortedListContainer (); + var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}"; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void TestSortedListDeserialization () + { + var collection = new SortedListContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + serializer.ReadObject (stream); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestStackSerialization () + { + var collection = new StackContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + public void TestEnumerableWithAddSerialization () + { + var collection = new EnumerableWithAddContainer (); + var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}"; + var expectedItemsCount = 4; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + + stream.Position = 0; + collection = (EnumerableWithAddContainer) serializer.ReadObject (stream); + + Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2"); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestEnumerableWithSpecialAddSerialization () + { + var collection = new EnumerableWithSpecialAddContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + public void TestHashSetSerialization () + { + var collection = new GenericHashSetContainer (); + var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}"; + var expectedItemsCount = 2; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + + stream.Position = 0; + collection = (GenericHashSetContainer) serializer.ReadObject (stream); + + Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2"); + } + + [Test] + public void TestLinkedListSerialization () + { + var collection = new GenericLinkedListContainer (); + var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}"; + var expectedItemsCount = 4; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + + stream.Position = 0; + collection = (GenericLinkedListContainer) serializer.ReadObject (stream); + + Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2"); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestGenericQueueSerialization () + { + var collection = new GenericQueueContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestGenericStackSerialization () + { + var collection = new GenericStackContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + public void TestGenericDictionarySerialization () + { + var collection = new GenericDictionaryContainer (); + var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}"; + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void TestGenericDictionaryDeserialization () + { + var collection = new GenericDictionaryContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + serializer.ReadObject (stream); + } + + [Test] + public void TestGenericSortedListSerialization () + { + var collection = new GenericSortedListContainer (); + var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}"; + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void TestGenericSortedListDeserialization () + { + var collection = new GenericSortedListContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + serializer.ReadObject (stream); + } + + [Test] + public void TestGenericSortedDictionarySerialization () + { + var collection = new GenericSortedDictionaryContainer (); + var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}"; + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void TestGenericSortedDictionaryDeserialization () + { + var collection = new GenericSortedDictionaryContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + serializer.ReadObject (stream); + } + + [Test] + public void TestGenericEnumerableWithAddSerialization () + { + var collection = new GenericEnumerableWithAddContainer (); + var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}"; + var expectedItemsCount = 4; + + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + + stream.Position = 0; + Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1"); + + stream.Position = 0; + collection = (GenericEnumerableWithAddContainer) serializer.ReadObject (stream); + + Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2"); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestGenericEnumerableWithSpecialAddSerialization () + { + var collection = new GenericEnumerableWithSpecialAddContainer (); + var serializer = new DataContractJsonSerializer (collection.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, collection); + } + + [Test] + [ExpectedException (typeof (InvalidDataContractException))] + public void TestNonCollectionGetOnlyProperty () + { + var o = new NonCollectionGetOnlyContainer (); + var serializer = new DataContractJsonSerializer (o.GetType ()); + var stream = new MemoryStream (); + serializer.WriteObject (stream, o); + } + + // properly deserialize object with a polymorphic property (known derived type) + [Test] + public void Bug23058() + { + string serializedObj = @"{""PolymorphicProperty"":{""__type"":""KnownDerivedType:#MonoTests.System.Runtime.Serialization.Json"",""BaseTypeProperty"":""Base"",""DerivedProperty"":""Derived 1""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize<ParentType> (serializedObj); + + Assert.AreEqual (deserializedObj.PolymorphicProperty.GetType ().FullName, "MonoTests.System.Runtime.Serialization.Json.KnownDerivedType"); + Assert.AreEqual (deserializedObj.PolymorphicProperty.BaseTypeProperty, "Base"); + Assert.AreEqual ((deserializedObj.PolymorphicProperty as KnownDerivedType).DerivedProperty, "Derived 1"); + Assert.AreEqual (deserializedObj.Name, "Parent2"); + } + + // properly deserialize object with a polymorphic property (base type with __type hint) + [Test] + public void DeserializeBaseTypePropHint() + { + string serializedObj = @"{""PolymorphicProperty"":{""__type"":""BaseType:#MonoTests.System.Runtime.Serialization.Json"",""BaseTypeProperty"":""Base""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize<ParentType> (serializedObj); + + Assert.AreEqual (deserializedObj.PolymorphicProperty.GetType ().FullName, "MonoTests.System.Runtime.Serialization.Json.BaseType"); + Assert.AreEqual (deserializedObj.PolymorphicProperty.BaseTypeProperty, "Base"); + } + + // properly deserialize object with a polymorphic property (base type with __type hint) + [Test] + public void DeserializeBaseTypePropNoHint() + { + string serializedObj = @"{""PolymorphicProperty"":{""BaseTypeProperty"":""Base""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize<ParentType> (serializedObj); + + Assert.AreEqual (deserializedObj.PolymorphicProperty.GetType ().FullName, "MonoTests.System.Runtime.Serialization.Json.BaseType"); + Assert.AreEqual (deserializedObj.PolymorphicProperty.BaseTypeProperty, "Base"); + } + + // properly fail deserializing object with a polymorphic property (unknown derived type) + [ExpectedException (typeof (SerializationException))] + [Test] + public void FailDeserializingUnknownTypeProp() + { + string serializedObj = @"{""PolymorphicProperty"":{""__type"":""UnknownDerivedType:#MonoTests.System.Runtime.Serialization.Json"",""BaseTypeProperty"":""Base"",""DerivedProperty"":""Derived 1""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize<ParentType> (serializedObj); + } + + [Test] + public void SubclassTest () + { + var knownTypes = new List<Type> { typeof(IntList) }; + var serializer = new DataContractJsonSerializer(typeof(ListOfNumbers), knownTypes); + + string json = "{\"Numbers\": [85]}"; + using (var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(json))) + { + var nums = (ListOfNumbers)serializer.ReadObject(stream); + Assert.AreEqual (1, nums.Numbers.Count); + } + } + [DataContract] + public class ListOfNumbers + { + [DataMember] + public IntList Numbers; + } + + public class IntList : List<int>{} + #endregion + + [Test] + public void DefaultValueDeserialization () + { + // value type + var person = new JsonPerson { name = "John" }; + using (var ms = new MemoryStream()) { + var serializer = new DataContractJsonSerializer (typeof (JsonPerson), new DataContractJsonSerializerSettings { + SerializeReadOnlyTypes = true, + UseSimpleDictionaryFormat = true + }); + serializer.WriteObject (ms, person); + } + + // reference type + var person2 = new PersonWithContact { + name = "Jane", + contact = new Contact { url = "localhost", email = "jane@localhost" } }; + using (var ms = new MemoryStream ()) { + var serializer = new DataContractJsonSerializer (typeof (PersonWithContact), new DataContractJsonSerializerSettings { + SerializeReadOnlyTypes = true, + UseSimpleDictionaryFormat = true + }); + serializer.WriteObject (ms, person2); + } + } + + [Test] + public void Bug15028() + { + DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Bug15028)); + using (MemoryStream memoryStream = new MemoryStream()) + { + ser.WriteObject(memoryStream, new Bug15028()); + string output = Encoding.Default.GetString(memoryStream.ToArray()); + Assert.AreEqual(@"{""Int0"":1,""Int1"":1,""IntZero1"":0,""Str0"":"""",""Str1"":"""",""StrNull1"":null}", output); + } + } + + [Test] + public void Bug4230() + { + string serializedObj = @"{ ""Notifications"": null }"; + Bug4230Response deserializedObj = Deserialize<Bug4230Response> (serializedObj); + + Assert.IsNull (deserializedObj.Notifications); + } + } + + public class Bug4230Notification { + } + + public class Bug4230Response + { + public Bug4230Notification[] Notifications + { + get; + set; + } + } + + [DataContract] + public class Bug15028 + { + [DataMember(EmitDefaultValue = false)] + public string StrNull0 { get; private set; } + + [DataMember(EmitDefaultValue = false)] + public string Str0 { get; private set; } + + [DataMember(EmitDefaultValue = true)] + public string StrNull1 { get; private set; } + + [DataMember(EmitDefaultValue = true)] + public string Str1 { get; private set; } + + [DataMember(EmitDefaultValue = false)] + public int IntZero0 { get; private set; } + + [DataMember(EmitDefaultValue = false)] + public int Int0 { get; private set; } + + [DataMember(EmitDefaultValue = true)] + public int IntZero1 { get; private set; } + + [DataMember(EmitDefaultValue = true)] + public int Int1 { get; private set; } + + public Bug15028() + { + Str0 = string.Empty; + Str1 = string.Empty; + Int0 = 1; + Int1 = 1; + } + } + + public class CharTest + { + public char Foo; + } + + public class TestData + { + public string Foo { get; set; } + public string Bar { get; set; } + internal string Baz { get; set; } + } + + public enum Colors { + Red, Green, Blue + } + + [DataContract (Name = "_ColorsWithDC")] + public enum ColorsWithDC { + + [EnumMember (Value = "_Red")] + Red, + [EnumMember] + Green, + Blue + } + + + public enum ColorsEnumMemberNoDC { + [EnumMember (Value = "_Red")] + Red, + [EnumMember] + Green, + Blue + } + + [DataContract] + public class DCWithEnum { + [DataMember (Name = "_colors")] + public Colors colors; + } + + [DataContract] + public class DCEmpty + { + // serializer doesn't touch it. + public string Foo = "TEST"; + } + + [DataContract] + public class DCSimple1 + { + [DataMember] + public string Foo = "TEST"; + } + + [DataContract] + public class DCHasNonDC + { + [DataMember] + public NonDC Hoge= new NonDC (); + } + + public class NonDC + { + public string Whee = "whee!"; + } + + [DataContract] + public class DCHasSerializable + { + [DataMember] + public SimpleSer1 Ser = new SimpleSer1 (); + } + + [DataContract (Name = "Foo")] + public class DCWithName + { + [DataMember (Name = "FooMember")] + public string DMWithName = "value"; + } + + [DataContract (Name = "")] + public class DCWithEmptyName + { + [DataMember] + public string Foo; + } + + [DataContract (Name = null)] + public class DCWithNullName + { + [DataMember] + public string Foo; + } + + [DataContract (Namespace = "")] + public class DCWithEmptyNamespace + { + [DataMember] + public string Foo; + } + + [Serializable] + public class SimpleSer1 + { + public string Doh = "doh!"; + } + + public class Wrapper + { + [DataContract] + public class DCWrapped + { + } + } + + [DataContract] + public class CollectionContainer + { + Collection<string> items = new Collection<string> (); + + [DataMember] + public Collection<string> Items { + get { return items; } + } + } + + [CollectionDataContract] + public class DataCollection<T> : Collection<T> + { + } + + [DataContract] + public class DataCollectionContainer + { + DataCollection<string> items = new DataCollection<string> (); + + [DataMember] + public DataCollection<string> Items { + get { return items; } + } + } + + [DataContract] + class SerializeNonDCArrayType + { + [DataMember] + public NonDCItem [] IPAddresses = new NonDCItem [0]; + } + + public class NonDCItem + { + public byte [] Data { get; set; } + } + + [DataContract] + public class VerifyObjectNameTestData + { + [DataMember] + string Member1 = "foo"; + } + + [Serializable] + public class KeyValueTestData { + public List<KeyValuePair<string,string>> TestData = new List<KeyValuePair<string,string>>(); + } + + [DataContract] // bug #586169 + public class Query + { + [DataMember (Order=1)] + public DateTime StartDate { get; set; } + [DataMember (Order=2)] + public DateTime EndDate { get; set; } + } + + public class ClassA { + public ClassB B { get; set; } + } + + public class ClassB + { + } + + public class GSPlayerListErg + { + public GSPlayerListErg () + { + Init (); + } + + void Init () + { + C = true; + ServerTimeUTC = DateTime.SpecifyKind (DateTime.MinValue, DateTimeKind.Utc); + } + + [OnDeserializing] + public void OnDeserializing (StreamingContext c) + { + A = true; + Init (); + } + + [OnDeserialized] + void OnDeserialized (StreamingContext c) + { + B = true; + } + + public static bool A, B, C; + + [DataMember (Name = "T")] + public long CodedServerTimeUTC { get; set; } + public DateTime ServerTimeUTC { get; set; } + } + + #region polymorphism test helper classes + + [DataContract] + [KnownType (typeof (KnownDerivedType))] + public class ParentType + { + [DataMember] + public string Name { get; set; } + + [DataMember] + public BaseType PolymorphicProperty { get; set; } + } + + [DataContract] + public class BaseType + { + [DataMember] + public string BaseTypeProperty { get; set; } + } + + [DataContract] + public class KnownDerivedType : BaseType + { + [DataMemberAttribute] + public string DerivedProperty { get; set; } + } + + [DataContract] + public class UnknownDerivedType : BaseType + { + [DataMember] + public string DerivedProperty { get; set; } + } + + #endregion +} + +[DataContract] +class JsonGlobalSample1 +{ +} + + +public class JsonMyDictionary<K, V> : System.Collections.Generic.IDictionary<K, V> +{ + Dictionary<K,V> dic = new Dictionary<K,V> (); + + public void Add (K key, V value) + { + dic.Add (key, value); + } + + public bool ContainsKey (K key) + { + return dic.ContainsKey (key); + } + + public ICollection<K> Keys { + get { return dic.Keys; } + } + + public bool Remove (K key) + { + return dic.Remove (key); + } + + public bool TryGetValue (K key, out V value) + { + return dic.TryGetValue (key, out value); + } + + public ICollection<V> Values { + get { return dic.Values; } + } + + public V this [K key] { + get { return dic [key]; } + set { dic [key] = value; } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return dic.GetEnumerator (); + } + + ICollection<KeyValuePair<K,V>> Coll { + get { return (ICollection<KeyValuePair<K,V>>) dic; } + } + + public void Add (KeyValuePair<K, V> item) + { + Coll.Add (item); + } + + public void Clear () + { + dic.Clear (); + } + + public bool Contains (KeyValuePair<K, V> item) + { + return Coll.Contains (item); + } + + public void CopyTo (KeyValuePair<K, V> [] array, int arrayIndex) + { + Coll.CopyTo (array, arrayIndex); + } + + public int Count { + get { return dic.Count; } + } + + public bool IsReadOnly { + get { return Coll.IsReadOnly; } + } + + public bool Remove (KeyValuePair<K, V> item) + { + return Coll.Remove (item); + } + + public IEnumerator<KeyValuePair<K, V>> GetEnumerator () + { + return Coll.GetEnumerator (); + } +} + +public class MyExplicitDictionary<K, V> : IDictionary<K, V> { + + Dictionary<K,V> dic = new Dictionary<K,V> (); + + public void Add (K key, V value) + { + dic.Add (key, value); + } + + public bool ContainsKey (K key) + { + return dic.ContainsKey (key); + } + + ICollection<K> IDictionary<K, V>.Keys { + get { return dic.Keys; } + } + + public bool Remove (K key) + { + return dic.Remove (key); + } + + public bool TryGetValue (K key, out V value) + { + return dic.TryGetValue (key, out value); + } + + ICollection<V> IDictionary<K, V>.Values { + get { return dic.Values; } + } + + public V this [K key] { + get { return dic [key]; } + set { dic [key] = value; } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return dic.GetEnumerator (); + } + + ICollection<KeyValuePair<K,V>> Coll { + get { return (ICollection<KeyValuePair<K,V>>) dic; } + } + + public void Add (KeyValuePair<K, V> item) + { + Coll.Add (item); + } + + public void Clear () + { + dic.Clear (); + } + + public bool Contains (KeyValuePair<K, V> item) + { + return Coll.Contains (item); + } + + public void CopyTo (KeyValuePair<K, V> [] array, int arrayIndex) + { + Coll.CopyTo (array, arrayIndex); + } + + public int Count { + get { return dic.Count; } + } + + public bool IsReadOnly { + get { return Coll.IsReadOnly; } + } + + public bool Remove (KeyValuePair<K, V> item) + { + return Coll.Remove (item); + } + + public IEnumerator<KeyValuePair<K, V>> GetEnumerator () + { + return Coll.GetEnumerator (); + } +} + +[DataContract] +public class Bug13485Type +{ + [DataMember] + public string Name { get; set; } + + [DataMember (Name = "Value")] + private string Value { get; set; } + + public string GetValue { get { return this.Value; } } +} + +#region Test classes for Collection serialization + +[DataContract] + public abstract class CollectionContainer <V> + { + V items; + + [DataMember] + public V Items + { + get { + if (items == null) items = Init (); + return items; + } + } + + public CollectionContainer () + { + Init (); + } + + protected abstract V Init (); + } + + [DataContract] + public class ArrayListContainer : CollectionContainer<ArrayList> { + protected override ArrayList Init () + { + return new ArrayList { "banana", "apple" }; + } + } + + [DataContract] + public class BitArrayContainer : CollectionContainer<BitArray> { + protected override BitArray Init () + { + return new BitArray (new [] { false, true }); + } + } + + [DataContract] + public class HashtableContainer : CollectionContainer<Hashtable> { + protected override Hashtable Init () + { + var ht = new Hashtable (); + ht.Add ("key1", "banana"); + ht.Add ("key2", "apple"); + return ht; + } + } + + [DataContract] + public class QueueContainer : CollectionContainer<Queue> { + protected override Queue Init () + { + var q = new Queue (); + q.Enqueue ("banana"); + q.Enqueue ("apple"); + return q; + } + } + + [DataContract] + public class SortedListContainer : CollectionContainer<SortedList> { + protected override SortedList Init () + { + var l = new SortedList (); + l.Add ("key1", "banana"); + l.Add ("key2", "apple"); + return l; + } + } + + [DataContract] + public class StackContainer : CollectionContainer<Stack> { + protected override Stack Init () + { + var s = new Stack (); + s.Push ("banana"); + s.Push ("apple"); + return s; + } + } + + public class EnumerableWithAdd : IEnumerable + { + private ArrayList items; + + public EnumerableWithAdd() + { + items = new ArrayList(); + } + + public IEnumerator GetEnumerator() + { + return items.GetEnumerator(); + } + + public void Add(object value) + { + items.Add(value); + } + + public int Count + { + get { + return items.Count; + } + } + } + + public class EnumerableWithSpecialAdd : IEnumerable + { + private ArrayList items; + + public EnumerableWithSpecialAdd() + { + items = new ArrayList(); + } + + public IEnumerator GetEnumerator() + { + return items.GetEnumerator(); + } + + public void Add(object value, int index) + { + items.Add(value); + } + + public int Count + { + get + { + return items.Count; + } + } + } + + [DataContract] + public class EnumerableWithAddContainer : CollectionContainer<EnumerableWithAdd> + { + protected override EnumerableWithAdd Init() + { + var s = new EnumerableWithAdd(); + s.Add ("banana"); + s.Add ("apple"); + return s; + } + } + + [DataContract] + public class EnumerableWithSpecialAddContainer : CollectionContainer<EnumerableWithSpecialAdd> + { + protected override EnumerableWithSpecialAdd Init() + { + var s = new EnumerableWithSpecialAdd(); + s.Add("banana", 0); + s.Add("apple", 0); + return s; + } + } + + [DataContract] + public class GenericDictionaryContainer : CollectionContainer<Dictionary<string, string>> { + protected override Dictionary<string, string> Init () + { + var d = new Dictionary<string, string> (); + d.Add ("key1", "banana"); + d.Add ("key2", "apple"); + return d; + } + } + + [DataContract] + public class GenericHashSetContainer : CollectionContainer<HashSet<string>> { + protected override HashSet<string> Init () + { + return new HashSet<string> { "banana", "apple" }; + } + } + + [DataContract] + public class GenericLinkedListContainer : CollectionContainer<LinkedList<string>> { + protected override LinkedList<string> Init () + { + var l = new LinkedList<string> (); + l.AddFirst ("apple"); + l.AddFirst ("banana"); + return l; + } + } + + [DataContract] + public class GenericListContainer : CollectionContainer<List<string>> { + protected override List<string> Init () + { + return new List<string> { "banana", "apple" }; + } + } + + [DataContract] + public class GenericQueueContainer : CollectionContainer<Queue<string>> { + protected override Queue<string> Init () + { + var q = new Queue<string> (); + q.Enqueue ("banana"); + q.Enqueue ("apple" ); + return q; + } + } + + [DataContract] + public class GenericSortedDictionaryContainer : CollectionContainer<SortedDictionary<string, string>> { + protected override SortedDictionary<string, string> Init () + { + var d = new SortedDictionary<string, string> (); + d.Add ("key1", "banana"); + d.Add ("key2", "apple"); + return d; + } + } + + [DataContract] + public class GenericSortedListContainer : CollectionContainer<SortedList<string, string>> { + protected override SortedList<string, string> Init () + { + var d = new SortedList<string, string> (); + d.Add ("key1", "banana"); + d.Add ("key2", "apple"); + return d; + } + } + + [DataContract] + public class GenericStackContainer : CollectionContainer<Stack<string>> { + protected override Stack<string> Init () + { + var s = new Stack<string> (); + s.Push ("banana"); + s.Push ("apple" ); + return s; + } + } + + public class GenericEnumerableWithAdd : IEnumerable<string> + { + private List<string> items; + + public GenericEnumerableWithAdd() + { + items = new List<string>(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return items.GetEnumerator (); + } + + public IEnumerator<string> GetEnumerator() + { + return items.GetEnumerator (); + } + + public void Add(string value) + { + items.Add(value); + } + + public int Count + { + get { + return items.Count; + } + } + } + + public class GenericEnumerableWithSpecialAdd : IEnumerable<string> + { + private List<string> items; + + public GenericEnumerableWithSpecialAdd() + { + items = new List<string>(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return items.GetEnumerator (); + } + + public IEnumerator<string> GetEnumerator() + { + return items.GetEnumerator (); + } + + public void Add(string value, int index) + { + items.Add(value); + } + + public int Count + { + get + { + return items.Count; + } + } + } + + [DataContract] + public class GenericEnumerableWithAddContainer : CollectionContainer<GenericEnumerableWithAdd> + { + protected override GenericEnumerableWithAdd Init() + { + var s = new GenericEnumerableWithAdd(); + s.Add ("banana"); + s.Add ("apple"); + return s; + } + } + + [DataContract] + public class GenericEnumerableWithSpecialAddContainer : CollectionContainer<GenericEnumerableWithSpecialAdd> + { + protected override GenericEnumerableWithSpecialAdd Init() + { + var s = new GenericEnumerableWithSpecialAdd(); + s.Add("banana", 0); + s.Add("apple", 0); + return s; + } + } + + [DataContract] + public class NonCollectionGetOnlyContainer + { + string _test = "my string"; + + [DataMember] + public string MyString { + get { + return _test; + } + } + } + +#endregion + +#region DefaultValueDeserialization + [DataContract] + public class JsonPerson + { + [DataMember(EmitDefaultValue = false)] + public string name { get; set; } + } + + [DataContract] + public class PersonWithContact + { + [DataMember(EmitDefaultValue = false)] + public string name { get; set; } + + [DataMember(EmitDefaultValue = false)] + public Contact contact { get; set; } + } + + [DataContract] + public class Contact + { + [DataMember(EmitDefaultValue = false)] + public string url { get; set; } + + [DataMember(EmitDefaultValue = false)] + public string email{ get; set; } + } +#endregion diff --git a/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs new file mode 100644 index 00000000000..c95c3b62352 --- /dev/null +++ b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs @@ -0,0 +1,883 @@ +// +// JsonReaderTest.cs +// +// Author: +// Atsushi Enomoto <atsushi@ximian.com> +// +// Copyright (C) 2007 Novell, Inc (http://www.novell.com) +// Copyright 2014 Xamarin Inc. (http://www.xamarin.com) +// +// 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. +// +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading; +using System.Xml; +using NUnit.Framework; + +namespace MonoTests.System.Runtime.Serialization.Json +{ + [TestFixture] + public class JsonReaderTest + { + XmlDictionaryReader reader; + + Stream GetInput (string s) + { + return new MemoryStream (Encoding.ASCII.GetBytes (s)); + } + + XmlDictionaryReader CreateReader (string s) + { + return JsonReaderWriterFactory.CreateJsonReader (GetInput (s), new XmlDictionaryReaderQuotas ()); + } + + void AssertNode (int depth, string localName, XmlNodeType nodeType, string value, string type, XmlDictionaryReader reader, string label) + { + Assert.AreEqual (localName, reader.LocalName, label + ".LocalName"); + Assert.AreEqual (nodeType, reader.NodeType, label + ".NodeType"); + Assert.AreEqual (value, reader.Value, label + ".Value"); + Assert.AreEqual (type, reader.GetAttribute ("type"), label + ".GetAttribute('type')"); + } + + // Constructors + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorNullBytes () + { + JsonReaderWriterFactory.CreateJsonReader ((byte []) null, new XmlDictionaryReaderQuotas ()); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorNullStream () + { + JsonReaderWriterFactory.CreateJsonReader ((Stream) null, new XmlDictionaryReaderQuotas ()); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorNullReaderQuotas () + { + JsonReaderWriterFactory.CreateJsonReader (GetInput ("{}"), null); + } + + [Test] + public void ConstructorNullEncodingAndReaderClose () + { + JsonReaderWriterFactory.CreateJsonReader (GetInput ("{}"), null, new XmlDictionaryReaderQuotas (), null); + } + + // Close() + + [Test] + public void CloseTwice () + { + reader = CreateReader ("{}"); + reader.Close (); + reader.Close (); + } + + [Test] + // hmm... [ExpectedException (typeof (InvalidOperationException))] + public void CloseAndRead () + { + reader = CreateReader ("{}"); + reader.Close (); + reader.Read (); + } + + [Test] + // hmm... [ExpectedException (typeof (InvalidOperationException))] + public void CloseAndMoveToFirstAttribute () + { + reader = CreateReader ("{}"); + reader.Close (); + reader.MoveToFirstAttribute (); + } + + // Read() several top-level types + + [Test] + public void ReadStateEmpty () + { + reader = CreateReader (""); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#2"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#3"); + } + + [Test] + public void ReadStateEmpty2 () + { + reader = CreateReader (" "); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#2"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#3"); + } + + [Test] + public void ReadStateObject () + { + reader = CreateReader ("{}"); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); // element + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#2"); + reader.Read (); // endelement + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#3"); + reader.Read (); // endoffile + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#4"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#5"); + } + + [Test] + public void ReadStateArray () + { + reader = CreateReader ("[]"); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); // element + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#2"); + reader.Read (); // endelement + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#3"); + reader.Read (); // endoffile + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#4"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#5"); + } + + [Test] + public void ReadNumber () + { + reader = CreateReader ("1234"); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); // dummy root element + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#2"); + Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "#2-1"); + Assert.AreEqual ("root", reader.LocalName, "#2-2"); + reader.Read (); // content (number) + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#3"); + Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "#3-1"); + Assert.AreEqual ("1234", reader.Value, "#3-2"); + reader.Read (); // endelement + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#4"); + Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "#4-1"); + reader.Read (); // endoffile + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#5"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#6"); + } + + [Test] + public void ReadBool () + { + reader = CreateReader ("true"); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); // dummy root element + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#2"); + Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "#2-1"); + Assert.AreEqual ("root", reader.LocalName, "#2-2"); + Assert.AreEqual ("boolean", reader.GetAttribute ("type"), "#2-3"); + reader.Read (); // content (boolean) + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#3"); + Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "#3-1"); + Assert.AreEqual ("true", reader.Value, "#3-2"); + reader.Read (); // endelement + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#4"); + Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "#4-1"); + reader.Read (); // endoffile + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#5"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#6"); + } + + [Test] + public void ReadNull () + { + reader = CreateReader ("null"); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); // dummy root element + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#2"); + Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "#2-1"); + Assert.AreEqual ("root", reader.LocalName, "#2-2"); + // When it is null, the value is never given and the reader is skipped to the end element. + reader.Read (); // endlement + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#3"); + Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "#3-1"); + reader.Read (); // endoffile + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#4"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#4"); + } + + [Test] + public void ReadString () + { + reader = CreateReader ("\"true\""); + Assert.AreEqual (ReadState.Initial, reader.ReadState, "#1"); + reader.Read (); // dummy root element + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#2"); + Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "#2-1"); + Assert.AreEqual ("root", reader.LocalName, "#2-2"); + Assert.AreEqual ("string", reader.GetAttribute ("type"), "#2-3"); + reader.Read (); // content (number) + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#3"); + Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "#3-1"); + Assert.AreEqual ("true", reader.Value, "#3-2"); + reader.Read (); // endelement + Assert.AreEqual (ReadState.Interactive, reader.ReadState, "#4"); + Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "#4-1"); + reader.Read (); // endoffile + Assert.AreEqual (ReadState.EndOfFile, reader.ReadState, "#5"); + reader.Close (); + Assert.AreEqual (ReadState.Closed, reader.ReadState, "#6"); + } + + // MoveToAttribute() / MoveToElement() + + [Test] + public void MoveToAttributeObject () + { + reader = CreateReader ("{}"); + Assert.IsFalse (reader.MoveToFirstAttribute (), "#1"); + reader.Read (); // element + Assert.IsTrue (reader.MoveToFirstAttribute (), "#2"); + Assert.AreEqual ("type", reader.LocalName, "#3"); + Assert.AreEqual ("object", reader.Value, "#4"); + Assert.IsTrue (reader.ReadAttributeValue (), "#5"); + Assert.AreEqual ("object", reader.Value, "#6"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#7"); + Assert.IsTrue (reader.MoveToFirstAttribute (), "#8"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#9"); + } + + [Test] + public void MoveToElementObject () + { + reader = CreateReader ("{}"); + reader.Read (); // element + Assert.IsTrue (reader.MoveToFirstAttribute (), "#1"); + Assert.IsTrue (reader.MoveToElement (), "#1-1"); + + Assert.IsTrue (reader.MoveToFirstAttribute (), "#2"); + Assert.IsTrue (reader.ReadAttributeValue (), "#2-1"); + Assert.IsTrue (reader.MoveToElement (), "#2-2"); + + Assert.IsTrue (reader.MoveToFirstAttribute (), "#3"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#3-1"); + Assert.IsTrue (reader.MoveToElement (), "#3-2"); + } + + [Test] + public void MoveToAttributeArray () + { + reader = CreateReader ("[]"); + Assert.IsFalse (reader.MoveToFirstAttribute (), "#1"); + reader.Read (); // element + Assert.IsTrue (reader.MoveToFirstAttribute (), "#2"); + Assert.AreEqual ("type", reader.LocalName, "#3"); + Assert.AreEqual ("array", reader.Value, "#4"); + Assert.IsTrue (reader.ReadAttributeValue (), "#5"); + Assert.AreEqual ("array", reader.Value, "#6"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#7"); + Assert.IsTrue (reader.MoveToFirstAttribute (), "#8"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#9"); + } + + [Test] + public void MoveToElementArray () + { + reader = CreateReader ("[]"); + reader.Read (); // element + Assert.IsTrue (reader.MoveToFirstAttribute (), "#1"); + Assert.IsTrue (reader.MoveToElement (), "#1-1"); + + Assert.IsTrue (reader.MoveToFirstAttribute (), "#2"); + Assert.IsTrue (reader.ReadAttributeValue (), "#2-1"); + Assert.IsTrue (reader.MoveToElement (), "#2-2"); + + Assert.IsTrue (reader.MoveToFirstAttribute (), "#3"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#3-1"); + Assert.IsTrue (reader.MoveToElement (), "#3-2"); + } + + [Test] + public void MoveToAttributeSimpleDummyRoot () + { + reader = CreateReader ("1234"); + Assert.IsFalse (reader.MoveToFirstAttribute (), "#1"); + reader.Read (); // element + Assert.IsTrue (reader.MoveToFirstAttribute (), "#2"); + Assert.AreEqual ("type", reader.LocalName, "#3"); + Assert.AreEqual ("number", reader.Value, "#4"); + Assert.IsTrue (reader.ReadAttributeValue (), "#5"); + Assert.AreEqual ("number", reader.Value, "#6"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#7"); + Assert.IsTrue (reader.MoveToFirstAttribute (), "#8"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#9"); + } + + [Test] + public void MoveToElementSimpleDummyRoot () + { + reader = CreateReader ("1234"); + reader.Read (); // element + Assert.IsTrue (reader.MoveToFirstAttribute (), "#1"); + Assert.IsTrue (reader.MoveToElement (), "#1-1"); + + Assert.IsTrue (reader.MoveToFirstAttribute (), "#2"); + Assert.IsTrue (reader.ReadAttributeValue (), "#2-1"); + Assert.IsTrue (reader.MoveToElement (), "#2-2"); + + Assert.IsTrue (reader.MoveToFirstAttribute (), "#3"); + Assert.IsFalse (reader.MoveToNextAttribute (), "#3-1"); + Assert.IsTrue (reader.MoveToElement (), "#3-2"); + } + + // Read() arrays and objects + + [Test] + public void ReadArrayContent () + { + reader = CreateReader ("[123, \"123\", true, \"true\"]"); + + // number value + reader.Read (); // element + AssertNode (0, "root", XmlNodeType.Element, String.Empty, "array", reader, "#1"); + + reader.Read (); // 123 - element + Assert.AreEqual ("number", reader.GetAttribute ("type"), "#2-0"); + AssertNode (1, "item", XmlNodeType.Element, String.Empty, "number", reader, "#2"); + reader.Read (); // 123 - text + AssertNode (2, String.Empty, XmlNodeType.Text, "123", null, reader, "#3"); + reader.Read (); // 123 - endelement + AssertNode (1, "item", XmlNodeType.EndElement, String.Empty, null, reader, "#4"); + + // string value #1 + reader.Read (); // "123" - element + Assert.AreEqual ("string", reader.GetAttribute ("type"), "#5-0"); + AssertNode (1, "item", XmlNodeType.Element, String.Empty, "string", reader, "#5"); + reader.Read (); // "123" - text + AssertNode (2, String.Empty, XmlNodeType.Text, "123", null, reader, "#6"); + reader.Read (); // "123" - endelement + AssertNode (1, "item", XmlNodeType.EndElement, String.Empty, null, reader, "#7"); + + reader.Read (); // true - element + Assert.AreEqual ("boolean", reader.GetAttribute ("type"), "#8-0"); + AssertNode (1, "item", XmlNodeType.Element, String.Empty, "boolean", reader, "#8"); + reader.Read (); // true - text + AssertNode (2, String.Empty, XmlNodeType.Text, "true", null, reader, "#9"); + reader.Read (); // true - endelement + AssertNode (1, "item", XmlNodeType.EndElement, String.Empty, null, reader, "#10"); + + // string value #2 + reader.Read (); // "true" - element + Assert.AreEqual ("string", reader.GetAttribute ("type"), "#11-0"); + AssertNode (1, "item", XmlNodeType.Element, String.Empty, "string", reader, "#11"); + reader.Read (); // "true" - text + AssertNode (2, String.Empty, XmlNodeType.Text, "true", null, reader, "#12"); + reader.Read (); // "true" - endelement + AssertNode (1, "item", XmlNodeType.EndElement, String.Empty, null, reader, "#13"); + Assert.IsTrue (reader.Read (), "#14"); // ] + AssertNode (0, "root", XmlNodeType.EndElement, String.Empty, null, reader, "#15"); + Assert.IsFalse (reader.Read (), "#16"); // EOF + } + + [Test] + public void ReadObjectContent () + { + reader = CreateReader ("{\"A\":123, \"B\": \"123\", \"C\" :true, \"D\" : \"true\"}"); + + // number value + reader.Read (); // element + AssertNode (0, "root", XmlNodeType.Element, String.Empty, "object", reader, "#1"); + + reader.Read (); // 123 - element + AssertNode (1, "A", XmlNodeType.Element, String.Empty, "number", reader, "#2"); + reader.Read (); // 123 - text + AssertNode (2, String.Empty, XmlNodeType.Text, "123", null, reader, "#3"); + reader.Read (); // 123 - endelement + AssertNode (1, "A", XmlNodeType.EndElement, String.Empty, null, reader, "#4"); + + // string value #1 + reader.Read (); // "123" - element + AssertNode (1, "B", XmlNodeType.Element, String.Empty, "string", reader, "#5"); + reader.Read (); // "123" - text + AssertNode (2, String.Empty, XmlNodeType.Text, "123", null, reader, "#6"); + reader.Read (); // "123" - endelement + AssertNode (1, "B", XmlNodeType.EndElement, String.Empty, null, reader, "#7"); + + reader.Read (); // true - element + AssertNode (1, "C", XmlNodeType.Element, String.Empty, "boolean", reader, "#8"); + reader.Read (); // true - text + AssertNode (2, String.Empty, XmlNodeType.Text, "true", null, reader, "#9"); + reader.Read (); // true - endelement + AssertNode (1, "C", XmlNodeType.EndElement, String.Empty, null, reader, "#10"); + + // string value #2 + reader.Read (); // "true" - element + AssertNode (1, "D", XmlNodeType.Element, String.Empty, "string", reader, "#11"); + reader.Read (); // "true" - text + AssertNode (2, String.Empty, XmlNodeType.Text, "true", null, reader, "#12"); + reader.Read (); // "true" - endelement + AssertNode (1, "D", XmlNodeType.EndElement, String.Empty, null, reader, "#13"); + Assert.IsTrue (reader.Read (), "#14"); // } + AssertNode (0, "root", XmlNodeType.EndElement, String.Empty, null, reader, "#15"); + Assert.IsFalse (reader.Read (), "#16"); // EOF + } + + [Test] + public void ReadNestedObjects () + { + reader = CreateReader ("{\"A\": [123, {\"B\": \"456\", \"C\" :true}], \"D\" : {\"E\" : \"false\"}}"); + Assert.IsTrue (reader.Read (), "#1"); // { + AssertNode (0, "root", XmlNodeType.Element, String.Empty, "object", reader, "#2"); + Assert.IsTrue (reader.Read (), "#3"); // A + AssertNode (1, "A", XmlNodeType.Element, String.Empty, "array", reader, "#4"); + Assert.IsTrue (reader.Read (), "#5"); // (<123>) + AssertNode (2, "item", XmlNodeType.Element, String.Empty, "number", reader, "#6"); + Assert.IsTrue (reader.Read (), "#7"); // (123) + AssertNode (3, String.Empty, XmlNodeType.Text, "123", null, reader, "#8"); + Assert.IsTrue (reader.Read (), "#9"); // (</123>) + AssertNode (2, "item", XmlNodeType.EndElement, String.Empty, null, reader, "#10"); + Assert.IsTrue (reader.Read (), "#11"); // { + AssertNode (2, "item", XmlNodeType.Element, String.Empty, "object", reader, "#12"); + Assert.IsTrue (reader.Read (), "#13"); // B + AssertNode (3, "B", XmlNodeType.Element, String.Empty, "string", reader, "#14"); + Assert.IsTrue (reader.Read (), "#15"); // "456" + AssertNode (4, String.Empty, XmlNodeType.Text, "456", null, reader, "#16"); + Assert.IsTrue (reader.Read (), "#17"); // /B + AssertNode (3, "B", XmlNodeType.EndElement, String.Empty, null, reader, "#18"); + + Assert.IsTrue (reader.Read (), "#19"); // C + AssertNode (3, "C", XmlNodeType.Element, String.Empty, "boolean", reader, "#20"); + Assert.IsTrue (reader.Read (), "#21"); // true + AssertNode (4, String.Empty, XmlNodeType.Text, "true", null, reader, "#22"); + Assert.IsTrue (reader.Read (), "#23"); // /C + AssertNode (3, "C", XmlNodeType.EndElement, String.Empty, null, reader, "#24"); + Assert.IsTrue (reader.Read (), "#25"); // } + AssertNode (2, "item", XmlNodeType.EndElement, String.Empty, null, reader, "#26"); + Assert.IsTrue (reader.Read (), "#27"); // ] + AssertNode (1, "A", XmlNodeType.EndElement, String.Empty, null, reader, "#28"); + Assert.IsTrue (reader.Read (), "#29"); // { + AssertNode (1, "D", XmlNodeType.Element, String.Empty, "object", reader, "#30"); + Assert.IsTrue (reader.Read (), "#31"); // D + AssertNode (2, "E", XmlNodeType.Element, String.Empty, "string", reader, "#32"); + Assert.IsTrue (reader.Read (), "#33"); // "false" + AssertNode (3, String.Empty, XmlNodeType.Text, "false", null, reader, "#34"); + Assert.IsTrue (reader.Read (), "#35"); // /D + AssertNode (2, "E", XmlNodeType.EndElement, String.Empty, null, reader, "#36"); + Assert.IsTrue (reader.Read (), "#37"); // } + AssertNode (1, "D", XmlNodeType.EndElement, String.Empty, null, reader, "#38"); + Assert.IsTrue (reader.Read (), "#39"); // } + AssertNode (0, "root", XmlNodeType.EndElement, String.Empty, null, reader, "#40"); + Assert.IsFalse (reader.Read (), "#41"); // EOF + } + + void ReadToEnd (XmlDictionaryReader reader) + { + while (!reader.EOF) + reader.Read (); + } + + // Read() valid and invalid contents + + [Test] + [Ignore ("It should throw XmlException for parser error, but .NET fails to report that")] + public void ReadTwoTopLevelContents () + { + ReadToEnd (CreateReader ("{}{}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadMissingCloseCurly () + { + ReadToEnd (CreateReader ("{")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadMissingCloseCurly2 () + { + ReadToEnd (CreateReader ("{{}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadExtraCloseCurly () + { + ReadToEnd (CreateReader ("}")); + } + + [Test] + [Ignore ("It should throw XmlException for parser error, but .NET fails to report that")] + public void ReadExtraCloseCurly2 () + { + ReadToEnd (CreateReader ("{}}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadMissingCloseBrace () + { + ReadToEnd (CreateReader ("[")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadMissingCloseBrace2 () + { + ReadToEnd (CreateReader ("[[]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadExtraCloseBrace () + { + ReadToEnd (CreateReader ("]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // hmm, why does it pass? + public void ReadExtraCloseBrace2 () + { + ReadToEnd (CreateReader ("[]]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadOpenCurlyCloseBrace () + { + ReadToEnd (CreateReader ("{]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadOpenBraceCloseCurly () + { + ReadToEnd (CreateReader ("[}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadParens () + { + ReadToEnd (CreateReader ("()")); + } + + [Test] + public void ReadValidNumber () + { + ReadToEnd (CreateReader ("0")); + } + + [Test] + public void ReadValidNumber2 () + { + ReadToEnd (CreateReader ("-0")); + } + + [Test] + public void ReadValidNumber3 () + { + ReadToEnd (CreateReader ("0e5")); + } + + [Test] + public void ReadValidNumber4 () + { + ReadToEnd (CreateReader ("0.5")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidNumber () + { + CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture; + try { + Thread.CurrentThread.CurrentCulture = new CultureInfo ("de-DE"); + // if we read a number just by current culture, it will be regarded as correct JSON. + ReadToEnd (CreateReader ("123,45")); + } finally { + Thread.CurrentThread.CurrentCulture = originalCulture; + } + } + + [Test] + public void ReadValidNumberGerman () + { + CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture; + try { + Thread.CurrentThread.CurrentCulture = new CultureInfo ("de-DE"); + var s = GetInput ("123.45"); // German is ',' for decimals + var r = new DataContractJsonSerializer (typeof (double)); + var d = (double) r.ReadObject (s); + Assert.AreEqual (123.45, d, "InvariantCulture"); + } finally { + Thread.CurrentThread.CurrentCulture = originalCulture; + } + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidNumber2 () + { + ReadToEnd (CreateReader ("+5")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidNumber3 () + { + ReadToEnd (CreateReader ("01")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidNumber4 () + { + ReadToEnd (CreateReader (".1")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidNumber5 () + { + ReadToEnd (CreateReader ("10.")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidNumber7 () + { + ReadToEnd (CreateReader ("e5")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidNumber8 () + { + ReadToEnd (CreateReader ("-e5")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidNumber9 () + { + ReadToEnd (CreateReader ("-e5.5")); + } + + [Test] + public void ReadInvalidNumber10 () // bug #531904 + { + ReadToEnd (CreateReader ("4.29153442382814E-05")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidObjectContent () + { + ReadToEnd (CreateReader ("{\"foo\"}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidObjectContent2 () + { + ReadToEnd (CreateReader ("{\"A\": 123 456}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidObjectContent3 () + { + ReadToEnd (CreateReader ("{, \"A\":123, \"B\":456}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidObjectContent4 () + { + ReadToEnd (CreateReader ("{\"A\":123, \"B\":456,}")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidArrayContent () + { + ReadToEnd (CreateReader ("[\"foo\":\"bar\"]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidArrayContent2 () + { + ReadToEnd (CreateReader ("[123 456]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidArrayContent3 () + { + ReadToEnd (CreateReader ("[,123,456]")); + } + + [Test] + [ExpectedException (typeof (XmlException))] + [Ignore ("NotDotNet")] // likely .NET bug + public void ReadInvalidArrayContent4 () + { + ReadToEnd (CreateReader ("[123,456,]")); + } + + [Test] + public void ReadObjectRuntimeTypeAsAttribute () + { + XmlDictionaryReader r = CreateReader ("{\"__type\":\"System.Int32\"}"); + r.Read (); + AssertNode (0, "root", XmlNodeType.Element, String.Empty, "object", r, "#1"); + Assert.IsTrue (r.MoveToAttribute ("type"), "#2"); + AssertNode (0, "type", XmlNodeType.Attribute, "object", "object", r, "#3"); + Assert.IsTrue (r.MoveToAttribute ("__type"), "#4"); + AssertNode (0, "__type", XmlNodeType.Attribute, "System.Int32", "object", r, "#5"); + r.Read (); + Assert.AreEqual (XmlNodeType.EndElement, r.NodeType, "#6"); + } + + [Test] + public void ReadObjectRuntimeType () + { + XmlDictionaryReader r = CreateReader ("{\"__type\":\"System.Int32\", \"foo\":true}"); + r.Read (); + AssertNode (0, "root", XmlNodeType.Element, String.Empty, "object", r, "#1"); + Assert.IsTrue (r.MoveToAttribute ("type"), "#2"); + AssertNode (0, "type", XmlNodeType.Attribute, "object", "object", r, "#3"); + Assert.IsTrue (r.MoveToAttribute ("__type"), "#4"); + AssertNode (0, "__type", XmlNodeType.Attribute, "System.Int32", "object", r, "#5"); + r.Read (); + Assert.AreEqual (XmlNodeType.Element, r.NodeType, "#6"); + Assert.AreEqual ("foo", r.LocalName, "#7"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void ReadInvalidObjectRuntimeTypeValue () + { + ReadToEnd (CreateReader ("{\"__type\":true}")); + } + + [Test] + public void ReadObjectRuntimeTypeIncorrectPosition () + { + XmlReader r = CreateReader ("{\"foo\" : false, \"__type\" : \"System.Int32\"}"); + r.Read (); + // When __type is not at the first content, it is not regarded as an attribute. Note that it is not treated as an error. + Assert.IsFalse (r.MoveToAttribute ("__type")); + r.Skip (); + } + + [Test] + public void ReadObjectRuntimeTypeInArray () + { + XmlReader r = CreateReader (@"[{""__type"":""DCWithEnum:#MonoTests.System.Runtime.Serialization.Json"",""_colors"":0}]"); + r.Read (); + Assert.AreEqual ("root", r.LocalName, "#1-1"); + Assert.AreEqual ("array", r.GetAttribute ("type"), "#1-2"); + r.Read (); + Assert.AreEqual ("item", r.LocalName, "#2-1"); + Assert.AreEqual ("object", r.GetAttribute ("type"), "#2-2"); + Assert.IsNotNull (r.GetAttribute ("__type"), "#2-3"); + r.Read (); + } + + [Test] + public void Skip () + { + XmlReader r = CreateReader ("{\"type\" : \"\", \"valid\" : \"0\", \"other\" : \"\"}"); + r.ReadStartElement (); + r.MoveToContent (); + Assert.AreEqual ("type", r.Name, "Skip-1"); + r.ReadElementContentAsString (); + r.MoveToContent (); + Assert.AreEqual ("valid", r.Name, "Skip-2"); + r.Skip (); + Assert.AreEqual ("other", r.Name, "Skip-3"); + } + + [Test] + public void Depth () + { + XmlReader r = CreateReader ("{\"type\" : \"\", \"valid\" : \"0\"}"); + r.ReadStartElement (); + r.Read (); + Assert.AreEqual (2, r.Depth, "Depth-1"); + } + + [Test] + public void UnicodeEncodingAutoDetect () + { + var ms = new MemoryStream (Encoding.Unicode.GetBytes ("{\"type\" : \"\", \"valid\" : \"0\"}")); + XmlReader r = JsonReaderWriterFactory.CreateJsonReader (ms, new XmlDictionaryReaderQuotas ()); + r.ReadStartElement (); + r.Read (); + } + + [Test] + public void ReadNumberAsObject () + { + const double testValue = 42.42D; + var serializer = new DataContractJsonSerializer (typeof (object)); + var serializedStream = GetInput (testValue.ToString (CultureInfo.InvariantCulture)); + var deserializedValue = serializer.ReadObject (serializedStream); + Assert.AreEqual (typeof (decimal), deserializedValue.GetType ()); + Assert.AreEqual (testValue, (decimal) deserializedValue); + } + + [Test] + public void IEnumerableTest () + { + string json = "[\"A\", \"B\"]"; + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { + DataContractJsonSerializer jsonSerializer = new + DataContractJsonSerializer(typeof(IEnumerable<string>)); + var result = jsonSerializer.ReadObject(stream); + Assert.AreEqual (typeof (string []), result.GetType ()); + } + } + } +} diff --git a/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs new file mode 100644 index 00000000000..b6e42b90bb0 --- /dev/null +++ b/mcs/class/System.Runtime.Serialization/Test/System.Runtime.Serialization.Json/JsonWriterTest.cs @@ -0,0 +1,640 @@ +// +// JsonWriterTest.cs +// +// Author: +// Atsushi Enomoto <atsushi@ximian.com> +// +// Copyright (C) 2007 Novell, Inc (http://www.novell.com) +// +// 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. +// +using System; +using System.IO; +using System.Text; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Xml; +using NUnit.Framework; + +namespace MonoTests.System.Runtime.Serialization.Json +{ + [TestFixture] + public class JsonWriterTest + { + MemoryStream ms; + XmlDictionaryWriter w; + + string ResultString { + get { return Encoding.UTF8.GetString (ms.ToArray ()); } + } + + [SetUp] + public void Setup () + { + ms = new MemoryStream (); + w = JsonReaderWriterFactory.CreateJsonWriter (ms); + } + + /* + [Test] + public void Dummy_BitFlagsGenerator () + { + var b = new BitFlagsGenerator (2); + Assert.IsFalse (b.Load (0), "#a1"); + b.Store (0, false); + Assert.IsFalse (b.Load (0), "#a2"); + b.Store (0, true); + Assert.IsTrue (b.Load (0), "#a3"); + Assert.IsFalse (b.Load (1), "#a4"); + b.Store (0, false); + Assert.IsFalse (b.Load (0), "#a5"); + Assert.IsFalse (b.Load (1), "#a6"); + + Assert.IsFalse (b.Load (1), "#b1"); + b.Store (1, false); + Assert.IsFalse (b.Load (1), "#b2"); + b.Store (1, true); + Assert.IsTrue (b.Load (1), "#b3"); + b.Store (1, false); + Assert.IsFalse (b.Load (1), "#b4"); + + var bytes = new byte [2]; + Assert.IsFalse (BitFlagsGenerator.IsBitSet (bytes, 0), "#c1"); + BitFlagsGenerator.SetBit (bytes, 0); + Assert.IsTrue (BitFlagsGenerator.IsBitSet (bytes, 0), "#c2"); + Assert.IsFalse (BitFlagsGenerator.IsBitSet (bytes, 1), "#c3"); + BitFlagsGenerator.SetBit (bytes, 0); + Assert.IsTrue (BitFlagsGenerator.IsBitSet (bytes, 0), "#c4"); + } + */ + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorNullStream () + { + JsonReaderWriterFactory.CreateJsonWriter (null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void ConstructorNullEncoding () + { + JsonReaderWriterFactory.CreateJsonWriter (new MemoryStream (), null); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void SimpleElementNotRoot () + { + w.WriteStartElement ("foo"); + } + + [Test] + public void SimpleElement () + { + w.WriteStartElement ("root"); + w.WriteEndElement (); + w.Close (); + // empty string literal ("") + Assert.AreEqual ("\"\"", ResultString, "#1"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void SimpleElement2 () + { + w.WriteStartElement ("root"); + w.WriteStartElement ("foo"); + // type='array' or type='object' is required before writing immediate child of an element. + } + + [Test] + public void SimpleElement3 () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("e1"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("e1_1"); + w.WriteEndElement (); // treated as a string literal + w.WriteEndElement (); + w.WriteStartElement ("e2"); + w.WriteString ("value"); + w.WriteEndElement (); + w.WriteEndElement (); + w.Close (); + string json = "{\"e1\":{\"e1_1\":\"\"},\"e2\":\"value\"}"; + Assert.AreEqual (json, ResultString, "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void AttributeNonType () + { + w.WriteStartElement ("root"); + // only "type" attribute is expected. + w.WriteStartAttribute ("a1"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void TypeAttributeNonStandard () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "foo"); + } + + [Test] + public void SimpleTypeAttribute () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "number"); + w.WriteEndElement (); + w.Close (); + Assert.AreEqual (String.Empty, ResultString, "#1"); + } + + [Test] + public void SimpleTypeAttribute2 () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "number"); + w.WriteString ("1"); + w.WriteEndElement (); + w.Close (); + Assert.AreEqual ("{\"foo\":1}", ResultString, "#1"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStringForNull () + { + w.WriteStartElement ("root"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "null"); + w.WriteString ("1"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStringForArray () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "array"); + w.WriteString ("1"); + } + + [Test] + // uh, no exception? + public void WriteStringForBoolean () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "boolean"); + w.WriteString ("xyz"); + w.WriteEndElement (); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStringForObject () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteString ("1"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteArrayNonItem () + { + w.WriteStartElement ("root"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "array"); + w.WriteStartElement ("bar"); + } + + [Test] + public void WriteArray () + { + w.WriteStartElement ("root"); // name is ignored + w.WriteAttributeString ("type", "array"); + w.WriteElementString ("item", "v1"); + w.WriteElementString ("item", "v2"); + w.Close (); + Assert.AreEqual (@"[""v1"",""v2""]", ResultString, "#1"); + } + + [Test] + public void WriteArrayInObject () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "array"); + w.WriteElementString ("item", "v1"); + w.WriteElementString ("item", "v2"); + w.Close (); + Assert.AreEqual (@"{""foo"":[""v1"",""v2""]}", ResultString, "#1"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteStartElementNonEmptyNS () + { + // namespaces are not allowed + w.WriteStartElement (String.Empty, "x", "urn:foo"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteStartElementNonEmptyPrefix () + { + // prefixes are not allowed + w.WriteStartElement ("p", "x", "urn:foo"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStartElementMultiTopLevel () + { + w.WriteStartElement ("root"); + w.WriteEndElement (); + // hmm... + Assert.AreEqual (WriteState.Content, w.WriteState, "#1"); + // writing of multiple root elements is not supported + w.WriteStartElement ("root2"); + w.Close (); + Assert.AreEqual (String.Empty, ResultString, "#2"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteStartAttributeNonEmptyNS () + { + // namespaces are not allowed + w.WriteStartElement ("root"); + // well, empty prefix for a global attribute would be + // replaced anyways ... + w.WriteStartAttribute (String.Empty, "x", "urn:foo"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteStartAttributeInXmlNamespace () + { + // even "xml" namespace is not allowed (anyways only "type" is allowed ...) + w.WriteStartElement ("root"); + w.WriteStartAttribute ("xml", "lang", "http://www.w3.org/XML/1998/namespace"); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void LookupPrefixNull () + { + w.LookupPrefix (null); + } + + [Test] + public void LookupPrefix () + { + // since namespaces are not allowed, it mostly makes no sense... + Assert.AreEqual (String.Empty, w.LookupPrefix (String.Empty), "#1"); + Assert.IsNull (w.LookupPrefix ("urn:nonexistent"), "#2"); + Assert.AreEqual ("xml", w.LookupPrefix ("http://www.w3.org/XML/1998/namespace"), "#3"); + Assert.AreEqual ("xmlns", w.LookupPrefix ("http://www.w3.org/2000/xmlns/"), "#4"); + } + + [Test] + public void WriteStartDocument () + { + Assert.AreEqual (WriteState.Start, w.WriteState, "#1"); + w.WriteStartDocument (); + Assert.AreEqual (WriteState.Start, w.WriteState, "#2"); + w.WriteStartDocument (true); + Assert.AreEqual (WriteState.Start, w.WriteState, "#3"); + // So, it does nothing + } + + [Test] + public void WriteEndDocument () + { + w.WriteEndDocument (); // so, it is completely wrong, but ignored. + } + + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void WriteDocType () + { + w.WriteDocType (null, null, null, null); + } + + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void WriteComment () + { + w.WriteComment ("test"); + } + + [Test] + [ExpectedException (typeof (NotSupportedException))] + public void WriteEntityRef () + { + w.WriteEntityRef ("ent"); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteProcessingInstruction () + { + // since this method accepts case-insensitive "XML", + // it throws ArgumentException. + w.WriteProcessingInstruction ("T", "D"); + } + + [Test] + public void WriteProcessingInstructionXML () + { + // You might not know, but in some cases, things like + // XmlWriter.WriteNode() is implemented to invoke + // this method for writing XML declaration. This + // check is (seems) case-insensitive. + w.WriteProcessingInstruction ("XML", "foobar"); + // In this case, the data is simply ignored (as + // WriteStartDocument() is). + } + + [Test] + public void WriteRaw () + { + w.WriteStartElement ("root"); + w.WriteRaw ("sample"); + w.WriteRaw (new char [] {'0', '1', '2', '3'}, 1, 2); + w.Close (); + Assert.AreEqual ("\"sample12\"", ResultString); + } + + [Test] + public void WriteCData () + { + w.WriteStartElement ("root"); + w.WriteCData ("]]>"); // this behavior is incompatible with ordinal XmlWriters. + w.Close (); + Assert.AreEqual ("\"]]>\"", ResultString); + } + + [Test] + public void WriteCharEntity () + { + w.WriteStartElement ("root"); + w.WriteCharEntity ('>'); + w.Close (); + Assert.AreEqual ("\">\"", ResultString); + } + + [Test] + public void WriteWhitespace () + { + w.WriteStartElement ("root"); + w.WriteWhitespace ("\t \n\r"); + w.Close (); + Assert.AreEqual (@"""\u0009 \u000a\u000d""", ResultString); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteWhitespaceNonWhitespace () + { + w.WriteStartElement ("root"); + w.WriteWhitespace ("TEST"); + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] + public void WriteStringTopLevel () + { + w.WriteString ("test"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStartAttributeTopLevel () + { + w.WriteStartAttribute ("test"); + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] + public void WriteStartDocumentAtClosed () + { + w.Close (); + w.WriteStartDocument (); + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] + public void WriteStartElementAtClosed () + { + w.Close (); + w.WriteStartElement ("foo"); + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] + public void WriteProcessingInstructionAtClosed () + { + w.Close (); + w.WriteProcessingInstruction ("xml", "version='1.0'"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteMixedContent () + { + w.WriteStartElement ("root"); + w.WriteString ("TEST"); + w.WriteStartElement ("mixed"); // is not allowed. + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStartElementInvalidTopLevelName () + { + w.WriteStartElement ("anyname"); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void WriteStartElementNullName () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement (null); + } + + [Test] + [ExpectedException (typeof (ArgumentException))] + public void WriteStartElementEmptyName () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement (String.Empty); + // It is regarded as invalid name in JSON. However, + // I don't think there is such limitation in JSON specification. + } + + [Test] + public void WriteStartElementWithRuntimeTypeName () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteAttributeString ("__type", "FooType:#FooNamespace"); + w.Close (); + Assert.AreEqual (@"{""__type"":""FooType:#FooNamespace""}", ResultString); + } + + [Test] + public void WriteStartElementWeirdName () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("!!!"); + w.Close (); + Assert.AreEqual (@"{""!!!"":""""}", ResultString); + } + + [Test] + public void WriteRootAsObject () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteString ("object"); + w.WriteEndAttribute (); + w.Close (); + Assert.AreEqual ("{}", ResultString); + } + + [Test] + public void WriteRootAsArray () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteString ("array"); + w.WriteEndAttribute (); + w.Close (); + Assert.AreEqual ("[]", ResultString); + } + + [Test] + public void WriteRootAsLiteral () + { + w.WriteStartElement ("root"); + w.Close (); + Assert.AreEqual ("\"\"", ResultString); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteEndElementOnAttribute () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteString ("array"); + w.WriteEndElement (); + } + + [Test] + public void WriteAttributeAsSeparateStrings () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteString ("arr"); + w.WriteString ("ay"); + w.WriteEndAttribute (); + w.Close (); + Assert.AreEqual ("[]", ResultString); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStartAttributeInAttributeMode () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteStartAttribute ("type"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStartAttributeInContentMode () + { + w.WriteStartElement ("root"); + w.WriteString ("TEST"); + w.WriteStartAttribute ("type"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void WriteStartElementInAttributeMode () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteStartElement ("child"); + } + + [Test] + [ExpectedException (typeof (XmlException))] + public void CloseAtAtributeState () + { + w.WriteStartElement ("root"); + w.WriteStartAttribute ("type"); + w.WriteString ("array"); + // It calls WriteEndElement() without calling + // WriteEndAttribute(). + w.Close (); + } + + [Test] + public void WriteSlashEscaped () + { + w.WriteStartElement ("root"); + w.WriteString ("/my date/"); + w.WriteEndElement (); + w.Close (); + Assert.AreEqual ("\"\\/my date\\/\"", ResultString); + } + + [Test] + public void WriteNullType () + { + w.WriteStartElement ("root"); + w.WriteAttributeString ("type", "object"); + w.WriteStartElement ("foo"); + w.WriteAttributeString ("type", "null"); + w.Close (); + Assert.AreEqual ("{\"foo\":null}", ResultString); + } + } +} |