System.Drawing: added email to icon and test file headers
[mono.git] / mcs / class / System.Xaml / Test / System.Xaml / XamlXmlWriterTest.cs
1 //
2 // Copyright (C) 2010 Novell Inc. http://novell.com
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 using System;
24 using System.Collections;
25 using System.Collections.Generic;
26 using System.ComponentModel;
27 using System.IO;
28 using System.Linq;
29 using System.Reflection;
30 using System.Windows.Markup;
31 using System.Xaml;
32 using System.Xaml.Schema;
33 using NUnit.Framework;
34
35 using CategoryAttribute = NUnit.Framework.CategoryAttribute;
36
37 namespace MonoTests.System.Xaml
38 {
39         [TestFixture]
40         public class XamlXmlWriterTest
41         {
42                 PropertyInfo str_len = typeof (string).GetProperty ("Length");
43                 XamlSchemaContext sctx = new XamlSchemaContext (null, null);
44                 XamlType xt, xt2;
45                 XamlMember xm;
46
47                 public XamlXmlWriterTest ()
48                 {
49                         xt = new XamlType (typeof (string), sctx);
50                         xt2 = new XamlType (typeof (List<int>), sctx);
51                         xm = new XamlMember (str_len, sctx);
52                 }
53
54                 public class Foo : List<int>
55                 {
56                         public List<string> Bar { get; set; }
57                 }
58                 
59                 [Test]
60                 [ExpectedException (typeof (ArgumentNullException))]
61                 public void SchemaContextNull ()
62                 {
63                         new XamlXmlWriter (new MemoryStream (), null);
64                 }
65
66                 [Test]
67                 public void SettingsNull ()
68                 {
69                         // allowed.
70                         var w = new XamlXmlWriter (new MemoryStream (), sctx, null);
71                         Assert.AreEqual (sctx, w.SchemaContext, "#1");
72                         Assert.IsNotNull (w.Settings, "#2");
73                 }
74
75                 [Test]
76                 [ExpectedException (typeof (XamlXmlWriterException))]
77                 public void InitWriteEndMember ()
78                 {
79                         new XamlXmlWriter (new MemoryStream (), sctx, null).WriteEndMember ();
80                 }
81
82                 [Test]
83                 [ExpectedException (typeof (XamlXmlWriterException))]
84                 public void InitWriteEndObject ()
85                 {
86                         new XamlXmlWriter (new MemoryStream (), sctx, null).WriteEndObject ();
87                 }
88
89                 [Test]
90                 [ExpectedException (typeof (XamlXmlWriterException))]
91                 public void InitWriteGetObject ()
92                 {
93                         new XamlXmlWriter (new MemoryStream (), sctx, null).WriteGetObject ();
94                 }
95
96                 [Test]
97                 [ExpectedException (typeof (XamlXmlWriterException))]
98                 public void InitWriteValue ()
99                 {
100                         new XamlXmlWriter (new StringWriter (), sctx, null).WriteValue ("foo");
101                 }
102
103                 [Test]
104                 [ExpectedException (typeof (XamlXmlWriterException))]
105                 public void InitWriteStartMember ()
106                 {
107                         new XamlXmlWriter (new StringWriter (), sctx, null).WriteStartMember (new XamlMember (str_len, sctx));
108                 }
109
110                 [Test]
111                 public void InitWriteNamespace ()
112                 {
113                         var sw = new StringWriter ();
114                         var xw = new XamlXmlWriter (sw, sctx, null);
115                         xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "x")); // ignored.
116                         xw.Close ();
117                         Assert.AreEqual ("", sw.ToString (), "#1");
118                 }
119
120                 [Test]
121                 [ExpectedException (typeof (ArgumentNullException))]
122                 public void WriteNamespaceNull ()
123                 {
124                         new XamlXmlWriter (new StringWriter (), sctx, null).WriteNamespace (null);
125                 }
126
127                 [Test]
128                 public void InitWriteStartObject ()
129                 {
130                         string xml = @"<?xml version='1.0' encoding='utf-16'?><Int32 xmlns='http://schemas.microsoft.com/winfx/2006/xaml' />";
131                         var sw = new StringWriter ();
132                         var xw = new XamlXmlWriter (sw, sctx, null);
133                         xw.WriteStartObject (new XamlType (typeof (int), sctx));
134                         xw.Close ();
135                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
136                 }
137
138                 [Test]
139                 [ExpectedException (typeof (XamlXmlWriterException))]
140                 public void GetObjectAfterStartObject ()
141                 {
142                         var sw = new StringWriter ();
143                         var xw = new XamlXmlWriter (sw, sctx, null);
144                         xw.WriteStartObject (xt);
145                         xw.WriteGetObject ();
146                 }
147
148                 [Test]
149                 [ExpectedException (typeof (XamlXmlWriterException))]
150                 public void WriteStartObjectAfterTopLevel ()
151                 {
152                         var sw = new StringWriter ();
153                         var xw = new XamlXmlWriter (sw, sctx, null);
154                         xw.WriteStartObject (xt);
155                         xw.WriteEndObject ();
156                         // writing another root is not allowed.
157                         xw.WriteStartObject (xt);
158                 }
159
160                 [Test]
161                 [ExpectedException (typeof (XamlXmlWriterException))]
162                 public void WriteEndObjectExcess ()
163                 {
164                         var sw = new StringWriter ();
165                         var xw = new XamlXmlWriter (sw, sctx, null);
166                         xw.WriteStartObject (xt);
167                         xw.WriteEndObject ();
168                         xw.WriteEndObject ();
169                 }
170
171                 [Test]
172                 [ExpectedException (typeof (XamlXmlWriterException))]
173                 public void StartObjectWriteEndMember ()
174                 {
175                         var sw = new StringWriter ();
176                         var xw = new XamlXmlWriter (sw, sctx, null);
177                         xw.WriteStartObject (xt);
178                         xw.WriteEndMember ();
179                 }
180
181                 [Test]
182                 public void WriteObjectAndMember ()
183                 {
184                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String Length='foo' xmlns='http://schemas.microsoft.com/winfx/2006/xaml' />";
185                         var sw = new StringWriter ();
186                         var xw = new XamlXmlWriter (sw, sctx, null);
187                         xw.WriteStartObject (xt);
188                         xw.WriteStartMember (xm);
189                         xw.WriteValue ("foo");
190                         xw.WriteEndMember ();
191                         xw.Close ();
192                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
193                 }
194
195                 [Test]
196                 [ExpectedException (typeof (XamlXmlWriterException))]
197                 public void StartMemberWriteEndMember ()
198                 {
199                         var sw = new StringWriter ();
200                         var xw = new XamlXmlWriter (sw, sctx, null);
201                         xw.WriteStartObject (xt);
202                         xw.WriteStartMember (xm);
203                         xw.WriteEndMember (); // wow, really?
204                 }
205
206                 [Test]
207                 [ExpectedException (typeof (XamlXmlWriterException))]
208                 public void StartMemberWriteStartMember ()
209                 {
210                         var sw = new StringWriter ();
211                         var xw = new XamlXmlWriter (sw, sctx, null);
212                         xw.WriteStartObject (xt);
213                         xw.WriteStartMember (xm);
214                         xw.WriteStartMember (xm);
215                 }
216
217                 [Test]
218                 public void WriteObjectInsideMember ()
219                 {
220                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length><String /></String.Length></String>";
221                         var sw = new StringWriter ();
222                         var xw = new XamlXmlWriter (sw, sctx, null);
223                         xw.WriteStartObject (xt);
224                         xw.WriteStartMember (xm);
225                         xw.WriteStartObject (xt);
226                         xw.WriteEndObject ();
227                         xw.WriteEndMember ();
228                         xw.Close ();
229                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
230                 }
231
232                 [Test]
233                 public void ValueAfterObject ()
234                 {
235                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length><String />foo</String.Length></String>";
236                         var sw = new StringWriter ();
237                         var xw = new XamlXmlWriter (sw, sctx, null);
238                         xw.WriteStartObject (xt);
239                         xw.WriteStartMember (xm);
240                         xw.WriteStartObject (xt);
241                         xw.WriteEndObject ();
242                         // allowed.
243                         xw.WriteValue ("foo");
244                         xw.WriteEndMember ();
245                         xw.Close ();
246                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
247                 }
248
249                 [Test]
250                 [Category ("NotWorking")] // This is an abnormal operation and I cannot completely care about such operations.
251                 public void ValueAfterObject2 ()
252                 {
253                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length>foo<String />foo</String.Length></String>";
254                         var sw = new StringWriter ();
255                         var xw = new XamlXmlWriter (sw, sctx, null);
256                         xw.WriteStartObject (xt);
257                         xw.WriteStartMember (xm);
258                         xw.WriteValue ("foo");
259                         xw.WriteStartObject (xt);
260                         xw.WriteEndObject ();
261                         // allowed.
262                         xw.WriteValue ("foo");
263                         xw.WriteEndMember ();
264                         xw.Close ();
265                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
266                 }
267
268                 [Test]
269                 public void ValueAfterObject3 ()
270                 {
271                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length><String />foo<String />foo</String.Length></String>";
272                         var sw = new StringWriter ();
273                         var xw = new XamlXmlWriter (sw, sctx, null);
274                         xw.WriteStartObject (xt);
275                         xw.WriteStartMember (xm);
276                         xw.WriteStartObject (xt);
277                         xw.WriteEndObject ();
278                         xw.WriteValue ("foo");
279                         xw.WriteStartObject (xt);
280                         xw.WriteEndObject ();
281                         xw.WriteValue ("foo");
282                         xw.WriteEndMember ();
283                         xw.Close ();
284                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
285                 }
286
287                 [Test]
288                 [ExpectedException (typeof (ArgumentException))]
289                 public void WriteValueTypeNonString ()
290                 {
291                         var sw = new StringWriter ();
292                         var xw = new XamlXmlWriter (sw, sctx, null);
293                         xw.WriteStartObject (xt);
294                         xw.WriteStartMember (xm);
295                         xw.WriteValue (5); // even the type matches the member type, writing non-string value is rejected.
296                 }
297
298                 [Test]
299                 [ExpectedException (typeof (XamlXmlWriterException))]
300                 public void WriteValueAfterValue ()
301                 {
302                         var sw = new StringWriter ();
303                         var xw = new XamlXmlWriter (sw, sctx, null);
304                         xw.WriteStartObject (xt);
305                         xw.WriteValue ("foo");
306                         xw.WriteValue ("bar");
307                 }
308
309                 [Test]
310                 [ExpectedException (typeof (XamlXmlWriterException))]
311                 public void WriteValueAfterNullValue ()
312                 {
313                         var sw = new StringWriter ();
314                         var xw = new XamlXmlWriter (sw, sctx, null);
315                         xw.WriteStartObject (xt);
316                         xw.WriteValue (null);
317                         xw.WriteValue ("bar");
318                 }
319
320                 [Test]
321                 [ExpectedException (typeof (XamlXmlWriterException))]
322                 public void WriteValueList ()
323                 {
324                         var sw = new StringWriter ();
325                         var xw = new XamlXmlWriter (sw, sctx, null);
326                         xw.WriteStartObject (new XamlType (typeof (List<string>), sctx));
327                         xw.WriteStartMember (XamlLanguage.Items);
328                         xw.WriteValue ("foo");
329                         xw.WriteValue ("bar");
330                 }
331
332                 [ExpectedException (typeof (XamlXmlWriterException))]
333                 public void StartMemberWriteEndObject ()
334                 {
335                         var sw = new StringWriter ();
336                         var xw = new XamlXmlWriter (sw, sctx, null);
337                         xw.WriteStartObject (xt);
338                         xw.WriteStartMember (xm);
339                         xw.WriteEndObject ();
340                 }
341
342                 [Test]
343                 public void WriteNamespace ()
344                 {
345                         string xml = @"<?xml version='1.0' encoding='utf-16'?><x:String xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:y='urn:foo' />";
346                         var sw = new StringWriter ();
347                         var xw = new XamlXmlWriter (sw, sctx, null);
348                         xw.WriteNamespace (new NamespaceDeclaration (XamlLanguage.Xaml2006Namespace, "x"));
349                         xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
350                         xw.WriteStartObject (xt);
351                         xw.WriteEndObject ();
352                         xw.Close ();
353                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
354                 }
355
356                 [Test]
357                 [ExpectedException (typeof (XamlXmlWriterException))]
358                 public void StartObjectStartObject ()
359                 {
360                         var sw = new StringWriter ();
361                         var xw = new XamlXmlWriter (sw, sctx, null);
362                         xw.WriteStartObject (xt);
363                         xw.WriteStartObject (xt);
364                 }
365
366                 [Test]
367                 [ExpectedException (typeof (XamlXmlWriterException))]
368                 public void StartObjectValue ()
369                 {
370                         var sw = new StringWriter ();
371                         var xw = new XamlXmlWriter (sw, sctx, null);
372                         xw.WriteStartObject (xt);
373                         xw.WriteValue ("foo");
374                 }
375
376                 [Test]
377                 public void ObjectThenNamespaceThenObjectThenObject ()
378                 {
379                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length><String /><String /></String.Length></String>";
380                         var sw = new StringWriter ();
381                         var xw = new XamlXmlWriter (sw, sctx, null);
382                         xw.WriteStartObject (xt); // <String>
383                         xw.WriteStartMember (xm); // <String.Length>
384                         xw.WriteStartObject (xt); // <String />
385                         xw.WriteEndObject ();
386                         xw.WriteStartObject (xt); // <String />
387                         xw.WriteEndObject ();
388                         xw.Close ();
389                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
390                 }
391
392                 // This doesn't result in XamlXmlWriterException. Instead,
393                 // IOE is thrown. WriteValueAfterNamespace() too.
394                 // It is probably because namespaces are verified independently
395                 // from state transition (and borks when the next write is not
396                 // appropriate).
397                 [Test]
398                 [ExpectedException (typeof (InvalidOperationException))]
399                 public void EndObjectAfterNamespace ()
400                 {
401                         var sw = new StringWriter ();
402                         var xw = new XamlXmlWriter (sw, sctx, null);
403                         xw.WriteStartObject (xt);
404                         xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
405                         xw.WriteEndObject ();
406                 }
407
408                 [Test]
409                 [ExpectedException (typeof (InvalidOperationException))] // ... shouldn't it be XamlXmlWriterException?
410                 public void WriteValueAfterNamespace ()
411                 {
412                         var sw = new StringWriter ();
413                         var xw = new XamlXmlWriter (sw, sctx, null);
414                         xw.WriteStartObject (xt);
415                         xw.WriteStartMember (XamlLanguage.Initialization);
416                         xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
417                         xw.WriteValue ("foo");
418                 }
419
420                 [Test]
421                 [Category ("NotWorking")]
422                 public void ValueThenStartObject ()
423                 {
424                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length>foo<String /></String.Length></String>";
425                         var sw = new StringWriter ();
426                         var xw = new XamlXmlWriter (sw, sctx, null);
427                         xw.WriteStartObject (xt);
428                         xw.WriteStartMember (xm);
429                         xw.WriteValue ("foo");
430                         xw.WriteStartObject (xt); // looks like it is ignored. It is weird input anyways.
431                         xw.Close ();
432                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
433                 }
434
435                 [Test]
436                 public void ValueThenNamespace ()
437                 {
438                         var sw = new StringWriter ();
439                         var xw = new XamlXmlWriter (sw, sctx, null);
440                         xw.WriteStartObject (xt);
441                         xw.WriteStartMember (xm);
442                         xw.WriteValue ("foo");
443                         xw.WriteNamespace (new NamespaceDeclaration ("y", "urn:foo")); // this does not raise an error (since it might start another object)
444                 }
445
446                 [Test]
447                 [ExpectedException (typeof (XamlXmlWriterException))] // strange, this does *not* result in IOE...
448                 public void ValueThenNamespaceThenEndMember ()
449                 {
450                         var sw = new StringWriter ();
451                         var xw = new XamlXmlWriter (sw, sctx, null);
452                         xw.WriteStartObject (xt);
453                         xw.WriteStartMember (xm);
454                         xw.WriteValue ("foo");
455                         xw.WriteNamespace (new NamespaceDeclaration ("y", "urn:foo"));
456                         xw.WriteEndMember ();
457                 }
458
459                 [Test]
460                 public void StartMemberAfterNamespace ()
461                 {
462                         // This test shows:
463                         // 1) StartMember after NamespaceDeclaration is valid
464                         // 2) Member is written as an element (not attribute)
465                         //    if there is a NamespaceDeclaration in the middle.
466                         string xml = @"<?xml version='1.0' encoding='utf-16'?><String xmlns='http://schemas.microsoft.com/winfx/2006/xaml'><String.Length xmlns:y='urn:foo'>foo</String.Length></String>";
467                         var sw = new StringWriter ();
468                         var xw = new XamlXmlWriter (sw, sctx, null);
469                         xw.WriteStartObject (xt);
470                         xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
471                         xw.WriteStartMember (xm);
472                         xw.WriteValue ("foo");
473                         xw.Close ();
474                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
475                 }
476
477                 [Test]
478                 [ExpectedException (typeof (XamlXmlWriterException))]
479                 public void EndMemberThenStartObject ()
480                 {
481                         var sw = new StringWriter ();
482                         var xw = new XamlXmlWriter (sw, sctx, null);
483                         xw.WriteStartObject (xt);
484                         xw.WriteStartMember (xm);
485                         xw.WriteValue ("foo");
486                         xw.WriteEndMember ();
487                         xw.WriteStartObject (xt);
488                 }
489
490                 [Test]
491                 [ExpectedException (typeof (InvalidOperationException))]
492                 public void GetObjectOnNonCollection ()
493                 {
494                         var sw = new StringWriter ();
495                         var xw = new XamlXmlWriter (sw, sctx, null);
496                         xw.WriteStartObject (xt);
497                         xw.WriteStartMember (xm);
498                         xw.WriteGetObject ();
499                 }
500
501                 [Test]
502                 [ExpectedException (typeof (InvalidOperationException))]
503                 public void GetObjectOnNonCollection2 ()
504                 {
505                         var sw = new StringWriter ();
506                         var xw = new XamlXmlWriter (sw, sctx, null);
507                         xw.WriteStartObject (xt);
508                         xw.WriteStartMember (new XamlMember (typeof (string).GetProperty ("Length"), sctx)); // Length is of type int, which is not a collection
509                         xw.WriteGetObject ();
510                 }
511
512                 [Test]
513                 public void GetObjectOnCollection ()
514                 {
515                         string xml = @"<?xml version='1.0' encoding='utf-16'?><List xmlns='clr-namespace:System.Collections.Generic;assembly=mscorlib'><x:TypeArguments xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>x:Int32</x:TypeArguments><List.Bar /></List>";
516                         var sw = new StringWriter ();
517                         var xw = new XamlXmlWriter (sw, sctx, null);
518                         xw.WriteStartObject (xt2);
519                         xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
520                         xw.WriteGetObject ();
521                         xw.Close ();
522                         // FIXME: enable it once we got generic type output fixed.
523                         //Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
524                 }
525
526                 [Test]
527                 [ExpectedException (typeof (XamlXmlWriterException))]
528                 public void ValueAfterGetObject ()
529                 {
530                         var sw = new StringWriter ();
531                         var xw = new XamlXmlWriter (sw, sctx, null);
532                         xw.WriteStartObject (xt2);
533                         xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
534                         xw.WriteGetObject ();
535                         xw.WriteValue ("foo");
536                 }
537
538                 [Test]
539                 [ExpectedException (typeof (XamlXmlWriterException))]
540                 public void StartObjectAfterGetObject ()
541                 {
542                         var sw = new StringWriter ();
543                         var xw = new XamlXmlWriter (sw, sctx, null);
544                         xw.WriteStartObject (xt2);
545                         xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
546                         xw.WriteGetObject ();
547                         xw.WriteStartObject (xt);
548                 }
549
550                 [Test]
551                 [ExpectedException (typeof (XamlXmlWriterException))]
552                 public void EndMemberAfterGetObject ()
553                 {
554                         var sw = new StringWriter ();
555                         var xw = new XamlXmlWriter (sw, sctx, null);
556                         xw.WriteStartObject (xt2);
557                         xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
558                         xw.WriteGetObject ();
559                         xw.WriteEndMember (); // ...!?
560                 }
561
562                 [Test]
563                 public void StartMemberAfterGetObject ()
564                 {
565                         string xml = @"<?xml version='1.0' encoding='utf-16'?><List xmlns='clr-namespace:System.Collections.Generic;assembly=mscorlib'><x:TypeArguments xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>x:Int32</x:TypeArguments><List.Bar><List.Length /></List.Bar></List>";
566                         var sw = new StringWriter ();
567                         var xw = new XamlXmlWriter (sw, sctx, null);
568                         xw.WriteStartObject (xt2); // <List
569                         xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx)); // <List.Bar>
570                         xw.WriteGetObject ();
571                         xw.WriteStartMember (xm); // <List.Length /> . Note that the corresponding member is String.Length(!)
572                         xw.Close ();
573                         // FIXME: enable it once we got generic type output fixed.
574                         //Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
575                 }
576
577                 [Test]
578                 public void EndObjectAfterGetObject ()
579                 {
580                         var sw = new StringWriter ();
581                         var xw = new XamlXmlWriter (sw, sctx, null);
582                         xw.WriteStartObject (xt2);
583                         xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
584                         xw.WriteGetObject ();
585                         xw.WriteEndObject ();
586                 }
587
588                 [Test]
589                 public void WriteNode ()
590                 {
591                         string xml = @"<?xml version='1.0' encoding='utf-16'?><x:String xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>foo</x:String>";
592                         var r = new XamlObjectReader ("foo", sctx);
593                         var sw = new StringWriter ();
594                         var w = new XamlXmlWriter (sw, sctx, null);
595                         while (r.Read ())
596                                 w.WriteNode (r);
597                         w.Close ();
598                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
599                 }
600
601                 [Test]
602                 public void WriteNode2 ()
603                 {
604                         var r = new XamlObjectReader ("foo", sctx);
605                         var w = new XamlObjectWriter (sctx, null);
606                         while (r.Read ())
607                                 w.WriteNode (r);
608                         w.Close ();
609                         Assert.AreEqual ("foo", w.Result, "#1");
610                 }
611
612                 [Test]
613                 public void ConstructorArguments ()
614                 {
615                         string xml = String.Format (@"<?xml version='1.0' encoding='utf-16'?><ArgumentAttributed xmlns='clr-namespace:MonoTests.System.Xaml;assembly={0}' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'><x:Arguments><x:String>xxx</x:String><x:String>yyy</x:String></x:Arguments></ArgumentAttributed>",  GetType ().Assembly.GetName ().Name);
616                         Assert.IsFalse (sctx.FullyQualifyAssemblyNamesInClrNamespaces, "premise0");
617                         var r = new XamlObjectReader (new ArgumentAttributed ("xxx", "yyy"), sctx);
618                         var sw = new StringWriter ();
619                         var w = new XamlXmlWriter (sw, sctx, null);
620                         XamlServices.Transform (r, w);
621                         Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
622                 }
623
624                 [Test]
625                 public void WriteValueAsString ()
626                 {
627                         var sw = new StringWriter ();
628                         var xw = new XamlXmlWriter (sw, sctx, null);
629                         var xt = sctx.GetXamlType (typeof (TestXmlWriterClass1));
630                         xw.WriteStartObject (xt);
631                         xw.WriteStartMember (xt.GetMember ("Foo"));
632                         xw.WriteValue ("50");
633                         xw.Close ();
634                         string xml = String.Format (@"<?xml version='1.0' encoding='utf-16'?><TestXmlWriterClass1 xmlns='clr-namespace:MonoTests.System.Xaml;assembly={0}' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'></TestXmlWriterClass1>",  GetType ().Assembly.GetName ().Name);
635                 }
636
637                 string ReadXml (string name)
638                 {
639                         return File.ReadAllText ("Test/XmlFiles/" + name).Trim ().Replace ("\r\n", "\n").Replace ("\n", Environment.NewLine);
640                 }
641
642                 [Test]
643                 public void Write_String ()
644                 {
645                         Assert.AreEqual (ReadXml ("String.xml"), XamlServices.Save ("foo"), "#1");
646                 }
647
648                 [Test]
649                 public void Write_Int32 ()
650                 {
651                         Assert.AreEqual (ReadXml ("Int32.xml"), XamlServices.Save (5), "#1");
652                 }
653
654                 [Test]
655                 public void Write_DateTime ()
656                 {
657                         Assert.AreEqual (ReadXml ("DateTime.xml"), XamlServices.Save (new DateTime (2010, 4, 14)), "#1");
658                 }
659
660                 [Test]
661                 public void Write_TimeSpan ()
662                 {
663                         Assert.AreEqual (ReadXml ("TimeSpan.xml"), XamlServices.Save (TimeSpan.FromMinutes (7)), "#1");
664                 }
665
666                 [Test]
667                 public void Write_Uri ()
668                 {
669                         Assert.AreEqual (ReadXml ("Uri.xml"), XamlServices.Save (new Uri ("urn:foo")), "#1");
670                 }
671
672                 [Test]
673                 public void Write_Null ()
674                 {
675                         Assert.AreEqual (ReadXml ("NullExtension.xml"), XamlServices.Save (null), "#1");
676                 }
677
678                 [Test]
679                 public void Write_NullExtension ()
680                 {
681                         Assert.AreEqual (ReadXml ("NullExtension.xml"), XamlServices.Save (new NullExtension ()), "#1");
682                 }
683
684                 [Test]
685                 public void Write_Type ()
686                 {
687                         Assert.AreEqual (ReadXml ("Type.xml").Trim (), XamlServices.Save (typeof (int)), "#1");
688                 }
689
690                 [Test]
691                 public void Write_Type2 ()
692                 {
693                         Assert.AreEqual (ReadXml ("Type2.xml").Trim (), XamlServices.Save (typeof (TestClass1)), "#1");
694                 }
695
696                 [Test]
697                 public void Write_Guid ()
698                 {
699                         Assert.AreEqual (ReadXml ("Guid.xml").Trim (), XamlServices.Save (Guid.Parse ("9c3345ec-8922-4662-8e8d-a4e41f47cf09")), "#1");
700                 }
701
702                 [Test]
703                 public void Write_StaticExtension ()
704                 {
705                         Assert.AreEqual (ReadXml ("StaticExtension.xml").Trim (), XamlServices.Save (new StaticExtension ("FooBar")), "#1");
706                 }
707
708                 [Test]
709                 public void Write_StaticExtension2 ()
710                 {
711                         Assert.AreEqual (ReadXml ("StaticExtension.xml").Trim (), XamlServices.Save (new StaticExtension () { Member = "FooBar"}), "#1");
712                 }
713
714                 [Test]
715                 public void Write_Reference ()
716                 {
717                         Assert.AreEqual (ReadXml ("Reference.xml").Trim (), XamlServices.Save (new Reference ("FooBar")), "#1");
718                 }
719
720                 [Test]
721                 public void Write_ArrayInt32 ()
722                 {
723                         Assert.AreEqual (ReadXml ("Array_Int32.xml").Trim (), XamlServices.Save (new int [] {4, -5, 0, 255, int.MaxValue}), "#1");
724                 }
725
726                 [Test]
727                 public void Write_ListInt32 ()
728                 {
729                         Assert.AreEqual (ReadXml ("List_Int32.xml").Trim (), XamlServices.Save (new int [] {5, -3, int.MaxValue, 0}.ToList ()), "#1");
730                 }
731
732                 [Test]
733                 public void Write_ListInt32_2 ()
734                 {
735                         var obj = new List<int> (new int [0]) { Capacity = 0 }; // set explicit capacity for trivial implementation difference
736                         Assert.AreEqual (ReadXml ("List_Int32_2.xml").Trim (), XamlServices.Save (obj), "#1");
737                 }
738
739                 [Test]
740                 public void Write_ListType ()
741                 {
742                         var obj = new List<Type> (new Type [] {typeof (int), typeof (Dictionary<Type, XamlType>)}) { Capacity = 2 };
743                         Assert.AreEqual (ReadXml ("List_Type.xml").Trim (), XamlServices.Save (obj), "#1");
744                 }
745
746                 [Test]
747                 public void Write_ListArray ()
748                 {
749                         var obj = new List<Array> (new Array [] { new int [] { 1,2,3}, new string [] { "foo", "bar", "baz" }}) { Capacity = 2 };
750                         Assert.AreEqual (ReadXml ("List_Array.xml").Trim (), XamlServices.Save (obj), "#1");
751                 }
752
753                 [Test]
754                 public void Write_DictionaryInt32String ()
755                 {
756                         var dic = new Dictionary<int,string> ();
757                         dic.Add (0, "foo");
758                         dic.Add (5, "bar");
759                         dic.Add (-2, "baz");
760                         Assert.AreEqual (ReadXml ("Dictionary_Int32_String.xml").Trim (), XamlServices.Save (dic), "#1");
761                 }
762
763                 [Test]
764                 public void Write_DictionaryStringType ()
765                 {
766                         var dic = new Dictionary<string,Type> ();
767                         dic.Add ("t1", typeof (int));
768                         dic.Add ("t2", typeof (int []));
769                         dic.Add ("t3", typeof (int?));
770                         dic.Add ("t4", typeof (List<int>));
771                         dic.Add ("t5", typeof (Dictionary<int,DateTime>));
772                         dic.Add ("t6", typeof (List<KeyValuePair<int,DateTime>>));
773                         Assert.AreEqual (ReadXml ("Dictionary_String_Type.xml").Trim (), XamlServices.Save (dic), "#1");
774                 }
775
776                 [Test]
777                 [ExpectedException (typeof (XamlXmlWriterException))]
778                 public void Write_PositionalParameters1 ()
779                 {
780                         // PositionalParameters can only be written when the 
781                         // instance is NOT the root object.
782                         //
783                         // A single positional parameter can be written as an 
784                         // attribute, but there are two in PositionalParameters1.
785                         //
786                         // A default constructor could be used to not use
787                         // PositionalParameters, but there isn't in this type.
788                         var obj = new PositionalParametersClass1 ("foo", 5);
789                         XamlServices.Save (obj);
790                 }
791
792                 [Test]
793                 public void Write_PositionalParameters1Wrapper ()
794                 {
795                         // Unlike the above case, this has the wrapper object and hence PositionalParametersClass1 can be written as an attribute (markup extension)
796                         var obj = new PositionalParametersWrapper ("foo", 5);
797                         Assert.AreEqual (ReadXml ("PositionalParametersWrapper.xml").Trim (), XamlServices.Save (obj), "#1");
798                 }
799                 
800                 [Test]
801                 public void Write_ArgumentAttributed ()
802                 {
803                         var obj = new ArgumentAttributed ("foo", "bar");
804                         Assert.AreEqual (ReadXml ("ArgumentAttributed.xml").Trim (), XamlServices.Save (obj), "#1");
805                 }
806
807                 [Test]
808                 public void Write_ArrayExtension2 ()
809                 {
810                         var obj = new ArrayExtension (typeof (int));
811                         Assert.AreEqual (ReadXml ("ArrayExtension2.xml").Trim (), XamlServices.Save (obj), "#1");
812                 }
813
814                 [Test]
815                 public void Write_ArrayList ()
816                 {
817                         var obj = new ArrayList (new int [] {5, -3, 0});
818                         Assert.AreEqual (ReadXml ("ArrayList.xml").Trim (), XamlServices.Save (obj), "#1");
819                 }
820
821                 [Test]
822                 public void ComplexPositionalParameterWrapper ()
823                 {
824                         var obj = new ComplexPositionalParameterWrapper () { Param = new ComplexPositionalParameterClass (new ComplexPositionalParameterValue () { Foo = "foo" })};
825                         Assert.AreEqual (ReadXml ("ComplexPositionalParameterWrapper.xml").Trim (), XamlServices.Save (obj), "#1");
826                 }
827
828                 [Test]
829                 public void Write_ListWrapper ()
830                 {
831                         var obj = new ListWrapper (new List<int> (new int [] {5, -3, 0}) { Capacity = 3}); // set explicit capacity for trivial implementation difference
832                         Assert.AreEqual (ReadXml ("ListWrapper.xml").Trim (), XamlServices.Save (obj), "#1");
833                 }
834
835                 [Test]
836                 public void Write_ListWrapper2 ()
837                 {
838                         var obj = new ListWrapper2 (new List<int> (new int [] {5, -3, 0}) { Capacity = 3}); // set explicit capacity for trivial implementation difference
839                         Assert.AreEqual (ReadXml ("ListWrapper2.xml").Trim (), XamlServices.Save (obj), "#1");
840                 }
841
842                 [Test]
843                 public void Write_MyArrayExtension ()
844                 {
845                         var obj = new MyArrayExtension (new int [] {5, -3, 0});
846                         Assert.AreEqual (ReadXml ("MyArrayExtension.xml").Trim (), XamlServices.Save (obj), "#1");
847                 }
848
849                 [Test]
850                 public void Write_MyArrayExtensionA ()
851                 {
852                         var obj = new MyArrayExtensionA (new int [] {5, -3, 0});
853                         Assert.AreEqual (ReadXml ("MyArrayExtensionA.xml").Trim (), XamlServices.Save (obj), "#1");
854                 }
855
856                 [Test]
857                 public void Write_MyExtension ()
858                 {
859                         var obj = new MyExtension () { Foo = typeof (int), Bar = "v2", Baz = "v7"};
860                         Assert.AreEqual (ReadXml ("MyExtension.xml").Trim (), XamlServices.Save (obj), "#1");
861                 }
862
863                 [Test]
864                 public void Write_MyExtension2 ()
865                 {
866                         var obj = new MyExtension2 () { Foo = typeof (int), Bar = "v2"};
867                         Assert.AreEqual (ReadXml ("MyExtension2.xml").Trim (), XamlServices.Save (obj), "#1");
868                 }
869
870                 [Test]
871                 public void Write_MyExtension3 ()
872                 {
873                         var obj = new MyExtension3 () { Foo = typeof (int), Bar = "v2"};
874                         Assert.AreEqual (ReadXml ("MyExtension3.xml").Trim (), XamlServices.Save (obj), "#1");
875                 }
876
877                 [Test]
878                 public void Write_MyExtension4 ()
879                 {
880                         var obj = new MyExtension4 () { Foo = typeof (int), Bar = "v2"};
881                         Assert.AreEqual (ReadXml ("MyExtension4.xml").Trim (), XamlServices.Save (obj), "#1");
882                 }
883
884                 [Test]
885                 public void Write_MyExtension6 ()
886                 {
887                         var obj = new MyExtension6 ("foo");
888                         Assert.AreEqual (ReadXml ("MyExtension6.xml").Trim (), XamlServices.Save (obj), "#1");
889                 }
890                 
891                 [Test]
892                 public void Write_PropertyDefinition ()
893                 {
894                         var obj = new PropertyDefinition () { Modifier = "protected", Name = "foo", Type = XamlLanguage.String };
895                         Assert.AreEqual (ReadXml ("PropertyDefinition.xml").Trim (), XamlServices.Save (obj), "#1");
896                 }
897                 
898                 [Test]
899                 public void Write_StaticExtensionWrapper ()
900                 {
901                         var obj = new StaticExtensionWrapper () { Param = new StaticExtension ("StaticExtensionWrapper.Foo") };
902                         Assert.AreEqual (ReadXml ("StaticExtensionWrapper.xml").Trim (), XamlServices.Save (obj), "#1");
903                 }
904
905                 [Test]
906                 public void Write_TypeExtensionWrapper ()
907                 {
908                         var obj = new TypeExtensionWrapper () { Param = new TypeExtension ("Foo") };
909                         Assert.AreEqual (ReadXml ("TypeExtensionWrapper.xml").Trim (), XamlServices.Save (obj), "#1");
910                 }
911
912                 [Test]
913                 public void Write_NamedItems ()
914                 {
915                         // foo
916                         // - bar
917                         // -- foo
918                         // - baz
919                         var obj = new NamedItem ("foo");
920                         var obj2 = new NamedItem ("bar");
921                         obj.References.Add (obj2);
922                         obj.References.Add (new NamedItem ("baz"));
923                         obj2.References.Add (obj);
924
925                         Assert.AreEqual (ReadXml ("NamedItems.xml").Trim (), XamlServices.Save (obj), "#1");
926                 }
927
928                 [Test]
929                 public void Write_NamedItems2 ()
930                 {
931                         // i1
932                         // - i2
933                         // -- i3
934                         // - i4
935                         // -- i3
936                         var obj = new NamedItem2 ("i1");
937                         var obj2 = new NamedItem2 ("i2");
938                         var obj3 = new NamedItem2 ("i3");
939                         var obj4 = new NamedItem2 ("i4");
940                         obj.References.Add (obj2);
941                         obj.References.Add (obj4);
942                         obj2.References.Add (obj3);
943                         obj4.References.Add (obj3);
944
945                         Assert.AreEqual (ReadXml ("NamedItems2.xml").Trim (), XamlServices.Save (obj), "#1");
946                 }
947
948                 [Test]
949                 public void Write_XmlSerializableWrapper ()
950                 {
951                         var obj = new XmlSerializableWrapper (new XmlSerializable ("<root/>"));
952                         Assert.AreEqual (ReadXml ("XmlSerializableWrapper.xml").Trim (), XamlServices.Save (obj), "#1");
953                 }
954
955                 [Test]
956                 public void Write_XmlSerializable ()
957                 {
958                         var obj = new XmlSerializable ("<root/>");
959                         Assert.AreEqual (ReadXml ("XmlSerializable.xml").Trim (), XamlServices.Save (obj), "#1");
960                 }
961
962                 [Test]
963                 public void Write_ListXmlSerializable ()
964                 {
965                         var obj = new List<XmlSerializable> ();
966                         obj.Add (new XmlSerializable ("<root/>"));
967                         Assert.AreEqual (ReadXml ("List_XmlSerializable.xml").Trim (), XamlServices.Save (obj), "#1");
968                 }
969
970                 [Test]
971                 public void Write_AttachedProperty ()
972                 {
973                         var obj = new AttachedWrapper ();
974                         Attachable.SetFoo (obj, "x");
975                         Attachable.SetFoo (obj.Value, "y");
976                         try {
977                                 Assert.AreEqual (ReadXml ("AttachedProperty.xml").Trim (), XamlServices.Save (obj), "#1");
978                         } finally {
979                                 Attachable.SetFoo (obj, null);
980                                 Attachable.SetFoo (obj.Value, null);
981                         }
982                 }
983
984                 [Test]
985                 [Category ("NotWorking")] // cosmetic attribute order difference
986                 public void Write_AbstractWrapper ()
987                 {
988                         var obj = new AbstractContainer () { Value2 = new DerivedObject () { Foo = "x" } };
989                         Assert.AreEqual (ReadXml ("AbstractContainer.xml").Trim (), XamlServices.Save (obj), "#1");
990                 }
991
992                 [Test]
993                 public void Write_ReadOnlyPropertyContainer ()
994                 {
995                         var obj = new ReadOnlyPropertyContainer () { Foo = "x" };
996                         Assert.AreEqual (ReadXml ("ReadOnlyPropertyContainer.xml").Trim (), XamlServices.Save (obj), "#1");
997                         
998                         var sw = new StringWriter ();
999                         var xw = new XamlXmlWriter (sw, new XamlSchemaContext ());
1000                         var xt = xw.SchemaContext.GetXamlType (obj.GetType ());
1001                         xw.WriteStartObject (xt);
1002                         xw.WriteStartMember (xt.GetMember ("Bar"));
1003                         xw.WriteValue ("x");
1004                         xw.WriteEndMember ();
1005                         xw.WriteEndObject ();
1006                         xw.Close ();
1007                         Assert.IsTrue (sw.ToString ().IndexOf ("Bar") > 0, "#2"); // it is not rejected by XamlXmlWriter. But XamlServices does not write it.
1008                 }
1009
1010                 [Test]
1011                 public void Write_TypeConverterOnListMember ()
1012                 {
1013                         var obj = new SecondTest.TypeOtherAssembly ();
1014                         obj.Values.AddRange (new uint? [] {1, 2, 3});
1015                         Assert.AreEqual (ReadXml ("TypeConverterOnListMember.xml").Trim (), XamlServices.Save (obj), "#1");
1016                 }
1017
1018                 [Test]
1019                 public void Write_EnumContainer ()
1020                 {
1021                         var obj = new EnumContainer () { EnumProperty = EnumValueType.Two };
1022                         Assert.AreEqual (ReadXml ("EnumContainer.xml").Trim (), XamlServices.Save (obj), "#1");
1023                 }
1024
1025                 [Test]
1026                 public void Write_CollectionContentProperty ()
1027                 {
1028                         var obj = new CollectionContentProperty ();
1029                         for (int i = 0; i < 4; i++)
1030                                 obj.ListOfItems.Add (new SimpleClass ());
1031                         Assert.AreEqual (ReadXml ("CollectionContentProperty.xml").Trim (), XamlServices.Save (obj), "#1");
1032                 }
1033
1034                 [Test]
1035                 public void Write_CollectionContentPropertyX ()
1036                 {
1037                         var obj = new CollectionContentPropertyX ();
1038                         var l = new List<object> ();
1039                         obj.ListOfItems.Add (l);
1040                         for (int i = 0; i < 4; i++)
1041                                 l.Add (new SimpleClass ());
1042                         Assert.AreEqual (ReadXml ("CollectionContentPropertyX.xml").Trim (), XamlServices.Save (obj), "#1");
1043                 }
1044
1045                 [Test]
1046                 [Category ("NotWorking")] // TestProperty is written as element so far.
1047                 public void Write_AmbientPropertyContainer ()
1048                 {
1049                         var obj = new SecondTest.ResourcesDict ();
1050                         var t1 = new SecondTest.TestObject ();
1051                         obj.Add ("TestDictItem", t1);
1052                         var t2 = new SecondTest.TestObject ();
1053                         t2.TestProperty = t1;
1054                         obj.Add ("okay", t2);
1055                         Assert.AreEqual (ReadXml ("AmbientPropertyContainer.xml").Trim (), XamlServices.Save (obj), "#1");
1056                 }
1057
1058                 [Test]
1059                 public void Write_NullableContainer ()
1060                 {
1061                         var obj = new NullableContainer () { TestProp = 5 };
1062                         Assert.AreEqual (ReadXml ("NullableContainer.xml").Trim (), XamlServices.Save (obj), "#1");
1063                 }
1064         }
1065
1066         public class TestXmlWriterClass1
1067         {
1068                 public int Foo { get; set; }
1069         }
1070 }