* XmlSerializerTests.cs: Added some identifiers for AssertEquals.
[mono.git] / mcs / class / System.XML / Test / System.Xml / XmlTextWriterTests.cs
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
10 //
11
12 using System;
13 using System.IO;
14 using System.Text;
15 using System.Xml;
16
17 using NUnit.Framework;
18
19 namespace MonoTests.System.Xml
20 {
21         [TestFixture]
22         public class XmlTextWriterTests : Assertion
23         {
24                 StringWriter sw;
25                 XmlTextWriter xtw;
26
27                 [SetUp]
28                 public void GetReady ()
29                 {
30                         sw = new StringWriter ();
31                         xtw = new XmlTextWriter (sw);
32                         xtw.QuoteChar = '\'';
33                 }
34
35                 private string StringWriterText 
36                 {
37                         get { return sw.GetStringBuilder ().ToString (); }
38                 }
39
40                 [Test]
41                 public void AttributeNamespacesNonNamespaceAttributeBefore ()
42                 {
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);
47                 }
48
49                 [Test]
50                 public void AttributeNamespacesNonNamespaceAttributeAfter ()
51                 {
52                         xtw.WriteStartElement ("foo");
53
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);
57                 }
58
59                 [Test]
60                 public void AttributeNamespacesThreeParamWithNullInNamespaceParam ()
61                 {
62                         xtw.WriteAttributeString ("xmlns", null, "http://abc.def");
63                         AssertEquals ("xmlns='http://abc.def'", StringWriterText);
64                 }
65
66                 [Test]
67                 public void AttributeNamespacesThreeParamWithTextInNamespaceParam ()
68                 {
69                         try 
70                         {
71                                 xtw.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
72                         } 
73                         catch (ArgumentException) {}
74                 }
75
76                 [Test]
77                 public void AttributeNamespacesWithNullInNamespaceParam ()
78                 {
79                         xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
80                         AssertEquals ("xmlns:abc='http://abc.def'", StringWriterText);
81                 }
82
83                 [Test]
84                 public void AttributeNamespacesWithTextInNamespaceParam ()
85                 {
86                         try {
87                                 xtw.WriteAttributeString ("xmlns", "abc", "http://somenamespace.com", "http://abc.def");
88                         } catch (ArgumentException) {}
89                 }
90
91                 [Test]
92                 public void AttributeNamespacesXmlnsXmlns ()
93                 {
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.");
100                         }
101                         catch (ArgumentException) {}
102                         xtw.WriteAttributeString ("", "xmlns", null, "http://abc.def");
103                 }
104
105                 [Test]
106                 public void AttributeWriteAttributeString ()
107                 {
108                         xtw.WriteStartElement ("foo");
109
110                         xtw.WriteAttributeString ("foo", "bar");
111                         AssertEquals ("<foo foo='bar'", StringWriterText);
112
113                         xtw.WriteAttributeString ("bar", "");
114                         AssertEquals ("<foo foo='bar' bar=''", StringWriterText);
115
116                         xtw.WriteAttributeString ("baz", null);
117                         AssertEquals ("<foo foo='bar' bar='' baz=''", StringWriterText);
118
119                         xtw.WriteAttributeString ("hoge", "a\nb");
120                         AssertEquals ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b'", StringWriterText);
121
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);
124
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) {
132                         }
133
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) {
141                         }
142                 }
143
144                 [Test]
145                 [ExpectedException (typeof (InvalidOperationException))]
146                 public void AttributeWriteAttributeStringNotInsideOpenStartElement ()
147                 {
148                         xtw.WriteStartElement ("foo");
149                         xtw.WriteString ("bar");
150                         
151                         xtw.WriteAttributeString ("baz", "quux");
152                 }
153
154                 [Test]
155                 public void AttributeWriteAttributeStringWithoutParentElement ()
156                 {
157                         xtw.WriteAttributeString ("foo", "bar");
158                         AssertEquals ("foo='bar'", StringWriterText);
159
160                         xtw.WriteAttributeString ("baz", "quux");
161                         AssertEquals ("foo='bar' baz='quux'", StringWriterText);
162                 }
163
164                 [Test]
165                 public void CDataValid ()
166                 {
167                         xtw.WriteCData ("foo");
168                         AssertEquals ("WriteCData had incorrect output.", "<![CDATA[foo]]>", StringWriterText);
169                 }
170
171                 [Test]
172                 [ExpectedException (typeof (ArgumentException))]
173                 public void CDataInvalid ()
174                 {
175                         xtw.WriteCData("foo]]>bar");
176                 }
177                 
178                 [Test]
179                 public void CloseOpenElements ()
180                 {
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);
186                 }
187
188                 [Test]
189                 public void CloseWriteAfter ()
190                 {
191                         xtw.WriteElementString ("foo", "bar");
192                         xtw.Close ();
193
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.
197
198                         try {
199                                 xtw.WriteCData ("foo");
200                                 Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
201                         } 
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);
206                         }
207
208                         try {
209                                 xtw.WriteComment ("foo");
210                                 Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
211                         } 
212                         catch (InvalidOperationException) {
213 //                              AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
214                         }
215
216                         try {
217                                 xtw.WriteProcessingInstruction ("foo", "bar");
218                                 Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
219                         } 
220                         catch (InvalidOperationException) {
221 //                              AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
222                         }
223
224                         try {
225                                 xtw.WriteStartElement ("foo", "bar", "baz");
226                                 Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
227                         } 
228                         catch (InvalidOperationException) {
229 //                              AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
230                         }
231
232                         try 
233                         {
234                                 xtw.WriteAttributeString ("foo", "bar");
235                                 Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
236                         } 
237                         catch (InvalidOperationException) 
238                         {
239 //                              AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
240                         }
241
242                         try {
243                                 xtw.WriteString ("foo");
244                                 Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
245                         } 
246                         catch (InvalidOperationException) {
247 //                              AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
248                         }
249                 }
250
251                 [Test]
252                 public void CommentValid ()
253                 {
254                         xtw.WriteComment ("foo");
255                         AssertEquals ("WriteComment had incorrect output.", "<!--foo-->", StringWriterText);
256                 }
257
258                 [Test]
259                 public void CommentInvalid ()
260                 {
261                         try {
262                                 xtw.WriteComment("foo-");
263                                 Fail("Should have thrown an ArgumentException.");
264                         } 
265                         catch (ArgumentException) { }
266
267                         try {
268                                 xtw.WriteComment("foo-->bar");
269                                 Fail("Should have thrown an ArgumentException.");
270                         } 
271                         catch (ArgumentException) { }
272                 }
273
274                 [Test]
275                 public void ConstructorsAndBaseStream ()
276                 {
277                         Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (null, this.xtw.BaseStream));
278
279                         MemoryStream ms;
280                         StreamReader sr;
281                         XmlTextWriter xtw;
282
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));
293
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 ());
301
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 ());
309
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 ());
317
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));
326                 }
327
328                 [Test]
329                 public void DocumentStart ()
330                 {
331                         xtw.WriteStartDocument ();
332                         AssertEquals ("XmlDeclaration is incorrect.", "<?xml version='1.0' encoding='utf-16'?>", StringWriterText);
333
334                         try 
335                         {
336                                 xtw.WriteStartDocument ();
337                                 Fail("Should have thrown an InvalidOperationException.");
338                         } 
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);
344                         }
345
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);
350
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);
355                 }
356
357                 [Test]
358                 public void ElementAndAttributeSameXmlns ()
359                 {
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);
364                 }
365
366                 [Test]
367                 public void ElementXmlnsNeedEscape ()
368                 {
369                         xtw.WriteStartElement ("test", "foo", "'");
370                         xtw.WriteEndElement ();
371                         // MS.NET fails this case.
372                         AssertEquals ("<test:foo xmlns:test='&apos;' />", StringWriterText);
373                 }
374
375                 [Test]
376                 public void ElementEmpty ()
377                 {
378                         xtw.WriteStartElement ("foo");
379                         xtw.WriteEndElement ();
380                         AssertEquals ("Incorrect output.", "<foo />", StringWriterText);
381                 }
382
383                 [Test]
384                 public void ElementWriteElementString ()
385                 {
386                         xtw.WriteElementString ("foo", "bar");
387                         AssertEquals ("WriteElementString has incorrect output.", "<foo>bar</foo>", StringWriterText);
388
389                         xtw.WriteElementString ("baz", "");
390                         AssertEquals ("<foo>bar</foo><baz />", StringWriterText);
391
392                         xtw.WriteElementString ("quux", null);
393                         AssertEquals ("<foo>bar</foo><baz /><quux />", StringWriterText);
394
395                         xtw.WriteElementString ("", "quuux");
396                         AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</>", StringWriterText);
397
398                         xtw.WriteElementString (null, "quuuux");
399                         AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", StringWriterText);
400                 }
401
402                 [Test]
403                 public void FormattingTest ()
404                 {
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);
411                 }
412
413                 [Test]
414                 public void FormattingInvalidXmlForFun ()
415                 {
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);
424                 }
425
426                 [Test]
427                 public void FormattingFromRemarks ()
428                 {
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);
440                 }
441
442                 [Test]
443                 public void LookupPrefix ()
444                 {
445                         xtw.WriteStartElement ("root");
446
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 ();
453
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"));
460
461                         AssertNull (xtw.LookupPrefix ("http://bogus"));
462                 }
463
464                 [Test]
465                 public void NamespacesAttributesPassingInNamespaces ()
466                 {
467                         xtw.Namespaces = false;
468                         xtw.WriteStartElement ("foo");
469
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");
477
478                         AssertEquals ("<foo bar='baz' a='b' c='d' e='f' g='h'", StringWriterText);
479
480                         // These should throw ArgumentException because they pass in a
481                         // namespace when Namespaces = false.
482                 }
483
484                 [Test]
485                 public void NamespacesElementsPassingInNamespaces ()
486                 {
487                         xtw.Namespaces = false;
488
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", "");
499
500                         AssertEquals ("<foo>bar</foo><baz><quux><quuux><a><b><c><d", StringWriterText);
501
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) {}
508
509                         try {
510                                 xtw.WriteStartElement ("foo", "http://netsack.com/");
511                                 Fail ("Expected an ArgumentException.");
512                         } catch (ArgumentException) {}
513
514                         try {
515                                 xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
516                                 Fail ("Expected an ArgumentException.");
517                         } catch (ArgumentException) {}
518
519                         try {
520                                 xtw.WriteStartElement ("foo", "bar", null);
521                                 Fail ("Expected an ArgumentException.");
522                         } catch (ArgumentException) {}
523
524                         try {
525                                 xtw.WriteStartElement ("foo", "bar", "");
526                                 Fail ("Expected an ArgumentException.");
527                         } catch (ArgumentException) {}
528
529                         try {
530                                 xtw.WriteStartElement ("foo", "", "");
531                                 Fail ("Expected an ArgumentException.");
532                         } catch (ArgumentException) {}
533                 }
534
535                 [Test]
536                 public void NamespacesNoNamespaceClearsDefaultNamespace ()
537                 {
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);
545                 }
546
547                 [Test]
548                 public void NamespacesPrefix ()
549                 {
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);
557                 }
558
559                 [Test]
560                 [ExpectedException (typeof (ArgumentException))]
561                 public void NamespacesPrefixWithEmptyAndNullNamespaceEmpty ()
562                 {
563                         xtw.WriteStartElement ("foo", "bar", "");
564                 }
565
566                 [Test]
567                 [ExpectedException (typeof (ArgumentException))]
568                 public void NamespacesPrefixWithEmptyAndNullNamespaceNull ()
569                 {
570                         xtw.WriteStartElement ("foo", "bar", null);
571                 }
572
573                 [Test]
574                 public void NamespacesSettingWhenWriteStateNotStart ()
575                 {
576                         xtw.WriteStartElement ("foo");
577                         try 
578                         {
579                                 xtw.Namespaces = false;
580                                 Fail ("Expected an InvalidOperationException.");
581                         } 
582                         catch (InvalidOperationException) {}
583                         AssertEquals (true, xtw.Namespaces);
584                 }
585
586                 [Test]
587                 public void ProcessingInstructionValid ()
588                 {
589                         xtw.WriteProcessingInstruction("foo", "bar");
590                         AssertEquals ("WriteProcessingInstruction had incorrect output.", "<?foo bar?>", StringWriterText);
591                 }
592
593                 [Test]
594                 public void ProcessingInstructionInvalid ()
595                 {
596                         try 
597                         {
598                                 xtw.WriteProcessingInstruction("fo?>o", "bar");
599                                 Fail("Should have thrown an ArgumentException.");
600                         } 
601                         catch (ArgumentException) { }
602
603                         try 
604                         {
605                                 xtw.WriteProcessingInstruction("foo", "ba?>r");
606                                 Fail("Should have thrown an ArgumentException.");
607                         } 
608                         catch (ArgumentException) { }
609
610                         try 
611                         {
612                                 xtw.WriteProcessingInstruction("", "bar");
613                                 Fail("Should have thrown an ArgumentException.");
614                         } 
615                         catch (ArgumentException) { }
616
617                         try 
618                         {
619                                 xtw.WriteProcessingInstruction(null, "bar");
620                                 Fail("Should have thrown an ArgumentException.");
621                         } 
622                         catch (ArgumentException) { }
623                 }
624
625                 [Test]
626                 public void QuoteCharDoubleQuote ()
627                 {
628                         xtw.QuoteChar = '"';
629
630                         // version, encoding, standalone
631                         xtw.WriteStartDocument (true);
632                         
633                         // namespace declaration
634                         xtw.WriteElementString ("foo", "http://netsack.com", "bar");
635
636                         AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?><foo xmlns=\"http://netsack.com\">bar</foo>", StringWriterText);
637
638
639                 }
640
641                 [Test]
642                 [ExpectedException (typeof (ArgumentException))]
643                 public void QuoteCharInvalid ()
644                 {
645                         xtw.QuoteChar = 'x';
646                 }
647
648                 [Test]
649                 public void WriteBase64 ()
650                 {
651                         UTF8Encoding encoding = new UTF8Encoding();
652                         byte[] fooBar = encoding.GetBytes("foobar");
653                         xtw.WriteBase64 (fooBar, 0, 6);
654                         AssertEquals("Zm9vYmFy", StringWriterText);
655
656                         try {
657                                 xtw.WriteBase64 (fooBar, 3, 6);
658                                 Fail ("Expected an Argument Exception to be thrown.");
659                         } catch (ArgumentException) {}
660
661                         try {
662                                 xtw.WriteBase64 (fooBar, -1, 6);
663                                 Fail ("Expected an Argument Exception to be thrown.");
664                         } catch (ArgumentOutOfRangeException) {}
665
666                         try {
667                                 xtw.WriteBase64 (fooBar, 3, -1);
668                                 Fail ("Expected an Argument Exception to be thrown.");
669                         } catch (ArgumentOutOfRangeException) {}
670
671                         try {
672                                 xtw.WriteBase64 (null, 0, 6);
673                                 Fail ("Expected an Argument Exception to be thrown.");
674                         } catch (ArgumentNullException) {}
675                 }
676
677                 [Test]
678                 public void WriteBinHex ()
679                 {
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);
683                 }
684
685                 [Test]
686                 public void WriteCharEntity ()
687                 {
688                         xtw.WriteCharEntity ('a');
689                         AssertEquals ("&#x61;", StringWriterText);
690
691                         xtw.WriteCharEntity ('A');
692                         AssertEquals ("&#x61;&#x41;", StringWriterText);
693
694                         xtw.WriteCharEntity ('1');
695                         AssertEquals ("&#x61;&#x41;&#x31;", StringWriterText);
696
697                         xtw.WriteCharEntity ('K');
698                         AssertEquals ("&#x61;&#x41;&#x31;&#x4B;", StringWriterText);
699
700                         try {
701                                 xtw.WriteCharEntity ((char)0xd800);
702                         } catch (ArgumentException) {}
703                 }
704
705                 [Test]
706                 [ExpectedException (typeof (InvalidOperationException))]
707                 public void WriteEndAttribute ()
708                 {
709                         xtw.WriteEndAttribute ();
710                 }
711
712                 [Test]
713                 public void WriteEndDocument ()
714                 {
715                         try {
716                                 xtw.WriteEndDocument ();
717                                 Fail ("Expected an ArgumentException.");
718                         } catch (ArgumentException) {}
719
720                         xtw.WriteStartDocument ();
721
722                         try 
723                         {
724                                 xtw.WriteEndDocument ();
725                                 Fail ("Expected an ArgumentException.");
726                         } 
727                         catch (ArgumentException) {}
728
729                         xtw.WriteStartElement ("foo");
730                         xtw.WriteStartAttribute ("bar", null);
731                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='", StringWriterText);
732
733                         xtw.WriteEndDocument ();
734                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", StringWriterText);
735                         AssertEquals (WriteState.Start, xtw.WriteState);
736                 }
737
738                 [Test]
739                 public void WriteEndElement ()
740                 {
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);
748                         }
749
750                         xtw.WriteStartElement ("foo");
751                         xtw.WriteEndElement ();
752                         AssertEquals ("<foo />", StringWriterText);
753
754                         xtw.WriteStartElement ("bar");
755                         xtw.WriteStartAttribute ("baz", null);
756                         xtw.WriteEndElement ();
757                         AssertEquals ("<foo /><bar baz='' />", StringWriterText);
758                 }
759
760                 [Test]
761                 public void FullEndElement ()
762                 {
763                         xtw.WriteStartElement ("foo");
764                         xtw.WriteFullEndElement ();
765                         AssertEquals ("<foo></foo>", StringWriterText);
766
767                         xtw.WriteStartElement ("bar");
768                         xtw.WriteAttributeString ("foo", "bar");
769                         xtw.WriteFullEndElement ();
770                         AssertEquals ("<foo></foo><bar foo='bar'></bar>", StringWriterText);
771
772                         xtw.WriteStartElement ("baz");
773                         xtw.WriteStartAttribute ("bar", null);
774                         xtw.WriteFullEndElement ();
775                         AssertEquals ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", StringWriterText);
776                 }
777
778                 [Test]
779                 public void WriteQualifiedName ()
780                 {
781                         xtw.WriteStartElement (null, "test", null);
782                         xtw.WriteAttributeString ("xmlns", "me", null, "http://localhost/");
783                         xtw.WriteQualifiedName ("bob", "http://localhost/");
784                         xtw.WriteEndElement ();
785
786                         AssertEquals ("<test xmlns:me='http://localhost/'>me:bob</test>", StringWriterText);
787                 }
788
789                 [Test]
790                 public void WriteRaw ()
791                 {
792                         xtw.WriteRaw("&<>\"'");
793                         AssertEquals ("&<>\"'", StringWriterText);
794
795                         xtw.WriteRaw(null);
796                         AssertEquals ("&<>\"'", StringWriterText);
797
798                         xtw.WriteRaw("");
799                         AssertEquals ("&<>\"'", StringWriterText);
800                 }
801
802                 [Test]
803                 public void WriteRawInvalidInAttribute ()
804                 {
805                         xtw.WriteStartElement ("foo");
806                         xtw.WriteStartAttribute ("bar", null);
807                         xtw.WriteRaw ("&<>\"'");
808                         xtw.WriteEndAttribute ();
809                         xtw.WriteEndElement ();
810                         AssertEquals ("<foo bar='&<>\"'' />", StringWriterText);
811                 }
812
813                 [Test]
814                 public void WriteStateTest ()
815                 {
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);
825                 }
826
827                 [Test]
828                 public void WriteString ()
829                 {
830                         xtw.WriteStartDocument ();
831                         try {
832                                 xtw.WriteString("foo");
833                         } catch (InvalidOperationException) {}
834
835                         // Testing attribute values
836
837                         xtw.WriteStartElement ("foo");
838                         xtw.WriteAttributeString ("bar", "&<>");
839                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='&amp;&lt;&gt;'", StringWriterText);
840                 }
841
842                 [Test]
843                 public void WriteAttributeStringSingleQuoteChar()
844                 {
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);
851                 }
852
853                 [Test]
854                 public void WriteAttributeStringDoubleQuoteChar()
855                 {
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);
863                 }
864
865                 [Test]
866                 public void WriteStringWithEntities()
867                 {
868                         // Testing element values
869                         xtw.QuoteChar = '\'';
870                         xtw.WriteElementString ("foo", "&<>\"'");
871                         AssertEquals ("<foo>&amp;&lt;&gt;\"'</foo>", StringWriterText);
872                 }
873
874                 [Test]
875                 public void XmlLang ()
876                 {
877                         AssertNull (xtw.XmlLang);
878                         
879                         xtw.WriteStartElement ("foo");
880                         xtw.WriteAttributeString ("xml", "lang", null, "langfoo");
881                         AssertEquals ("langfoo", xtw.XmlLang);
882                         AssertEquals ("<foo xml:lang='langfoo'", StringWriterText);
883
884                         xtw.WriteAttributeString ("boo", "yah");
885                         AssertEquals ("langfoo", xtw.XmlLang);
886                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'", StringWriterText);
887                         
888                         xtw.WriteElementString("bar", "baz");
889                         AssertEquals ("langfoo", xtw.XmlLang);
890                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", StringWriterText);
891                         
892                         xtw.WriteString("baz");
893                         AssertEquals ("langfoo", xtw.XmlLang);
894                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", StringWriterText);
895                         
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);
900                         
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);
904                         
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);
908
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);
913
914                         
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);
918
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);
923                         
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);
927                         
928                         xtw.Close ();
929                         AssertNull (xtw.XmlLang);
930                 }
931
932                 // TODO: test operational aspects
933                 [Test]
934                 public void XmlSpaceTest ()
935                 {
936                         xtw.WriteStartElement ("foo");
937                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
938
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);
943
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);
948
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);
953
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);
957                         
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);
961
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);
968
969                         xtw.WriteStartElement ("quux");
970                         try {
971                                 xtw.WriteAttributeString ("xml", "space", null, "bubba");
972                         } catch (ArgumentException) {}
973
974                         try {
975                                 xtw.WriteAttributeString ("xml", "space", null, "PRESERVE");
976                         } catch (ArgumentException) {}
977
978                         try {
979                                 xtw.WriteAttributeString ("xml", "space", null, "Preserve");
980                         } catch (ArgumentException) {}
981
982                         try {
983                                 xtw.WriteAttributeString ("xml", "space", null, "Default");
984                         } catch (ArgumentException) {}
985
986                         try {
987                                 xtw.WriteWhitespace ("x");
988                         } catch (ArgumentException) { }
989                 }
990
991                 [Test]
992                 public void XmlSpaceRaw ()
993                 {
994                         xtw.WriteStartElement ("foo");
995                         xtw.WriteStartAttribute ("xml", "space", null);
996                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
997                         AssertEquals ("<foo xml:space='", StringWriterText);
998
999                         xtw.WriteString ("default");
1000                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
1001                         AssertEquals ("<foo xml:space='", StringWriterText);
1002
1003                         xtw.WriteEndAttribute ();
1004                         AssertEquals (XmlSpace.Default, xtw.XmlSpace);
1005                         AssertEquals ("<foo xml:space='default'", StringWriterText);
1006                 }
1007
1008                 [Test]
1009                 public void WriteAttributes ()
1010                 {
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);
1017
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());
1022
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);
1030
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());
1035
1036                         sw = new StringWriter ();
1037                         wr = new XmlTextWriter (sw);
1038                         sb.Remove(0, sb.Length);        // init
1039
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 ();\r
1049                 }
1050
1051                 [Test]
1052                 public void WriteWhitespace ()
1053                 {
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);
1064                 }
1065
1066                 [Test]
1067                 public void FlushDoesntCloseTag ()
1068                 {
1069                         xtw.WriteStartElement ("foo");
1070                         xtw.WriteAttributeString ("bar", "baz");
1071                         xtw.Flush ();
1072                         AssertEquals ("<foo bar='baz'", StringWriterText);
1073                 }
1074
1075                 [Test]
1076                 public void WriteWhitespaceClosesTag ()
1077                 {
1078                         xtw.WriteStartElement ("foo");
1079                         xtw.WriteAttributeString ("bar", "baz");
1080                         xtw.WriteWhitespace (" ");
1081                         AssertEquals ("<foo bar='baz'> ", StringWriterText);
1082                 }
1083
1084                 [Test]
1085                 public void DontOutputMultipleXmlns ()
1086                 {
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);
1093                 }
1094
1095                 [Test]
1096                 public void DontOutputNonDeclaredXmlns ()
1097                 {
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);
1104                 }
1105
1106                 [Test]
1107                 public void DontOutputRemovalDefaultNSDeclaration ()
1108                 {
1109                         xtw.WriteStartDocument ();\r
1110                         xtw.WriteStartElement ("foo");\r
1111                         xtw.WriteAttributeString ("xmlns", "probe");\r
1112                         AssertEquals (String.Empty, xtw.LookupPrefix ("probe"));\r
1113                         xtw.WriteStartElement ("b");\r
1114                         AssertEquals (String.Empty, xtw.LookupPrefix ("probe"));\r
1115                         xtw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""\r
1116                         xtw.WriteEndElement (); // b2\r
1117                         xtw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""\r
1118                         xtw.WriteEndElement (); // b2\r
1119                         xtw.WriteEndElement (); // b\r
1120                         xtw.WriteEndElement (); // foo\r
1121                         xtw.WriteEndDocument ();\r
1122                         xtw.Close ();\r
1123 \r
1124                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 xmlns='' /></b></foo>", StringWriterText);\r
1125                 }
1126
1127                 [Test]
1128                 public void DontOutputRemovalDefaultNSDeclaration2 ()
1129                 {
1130                         xtw.WriteStartDocument ();\r
1131                         // IMPORTANT DIFFERENCE!! ns = "", not null\r
1132                         xtw.WriteStartElement ("foo", "");\r
1133                         xtw.WriteAttributeString ("xmlns", "probe");\r
1134                         AssertNull (xtw.LookupPrefix ("probe"));\r
1135                         xtw.WriteStartElement ("b");\r
1136                         AssertNull (xtw.LookupPrefix ("probe"));\r
1137                         xtw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""\r
1138                         xtw.WriteEndElement (); // b2\r
1139                         xtw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""\r
1140                         xtw.WriteEndElement (); // b2\r
1141                         xtw.WriteEndElement (); // b\r
1142                         xtw.WriteEndElement (); // foo\r
1143                         xtw.WriteEndDocument ();\r
1144                         xtw.Close ();\r
1145 \r
1146                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 /></b></foo>", StringWriterText);\r
1147                 }
1148
1149                 [Test]
1150                 public void DoOutputRemovalDefaultNSDeclaration ()
1151                 {
1152                         xtw.WriteStartElement ("docelem", "a-namespace");\r
1153                         \r
1154                         XmlDocument doc = new XmlDocument ();\r
1155                         doc.CreateElement ("hola").WriteTo (xtw);\r
1156                         // This means, WriteTo never passes null NamespaceURI argument to XmlWriter.\r
1157                         xtw.WriteEndElement ();\r
1158                         xtw.Close ();\r
1159 \r
1160                         AssertEquals ("<docelem xmlns='a-namespace'><hola xmlns='' /></docelem>", StringWriterText);\r
1161                 }
1162
1163                 [Test]
1164                 public void WriteAttributeTakePrecedenceOnXmlns ()
1165                 {
1166                         xtw.WriteStartElement ("root", "urn:foo");\r
1167                         xtw.WriteAttributeString ("xmlns", "urn:bar");\r
1168                         xtw.WriteEndElement ();\r
1169                         xtw.Close ();\r
1170                         AssertEquals ("<root xmlns='urn:bar' />", StringWriterText);\r
1171                 }
1172
1173                 [Test]
1174                 [ExpectedException (typeof (ArgumentException))]
1175                 public void LookupPrefixNull ()
1176                 {
1177                         xtw.LookupPrefix (null);
1178                 }
1179
1180                 [Test]
1181                 [ExpectedException (typeof (ArgumentException))]
1182                 public void LookupPrefixEmpty ()
1183                 {
1184                         xtw.LookupPrefix (String.Empty);
1185                 }
1186
1187                 [Test]
1188                 public void LookupPrefixIgnoresXmlnsAttribute ()
1189                 {
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");\r
1200                         // Is this testing on the correct way? Yes, here it is.\r
1201                         AssertEquals (String.Empty, xtw.LookupPrefix ("urn:foo"));
1202                 }
1203
1204                 [Test]
1205                 public void WriteInvalidNames ()
1206                 {
1207                         xtw.WriteStartElement ("foo<>");
1208                         xtw.WriteAttributeString ("ho<>ge", "value");
1209                 }
1210
1211                 [Test]
1212                 [ExpectedException (typeof (ArgumentException))]
1213                 public void AttributeWriteStartAttributePrefixWithoutNS ()
1214                 {
1215                         xtw.WriteStartAttribute ("some", "foo", null);
1216                 }
1217
1218                 [Test]
1219                 public void AttributeWriteStartAttributeXmlnsNullNS ()
1220                 {
1221                         xtw.WriteStartAttribute ("xmlns", "foo", null);
1222                 }
1223
1224                 [Test]
1225                 [ExpectedException (typeof (ArgumentException))]
1226                 public void AttributeWriteEndAttributeXmlnsNullNs ()
1227                 {
1228                         // Compare with the test AttributeWriteStartAttributeXmlnsNullNS().
1229                         xtw.WriteStartAttribute ("xmlns", "foo", null);
1230                         xtw.WriteEndAttribute ();
1231                 }
1232
1233                 [Test]
1234                 [ExpectedException (typeof (ArgumentException))]
1235                 public void AttributeWriteStartAttributePrefixXmlnsNonW3CNS ()
1236                 {
1237                         xtw.WriteStartAttribute ("xmlns", "foo", "urn:foo");
1238                 }
1239
1240                 [Test]
1241                 [ExpectedException (typeof (ArgumentException))]
1242                 public void AttributeWriteStartAttributeLocalXmlnsNonW3CNS ()
1243                 {
1244                         xtw.WriteStartAttribute ("", "xmlns", "urn:foo");
1245                 }
1246         }
1247 }