Xamarin Public Jenkins (auto-signing) 536cd135cc Imported Upstream version 5.4.0.167
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
2017-08-21 15:34:15 +00:00

641 lines
16 KiB
C#

//
// 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 (@"""\t \n\r""", 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);
}
}
}