// // System.Xml.XmlTextWriterTests // // Author: // Kral Ferch // // (C) 2002 Kral Ferch // using System; using System.IO; using System.Text; using System.Xml; using NUnit.Framework; namespace MonoTests.System.Xml { public class XmlTextWriterTests : TestCase { public XmlTextWriterTests () : base ("MonoTests.System.Xml.XmlTextWriterTests testsuite") {} public XmlTextWriterTests (string name) : base (name) {} StringWriter sw; XmlTextWriter xtw; protected override void SetUp () { sw = new StringWriter (); xtw = new XmlTextWriter (sw); xtw.QuoteChar = '\''; } private string StringWriterText { get { return sw.GetStringBuilder ().ToString (); } } public void TestAttributeNamespacesNonNamespaceAttributeBefore () { xtw.WriteStartElement ("foo"); xtw.WriteAttributeString("bar", "baz"); xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def"); AssertEquals ("", StringWriterText); } public void TestCDataInvalid () { try { xtw.WriteCData("foo]]>bar"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } } public void TestCloseOpenElements () { xtw.WriteStartElement("foo"); xtw.WriteStartElement("bar"); xtw.WriteStartElement("baz"); xtw.Close(); AssertEquals ("Close didn't write out end elements properly.", "", StringWriterText); } public void TestCloseWriteAfter () { xtw.WriteElementString ("foo", "bar"); xtw.Close (); // WriteEndElement and WriteStartDocument aren't tested here because // they will always throw different exceptions besides 'The Writer is closed.' // and there are already tests for those exceptions. try { xtw.WriteCData ("foo"); Fail ("WriteCData after Close Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message); } try { xtw.WriteComment ("foo"); Fail ("WriteComment after Close Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message); } try { xtw.WriteProcessingInstruction ("foo", "bar"); Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message); } try { xtw.WriteStartElement ("foo", "bar", "baz"); Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message); } try { xtw.WriteAttributeString ("foo", "bar"); Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message); } try { xtw.WriteString ("foo"); Fail ("WriteString after Close Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message); } } public void TestCommentValid () { xtw.WriteComment ("foo"); AssertEquals ("WriteComment had incorrect output.", "", StringWriterText); } public void TestCommentInvalid () { try { xtw.WriteComment("foo-"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } try { xtw.WriteComment("foo-->bar"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } } public void TestConstructorsAndBaseStream () { Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (null, this.xtw.BaseStream)); MemoryStream ms; StreamReader sr; XmlTextWriter xtw; ms = new MemoryStream (); xtw = new XmlTextWriter (ms, new UnicodeEncoding ()); xtw.WriteStartDocument (); xtw.Flush (); ms.Seek (0, SeekOrigin.Begin); sr = new StreamReader (ms, Encoding.Unicode); string expectedXmlDeclaration = ""; string actualXmlDeclaration = sr.ReadToEnd(); AssertEquals (expectedXmlDeclaration, actualXmlDeclaration); Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (ms, xtw.BaseStream)); ms = new MemoryStream (); xtw = new XmlTextWriter (ms, new UnicodeEncoding ()); xtw.WriteStartDocument (true); xtw.Flush (); ms.Seek (0, SeekOrigin.Begin); sr = new StreamReader (ms, Encoding.Unicode); AssertEquals ("", sr.ReadToEnd ()); ms = new MemoryStream (); xtw = new XmlTextWriter (ms, new UTF8Encoding ()); xtw.WriteStartDocument (); xtw.Flush (); ms.Seek (0, SeekOrigin.Begin); sr = new StreamReader (ms, Encoding.UTF8); AssertEquals ("", sr.ReadToEnd ()); ms = new MemoryStream (); xtw = new XmlTextWriter (ms, null); xtw.WriteStartDocument (); xtw.Flush (); ms.Seek (0, SeekOrigin.Begin); sr = new StreamReader (ms, Encoding.UTF8); AssertEquals ("", sr.ReadToEnd ()); ms = new MemoryStream (); xtw = new XmlTextWriter (ms, null); xtw.WriteStartDocument (true); xtw.Flush (); ms.Seek (0, SeekOrigin.Begin); sr = new StreamReader (ms, Encoding.UTF8); AssertEquals ("", sr.ReadToEnd ()); Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (ms, xtw.BaseStream)); } public void TestDocumentStart () { xtw.WriteStartDocument (); AssertEquals ("XmlDeclaration is incorrect.", "", StringWriterText); try { xtw.WriteStartDocument (); Fail("Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "WriteStartDocument should be the first call.", e.Message); } xtw = new XmlTextWriter (sw = new StringWriter ()); xtw.QuoteChar = '\''; xtw.WriteStartDocument (true); AssertEquals ("", StringWriterText); xtw = new XmlTextWriter (sw = new StringWriter ()); xtw.QuoteChar = '\''; xtw.WriteStartDocument (false); AssertEquals ("", StringWriterText); } public void TestElementEmpty () { xtw.WriteStartElement ("foo"); xtw.WriteEndElement (); AssertEquals ("Incorrect output.", "", StringWriterText); } public void TestElementWriteElementString () { xtw.WriteElementString ("foo", "bar"); AssertEquals ("WriteElementString has incorrect output.", "bar", StringWriterText); xtw.WriteElementString ("baz", ""); AssertEquals ("bar", StringWriterText); xtw.WriteElementString ("quux", null); AssertEquals ("bar", StringWriterText); xtw.WriteElementString ("", "quuux"); AssertEquals ("bar<>quuux", StringWriterText); xtw.WriteElementString (null, "quuuux"); AssertEquals ("bar<>quuux<>quuuux", StringWriterText); } public void TestFormatting () { xtw.Formatting = Formatting.Indented; xtw.WriteStartDocument (); xtw.WriteStartElement ("foo"); xtw.WriteElementString ("bar", ""); xtw.Close (); AssertEquals ("\r\n\r\n \r\n", StringWriterText); } public void TestFormattingInvalidXmlForFun () { xtw.Formatting = Formatting.Indented; xtw.IndentChar = 'x'; xtw.WriteStartDocument (); xtw.WriteStartElement ("foo"); xtw.WriteStartElement ("bar"); xtw.WriteElementString ("baz", ""); xtw.Close (); AssertEquals ("\r\n\r\nxx\r\nxxxx\r\nxx\r\n", StringWriterText); } public void TestFormattingFromRemarks () { // Remarks section of on-line help for XmlTextWriter.Formatting suggests this test. xtw.Formatting = Formatting.Indented; xtw.WriteStartElement ("ol"); xtw.WriteStartElement ("li"); xtw.WriteString ("The big "); // This means "li" now has a mixed content model. xtw.WriteElementString ("b", "E"); xtw.WriteElementString ("i", "lephant"); xtw.WriteString (" walks slowly."); xtw.WriteEndElement (); xtw.WriteEndElement (); AssertEquals ("
    \r\n
  1. The big Elephant walks slowly.
  2. \r\n
