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