2003-01-26 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / Test / XmlTextWriterTests.cs
1 //
2 // System.Xml.XmlTextWriterTests
3 //
4 // Author:
5 //   Kral Ferch <kral_ferch@hotmail.com>
6 //
7 // (C) 2002 Kral Ferch
8 //
9
10 using System;
11 using System.IO;
12 using System.Text;
13 using System.Xml;
14
15 using NUnit.Framework;
16
17 namespace MonoTests.System.Xml
18 {
19         public class XmlTextWriterTests : TestCase
20         {
21                 public XmlTextWriterTests () : base ("MonoTests.System.Xml.XmlTextWriterTests testsuite") {}
22                 public XmlTextWriterTests (string name) : base (name) {}
23
24                 StringWriter sw;
25                 XmlTextWriter xtw;
26
27                 protected override void SetUp ()
28                 {
29                         sw = new StringWriter ();
30                         xtw = new XmlTextWriter (sw);
31                         xtw.QuoteChar = '\'';
32                 }
33
34                 private string StringWriterText 
35                 {
36                         get { return sw.GetStringBuilder ().ToString (); }
37                 }
38
39                 public void TestAttributeNamespacesNonNamespaceAttributeBefore ()
40                 {
41                         xtw.WriteStartElement ("foo");
42                         xtw.WriteAttributeString("bar", "baz");
43                         xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
44                         AssertEquals ("<foo bar='baz' xmlns:abc='http://abc.def'", StringWriterText);
45                 }
46
47                 public void TestAttributeNamespacesNonNamespaceAttributeAfter ()
48                 {
49                         xtw.WriteStartElement ("foo");
50
51                         xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
52                         xtw.WriteAttributeString("bar", "baz");
53                         AssertEquals ("<foo xmlns:abc='http://abc.def' bar='baz'", StringWriterText);
54                 }
55
56                 public void TestAttributeNamespacesThreeParamWithNullInNamespaceParam ()
57                 {
58                         xtw.WriteAttributeString ("xmlns", null, "http://abc.def");
59                         AssertEquals ("xmlns='http://abc.def'", StringWriterText);
60                 }
61
62                 public void TestAttributeNamespacesThreeParamWithTextInNamespaceParam ()
63                 {
64                         try 
65                         {
66                                 xtw.WriteAttributeString ("xmlns", "http://somenamespace.com", "http://abc.def");
67                         } 
68                         catch (ArgumentException) {}
69                 }
70
71                 public void TestAttributeNamespacesWithNullInNamespaceParam ()
72                 {
73                         xtw.WriteAttributeString ("xmlns", "abc", null, "http://abc.def");
74                         AssertEquals ("xmlns:abc='http://abc.def'", StringWriterText);
75                 }
76
77                 public void TestAttributeNamespacesWithTextInNamespaceParam ()
78                 {
79                         try {
80                                 xtw.WriteAttributeString ("xmlns", "abc", "http://somenamespace.com", "http://abc.def");
81                         } catch (ArgumentException) {}
82                 }
83
84                 public void TestAttributeNamespacesXmlnsXmlns ()
85                 {
86                         xtw.WriteStartElement ("foo");
87                         try 
88                         {
89                                 xtw.WriteAttributeString ("xmlns", "xmlns", null, "http://abc.def");
90                                 Fail ("any prefix which name starts from \"xml\" must not be allowed.");
91                         } 
92                         catch (ArgumentException e) {}
93                 }
94
95                 public void TestAttributeWriteAttributeString ()
96                 {
97                         xtw.WriteStartElement ("foo");
98
99                         xtw.WriteAttributeString ("foo", "bar");
100                         AssertEquals ("<foo foo='bar'", StringWriterText);
101
102                         xtw.WriteAttributeString ("bar", "");
103                         AssertEquals ("<foo foo='bar' bar=''", StringWriterText);
104
105                         xtw.WriteAttributeString ("baz", null);
106                         AssertEquals ("<foo foo='bar' bar='' baz=''", StringWriterText);
107
108                         // TODO: Why does this pass Microsoft?
109                         xtw.WriteAttributeString ("", "quux");
110                         AssertEquals ("<foo foo='bar' bar='' baz='' ='quux'", StringWriterText);
111
112                         // TODO: Why does this pass Microsoft?
113                         xtw.WriteAttributeString (null, "quuux");
114                         AssertEquals ("<foo foo='bar' bar='' baz='' ='quux' ='quuux'", StringWriterText);
115                 }
116
117                 public void TestAttributeWriteAttributeStringNotInsideOpenStartElement ()
118                 {
119                         xtw.WriteStartElement ("foo");
120                         xtw.WriteString ("bar");
121                         
122                         try 
123                         {
124                                 xtw.WriteAttributeString ("baz", "quux");
125                                 Fail ("Expected an InvalidOperationException to be thrown.");
126                         } 
127                         catch (InvalidOperationException) {}
128                 }
129
130                 public void TestAttributeWriteAttributeStringWithoutParentElement ()
131                 {
132                         xtw.WriteAttributeString ("foo", "bar");
133                         AssertEquals ("foo='bar'", StringWriterText);
134
135                         xtw.WriteAttributeString ("baz", "quux");
136                         AssertEquals ("foo='bar' baz='quux'", StringWriterText);
137                 }
138
139                 public void TestCDataValid ()
140                 {
141                         xtw.WriteCData ("foo");
142                         AssertEquals ("WriteCData had incorrect output.", "<![CDATA[foo]]>", StringWriterText);
143                 }
144
145                 public void TestCDataInvalid ()
146                 {
147                         try {
148                                 xtw.WriteCData("foo]]>bar");
149                                 Fail("Should have thrown an ArgumentException.");
150                         } 
151                         catch (ArgumentException) { }
152                 }
153
154                 public void TestCloseOpenElements ()
155                 {
156                         xtw.WriteStartElement("foo");
157                         xtw.WriteStartElement("bar");
158                         xtw.WriteStartElement("baz");
159                         xtw.Close();
160                         AssertEquals ("Close didn't write out end elements properly.", "<foo><bar><baz /></bar></foo>", StringWriterText);
161                 }
162
163                 public void TestCloseWriteAfter ()
164                 {
165                         xtw.WriteElementString ("foo", "bar");
166                         xtw.Close ();
167
168                         // WriteEndElement and WriteStartDocument aren't tested here because
169                         // they will always throw different exceptions besides 'The Writer is closed.'
170                         // and there are already tests for those exceptions.
171
172                         try {
173                                 xtw.WriteCData ("foo");
174                                 Fail ("WriteCData after Close Should have thrown an InvalidOperationException.");
175                         } 
176                         catch (InvalidOperationException e) {
177                                 AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
178                         }
179
180                         try {
181                                 xtw.WriteComment ("foo");
182                                 Fail ("WriteComment after Close Should have thrown an InvalidOperationException.");
183                         } 
184                         catch (InvalidOperationException e) {
185                                 AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
186                         }
187
188                         try {
189                                 xtw.WriteProcessingInstruction ("foo", "bar");
190                                 Fail ("WriteProcessingInstruction after Close Should have thrown an InvalidOperationException.");
191                         } 
192                         catch (InvalidOperationException e) {
193                                 AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
194                         }
195
196                         try {
197                                 xtw.WriteStartElement ("foo", "bar", "baz");
198                                 Fail ("WriteStartElement after Close Should have thrown an InvalidOperationException.");
199                         } 
200                         catch (InvalidOperationException e) {
201                                 AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
202                         }
203
204                         try 
205                         {
206                                 xtw.WriteAttributeString ("foo", "bar");
207                                 Fail ("WriteAttributeString after Close Should have thrown an InvalidOperationException.");
208                         } 
209                         catch (InvalidOperationException e) 
210                         {
211                                 AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
212                         }
213
214                         try {
215                                 xtw.WriteString ("foo");
216                                 Fail ("WriteString after Close Should have thrown an InvalidOperationException.");
217                         } 
218                         catch (InvalidOperationException e) {
219                                 AssertEquals ("Exception message is incorrect.", "The Writer is closed.", e.Message);
220                         }
221                 }
222
223                 public void TestCommentValid ()
224                 {
225                         xtw.WriteComment ("foo");
226                         AssertEquals ("WriteComment had incorrect output.", "<!--foo-->", StringWriterText);
227                 }
228
229                 public void TestCommentInvalid ()
230                 {
231                         try {
232                                 xtw.WriteComment("foo-");
233                                 Fail("Should have thrown an ArgumentException.");
234                         } 
235                         catch (ArgumentException) { }
236
237                         try {
238                                 xtw.WriteComment("foo-->bar");
239                                 Fail("Should have thrown an ArgumentException.");
240                         } 
241                         catch (ArgumentException) { }
242                 }
243
244                 public void TestConstructorsAndBaseStream ()
245                 {
246                         Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (null, this.xtw.BaseStream));
247
248                         MemoryStream ms;
249                         StreamReader sr;
250                         XmlTextWriter xtw;
251
252                         ms = new MemoryStream ();
253                         xtw = new XmlTextWriter (ms, new UnicodeEncoding ());
254                         xtw.WriteStartDocument ();
255                         xtw.Flush ();
256                         ms.Seek (0, SeekOrigin.Begin);
257                         sr = new StreamReader (ms, Encoding.Unicode);
258                         string expectedXmlDeclaration = "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
259                         string actualXmlDeclaration = sr.ReadToEnd();
260                         AssertEquals (expectedXmlDeclaration, actualXmlDeclaration);
261                         Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (ms, xtw.BaseStream));
262
263                         ms = new MemoryStream ();
264                         xtw = new XmlTextWriter (ms, new UnicodeEncoding ());
265                         xtw.WriteStartDocument (true);
266                         xtw.Flush ();
267                         ms.Seek (0, SeekOrigin.Begin);
268                         sr = new StreamReader (ms, Encoding.Unicode);
269                         AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?>", sr.ReadToEnd ());
270
271                         ms = new MemoryStream ();
272                         xtw = new XmlTextWriter (ms, new UTF8Encoding ());
273                         xtw.WriteStartDocument ();
274                         xtw.Flush ();
275                         ms.Seek (0, SeekOrigin.Begin);
276                         sr = new StreamReader (ms, Encoding.UTF8);
277                         AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-8\"?>", sr.ReadToEnd ());
278
279                         ms = new MemoryStream ();
280                         xtw = new XmlTextWriter (ms, null);
281                         xtw.WriteStartDocument ();
282                         xtw.Flush ();
283                         ms.Seek (0, SeekOrigin.Begin);
284                         sr = new StreamReader (ms, Encoding.UTF8);
285                         AssertEquals ("<?xml version=\"1.0\"?>", sr.ReadToEnd ());
286
287                         ms = new MemoryStream ();
288                         xtw = new XmlTextWriter (ms, null);
289                         xtw.WriteStartDocument (true);
290                         xtw.Flush ();
291                         ms.Seek (0, SeekOrigin.Begin);
292                         sr = new StreamReader (ms, Encoding.UTF8);
293                         AssertEquals ("<?xml version=\"1.0\" standalone=\"yes\"?>", sr.ReadToEnd ());
294                         Assert ("BaseStream property returned wrong value.", Object.ReferenceEquals (ms, xtw.BaseStream));
295                 }
296
297                 public void TestDocumentStart ()
298                 {
299                         xtw.WriteStartDocument ();
300                         AssertEquals ("XmlDeclaration is incorrect.", "<?xml version='1.0' encoding='utf-16'?>", StringWriterText);
301
302                         try 
303                         {
304                                 xtw.WriteStartDocument ();
305                                 Fail("Should have thrown an InvalidOperationException.");
306                         } 
307                         catch (InvalidOperationException e) {
308                                 AssertEquals ("Exception message is incorrect.",
309                                         "WriteStartDocument should be the first call.", e.Message);
310                         }
311
312                         xtw = new XmlTextWriter (sw = new StringWriter ());
313                         xtw.QuoteChar = '\'';
314                         xtw.WriteStartDocument (true);
315                         AssertEquals ("<?xml version='1.0' encoding='utf-16' standalone='yes'?>", StringWriterText);
316
317                         xtw = new XmlTextWriter (sw = new StringWriter ());
318                         xtw.QuoteChar = '\'';
319                         xtw.WriteStartDocument (false);
320                         AssertEquals ("<?xml version='1.0' encoding='utf-16' standalone='no'?>", StringWriterText);
321                 }
322
323                 public void TestElementEmpty ()
324                 {
325                         xtw.WriteStartElement ("foo");
326                         xtw.WriteEndElement ();
327                         AssertEquals ("Incorrect output.", "<foo />", StringWriterText);
328                 }
329
330                 public void TestElementWriteElementString ()
331                 {
332                         xtw.WriteElementString ("foo", "bar");
333                         AssertEquals ("WriteElementString has incorrect output.", "<foo>bar</foo>", StringWriterText);
334
335                         xtw.WriteElementString ("baz", "");
336                         AssertEquals ("<foo>bar</foo><baz />", StringWriterText);
337
338                         xtw.WriteElementString ("quux", null);
339                         AssertEquals ("<foo>bar</foo><baz /><quux />", StringWriterText);
340
341                         xtw.WriteElementString ("", "quuux");
342                         AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</>", StringWriterText);
343
344                         xtw.WriteElementString (null, "quuuux");
345                         AssertEquals ("<foo>bar</foo><baz /><quux /><>quuux</><>quuuux</>", StringWriterText);
346                 }
347
348                 public void TestFormatting ()
349                 {
350                         xtw.Formatting = Formatting.Indented;
351                         xtw.WriteStartDocument ();
352                         xtw.WriteStartElement ("foo");
353                         xtw.WriteElementString ("bar", "");
354                         xtw.Close ();
355                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?>\r\n<foo>\r\n  <bar />\r\n</foo>", StringWriterText);
356                 }
357
358                 public void TestFormattingInvalidXmlForFun ()
359                 {
360                         xtw.Formatting = Formatting.Indented;
361                         xtw.IndentChar = 'x';
362                         xtw.WriteStartDocument ();
363                         xtw.WriteStartElement ("foo");
364                         xtw.WriteStartElement ("bar");
365                         xtw.WriteElementString ("baz", "");
366                         xtw.Close ();
367                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?>\r\n<foo>\r\nxx<bar>\r\nxxxx<baz />\r\nxx</bar>\r\n</foo>", StringWriterText);
368                 }
369
370                 public void TestFormattingFromRemarks ()
371                 {
372                         // Remarks section of on-line help for XmlTextWriter.Formatting suggests this test.
373                         xtw.Formatting = Formatting.Indented; 
374                         xtw.WriteStartElement ("ol"); 
375                         xtw.WriteStartElement ("li"); 
376                         xtw.WriteString ("The big "); // This means "li" now has a mixed content model. 
377                         xtw.WriteElementString ("b", "E"); 
378                         xtw.WriteElementString ("i", "lephant"); 
379                         xtw.WriteString (" walks slowly."); 
380                         xtw.WriteEndElement (); 
381                         xtw.WriteEndElement ();
382                         AssertEquals ("<ol>\r\n  <li>The big <b>E</b><i>lephant</i> walks slowly.</li>\r\n</ol>", StringWriterText);
383                 }
384
385                 public void TestLookupPrefix ()
386                 {
387                         xtw.WriteStartElement ("root");
388
389                         xtw.WriteStartElement ("one");
390                         xtw.WriteAttributeString ("xmlns", "foo", null, "http://abc.def");
391                         xtw.WriteAttributeString ("xmlns", "bar", null, "http://ghi.jkl");
392                         AssertEquals ("foo", xtw.LookupPrefix ("http://abc.def"));
393                         AssertEquals ("bar", xtw.LookupPrefix ("http://ghi.jkl"));
394                         xtw.WriteEndElement ();
395
396                         xtw.WriteStartElement ("two");
397                         xtw.WriteAttributeString ("xmlns", "baz", null, "http://mno.pqr");
398                         xtw.WriteString("quux");
399                         AssertEquals ("baz", xtw.LookupPrefix ("http://mno.pqr"));
400                         AssertNull (xtw.LookupPrefix ("http://abc.def"));
401                         AssertNull (xtw.LookupPrefix ("http://ghi.jkl"));
402
403                         AssertNull (xtw.LookupPrefix ("http://bogus"));
404                 }
405
406                 public void TestNamespacesAttributesPassingInNamespaces ()
407                 {
408                         xtw.Namespaces = false;
409                         xtw.WriteStartElement ("foo");
410
411                         // These shouldn't throw any exceptions since they don't pass in
412                         // a namespace.
413                         xtw.WriteAttributeString ("bar", "baz");
414                         xtw.WriteAttributeString ("", "a", "", "b");
415                         xtw.WriteAttributeString (null, "c", "", "d");
416                         xtw.WriteAttributeString ("", "e", null, "f");
417                         xtw.WriteAttributeString (null, "g", null, "h");
418
419                         AssertEquals ("<foo bar='baz' a='b' c='d' e='f' g='h'", StringWriterText);
420
421                         // These should throw ArgumentException because they pass in a
422                         // namespace when Namespaces = false.
423                 }
424
425                 public void TestNamespacesElementsPassingInNamespaces ()
426                 {
427                         xtw.Namespaces = false;
428
429                         // These shouldn't throw any exceptions since they don't pass in
430                         // a namespace.
431                         xtw.WriteElementString ("foo", "bar");
432                         xtw.WriteStartElement ("baz");
433                         xtw.WriteStartElement ("quux", "");
434                         xtw.WriteStartElement ("quuux", null);
435                         xtw.WriteStartElement (null, "a", null);
436                         xtw.WriteStartElement (null, "b", "");
437                         xtw.WriteStartElement ("", "c", null);
438                         xtw.WriteStartElement ("", "d", "");
439
440                         AssertEquals ("<foo>bar</foo><baz><quux><quuux><a><b><c><d", StringWriterText);
441
442                         // These should throw ArgumentException because they pass in a
443                         // namespace when Namespaces = false.
444                         try {
445                                 xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
446                                 Fail ("Expected an ArgumentException.");
447                         } catch (ArgumentException) {}
448
449                         try {
450                                 xtw.WriteStartElement ("foo", "http://netsack.com/");
451                                 Fail ("Expected an ArgumentException.");
452                         } catch (ArgumentException) {}
453
454                         try {
455                                 xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
456                                 Fail ("Expected an ArgumentException.");
457                         } catch (ArgumentException) {}
458
459                         try {
460                                 xtw.WriteStartElement ("foo", "bar", null);
461                                 Fail ("Expected an ArgumentException.");
462                         } catch (ArgumentException) {}
463
464                         try {
465                                 xtw.WriteStartElement ("foo", "bar", "");
466                                 Fail ("Expected an ArgumentException.");
467                         } catch (ArgumentException) {}
468
469                         try {
470                                 xtw.WriteStartElement ("foo", "", "");
471                                 Fail ("Expected an ArgumentException.");
472                         } catch (ArgumentException) {}
473                 }
474
475                 public void TestNamespacesNoNamespaceClearsDefaultNamespace ()
476                 {
477                         xtw.WriteStartElement(String.Empty, "foo", "http://netsack.com/");
478                         xtw.WriteStartElement(String.Empty, "bar", String.Empty);
479                         xtw.WriteElementString("baz", String.Empty, String.Empty);
480                         xtw.WriteEndElement();
481                         xtw.WriteEndElement();
482                         AssertEquals ("XmlTextWriter is incorrectly outputting namespaces.",
483                                 "<foo xmlns='http://netsack.com/'><bar xmlns=''><baz /></bar></foo>", StringWriterText);
484                 }
485
486                 public void TestNamespacesPrefix ()
487                 {
488                         xtw.WriteStartElement ("foo", "bar", "http://netsack.com/");
489                         xtw.WriteStartElement ("foo", "baz", "http://netsack.com/");
490                         xtw.WriteElementString ("qux", "http://netsack.com/", String.Empty);
491                         xtw.WriteEndElement ();
492                         xtw.WriteEndElement ();
493                         AssertEquals ("XmlTextWriter is incorrectly outputting prefixes.",
494                                 "<foo:bar xmlns:foo='http://netsack.com/'><foo:baz><foo:qux /></foo:baz></foo:bar>", StringWriterText);
495                 }
496
497                 public void TestNamespacesPrefixWithEmptyAndNullNamespace ()
498                 {
499                         try {
500                                 xtw.WriteStartElement ("foo", "bar", "");
501                                 Fail ("Should have thrown an ArgumentException.");
502                         } catch (ArgumentException) {}
503
504                         try 
505                         {
506                                 xtw.WriteStartElement ("foo", "bar", null);
507                                 Fail ("Should have thrown an ArgumentException.");
508                         } 
509                         catch (ArgumentException) {}
510                 }
511
512                 public void TestNamespacesSettingWhenWriteStateNotStart ()
513                 {
514                         xtw.WriteStartElement ("foo");
515                         try 
516                         {
517                                 xtw.Namespaces = false;
518                                 Fail ("Expected an InvalidOperationException.");
519                         } 
520                         catch (InvalidOperationException) {}
521                         AssertEquals (true, xtw.Namespaces);
522                 }
523
524                 public void TestProcessingInstructionValid ()
525                 {
526                         xtw.WriteProcessingInstruction("foo", "bar");
527                         AssertEquals ("WriteProcessingInstruction had incorrect output.", "<?foo bar?>", StringWriterText);
528                 }
529
530                 public void TestProcessingInstructionInvalid ()
531                 {
532                         try 
533                         {
534                                 xtw.WriteProcessingInstruction("fo?>o", "bar");
535                                 Fail("Should have thrown an ArgumentException.");
536                         } 
537                         catch (ArgumentException) { }
538
539                         try 
540                         {
541                                 xtw.WriteProcessingInstruction("foo", "ba?>r");
542                                 Fail("Should have thrown an ArgumentException.");
543                         } 
544                         catch (ArgumentException) { }
545
546                         try 
547                         {
548                                 xtw.WriteProcessingInstruction("", "bar");
549                                 Fail("Should have thrown an ArgumentException.");
550                         } 
551                         catch (ArgumentException) { }
552
553                         try 
554                         {
555                                 xtw.WriteProcessingInstruction(null, "bar");
556                                 Fail("Should have thrown an ArgumentException.");
557                         } 
558                         catch (ArgumentException) { }
559                 }
560
561                 public void TestQuoteCharDoubleQuote ()
562                 {
563                         xtw.QuoteChar = '"';
564
565                         // version, encoding, standalone
566                         xtw.WriteStartDocument (true);
567                         
568                         // namespace declaration
569                         xtw.WriteElementString ("foo", "http://netsack.com", "bar");
570
571                         AssertEquals ("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?><foo xmlns=\"http://netsack.com\">bar</foo>", StringWriterText);
572
573
574                 }
575
576                 public void TestQuoteCharInvalid ()
577                 {
578                         try {
579                                 xtw.QuoteChar = 'x';
580                                 Fail ("Should have thrown an ArgumentException.");
581                         } catch (ArgumentException) {}
582                 }
583
584                 public void TestWriteBase64 ()
585                 {
586                         UTF8Encoding encoding = new UTF8Encoding();
587                         byte[] fooBar = encoding.GetBytes("foobar");
588                         xtw.WriteBase64 (fooBar, 0, 6);
589                         AssertEquals("Zm9vYmFy", StringWriterText);
590
591                         try {
592                                 xtw.WriteBase64 (fooBar, 3, 6);
593                                 Fail ("Expected an Argument Exception to be thrown.");
594                         } catch (ArgumentException) {}
595
596                         try {
597                                 xtw.WriteBase64 (fooBar, -1, 6);
598                                 Fail ("Expected an Argument Exception to be thrown.");
599                         } catch (ArgumentOutOfRangeException) {}
600
601                         try {
602                                 xtw.WriteBase64 (fooBar, 3, -1);
603                                 Fail ("Expected an Argument Exception to be thrown.");
604                         } catch (ArgumentOutOfRangeException) {}
605
606                         try {
607                                 xtw.WriteBase64 (null, 0, 6);
608                                 Fail ("Expected an Argument Exception to be thrown.");
609                         } catch (ArgumentNullException) {}
610                 }
611
612                 public void TestWriteCharEntity ()
613                 {
614                         xtw.WriteCharEntity ('a');
615                         AssertEquals ("&#x61;", StringWriterText);
616
617                         xtw.WriteCharEntity ('A');
618                         AssertEquals ("&#x61;&#x41;", StringWriterText);
619
620                         xtw.WriteCharEntity ('1');
621                         AssertEquals ("&#x61;&#x41;&#x31;", StringWriterText);
622
623                         xtw.WriteCharEntity ('K');
624                         AssertEquals ("&#x61;&#x41;&#x31;&#x4B;", StringWriterText);
625
626                         try {
627                                 xtw.WriteCharEntity ((char)0xd800);
628                         } catch (ArgumentException) {}
629                 }
630
631                 public void TestWriteEndAttribute ()
632                 {
633                         try 
634                         {
635                                 xtw.WriteEndAttribute ();
636                                 Fail ("Should have thrown an InvalidOperationException.");
637                         }
638                         catch (InvalidOperationException) {}
639                 }
640
641                 public void TestWriteEndDocument ()
642                 {
643                         try {
644                                 xtw.WriteEndDocument ();
645                                 Fail ("Expected an ArgumentException.");
646                         } catch (ArgumentException) {}
647
648                         xtw.WriteStartDocument ();
649
650                         try 
651                         {
652                                 xtw.WriteEndDocument ();
653                                 Fail ("Expected an ArgumentException.");
654                         } 
655                         catch (ArgumentException) {}
656
657                         xtw.WriteStartElement ("foo");
658                         xtw.WriteStartAttribute ("bar", null);
659                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='", StringWriterText);
660
661                         xtw.WriteEndDocument ();
662                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='' />", StringWriterText);
663                         AssertEquals (WriteState.Start, xtw.WriteState);
664                 }
665
666                 public void TestWriteEndElement ()
667                 {
668                         try {
669                                 xtw.WriteEndElement ();
670                                 Fail ("Should have thrown an InvalidOperationException.");
671                         } catch (InvalidOperationException e) {
672                                 AssertEquals ("Exception message is incorrect.", "There was no XML start tag open.", e.Message);
673                         }
674
675                         xtw.WriteStartElement ("foo");
676                         xtw.WriteEndElement ();
677                         AssertEquals ("<foo />", StringWriterText);
678
679                         xtw.WriteStartElement ("bar");
680                         xtw.WriteStartAttribute ("baz", null);
681                         xtw.WriteEndElement ();
682                         AssertEquals ("<foo /><bar baz='' />", StringWriterText);
683                 }
684
685                 public void TestFullEndElement ()
686                 {
687                         xtw.WriteStartElement ("foo");
688                         xtw.WriteFullEndElement ();
689                         AssertEquals ("<foo></foo>", StringWriterText);
690
691                         xtw.WriteStartElement ("bar");
692                         xtw.WriteAttributeString ("foo", "bar");
693                         xtw.WriteFullEndElement ();
694                         AssertEquals ("<foo></foo><bar foo='bar'></bar>", StringWriterText);
695
696                         xtw.WriteStartElement ("baz");
697                         xtw.WriteStartAttribute ("bar", null);
698                         xtw.WriteFullEndElement ();
699                         AssertEquals ("<foo></foo><bar foo='bar'></bar><baz bar=''></baz>", StringWriterText);
700                 }
701
702                 public void TestWriteRaw ()
703                 {
704                         xtw.WriteRaw("&<>\"'");
705                         AssertEquals ("&<>\"'", StringWriterText);
706
707                         xtw.WriteRaw(null);
708                         AssertEquals ("&<>\"'", StringWriterText);
709
710                         xtw.WriteRaw("");
711                         AssertEquals ("&<>\"'", StringWriterText);
712                 }
713
714                 public void TestWriteRawInvalidInAttribute ()
715                 {
716                         xtw.WriteStartElement ("foo");
717                         xtw.WriteStartAttribute ("bar", null);
718                         xtw.WriteRaw ("&<>\"'");
719                         xtw.WriteEndAttribute ();
720                         xtw.WriteEndElement ();
721                         AssertEquals ("<foo bar='&<>\"'' />", StringWriterText);
722                 }
723
724                 public void TestWriteState ()
725                 {
726                         AssertEquals (WriteState.Start, xtw.WriteState);
727                         xtw.WriteStartDocument ();
728                         AssertEquals (WriteState.Prolog, xtw.WriteState);
729                         xtw.WriteStartElement ("root");
730                         AssertEquals (WriteState.Element, xtw.WriteState);
731                         xtw.WriteElementString ("foo", "bar");
732                         AssertEquals (WriteState.Content, xtw.WriteState);
733                         xtw.Close ();
734                         AssertEquals (WriteState.Closed, xtw.WriteState);
735                 }
736
737                 public void TestWriteString ()
738                 {
739                         xtw.WriteStartDocument ();
740                         try {
741                                 xtw.WriteString("foo");
742                         } catch (InvalidOperationException) {}
743
744                         // Testing attribute values
745
746                         xtw.WriteStartElement ("foo");
747                         xtw.WriteAttributeString ("bar", "&<>");
748                         AssertEquals ("<?xml version='1.0' encoding='utf-16'?><foo bar='&amp;&lt;&gt;'", StringWriterText);
749                 }
750
751                 public void TestWriteAttributeStringSingleQuoteChar()
752                 {
753                         // When QuoteChar is single quote then replaces single quotes within attributes
754                         // but not double quotes.
755                         xtw.WriteStartElement ("foo");
756                         xtw.WriteAttributeString ("bar", "\"baz\"");
757                         xtw.WriteAttributeString ("quux", "'baz'");
758                         AssertEquals ("<foo bar='\"baz\"' quux='&apos;baz&apos;'", StringWriterText);
759                 }
760
761                 public void TestWriteAttributeStringDoubleQuoteChar()
762                 {
763                         // When QuoteChar is double quote then replaces double quotes within attributes
764                         // but not single quotes.
765                         xtw.QuoteChar = '"';
766                         xtw.WriteStartElement ("foo");
767                         xtw.WriteAttributeString ("bar", "\"baz\"");
768                         xtw.WriteAttributeString ("quux", "'baz'");
769                         AssertEquals ("<foo bar=\"&quot;baz&quot;\" quux=\"'baz'\"", StringWriterText);
770                 }
771
772                 public void TestWriteStringWithEntities()
773                 {
774                         // Testing element values
775                         xtw.QuoteChar = '\'';
776                         xtw.WriteElementString ("foo", "&<>\"'");
777                         AssertEquals ("<foo>&amp;&lt;&gt;\"'</foo>", StringWriterText);
778                 }
779
780                 public void TestXmlLang ()
781                 {
782                         AssertNull (xtw.XmlLang);
783                         
784                         xtw.WriteStartElement ("foo");
785                         xtw.WriteAttributeString ("xml", "lang", null, "langfoo");
786                         AssertEquals ("langfoo", xtw.XmlLang);
787                         AssertEquals ("<foo xml:lang='langfoo'", StringWriterText);
788
789                         xtw.WriteAttributeString ("boo", "yah");
790                         AssertEquals ("langfoo", xtw.XmlLang);
791                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'", StringWriterText);
792                         
793                         xtw.WriteElementString("bar", "baz");
794                         AssertEquals ("langfoo", xtw.XmlLang);
795                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>", StringWriterText);
796                         
797                         xtw.WriteString("baz");
798                         AssertEquals ("langfoo", xtw.XmlLang);
799                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz", StringWriterText);
800                         
801                         xtw.WriteStartElement ("quux");
802                         xtw.WriteStartAttribute ("xml", "lang", null);
803                         AssertEquals ("langfoo", xtw.XmlLang);
804                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText);
805                         
806                         xtw.WriteString("langbar");
807                         AssertEquals ("langfoo", xtw.XmlLang);
808                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='", StringWriterText);
809                         
810                         xtw.WriteEndAttribute ();
811                         AssertEquals ("langbar", xtw.XmlLang);
812                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'", StringWriterText);
813
814                         // check if xml:lang repeats output even if same as current scope.
815                         xtw.WriteStartElement ("joe");
816                         xtw.WriteAttributeString ("xml", "lang", null, "langbar");
817                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'", StringWriterText);
818
819                         
820                         xtw.WriteElementString ("quuux", "squonk");
821                         AssertEquals ("langbar", xtw.XmlLang);
822                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux>", StringWriterText);
823
824                         xtw.WriteEndElement ();
825                         xtw.WriteEndElement ();
826                         AssertEquals ("langfoo", xtw.XmlLang);
827                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux>", StringWriterText);
828                         
829                         xtw.WriteEndElement ();
830                         AssertNull (xtw.XmlLang);
831                         AssertEquals ("<foo xml:lang='langfoo' boo='yah'><bar>baz</bar>baz<quux xml:lang='langbar'><joe xml:lang='langbar'><quuux>squonk</quuux></joe></quux></foo>", StringWriterText);
832                         
833                         xtw.Close ();
834                         AssertNull (xtw.XmlLang);
835                 }
836
837                 // TODO: test operational aspects
838                 public void TestXmlSpace ()
839                 {
840                         xtw.WriteStartElement ("foo");
841                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
842
843                         xtw.WriteStartElement ("bar");
844                         xtw.WriteAttributeString ("xml", "space", null, "preserve");
845                         AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
846                         AssertEquals ("<foo><bar xml:space='preserve'", StringWriterText);
847
848                         xtw.WriteStartElement ("baz");
849                         xtw.WriteAttributeString ("xml", "space", null, "preserve");
850                         AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
851                         AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'", StringWriterText);
852
853                         xtw.WriteStartElement ("quux");
854                         xtw.WriteStartAttribute ("xml", "space", null);
855                         AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
856                         AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText);
857
858                         xtw.WriteString ("default");
859                         AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
860                         AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='", StringWriterText);
861                         
862                         xtw.WriteEndAttribute ();
863                         AssertEquals (XmlSpace.Default, xtw.XmlSpace);
864                         AssertEquals ("<foo><bar xml:space='preserve'><baz xml:space='preserve'><quux xml:space='default'", StringWriterText);
865
866                         xtw.WriteEndElement ();
867                         AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
868                         xtw.WriteEndElement ();
869                         AssertEquals (XmlSpace.Preserve, xtw.XmlSpace);
870                         xtw.WriteEndElement ();
871                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
872
873                         xtw.WriteStartElement ("quux");
874                         try {
875                                 xtw.WriteAttributeString ("xml", "space", null, "bubba");
876                         } catch (ArgumentException) {}
877
878                         try {
879                                 xtw.WriteAttributeString ("xml", "space", null, "PRESERVE");
880                         } catch (ArgumentException) {}
881
882                         try {
883                                 xtw.WriteAttributeString ("xml", "space", null, "Preserve");
884                         } catch (ArgumentException) {}
885
886                         try {
887                                 xtw.WriteAttributeString ("xml", "space", null, "Default");
888                         } catch (ArgumentException) {}
889
890                         try {
891                                 xtw.WriteWhitespace ("x");
892                         } catch (ArgumentException) { }
893                 }
894
895                 public void TestXmlSpaceRaw ()
896                 {
897                         xtw.WriteStartElement ("foo");
898                         xtw.WriteStartAttribute ("xml", "space", null);
899                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
900                         AssertEquals ("<foo xml:space='", StringWriterText);
901
902                         xtw.WriteString ("default");
903                         AssertEquals (XmlSpace.None, xtw.XmlSpace);
904                         AssertEquals ("<foo xml:space='", StringWriterText);
905
906                         xtw.WriteEndAttribute ();
907                         AssertEquals (XmlSpace.Default, xtw.XmlSpace);
908                         AssertEquals ("<foo xml:space='default'", StringWriterText);
909                 }
910
911                 public void TestWriteAttributes ()
912                 {
913                         XmlDocument doc = new XmlDocument();
914                         StringWriter sw = new StringWriter();
915                         XmlWriter wr = new XmlTextWriter(sw);
916                         StringBuilder sb = sw.GetStringBuilder();
917                         XmlParserContext ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
918                         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);
919
920                         xtr.Read();     // read XMLDecl
921                         wr.WriteAttributes(xtr, false);
922                         // This method don't always have to take this double-quoted style...
923                         AssertEquals("#WriteAttributes.XmlDecl.1", "version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"", sw.ToString().Trim());
924
925                         sb.Remove(0, sb.Length);        // init
926                         ctx = new XmlParserContext(doc.NameTable, new XmlNamespaceManager(doc.NameTable), "", XmlSpace.Default);
927                         xtr = new XmlTextReader("<?xml version='1.0'             standalone='no'?><root a1='A' b2='B' c3='C'><foo><bar /></foo></root>", XmlNodeType.Document, ctx);
928                         xtr.Read();     // read XMLDecl
929                         wr.WriteAttributes(xtr, false);
930                         // This method don't always have to take this double-quoted style...
931                         AssertEquals("#WriteAttributes.XmlDecl.2", "version=\"1.0\" standalone=\"no\"", sw.ToString().Trim());
932
933                         sb.Remove(0, sb.Length);        // init
934                         xtr.Read();     // read root
935                         wr.WriteStartElement(xtr.LocalName, xtr.Value);
936                         wr.WriteAttributes(xtr, false);
937                         wr.WriteEndElement();
938                         wr.Close();
939                         // This method don't always have to take this double-quoted style...
940                         AssertEquals("#WriteAttributes.Element", "<root a1=\"A\" b2=\"B\" c3=\"C\" />", sw.ToString().Trim());
941                 }
942         }
943 }