2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / System.Runtime.Serialization / Test / System.Xml / XmlSimpleDictionaryWriterTest.cs
1 //
2 // XmlSimpleDictionaryWriterTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
8
9 //
10 // Copied from System.XML/Test/System.Xml/XmlTextWriterTests.cs
11 //
12 // Authors:
13 //   Kral Ferch <kral_ferch@hotmail.com>
14 //   Martin Willemoes Hansen <mwh@sysrq.dk>
15 //
16 // (C) 2002 Kral Ferch
17 // (C) 2003 Martin Willemoes Hansen
18 //
19
20 //
21 // Permission is hereby granted, free of charge, to any person obtaining
22 // a copy of this software and associated documentation files (the
23 // "Software"), to deal in the Software without restriction, including
24 // without limitation the rights to use, copy, modify, merge, publish,
25 // distribute, sublicense, and/or sell copies of the Software, and to
26 // permit persons to whom the Software is furnished to do so, subject to
27 // the following conditions:
28 // 
29 // The above copyright notice and this permission notice shall be
30 // included in all copies or substantial portions of the Software.
31 // 
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 //
40
41 using System;
42 using System.IO;
43 using System.Text;
44 using System.Xml;
45 using NUnit.Framework;
46
47 namespace MonoTests.System.Xml
48 {
49         [TestFixture]
50         public class XmlSimpleDictionaryWriterTest
51         {
52                 [Test]
53                 public void WriteXmlnsAttribute ()
54                 {
55                         xw.WriteStartElement ("l1");
56                         xw.WriteXmlAttribute ("lang", "ja");
57                         xw.WriteXmlnsAttribute ("f", "urn:foo");
58                         xw.WriteStartElement ("l2");
59                         xw.WriteXmlnsAttribute ("", "");
60                         xw.WriteEndElement ();
61                         xw.WriteStartElement ("l2");
62                         xw.WriteXmlnsAttribute ("", "urn:bar");
63                         xw.WriteEndElement ();
64                         xw.WriteEndElement ();
65                         xw.Flush ();
66                         Assert.AreEqual ("<l1 xml:lang='ja' xmlns:f='urn:foo'><l2 xmlns='' /><l2 xmlns='urn:bar' /></l1>", Output);
67                 }
68
69                 [Test]
70                 public void WriteXmlnsAttributeNullPrefix ()
71                 {
72                         xw.WriteStartElement ("root", "urn:x");
73                         xw.WriteXmlnsAttribute (null, "urn:foo");
74                         xw.WriteEndElement ();
75                         xw.Close ();
76                         Assert.AreEqual ("<root xmlns:d1p1='urn:foo' xmlns='urn:x' />", Output);
77                 }
78
79                 #region Copied from XmlTextWriterTests.cs
80
81                 StringWriter sw;
82                 XmlDictionaryWriter xw;
83
84                 [SetUp]
85                 public void GetReady ()
86                 {
87                         sw = new StringWriter ();
88                         XmlTextWriter xtw = new XmlTextWriter (sw);
89                         xtw.QuoteChar = '\'';
90                         xw = XmlDictionaryWriter.CreateDictionaryWriter (xtw);
91                 }
92
93                 private string Output
94                 {
95                         get { return sw.ToString (); }
96                 }
97
98                 [Test]
99                 public void AttributeNamespacesNonNamespaceAttributeBefore ()
100                 {
101                         xw.WriteStartElement ("foo");
102                         xw.WriteAttributeString("bar", "baz");
103                         xw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
104                         Assert.AreEqual ("<foo bar='baz' xmlns:abc='http://abc.def'", Output);
105                 }
106
107                 [Test]
108                 public void AttributeNamespacesNonNamespaceAttributeAfter ()
109                 {
110                         xw.WriteStartElement ("foo");
111
112                         xw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
113                         xw.WriteAttributeString("bar", "baz");
114                         Assert.AreEqual ("<foo xmlns:abc='http://abc.def' bar='baz'", Output);
115                 }
116
117                 [Test]
118                 public void AttributeNamespacesThreeParamWithNullInNamespaceParam ()
119                 {
120                         xw.WriteAttributeString ("xmlns", null, "http://abc.def");
121                         Assert.AreEqual ("xmlns='http://abc.def'", Output);
122                 }
123
124                 [Test]
125                 public void AttributeNamespacesThreeParamWithTextInNamespaceParam ()
126                 {
127                         try 
128                         {
129                                 xw.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
130                         } 
131                         catch (ArgumentException) {}
132                 }
133
134                 [Test]
135                 public void AttributeNamespacesWithNullInNamespaceParam ()
136                 {
137                         xw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
138                         Assert.AreEqual ("xmlns:abc='http://abc.def'", Output);
139                 }
140
141                 [Test]
142                 public void AttributeNamespacesWithTextInNamespaceParam ()
143                 {
144                         try {
145                                 xw.WriteAttributeString ("xmlns", "abc", "http://somenamespace.com", "http://abc.def");
146                         } catch (ArgumentException) {}
147                 }
148
149                 [Test]
150                 public void AttributeNamespacesXmlnsXmlns ()
151                 {
152                         xw.WriteStartElement ("foo");
153                         // When namespaceURI argument is null, constraints by
154                         // namespaces in XML are ignored.
155                         xw.WriteAttributeString ("xmlns", "xmlns", null, "http://abc.def");
156                         xw.WriteAttributeString ("", "xmlns", null, "http://abc.def");
157                 }
158
159                 [Test]
160                 public void AttributeWriteAttributeString ()
161                 {
162                         xw.WriteStartElement ("foo");
163
164                         xw.WriteAttributeString ("foo", "bar");
165                         Assert.AreEqual ("<foo foo='bar'", Output);
166
167                         xw.WriteAttributeString ("bar", "");
168                         Assert.AreEqual ("<foo foo='bar' bar=''", Output);
169
170                         xw.WriteAttributeString ("baz", null);
171                         Assert.AreEqual ("<foo foo='bar' bar='' baz=''", Output);
172
173                         xw.WriteAttributeString ("hoge", "a\nb");
174                         Assert.AreEqual ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b'", Output);
175
176                         xw.WriteAttributeString ("fuga", " a\t\r\nb\t");
177                         Assert.AreEqual ("<foo foo='bar' bar='' baz='' hoge='a&#xA;b' fuga=' a\t&#xD;&#xA;b\t'", Output);
178
179                         try {
180                                 // Why does this pass Microsoft?
181                                 // Anyway, Mono should not allow such code.
182                                 xw.WriteAttributeString ("", "quux");
183 //                              Assert.AreEqual ("<foo foo='bar' bar='' baz='' ='quux'", Output);
184                                 Assert.Fail ("empty name not allowed.");
185                         } catch (Exception) {
186                         }
187
188                         try {
189                                 // Why does this pass Microsoft?
190                                 // Anyway, Mono should not allow such code.
191                                 xw.WriteAttributeString (null, "quuux");
192 //                              Assert.AreEqual ("<foo foo='bar' bar='' baz='' ='quux' ='quuux'", Output);
193                                 Assert.Fail ("null name not allowed.");
194                         } catch (Exception) {
195                         }
196                 }
197
198                 [Test]
199                 [ExpectedException (typeof (InvalidOperationException))]
200                 public void AttributeWriteAttributeStringNotInsideOpenStartElement ()
201                 {
202                         xw.WriteStartElement ("foo");
203                         xw.WriteString ("bar");
204                         
205                         xw.WriteAttributeString ("baz", "quux");
206                 }
207
208                 [Test]
209                 public void AttributeWriteAttributeStringWithoutParentElement ()
210                 {
211                         xw.WriteAttributeString ("foo", "bar");
212                         Assert.AreEqual ("foo='bar'", Output);
213
214                         xw.WriteAttributeString ("baz", "quux");
215                         Assert.AreEqual ("foo='bar' baz='quux'", Output);
216                 }
217
218                 [Test]
219                 public void CDataValid ()
220                 {
221                         xw.WriteCData ("foo");
222                         Assert.AreEqual ("<![CDATA[foo]]>", Output,
223                                 "WriteCData had incorrect output.");
224                 }
225
226                 [Test]
227                 [ExpectedException (typeof (ArgumentException))]
228                 public void CDataInvalid ()
229                 {
230                         xw.WriteCData("foo]]>bar");
231                 }
232                 
233                 [Test]
234                 public void CloseOpenElements ()
235                 {
236                         xw.WriteStartElement("foo");
237                         xw.WriteStartElement("bar");
238                         xw.WriteStartElement("baz");
239                         xw.Close();
240                         Assert.AreEqual ("<foo><bar><baz /></bar></foo>",       Output,
241                                 "Close didn't write out end elements properly.");
242                 }
243
244                 [Test]
245                 public void CloseWriteAfter ()
246                 {
247                         xw.WriteElementString ("foo", "bar");
248                         xw.Close ();
249
250                         // WriteEndElement and WriteStartDocument aren't tested here because
251                         // they will always throw different exceptions besides 'The Writer is closed.'
252                         // and there are already tests for those exceptions.
253
254                         try {
255                                 xw.WriteCData ("foo");
256                                 Assert.Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
257                         } 
258                         catch (InvalidOperationException) {
259                                 // Don't rely on English message assertion.
260                                 // It is enough to check an exception occurs.
261 //                              Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
262                         }
263
264                         try {
265                                 xw.WriteComment ("foo");
266                                 Assert.Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
267                         } 
268                         catch (InvalidOperationException) {
269 //                              Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
270                         }
271
272                         try {
273                                 xw.WriteProcessingInstruction ("foo", "bar");
274                                 Assert.Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
275                         } 
276                         catch (InvalidOperationException) {
277 //                              Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
278                         }
279
280                         try {
281                                 xw.WriteStartElement ("foo", "bar", "baz");
282                                 Assert.Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
283                         } 
284                         catch (InvalidOperationException) {
285 //                              Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
286                         }
287
288                         try 
289                         {
290                                 xw.WriteAttributeString ("foo", "bar");
291                                 Assert.Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
292                         } 
293                         catch (InvalidOperationException) 
294                         {
295 //                              Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
296                         }
297
298                         try {
299                                 xw.WriteString ("foo");
300                                 Assert.Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
301                         } 
302                         catch (InvalidOperationException) {
303 //                              Assert.AreEqual ("Exception message is incorrect.", "The Writer is closed.", e.Message);
304                         }
305                 }
306
307                 [Test]
308                 public void CommentValid ()
309                 {
310                         xw.WriteComment ("foo");
311                         Assert.AreEqual ("<!--foo-->", Output,
312                                 "WriteComment had incorrect output.");
313                 }
314
315                 [Test]
316                 public void CommentInvalid ()
317                 {
318                         try {
319                                 xw.WriteComment("foo-");
320                                 Assert.Fail ("Should have thrown an ArgumentException.");
321                         } 
322                         catch (ArgumentException) { }
323
324                         try {
325                                 xw.WriteComment("foo-->bar");
326                                 Assert.Fail ("Should have thrown an ArgumentException.");
327                         } 
328                         catch (ArgumentException) { }
329                 }
330
331                 [Test]
332                 public void DocumentStart ()
333                 {
334                         xw.WriteStartDocument ();
335                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?>", Output,
336                                 "XmlDeclaration is incorrect.");
337
338                         try 
339                         {
340                                 xw.WriteStartDocument ();
341                                 Assert.Fail ("Should have thrown an InvalidOperationException.");
342                         } 
343                         catch (InvalidOperationException) {
344                                 // Don't rely on English message assertion.
345                                 // It is enough to check an exception occurs.
346 //                              Assert.AreEqual ("Exception message is incorrect.",
347 //                                      "WriteStartDocument should be the first call.", e.Message);
348                         }
349
350                         GetReady ();
351                         xw.WriteStartDocument (true);
352                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16' standalone='yes'?>", Output);
353
354                         GetReady ();
355                         xw.WriteStartDocument (false);
356                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16' standalone='no'?>", Output);
357                 }
358
359                 [Test]
360                 public void ElementAndAttributeSameXmlns ()
361                 {
362                         xw.WriteStartElement ("ped", "foo", "urn:foo");
363                         xw.WriteStartAttribute ("ped", "foo", "urn:foo");
364                         xw.WriteEndElement ();
365                         Assert.AreEqual ("<ped:foo ped:foo='' xmlns:ped='urn:foo' />", Output);
366                 }
367
368                 [Test]
369                 [Category ("NotDotNet")]
370                 public void ElementXmlnsNeedEscape ()
371                 {
372                         xw.WriteStartElement ("test", "foo", "'");
373                         xw.WriteEndElement ();
374                         // MS.NET output is : xmlns:test='''
375                         Assert.AreEqual ("<test:foo xmlns:test='&apos;' />", Output);
376                 }
377
378                 [Test]
379                 public void ElementEmpty ()
380                 {
381                         xw.WriteStartElement ("foo");
382                         xw.WriteEndElement ();
383                         Assert.AreEqual ("<foo />", Output);
384                 }
385
386                 [Test]
387                 public void ElementWriteElementString ()
388                 {
389                         xw.WriteElementString ("foo", "bar");
390                         Assert.AreEqual ("<foo>bar</foo>", Output,
391                                 "WriteElementString has incorrect output.");
392
393                         xw.WriteElementString ("baz", "");
394                         Assert.AreEqual ("<foo>bar</foo><baz />", Output);
395
396                         xw.WriteElementString ("quux", null);
397                         Assert.AreEqual ("<foo>bar</foo><baz /><quux />", Output);
398
399                         xw.WriteElementString ("", "quuux");
400                         Assert.AreEqual ("<foo>bar</foo><baz /><quux /><>quuux</>", Output);
401
402                         xw.WriteElementString (null, "quuuux");
403                         Assert.AreEqual ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", Output);
404                 }
405
406                 [Test]
407                 public void LookupPrefix ()
408                 {
409                         xw.WriteStartElement ("root");
410
411                         xw.WriteStartElement ("one");
412                         xw.WriteAttributeString ("xmlns", "foo", null, "http://abc.def");
413                         xw.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl");
414                         Assert.AreEqual ("foo", xw.LookupPrefix ("http://abc.def"));
415                         Assert.AreEqual ("bar", xw.LookupPrefix ("http://ghi.jkl"));
416                         xw.WriteEndElement ();
417
418                         xw.WriteStartElement ("two");
419                         xw.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr");
420                         xw.WriteString("quux");
421                         Assert.AreEqual ("baz", xw.LookupPrefix ("http://mno.pqr"));
422                         Assert.IsNull (xw.LookupPrefix ("http://abc.def"));
423                         Assert.IsNull (xw.LookupPrefix ("http://ghi.jkl"));
424
425                         Assert.IsNull (xw.LookupPrefix ("http://bogus"));
426                 }
427
428                 [Test]
429                 public void NamespacesNoNamespaceClearsDefaultNamespace ()
430                 {
431                         xw.WriteStartElement(String.Empty, "foo", "http://netsack.com/");
432                         xw.WriteStartElement(String.Empty, "bar", String.Empty);
433                         xw.WriteElementString("baz", String.Empty, String.Empty);
434                         xw.WriteEndElement();
435                         xw.WriteEndElement();
436                         Assert.AreEqual (
437                                 "<foo xmlns='http://netsack.com/'><bar xmlns=''><baz /></bar></foo>",
438                                 Output,
439                                 "XmlTextWriter is incorrectly outputting namespaces.");
440                 }
441
442                 [Test]
443                 public void NamespacesPrefix ()
444                 {
445                         xw.WriteStartElement ("foo", "bar", "http://netsack.com/");
446                         xw.WriteStartElement ("foo", "baz", "http://netsack.com/");
447                         xw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
448                         xw.WriteEndElement ();
449                         xw.WriteEndElement ();
450                         Assert.AreEqual ("<foo:bar xmlns:foo='http://netsack.com/'><foo:baz><foo:qux /></foo:baz></foo:bar>",
451                                 Output,
452                                 "XmlTextWriter is incorrectly outputting prefixes.");
453                 }
454
455                 [Test]
456                 // [ExpectedException (typeof (ArgumentException))]
457                 public void NamespacesPrefixWithEmptyAndNullNamespaceEmpty ()
458                 {
459                         xw.WriteStartElement ("foo", "bar", "");
460                 }
461
462                 [Test]
463                 [ExpectedException (typeof (ArgumentException))]
464                 public void NamespacesPrefixWithEmptyAndNullNamespaceNull ()
465                 {
466                         xw.WriteStartElement ("foo", "bar", null);
467                 }
468
469                 [Test]
470                 public void ProcessingInstructionValid ()
471                 {
472                         xw.WriteProcessingInstruction("foo", "bar");
473                         Assert.AreEqual ("<?foo bar?>", Output, "WriteProcessingInstruction had incorrect output.");
474                 }
475
476                 [Test]
477                 [ExpectedException (typeof (ArgumentException))]
478                 public void ProcessingInstructionInvalid1 ()
479                 {
480                         xw.WriteProcessingInstruction("fo?>o", "bar");
481                 }
482
483                 [Test]
484                 [ExpectedException (typeof (ArgumentException))]
485                 public void ProcessingInstructionInvalid2 ()
486                 {
487                         xw.WriteProcessingInstruction("foo", "ba?>r");
488                 }
489
490                 [Test]
491                 [ExpectedException (typeof (ArgumentException))]
492                 public void ProcessingInstructionInvalid3 ()
493                 {
494                         xw.WriteProcessingInstruction("", "bar");
495                 }
496
497                 [Test]
498                 [ExpectedException (typeof (ArgumentException))]
499                 public void ProcessingInstructionInvalid4 ()
500                 {
501                         xw.WriteProcessingInstruction(null, "bar");
502                 }
503
504                 [Test]
505                 public void WriteBase64 ()
506                 {
507                         UTF8Encoding encoding = new UTF8Encoding();
508                         byte[] fooBar = encoding.GetBytes("foobar");
509                         xw.WriteBase64 (fooBar, 0, 6);
510                         Assert.AreEqual("Zm9vYmFy", Output);
511
512                         try {
513                                 xw.WriteBase64 (fooBar, 3, 6);
514                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
515                         } catch (ArgumentException) {}
516
517                         try {
518                                 xw.WriteBase64 (fooBar, -1, 6);
519                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
520                         } catch (ArgumentOutOfRangeException) {}
521
522                         try {
523                                 xw.WriteBase64 (fooBar, 3, -1);
524                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
525                         } catch (ArgumentOutOfRangeException) {}
526
527                         try {
528                                 xw.WriteBase64 (null, 0, 6);
529                                 Assert.Fail ("Expected an Argument Exception to be thrown.");
530                         } catch (ArgumentNullException) {}
531                 }
532
533                 [Test]
534                 public void WriteBinHex ()
535                 {
536                         byte [] bytes = new byte [] {4,14,34, 54,94,114, 134,194,255, 0,5};
537                         xw.WriteBinHex (bytes, 0, 11);
538                         Assert.AreEqual ("040E22365E7286C2FF0005", Output);
539                 }
540
541                 [Test]
542                 public void WriteCharEntity ()
543                 {
544                         xw.WriteCharEntity ('a');
545                         Assert.AreEqual ("&#x61;", Output);
546
547                         xw.WriteCharEntity ('A');
548                         Assert.AreEqual ("&#x61;&#x41;", Output);
549
550                         xw.WriteCharEntity ('1');
551                         Assert.AreEqual ("&#x61;&#x41;&#x31;", Output);
552
553                         xw.WriteCharEntity ('K');
554                         Assert.AreEqual ("&#x61;&#x41;&#x31;&#x4B;", Output);
555
556                         try {
557                                 xw.WriteCharEntity ((char)0xd800);
558                         } catch (ArgumentException) {}
559                 }
560
561                 [Test]
562                 [ExpectedException (typeof (InvalidOperationException))]
563                 public void WriteEndAttribute ()
564                 {
565                         xw.WriteEndAttribute ();
566                 }
567
568                 [Test]
569                 public void WriteEndDocument ()
570                 {
571                         try {
572                                 xw.WriteEndDocument ();
573                                 Assert.Fail ("Expected an Exception.");
574                         // in .NET 2.0 it is InvalidOperationException.
575                         // in .NET 1,1 it is ArgumentException.
576                         } catch (Exception) {}
577                 }
578
579                 [Test]
580                 public void WriteEndDocument2 ()
581                 {
582                         xw.WriteStartDocument ();
583                         try 
584                         {
585                                 xw.WriteEndDocument ();
586                                 Assert.Fail ("Expected an Exception.");
587                         // in .NET 2.0 it is InvalidOperationException.
588                         // in .NET 1,1 it is ArgumentException.
589                         } catch (Exception) {}
590                 }
591
592                 [Test]
593                 public void WriteEndDocument3 ()
594                 {
595                         xw.WriteStartDocument ();
596                         xw.WriteStartElement ("foo");
597                         xw.WriteStartAttribute ("bar", null);
598                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='", Output);
599
600                         xw.WriteEndDocument ();
601                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", Output);
602                         Assert.AreEqual (WriteState.Start, xw.WriteState);
603                 }
604
605                 [Test]
606                 [ExpectedException (typeof (InvalidOperationException))]
607                 public void WriteEndElement ()
608                 {
609                         // no matching StartElement
610                         xw.WriteEndElement ();
611                 }
612
613                 [Test]
614                 public void WriteEndElement2 ()
615                 {
616                         xw.WriteStartElement ("foo");
617                         xw.WriteEndElement ();
618                         Assert.AreEqual ("<foo />", Output);
619
620                         xw.WriteStartElement ("bar");
621                         xw.WriteStartAttribute ("baz", null);
622                         xw.WriteEndElement ();
623                         Assert.AreEqual ("<foo /><bar baz='' />", Output);
624                 }
625
626                 [Test]
627                 public void FullEndElement ()
628                 {
629                         xw.WriteStartElement ("foo");
630                         xw.WriteFullEndElement ();
631                         Assert.AreEqual ("<foo></foo>", Output);
632
633                         xw.WriteStartElement ("bar");
634                         xw.WriteAttributeString ("foo", "bar");
635                         xw.WriteFullEndElement ();
636                         Assert.AreEqual ("<foo></foo><bar foo='bar'></bar>", Output);
637
638                         xw.WriteStartElement ("baz");
639                         xw.WriteStartAttribute ("bar", null);
640                         xw.WriteFullEndElement ();
641                         Assert.AreEqual ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", Output);
642                 }
643
644                 [Test]
645                 public void WriteQualifiedName ()
646                 {
647                         xw.WriteStartElement (null, "test", null);
648                         xw.WriteAttributeString ("xmlns", "me", null, "http://localhost/");
649                         xw.WriteQualifiedName ("bob", "http://localhost/");
650                         xw.WriteEndElement ();
651
652                         Assert.AreEqual ("<test xmlns:me='http://localhost/'>me:bob</test>", Output);
653                 }
654
655                 [Test]
656                 public void WriteQualifiedNameNonDeclaredAttribute ()
657                 {
658                         xw.WriteStartElement ("foo");
659                         xw.WriteStartAttribute ("a", "");
660                         xw.WriteQualifiedName ("attr", "urn:a");
661                         xw.WriteWhitespace (" ");
662                         xw.WriteQualifiedName ("attr", "urn:b");
663                         xw.WriteEndAttribute ();
664                         xw.WriteEndElement ();
665                         string xml = sw.ToString ();
666                         Assert.IsTrue (
667                                 xml.IndexOf ("<foo ") >= 0,
668                                 "foo");
669                         Assert.IsTrue (
670                                 xml.IndexOf ("a='d1p1:attr d1p2:attr'") > 0,
671                                 "qnames");
672                         Assert.IsTrue (
673                                 xml.IndexOf (" xmlns:d1p1='urn:a'") > 0,
674                                 "xmlns:a");
675                         Assert.IsTrue (
676                                 xml.IndexOf (" xmlns:d1p2='urn:b'") > 0,
677                                 "xmlns:b");
678                 }
679
680                 [Test]
681                 [ExpectedException (typeof (ArgumentException))]
682                 public void WriteQualifiedNameNonDeclaredContent ()
683                 {
684                         xw.WriteStartElement ("foo");
685                         xw.WriteQualifiedName ("abc", "urn:abc");
686                 }
687
688                 [Test]
689                 [ExpectedException (typeof (ArgumentException))]
690                 public void WriteQualifiedNameNonNCName ()
691                 {
692                         xw.WriteStartElement ("foo");
693                         xw.WriteAttributeString ("xmlns", "urn:default");
694                         xw.WriteStartElement ("child");
695                         xw.WriteStartAttribute ("a", "");
696                         xw.WriteQualifiedName ("x:def", "urn:def");
697                 }
698
699                 [Test]
700                 public void WriteRaw ()
701                 {
702                         xw.WriteRaw("&<>\"'");
703                         Assert.AreEqual ("&<>\"'", Output);
704
705                         xw.WriteRaw(null);
706                         Assert.AreEqual ("&<>\"'", Output);
707
708                         xw.WriteRaw("");
709                         Assert.AreEqual ("&<>\"'", Output);
710                 }
711
712                 [Test]
713                 public void WriteRawInvalidInAttribute ()
714                 {
715                         xw.WriteStartElement ("foo");
716                         xw.WriteStartAttribute ("bar", null);
717                         xw.WriteRaw ("&<>\"'");
718                         xw.WriteEndAttribute ();
719                         xw.WriteEndElement ();
720                         Assert.AreEqual ("<foo bar='&<>\"'' />", Output);
721                 }
722
723                 [Test]
724                 public void WriteStateTest ()
725                 {
726                         Assert.AreEqual (WriteState.Start, xw.WriteState);
727                         xw.WriteStartDocument ();
728                         Assert.AreEqual (WriteState.Prolog, xw.WriteState);
729                         xw.WriteStartElement ("root");
730                         Assert.AreEqual (WriteState.Element, xw.WriteState);
731                         xw.WriteElementString ("foo", "bar");
732                         Assert.AreEqual (WriteState.Content, xw.WriteState);
733                         xw.Close ();
734                         Assert.AreEqual (WriteState.Closed, xw.WriteState);
735                 }
736
737                 [Test]
738                 public void WriteString ()
739                 {
740                         xw.WriteStartDocument ();
741                         try {
742                                 xw.WriteString("foo");
743                         } catch (InvalidOperationException) {}
744                 }
745
746                 [Test]
747                 public void WriteString2 ()
748                 {
749                         xw.WriteStartDocument ();
750                         // Testing attribute values
751
752                         xw.WriteStartElement ("foo");
753                         xw.WriteAttributeString ("bar", "&<>");
754                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo bar='&amp;&lt;&gt;'", Output);
755                 }
756
757                 [Test]
758                 public void WriteStringWithEntities()
759                 {
760                         // Testing element values
761                         xw.WriteElementString ("foo", "&<>\"'");
762                         Assert.AreEqual ("<foo>&amp;&lt;&gt;\"'</foo>", Output);
763                 }
764
765                 [Test]
766                 public void XmlLang ()
767                 {
768                         Assert.IsNull (xw.XmlLang);
769                         
770                         xw.WriteStartElement ("foo");
771                         xw.WriteAttributeString ("xml", "lang", null, "langfoo");
772                         Assert.AreEqual ("langfoo", xw.XmlLang);
773                         Assert.AreEqual ("<foo xml:lang='langfoo'", Output);
774
775                         xw.WriteAttributeString ("boo", "yah");
776                         Assert.AreEqual ("langfoo", xw.XmlLang);
777                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'", Output);
778                         
779                         xw.WriteElementString("bar", "baz");
780                         Assert.AreEqual ("langfoo", xw.XmlLang);
781                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", Output);
782                         
783                         xw.WriteString("baz");
784                         Assert.AreEqual ("langfoo", xw.XmlLang);
785                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", Output);
786                         
787                         xw.WriteStartElement ("quux");
788                         xw.WriteStartAttribute ("xml", "lang", null);
789                         Assert.AreEqual ("langfoo", xw.XmlLang);
790                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", Output);
791                         
792                         xw.WriteString("langbar");
793                         // Commented out there: it is implementation-dependent.
794                         // and incompatible between .NET 1.0 and 1.1
795 //                      Assert.AreEqual ("langfoo", xw.XmlLang);
796 //                      Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", Output);
797                         
798                         xw.WriteEndAttribute ();
799                         // Commented out there: it is implementation-dependent.
800                         // and incompatible between .NET 1.0 and 1.1
801 //                      Assert.AreEqual ("langbar", xw.XmlLang);
802 //                      Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'", Output);
803
804                         // check if xml:lang repeats output even if same as current scope.
805                         xw.WriteStartElement ("joe");
806                         xw.WriteAttributeString ("xml", "lang", null, "langbar");
807                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'", Output);
808
809                         
810                         xw.WriteElementString ("quuux", "squonk");
811                         Assert.AreEqual ("langbar", xw.XmlLang);
812                         Assert.AreEqual ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux>", Output);
813
814                         xw.WriteEndElement ();
815                         xw.WriteEndElement ();
816                         Assert.AreEqual ("langfoo", xw.XmlLang);
817                         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>", Output);
818                         
819                         xw.WriteEndElement ();
820                         Assert.IsNull (xw.XmlLang);
821                         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>", Output);
822                         
823                         xw.Close ();
824                         Assert.IsNull (xw.XmlLang);
825                 }
826
827                 // TODO: test operational aspects
828                 [Test]
829                 public void XmlSpaceTest ()
830                 {
831                         xw.WriteStartElement ("foo");
832                         Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
833
834                         xw.WriteStartElement ("bar");
835                         xw.WriteAttributeString ("xml", "space", null, "preserve");
836                         Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
837                         Assert.AreEqual ("<foo><bar xml:space='preserve'",      Output);
838
839                         xw.WriteStartElement ("baz");
840                         xw.WriteAttributeString ("xml", "space", null, "preserve");
841                         Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
842                         Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'", Output);
843
844                         xw.WriteStartElement ("quux");
845                         xw.WriteStartAttribute ("xml", "space", null);
846                         Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
847                         Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", Output);
848
849                         // Commented out there: it is implementation-dependent
850                         // and incompatible between .NET 1.0 and 1.1
851                         xw.WriteString ("default");
852 //                      Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
853 //                      Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", Output);
854                         
855                         xw.WriteEndAttribute ();
856                         Assert.AreEqual (XmlSpace.Default, xw.XmlSpace);
857                         Assert.AreEqual ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='default'", Output);
858
859                         xw.WriteEndElement ();
860                         Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
861                         xw.WriteEndElement ();
862                         Assert.AreEqual (XmlSpace.Preserve, xw.XmlSpace);
863                         xw.WriteEndElement ();
864                         Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
865
866                         xw.WriteStartElement ("quux");
867                 }
868
869                 [Test]
870                 [ExpectedException (typeof (ArgumentException))]
871                 public void XmlSpaceTestInvalidValue1 ()
872                 {
873                         xw.WriteStartElement ("foo");
874                         xw.WriteAttributeString ("xml", "space", null, "bubba");
875                 }
876
877                 [Test]
878                 [ExpectedException (typeof (ArgumentException))]
879                 public void XmlSpaceTestInvalidValue2 ()
880                 {
881                         xw.WriteStartElement ("foo");
882                         xw.WriteAttributeString ("xml", "space", null, "PRESERVE");
883                 }
884
885                 [Test]
886                 [ExpectedException (typeof (ArgumentException))]
887                 public void XmlSpaceTestInvalidValue3 ()
888                 {
889                         xw.WriteStartElement ("foo");
890                         xw.WriteAttributeString ("xml", "space", null, "Default");
891                 }
892
893                 [Test]
894                 [ExpectedException (typeof (ArgumentException))]
895                 public void XmlSpaceTestInvalidValue4 ()
896                 {
897                         xw.WriteStartElement ("foo");
898                         xw.WriteAttributeString ("xml", "space", null, "bubba");
899                 }
900
901                 [Test]
902                 [ExpectedException (typeof (ArgumentException))]
903                 public void WriteWhitespaceNonWhitespace ()
904                 {
905                         xw.WriteWhitespace ("x");
906                 }
907
908                 [Test]
909                 public void XmlSpaceRaw ()
910                 {
911                         xw.WriteStartElement ("foo");
912                         xw.WriteStartAttribute ("xml", "space", null);
913                         Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
914                         Assert.AreEqual ("<foo xml:space='", Output);
915
916                         xw.WriteString ("default");
917                         // Commented out there: it is implementation-dependent
918                         // and incompatible between .NET 1.0 and 1.1
919 //                      Assert.AreEqual (XmlSpace.None, xw.XmlSpace);
920 //                      Assert.AreEqual ("<foo xml:space='", Output);
921
922                         xw.WriteEndAttribute ();
923                         Assert.AreEqual (XmlSpace.Default, xw.XmlSpace);
924                         Assert.AreEqual ("<foo xml:space='default'", Output);
925                 }
926
927                 [Test]
928                 public void WriteAttributes ()
929                 {
930                         XmlDocument doc = new XmlDocument();
931                         StringWriter sw = new StringWriter();
932                         XmlWriter wr = new XmlTextWriter(sw);
933                         StringBuilder sb = sw.GetStringBuilder();
934                         XmlParserContext ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
935                         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);
936
937                         xtr.Read();     // read XMLDecl
938                         wr.WriteAttributes(xtr, false);
939                         // This method don't always have to take this double-quoted style...
940                         Assert.AreEqual("version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"", sw.ToString().Trim(), "#WriteAttributes.XmlDecl.1");
941
942                         sb.Remove(0, sb.Length);        // init
943                         ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
944                         xtr = new XmlTextReader("<?xml version='1.0'             standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
945                         xtr.Read();     // read XMLDecl
946                         Assert.AreEqual (XmlNodeType.XmlDeclaration, xtr.NodeType);
947                         sw = new StringWriter ();
948                         wr = new XmlTextWriter (sw);
949
950                         // This block raises an error on MS.NET 1.0.
951                         wr.WriteAttributes(xtr, false);
952                         // This method don't always have to take this double-quoted style...
953                         Assert.AreEqual("version=\"1.0\" standalone=\"no\"", sw.ToString().Trim(), "#WriteAttributes.XmlDecl.2");
954
955                         sw = new StringWriter ();
956                         wr = new XmlTextWriter (sw);
957                         sb.Remove(0, sb.Length);        // init
958
959                         xtr.Read();     // read root
960                         Assert.AreEqual (XmlNodeType.Element, xtr.NodeType);
961                         wr.WriteStartElement(xtr.LocalName, xtr.NamespaceURI);
962                         wr.WriteAttributes(xtr, false);
963                         wr.WriteEndElement();
964                         wr.Close();
965                         // This method don't always have to take this double-quoted style...
966                         Assert.AreEqual("<root a1=\"A\" b2=\"B\" c3=\"C\" />", sw.ToString().Trim(), "#WriteAttributes.Element");
967                         xtr.Close ();
968                 }
969
970                 [Test]
971                 public void WriteWhitespace ()
972                 {
973                         xw.WriteStartElement ("a");
974                         xw.WriteWhitespace ("\n\t");
975                         xw.WriteStartElement ("b");
976                         xw.WriteWhitespace ("\n\t");
977                         xw.WriteEndElement ();
978                         xw.WriteWhitespace ("\n");
979                         xw.WriteEndElement ();
980                         xw.WriteWhitespace ("\n");
981                         xw.Flush ();
982                         Assert.AreEqual ("<a>\n\t<b>\n\t</b>\n</a>\n", Output);
983                 }
984
985                 [Test]
986                 public void FlushDoesntCloseTag ()
987                 {
988                         xw.WriteStartElement ("foo");
989                         xw.WriteAttributeString ("bar", "baz");
990                         xw.Flush ();
991                         Assert.AreEqual ("<foo bar='baz'", Output);
992                 }
993
994                 [Test]
995                 public void WriteWhitespaceClosesTag ()
996                 {
997                         xw.WriteStartElement ("foo");
998                         xw.WriteAttributeString ("bar", "baz");
999                         xw.WriteWhitespace (" ");
1000                         Assert.AreEqual ("<foo bar='baz'> ", Output);
1001                 }
1002
1003                 [Test]
1004                 public void DontOutputMultipleXmlns ()
1005                 {
1006                         XmlDocument doc = new XmlDocument();
1007                         doc.LoadXml("<a xmlns:dt=\"b\" dt:dt=\"c\"/>");
1008                         XmlDocument doc2 = new XmlDocument();
1009                         doc2.LoadXml(doc.InnerXml);
1010                         Assert.AreEqual ("<a xmlns:dt=\"b\" dt:dt=\"c\" />",
1011                                 doc2.OuterXml);
1012                 }
1013
1014                 [Test]
1015                 public void DontOutputNonDeclaredXmlns ()
1016                 {
1017                         string xml = "<x:a foo='foo' xmlns:x='urn:foo'><b /></x:a>";
1018                         XmlDocument doc = new XmlDocument();
1019                         doc.LoadXml(xml);
1020                         XmlDocument doc2 = new XmlDocument();
1021                         doc2.LoadXml(doc.InnerXml);
1022                         Assert.AreEqual (xml.Replace ('\'', '"'), doc2.OuterXml);
1023                 }
1024
1025                 [Test]
1026                 public void DontOutputRemovalDefaultNSDeclaration ()
1027                 {
1028                         xw.WriteStartDocument ();
1029                         xw.WriteStartElement ("foo");
1030                         xw.WriteAttributeString ("xmlns", "probe");
1031                         Assert.AreEqual (String.Empty, xw.LookupPrefix ("probe"));
1032                         xw.WriteStartElement ("b");
1033                         Assert.AreEqual (String.Empty, xw.LookupPrefix ("probe"));
1034                         xw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1035                         xw.WriteEndElement (); // b2
1036                         xw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1037                         xw.WriteEndElement (); // b2
1038                         xw.WriteEndElement (); // b
1039                         xw.WriteEndElement (); // foo
1040                         xw.WriteEndDocument ();
1041                         xw.Close ();
1042
1043                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 xmlns='' /></b></foo>", Output);
1044                 }
1045
1046                 [Test]
1047                 public void DontOutputRemovalDefaultNSDeclaration2 ()
1048                 {
1049                         xw.WriteStartDocument ();
1050                         // IMPORTANT DIFFERENCE!! ns = "", not null
1051                         xw.WriteStartElement ("foo", "");
1052                         xw.WriteAttributeString ("xmlns", "probe");
1053                         Assert.IsNull (xw.LookupPrefix ("probe"));
1054                         xw.WriteStartElement ("b");
1055                         Assert.IsNull (xw.LookupPrefix ("probe"));
1056                         xw.WriteStartElement (null, "b2", null); // *Don't* output xmlns=""
1057                         xw.WriteEndElement (); // b2
1058                         xw.WriteStartElement (null, "b2", ""); // *Do* output xmlns=""
1059                         xw.WriteEndElement (); // b2
1060                         xw.WriteEndElement (); // b
1061                         xw.WriteEndElement (); // foo
1062                         xw.WriteEndDocument ();
1063                         xw.Close ();
1064
1065                         Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><foo xmlns='probe'><b><b2 /><b2 /></b></foo>", Output);
1066                 }
1067
1068                 [Test]
1069                 public void DoOutputRemovalDefaultNSDeclaration ()
1070                 {
1071                         xw.WriteStartElement ("docelem", "a-namespace");
1072                         
1073                         XmlDocument doc = new XmlDocument ();
1074                         doc.CreateElement ("hola").WriteTo (xw);
1075                         // This means, WriteTo never passes null NamespaceURI argument to XmlWriter.
1076                         xw.WriteEndElement ();
1077                         xw.Close ();
1078
1079                         Assert.AreEqual ("<docelem xmlns='a-namespace'><hola xmlns='' /></docelem>", Output);
1080                 }
1081
1082                 [Test]
1083                 public void WriteAttributeTakePrecedenceOnXmlns ()
1084                 {
1085                         xw.WriteStartElement ("root", "urn:foo");
1086                         xw.WriteAttributeString ("xmlns", "urn:bar");
1087                         xw.WriteEndElement ();
1088                         xw.Close ();
1089                         Assert.AreEqual ("<root xmlns='urn:bar' />", Output);
1090                 }
1091
1092                 [Test]
1093                 [ExpectedException (typeof (ArgumentException))]
1094                 public void LookupPrefixNull ()
1095                 {
1096                         xw.LookupPrefix (null);
1097                 }
1098
1099                 [Test]
1100                 [ExpectedException (typeof (ArgumentException))]
1101                 public void LookupPrefixEmpty ()
1102                 {
1103                         xw.LookupPrefix (String.Empty);
1104                 }
1105
1106                 [Test]
1107                 public void LookupPrefixIgnoresXmlnsAttribute ()
1108                 {
1109                         Assert.IsNull (xw.LookupPrefix ("urn:foo"));
1110                         xw.WriteStartElement ("root");
1111                         Assert.IsNull (xw.LookupPrefix ("urn:foo"));
1112                         xw.WriteAttributeString ("xmlns", "urn:foo");
1113                         // Surprisingly to say, it is ignored!!
1114                         Assert.AreEqual (String.Empty, xw.LookupPrefix ("urn:foo"));
1115                         xw.WriteStartElement ("hoge");
1116                         // (still after flushing previous start element.)
1117                         Assert.AreEqual (String.Empty, xw.LookupPrefix ("urn:foo"));
1118                         xw.WriteStartElement ("fuga", "urn:foo");
1119                         // Is this testing on the correct way? Yes, here it is.
1120                         Assert.AreEqual (String.Empty, xw.LookupPrefix ("urn:foo"));
1121                 }
1122
1123                 [Test]
1124                 public void WriteInvalidNames ()
1125                 {
1126                         xw.WriteStartElement ("foo<>");
1127                         xw.WriteAttributeString ("ho<>ge", "value");
1128                 }
1129
1130                 [Test]
1131                 [ExpectedException (typeof (ArgumentException))]
1132                 public void AttributeWriteStartAttributePrefixWithoutNS ()
1133                 {
1134                         xw.WriteStartAttribute ("some", "foo", null);
1135                 }
1136
1137                 [Test]
1138                 public void AttributeWriteStartAttributeXmlnsNullNS ()
1139                 {
1140                         xw.WriteStartAttribute ("xmlns", "foo", null);
1141                 }
1142
1143                 [Test]
1144                 [ExpectedException (typeof (ArgumentException))]
1145                 public void AttributeWriteEndAttributeXmlnsNullNs ()
1146                 {
1147                         // Compare with the test AttributeWriteStartAttributeXmlnsNullNS().
1148                         xw.WriteStartAttribute ("xmlns", "foo", null);
1149                         xw.WriteEndAttribute ();
1150                 }
1151
1152                 [Test]
1153                 [ExpectedException (typeof (ArgumentException))]
1154                 public void AttributeWriteStartAttributePrefixXmlnsNonW3CNS ()
1155                 {
1156                         xw.WriteStartAttribute ("xmlns", "foo", "urn:foo");
1157                 }
1158
1159                 [Test]
1160                 [ExpectedException (typeof (ArgumentException))]
1161                 public void AttributeWriteStartAttributeLocalXmlnsNonW3CNS ()
1162                 {
1163                         xw.WriteStartAttribute ("", "xmlns", "urn:foo");
1164                 }
1165
1166                 [Test]
1167                 public void WriteRawProceedToProlog ()
1168                 {
1169                         XmlTextWriter xw = new XmlTextWriter (new StringWriter ());
1170                         xw.WriteRaw ("");
1171                         Assert.AreEqual (WriteState.Prolog, xw.WriteState);
1172                 }
1173
1174                 [Test]
1175                 public void CloseTwice ()
1176                 {
1177                         StringWriter sw = new StringWriter ();
1178                         XmlTextWriter writer = new XmlTextWriter (sw);
1179                         writer.Close ();
1180                         // should not result in an exception
1181                         writer.Close ();
1182                 }
1183
1184                 [Test]
1185                 public void WriteRawWriteString ()
1186                 {
1187                         // WriteRaw () -> WriteString ().
1188                         xw.WriteRaw ("");
1189                         xw.WriteString ("foo");
1190                         Assert.AreEqual (WriteState.Content, xw.WriteState);
1191                 }
1192
1193                 [Test]
1194                 public void LookupOverridenPrefix ()
1195                 {
1196                         xw.WriteStartElement ("out");
1197                         xw.WriteAttributeString ("xmlns", "baz", "http://www.w3.org/2000/xmlns/", "xyz");
1198                         xw.WriteStartElement ("baz", "foo", "abc");
1199                         Assert.IsNull (xw.LookupPrefix ("xyz"));
1200                 }
1201
1202                 [Test]
1203                 public void DuplicatingNamespaceMappingInAttributes ()
1204                 {
1205                         xw.WriteStartElement ("out");
1206                         xw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1207                         xw.WriteAttributeString ("p", "bar", "urn:bar", "xyz");
1208                         xw.WriteAttributeString ("p", "baz", "urn:baz", "xyz");
1209                         xw.WriteStartElement ("out");
1210                         xw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1211                         xw.WriteStartElement ("out");
1212                         xw.WriteAttributeString ("p", "foo", "urn:foo", "xyz");
1213                         xw.WriteEndElement ();
1214                         xw.WriteEndElement ();
1215                         xw.WriteEndElement ();
1216                         string xml = sw.ToString ();
1217                         Assert.IsTrue (
1218                                 xml.IndexOf ("p:foo='xyz'") > 0,
1219                                 "p:foo");
1220                         Assert.IsTrue (
1221                                 xml.IndexOf ("d1p1:bar='xyz'") > 0,
1222                                 "d1p1:bar");
1223                         Assert.IsTrue (
1224                                 xml.IndexOf ("d1p2:baz='xyz'") > 0,
1225                                 "d1p1:baz");
1226                         Assert.IsTrue (
1227                                 xml.IndexOf ("xmlns:d1p2='urn:baz'") > 0,
1228                                 "xmlns:d1p2");
1229                         Assert.IsTrue (
1230                                 xml.IndexOf ("xmlns:d1p1='urn:bar'") > 0,
1231                                 "xmlns:d1p1");
1232                         Assert.IsTrue (
1233                                 xml.IndexOf ("xmlns:p='urn:foo'") > 0,
1234                                 "xmlns:p");
1235                         Assert.IsTrue (
1236                                 xml.IndexOf ("<out p:foo='xyz'><out p:foo='xyz' /></out></out>") > 0,
1237                                 "remaining");
1238                 }
1239
1240                 [Test]
1241                 public void WriteXmlSpaceIgnoresNS ()
1242                 {
1243                         xw.WriteStartElement ("root");
1244                         xw.WriteAttributeString ("xml", "space", "abc", "preserve");
1245                         xw.WriteEndElement ();
1246                         Assert.AreEqual ("<root xml:space='preserve' />", sw.ToString ());
1247                 }
1248
1249                 [Test] // bug #75546
1250                 public void WriteEmptyNSQNameInAttribute ()
1251                 {
1252                         XmlTextWriter xw = new XmlTextWriter (TextWriter.Null);
1253                         xw.WriteStartElement ("foo", "urn:goo");
1254                         xw.WriteAttributeString ("xmlns:bar", "urn:bar");
1255                         xw.WriteStartAttribute ("foo", "");
1256                         xw.WriteQualifiedName ("n1", "urn:bar");
1257                         xw.WriteEndAttribute ();
1258                         xw.WriteStartAttribute ("foo", "");
1259                         xw.WriteQualifiedName ("n2", "");
1260                         xw.WriteEndAttribute ();
1261                 }
1262
1263                 [Test] // bug #76095
1264                 public void SurrogatePairsInWriteString ()
1265                 {
1266                         MemoryStream ms = new MemoryStream ();
1267                         XmlWriter writer = new XmlTextWriter(ms, null);
1268                         writer.WriteElementString("a", "\ud800\udf39");
1269                         writer.Close();
1270                         byte [] referent = new byte [] {0x3c, 0x61, 0x3e, 0xf0,
1271                                 0x90, 0x8c, 0xb9, 0x3c, 0x2f, 0x61, 0x3e};
1272                         NUnit.Framework.Assert.AreEqual (referent, ms.ToArray ());
1273                 }
1274
1275                 [Test]
1276                 [ExpectedException (typeof (InvalidOperationException))]
1277                 public void RejectWritingAtErrorState ()
1278                 {
1279                         try {
1280                                 xw.WriteEndElement ();
1281                         } catch (Exception) {
1282                         }
1283
1284                         xw.WriteStartElement ("foo");
1285                 }
1286
1287                 #endregion
1288
1289                 [Test]
1290                 public void WriteBooleanArray ()
1291                 {
1292                         bool [] array = new bool [] {true, false, true, true, false};
1293                         xw.WriteArray ("", "root", "", array, 1, 3);
1294                         Assert.AreEqual ("<root>false</root><root>true</root><root>true</root>", Output, "#1");
1295                 }
1296
1297                 [Test]
1298                 public void WriteNode ()
1299                 {
1300                         string s = @"<Resolve xmlns='http://schemas.microsoft.com/net/2006/05/peer' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'><ClientId>79310c9f-18d4-4337-a95a-1865ca54a66e</ClientId><MaxAddresses>3</MaxAddresses><MeshId>amesh</MeshId></Resolve>".Replace ('\'', '"');
1301                         var sw = new StringWriter ();
1302                         var xw = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw, new XmlWriterSettings () { OmitXmlDeclaration = true }));
1303                         var xr = XmlDictionaryReader.CreateDictionaryReader (XmlReader.Create (new StringReader (s)));
1304                         xr.MoveToContent ();
1305                         while (!xr.EOF && xr.NodeType != XmlNodeType.EndElement)
1306                                 xw.WriteNode (xr, false);
1307                         xw.Flush ();
1308                         Assert.AreEqual (s, sw.ToString ());
1309                 }
1310         }
1311 }