1b3bd6597201dec16b02446786571b45924b104b
[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.Globalization;
14 using System.IO;
15 using System.Text;
16 using System.Xml;
17
18 using NUnit.Framework;
19
20 namespace MonoTests.System.Xml
21 {
22         [TestFixture]
23         public class XmlTextWriterTests
24         {
25                 StringWriter sw;
26                 XmlTextWriter xtw;
27
28                 [SetUp]
29                 public void GetReady ()
30                 {
31                         sw = new StringWriter ();
32                         CreateXmlTextWriter ();
33                 }
34
35                 private void CreateXmlTextWriter ()
36                 {
37                         xtw = new XmlTextWriter (sw);
38                         xtw.QuoteChar = '\'';
39                 }
40
41                 private string StringWriterText 
42                 {
43                         get { return sw.GetStringBuilder ().ToString (); }
44                 }
45
46                 [Test]
47                 public void AttributeNamespacesNonNamespaceAttributeBefore ()
48                 {
49                         xtw.WriteStartElement ("foo");
50                         xtw.WriteAttributeString("bar", "baz");
51                         xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
52                         Assert.AreEqual ("<foo bar='baz' xmlns:abc='http://abc.def'", StringWriterText);
53                 }
54
55                 [Test]
56                 public void AttributeNamespacesNonNamespaceAttributeAfter ()
57                 {
58                         xtw.WriteStartElement ("foo");
59
60                         xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
61                         xtw.WriteAttributeString("bar", "baz");
62                         Assert.AreEqual ("<foo xmlns:abc='http://abc.def' bar='baz'", StringWriterText);
63                 }
64
65                 [Test]
66                 public void AttributeNamespacesThreeParamWithNullInNamespaceParam ()
67                 {
68                         xtw.WriteAttributeString ("xmlns", null, "http://abc.def");
69                         Assert.AreEqual ("xmlns='http://abc.def'", StringWriterText);
70                 }
71
72                 [Test]
73                 public void WriteAttributeString_XmlNs_Valid ()
74                 {
75                         xtw.WriteAttributeString ("xmlns", null, "http://abc.def");
76                         Assert.AreEqual ("xmlns='http://abc.def'", StringWriterText, "#1");
77
78                         sw.GetStringBuilder ().Length = 0;
79                         CreateXmlTextWriter ();
80
81                         xtw.WriteAttributeString ("xmlns", "http://www.w3.org/2000/xmlns/", "http://abc.def");
82                         Assert.AreEqual ("xmlns='http://abc.def'", StringWriterText, "#2");
83
84                         sw.GetStringBuilder ().Length = 0;
85                         CreateXmlTextWriter ();
86
87                         xtw.WriteAttributeString (null, "test", "http://www.w3.org/2000/xmlns/", "http://abc.def");
88                         Assert.AreEqual ("xmlns:test='http://abc.def'", StringWriterText, "#3");
89
90                         sw.GetStringBuilder ().Length = 0;
91                         CreateXmlTextWriter ();
92
93                         xtw.WriteAttributeString ("", "test", "http://www.w3.org/2000/xmlns/", "http://abc.def");
94                         Assert.AreEqual ("xmlns:test='http://abc.def'", StringWriterText, "#4");
95
96                         sw.GetStringBuilder ().Length = 0;
97                         CreateXmlTextWriter ();
98
99                         xtw.WriteStartElement ("person");
100                         xtw.WriteAttributeString ("", "test", "http://www.w3.org/2000/xmlns/", "http://abc.def");
101                         xtw.WriteEndElement ();
102                         Assert.AreEqual ("<person xmlns:test='http://abc.def' />", StringWriterText, "#5");
103                 }
104
105                 [Test]
106                 [ExpectedException (typeof (ArgumentException))]
107                 public void WriteAttributeString_XmlNs_Invalid1 ()
108                 {
109                         // The 'xmlns' attribute is bound to the reserved namespace 'http://www.w3.org/2000/xmlns/'
110                         xtw.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
111                 }
112
113                 [Test]
114                 [ExpectedException (typeof (ArgumentException))]
115                 public void WriteAttributeString_XmlNs_Invalid2 ()
116                 {
117                         // The 'xmlns' attribute is bound to the reserved namespace 'http://www.w3.org/2000/xmlns/'
118                         xtw.WriteAttributeString (null, "xmlns", "http://somenamespace.com", "http://abc.def");
119                 }
120
121                 [Test]
122                 public void XmlSpace_Valid () // bug #77084
123                 {
124                         xtw.WriteAttributeString ("xml", "space", null, "preserve");
125                         Assert.AreEqual ("xml:space='preserve'", StringWriterText, "#1");
126
127                         sw.GetStringBuilder ().Length = 0;
128                         CreateXmlTextWriter ();
129
130                         xtw.WriteAttributeString ("xml", "space", "whatever", "default");
131                         Assert.AreEqual ("xml:space='default'", StringWriterText, "#2");
132
133                         sw.GetStringBuilder ().Length = 0;
134                         CreateXmlTextWriter ();
135
136                         xtw.WriteStartElement ("person");
137                         xtw.WriteAttributeString ("xml", "space", "whatever", "default");
138                         xtw.WriteEndElement ();
139                         Assert.AreEqual ("<person xml:space='default' />", StringWriterText, "#3");
140                 }
141
142                 [Test]
143                 public void WriteAttributeString_XmlPrefix_Valid ()
144                 {
145                         xtw.WriteAttributeString ("xml", "something", "whatever", "default");
146                         Assert.AreEqual ("xml:something='default'", StringWriterText, "#1");
147
148                         sw.GetStringBuilder ().Length = 0;
149                         CreateXmlTextWriter ();
150
151                         xtw.WriteAttributeString ("xml", "else", null, "whatever");
152                         Assert.AreEqual ("xml:else='whatever'", StringWriterText, "#2");
153
154                         sw.GetStringBuilder ().Length = 0;
155                         CreateXmlTextWriter ();
156
157                         xtw.WriteStartElement ("person");
158                         xtw.WriteAttributeString ("xml", "something", "whatever", "default");
159                         xtw.WriteAttributeString ("xml", "else", null, "whatever");
160                         xtw.WriteEndElement ();
161                         Assert.AreEqual ("<person xml:something='default' xml:else='whatever' />", 
162                                 StringWriterText, "#3");
163                 }
164
165                 [Test]
166                 [ExpectedException (typeof (ArgumentException))]
167                 public void WriteAttributeString_XmlSpace_Invalid ()
168                 {
169                         // only preserve and default are valid values for xml:space
170                         xtw.WriteAttributeString ("xml", "space", null, "something");
171                 }
172
173                 [Test]
174                 public void AttributeNamespacesThreeParamWithTextInNamespaceParam ()
175                 {
176                         xtw.WriteAttributeString ("a", "http://somenamespace.com", "http://abc.def");
177                         Assert.AreEqual ("d0p1:a='http://abc.def'", StringWriterText, "#1");
178                 }
179
180                 [Test]
181                 [ExpectedException (typeof (ArgumentException))]
182                 public void AttributeNamespacesWithNullInNamespaceParam ()
183                 {
184                         // you cannot use prefix with an empty namespace
185                         xtw.WriteAttributeString ("a", "abc", null, "http://abc.def");
186                 }
187
188                 [Test]
189                 public void AttributeNamespacesWithTextInNamespaceParam ()
190                 {
191                         xtw.WriteAttributeString ("a", "abc", "http://somenamespace.com", "http://abc.def");
192                         Assert.AreEqual ("a:abc='http://abc.def'", StringWriterText, "#1");
193
194                         sw.GetStringBuilder ().Length = 0;
195                         CreateXmlTextWriter ();
196
197                         xtw.WriteAttributeString ("", "abc", "http://somenamespace.com", "http://abc.def");
198                         Assert.AreEqual ("d0p1:abc='http://abc.def'", StringWriterText, "#2");
199
200                         sw.GetStringBuilder ().Length = 0;
201                         CreateXmlTextWriter ();
202
203                         xtw.WriteAttributeString (null, "abc", "http://somenamespace.com", "http://abc.def");
204                         Assert.AreEqual ("d0p1:abc='http://abc.def'", StringWriterText, "#3");
205                 }
206
207                 [Test]
208                 [Ignore ("Due to the (silly) dependency on bug #77088, this test will not be fixed. The test could be rewritten but it depends on the original test author.")]
209                 public void AutoCreatePrefixes ()
210                 {
211                         xtw.WriteStartElement ("root");
212                         xtw.WriteAttributeString (null, "abc", "http://somenamespace.com", "http://abc.def");
213                         xtw.WriteAttributeString (null, "def", "http://somenamespace.com", "http://def.ghi");
214                         xtw.WriteAttributeString (null, "ghi", "http://othernamespace.com", "http://ghi.jkl");
215                         xtw.WriteEndElement ();
216
217                         Assert.AreEqual ("<root d1p1:abc='http://abc.def' d1p1:def='http://def.ghi' d1p2:ghi='http://ghi.jkl' xmlns:d1p2='http://othernamespace.com' xmlns:d1p1='http://somenamespace.com' />", StringWriterText, "#1");
218                 }
219
220                 [Test]
221                 [Ignore ("Due to the (silly) dependency on bug #77088, this test will not be fixed. The test could be rewritten but it depends on the original test author.")]
222                 public void AutoCreatePrefixes2 ()
223                 {
224                         xtw.WriteStartElement ("person");
225                         xtw.WriteAttributeString (null, "name", "http://somenamespace.com", "Driesen");
226                         xtw.WriteAttributeString (null, "initials", "http://othernamespace.com", "GD");
227                         xtw.WriteAttributeString (null, "firstName", "http://somenamespace.com", "Gert");
228                         xtw.WriteStartElement ("address");
229                         xtw.WriteAttributeString (null, "street", "http://somenamespace.com", "Campus");
230                         xtw.WriteAttributeString (null, "number", "http://othernamespace.com", "1");
231                         xtw.WriteAttributeString (null, "zip", "http://newnamespace.com", "3000");
232                         xtw.WriteAttributeString (null, "box", "http://othernamespace.com", "a");
233                         xtw.WriteEndElement ();
234                         xtw.WriteEndElement ();
235
236                         Assert.AreEqual (
237                                 "<person" +
238                                         " d1p1:name='Driesen'" +
239                                         " d1p2:initials='GD'" +
240                                         " d1p1:firstName='Gert'" +
241                                         " xmlns:d1p2='http://othernamespace.com'" +
242                                         " xmlns:d1p1='http://somenamespace.com'>" +
243                                         "<address" +
244                                                 " d1p1:street='Campus'" +
245                                                 " d1p2:number='1'" +
246                                                 " d2p1:zip='3000'" +
247                                                 " d1p2:box='a'" +
248                                                 " xmlns:d2p1='http://newnamespace.com' />" +
249                                 "</person>", StringWriterText, "#2");
250                 }
251
252                 [Test]
253                 public void AttributeNamespacesXmlnsXmlns ()
254                 {
255                         xtw.WriteStartElement ("foo");
256                         // If XmlTextWriter conforms to "Namespaces in XML"
257                         // when namespaceURI argument is null, then this
258                         // is not allowed (http://www.w3.org/TR/REC-xml-names/
259                         // Namespace Constraint: Prefix Declared), but seems
260                         // like XmlTextWriter just ignores XML namespace
261                         // constraints when namespaceURI argument is null.
262                         xtw.WriteAttributeString ("xmlns", "xmlns", null, "http://abc.def");
263                         //Assert.Fail ("A prefix must not start with \"xml\".");
264                 }
265
266                 [Test]
267                 public void AttributeNamespacesXmlnsXmlns2 ()
268                 {
269                         // It is split from AttributeNamespacesXmlnsXmlns()
270                         // because depending on XmlWriter it is likely to cause
271                         // duplicate attribute error (XmlTextWriter is pretty
272                         // hacky, so it does not raise such errors).
273                         xtw.WriteStartElement ("foo");
274                         xtw.WriteAttributeString ("", "xmlns", null, "http://abc.def");
275                 }
276
277                 [Test]
278                 public void WriteAttributeString_EmptyLocalName ()
279                 {
280                         xtw.WriteAttributeString ("", "something");
281                         Assert.AreEqual ("='something'", StringWriterText, "#1");
282
283                         sw.GetStringBuilder ().Length = 0;
284                         CreateXmlTextWriter ();
285
286                         xtw.WriteAttributeString ("", "", "something");
287                         Assert.AreEqual ("='something'", StringWriterText, "#2");
288
289                         sw.GetStringBuilder ().Length = 0;
290                         CreateXmlTextWriter ();
291
292                         xtw.WriteAttributeString ("", "http://somenamespace.com", "something");
293                         Assert.AreEqual ("d0p1:='something'", StringWriterText, "#3");
294
295                         sw.GetStringBuilder ().Length = 0;
296                         CreateXmlTextWriter ();
297
298                         xtw.WriteAttributeString ("x", "", "http://somenamespace.com", "something");
299                         Assert.AreEqual ("x:='something'", StringWriterText, "#4");
300
301                         sw.GetStringBuilder ().Length = 0;
302                         CreateXmlTextWriter ();
303
304                         xtw.WriteAttributeString (null, "something");
305                         Assert.AreEqual ("='something'", StringWriterText, "#5");
306
307                         sw.GetStringBuilder ().Length = 0;
308                         CreateXmlTextWriter ();
309
310                         xtw.WriteAttributeString (null, "", "something");
311                         Assert.AreEqual ("='something'", StringWriterText, "#6");
312
313                         sw.GetStringBuilder ().Length = 0;
314                         CreateXmlTextWriter ();
315
316                         xtw.WriteAttributeString (null, "http://somenamespace.com", "something");
317                         Assert.AreEqual ("d0p1:='something'", StringWriterText, "#7");
318
319                         sw.GetStringBuilder ().Length = 0;
320                         CreateXmlTextWriter ();
321
322                         xtw.WriteAttributeString ("x", null, "http://somenamespace.com", "something");
323                         Assert.AreEqual ("x:='something'", StringWriterText, "#8");
324                 }
325
326                 [Test]
327                 public void WriteStartAttribute_EmptyLocalName ()
328                 {
329                         xtw.WriteStartAttribute ("", "");
330                         Assert.AreEqual ("='", StringWriterText, "#1");
331
332                         sw.GetStringBuilder ().Length = 0;
333                         CreateXmlTextWriter ();
334
335                         xtw.WriteStartAttribute ("", "", "");
336                         Assert.AreEqual ("='", StringWriterText, "#2");
337
338                         sw.GetStringBuilder ().Length = 0;
339                         CreateXmlTextWriter ();
340
341                         xtw.WriteStartAttribute ("", "", "http://somenamespace.com");
342                         Assert.AreEqual ("d0p1:='", StringWriterText, "#3");
343
344                         sw.GetStringBuilder ().Length = 0;
345                         CreateXmlTextWriter ();
346
347                         xtw.WriteStartAttribute ("x", "", "http://somenamespace.com");
348                         Assert.AreEqual ("x:='", StringWriterText, "#4");
349
350                         sw.GetStringBuilder ().Length = 0;
351                         CreateXmlTextWriter ();
352
353                         xtw.WriteStartAttribute ("", null);
354                         Assert.AreEqual ("='", StringWriterText, "#5");
355
356                         sw.GetStringBuilder ().Length = 0;
357                         CreateXmlTextWriter ();
358
359                         xtw.WriteStartAttribute ("", null, "");
360                         Assert.AreEqual ("='", StringWriterText, "#6");
361
362                         sw.GetStringBuilder ().Length = 0;
363                         CreateXmlTextWriter ();
364
365                         xtw.WriteStartAttribute ("", null, "http://somenamespace.com");
366                         Assert.AreEqual ("d0p1:='", StringWriterText, "#7");
367
368                         sw.GetStringBuilder ().Length = 0;
369                         CreateXmlTextWriter ();
370
371                         xtw.WriteStartAttribute ("x", null, "http://somenamespace.com");
372                         Assert.AreEqual ("x:='", StringWriterText, "#8");
373                 }
374
375                 [Test]
376                 public void AttributeWriteAttributeString ()
377                 {
378                         xtw.WriteStartElement ("foo");
379
380                         xtw.WriteAttributeString ("foo", "bar");
381                         Assert.AreEqual ("<foo foo='bar'", StringWriterText);
382
383                         xtw.WriteAttributeString ("bar", "");
384                         Assert.AreEqual ("<foo foo='bar' bar=''", StringWriterText);
385
386                         xtw.WriteAttributeString ("baz", null);
387                         Assert.AreEqual ("<foo foo='bar' bar='' baz=''", StringWriterText);
388
389                         xtw.WriteAttributeString ("hoge", "a\nb");
390                         Assert.AreEqual ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b'", StringWriterText);
391
392                         xtw.WriteAttributeString ("fuga", " a\t\r\nb\t");
393                         Assert.AreEqual ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b' fuga=' a\t&#xD;&#xA;b\t'", StringWriterText);
394                 }
395
396                 [Test]
397                 [ExpectedException (typeof (InvalidOperationException))]
398                 public void AttributeWriteAttributeStringNotInsideOpenStartElement ()
399                 {
400                         xtw.WriteStartElement ("foo");
401                         xtw.WriteString ("bar");
402                         
403                         xtw.WriteAttributeString ("baz", "quux");
404                 }
405
406                 [Test]
407                 public void AttributeWriteAttributeStringWithoutParentElement ()
408                 {
409                         xtw.WriteAttributeString ("foo", "bar");
410                         Assert.AreEqual ("foo='bar'", StringWriterText);
411
412                         xtw.WriteAttributeString ("baz", "quux");
413                         Assert.AreEqual ("foo='bar' baz='quux'", StringWriterText);
414                 }
415
416                 [Test]
417                 public void WriteStartElement_EmptyLocalName ()
418                 {
419                         xtw.WriteStartElement ("", "");
420                         Assert.AreEqual ("<", StringWriterText, "#1");
421
422                         sw.GetStringBuilder ().Length = 0;
423                         CreateXmlTextWriter ();
424
425                         xtw.WriteStartElement ("", "", "");
426                         Assert.AreEqual ("<", StringWriterText, "#2");
427
428                         sw.GetStringBuilder ().Length = 0;
429                         CreateXmlTextWriter ();
430
431                         xtw.WriteStartElement ("", "", "http://somenamespace.com");
432                         Assert.AreEqual ("<", StringWriterText, "#3");
433
434                         sw.GetStringBuilder ().Length = 0;
435                         CreateXmlTextWriter ();
436
437                         xtw.WriteStartElement ("x", "", "http://somenamespace.com");
438                         Assert.AreEqual ("<x:", StringWriterText, "#4");
439
440                         sw.GetStringBuilder ().Length = 0;
441                         CreateXmlTextWriter ();
442
443                         xtw.WriteStartElement ("", null);
444                         Assert.AreEqual ("<", StringWriterText, "#5");
445
446                         sw.GetStringBuilder ().Length = 0;
447                         CreateXmlTextWriter ();
448
449                         xtw.WriteStartElement ("", null, "");
450                         Assert.AreEqual ("<", StringWriterText, "#6");
451
452                         sw.GetStringBuilder ().Length = 0;
453                         CreateXmlTextWriter ();
454
455                         xtw.WriteStartElement ("", null, "http://somenamespace.com");
456                         Assert.AreEqual ("<", StringWriterText, "#7");
457
458                         sw.GetStringBuilder ().Length = 0;
459                         CreateXmlTextWriter ();
460
461                         xtw.WriteStartElement ("x", null, "http://somenamespace.com");
462                         Assert.AreEqual ("<x:", StringWriterText, "#8");
463                 }
464
465                 [Test]
466                 public void WriteElementString_EmptyLocalName ()
467                 {
468                         xtw.WriteElementString ("", "");
469                         Assert.AreEqual ("< />", StringWriterText, "#1");
470
471                         sw.GetStringBuilder ().Length = 0;
472                         CreateXmlTextWriter ();
473
474                         xtw.WriteElementString ("", "", "");
475                         Assert.AreEqual ("< />", StringWriterText, "#2");
476
477                         sw.GetStringBuilder ().Length = 0;
478                         CreateXmlTextWriter ();
479
480                         xtw.WriteElementString ("", "http://somenamespace.com", "whatever");
481                         Assert.AreEqual ("< xmlns='http://somenamespace.com'>whatever</>", StringWriterText, "#3");
482
483                         sw.GetStringBuilder ().Length = 0;
484                         CreateXmlTextWriter ();
485
486                         xtw.WriteElementString ("", "http://somenamespace.com", "");
487                         Assert.AreEqual ("< xmlns='http://somenamespace.com' />", StringWriterText, "#4");
488
489                         sw.GetStringBuilder ().Length = 0;
490                         CreateXmlTextWriter ();
491
492                         xtw.WriteElementString (null, null);
493                         Assert.AreEqual ("< />", StringWriterText, "#5");
494
495                         sw.GetStringBuilder ().Length = 0;
496                         CreateXmlTextWriter ();
497
498                         xtw.WriteElementString (null, null, null);
499                         Assert.AreEqual ("< />", StringWriterText, "#6");
500
501                         sw.GetStringBuilder ().Length = 0;
502                         CreateXmlTextWriter ();
503
504                         xtw.WriteElementString (null, "http://somenamespace.com", "whatever");
505                         Assert.AreEqual ("< xmlns='http://somenamespace.com'>whatever</>", StringWriterText, "#7");
506
507                         sw.GetStringBuilder ().Length = 0;
508                         CreateXmlTextWriter ();
509
510                         xtw.WriteElementString (null, "http://somenamespace.com", null);
511                         Assert.AreEqual ("< xmlns='http://somenamespace.com' />", StringWriterText, "#8");
512                 }
513
514                 [Test]
515                 public void WriteStartElement_Prefix_EmptyNamespace ()
516                 {
517                         xtw.WriteStartElement ("x", "whatever", "");
518                         Assert.AreEqual ("<whatever", StringWriterText, "#1");
519
520                         xtw.WriteEndElement ();
521
522                         Assert.AreEqual ("<whatever />", StringWriterText, "#2");
523                 }
524
525                 [Test]
526                 [ExpectedException (typeof (ArgumentException))]
527                 public void WriteStartElement_Prefix_NullNamespace ()
528                 {
529                         xtw.WriteStartElement ("x", "whatever", null);
530                 }
531
532                 [Test]
533                 public void WriteStartElement_XmlPrefix ()
534                 {
535                         xtw.WriteStartElement ("xml", "something", "http://www.w3.org/XML/1998/namespace");
536                         Assert.AreEqual ("<xml:something", StringWriterText, "#1");
537
538                         sw.GetStringBuilder ().Length = 0;
539                         CreateXmlTextWriter ();
540
541                         xtw.WriteStartElement ("XmL", null, "http://www.w3.org/XML/1998/namespace");
542                         Assert.AreEqual ("<XmL:", StringWriterText, "#2");
543
544                         sw.GetStringBuilder ().Length = 0;
545                         CreateXmlTextWriter ();
546
547                         xtw.WriteStartElement ("xmlsomething", "name", "http://www.w3.org/XML/1998/namespace");
548                         Assert.AreEqual ("<xmlsomething:name", StringWriterText, "#3");
549
550                         sw.GetStringBuilder ().Length = 0;
551                         CreateXmlTextWriter ();
552                 }
553
554                 [Test]
555                 [ExpectedException (typeof (ArgumentException))]
556                 public void WriteStartElement_XmlPrefix_Invalid1 ()
557                 {
558                         xtw.WriteStartElement ("xml", null, "http://somenamespace.com");
559                 }
560
561                 [Test]
562                 [ExpectedException (typeof (ArgumentException))]
563                 public void WriteStartElement_XmlPrefix_Invalid2 ()
564                 {
565                         xtw.WriteStartElement ("XmL", null, "http://somenamespace.com");
566                 }
567
568                 [Test]
569                 public void WriteStartElement_XmlPrefix_Invalid3 ()
570                 {
571                         // from XML 1.0 (third edition) specification:
572                         //
573                         // [Definition: A Name is a token beginning with a letter or one of a
574                         // few punctuation characters, and continuing with letters, digits, 
575                         // hyphens, underscores, colons, or full stops, together known as name 
576                         // characters.] Names beginning with the string "xml", or with any string
577                         // which would match (('X'|'x') ('M'|'m') ('L'|'l')), are reserved for 
578                         // standardization in this or future versions of this specification.
579                         //
580                         // from the Namespaces in XML 1.0 specification:
581                         //
582                         // Prefixes beginning with the three-letter sequence x, m, l, in any case 
583                         // combination, are reserved for use by XML and XML-related specifications. 
584                         //
585                         // should this prefix then not be considered invalid ?
586                         //
587                         // both Mono and MS.NET 1.x/2.0 accept it though
588
589                         xtw.WriteStartElement ("xmlsomething", null, "http://somenamespace.com");
590                         Assert.AreEqual ("<xmlsomething:", StringWriterText, "#1");
591
592                         sw.GetStringBuilder ().Length = 0;
593                         CreateXmlTextWriter ();
594
595                         xtw.WriteStartElement ("XmLsomething", null, "http://somenamespace.com");
596                         Assert.AreEqual ("<XmLsomething:", StringWriterText, "#2");
597                 }
598
599                 [Test]
600                 public void CDataValid ()
601                 {
602                         xtw.WriteCData ("foo");
603                         Assert.AreEqual ("<![CDATA[foo]]>", StringWriterText, "WriteCData had incorrect output.");
604                 }
605
606                 [Test]
607                 public void CDataNull ()
608                 {
609                         xtw.WriteCData (null);
610                         Assert.AreEqual ("<![CDATA[]]>", StringWriterText, "WriteCData had incorrect output.");
611                 }
612
613                 [Test]
614                 [ExpectedException (typeof (ArgumentException))]
615                 public void CDataInvalid ()
616                 {
617                         xtw.WriteCData("foo]]>bar");
618                 }
619                 
620                 [Test]
621                 public void CloseOpenElements ()
622                 {
623                         xtw.WriteStartElement("foo");
624                         xtw.WriteStartElement("bar");
625                         xtw.WriteStartElement("baz");
626                         xtw.Close();
627                         Assert.AreEqual ("<foo><bar><baz /></bar></foo>", StringWriterText,
628                                 "Close didn't write out end elements properly.");
629                 }
630
631                 [Test]
632                 public void CloseWriteAfter ()
633                 {
634                         xtw.WriteElementString ("foo", "bar");
635                         xtw.Close ();
636
637                         // WriteEndElement and WriteStartDocument aren't tested here because
638                         // they will always throw different exceptions besides 'The Writer is closed.'
639                         // and there are already tests for those exceptions.
640
641                         try {
642                                 xtw.WriteCData ("foo");
643                                 Assert.Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
644                         } catch (InvalidOperationException) {
645                                 // Don't rely on English message assertion.
646                                 // It is enough to check an exception occurs.
647                                 // Assert.AreEqual ("The Writer is closed.", e.Message, "Exception message is incorrect.");
648                         }
649
650                         try {
651                                 xtw.WriteComment ("foo");
652                                 Assert.Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
653                         } catch (InvalidOperationException) {
654                                 // Assert.AreEqual ("The Writer is closed.", e.Message, "Exception message is incorrect.");
655                         }
656
657                         try {
658                                 xtw.WriteProcessingInstruction ("foo", "bar");
659                                 Assert.Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
660                         } catch (InvalidOperationException) {
661                                 // Assert.AreEqual ("The Writer is closed.", e.Message, "Exception message is incorrect.");
662                         }
663
664                         try {
665                                 xtw.WriteStartElement ("foo", "bar", "baz");
666                                 Assert.Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
667                         } catch (InvalidOperationException) {
668                                 // Assert.AreEqual ("The Writer is closed.", e.Message, "Exception message is incorrect.");
669                         }
670
671                         try {
672                                 xtw.WriteAttributeString ("foo", "bar");
673                                 Assert.Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
674                         } catch (InvalidOperationException) {
675                                 // Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
676                         }
677
678                         try {
679                                 xtw.WriteString ("foo");
680                                 Assert.Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
681                         } catch (InvalidOperationException) {
682                                 // Assert.AreEqual ("The Writer is closed.", e.Message, "Exception message is incorrect.");
683                         }
684                 }
685
686                 [Test]
687                 public void CommentValid ()
688                 {
689                         xtw.WriteComment ("foo");
690                         Assert.AreEqual ("<!--foo-->", StringWriterText, "WriteComment had incorrect output.");
691                 }
692
693                 [Test]
694                 public void CommentInvalid ()
695                 {
696                         try {
697                                 xtw.WriteComment("foo-");
698                                 Assert.Fail("Should have thrown an ArgumentException.");
699                         } catch (ArgumentException) { }
700
701                         try {
702                                 xtw.WriteComment("foo-->bar");
703                                 Assert.Fail("Should have thrown an ArgumentException.");
704                         } catch (ArgumentException) { }
705                 }
706
707                 [Test]
708                 public void ConstructorsAndBaseStream ()
709                 {
710                         Assert.IsTrue (Object.ReferenceEquals (null, this.xtw.BaseStream), "BaseStream property returned wrong value.");
711
712                         MemoryStream ms;
713                         StreamReader sr;
714                         XmlTextWriter xtw;
715
716                         ms = new MemoryStream ();
717                         xtw = new XmlTextWriter (ms, new UnicodeEncoding ());
718                         xtw.WriteStartDocument ();
719                         xtw.Flush ();
720                         ms.Seek (0, SeekOrigin.Begin);
721                         sr = new StreamReader (ms, Encoding.Unicode);
722                         string expectedXmlDeclaration = "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
723                         string actualXmlDeclaration = sr.ReadToEnd();
724                         Assert.AreEqual (expectedXmlDeclaration, actualXmlDeclaration);
725                         Assert.IsTrue (Object.ReferenceEquals (ms, xtw.BaseStream), "BaseStream property returned wrong value.");
726
727                         ms = new MemoryStream ();
728                         xtw = new XmlTextWriter (ms, new UnicodeEncoding ());
729                         xtw.WriteStartDocument (true);
730                         xtw.Flush ();
731                         ms.Seek (0, SeekOrigin.Begin);
732                         sr = new StreamReader (ms, Encoding.Unicode);
733                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>", sr.ReadToEnd ());
734
735                         ms = new MemoryStream ();
736                         xtw = new XmlTextWriter (ms, new UTF8Encoding ());
737                         xtw.WriteStartDocument ();
738                         xtw.Flush ();
739                         ms.Seek (0, SeekOrigin.Begin);
740                         sr = new StreamReader (ms, Encoding.UTF8);
741                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-8\"?>", sr.ReadToEnd ());
742
743                         ms = new MemoryStream ();
744                         xtw = new XmlTextWriter (ms, null);
745                         xtw.WriteStartDocument ();
746                         xtw.Flush ();
747                         ms.Seek (0, SeekOrigin.Begin);
748                         sr = new StreamReader (ms, Encoding.UTF8);
749                         Assert.AreEqual ("<?xml version=\"1.0\"?>", sr.ReadToEnd ());
750
751                         ms = new MemoryStream ();
752                         xtw = new XmlTextWriter (ms, null);
753                         xtw.WriteStartDocument (true);
754                         xtw.Flush ();
755                         ms.Seek (0, SeekOrigin.Begin);
756                         sr = new StreamReader (ms, Encoding.UTF8);
757                         Assert.AreEqual ("<?xml version=\"1.0\" standalone=\"yes\"?>", sr.ReadToEnd ());
758                         Assert.IsTrue (Object.ReferenceEquals (ms, xtw.BaseStream), "BaseStream property returned wrong value.");
759                 }
760
761                 [Test]
762                 public void DocumentStart ()
763                 {
764                         xtw.WriteStartDocument ();
765                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?>", StringWriterText,
766                                 "XmlDeclaration is incorrect.");
767
768                         try {
769                                 xtw.WriteStartDocument ();
770                                 Assert.Fail("Should have thrown an InvalidOperationException.");
771                         } catch (InvalidOperationException) {
772                                 // Don't rely on English message assertion.
773                                 // It is enough to check an exception occurs.
774                                 // Assert.AreEqual ("WriteStartDocument should be the first call.", e.Message, "Exception message is incorrect.");
775                         }
776
777                         xtw = new XmlTextWriter (sw = new StringWriter ());
778                         xtw.QuoteChar = '\'';
779                         xtw.WriteStartDocument (true);
780                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16' standalone='yes'?>", StringWriterText);
781
782                         xtw = new XmlTextWriter (sw = new StringWriter ());
783                         xtw.QuoteChar = '\'';
784                         xtw.WriteStartDocument (false);
785                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16' standalone='no'?>", StringWriterText);
786                 }
787
788                 [Test]
789                 public void ElementAndAttributeSameXmlns ()
790                 {
791                         xtw.WriteStartElement ("ped", "foo", "urn:foo");
792                         xtw.WriteStartAttribute ("ped", "foo", "urn:foo");
793                         xtw.WriteEndElement ();
794                         Assert.AreEqual ("<ped:foo ped:foo='' xmlns:ped='urn:foo' />", StringWriterText);
795                 }
796
797                 [Test]
798                 [Category ("NotDotNet")]
799                 public void ElementXmlnsNeedEscape ()
800                 {
801                         xtw.WriteStartElement ("test", "foo", "'");
802                         xtw.WriteEndElement ();
803                         // MS.NET output is : xmlns:test='''
804                         Assert.AreEqual ("<test:foo xmlns:test='&apos;' />", StringWriterText);
805                 }
806
807                 [Test]
808                 public void ElementEmpty ()
809                 {
810                         xtw.WriteStartElement ("foo");
811                         xtw.WriteEndElement ();
812                         Assert.AreEqual ("<foo />", StringWriterText, "Incorrect output.");
813                 }
814
815                 [Test]
816                 public void ElementWriteElementString ()
817                 {
818                         xtw.WriteElementString ("foo", "bar");
819                         Assert.AreEqual ("<foo>bar</foo>", StringWriterText, "WriteElementString has incorrect output.");
820
821                         xtw.WriteElementString ("baz", "");
822                         Assert.AreEqual ("<foo>bar</foo><baz />", StringWriterText, "#2");
823
824                         xtw.WriteElementString ("quux", null);
825                         Assert.AreEqual ("<foo>bar</foo><baz /><quux />", StringWriterText, "#3");
826
827                         xtw.WriteElementString ("", "quuux");
828                         Assert.AreEqual ("<foo>bar</foo><baz /><quux /><>quuux</>", StringWriterText, "#4");
829
830                         xtw.WriteElementString (null, "quuuux");
831                         Assert.AreEqual ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", StringWriterText, "#5");
832                 }
833
834                 [Test]
835                 public void FormattingTest ()
836                 {
837                         xtw.Formatting = Formatting.Indented;
838                         xtw.WriteStartDocument ();
839                         xtw.WriteStartElement ("foo");
840                         xtw.WriteElementString ("bar", "");
841                         xtw.Close ();
842                         Assert.AreEqual (String.Format ("<?xml version='1.0' encoding='utf-16'?>{0}<foo>{0}  <bar />{0}</foo>", Environment.NewLine), StringWriterText);
843                 }
844
845                 [Test]
846                 public void FormattingInvalidXmlForFun ()
847                 {
848                         xtw.Formatting = Formatting.Indented;
849                         xtw.IndentChar = 'x';
850                         xtw.WriteStartDocument ();
851                         xtw.WriteStartElement ("foo");
852                         xtw.WriteStartElement ("bar");
853                         xtw.WriteElementString ("baz", "");
854                         xtw.Close ();
855                         Assert.AreEqual (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);
856                 }
857
858                 [Test]
859                 public void FormattingFromRemarks ()
860                 {
861                         // Remarks section of on-line help for XmlTextWriter.Formatting suggests this test.
862                         xtw.Formatting = Formatting.Indented; 
863                         xtw.WriteStartElement ("ol"); 
864                         xtw.WriteStartElement ("li"); 
865                         xtw.WriteString ("The big "); // This means "li" now has a mixed content model. 
866                         xtw.WriteElementString ("b", "E"); 
867                         xtw.WriteElementString ("i", "lephant"); 
868                         xtw.WriteString (" walks slowly."); 
869                         xtw.WriteEndElement (); 
870                         xtw.WriteEndElement ();
871                         Assert.AreEqual (String.Format ("<ol>{0}  <li>The big <b>E</b><i>lephant</i> walks slowly.</li>{0}</ol>", Environment.NewLine), StringWriterText);
872                 }
873
874                 [Test]
875                 public void LookupPrefix ()
876                 {
877                         xtw.WriteStartElement ("root");
878
879                         xtw.WriteStartElement ("one");
880                         xtw.WriteAttributeString ("xmlns", "foo", null, "http://abc.def");
881                         xtw.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl");
882                         Assert.AreEqual ("foo", xtw.LookupPrefix ("http://abc.def"), "#1");
883                         Assert.AreEqual ("bar", xtw.LookupPrefix ("http://ghi.jkl"), "#2");
884                         xtw.WriteEndElement ();
885
886                         xtw.WriteStartElement ("two");
887                         xtw.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr");
888                         xtw.WriteString("quux");
889                         Assert.AreEqual ("baz", xtw.LookupPrefix ("http://mno.pqr"), "#3");
890                         Assert.IsNull (xtw.LookupPrefix ("http://abc.def"), "#4");
891                         Assert.IsNull (xtw.LookupPrefix ("http://ghi.jkl"), "#5");
892
893                         Assert.IsNull (xtw.LookupPrefix ("http://bogus"), "#6");
894                 }
895
896                 [Test]
897                 public void NamespacesAttributesPassingInNamespaces ()
898                 {
899                         xtw.Namespaces = false;
900                         xtw.WriteStartElement ("foo");
901
902                         // These shouldn't throw any exceptions since they don't pass in
903                         // a namespace.
904                         xtw.WriteAttributeString ("bar", "baz");
905                         xtw.WriteAttributeString ("", "a", "", "b");
906                         xtw.WriteAttributeString (null, "c", "", "d");
907                         xtw.WriteAttributeString ("", "e", null, "f");
908                         xtw.WriteAttributeString (null, "g", null, "h");
909
910                         Assert.AreEqual ("<foo bar='baz' a='b' c='d' e='f' g='h'", StringWriterText);
911                 }
912
913                 [Test]
914                 public void NamespacesElementsPassingInNamespaces ()
915                 {
916                         xtw.Namespaces = false;
917
918                         // These shouldn't throw any exceptions since they don't pass in
919                         // a namespace.
920                         xtw.WriteElementString ("foo", "bar");
921                         xtw.WriteStartElement ("baz");
922                         xtw.WriteStartElement ("quux", "");
923                         xtw.WriteStartElement ("quuux", null);
924                         xtw.WriteStartElement (null, "a", null);
925                         xtw.WriteStartElement (null, "b", "");
926                         xtw.WriteStartElement ("", "c", null);
927                         xtw.WriteStartElement ("", "d", "");
928
929                         Assert.AreEqual ("<foo>bar</foo><baz><quux><quuux><a><b><c><d", StringWriterText);
930                 }
931
932                 [Test]
933                 [ExpectedException (typeof (ArgumentException))]
934                 public void NamespacesElementsPassingInNamespacesInvalid1 ()
935                 {
936                         // These should throw ArgumentException because they pass in a
937                         // namespace when Namespaces = false.
938                         xtw.Namespaces = false;
939                         xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
940                 }
941
942                 [Test]
943                 [ExpectedException (typeof (ArgumentException))]
944                 public void NamespacesElementsPassingInNamespacesInvalid2 ()
945                 {
946                         xtw.Namespaces = false;
947                         xtw.WriteStartElement ("foo", "http://netsack.com/");
948                 }
949
950                 [Test]
951                 [ExpectedException (typeof (ArgumentException))]
952                 public void NamespacesElementsPassingInNamespacesInvalid3 ()
953                 {
954                         xtw.Namespaces = false;
955                         xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
956                 }
957
958                 [Test]
959                 [ExpectedException (typeof (ArgumentException))]
960                 public void NamespacesElementsPassingInNamespacesInvalid4 ()
961                 {
962                         xtw.Namespaces = false;
963                         xtw.WriteStartElement ("foo", "bar", null);
964                 }
965
966                 [Test]
967                 [ExpectedException (typeof (ArgumentException))]
968                 public void NamespacesElementsPassingInNamespacesInvalid5 ()
969                 {
970                         xtw.Namespaces = false;
971                         xtw.WriteStartElement ("foo", "bar", "");
972                 }
973
974                 [Test]
975                 [ExpectedException (typeof (ArgumentException))]
976                 public void NamespacesElementsPassingInNamespacesInvalid6 ()
977                 {
978                         xtw.Namespaces = false;
979                         xtw.WriteStartElement ("foo", "", "");
980                 }
981
982                 [Test]
983                 public void NamespacesNoNamespaceClearsDefaultNamespace ()
984                 {
985                         xtw.WriteStartElement(String.Empty, "foo", "http://netsack.com/");
986                         xtw.WriteStartElement(String.Empty, "bar", String.Empty);
987                         xtw.WriteElementString("baz", String.Empty, String.Empty);
988                         xtw.WriteEndElement();
989                         xtw.WriteEndElement();
990                         Assert.AreEqual ("<foo xmlns='http://netsack.com/'><bar xmlns=''><baz /></bar></foo>",
991                                 StringWriterText, "XmlTextWriter is incorrectly outputting namespaces.");
992                 }
993
994                 [Test]
995                 public void NamespacesPrefix ()
996                 {
997                         xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
998                         xtw.WriteStartElement ("foo", "baz", "http://netsack.com/");
999                         xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
1000                         xtw.WriteEndElement ();
1001                         xtw.WriteEndElement ();
1002                         Assert.AreEqual ("<foo:bar xmlns:foo='http://netsack.com/'><foo:baz><foo:qux /></foo:baz></foo:bar>",
1003                                 StringWriterText, "XmlTextWriter is incorrectly outputting prefixes.");
1004                 }
1005
1006                 [Test]
1007                 public void NamespacesPrefixWithEmptyAndNullNamespaceEmpty ()
1008                 {
1009                         xtw.WriteStartElement ("foo", "bar", "");
1010                 }
1011
1012                 [Test]
1013                 [ExpectedException (typeof (ArgumentException))]
1014                 public void NamespacesPrefixWithEmptyAndNullNamespaceNull ()
1015                 {
1016                         xtw.WriteStartElement ("foo", "bar", null);
1017                 }
1018
1019                 [Test]
1020                 public void NamespacesSettingWhenWriteStateNotStart ()
1021                 {
1022                         xtw.WriteStartElement ("foo");
1023                         try {
1024                                 xtw.Namespaces = false;
1025                                 Assert.Fail ("Expected an InvalidOperationException.");
1026                         } catch (InvalidOperationException) {}
1027                         Assert.IsTrue (xtw.Namespaces);
1028                 }
1029
1030                 [Test]
1031                 public void ProcessingInstructionValid ()
1032                 {
1033                         xtw.WriteProcessingInstruction("foo", "bar");
1034                         Assert.AreEqual ("<?foo bar?>", StringWriterText, "WriteProcessingInstruction had incorrect output.");
1035                 }
1036
1037                 [Test]
1038                 [ExpectedException (typeof (ArgumentException))]
1039                 public void ProcessingInstructionInvalid1 ()
1040                 {
1041                         xtw.WriteProcessingInstruction("fo?>o", "bar");
1042                 }
1043
1044                 [Test]
1045                 [ExpectedException (typeof (ArgumentException))]
1046                 public void ProcessingInstructionInvalid2 ()
1047                 {
1048                         xtw.WriteProcessingInstruction("foo", "ba?>r");
1049                 }
1050
1051                 [Test]
1052                 [ExpectedException (typeof (ArgumentException))]
1053                 public void ProcessingInstructionInvalid3 ()
1054                 {
1055                         xtw.WriteProcessingInstruction("", "bar");
1056                 }
1057
1058                 [Test]
1059                 [ExpectedException (typeof (ArgumentException))]
1060                 public void ProcessingInstructionInvalid4 ()
1061                 {
1062                         xtw.WriteProcessingInstruction(null, "bar");
1063                 }
1064
1065                 [Test]
1066                 public void QuoteCharDoubleQuote ()
1067                 {
1068                         xtw.QuoteChar = '"';
1069
1070                         // version, encoding, standalone
1071                         xtw.WriteStartDocument (true);
1072                         
1073                         // namespace declaration
1074                         xtw.WriteElementString ("foo", "http://netsack.com", "bar");
1075
1076                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?><foo xmlns=\"http://netsack.com\">bar</foo>", StringWriterText);
1077                 }
1078
1079                 [Test]
1080                 [ExpectedException (typeof (ArgumentException))]
1081                 public void QuoteCharInvalid ()
1082                 {
1083                         xtw.QuoteChar = 'x';
1084                 }
1085
1086                 [Test]
1087                 public void WriteBase64 ()
1088                 {
1089                         UTF8Encoding encoding = new UTF8Encoding();
1090                         byte[] fooBar = encoding.GetBytes("foobar");
1091                         xtw.WriteBase64 (fooBar, 0, 6);
1092                         Assert.AreEqual ("Zm9vYmFy", StringWriterText);
1093
1094                         try {
1095                                 xtw.WriteBase64 (fooBar, 3, 6);
1096                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
1097                         } catch (ArgumentException) {}
1098
1099                         try {
1100                                 xtw.WriteBase64 (fooBar, -1, 6);
1101                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
1102                         } catch (ArgumentOutOfRangeException) {}
1103
1104                         try {
1105                                 xtw.WriteBase64 (fooBar, 3, -1);
1106                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
1107                         } catch (ArgumentOutOfRangeException) {}
1108
1109                         try {
1110                                 xtw.WriteBase64 (null, 0, 6);
1111                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
1112                         } catch (ArgumentNullException) {}
1113                 }
1114
1115                 [Test]
1116                 public void WriteBinHex ()
1117                 {
1118                         byte [] bytes = new byte [] {4,14,34, 54,94,114, 134,194,255, 0,5};
1119                         xtw.WriteBinHex (bytes, 0, 11);
1120                         Assert.AreEqual ("040E22365E7286C2FF0005", StringWriterText);
1121                 }
1122
1123                 [Test]
1124                 public void WriteCharEntity ()
1125                 {
1126                         xtw.WriteCharEntity ('a');
1127                         Assert.AreEqual ("&#x61;", StringWriterText);
1128
1129                         xtw.WriteCharEntity ('A');
1130                         Assert.AreEqual ("&#x61;&#x41;", StringWriterText);
1131
1132                         xtw.WriteCharEntity ('1');
1133                         Assert.AreEqual ("&#x61;&#x41;&#x31;", StringWriterText);
1134
1135                         xtw.WriteCharEntity ('K');
1136                         Assert.AreEqual ("&#x61;&#x41;&#x31;&#x4B;", StringWriterText);
1137
1138                         try {
1139                                 xtw.WriteCharEntity ((char)0xd800);
1140                         } catch (ArgumentException) {}
1141                 }
1142
1143                 [Test]
1144                 [ExpectedException (typeof (InvalidOperationException))]
1145                 public void WriteEndAttribute ()
1146                 {
1147                         xtw.WriteEndAttribute ();
1148                 }
1149
1150                 [Test]
1151                 public void WriteEndDocument ()
1152                 {
1153                         try {
1154                                 xtw.WriteEndDocument ();
1155                                 Assert.Fail ("Expected an Exception.");
1156                         // in .NET 2.0 it is InvalidOperationException.
1157                         // in .NET 1,1 it is ArgumentException.
1158                         } catch (Exception) {}
1159                 }
1160
1161                 [Test]
1162                 public void WriteEndDocument2 ()
1163                 {
1164                         xtw.WriteStartDocument ();
1165                         try 
1166                         {
1167                                 xtw.WriteEndDocument ();
1168                                 Assert.Fail ("Expected an Exception.");
1169                         // in .NET 2.0 it is InvalidOperationException.
1170                         // in .NET 1,1 it is ArgumentException.
1171                         } catch (Exception) {}
1172                 }
1173
1174                 [Test]
1175                 public void WriteEndDocument3 ()
1176                 {
1177                         xtw.WriteStartDocument ();
1178                         xtw.WriteStartElement ("foo");
1179                         xtw.WriteStartAttribute ("bar", null);
1180                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='", StringWriterText);
1181
1182                         xtw.WriteEndDocument ();
1183                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", StringWriterText);
1184                         Assert.AreEqual (WriteState.Start, xtw.WriteState);
1185                 }
1186
1187                 [Test]
1188                 [ExpectedException (typeof (InvalidOperationException))]
1189                 public void WriteEndElement ()
1190                 {
1191                         // no matching StartElement
1192                         xtw.WriteEndElement ();
1193                 }
1194
1195                 [Test]
1196                 public void WriteEndElement2 ()
1197                 {
1198                         xtw.WriteStartElement ("foo");
1199                         xtw.WriteEndElement ();
1200                         Assert.AreEqual ("<foo />", StringWriterText);
1201
1202                         xtw.WriteStartElement ("bar");
1203                         xtw.WriteStartAttribute ("baz", null);
1204                         xtw.WriteEndElement ();
1205                         Assert.AreEqual ("<foo /><bar baz='' />", StringWriterText);
1206                 }
1207
1208                 [Test]
1209                 public void FullEndElement ()
1210                 {
1211                         xtw.WriteStartElement ("foo");
1212                         xtw.WriteFullEndElement ();
1213                         Assert.AreEqual ("<foo></foo>", StringWriterText);
1214
1215                         xtw.WriteStartElement ("bar");
1216                         xtw.WriteAttributeString ("foo", "bar");
1217                         xtw.WriteFullEndElement ();
1218                         Assert.AreEqual ("<foo></foo><bar foo='bar'></bar>", StringWriterText);
1219
1220                         xtw.WriteStartElement ("baz");
1221                         xtw.WriteStartAttribute ("bar", null);
1222                         xtw.WriteFullEndElement ();
1223                         Assert.AreEqual ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", StringWriterText);
1224                 }
1225
1226                 [Test]
1227                 public void WriteQualifiedName ()
1228                 {
1229                         xtw.WriteStartElement (null, "test", null);
1230                         xtw.WriteAttributeString ("xmlns", "me", null, "http://localhost/");
1231                         xtw.WriteQualifiedName ("bob", "http://localhost/");
1232                         xtw.WriteEndElement ();
1233
1234                         Assert.AreEqual ("<test xmlns:me='http://localhost/'>me:bob</test>", StringWriterText);
1235                 }
1236
1237                 [Test]
1238                 public void WriteQualifiedNameNonDeclaredAttribute ()
1239                 {
1240                         xtw.WriteStartElement ("foo");
1241                         xtw.WriteStartAttribute ("a", "");
1242                         xtw.WriteQualifiedName ("attr", "urn:a");
1243                         xtw.WriteWhitespace (" ");
1244                         xtw.WriteQualifiedName ("attr", "urn:b");
1245                         xtw.WriteEndAttribute ();
1246                         xtw.WriteEndElement ();
1247                         string xml = sw.ToString ();
1248                         Assert.IsTrue (xml.IndexOf ("<foo ") >= 0, "foo");
1249                         Assert.IsTrue (xml.IndexOf ("a='d1p1:attr d1p2:attr'") > 0, "qnames");
1250                         Assert.IsTrue (xml.IndexOf (" xmlns:d1p1='urn:a'") > 0, "xmlns:a");
1251                         Assert.IsTrue (xml.IndexOf (" xmlns:d1p2='urn:b'") > 0, "xmlns:b");
1252                 }
1253
1254                 [Test]
1255                 public void WriteQualifiedNameNonNamespacedName ()
1256                 {
1257                         xtw.WriteStartElement ("root");
1258                         xtw.WriteQualifiedName ("foo", "");
1259                         xtw.WriteEndElement ();
1260                         Assert.AreEqual ("<root>foo</root>", StringWriterText);
1261                 }
1262
1263                 [Test]
1264                 [ExpectedException (typeof (ArgumentException))]
1265                 public void WriteQualifiedNameNonDeclaredContent ()
1266                 {
1267                         xtw.WriteStartElement ("foo");
1268                         xtw.WriteQualifiedName ("abc", "urn:abc");
1269                 }
1270
1271                 [Test]
1272                 [ExpectedException (typeof (ArgumentException))]
1273                 public void WriteQualifiedNameNonNCName ()
1274                 {
1275                         xtw.WriteStartElement ("foo");
1276                         xtw.WriteAttributeString ("xmlns", "urn:default");
1277                         xtw.WriteStartElement ("child");
1278                         xtw.WriteStartAttribute ("a", "");
1279                         xtw.WriteQualifiedName ("x:def", "urn:def");
1280                 }
1281
1282                 [Test]
1283                 public void WriteRaw ()
1284                 {
1285                         xtw.WriteRaw("&<>\"'");
1286                         Assert.AreEqual ("&<>\"'", StringWriterText);
1287
1288                         xtw.WriteRaw(null);
1289                         Assert.AreEqual ("&<>\"'", StringWriterText);
1290
1291                         xtw.WriteRaw("");
1292                         Assert.AreEqual ("&<>\"'", StringWriterText);
1293
1294                         // bug #77623
1295                         xtw.WriteRaw ("{0}{1}");
1296                 }
1297
1298                 [Test]
1299                 public void WriteRawInvalidInAttribute ()
1300                 {
1301                         xtw.WriteStartElement ("foo");
1302                         xtw.WriteStartAttribute ("bar", null);
1303                         xtw.WriteRaw ("&<>\"'");
1304                         xtw.WriteEndAttribute ();
1305                         xtw.WriteEndElement ();
1306                         Assert.AreEqual ("<foo bar='&<>\"'' />", StringWriterText);
1307                 }
1308
1309                 [Test]
1310                 public void WriteStateTest ()
1311                 {
1312                         Assert.AreEqual (WriteState.Start, xtw.WriteState);
1313                         xtw.WriteStartDocument ();
1314                         Assert.AreEqual (WriteState.Prolog, xtw.WriteState);
1315                         xtw.WriteStartElement ("root");
1316                         Assert.AreEqual (WriteState.Element, xtw.WriteState);
1317                         xtw.WriteElementString ("foo", "bar");
1318                         Assert.AreEqual (WriteState.Content, xtw.WriteState);
1319                         xtw.Close ();
1320                         Assert.AreEqual (WriteState.Closed, xtw.WriteState);
1321                 }
1322
1323                 [Test]
1324                 public void WriteString ()
1325                 {
1326                         xtw.WriteStartDocument ();
1327                         try {
1328                                 xtw.WriteString("foo");
1329                                 Assert.Fail ("should raise an error.");
1330                         } catch (InvalidOperationException) {}
1331                 }
1332
1333                 [Test]
1334                 public void WriteString2 ()
1335                 {
1336                         xtw.WriteStartDocument ();
1337                         // Testing attribute values
1338
1339                         xtw.WriteStartElement ("foo");
1340                         xtw.WriteAttributeString ("bar", "&<>");
1341                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='&amp;&lt;&gt;'", StringWriterText);
1342                 }
1343
1344                 [Test]
1345                 public void WriteAttributeStringSingleQuoteChar()
1346                 {
1347                         // When QuoteChar is single quote then replaces single quotes within attributes
1348                         // but not double quotes.
1349                         xtw.WriteStartElement ("foo");
1350                         xtw.WriteAttributeString ("bar", "\"baz\"");
1351                         xtw.WriteAttributeString ("quux", "'baz'");
1352                         Assert.AreEqual ("<foo bar='\"baz\"' quux='&apos;baz&apos;'", StringWriterText);
1353                 }
1354
1355                 [Test]
1356                 public void WriteAttributeStringDoubleQuoteChar()
1357                 {
1358                         // When QuoteChar is double quote then replaces double quotes within attributes
1359                         // but not single quotes.
1360                         xtw.QuoteChar = '"';
1361                         xtw.WriteStartElement ("foo");
1362                         xtw.WriteAttributeString ("bar", "\"baz\"");
1363                         xtw.WriteAttributeString ("quux", "'baz'");
1364                         Assert.AreEqual ("<foo bar=\"&quot;baz&quot;\" quux=\"'baz'\"", StringWriterText);
1365                 }
1366
1367                 [Test]
1368                 public void WriteStringWithEntities()
1369                 {
1370                         // Testing element values
1371                         xtw.QuoteChar = '\'';
1372                         xtw.WriteElementString ("foo", "&<>\"'");
1373                         Assert.AreEqual ("<foo>&amp;&lt;&gt;\"'</foo>", StringWriterText);
1374                 }
1375
1376                 [Test]
1377                 public void XmlLang ()
1378                 {
1379                         Assert.IsNull (xtw.XmlLang);
1380                         
1381                         xtw.WriteStartElement ("foo");
1382                         xtw.WriteAttributeString ("xml", "lang", null, "langfoo");
1383                         Assert.AreEqual ("langfoo", xtw.XmlLang);
1384                         Assert.AreEqual ("<foo xml:lang='langfoo'", StringWriterText);
1385
1386                         xtw.WriteAttributeString ("boo", "yah");
1387                         Assert.AreEqual ("langfoo", xtw.XmlLang);
1388                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'", StringWriterText);
1389                         
1390                         xtw.WriteElementString("bar", "baz");
1391                         Assert.AreEqual ("langfoo", xtw.XmlLang);
1392                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", StringWriterText);
1393                         
1394                         xtw.WriteString("baz");
1395                         Assert.AreEqual ("langfoo", xtw.XmlLang);
1396                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", StringWriterText);
1397                         
1398                         xtw.WriteStartElement ("quux");
1399                         xtw.WriteStartAttribute ("xml", "lang", null);
1400                         Assert.AreEqual ("langfoo", xtw.XmlLang);
1401                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText);
1402                         
1403                         xtw.WriteString("langbar");
1404                         // Commented out there: it is implementation-dependent.
1405                         // and incompatible between .NET 1.0 and 1.1
1406                         // Assert.AreEqual ("langfoo", xtw.XmlLang);
1407                         // Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText);
1408                         
1409                         xtw.WriteEndAttribute ();
1410                         // Commented out there: it is implementation-dependent.
1411                         // and incompatible between .NET 1.0 and 1.1
1412                         // Assert.AreEqual ("langbar", xtw.XmlLang);
1413                         // Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'", StringWriterText);
1414
1415                         // check if xml:lang repeats output even if same as current scope.
1416                         xtw.WriteStartElement ("joe");
1417                         xtw.WriteAttributeString ("xml", "lang", null, "langbar");
1418                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'", StringWriterText);
1419
1420                         
1421                         xtw.WriteElementString ("quuux", "squonk");
1422                         Assert.AreEqual ("langbar", xtw.XmlLang);
1423                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux>", StringWriterText);
1424
1425                         xtw.WriteEndElement ();
1426                         xtw.WriteEndElement ();
1427                         Assert.AreEqual ("langfoo", xtw.XmlLang);
1428                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux>", StringWriterText);
1429                         
1430                         xtw.WriteEndElement ();
1431                         Assert.IsNull (xtw.XmlLang);
1432                         Assert.AreEqual ("<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);
1433                         
1434                         xtw.Close ();
1435                         Assert.IsNull (xtw.XmlLang);
1436                 }
1437
1438                 // TODO: test operational aspects
1439                 [Test]
1440                 public void XmlSpaceTest ()
1441                 {
1442                         xtw.WriteStartElement ("foo");
1443                         Assert.AreEqual (XmlSpace.None, xtw.XmlSpace, "#1");
1444
1445                         xtw.WriteStartElement ("bar");
1446                         xtw.WriteAttributeString ("xml", "space", null, "preserve");
1447                         Assert.AreEqual (XmlSpace.Preserve, xtw.XmlSpace, "#2");
1448                         Assert.AreEqual ("<foo><bar xml:space='preserve'", StringWriterText, "#3");
1449
1450                         xtw.WriteStartElement ("baz");
1451                         xtw.WriteAttributeString ("xml", "space", null, "preserve");
1452                         Assert.AreEqual (XmlSpace.Preserve, xtw.XmlSpace, "#4");
1453                         Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'", StringWriterText, "#5");
1454
1455                         xtw.WriteStartElement ("quux");
1456                         xtw.WriteStartAttribute ("xml", "space", null);
1457                         Assert.AreEqual (XmlSpace.Preserve, xtw.XmlSpace, "#6");
1458                         Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText, "#7");
1459
1460                         // Commented out there: it is implementation-dependent
1461                         // and incompatible between .NET 1.0 and 1.1
1462                         xtw.WriteString ("default");
1463                         // Assert.AreEqual (XmlSpace.Preserve, xtw.XmlSpace);
1464                         // Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText);
1465                         
1466                         xtw.WriteEndAttribute ();
1467                         Assert.AreEqual (XmlSpace.Default, xtw.XmlSpace, "#8");
1468                         Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='default'", StringWriterText, "#9");
1469
1470                         xtw.WriteEndElement ();
1471                         Assert.AreEqual (XmlSpace.Preserve, xtw.XmlSpace, "#10");
1472                         xtw.WriteEndElement ();
1473                         Assert.AreEqual (XmlSpace.Preserve, xtw.XmlSpace, "#11");
1474                         xtw.WriteEndElement ();
1475                         Assert.AreEqual (XmlSpace.None, xtw.XmlSpace, "#12");
1476
1477                         xtw.WriteStartElement ("quux");
1478                 }
1479
1480                 [Test]
1481                 [ExpectedException (typeof (ArgumentException))]
1482                 public void XmlSpaceTestInvalidValue1 ()
1483                 {
1484                         xtw.WriteStartElement ("foo");
1485                         xtw.WriteAttributeString ("xml", "space", null, "bubba");
1486                 }
1487
1488                 [Test]
1489                 [ExpectedException (typeof (ArgumentException))]
1490                 public void XmlSpaceTestInvalidValue2 ()
1491                 {
1492                         xtw.WriteStartElement ("foo");
1493                         xtw.WriteAttributeString ("xml", "space", null, "PRESERVE");
1494                 }
1495
1496                 [Test]
1497                 [ExpectedException (typeof (ArgumentException))]
1498                 public void XmlSpaceTestInvalidValue3 ()
1499                 {
1500                         xtw.WriteStartElement ("foo");
1501                         xtw.WriteAttributeString ("xml", "space", null, "Default");
1502                 }
1503
1504                 [Test]
1505                 [ExpectedException (typeof (ArgumentException))]
1506                 public void XmlSpaceTestInvalidValue4 ()
1507                 {
1508                         xtw.WriteStartElement ("foo");
1509                         xtw.WriteAttributeString ("xml", "space", null, "bubba");
1510                 }
1511
1512                 [Test]
1513                 [ExpectedException (typeof (ArgumentException))]
1514                 public void WriteWhitespaceNonWhitespace ()
1515                 {
1516                         xtw.WriteWhitespace ("x");
1517                 }
1518
1519                 [Test]
1520                 [ExpectedException (typeof (ArgumentException))]
1521                 public void WriteWhitespace_Null ()
1522                 {
1523                         xtw.WriteWhitespace ((string) null);
1524                 }
1525
1526                 [Test]
1527                 [ExpectedException (typeof (ArgumentException))]
1528                 public void WriteWhitespace_Empty ()
1529                 {
1530                         xtw.WriteWhitespace (string.Empty);
1531                 }
1532
1533                 [Test]
1534                 [ExpectedException (typeof (ArgumentException))]
1535                 public void WriteNmToken_Null ()
1536                 {
1537                         xtw.WriteNmToken ((string) null);
1538                 }
1539
1540                 [Test]
1541                 [ExpectedException (typeof (ArgumentException))]
1542                 public void WriteNmToken_Empty ()
1543                 {
1544                         xtw.WriteNmToken (string.Empty);
1545                 }
1546
1547                 [Test]
1548                 [ExpectedException (typeof (ArgumentException))]
1549                 public void WriteNmToken_InvalidChars ()
1550                 {
1551                         xtw.WriteNmToken ("\uFFFF");
1552                 }
1553
1554                 [Test]
1555                 public void WriteNmToken ()
1556                 {
1557                         xtw.WriteNmToken ("some:name");
1558                         Assert.AreEqual ("some:name", StringWriterText);
1559                 }
1560
1561                 [Test]
1562                 public void XmlSpaceRaw ()
1563                 {
1564                         xtw.WriteStartElement ("foo");
1565                         xtw.WriteStartAttribute ("xml", "space", null);
1566                         Assert.AreEqual (XmlSpace.None, xtw.XmlSpace);
1567                         Assert.AreEqual ("<foo xml:space='", StringWriterText);
1568
1569                         xtw.WriteString ("default");
1570                         // Commented out there: it is implementation-dependent
1571                         // and incompatible between .NET 1.0 and 1.1
1572                         // Assert.AreEqual (XmlSpace.None, xtw.XmlSpace);
1573                         // Assert.AreEqual ("<foo xml:space='", StringWriterText);
1574
1575                         xtw.WriteEndAttribute ();
1576                         Assert.AreEqual (XmlSpace.Default, xtw.XmlSpace);
1577                         Assert.AreEqual ("<foo xml:space='default'", StringWriterText);
1578                 }
1579
1580                 [Test]
1581                 public void WriteAttributes ()
1582                 {
1583                         XmlDocument doc = new XmlDocument();
1584                         StringWriter sw = new StringWriter();
1585                         XmlWriter wr = new XmlTextWriter(sw);
1586                         StringBuilder sb = sw.GetStringBuilder();
1587                         XmlParserContext ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
1588                         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);
1589
1590                         xtr.Read();     // read XMLDecl
1591                         wr.WriteAttributes(xtr, false);
1592                         // This method don't always have to take this double-quoted style...
1593                         Assert.AreEqual ("version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"", sw.ToString ().Trim (),
1594                                 "#WriteAttributes.XmlDecl.1");
1595
1596                         sb.Remove(0, sb.Length);        // init
1597                         ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
1598                         xtr = new XmlTextReader("<?xml version='1.0'             standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
1599                         xtr.Read();     // read XMLDecl
1600                         Assert.AreEqual (XmlNodeType.XmlDeclaration, xtr.NodeType);
1601                         sw = new StringWriter ();
1602                         wr = new XmlTextWriter (sw);
1603
1604                         // This block raises an error on MS.NET 1.0.
1605                         wr.WriteAttributes(xtr, false);
1606                         // This method don't always have to take this double-quoted style...
1607                         Assert.AreEqual ("version=\"1.0\" standalone=\"no\"", sw.ToString ().Trim (),
1608                                 "#WriteAttributes.XmlDecl.2");
1609
1610                         sw = new StringWriter ();
1611                         wr = new XmlTextWriter (sw);
1612                         sb.Remove(0, sb.Length);        // init
1613
1614                         xtr.Read();     // read root
1615                         Assert.AreEqual (XmlNodeType.Element, xtr.NodeType);
1616                         wr.WriteStartElement(xtr.LocalName, xtr.NamespaceURI);
1617                         wr.WriteAttributes(xtr, false);
1618                         wr.WriteEndElement();
1619                         wr.Close();
1620                         // This method don't always have to take this double-quoted style...
1621                         Assert.AreEqual ("<root a1=\"A\" b2=\"B\" c3=\"C\" />", sw.ToString ().Trim (),
1622                                 "#WriteAttributes.Element");
1623                         xtr.Close ();
1624                 }
1625
1626                 [Test]
1627                 public void WriteWhitespace ()
1628                 {
1629                         xtw.WriteStartElement ("a");
1630                         xtw.WriteWhitespace ("\n\t");
1631                         xtw.WriteStartElement ("b");
1632                         xtw.WriteWhitespace ("\n\t");
1633                         xtw.WriteEndElement ();
1634                         xtw.WriteWhitespace ("\n");
1635                         xtw.WriteEndElement ();
1636                         xtw.WriteWhitespace ("\n");
1637                         xtw.Flush ();
1638                         Assert.AreEqual ("<a>\n\t<b>\n\t</b>\n</a>\n", StringWriterText);
1639                 }
1640
1641                 [Test]
1642                 public void FlushDoesntCloseTag ()
1643                 {
1644                         xtw.WriteStartElement ("foo");
1645                         xtw.WriteAttributeString ("bar", "baz");
1646                         xtw.Flush ();
1647                         Assert.AreEqual ("<foo bar='baz'", StringWriterText);
1648                 }
1649
1650                 [Test]
1651                 public void WriteWhitespaceClosesTag ()
1652                 {
1653                         xtw.WriteStartElement ("foo");
1654                         xtw.WriteAttributeString ("bar", "baz");
1655                         xtw.WriteWhitespace (" ");
1656                         Assert.AreEqual ("<foo bar='baz'> ", StringWriterText);
1657                 }
1658
1659                 [Test]
1660                 public void DontOutputMultipleXmlns ()
1661                 {
1662                         XmlDocument doc = new XmlDocument();
1663                         doc.LoadXml("<a xmlns:dt=\"b\" dt:dt=\"c\"/>");
1664                         XmlDocument doc2 = new XmlDocument();
1665                         doc2.LoadXml(doc.InnerXml);
1666                         Assert.AreEqual ("<a xmlns:dt=\"b\" dt:dt=\"c\" />",
1667                                 doc2.OuterXml);
1668                 }
1669
1670                 [Test]
1671                 public void DontOutputNonDeclaredXmlns ()
1672                 {
1673                         string xml = "<x:a foo='foo' xmlns:x='urn:foo'><b /></x:a>";
1674                         XmlDocument doc = new XmlDocument();
1675                         doc.LoadXml(xml);
1676                         XmlDocument doc2 = new XmlDocument();
1677                         doc2.LoadXml(doc.InnerXml);
1678                         Assert.AreEqual (xml.Replace ('\'', '"'), doc2.OuterXml);
1679                 }
1680
1681                 [Test]
1682                 public void DontOutputRemovalDefaultNSDeclaration ()
1683                 {
1684                         xtw.WriteStartDocument ();
1685                         xtw.WriteStartElement ("foo");
1686                         xtw.WriteAttributeString ("xmlns", "probe");
1687                         Assert.AreEqual (String.Empty, xtw.LookupPrefix ("probe"), "#1");
1688                         xtw.WriteStartElement ("b");
1689                         Assert.AreEqual (String.Empty, xtw.LookupPrefix ("probe"), "#2");
1690                         xtw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1691                         xtw.WriteEndElement (); // b2
1692                         xtw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1693                         xtw.WriteEndElement (); // b2
1694                         xtw.WriteEndElement (); // b
1695                         xtw.WriteEndElement (); // foo
1696                         xtw.WriteEndDocument ();
1697                         xtw.Close ();
1698
1699                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 xmlns='' /></b></foo>", StringWriterText, "#3");
1700                 }
1701
1702                 [Test]
1703                 public void DontOutputRemovalDefaultNSDeclaration2 ()
1704                 {
1705                         xtw.WriteStartDocument ();
1706                         // IMPORTANT DIFFERENCE!! ns = "", not null
1707                         xtw.WriteStartElement ("foo", "");
1708                         xtw.WriteAttributeString ("xmlns", "probe");
1709                         Assert.IsNull (xtw.LookupPrefix ("probe"), "#1");
1710                         xtw.WriteStartElement ("b");
1711                         Assert.IsNull (xtw.LookupPrefix ("probe"), "#2");
1712                         xtw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1713                         xtw.WriteEndElement (); // b2
1714                         xtw.WriteStartElement (null, "b2", ""); // *Don't* output xmlns=""
1715                         xtw.WriteEndElement (); // b2
1716                         xtw.WriteEndElement (); // b
1717                         xtw.WriteEndElement (); // foo
1718                         xtw.WriteEndDocument ();
1719                         xtw.Close ();
1720
1721                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 /></b></foo>", StringWriterText, "#3");
1722                 }
1723
1724                 [Test]
1725                 public void DoOutputRemovalDefaultNSDeclaration ()
1726                 {
1727                         xtw.WriteStartElement ("docelem", "a-namespace");
1728                         
1729                         XmlDocument doc = new XmlDocument ();
1730                         doc.CreateElement ("hola").WriteTo (xtw);
1731                         // This means, WriteTo never passes null NamespaceURI argument to XmlWriter.
1732                         xtw.WriteEndElement ();
1733                         xtw.Close ();
1734
1735                         Assert.AreEqual ("<docelem xmlns='a-namespace'><hola xmlns='' /></docelem>", StringWriterText);
1736                 }
1737
1738                 [Test]
1739                 public void WriteAttributeTakePrecedenceOnXmlns ()
1740                 {
1741                         xtw.WriteStartElement ("root", "urn:foo");
1742                         xtw.WriteAttributeString ("xmlns", "urn:bar");
1743                         xtw.WriteEndElement ();
1744                         xtw.Close ();
1745                         Assert.AreEqual ("<root xmlns='urn:bar' />", StringWriterText);
1746                 }
1747
1748                 [Test]
1749                 [ExpectedException (typeof (ArgumentException))]
1750                 public void LookupPrefixNull ()
1751                 {
1752                         xtw.LookupPrefix (null);
1753                 }
1754
1755                 [Test]
1756                 [ExpectedException (typeof (ArgumentException))]
1757                 public void LookupPrefixEmpty ()
1758                 {
1759                         xtw.LookupPrefix (String.Empty);
1760                 }
1761
1762                 [Test]
1763                 public void LookupPrefixIgnoresXmlnsAttribute ()
1764                 {
1765                         Assert.IsNull (xtw.LookupPrefix ("urn:foo"));
1766                         xtw.WriteStartElement ("root");
1767                         Assert.IsNull (xtw.LookupPrefix ("urn:foo"));
1768                         xtw.WriteAttributeString ("xmlns", "urn:foo");
1769                         // Surprisingly to say, it is ignored!!
1770                         Assert.AreEqual (String.Empty, xtw.LookupPrefix ("urn:foo"));
1771                         xtw.WriteStartElement ("hoge");
1772                         // (still after flushing previous start element.)
1773                         Assert.AreEqual (String.Empty, xtw.LookupPrefix ("urn:foo"));
1774                         xtw.WriteStartElement ("fuga", "urn:foo");
1775                         // Is this testing on the correct way? Yes, here it is.
1776                         Assert.AreEqual (String.Empty, xtw.LookupPrefix ("urn:foo"));
1777                 }
1778
1779                 [Test]
1780                 public void WriteInvalidNames ()
1781                 {
1782                         xtw.WriteStartElement ("foo<>");
1783                         xtw.WriteAttributeString ("ho<>ge", "value");
1784                 }
1785
1786                 [Test]
1787                 [ExpectedException (typeof (ArgumentException))]
1788                 public void AttributeWriteStartAttributePrefixWithoutNS ()
1789                 {
1790                         xtw.WriteStartAttribute ("some", "foo", null);
1791                 }
1792
1793                 [Test]
1794                 public void AttributeWriteStartAttributeXmlnsNullNS ()
1795                 {
1796                         xtw.WriteStartAttribute ("xmlns", "foo", null);
1797                 }
1798
1799                 [Test]
1800                 [ExpectedException (typeof (ArgumentException))]
1801                 public void AttributeWriteEndAttributeXmlnsNullNs ()
1802                 {
1803                         // This test checks if the specified namespace URI is
1804                         // incorrectly empty or not. Compare it with
1805                         // AttributeWriteStartAttributeXmlnsNullNS().
1806                         xtw.WriteStartAttribute ("xmlns", "foo", null);
1807                         xtw.WriteEndAttribute ();
1808                 }
1809
1810                 [Test]
1811                 [ExpectedException (typeof (ArgumentException))]
1812                 public void AttributeWriteStartAttributePrefixXmlnsNonW3CNS ()
1813                 {
1814                         xtw.WriteStartAttribute ("xmlns", "foo", "urn:foo");
1815                 }
1816
1817                 [Test]
1818                 [ExpectedException (typeof (ArgumentException))]
1819                 public void AttributeWriteStartAttributeLocalXmlnsNonW3CNS ()
1820                 {
1821                         xtw.WriteStartAttribute ("", "xmlns", "urn:foo");
1822                 }
1823
1824                 [Test]
1825                 public void WriteRawProceedToProlog ()
1826                 {
1827                         XmlTextWriter xtw = new XmlTextWriter (new StringWriter ());
1828                         xtw.WriteRaw ("");
1829                         Assert.AreEqual (WriteState.Prolog, xtw.WriteState);
1830                 }
1831
1832                 [Test]
1833                 public void Indent ()
1834                 {
1835                         XmlDocument doc = new XmlDocument ();
1836                         doc.LoadXml ("<root><test>test<foo></foo>string</test><test>string</test></root>");
1837                         StringWriter sw = new StringWriter ();
1838                         sw.NewLine = "_";
1839                         XmlTextWriter xtw = new XmlTextWriter (sw);
1840                         xtw.Formatting = Formatting.Indented;
1841                         doc.WriteContentTo (xtw);
1842                         Assert.AreEqual (@"<root>_  <test>test<foo></foo>string</test>_  <test>string</test>_</root>", sw.ToString ());
1843                 }
1844
1845                 [Test]
1846                 public void Indent2 ()
1847                 {
1848                         StringWriter sw = new StringWriter ();
1849                         XmlTextWriter xtw = new XmlTextWriter (sw);
1850                         xtw.Formatting = Formatting.Indented;
1851                         // sadly, this silly usage of this method is actually
1852                         // used in WriteNode() in MS.NET.
1853                         xtw.WriteProcessingInstruction ("xml",
1854                                 "version=\"1.0\"");
1855                         xtw.WriteComment ("sample XML fragment");
1856                         Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
1857                                 @"<?xml version=""1.0""?>{0}" +
1858                                 "<!--sample XML fragment-->", Environment.NewLine),
1859                                 sw.ToString ());
1860                 }
1861
1862                 [Test]
1863                 public void Indent3 ()
1864                 {
1865                         XmlDocument doc = new XmlDocument ();
1866                         doc.PreserveWhitespace = true;
1867                         string s;
1868
1869                         doc.LoadXml ("<root><element></element><!-- comment indented --><element>sample <!-- comment non-indented --></element></root>");
1870                         s = GetIndentedOutput (doc.DocumentElement);
1871                         Assert.AreEqual (s, String.Format ("<root>{0}  <element>{0}  </element>{0}  <!-- comment indented -->{0}  <element>sample <!-- comment non-indented --></element>{0}</root>", "\n"), "#1");
1872
1873                         doc.LoadXml ("<root> \n<mid> \n<mid>   \n<child attr='value'>sample <nested attr='value' /> string</child>     <child2 attr='value'>sample string</child2>  <empty attr='value'/>\n<a>test</a> \n</mid> <returnValue>  <returnType>System.String</returnType>  </returnValue>  </mid>   </root>");
1874                         s = GetIndentedOutput (doc.DocumentElement);
1875                         Assert.AreEqual (s, String.Format ("<root> {0}<mid> {0}<mid>   {0}<child attr='value'>sample <nested attr='value' /> string</child>     <child2 attr='value'>sample string</child2>  <empty attr='value' />{0}<a>test</a> {0}</mid> <returnValue>  <returnType>System.String</returnType>  </returnValue>  </mid>   </root>", "\n"), "#2");
1876
1877                         doc.LoadXml ("<!-- after /MemberType and after /returnValue --><root><MemberType>blah</MemberType>\n  <returnValue><returnType>System.String</returnType></returnValue>\n  <Docs><summary>text</summary><value>text<see cref='ttt' /></value><remarks/></Docs></root>");
1878                         s = GetIndentedOutput (doc.DocumentElement);
1879                         Assert.AreEqual (s, String.Format ("<root>{0}  <MemberType>blah</MemberType>{0}  <returnValue><returnType>System.String</returnType></returnValue>{0}  <Docs><summary>text</summary><value>text<see cref='ttt' /></value><remarks /></Docs></root>", "\n"), "#3");
1880                 }
1881
1882                 string GetIndentedOutput (XmlNode n)
1883                 {
1884                         StringWriter sw = new StringWriter ();
1885                         sw.NewLine = "\n";
1886                         XmlTextWriter xtw = new XmlTextWriter (sw);
1887                         xtw.QuoteChar = '\'';
1888                         xtw.Formatting = Formatting.Indented;
1889                         n.WriteTo (xtw);
1890                         return sw.ToString ();
1891                 }
1892
1893                 [Test]
1894                 public void CloseTwice ()
1895                 {
1896                         StringWriter sw = new StringWriter ();
1897                         XmlTextWriter writer = new XmlTextWriter (sw);
1898                         writer.Close ();
1899                         // should not result in an exception
1900                         writer.Close ();
1901                 }
1902
1903                 [Test]
1904                 public void WriteRawWriteString ()
1905                 {
1906                         // WriteRaw () -> WriteString ().
1907                         xtw.WriteRaw ("");
1908                         xtw.WriteString ("foo");
1909                         Assert.AreEqual (WriteState.Content, xtw.WriteState);
1910                 }
1911
1912                 [Test]
1913                 public void LookupOverridenPrefix ()
1914                 {
1915                         xtw.WriteStartElement ("out");
1916                         xtw.WriteAttributeString ("xmlns", "baz", "http://www.w3.org/2000/xmlns/", "xyz");
1917                         xtw.WriteStartElement ("baz", "foo", "abc");
1918                         Assert.IsNull (xtw.LookupPrefix ("xyz"));
1919                 }
1920
1921                 [Test]
1922                 public void DuplicatingNamespaceMappingInAttributes ()
1923                 {
1924                         xtw.WriteStartElement ("out");
1925                         xtw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1926                         xtw.WriteAttributeString ("p", "bar", "urn:bar", "xyz");
1927                         xtw.WriteAttributeString ("p", "baz", "urn:baz", "xyz");
1928                         xtw.WriteStartElement ("out");
1929                         xtw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1930                         xtw.WriteStartElement ("out");
1931                         xtw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1932                         xtw.WriteEndElement ();
1933                         xtw.WriteEndElement ();
1934                         xtw.WriteEndElement ();
1935                         string xml = sw.ToString ();
1936                         Assert.IsTrue (xml.IndexOf ("p:foo='xyz'") > 0, "p:foo" + ". output is " + xml);
1937                         Assert.IsTrue (xml.IndexOf ("d1p1:bar='xyz'") > 0, "d1p1:bar" + ". output is " + xml);
1938                         Assert.IsTrue (xml.IndexOf ("d1p2:baz='xyz'") > 0, "d1p1:baz" + ". output is " + xml);
1939                         Assert.IsTrue (xml.IndexOf ("xmlns:d1p2='urn:baz'") > 0, "xmlns:d1p2" + ". output is " + xml);
1940                         Assert.IsTrue (xml.IndexOf ("xmlns:d1p1='urn:bar'") > 0, "xmlns:d1p1" + ". output is " + xml);
1941                         Assert.IsTrue (xml.IndexOf ("xmlns:p='urn:foo'") > 0, "xmlns:p" + ". output is " + xml);
1942                         Assert.IsTrue (xml.IndexOf ("<out p:foo='xyz'><out p:foo='xyz' /></out></out>") > 0, "remaining" + ". output is " + xml);
1943                 }
1944
1945                 [Test]
1946                 public void WriteXmlSpaceIgnoresNS ()
1947                 {
1948                         xtw.WriteStartElement ("root");
1949                         xtw.WriteAttributeString ("xml", "space", "abc", "preserve");
1950                         xtw.WriteEndElement ();
1951                         Assert.AreEqual ("<root xml:space='preserve' />", sw.ToString ());
1952                 }
1953
1954                 [Test] // bug #75546
1955                 public void WriteEmptyNSQNameInAttribute ()
1956                 {
1957                         XmlTextWriter xtw = new XmlTextWriter (TextWriter.Null);
1958                         xtw.WriteStartElement ("foo", "urn:goo");
1959                         xtw.WriteAttributeString ("xmlns:bar", "urn:bar");
1960                         xtw.WriteStartAttribute ("foo", "");
1961                         xtw.WriteQualifiedName ("n1", "urn:bar");
1962                         xtw.WriteEndAttribute ();
1963                         xtw.WriteStartAttribute ("foo", "");
1964                         xtw.WriteQualifiedName ("n2", "");
1965                         xtw.WriteEndAttribute ();
1966                 }
1967
1968                 [Test]
1969                 [ExpectedException (typeof (ArgumentException))]
1970                 // cannot bind any prefix to "http://www.w3.org/2000/xmlns/".
1971                 public void WriteQualifiedNameXmlnsError ()
1972                 {
1973                         xtw.WriteStartElement ("foo");
1974                         xtw.WriteQualifiedName ("", "http://www.w3.org/2000/xmlns/");
1975                 }
1976
1977                 [Test]
1978                 public void WriteDocType ()
1979                 {
1980                         // we have the following test matrix:
1981                         //
1982                         // | name | publicid | systemid | subset|
1983                         // |------------------------------------|
1984                         // |  X   |    X     |    X     |   X   | #01
1985                         // |  X   |    E     |    X     |   X   | #02
1986                         // |  X   |    X     |    E     |   X   | #03
1987                         // |  X   |    X     |    X     |   E   | #04
1988                         // |  X   |    E     |    E     |   X   | #05
1989                         // |  X   |    X     |    E     |   E   | #06
1990                         // |  X   |    E     |    X     |   E   | #07
1991                         // |  X   |    E     |    E     |   E   | #08
1992                         // |  X   |    N     |    X     |   X   | #09
1993                         // |  X   |    X     |    N     |   X   | #10
1994                         // |  X   |    X     |    X     |   N   | #11
1995                         // |  X   |    N     |    N     |   X   | #12
1996                         // |  X   |    X     |    N     |   N   | #13
1997                         // |  X   |    N     |    X     |   N   | #14
1998                         // |  X   |    N     |    N     |   N   | #15
1999                         //
2000                         // Legend:
2001                         // -------
2002                         // X = Has value
2003                         // E = Zero-length string
2004                         // N = Null
2005
2006                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2007                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "sub");
2008                         Assert.AreEqual ("<!DOCTYPE test PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'" +
2009                                 " 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'[sub]>",
2010                                 sw.ToString (), "#01");
2011
2012                         sw.GetStringBuilder ().Length = 0;
2013                         xtw = new XmlTextWriter (sw);
2014
2015                         xtw.WriteDocType ("test", string.Empty,
2016                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "sub");
2017                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"\"" +
2018                                 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"[sub]>",
2019                                 sw.ToString (), "#02");
2020
2021                         sw.GetStringBuilder ().Length = 0; 
2022                         xtw = new XmlTextWriter (sw);
2023
2024                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2025                                 string.Empty, "sub");
2026                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
2027                                 " \"\"[sub]>",
2028                                 sw.ToString (), "#03");
2029
2030                         sw.GetStringBuilder ().Length = 0;
2031                         xtw = new XmlTextWriter (sw);
2032
2033                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2034                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", string.Empty);
2035                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
2036                                 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"[]>",
2037                                 sw.ToString (), "#04");
2038
2039                         sw.GetStringBuilder ().Length = 0;
2040                         xtw = new XmlTextWriter (sw);
2041
2042                         xtw.WriteDocType ("test", string.Empty, string.Empty, "sub");
2043                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"\" \"\"[sub]>",
2044                                 sw.ToString (), "#05");
2045
2046                         sw.GetStringBuilder ().Length = 0;
2047                         xtw = new XmlTextWriter (sw);
2048
2049                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2050                                 string.Empty, string.Empty);
2051                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
2052                                 " \"\"[]>",
2053                                 sw.ToString (), "#06");
2054
2055                         sw.GetStringBuilder ().Length = 0;
2056                         xtw = new XmlTextWriter (sw);
2057
2058                         xtw.WriteDocType ("test", string.Empty,
2059                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", string.Empty);
2060                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"\"" +
2061                                 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"[]>",
2062                                 sw.ToString (), "#07");
2063
2064                         sw.GetStringBuilder ().Length = 0;
2065                         xtw = new XmlTextWriter (sw);
2066
2067                         xtw.WriteDocType ("test", string.Empty, string.Empty, string.Empty);
2068                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"\" \"\"[]>",
2069                                 sw.ToString (), "#08");
2070
2071                         sw.GetStringBuilder ().Length = 0;
2072                         xtw = new XmlTextWriter (sw);
2073
2074                         xtw.WriteDocType ("test", (string) null,
2075                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "sub");
2076                         Assert.AreEqual ("<!DOCTYPE test SYSTEM" +
2077                                 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"[sub]>",
2078                                 sw.ToString (), "#09");
2079
2080                         sw.GetStringBuilder ().Length = 0;
2081                         xtw = new XmlTextWriter (sw);
2082
2083                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2084                                 (string) null, "sub");
2085                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
2086                                 " \"\"[sub]>",
2087                                 sw.ToString (), "#10");
2088
2089                         sw.GetStringBuilder ().Length = 0;
2090                         xtw = new XmlTextWriter (sw);
2091
2092                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2093                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", (string) null);
2094                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
2095                                 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
2096                                 sw.ToString (), "#11");
2097
2098                         sw.GetStringBuilder ().Length = 0;
2099                         xtw = new XmlTextWriter (sw);
2100
2101                         xtw.WriteDocType ("test", (string) null, (string) null, "sub");
2102                         Assert.AreEqual ("<!DOCTYPE test[sub]>",
2103                                 sw.ToString (), "#12");
2104
2105                         sw.GetStringBuilder ().Length = 0; 
2106                         xtw = new XmlTextWriter (sw);
2107
2108                         xtw.WriteDocType ("test", "-//W3C//DTD XHTML 1.0 Strict//EN",
2109                                 (string) null, (string) null);
2110                         Assert.AreEqual ("<!DOCTYPE test PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" +
2111                                 " \"\">",
2112                                 sw.ToString (), "#13");
2113
2114                         sw.GetStringBuilder ().Length = 0;
2115                         xtw = new XmlTextWriter (sw);
2116
2117                         xtw.WriteDocType ("test", (string) null,
2118                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", (string) null);
2119                         Assert.AreEqual ("<!DOCTYPE test SYSTEM" +
2120                                 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">",
2121                                 sw.ToString (), "#14");
2122
2123                         sw.GetStringBuilder ().Length = 0;
2124                         xtw = new XmlTextWriter (sw);
2125
2126                         xtw.WriteDocType ("test", (string) null, (string) null, (string) null);
2127                         Assert.AreEqual ("<!DOCTYPE test>",
2128                                 sw.ToString (), "#15");
2129                 }
2130
2131                 [Test]
2132                 [ExpectedException (typeof (ArgumentException))]
2133                 public void WriteDocType_EmptyName ()
2134                 {
2135                         xtw.WriteDocType (string.Empty, "-//W3C//DTD XHTML 1.0 Strict//EN",
2136                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "sub");
2137                 }
2138
2139                 [Test]
2140                 [ExpectedException (typeof (ArgumentException))]
2141                 public void WriteDocType_NullName ()
2142                 {
2143                         xtw.WriteDocType ((string) null, "-//W3C//DTD XHTML 1.0 Strict//EN",
2144                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "sub");
2145                 }
2146
2147                 [Test] // bug #76095
2148                 public void SurrogatePairsInWriteString ()
2149                 {
2150                         MemoryStream ms = new MemoryStream ();
2151                         XmlWriter writer = new XmlTextWriter(ms, null);
2152                         writer.WriteElementString("a", "\ud800\udf39");
2153                         writer.Close();
2154                         byte [] referent = new byte [] {0x3c, 0x61, 0x3e, 0xf0,
2155                                 0x90, 0x8c, 0xb9, 0x3c, 0x2f, 0x61, 0x3e};
2156                         NUnit.Framework.Assert.AreEqual (referent, ms.ToArray ());
2157                 }
2158
2159                 [Test]
2160                 public void InvalidCharIsWrittenAsSillyReferences ()
2161                 {
2162                         // I can't say how MS XmlTextWriter is silly. 
2163                         // The expected output is *not* well-formed XML.
2164                         // Everyone have to make sure that he or she does 
2165                         // not write invalid characters directly so that
2166                         // the output XML string can be fed by other XML
2167                         // processors.
2168
2169                         // The funny thing is that XmlTextWriter spends
2170                         // significant performance on checking invalid
2171                         // characters, but results in nothing.
2172                         xtw.WriteElementString ("a", "\x0");
2173                         NUnit.Framework.Assert.AreEqual ("<a>&#x0;</a>",
2174                                 StringWriterText);
2175                 }
2176
2177                 [Test] // see also bug #77082
2178                 public void WriteDocTypeIndent ()
2179                 {
2180                         string expected = String.Format (@"<?xml version='1.0'?>{0}<!DOCTYPE root PUBLIC '' 'urn:foo'[]>{0}<root />", Environment.NewLine);
2181                         xtw.Formatting = Formatting.Indented;
2182                         xtw.WriteProcessingInstruction ("xml", "version='1.0'");
2183                         xtw.WriteDocType ("root", "", "urn:foo", "");
2184                         xtw.WriteStartElement ("root");
2185                         xtw.WriteEndElement ();
2186                         xtw.Close ();
2187                         Assert.AreEqual (expected, StringWriterText);
2188                 }
2189
2190                 [Test]
2191                 [ExpectedException (typeof (InvalidOperationException))]
2192                 public void WriteDocTypeTwice ()
2193                 {
2194                         xtw.WriteDocType ("root", "", "urn:foo", "");
2195                         xtw.WriteDocType ("root", "", "urn:foo", "");
2196                 }
2197
2198                 [Test]
2199                 [ExpectedException (typeof (InvalidOperationException))]
2200                 public void XmlDeclAfterDocType ()
2201                 {
2202                         xtw.WriteDocType ("root", "", "urn:foo", "");
2203                         xtw.WriteStartDocument ();
2204                 }
2205
2206                 [Test]
2207                 [ExpectedException (typeof (InvalidOperationException))]
2208                 public void XmlDeclAfterWhitespace ()
2209                 {
2210                         xtw.WriteWhitespace ("   ");
2211                         xtw.WriteStartDocument ();
2212                 }
2213
2214                 [Test]
2215                 [ExpectedException (typeof (InvalidOperationException))]
2216                 public void XmlDeclAfterPI ()
2217                 {
2218                         xtw.WriteProcessingInstruction ("pi", "");
2219                         xtw.WriteStartDocument ();
2220                 }
2221
2222                 [Test]
2223                 public void WriteRawEmptyCloseStartTag ()
2224                 {
2225                         xtw.WriteStartElement ("stream", "stream","http://etherx.jabber.org/streams");
2226                         xtw.WriteAttributeString ("version", "1.0");
2227                         xtw.WriteAttributeString ("to", "me@test.com");
2228                         xtw.WriteAttributeString ("from", "server");
2229                         xtw.WriteAttributeString ("xmlns", "jabber:client");
2230                         xtw.WriteRaw ("");// Ensure that the tag is closed
2231                         xtw.Flush ();
2232
2233                         Assert.AreEqual ("<stream:stream version='1.0' to='me@test.com' from='server' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>", StringWriterText);
2234                 }
2235
2236                 [Test] // bug #78148
2237                 public void UpdateFormattingOnTheFly ()
2238                 {
2239                         XmlTextWriter w = new XmlTextWriter (TextWriter.Null);
2240                         w.WriteStartElement ("test");
2241                         w.Formatting = Formatting.Indented;
2242                 }
2243
2244                 [Test] // bug #78598
2245                 public void WriteGlobalAttributeInDefaultNS ()
2246                 {
2247                         StringWriter sw = new StringWriter ();
2248                         XmlTextWriter tw = new XmlTextWriter (sw);
2249                         string ns = "http://schemas.xmlsoap.org/soap/envelope/";
2250                         tw.WriteStartElement ("Envelope");
2251                         tw.WriteAttributeString ("xmlns", ns);
2252                         int start = sw.ToString ().Length;
2253                         tw.WriteStartElement ("UserInfo");
2254                         tw.WriteStartAttribute ("actor", ns);
2255                         tw.WriteEndAttribute ();
2256                         tw.WriteEndElement ();
2257                         tw.WriteEndElement ();
2258                         Assert.IsTrue (sw.ToString ().IndexOf (ns, start) > 0);
2259                 }
2260
2261                 [Test]
2262                 public void WriteCommentPIAndIndent ()
2263                 {
2264                         StringWriter sw = new StringWriter ();
2265                         XmlTextWriter w = new XmlTextWriter (sw);
2266                         w.Formatting = Formatting.Indented;
2267                         w.WriteStartElement ("foo");
2268                         w.WriteComment ("test");
2269                         w.WriteProcessingInstruction ("PI", "");
2270                         w.WriteStartElement ("child");
2271                         w.WriteEndElement ();
2272                         w.WriteComment ("test");
2273                         w.WriteString ("STRING");
2274                         w.WriteEndElement ();
2275                         Assert.AreEqual (String.Format (@"<foo>{0}  <!--test-->{0}  <?PI ?>{0}  <child />{0}  <!--test-->STRING</foo>", Environment.NewLine), sw.ToString ());
2276                 }
2277
2278                 [Test]
2279                 public void WriteBinHexAttribute () // for bug #79019
2280                 {
2281                         XmlWriter writer = new XmlTextWriter (TextWriter.Null);
2282                         writer.WriteStartElement ("test");
2283                         byte [] buffer1 = new byte [] {200, 155};
2284                         writer.WriteStartAttribute ("key", "");
2285                         writer.WriteBinHex (buffer1, 0, buffer1.Length);
2286                         writer.WriteEndAttribute ();
2287                         writer.WriteEndElement ();
2288                 }
2289
2290                 [Test]
2291                 public void LookupNamespace ()
2292                 {
2293                         StringWriter sw = new StringWriter ();
2294                         XmlTextWriter xw = new XmlTextWriter (sw);
2295                         xw.Formatting = Formatting.Indented;
2296                         string q1 = "urn:test";
2297
2298                         string q1prefix_first= "q1";
2299                         // Ensure we get a different reference for the string "q1"
2300                         string q1prefix_second = ("q1" + "a").Substring(0,2);
2301
2302                         xw.WriteStartElement("document");
2303                         xw.WriteStartElement("item");
2304                         xw.WriteStartElement (q1prefix_first, "addMedia", q1);
2305                         xw.WriteEndElement();
2306                         xw.WriteEndElement();
2307                         xw.WriteStartElement("item");
2308                         xw.WriteStartElement (q1prefix_second, "addMedia", q1);
2309                         xw.WriteEndElement();
2310                         xw.WriteEndElement();
2311                         xw.WriteEndElement();
2312                         string xml = sw.ToString ();
2313                         int first = xml.IndexOf ("xmlns");
2314                         Assert.IsTrue (xml.IndexOf ("xmlns", first + 5) > 0);
2315                 }
2316
2317                 [Test]
2318                 public void WriteAttributePrefixedNullNamespace ()
2319                 {
2320                         StringWriter sw = new StringWriter ();
2321                         XmlWriter xw = new XmlTextWriter (sw);
2322                         xw.WriteStartElement ("root");
2323                         xw.WriteAttributeString ("xmlns", "abc", null, "uri:abcnamespace");
2324                         xw.WriteAttributeString ("abc", "def", null, "value");
2325                         xw.WriteEndElement ();
2326                         Assert.AreEqual ("<root xmlns:abc=\"uri:abcnamespace\" abc:def=\"value\" />", sw.ToString ());
2327                 }
2328
2329                 [Test]
2330                 public void WriteElementPrefixedNullNamespace ()
2331                 {
2332                         StringWriter sw = new StringWriter ();
2333                         XmlWriter xw = new XmlTextWriter (sw);
2334                         xw.WriteStartElement ("root");
2335                         xw.WriteAttributeString ("xmlns", "abc", null, "uri:abcnamespace");
2336                         xw.WriteStartElement ("abc", "def", null);
2337                         xw.WriteEndElement ();
2338                         xw.WriteEndElement ();
2339                         Assert.AreEqual ("<root xmlns:abc=\"uri:abcnamespace\"><abc:def /></root>", sw.ToString ());
2340                 }
2341
2342                 [Test]
2343                 [ExpectedException (typeof (InvalidOperationException))]
2344                 public void RejectWritingAtErrorState ()
2345                 {
2346                         try {
2347                                 xtw.WriteEndElement ();
2348                         } catch (Exception) {
2349                         }
2350
2351                         xtw.WriteStartElement ("foo");
2352                 }
2353         }
2354 }