context: //
  // 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 (GlobalSample1)).WriteObject (new MemoryStream (), new GlobalSample1 ());
  		}
  
  		[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))]
  		[Category ("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))]
  		[Category ("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);
  		}
  
  		[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);
  
gt: 			ds.WriteObject (ms, new TestData () { Foo = "foo"});