2 // Copyright (C) 2010 Novell Inc. http://novell.com
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:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
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.
24 using System.Collections;
25 using System.Collections.Generic;
26 using System.ComponentModel;
28 using System.Reflection;
29 using System.Windows.Markup;
31 using System.Xaml.Schema;
32 using NUnit.Framework;
34 using Category = NUnit.Framework.CategoryAttribute;
36 namespace MonoTests.System.Xaml
39 public class XamlObjectWriterTest
41 PropertyInfo str_len = typeof (string).GetProperty ("Length");
42 XamlSchemaContext sctx = new XamlSchemaContext (null, null);
43 XamlType xt, xt2, xt3, xt4;
44 XamlMember xm, xm2, xm3;
46 public XamlObjectWriterTest ()
48 xt = new XamlType (typeof (string), sctx);
49 xt2 = new XamlType (typeof (List<int>), sctx);
50 xt3 = new XamlType (typeof (TestClass1), sctx);
51 xt4 = new XamlType (typeof (Foo), sctx);
52 xm = new XamlMember (str_len, sctx);
53 xm2 = new XamlMember (typeof (TestClass1).GetProperty ("TestProp1"), sctx);
54 xm3 = new XamlMember (typeof (TestClass1).GetProperty ("TestProp2"), sctx);
57 public class TestClass1
63 public string TestProp1 { get; set; }
65 public TestClass1 TestProp2 { get; set; }
66 public string TestProp3 { get; set; }
67 public int TestProp4 { get; set; }
70 public class Foo : List<int>
74 Bar = new List<string> ();
76 public List<string> Bar { get; private set; }
77 public List<string> Baz { get; set; }
78 public string Ext { get; set; }
82 [ExpectedException (typeof (ArgumentNullException))]
83 public void SchemaContextNull ()
85 new XamlObjectWriter (null);
89 public void SettingsNull ()
92 var w = new XamlObjectWriter (sctx, null);
93 Assert.AreEqual (sctx, w.SchemaContext, "#1");
97 [ExpectedException (typeof (XamlObjectWriterException))]
98 public void InitWriteEndMember ()
100 new XamlObjectWriter (sctx, null).WriteEndMember ();
104 [ExpectedException (typeof (XamlObjectWriterException))]
105 public void InitWriteEndObject ()
107 new XamlObjectWriter (sctx, null).WriteEndObject ();
111 [ExpectedException (typeof (XamlObjectWriterException))]
112 public void InitWriteGetObject ()
114 new XamlObjectWriter (sctx, null).WriteGetObject ();
118 [ExpectedException (typeof (XamlObjectWriterException))]
119 public void InitWriteValue ()
121 new XamlObjectWriter (sctx, null).WriteValue ("foo");
125 [ExpectedException (typeof (XamlObjectWriterException))]
126 public void InitWriteStartMember ()
128 new XamlObjectWriter (sctx, null).WriteStartMember (new XamlMember (str_len, sctx));
132 public void InitWriteNamespace ()
134 var xw = new XamlObjectWriter (sctx, null);
135 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "x")); // ignored.
137 Assert.IsNull (xw.Result, "#1");
141 [ExpectedException (typeof (ArgumentNullException))]
142 public void WriteNamespaceNull ()
144 new XamlObjectWriter (sctx, null).WriteNamespace (null);
148 public void InitWriteStartObject ()
150 var xw = new XamlObjectWriter (sctx, null);
151 xw.WriteStartObject (new XamlType (typeof (int), sctx));
153 Assert.AreEqual (0, xw.Result, "#1");
157 [ExpectedException (typeof (XamlObjectWriterException))]
158 public void GetObjectAfterStartObject ()
160 var xw = new XamlObjectWriter (sctx, null);
161 xw.WriteStartObject (xt3);
162 xw.WriteGetObject ();
166 //[ExpectedException (typeof (XamlObjectWriterException))]
167 public void WriteStartObjectAfterTopLevel ()
169 var xw = new XamlObjectWriter (sctx, null);
170 xw.WriteStartObject (xt3);
171 xw.WriteEndObject ();
172 // writing another root is <del>not</del> allowed.
173 xw.WriteStartObject (xt3);
177 [ExpectedException (typeof (XamlObjectWriterException))]
178 public void WriteEndObjectExcess ()
180 var xw = new XamlObjectWriter (sctx, null);
181 xw.WriteStartObject (xt3);
182 xw.WriteEndObject ();
183 xw.WriteEndObject ();
187 [ExpectedException (typeof (XamlObjectWriterException))]
188 public void StartObjectWriteEndMember ()
190 var xw = new XamlObjectWriter (sctx, null);
191 xw.WriteStartObject (xt3);
192 xw.WriteEndMember ();
196 public void WriteObjectAndMember ()
198 var xw = new XamlObjectWriter (sctx, null);
199 xw.WriteStartObject (xt3);
200 xw.WriteStartMember (xm2);
201 xw.WriteValue ("foo");
202 xw.WriteEndMember ();
207 public void StartMemberWriteEndMember ()
209 var xw = new XamlObjectWriter (sctx, null);
210 xw.WriteStartObject (xt3);
211 xw.WriteStartMember (xm3);
212 xw.WriteEndMember (); // unlike XamlXmlWriter, it is not treated as an error...
217 [ExpectedException (typeof (XamlObjectWriterException))]
218 public void StartMemberWriteStartMember ()
220 var xw = new XamlObjectWriter (sctx, null);
221 xw.WriteStartObject (xt3);
222 xw.WriteStartMember (xm3);
223 xw.WriteStartMember (xm3);
227 public void WriteObjectInsideMember ()
229 var xw = new XamlObjectWriter (sctx, null);
230 xw.WriteStartObject (xt3);
231 xw.WriteStartMember (xm3);
232 xw.WriteStartObject (xt3);
233 xw.WriteEndObject ();
234 xw.WriteEndMember ();
239 [ExpectedException (typeof (XamlDuplicateMemberException))]
240 public void ValueAfterObject ()
242 var xw = new XamlObjectWriter (sctx, null);
243 xw.WriteStartObject (xt3);
244 xw.WriteStartMember (xm3);
245 xw.WriteStartObject (xt3);
246 xw.WriteEndObject ();
247 // passes here, but ...
248 xw.WriteValue ("foo");
249 // rejected here, unlike XamlXmlWriter.
251 // Basically, assume that no content could be written
252 // for an object member within XamlObjectWriter.
253 xw.WriteEndMember ();
257 public void ValueAfterObject2 ()
259 var xw = new XamlObjectWriter (sctx, null);
260 xw.WriteStartObject (xt3);
261 xw.WriteStartMember (xm3);
262 xw.WriteStartObject (xt3);
263 xw.WriteEndObject ();
264 // passes here, but should be rejected later.
265 xw.WriteValue ("foo");
269 [ExpectedException (typeof (XamlDuplicateMemberException))]
270 public void DuplicateAssignment ()
272 var xw = new XamlObjectWriter (sctx, null);
273 xw.WriteStartObject (xt3);
274 xw.WriteStartMember (xm3);
275 xw.WriteStartObject (xt3);
276 xw.WriteEndObject ();
277 xw.WriteValue ("foo"); // causes duplicate assignment.
278 xw.WriteEndMember ();
282 [ExpectedException (typeof (XamlDuplicateMemberException))]
283 public void DuplicateAssignment2 ()
285 var xw = new XamlObjectWriter (sctx, null);
286 xw.WriteStartObject (xt3);
287 xw.WriteStartMember (xm3);
288 xw.WriteStartObject (xt3);
289 xw.WriteEndObject ();
290 xw.WriteEndMember ();
291 xw.WriteStartMember (xm3);
295 //[ExpectedException (typeof (ArgumentException))] // oh? XamlXmlWriter raises this.
296 public void WriteValueTypeMismatch ()
298 var xw = new XamlObjectWriter (sctx, null);
299 xw.WriteStartObject (xt);
300 xw.WriteStartMember (XamlLanguage.Initialization);
301 xw.WriteValue (new TestClass1 ());
302 xw.WriteEndMember ();
304 Assert.IsNotNull (xw.Result, "#1");
305 Assert.AreEqual (typeof (TestClass1), xw.Result.GetType (), "#2");
309 [ExpectedException (typeof (XamlObjectWriterException))] // it fails to convert type and set property value.
310 public void WriteValueTypeMismatch2 ()
312 var xw = new XamlObjectWriter (sctx, null);
313 xw.WriteStartObject (xt3);
314 xw.WriteStartMember (xm3);
315 xw.WriteValue ("foo");
316 xw.WriteEndMember ();
320 public void WriteValueTypeOK ()
322 var xw = new XamlObjectWriter (sctx, null);
323 xw.WriteStartObject (xt);
324 xw.WriteStartMember (XamlLanguage.Initialization);
325 xw.WriteValue ("foo");
326 xw.WriteEndMember ();
328 Assert.AreEqual ("foo", xw.Result, "#1");
332 public void WriteValueList ()
334 var xw = new XamlObjectWriter (sctx, null);
335 xw.WriteStartObject (new XamlType (typeof (List<string>), sctx));
336 xw.WriteStartMember (XamlLanguage.Items);
337 xw.WriteValue ("foo");
338 xw.WriteValue ("bar");
339 xw.WriteEndMember ();
341 var l = xw.Result as List<string>;
342 Assert.IsNotNull (l, "#1");
343 Assert.AreEqual ("foo", l [0], "#2");
344 Assert.AreEqual ("bar", l [1], "#3");
348 [ExpectedException (typeof (XamlObjectWriterException))]
349 public void CloseWithoutEndMember ()
351 var xw = new XamlObjectWriter (sctx, null);
352 xw.WriteStartObject (xt);
353 xw.WriteStartMember (XamlLanguage.Initialization);
354 xw.WriteValue ("foo");
359 [ExpectedException (typeof (XamlObjectWriterException))]
360 public void WriteValueAfterValue ()
362 var xw = new XamlObjectWriter (sctx, null);
363 xw.WriteStartObject (xt);
364 xw.WriteValue ("foo");
365 xw.WriteValue ("bar");
369 [ExpectedException (typeof (XamlObjectWriterException))]
370 public void WriteValueAfterNullValue ()
372 var xw = new XamlObjectWriter (sctx, null);
373 xw.WriteStartObject (xt);
374 xw.WriteValue (null);
375 xw.WriteValue ("bar");
378 [ExpectedException (typeof (XamlObjectWriterException))]
379 public void StartMemberWriteEndObject ()
381 var xw = new XamlObjectWriter (sctx, null);
382 xw.WriteStartObject (xt3);
383 xw.WriteStartMember (xm3);
384 xw.WriteEndObject ();
388 public void WriteNamespace ()
390 var xw = new XamlObjectWriter (sctx, null);
391 xw.WriteNamespace (new NamespaceDeclaration (XamlLanguage.Xaml2006Namespace, "x"));
392 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
393 xw.WriteStartObject (xt3);
394 xw.WriteEndObject ();
397 Assert.IsTrue (ret is TestClass1, "#1");
401 [ExpectedException (typeof (XamlObjectWriterException))]
402 public void StartObjectStartObject ()
404 var xw = new XamlObjectWriter (sctx, null);
405 xw.WriteStartObject (xt3);
406 xw.WriteStartObject (xt3);
410 [ExpectedException (typeof (XamlObjectWriterException))]
411 public void StartObjectValue ()
413 var xw = new XamlObjectWriter (sctx, null);
414 xw.WriteStartObject (xt3);
415 xw.WriteValue ("foo");
419 [ExpectedException (typeof (XamlDuplicateMemberException))] // duplicate member assignment
420 public void ObjectContainsObjectAndObject ()
422 var xw = new XamlObjectWriter (sctx, null);
423 xw.WriteStartObject (xt3);
424 xw.WriteStartMember (xm3);
425 xw.WriteStartObject (xt3);
426 xw.WriteEndObject ();
427 xw.WriteStartObject (xt3);
428 xw.WriteEndObject (); // the exception happens *here*
429 // FIXME: so, WriteEndMember() should not be required, but we fail here. Practically this difference should not matter.
430 xw.WriteEndMember (); // of xm3
434 public void ObjectContainsObjectAndValue ()
436 var xw = new XamlObjectWriter (sctx, null);
437 xw.WriteStartObject (xt3);
438 xw.WriteStartMember (xm3);
439 xw.WriteStartObject (xt3);
440 xw.WriteEndObject ();
441 xw.WriteValue ("foo"); // but this is allowed ...
445 [ExpectedException (typeof (XamlDuplicateMemberException))] // duplicate member assignment
446 public void ObjectContainsObjectAndValue2 ()
448 var xw = new XamlObjectWriter (sctx, null);
449 xw.WriteStartObject (xt3);
450 xw.WriteStartMember (xm3);
451 xw.WriteStartObject (xt3);
452 xw.WriteEndObject ();
453 xw.WriteValue ("foo");
454 xw.WriteEndMember (); // ... until here.
458 [ExpectedException (typeof (XamlObjectWriterException))] // unlike XamlXmlWriter (IOE)
459 public void EndObjectAfterNamespace ()
461 var xw = new XamlObjectWriter (sctx, null);
462 xw.WriteStartObject (xt3);
463 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
464 xw.WriteEndObject ();
468 [ExpectedException (typeof (XamlObjectWriterException))] // ... unlike XamlXmlWriter (throws IOE)
469 public void WriteValueAfterNamespace ()
471 var xw = new XamlObjectWriter (sctx, null);
472 xw.WriteStartObject (xt);
473 xw.WriteStartMember (XamlLanguage.Initialization);
474 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
475 xw.WriteValue ("foo");
479 [ExpectedException (typeof (XamlObjectWriterException))] // ... unlike XamlXmlWriter (allowed)
480 public void ValueThenStartObject ()
482 var xw = new XamlObjectWriter (sctx, null);
483 xw.WriteStartObject (xt3);
484 xw.WriteStartMember (xm2);
485 xw.WriteValue ("foo");
486 xw.WriteStartObject (xt3);
491 [ExpectedException (typeof (XamlObjectWriterException))] // ... unlike XamlXmlWriter (allowed, as it allows StartObject after Value)
492 public void ValueThenNamespace ()
494 var xw = new XamlObjectWriter (sctx, null);
495 xw.WriteStartObject (xt3);
496 xw.WriteStartMember (xm2);
497 xw.WriteValue ("foo");
498 xw.WriteNamespace (new NamespaceDeclaration ("y", "urn:foo")); // this does not raise an error (since it might start another object)
502 [ExpectedException (typeof (XamlObjectWriterException))] // strange, this does *not* result in IOE...
503 public void ValueThenNamespaceThenEndMember ()
505 var xw = new XamlObjectWriter (sctx, null);
506 xw.WriteStartObject (xt3);
507 xw.WriteStartMember (xm2);
508 xw.WriteValue ("foo");
509 xw.WriteNamespace (new NamespaceDeclaration ("y", "urn:foo"));
510 xw.WriteEndMember ();
514 [ExpectedException (typeof (XamlObjectWriterException))] // This is also very different, requires exactly opposite namespace output manner to XamlXmlWriter (namespace first, object follows).
515 [Category ("NotWorking")]
516 public void StartMemberAfterNamespace ()
518 var xw = new XamlObjectWriter (sctx, null);
519 xw.WriteStartObject (xt3);
520 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
524 [Category ("NotWorking")]
525 public void StartMemberBeforeNamespace ()
527 var xw = new XamlObjectWriter (sctx, null);
528 xw.WriteStartObject (xt3);
529 xw.WriteStartMember (xm2); // note that it should be done *after* WriteNamespace in XamlXmlWriter. SO inconsistent.
530 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
531 xw.WriteEndMember ();
536 [ExpectedException (typeof (XamlObjectWriterException))]
537 public void StartMemberBeforeNamespace2 ()
539 var xw = new XamlObjectWriter (sctx, null);
540 xw.WriteStartObject (xt3);
541 xw.WriteStartMember (xm2);
542 xw.WriteNamespace (new NamespaceDeclaration ("urn:foo", "y"));
543 // and here, NamespaceDeclaration is written as if it
544 // were another value object( unlike XamlXmlWriter)
545 // and rejects further value.
546 xw.WriteValue ("foo");
550 [ExpectedException (typeof (XamlObjectWriterException))]
551 public void EndMemberThenStartObject ()
553 var xw = new XamlObjectWriter (sctx, null);
554 xw.WriteStartObject (xt3);
555 xw.WriteStartMember (xm2);
556 xw.WriteValue ("foo");
557 xw.WriteEndMember ();
558 xw.WriteStartObject (xt3);
561 // The semantics on WriteGetObject() is VERY different from XamlXmlWriter.
564 [ExpectedException (typeof (XamlObjectWriterException))]
565 public void GetObjectOnNullValue ()
567 var xw = new XamlObjectWriter (sctx, null);
568 xw.WriteStartObject (xt3);
569 xw.WriteStartMember (xm2);
570 xw.WriteGetObject ();
574 [ExpectedException (typeof (XamlObjectWriterException))]
575 public void GetObjectOnNullValue2 ()
577 var xw = new XamlObjectWriter (sctx, null);
578 xw.WriteStartObject (xt4);
579 xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Baz"), sctx)); // unlike Bar, Baz is not initialized.
580 xw.WriteGetObject (); // fails, because it is null.
584 [Category ("NotWorking")]
585 public void GetObjectOnIntValue ()
587 var xw = new XamlObjectWriter (sctx, null);
588 xw.WriteStartObject (xt3);
589 xw.WriteStartMember (xt3.GetMember ("TestProp4")); // int
590 xw.WriteGetObject (); // passes!!! WTF
591 xw.WriteEndObject ();
595 // String is not treated as a collection on XamlXmlWriter, while this XamlObjectReader does.
596 [Category ("NotWorking")]
597 public void GetObjectOnNonNullString ()
599 var xw = new XamlObjectWriter (sctx, null);
600 xw.WriteStartObject (xt3);
601 xw.WriteStartMember (xt3.GetMember ("TestProp3"));
602 xw.WriteGetObject ();
606 [Category ("NotWorking")]
607 public void GetObjectOnCollection ()
609 var xw = new XamlObjectWriter (sctx, null);
610 xw.WriteStartObject (xt4);
611 xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
612 xw.WriteGetObject ();
614 // FIXME: enable it once we got generic type output fixed.
615 //Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1");
619 [ExpectedException (typeof (XamlObjectWriterException))]
620 public void ValueAfterGetObject ()
622 var xw = new XamlObjectWriter (sctx, null);
623 xw.WriteStartObject (xt4);
624 xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
625 xw.WriteGetObject ();
626 xw.WriteValue ("foo");
630 [ExpectedException (typeof (XamlObjectWriterException))]
631 public void StartObjectAfterGetObject ()
633 var xw = new XamlObjectWriter (sctx, null);
634 xw.WriteStartObject (xt4);
635 xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
636 xw.WriteGetObject ();
637 xw.WriteStartObject (xt);
641 [ExpectedException (typeof (XamlObjectWriterException))]
642 public void EndMemberAfterGetObject ()
644 var xw = new XamlObjectWriter (sctx, null);
645 xw.WriteStartObject (xt4);
646 xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
647 xw.WriteGetObject ();
648 xw.WriteEndMember (); // ...!?
652 [Category ("NotWorking")]
653 public void StartMemberAfterGetObject ()
655 var xw = new XamlObjectWriter (sctx, null);
656 xw.WriteStartObject (xt4);
657 var xmm = xt4.GetMember ("Bar");
658 xw.WriteStartMember (xmm); // <List.Bar>
659 xw.WriteGetObject (); // shifts current member to List<T>.
660 xw.WriteStartMember (xmm.Type.GetMember ("Capacity"));
662 xw.WriteEndMember ();
664 xw.WriteEndObject (); // got object
665 xw.WriteEndMember (); // Bar
666 xw.WriteEndObject (); // started object
672 public void EndObjectAfterGetObject ()
674 var xw = new XamlObjectWriter (sctx, null);
675 xw.WriteStartObject (xt4);
676 xw.WriteStartMember (new XamlMember (typeof (Foo).GetProperty ("Bar"), sctx));
677 xw.WriteGetObject ();
678 xw.WriteEndObject ();