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