**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / Test / System.Xml / XmlTextWriterTests.cs
blobfab47538a2b69cc1bfe94c50a508b807eb3c2df7
1 //
2 // System.Xml.XmlTextWriterTests
3 //
4 // Authors:
5 // Kral Ferch <kral_ferch@hotmail.com>
6 // Martin Willemoes Hansen <mwh@sysrq.dk>
7 //
8 // (C) 2002 Kral Ferch
9 // (C) 2003 Martin Willemoes Hansen
12 using System;
13 using System.IO;
14 using System.Text;
15 using System.Xml;
17 using NUnit.Framework;
19 namespace MonoTests.System.Xml
21 [TestFixture]
22 public class XmlTextWriterTests : Assertion
24 StringWriter sw;
25 XmlTextWriter xtw;
27 [SetUp]
28 public void GetReady ()
30 sw = new StringWriter ();
31 xtw = new XmlTextWriter (sw);
32 xtw.QuoteChar = '\'';
35 private string StringWriterText
37 get { return sw.GetStringBuilder ().ToString (); }
40 [Test]
41 public void AttributeNamespacesNonNamespaceAttributeBefore ()
43 xtw.WriteStartElement ("foo");
44 xtw.WriteAttributeString("bar", "baz");
45 xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
46 AssertEquals ("<foo bar='baz' xmlns:abc='http://abc.def'", StringWriterText);
49 [Test]
50 public void AttributeNamespacesNonNamespaceAttributeAfter ()
52 xtw.WriteStartElement ("foo");
54 xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
55 xtw.WriteAttributeString("bar", "baz");
56 AssertEquals ("<foo xmlns:abc='http://abc.def' bar='baz'", StringWriterText);
59 [Test]
60 public void AttributeNamespacesThreeParamWithNullInNamespaceParam ()
62 xtw.WriteAttributeString ("xmlns", null, "http://abc.def");
63 AssertEquals ("xmlns='http://abc.def'", StringWriterText);
66 [Test]
67 public void AttributeNamespacesThreeParamWithTextInNamespaceParam ()
69 try
71 xtw.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
73 catch (ArgumentException) {}
76 [Test]
77 public void AttributeNamespacesWithNullInNamespaceParam ()
79 xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
80 AssertEquals ("xmlns:abc='http://abc.def'", StringWriterText);
83 [Test]
84 public void AttributeNamespacesWithTextInNamespaceParam ()
86 try {
87 xtw.WriteAttributeString ("xmlns", "abc", "http://somenamespace.com", "http://abc.def");
88 } catch (ArgumentException) {}
91 [Test]
92 public void AttributeNamespacesXmlnsXmlns ()
94 xtw.WriteStartElement ("foo");
95 try {
96 xtw.WriteAttributeString ("xmlns", "xmlns", null, "http://abc.def");
97 // This should not be allowed, even though MS.NET doesn't treat as an error.
98 // See http://www.w3.org/TR/REC-xml-names/ Namespace Constraint: Prefix Declared
99 Fail ("any prefix which name starts from \"xml\" must not be allowed.");
101 catch (ArgumentException) {}
102 xtw.WriteAttributeString ("", "xmlns", null, "http://abc.def");
105 [Test]
106 public void AttributeWriteAttributeString ()
108 xtw.WriteStartElement ("foo");
110 xtw.WriteAttributeString ("foo", "bar");
111 AssertEquals ("<foo foo='bar'", StringWriterText);
113 xtw.WriteAttributeString ("bar", "");
114 AssertEquals ("<foo foo='bar' bar=''", StringWriterText);
116 xtw.WriteAttributeString ("baz", null);
117 AssertEquals ("<foo foo='bar' bar='' baz=''", StringWriterText);
119 xtw.WriteAttributeString ("hoge", "a\nb");
120 AssertEquals ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b'", StringWriterText);
122 xtw.WriteAttributeString ("fuga", " a\t\r\nb\t");
123 AssertEquals ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b' fuga=' a\t&#xD;&#xA;b\t'", StringWriterText);
125 try {
126 // Why does this pass Microsoft?
127 // Anyway, Mono should not allow such code.
128 xtw.WriteAttributeString ("", "quux");
129 // AssertEquals ("<foo foo='bar' bar='' baz='' ='quux'", StringWriterText);
130 Fail ("empty name not allowed.");
131 } catch (Exception) {
134 try {
135 // Why does this pass Microsoft?
136 // Anyway, Mono should not allow such code.
137 xtw.WriteAttributeString (null, "quuux");
138 // AssertEquals ("<foo foo='bar' bar='' baz='' ='quux' ='quuux'", StringWriterText);
139 Fail ("null name not allowed.");
140 } catch (Exception) {
144 [Test]
145 [ExpectedException (typeof (InvalidOperationException))]
146 public void AttributeWriteAttributeStringNotInsideOpenStartElement ()
148 xtw.WriteStartElement ("foo");
149 xtw.WriteString ("bar");
151 xtw.WriteAttributeString ("baz", "quux");
154 [Test]
155 public void AttributeWriteAttributeStringWithoutParentElement ()
157 xtw.WriteAttributeString ("foo", "bar");
158 AssertEquals ("foo='bar'", StringWriterText);
160 xtw.WriteAttributeString ("baz", "quux");
161 AssertEquals ("foo='bar' baz='quux'", StringWriterText);
164 [Test]
165 public void CDataValid ()
167 xtw.WriteCData ("foo");
168 AssertEquals ("WriteCData had incorrect output.", "<![CDATA[foo]]>", StringWriterText);
171 [Test]
172 [ExpectedException (typeof (ArgumentException))]
173 public void CDataInvalid ()
175 xtw.WriteCData("foo]]>bar");
178 [Test]
179 public void CloseOpenElements ()
181 xtw.WriteStartElement("foo");
182 xtw.WriteStartElement("bar");
183 xtw.WriteStartElement("baz");
184 xtw.Close();
185 AssertEquals ("Close didn't write out end elements properly.", "<foo><bar><baz /></bar></foo>", StringWriterText);
188 [Test]
189 public void CloseWriteAfter ()
191 xtw.WriteElementString ("foo", "bar");
192 xtw.Close ();
194 // WriteEndElement and WriteStartDocument aren't tested here because
195 // they will always throw different exceptions besides 'The Writer is closed.'
196 // and there are already tests for those exceptions.
198 try {
199 xtw.WriteCData ("foo");
200 Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
202 catch (InvalidOperationException) {
203 // Don't rely on English message assertion.
204 // It is enough to check an exception occurs.
205 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
208 try {
209 xtw.WriteComment ("foo");
210 Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
212 catch (InvalidOperationException) {
213 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
216 try {
217 xtw.WriteProcessingInstruction ("foo", "bar");
218 Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
220 catch (InvalidOperationException) {
221 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
224 try {
225 xtw.WriteStartElement ("foo", "bar", "baz");
226 Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
228 catch (InvalidOperationException) {
229 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
232 try
234 xtw.WriteAttributeString ("foo", "bar");
235 Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
237 catch (InvalidOperationException)
239 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
242 try {
243 xtw.WriteString ("foo");
244 Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
246 catch (InvalidOperationException) {
247 // AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
251 [Test]
252 public void CommentValid ()
254 xtw.WriteComment ("foo");
255 AssertEquals ("WriteComment had incorrect output.", "<!--foo-->", StringWriterText);
258 [Test]
259 public void CommentInvalid ()
261 try {
262 xtw.WriteComment("foo-");
263 Fail("Should have thrown an ArgumentException.");
265 catch (ArgumentException) { }
267 try {
268 xtw.WriteComment("foo-->bar");
269 Fail("Should have thrown an ArgumentException.");
271 catch (ArgumentException) { }
274 [Test]
275 public void ConstructorsAndBaseStream ()
277 Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (null, this.xtw.BaseStream));
279 MemoryStream ms;
280 StreamReader sr;
281 XmlTextWriter xtw;
283 ms = new MemoryStream ();
284 xtw = new XmlTextWriter (ms, new UnicodeEncoding ());
285 xtw.WriteStartDocument ();
286 xtw.Flush ();
287 ms.Seek (0, SeekOrigin.Begin);
288 sr = new StreamReader (ms, Encoding.Unicode);
289 string expectedXmlDeclaration = "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
290 string actualXmlDeclaration = sr.ReadToEnd();
291 AssertEquals (expectedXmlDeclaration, actualXmlDeclaration);
292 Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (ms, xtw.BaseStream));
294 ms = new MemoryStream ();
295 xtw = new XmlTextWriter (ms, new UnicodeEncoding ());
296 xtw.WriteStartDocument (true);
297 xtw.Flush ();
298 ms.Seek (0, SeekOrigin.Begin);
299 sr = new StreamReader (ms, Encoding.Unicode);
300 AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>", sr.ReadToEnd ());
302 ms = new MemoryStream ();
303 xtw = new XmlTextWriter (ms, new UTF8Encoding ());
304 xtw.WriteStartDocument ();
305 xtw.Flush ();
306 ms.Seek (0, SeekOrigin.Begin);
307 sr = new StreamReader (ms, Encoding.UTF8);
308 AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-8\"?>", sr.ReadToEnd ());
310 ms = new MemoryStream ();
311 xtw = new XmlTextWriter (ms, null);
312 xtw.WriteStartDocument ();
313 xtw.Flush ();
314 ms.Seek (0, SeekOrigin.Begin);
315 sr = new StreamReader (ms, Encoding.UTF8);
316 AssertEquals ("<?xml version=\"1.0\"?>", sr.ReadToEnd ());
318 ms = new MemoryStream ();
319 xtw = new XmlTextWriter (ms, null);
320 xtw.WriteStartDocument (true);
321 xtw.Flush ();
322 ms.Seek (0, SeekOrigin.Begin);
323 sr = new StreamReader (ms, Encoding.UTF8);
324 AssertEquals ("<?xml version=\"1.0\" standalone=\"yes\"?>", sr.ReadToEnd ());
325 Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (ms, xtw.BaseStream));
328 [Test]
329 public void DocumentStart ()
331 xtw.WriteStartDocument ();
332 AssertEquals ("XmlDeclaration is incorrect.", "<?xml version='1.0' encoding='utf-16'?>", StringWriterText);
334 try
336 xtw.WriteStartDocument ();
337 Fail("Should have thrown an InvalidOperationException.");
339 catch (InvalidOperationException) {
340 // Don't rely on English message assertion.
341 // It is enough to check an exception occurs.
342 // AssertEquals ("Exception message is incorrect.",
343 // "WriteStartDocument should be the first call.", e.Message);
346 xtw = new XmlTextWriter (sw = new StringWriter ());
347 xtw.QuoteChar = '\'';
348 xtw.WriteStartDocument (true);
349 AssertEquals ("<?xml version='1.0' encoding='utf-16' standalone='yes'?>", StringWriterText);
351 xtw = new XmlTextWriter (sw = new StringWriter ());
352 xtw.QuoteChar = '\'';
353 xtw.WriteStartDocument (false);
354 AssertEquals ("<?xml version='1.0' encoding='utf-16' standalone='no'?>", StringWriterText);
357 [Test]
358 public void ElementAndAttributeSameXmlns ()
360 xtw.WriteStartElement ("ped", "foo", "urn:foo");
361 xtw.WriteStartAttribute ("ped", "foo", "urn:foo");
362 xtw.WriteEndElement ();
363 AssertEquals ("<ped:foo ped:foo='' xmlns:ped='urn:foo' />", StringWriterText);
366 [Test]
367 public void ElementXmlnsNeedEscape ()
369 xtw.WriteStartElement ("test", "foo", "'");
370 xtw.WriteEndElement ();
371 // MS.NET fails this case.
372 AssertEquals ("<test:foo xmlns:test='&apos;' />", StringWriterText);
375 [Test]
376 public void ElementEmpty ()
378 xtw.WriteStartElement ("foo");
379 xtw.WriteEndElement ();
380 AssertEquals ("Incorrect output.", "<foo />", StringWriterText);
383 [Test]
384 public void ElementWriteElementString ()
386 xtw.WriteElementString ("foo", "bar");
387 AssertEquals ("WriteElementString has incorrect output.", "<foo>bar</foo>", StringWriterText);
389 xtw.WriteElementString ("baz", "");
390 AssertEquals ("<foo>bar</foo><baz />", StringWriterText);
392 xtw.WriteElementString ("quux", null);
393 AssertEquals ("<foo>bar</foo><baz /><quux />", StringWriterText);
395 xtw.WriteElementString ("", "quuux");
396 AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</>", StringWriterText);
398 xtw.WriteElementString (null, "quuuux");
399 AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", StringWriterText);
402 [Test]
403 public void FormattingTest ()
405 xtw.Formatting = Formatting.Indented;
406 xtw.WriteStartDocument ();
407 xtw.WriteStartElement ("foo");
408 xtw.WriteElementString ("bar", "");
409 xtw.Close ();
410 AssertEquals (String.Format ("<?xml version='1.0' encoding='utf-16'?>{0}<foo>{0} <bar />{0}</foo>", Environment.NewLine), StringWriterText);
413 [Test]
414 public void FormattingInvalidXmlForFun ()
416 xtw.Formatting = Formatting.Indented;
417 xtw.IndentChar = 'x';
418 xtw.WriteStartDocument ();
419 xtw.WriteStartElement ("foo");
420 xtw.WriteStartElement ("bar");
421 xtw.WriteElementString ("baz", "");
422 xtw.Close ();
423 AssertEquals (String.Format ("<?xml version='1.0' encoding='utf-16'?>{0}<foo>{0}xx<bar>{0}xxxx<baz />{0}xx</bar>{0}</foo>", Environment.NewLine), StringWriterText);
426 [Test]
427 public void FormattingFromRemarks ()
429 // Remarks section of on-line help for XmlTextWriter.Formatting suggests this test.
430 xtw.Formatting = Formatting.Indented;
431 xtw.WriteStartElement ("ol");
432 xtw.WriteStartElement ("li");
433 xtw.WriteString ("The big "); // This means "li" now has a mixed content model.
434 xtw.WriteElementString ("b", "E");
435 xtw.WriteElementString ("i", "lephant");
436 xtw.WriteString (" walks slowly.");
437 xtw.WriteEndElement ();
438 xtw.WriteEndElement ();
439 AssertEquals (String.Format ("<ol>{0} <li>The big <b>E</b><i>lephant</i> walks slowly.</li>{0}</ol>", Environment.NewLine), StringWriterText);
442 [Test]
443 public void LookupPrefix ()
445 xtw.WriteStartElement ("root");
447 xtw.WriteStartElement ("one");
448 xtw.WriteAttributeString ("xmlns", "foo", null, "http://abc.def");
449 xtw.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl");
450 AssertEquals ("foo", xtw.LookupPrefix ("http://abc.def"));
451 AssertEquals ("bar", xtw.LookupPrefix ("http://ghi.jkl"));
452 xtw.WriteEndElement ();
454 xtw.WriteStartElement ("two");
455 xtw.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr");
456 xtw.WriteString("quux");
457 AssertEquals ("baz", xtw.LookupPrefix ("http://mno.pqr"));
458 AssertNull (xtw.LookupPrefix ("http://abc.def"));
459 AssertNull (xtw.LookupPrefix ("http://ghi.jkl"));
461 AssertNull (xtw.LookupPrefix ("http://bogus"));
464 [Test]
465 public void NamespacesAttributesPassingInNamespaces ()
467 xtw.Namespaces = false;
468 xtw.WriteStartElement ("foo");
470 // These shouldn't throw any exceptions since they don't pass in
471 // a namespace.
472 xtw.WriteAttributeString ("bar", "baz");
473 xtw.WriteAttributeString ("", "a", "", "b");
474 xtw.WriteAttributeString (null, "c", "", "d");
475 xtw.WriteAttributeString ("", "e", null, "f");
476 xtw.WriteAttributeString (null, "g", null, "h");
478 AssertEquals ("<foo bar='baz' a='b' c='d' e='f' g='h'", StringWriterText);
480 // These should throw ArgumentException because they pass in a
481 // namespace when Namespaces = false.
484 [Test]
485 public void NamespacesElementsPassingInNamespaces ()
487 xtw.Namespaces = false;
489 // These shouldn't throw any exceptions since they don't pass in
490 // a namespace.
491 xtw.WriteElementString ("foo", "bar");
492 xtw.WriteStartElement ("baz");
493 xtw.WriteStartElement ("quux", "");
494 xtw.WriteStartElement ("quuux", null);
495 xtw.WriteStartElement (null, "a", null);
496 xtw.WriteStartElement (null, "b", "");
497 xtw.WriteStartElement ("", "c", null);
498 xtw.WriteStartElement ("", "d", "");
500 AssertEquals ("<foo>bar</foo><baz><quux><quuux><a><b><c><d", StringWriterText);
502 // These should throw ArgumentException because they pass in a
503 // namespace when Namespaces = false.
504 try {
505 xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
506 Fail ("Expected an ArgumentException.");
507 } catch (ArgumentException) {}
509 try {
510 xtw.WriteStartElement ("foo", "http://netsack.com/");
511 Fail ("Expected an ArgumentException.");
512 } catch (ArgumentException) {}
514 try {
515 xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
516 Fail ("Expected an ArgumentException.");
517 } catch (ArgumentException) {}
519 try {
520 xtw.WriteStartElement ("foo", "bar", null);
521 Fail ("Expected an ArgumentException.");
522 } catch (ArgumentException) {}
524 try {
525 xtw.WriteStartElement ("foo", "bar", "");
526 Fail ("Expected an ArgumentException.");
527 } catch (ArgumentException) {}
529 try {
530 xtw.WriteStartElement ("foo", "", "");
531 Fail ("Expected an ArgumentException.");
532 } catch (ArgumentException) {}
535 [Test]
536 public void NamespacesNoNamespaceClearsDefaultNamespace ()
538 xtw.WriteStartElement(String.Empty, "foo", "http://netsack.com/");
539 xtw.WriteStartElement(String.Empty, "bar", String.Empty);
540 xtw.WriteElementString("baz", String.Empty, String.Empty);
541 xtw.WriteEndElement();
542 xtw.WriteEndElement();
543 AssertEquals ("XmlTextWriter is incorrectly outputting namespaces.",
544 "<foo xmlns='http://netsack.com/'><bar xmlns=''><baz /></bar></foo>", StringWriterText);
547 [Test]
548 public void NamespacesPrefix ()
550 xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
551 xtw.WriteStartElement ("foo", "baz", "http://netsack.com/");
552 xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
553 xtw.WriteEndElement ();
554 xtw.WriteEndElement ();
555 AssertEquals ("XmlTextWriter is incorrectly outputting prefixes.",
556 "<foo:bar xmlns:foo='http://netsack.com/'><foo:baz><foo:qux /></foo:baz></foo:bar>", StringWriterText);
559 [Test]
560 [ExpectedException (typeof (ArgumentException))]
561 public void NamespacesPrefixWithEmptyAndNullNamespaceEmpty ()
563 xtw.WriteStartElement ("foo", "bar", "");
566 [Test]
567 [ExpectedException (typeof (ArgumentException))]
568 public void NamespacesPrefixWithEmptyAndNullNamespaceNull ()
570 xtw.WriteStartElement ("foo", "bar", null);
573 [Test]
574 public void NamespacesSettingWhenWriteStateNotStart ()
576 xtw.WriteStartElement ("foo");
577 try
579 xtw.Namespaces = false;
580 Fail ("Expected an InvalidOperationException.");
582 catch (InvalidOperationException) {}
583 AssertEquals (true, xtw.Namespaces);
586 [Test]
587 public void ProcessingInstructionValid ()
589 xtw.WriteProcessingInstruction("foo", "bar");
590 AssertEquals ("WriteProcessingInstruction had incorrect output.", "<?foo bar?>", StringWriterText);
593 [Test]
594 public void ProcessingInstructionInvalid ()
596 try
598 xtw.WriteProcessingInstruction("fo?>o", "bar");
599 Fail("Should have thrown an ArgumentException.");
601 catch (ArgumentException) { }
603 try
605 xtw.WriteProcessingInstruction("foo", "ba?>r");
606 Fail("Should have thrown an ArgumentException.");
608 catch (ArgumentException) { }
610 try
612 xtw.WriteProcessingInstruction("", "bar");
613 Fail("Should have thrown an ArgumentException.");
615 catch (ArgumentException) { }
617 try
619 xtw.WriteProcessingInstruction(null, "bar");
620 Fail("Should have thrown an ArgumentException.");
622 catch (ArgumentException) { }
625 [Test]
626 public void QuoteCharDoubleQuote ()
628 xtw.QuoteChar = '"';
630 // version, encoding, standalone
631 xtw.WriteStartDocument (true);
633 // namespace declaration
634 xtw.WriteElementString ("foo", "http://netsack.com", "bar");
636 AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?><foo xmlns=\"http://netsack.com\">bar</foo>", StringWriterText);
641 [Test]
642 [ExpectedException (typeof (ArgumentException))]
643 public void QuoteCharInvalid ()
645 xtw.QuoteChar = 'x';
648 [Test]
649 public void WriteBase64 ()
651 UTF8Encoding encoding = new UTF8Encoding();
652 byte[] fooBar = encoding.GetBytes("foobar");
653 xtw.WriteBase64 (fooBar, 0, 6);
654 AssertEquals("Zm9vYmFy", StringWriterText);
656 try {
657 xtw.WriteBase64 (fooBar, 3, 6);
658 Fail ("Expected an Argument Exception to be thrown.");
659 } catch (ArgumentException) {}
661 try {
662 xtw.WriteBase64 (fooBar, -1, 6);
663 Fail ("Expected an Argument Exception to be thrown.");
664 } catch (ArgumentOutOfRangeException) {}
666 try {
667 xtw.WriteBase64 (fooBar, 3, -1);
668 Fail ("Expected an Argument Exception to be thrown.");
669 } catch (ArgumentOutOfRangeException) {}
671 try {
672 xtw.WriteBase64 (null, 0, 6);
673 Fail ("Expected an Argument Exception to be thrown.");
674 } catch (ArgumentNullException) {}
677 [Test]
678 public void WriteBinHex ()
680 byte [] bytes = new byte [] {4,14,34, 54,94,114, 134,194,255, 0,5};
681 xtw.WriteBinHex (bytes, 0, 11);
682 AssertEquals ("040E22365E7286C2FF0005", StringWriterText);
685 [Test]
686 public void WriteCharEntity ()
688 xtw.WriteCharEntity ('a');
689 AssertEquals ("&#x61;", StringWriterText);
691 xtw.WriteCharEntity ('A');
692 AssertEquals ("&#x61;&#x41;", StringWriterText);
694 xtw.WriteCharEntity ('1');
695 AssertEquals ("&#x61;&#x41;&#x31;", StringWriterText);
697 xtw.WriteCharEntity ('K');
698 AssertEquals ("&#x61;&#x41;&#x31;&#x4B;", StringWriterText);
700 try {
701 xtw.WriteCharEntity ((char)0xd800);
702 } catch (ArgumentException) {}
705 [Test]
706 [ExpectedException (typeof (InvalidOperationException))]
707 public void WriteEndAttribute ()
709 xtw.WriteEndAttribute ();
712 [Test]
713 public void WriteEndDocument ()
715 try {
716 xtw.WriteEndDocument ();
717 Fail ("Expected an ArgumentException.");
718 } catch (ArgumentException) {}
720 xtw.WriteStartDocument ();
722 try
724 xtw.WriteEndDocument ();
725 Fail ("Expected an ArgumentException.");
727 catch (ArgumentException) {}
729 xtw.WriteStartElement ("foo");
730 xtw.WriteStartAttribute ("bar", null);
731 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='", StringWriterText);
733 xtw.WriteEndDocument ();
734 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", StringWriterText);
735 AssertEquals (WriteState.Start, xtw.WriteState);
738 [Test]
739 public void WriteEndElement ()
741 try {
742 xtw.WriteEndElement ();
743 Fail ("Should have thrown an InvalidOperationException.");
744 } catch (InvalidOperationException) {
745 // Don't rely on English message assertion.
746 // It is enough to check an exception occurs.
747 // AssertEquals ("Exception message is incorrect.", "There was no XML start tag open.", e.Message);
750 xtw.WriteStartElement ("foo");
751 xtw.WriteEndElement ();
752 AssertEquals ("<foo />", StringWriterText);
754 xtw.WriteStartElement ("bar");
755 xtw.WriteStartAttribute ("baz", null);
756 xtw.WriteEndElement ();
757 AssertEquals ("<foo /><bar baz='' />", StringWriterText);
760 [Test]
761 public void FullEndElement ()
763 xtw.WriteStartElement ("foo");
764 xtw.WriteFullEndElement ();
765 AssertEquals ("<foo></foo>", StringWriterText);
767 xtw.WriteStartElement ("bar");
768 xtw.WriteAttributeString ("foo", "bar");
769 xtw.WriteFullEndElement ();
770 AssertEquals ("<foo></foo><bar foo='bar'></bar>", StringWriterText);
772 xtw.WriteStartElement ("baz");
773 xtw.WriteStartAttribute ("bar", null);
774 xtw.WriteFullEndElement ();
775 AssertEquals ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", StringWriterText);
778 [Test]
779 public void WriteQualifiedName ()
781 xtw.WriteStartElement (null, "test", null);
782 xtw.WriteAttributeString ("xmlns", "me", null, "http://localhost/");
783 xtw.WriteQualifiedName ("bob", "http://localhost/");
784 xtw.WriteEndElement ();
786 AssertEquals ("<test xmlns:me='http://localhost/'>me:bob</test>", StringWriterText);
789 [Test]
790 public void WriteRaw ()
792 xtw.WriteRaw("&<>\"'");
793 AssertEquals ("&<>\"'", StringWriterText);
795 xtw.WriteRaw(null);
796 AssertEquals ("&<>\"'", StringWriterText);
798 xtw.WriteRaw("");
799 AssertEquals ("&<>\"'", StringWriterText);
802 [Test]
803 public void WriteRawInvalidInAttribute ()
805 xtw.WriteStartElement ("foo");
806 xtw.WriteStartAttribute ("bar", null);
807 xtw.WriteRaw ("&<>\"'");
808 xtw.WriteEndAttribute ();
809 xtw.WriteEndElement ();
810 AssertEquals ("<foo bar='&<>\"'' />", StringWriterText);
813 [Test]
814 public void WriteStateTest ()
816 AssertEquals (WriteState.Start, xtw.WriteState);
817 xtw.WriteStartDocument ();
818 AssertEquals (WriteState.Prolog, xtw.WriteState);
819 xtw.WriteStartElement ("root");
820 AssertEquals (WriteState.Element, xtw.WriteState);
821 xtw.WriteElementString ("foo", "bar");
822 AssertEquals (WriteState.Content, xtw.WriteState);
823 xtw.Close ();
824 AssertEquals (WriteState.Closed, xtw.WriteState);
827 [Test]
828 public void WriteString ()
830 xtw.WriteStartDocument ();
831 try {
832 xtw.WriteString("foo");
833 } catch (InvalidOperationException) {}
835 // Testing attribute values
837 xtw.WriteStartElement ("foo");
838 xtw.WriteAttributeString ("bar", "&<>");
839 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='&amp;&lt;&gt;'", StringWriterText);
842 [Test]
843 public void WriteAttributeStringSingleQuoteChar()
845 // When QuoteChar is single quote then replaces single quotes within attributes
846 // but not double quotes.
847 xtw.WriteStartElement ("foo");
848 xtw.WriteAttributeString ("bar", "\"baz\"");
849 xtw.WriteAttributeString ("quux", "'baz'");
850 AssertEquals ("<foo bar='\"baz\"' quux='&apos;baz&apos;'", StringWriterText);
853 [Test]
854 public void WriteAttributeStringDoubleQuoteChar()
856 // When QuoteChar is double quote then replaces double quotes within attributes
857 // but not single quotes.
858 xtw.QuoteChar = '"';
859 xtw.WriteStartElement ("foo");
860 xtw.WriteAttributeString ("bar", "\"baz\"");
861 xtw.WriteAttributeString ("quux", "'baz'");
862 AssertEquals ("<foo bar=\"&quot;baz&quot;\" quux=\"'baz'\"", StringWriterText);
865 [Test]
866 public void WriteStringWithEntities()
868 // Testing element values
869 xtw.QuoteChar = '\'';
870 xtw.WriteElementString ("foo", "&<>\"'");
871 AssertEquals ("<foo>&amp;&lt;&gt;\"'</foo>", StringWriterText);
874 [Test]
875 public void XmlLang ()
877 AssertNull (xtw.XmlLang);
879 xtw.WriteStartElement ("foo");
880 xtw.WriteAttributeString ("xml", "lang", null, "langfoo");
881 AssertEquals ("langfoo", xtw.XmlLang);
882 AssertEquals ("<foo xml:lang='langfoo'", StringWriterText);
884 xtw.WriteAttributeString ("boo", "yah");
885 AssertEquals ("langfoo", xtw.XmlLang);
886 AssertEquals ("<foo xml:lang='langfoo' boo='yah'", StringWriterText);
888 xtw.WriteElementString("bar", "baz");
889 AssertEquals ("langfoo", xtw.XmlLang);
890 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", StringWriterText);
892 xtw.WriteString("baz");
893 AssertEquals ("langfoo", xtw.XmlLang);
894 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", StringWriterText);
896 xtw.WriteStartElement ("quux");
897 xtw.WriteStartAttribute ("xml", "lang", null);
898 AssertEquals ("langfoo", xtw.XmlLang);
899 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText);
901 xtw.WriteString("langbar");
902 AssertEquals ("langfoo", xtw.XmlLang);
903 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText);
905 xtw.WriteEndAttribute ();
906 AssertEquals ("langbar", xtw.XmlLang);
907 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'", StringWriterText);
909 // check if xml:lang repeats output even if same as current scope.
910 xtw.WriteStartElement ("joe");
911 xtw.WriteAttributeString ("xml", "lang", null, "langbar");
912 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'", StringWriterText);
915 xtw.WriteElementString ("quuux", "squonk");
916 AssertEquals ("langbar", xtw.XmlLang);
917 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux>", StringWriterText);
919 xtw.WriteEndElement ();
920 xtw.WriteEndElement ();
921 AssertEquals ("langfoo", xtw.XmlLang);
922 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux>", StringWriterText);
924 xtw.WriteEndElement ();
925 AssertNull (xtw.XmlLang);
926 AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux></foo>", StringWriterText);
928 xtw.Close ();
929 AssertNull (xtw.XmlLang);
932 // TODO: test operational aspects
933 [Test]
934 public void XmlSpaceTest ()
936 xtw.WriteStartElement ("foo");
937 AssertEquals (XmlSpace.None, xtw.XmlSpace);
939 xtw.WriteStartElement ("bar");
940 xtw.WriteAttributeString ("xml", "space", null, "preserve");
941 AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
942 AssertEquals ("<foo><bar xml:space='preserve'", StringWriterText);
944 xtw.WriteStartElement ("baz");
945 xtw.WriteAttributeString ("xml", "space", null, "preserve");
946 AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
947 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'", StringWriterText);
949 xtw.WriteStartElement ("quux");
950 xtw.WriteStartAttribute ("xml", "space", null);
951 AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
952 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText);
954 xtw.WriteString ("default");
955 AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
956 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText);
958 xtw.WriteEndAttribute ();
959 AssertEquals (XmlSpace.Default, xtw.XmlSpace);
960 AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='default'", StringWriterText);
962 xtw.WriteEndElement ();
963 AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
964 xtw.WriteEndElement ();
965 AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
966 xtw.WriteEndElement ();
967 AssertEquals (XmlSpace.None, xtw.XmlSpace);
969 xtw.WriteStartElement ("quux");
970 try {
971 xtw.WriteAttributeString ("xml", "space", null, "bubba");
972 } catch (ArgumentException) {}
974 try {
975 xtw.WriteAttributeString ("xml", "space", null, "PRESERVE");
976 } catch (ArgumentException) {}
978 try {
979 xtw.WriteAttributeString ("xml", "space", null, "Preserve");
980 } catch (ArgumentException) {}
982 try {
983 xtw.WriteAttributeString ("xml", "space", null, "Default");
984 } catch (ArgumentException) {}
986 try {
987 xtw.WriteWhitespace ("x");
988 } catch (ArgumentException) { }
991 [Test]
992 public void XmlSpaceRaw ()
994 xtw.WriteStartElement ("foo");
995 xtw.WriteStartAttribute ("xml", "space", null);
996 AssertEquals (XmlSpace.None, xtw.XmlSpace);
997 AssertEquals ("<foo xml:space='", StringWriterText);
999 xtw.WriteString ("default");
1000 AssertEquals (XmlSpace.None, xtw.XmlSpace);
1001 AssertEquals ("<foo xml:space='", StringWriterText);
1003 xtw.WriteEndAttribute ();
1004 AssertEquals (XmlSpace.Default, xtw.XmlSpace);
1005 AssertEquals ("<foo xml:space='default'", StringWriterText);
1008 [Test]
1009 public void WriteAttributes ()
1011 XmlDocument doc = new XmlDocument();
1012 StringWriter sw = new StringWriter();
1013 XmlWriter wr = new XmlTextWriter(sw);
1014 StringBuilder sb = sw.GetStringBuilder();
1015 XmlParserContext ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
1016 XmlTextReader xtr = new XmlTextReader("<?xml version='1.0' encoding='utf-8' standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
1018 xtr.Read(); // read XMLDecl
1019 wr.WriteAttributes(xtr, false);
1020 // This method don't always have to take this double-quoted style...
1021 AssertEquals("#WriteAttributes.XmlDecl.1", "version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"", sw.ToString().Trim());
1023 sb.Remove(0, sb.Length); // init
1024 ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
1025 xtr = new XmlTextReader("<?xml version='1.0' standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
1026 xtr.Read(); // read XMLDecl
1027 AssertEquals (XmlNodeType.XmlDeclaration, xtr.NodeType);
1028 sw = new StringWriter ();
1029 wr = new XmlTextWriter (sw);
1031 // This block raises an error on MS.NET 1.0.
1032 wr.WriteAttributes(xtr, false);
1033 // This method don't always have to take this double-quoted style...
1034 AssertEquals("#WriteAttributes.XmlDecl.2", "version=\"1.0\" standalone=\"no\"", sw.ToString().Trim());
1036 sw = new StringWriter ();
1037 wr = new XmlTextWriter (sw);
1038 sb.Remove(0, sb.Length); // init
1040 xtr.Read(); // read root
1041 AssertEquals (XmlNodeType.Element, xtr.NodeType);
1042 wr.WriteStartElement(xtr.LocalName, xtr.NamespaceURI);
1043 wr.WriteAttributes(xtr, false);
1044 wr.WriteEndElement();
1045 wr.Close();
1046 // This method don't always have to take this double-quoted style...
1047 AssertEquals("#WriteAttributes.Element", "<root a1=\"A\" b2=\"B\" c3=\"C\" />", sw.ToString().Trim());
1048 xtr.Close ();
1051 [Test]
1052 public void WriteWhitespace ()
1054 xtw.WriteStartElement ("a");
1055 xtw.WriteWhitespace ("\n\t");
1056 xtw.WriteStartElement ("b");
1057 xtw.WriteWhitespace ("\n\t");
1058 xtw.WriteEndElement ();
1059 xtw.WriteWhitespace ("\n");
1060 xtw.WriteEndElement ();
1061 xtw.WriteWhitespace ("\n");
1062 xtw.Flush ();
1063 AssertEquals ("<a>\n\t<b>\n\t</b>\n</a>\n", StringWriterText);
1066 [Test]
1067 public void FlushDoesntCloseTag ()
1069 xtw.WriteStartElement ("foo");
1070 xtw.WriteAttributeString ("bar", "baz");
1071 xtw.Flush ();
1072 AssertEquals ("<foo bar='baz'", StringWriterText);
1075 [Test]
1076 public void WriteWhitespaceClosesTag ()
1078 xtw.WriteStartElement ("foo");
1079 xtw.WriteAttributeString ("bar", "baz");
1080 xtw.WriteWhitespace (" ");
1081 AssertEquals ("<foo bar='baz'> ", StringWriterText);
1084 [Test]
1085 public void DontOutputMultipleXmlns ()
1087 XmlDocument doc = new XmlDocument();
1088 doc.LoadXml("<a xmlns:dt=\"b\" dt:dt=\"c\"/>");
1089 XmlDocument doc2 = new XmlDocument();
1090 doc2.LoadXml(doc.InnerXml);
1091 AssertEquals ("<a xmlns:dt=\"b\" dt:dt=\"c\" />",
1092 doc2.OuterXml);
1095 [Test]
1096 public void DontOutputNonDeclaredXmlns ()
1098 string xml = "<x:a foo='foo' xmlns:x='urn:foo'><b /></x:a>";
1099 XmlDocument doc = new XmlDocument();
1100 doc.LoadXml(xml);
1101 XmlDocument doc2 = new XmlDocument();
1102 doc2.LoadXml(doc.InnerXml);
1103 AssertEquals (xml.Replace ('\'', '"'), doc2.OuterXml);
1106 [Test]
1107 public void DontOutputRemovalDefaultNSDeclaration ()
1109 xtw.WriteStartDocument ();
1110 xtw.WriteStartElement ("foo");
1111 xtw.WriteAttributeString ("xmlns", "probe");
1112 AssertEquals (String.Empty, xtw.LookupPrefix ("probe"));
1113 xtw.WriteStartElement ("b");
1114 AssertEquals (String.Empty, xtw.LookupPrefix ("probe"));
1115 xtw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1116 xtw.WriteEndElement (); // b2
1117 xtw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1118 xtw.WriteEndElement (); // b2
1119 xtw.WriteEndElement (); // b
1120 xtw.WriteEndElement (); // foo
1121 xtw.WriteEndDocument ();
1122 xtw.Close ();
1124 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 xmlns='' /></b></foo>", StringWriterText);
1127 [Test]
1128 public void DontOutputRemovalDefaultNSDeclaration2 ()
1130 xtw.WriteStartDocument ();
1131 // IMPORTANT DIFFERENCE!! ns = "", not null
1132 xtw.WriteStartElement ("foo", "");
1133 xtw.WriteAttributeString ("xmlns", "probe");
1134 AssertNull (xtw.LookupPrefix ("probe"));
1135 xtw.WriteStartElement ("b");
1136 AssertNull (xtw.LookupPrefix ("probe"));
1137 xtw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1138 xtw.WriteEndElement (); // b2
1139 xtw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1140 xtw.WriteEndElement (); // b2
1141 xtw.WriteEndElement (); // b
1142 xtw.WriteEndElement (); // foo
1143 xtw.WriteEndDocument ();
1144 xtw.Close ();
1146 AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 /></b></foo>", StringWriterText);
1149 [Test]
1150 public void DoOutputRemovalDefaultNSDeclaration ()
1152 xtw.WriteStartElement ("docelem", "a-namespace");
1154 XmlDocument doc = new XmlDocument ();
1155 doc.CreateElement ("hola").WriteTo (xtw);
1156 // This means, WriteTo never passes null NamespaceURI argument to XmlWriter.
1157 xtw.WriteEndElement ();
1158 xtw.Close ();
1160 AssertEquals ("<docelem xmlns='a-namespace'><hola xmlns='' /></docelem>", StringWriterText);
1163 [Test]
1164 public void WriteAttributeTakePrecedenceOnXmlns ()
1166 xtw.WriteStartElement ("root", "urn:foo");
1167 xtw.WriteAttributeString ("xmlns", "urn:bar");
1168 xtw.WriteEndElement ();
1169 xtw.Close ();
1170 AssertEquals ("<root xmlns='urn:bar' />", StringWriterText);
1173 [Test]
1174 [ExpectedException (typeof (ArgumentException))]
1175 public void LookupPrefixNull ()
1177 xtw.LookupPrefix (null);
1180 [Test]
1181 [ExpectedException (typeof (ArgumentException))]
1182 public void LookupPrefixEmpty ()
1184 xtw.LookupPrefix (String.Empty);
1187 [Test]
1188 public void LookupPrefixIgnoresXmlnsAttribute ()
1190 AssertNull (xtw.LookupPrefix ("urn:foo"));
1191 xtw.WriteStartElement ("root");
1192 AssertNull (xtw.LookupPrefix ("urn:foo"));
1193 xtw.WriteAttributeString ("xmlns", "urn:foo");
1194 // Surprisingly to say, it is ignored!!
1195 AssertEquals (String.Empty, xtw.LookupPrefix ("urn:foo"));
1196 xtw.WriteStartElement ("hoge");
1197 // (still after flushing previous start element.)
1198 AssertEquals (String.Empty, xtw.LookupPrefix ("urn:foo"));
1199 xtw.WriteStartElement ("fuga", "urn:foo");
1200 // Is this testing on the correct way? Yes, here it is.
1201 AssertEquals (String.Empty, xtw.LookupPrefix ("urn:foo"));
1204 [Test]
1205 public void WriteInvalidNames ()
1207 xtw.WriteStartElement ("foo<>");
1208 xtw.WriteAttributeString ("ho<>ge", "value");
1211 [Test]
1212 [ExpectedException (typeof (ArgumentException))]
1213 public void AttributeWriteStartAttributePrefixWithoutNS ()
1215 xtw.WriteStartAttribute ("some", "foo", null);
1218 [Test]
1219 public void AttributeWriteStartAttributeXmlnsNullNS ()
1221 xtw.WriteStartAttribute ("xmlns", "foo", null);
1224 [Test]
1225 [ExpectedException (typeof (ArgumentException))]
1226 public void AttributeWriteEndAttributeXmlnsNullNs ()
1228 // Compare with the test AttributeWriteStartAttributeXmlnsNullNS().
1229 xtw.WriteStartAttribute ("xmlns", "foo", null);
1230 xtw.WriteEndAttribute ();
1233 [Test]
1234 [ExpectedException (typeof (ArgumentException))]
1235 public void AttributeWriteStartAttributePrefixXmlnsNonW3CNS ()
1237 xtw.WriteStartAttribute ("xmlns", "foo", "urn:foo");
1240 [Test]
1241 [ExpectedException (typeof (ArgumentException))]
1242 public void AttributeWriteStartAttributeLocalXmlnsNonW3CNS ()
1244 xtw.WriteStartAttribute ("", "xmlns", "urn:foo");
1247 [Test]
1248 public void WriteRawProceedToProlog ()
1250 XmlTextWriter xtw = new XmlTextWriter (new StringWriter ());
1251 xtw.WriteRaw ("");
1252 AssertEquals (WriteState.Prolog, xtw.WriteState);
1255 [Test]
1256 public void Indent ()
1258 XmlDocument doc = new XmlDocument ();
1259 doc.LoadXml ("<root><test>test<foo></foo>string</test><test>string</test></root>");
1260 StringWriter sw = new StringWriter ();
1261 sw.NewLine = "_";
1262 XmlTextWriter xtw = new XmlTextWriter (sw);
1263 xtw.Formatting = Formatting.Indented;
1264 doc.WriteContentTo (xtw);
1265 AssertEquals (@"<root>_ <test>test<foo></foo>string</test>_ <test>string</test>_</root>", sw.ToString ());
1268 [Test]
1269 public void CloseTwice ()
1271 StringWriter sw = new StringWriter ();
1272 XmlTextWriter writer = new XmlTextWriter (sw);
1273 writer.Close ();
1274 // should not result in an exception
1275 writer.Close ();