", StringWriterText); } public void TestLookupPrefix () { xtw.WriteStartElement ("root"); xtw.WriteStartElement ("one"); xtw.WriteAttributeString ("xmlns", "foo", null, "http://abc.def"); xtw.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl"); AssertEquals ("foo", xtw.LookupPrefix ("http://abc.def")); AssertEquals ("bar", xtw.LookupPrefix ("http://ghi.jkl")); xtw.WriteEndElement (); xtw.WriteStartElement ("two"); xtw.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr"); xtw.WriteString("quux"); AssertEquals ("baz", xtw.LookupPrefix ("http://mno.pqr")); AssertNull (xtw.LookupPrefix ("http://abc.def")); AssertNull (xtw.LookupPrefix ("http://ghi.jkl")); AssertNull (xtw.LookupPrefix ("http://bogus")); } public void TestNamespacesAttributesPassingInNamespaces () { xtw.Namespaces = false; xtw.WriteStartElement ("foo"); // These shouldn't throw any exceptions since they don't pass in // a namespace. xtw.WriteAttributeString ("bar", "baz"); xtw.WriteAttributeString ("", "a", "", "b"); xtw.WriteAttributeString (null, "c", "", "d"); xtw.WriteAttributeString ("", "e", null, "f"); xtw.WriteAttributeString (null, "g", null, "h"); AssertEquals ("bar
", StringWriterText); } public void TestNamespacesPrefix () { xtw.WriteStartElement ("foo", "bar", "http://netsack.com/"); xtw.WriteStartElement ("foo", "baz", "http://netsack.com/"); xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty); xtw.WriteEndElement (); xtw.WriteEndElement (); AssertEquals ("XmlTextWriter is incorrectly outputting prefixes.", "", StringWriterText); } public void TestNamespacesPrefixWithEmptyAndNullNamespace () { try { xtw.WriteStartElement ("foo", "bar", ""); Fail ("Should have thrown an ArgumentException."); } catch (ArgumentException) {} try { xtw.WriteStartElement ("foo", "bar", null); Fail ("Should have thrown an ArgumentException."); } catch (ArgumentException) {} } public void TestNamespacesSettingWhenWriteStateNotStart () { xtw.WriteStartElement ("foo"); try { xtw.Namespaces = false; Fail ("Expected an InvalidOperationException."); } catch (InvalidOperationException) {} AssertEquals (true, xtw.Namespaces); } public void TestProcessingInstructionValid () { xtw.WriteProcessingInstruction("foo", "bar"); AssertEquals ("WriteProcessingInstruction had incorrect output.", "", StringWriterText); } public void TestProcessingInstructionInvalid () { try { xtw.WriteProcessingInstruction("fo?>o", "bar"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } try { xtw.WriteProcessingInstruction("foo", "ba?>r"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } try { xtw.WriteProcessingInstruction("", "bar"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } try { xtw.WriteProcessingInstruction(null, "bar"); Fail("Should have thrown an ArgumentException."); } catch (ArgumentException) { } } public void TestQuoteCharDoubleQuote () { xtw.QuoteChar = '"'; // version, encoding, standalone xtw.WriteStartDocument (true); // namespace declaration xtw.WriteElementString ("foo", "http://netsack.com", "bar"); AssertEquals ("bar", StringWriterText); } public void TestQuoteCharInvalid () { try { xtw.QuoteChar = 'x'; Fail ("Should have thrown an ArgumentException."); } catch (ArgumentException) {} } public void TestWriteBase64 () { UTF8Encoding encoding = new UTF8Encoding(); byte[] fooBar = encoding.GetBytes("foobar"); xtw.WriteBase64 (fooBar, 0, 6); AssertEquals("Zm9vYmFy", StringWriterText); try { xtw.WriteBase64 (fooBar, 3, 6); Fail ("Expected an Argument Exception to be thrown."); } catch (ArgumentException) {} try { xtw.WriteBase64 (fooBar, -1, 6); Fail ("Expected an Argument Exception to be thrown."); } catch (ArgumentOutOfRangeException) {} try { xtw.WriteBase64 (fooBar, 3, -1); Fail ("Expected an Argument Exception to be thrown."); } catch (ArgumentOutOfRangeException) {} try { xtw.WriteBase64 (null, 0, 6); Fail ("Expected an Argument Exception to be thrown."); } catch (ArgumentNullException) {} } public void TestWriteCharEntity () { xtw.WriteCharEntity ('a'); AssertEquals ("a", StringWriterText); xtw.WriteCharEntity ('A'); AssertEquals ("aA", StringWriterText); xtw.WriteCharEntity ('1'); AssertEquals ("aA1", StringWriterText); xtw.WriteCharEntity ('K'); AssertEquals ("aA1K", StringWriterText); try { xtw.WriteCharEntity ((char)0xd800); } catch (ArgumentException) {} } public void TestWriteEndAttribute () { try { xtw.WriteEndAttribute (); Fail ("Should have thrown an InvalidOperationException."); } catch (InvalidOperationException) {} } public void TestWriteEndDocument () { try { xtw.WriteEndDocument (); Fail ("Expected an ArgumentException."); } catch (ArgumentException) {} xtw.WriteStartDocument (); try { xtw.WriteEndDocument (); Fail ("Expected an ArgumentException."); } catch (ArgumentException) {} xtw.WriteStartElement ("foo"); xtw.WriteStartAttribute ("bar", null); AssertEquals ("", StringWriterText); AssertEquals (WriteState.Start, xtw.WriteState); } public void TestWriteEndElement () { try { xtw.WriteEndElement (); Fail ("Should have thrown an InvalidOperationException."); } catch (InvalidOperationException e) { AssertEquals ("Exception message is incorrect.", "There was no XML start tag open.", e.Message); } xtw.WriteStartElement ("foo"); xtw.WriteEndElement (); AssertEquals ("", StringWriterText); xtw.WriteStartElement ("bar"); xtw.WriteStartAttribute ("baz", null); xtw.WriteEndElement (); AssertEquals ("", StringWriterText); } public void TestFullEndElement () { xtw.WriteStartElement ("foo"); xtw.WriteFullEndElement (); AssertEquals ("", StringWriterText); xtw.WriteStartElement ("bar"); xtw.WriteAttributeString ("foo", "bar"); xtw.WriteFullEndElement (); AssertEquals ("", StringWriterText); xtw.WriteStartElement ("baz"); xtw.WriteStartAttribute ("bar", null); xtw.WriteFullEndElement (); AssertEquals ("", StringWriterText); } public void TestWriteRaw () { xtw.WriteRaw("&<>\"'"); AssertEquals ("&<>\"'", StringWriterText); xtw.WriteRaw(null); AssertEquals ("&<>\"'", StringWriterText); xtw.WriteRaw(""); AssertEquals ("&<>\"'", StringWriterText); } public void TestWriteRawInvalidInAttribute () { xtw.WriteStartElement ("foo"); xtw.WriteStartAttribute ("bar", null); xtw.WriteRaw ("&<>\"'"); xtw.WriteEndAttribute (); xtw.WriteEndElement (); AssertEquals ("", StringWriterText); } public void TestWriteState () { AssertEquals (WriteState.Start, xtw.WriteState); xtw.WriteStartDocument (); AssertEquals (WriteState.Prolog, xtw.WriteState); xtw.WriteStartElement ("root"); AssertEquals (WriteState.Element, xtw.WriteState); xtw.WriteElementString ("foo", "bar"); AssertEquals (WriteState.Content, xtw.WriteState); xtw.Close (); AssertEquals (WriteState.Closed, xtw.WriteState); } public void TestWriteString () { xtw.WriteStartDocument (); try { xtw.WriteString("foo"); } catch (InvalidOperationException) {} // Testing attribute values xtw.WriteStartElement ("foo"); xtw.WriteAttributeString ("bar", "&<>"); AssertEquals ("\"'"); AssertEquals ("&<>\"'", StringWriterText); } public void TestXmlLang () { AssertNull (xtw.XmlLang); xtw.WriteStartElement ("foo"); xtw.WriteAttributeString ("xml", "lang", null, "langfoo"); AssertEquals ("langfoo", xtw.XmlLang); AssertEquals ("baz", StringWriterText); xtw.WriteString("baz"); AssertEquals ("langfoo", xtw.XmlLang); AssertEquals ("bazbaz", StringWriterText); xtw.WriteStartElement ("quux"); xtw.WriteStartAttribute ("xml", "lang", null); AssertEquals ("langfoo", xtw.XmlLang); AssertEquals ("bazbazbazbazbazbazbazbazbazbazsquonk", StringWriterText); xtw.WriteEndElement (); xtw.WriteEndElement (); AssertEquals ("langfoo", xtw.XmlLang); AssertEquals ("bazbazsquonk", StringWriterText); xtw.WriteEndElement (); AssertNull (xtw.XmlLang); AssertEquals ("bazbazsquonk", StringWriterText); xtw.Close (); AssertNull (xtw.XmlLang); } // TODO: test operational aspects public void TestXmlSpace () { xtw.WriteStartElement ("foo"); AssertEquals (XmlSpace.None, xtw.XmlSpace); xtw.WriteStartElement ("bar"); xtw.WriteAttributeString ("xml", "space", null, "preserve"); AssertEquals (XmlSpace.Preserve, xtw.XmlSpace); AssertEquals ("