a69c1045b76d41422c6d01e68d3ea06347ea102a
[mono.git] / mcs / class / System.XML / Test / System.Xml.Serialization / ComplexDataStructure.cs
1 //
2 // ComplexDataStructure.cs
3 //
4 // Author:
5 //      Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // (C) 2004 Novell, Inc.
8 //
9 //
10 using System;
11 using System.IO;
12 using System.Xml;
13 using System.Xml.Schema;
14 using System.Xml.Serialization;
15 using System.Collections;
16 using System.ComponentModel; 
17 using NUnit.Framework;
18
19 namespace MonoTests.System.XmlSerialization
20 {
21         [TestFixture]
22         public class ComplexDataStructure
23         {
24                 [Test]
25                 [NUnit.Framework.Category("NotDotNet")] // FDBK50639 
26 #if TARGET_JVM
27                 [Ignore ("JVM returns fields in different order")]
28 #endif
29                 public void WriteLiteral ()
30                 {
31                         Test data = BuildTestObject ();
32
33                         XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
34                         XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
35                         StringWriter sw = new StringWriter();
36                         ss.Serialize (sw,data,nams);
37                         string serialized = sw.ToString ();
38                         serialized = XmlSerializerTests.Infoset (serialized);
39
40                         StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
41                         string expected = sr.ReadToEnd ();
42                         sr.Close ();
43                         
44                         expected = XmlSerializerTests.Infoset (expected);
45                         Assert.AreEqual (expected, serialized);
46                 }
47                 
48                 [Test]
49                 [NUnit.Framework.Category ("NotDotNet")] // MS.NET results in compilation error (probably it generates bogus source.)
50                 public void ReadLiteral ()
51                 {
52                         XmlSerializer ss = new XmlSerializer (GetLiteralTypeMapping ());
53                         XmlSerializerNamespaces nams = new XmlSerializerNamespaces ();
54                         
55                         StreamReader sr = new StreamReader ("Test/XmlFiles/literal-data.xml");
56                         Test data = (Test) ss.Deserialize (sr);
57                         sr.Close ();
58                         
59                         CheckObjectContent (BuildTestObject(), data);
60                 }
61                 
62                 XmlTypeMapping GetLiteralTypeMapping ()
63                 {
64                         XmlRootAttribute root = new XmlRootAttribute("rootroot");
65                         Type[] types = new Type[] {typeof(UknTestPart), typeof(AnotherTestPart), typeof(DblStringContainer) };
66                         XmlReflectionImporter ri = new XmlReflectionImporter ();
67                         foreach (Type t in types) ri.IncludeType (t);
68                         return ri.ImportTypeMapping (typeof(Test), root);
69                 }
70
71                 XmlTypeMapping GetEncodedTypeMapping ()
72                 {
73                         SoapReflectionImporter sri = new SoapReflectionImporter ();
74                         sri.IncludeType (typeof(UknTestPart));
75                         sri.IncludeType (typeof(AnotherTestPart));
76                         sri.IncludeType (typeof(DblStringContainer));
77                         return sri.ImportTypeMapping (typeof(Test));
78                 }
79                 
80                 Test BuildTestObject ()
81                 {
82                         XmlDocument doc = new XmlDocument();
83
84                         Test t = new UknTestPart();
85                         t.a = 1;
86                         t.b = "hola";
87                         t.bbis = t.b;
88                         t.c = 44;
89                         t.parts = new TestPart[3];
90                         t.parts[0] = new TestPart();
91                         t.parts[0].name = "un";
92                         t.parts[0].bval = true;
93                         t.parts[1] = new TestPart();
94                         t.parts[1].name = "dos";
95                         t.parts[1].bval = false;
96                         t.parts[2] = t.parts[0];
97                         t.part = t.parts[1];
98                         t.strings = new string[] { "un", "dos", null, "tres" };
99                         t.ushorts = new ushort[] { 1,2,3 };
100                         t.ta = new TB();
101                         t.ta.extraTextNodes = new XmlNode[] { doc.CreateTextNode ("AA"), doc.CreateTextNode ("BB") };
102
103                         t.tam2 = new TA[][][]
104                                         {
105                                                 new TA[][] { new TA[] {new TA(), new TA()}, new TA[] {new TA(), new TA()}},
106                                                 new TA[][] { new TA[] {new TB(), new TA()}, new TA[] {new TB(), new TA()}},
107                                                 new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}} 
108                                         };
109
110                         t.tam3 = t.tam2;
111                         t.flatParts = t.parts;
112
113                         t.flatParts2 = new TA[] {new TA(), new TB(), null, new TB()};
114
115                         t.anot = new AnotherTestPart ();
116                         ((AnotherTestPart)t.anot).lo = 1234567890;
117
118                         t.ob = t.parts[1];
119                         t.ob2 = t.parts[1];
120
121                         XmlElement e1 = doc.CreateElement ("explicitElement");
122                         XmlElement e2 = doc.CreateElement ("subElement");
123                         e2.SetAttribute ("unAtrib","val");
124                         doc.AppendChild (e1);
125                         e1.AppendChild (e2);
126
127                         t.oneElem = e1;
128                         t.oneElem2 = e1;
129                         t.someElems = new XmlNode[3];
130                         t.someElems[0] = e1;
131                         t.someElems[1] = null;
132                         t.someElems[2] = e2;
133
134                         t.extraElems = new XmlElement[1];
135                         t.extraElems[0] = doc.CreateElement ("extra1");
136                         t.extraElems[0].SetAttribute ("val","1");
137
138                         t.extraElems23 = new XmlElement[2];
139                         t.extraElems23[0] = doc.CreateElement ("extra2");
140                         t.extraElems23[0].SetAttribute ("val","2");
141                         t.extraElems23[1] = doc.CreateElement ("extra3");
142                         t.extraElems23[1].SetAttribute ("val","3");
143
144                         t.extraElemsRest = doc.CreateElement ("extra4");
145                         t.extraElemsRest.SetAttribute ("val","4");
146
147                         t.uktester = new UnknownAttributeTester();
148                         t.uktester.aa = "hihi";
149
150                         t.uktester.extraAtts = new XmlAttribute[3];
151                         t.uktester.extraAtts[0] = doc.CreateAttribute ("extraAtt1");
152                         t.uktester.extraAtts[0].Value = "val1";
153                         t.uktester.extraAtts[1] = doc.CreateAttribute ("extraAtt2");
154                         t.uktester.extraAtts[1].Value = "val2";
155                         t.uktester.extraAtts[2] = doc.CreateAttribute ("extraAtt3");
156                         t.uktester.extraAtts[2].Value = "val3";
157
158                         t.ob3 = 12345;
159                         t.ob4 = (float)54321.12;
160
161                         t.op1 = option.AA;
162                         t.opArray = new option[] { option.CC, option.BB, option.AA };
163                         t.ukOpt = option.DD;
164                         t.opAtt = option.BB;
165
166                         t.byteArray = new byte[] { 11,33,55,222 };
167                         t.byteByteArray = new byte[][] { t.byteArray, t.byteArray };
168
169                         t.ttList = new ArrayList();
170                         t.ttList.Add ("two");
171                         t.ttList.Add ("strings");
172                         //                      t.extraText = "Additional text";
173
174                         t.RoList = new ArrayList ();
175                         t.RoList.Add (t.parts[0]);
176                         t.RoList.Add (t.parts[1]);
177
178 /*                      t.struc = new OneStruct();
179                         t.struc.aa = 776655;
180                         t.struc.cc = "this is a struct";
181 */
182                         t.multiList = new ArrayList[2];
183                         t.multiList[0] = new ArrayList ();
184                         t.multiList[0].Add (22);
185                         t.multiList[0].Add (33);
186                         t.multiList[1] = new ArrayList ();
187                         t.multiList[1].Add (888);
188                         t.multiList[1].Add (999);
189
190                         // XmlSerializer does not deserialize default values explicitly.
191                         //t.defElem = "theDefValue";
192                         //t.defAttr = "theDefValue";
193
194                         t.special = new CustomHashtable ();
195                         t.special.Add ("one","1");
196                         t.special.Add ("two","2");
197                         t.special.Add ("three","3");
198
199                         t.attqname = new XmlQualifiedName ("thename","thenamespace");
200
201                         DblStringContainer dbc = new DblStringContainer ();
202                         dbc.doublestring = new string [][] { null, new string[] {"hello"} };
203                         AnotherTestPart at = new AnotherTestPart ();
204                         at.lo = 567;
205                         dbc.at = at;
206
207                         DblStringContainerAnm dbca = new DblStringContainerAnm ();
208                         dbca.at = dbc;
209                         t.dbscontainer = dbca;
210                         
211                         return t;
212                 }
213                 
214                 void CheckObjectContent (Test exp, Test t)
215                 {
216                         Assert.AreEqual (exp.a, t.a, "t.a");
217                         Assert.AreEqual (exp.b, t.b, "t.b");
218                         Assert.AreEqual (exp.bbis, t.bbis, "t.bbis");
219                         Assert.AreEqual (exp.c, t.c, "t.c");
220                         
221                         Assert.IsNotNull (t.parts, "t.parts");
222                         CheckParts ("t.parts", exp.parts, t.parts);
223                         
224                         TestPart.AssertEquals ("t.part", exp.part, t.part);
225                         
226                         AssertionHelper.AssertEqualsArray ("t.strings", exp.strings, t.strings);
227                         AssertionHelper.AssertEqualsArray ("t.ushorts", exp.ushorts, t.ushorts);
228                         
229                         TA.AssertEquals ("t.ta", exp.ta, t.ta);
230
231                         Assert.IsNotNull (t.tam2, "t.tam2");
232                         CheckTaArray ("t.tam2", exp.tam2, t.tam2);
233                         
234                         Assert.IsNotNull (t.tam3, "t.tam3");
235                         CheckTaArray ("t.tam3", exp.tam3, t.tam3);
236                         
237                         Assert.IsNotNull (t.flatParts, "t.flatParts");
238                         CheckParts ("t.flatParts", exp.flatParts, t.flatParts);
239
240                         // Null element is ignored
241                         Assert.IsNotNull (t.flatParts2, "t.flatParts2");
242                         Assert.AreEqual (3, t.flatParts2.Length, "t.flatParts2.Length");
243                         TA.AssertEquals ("t.flatParts2 0", exp.flatParts2[0], t.flatParts2[0]);
244                         TA.AssertEquals ("t.flatParts2 1", exp.flatParts2[1], t.flatParts2[1]);
245                         TA.AssertEquals ("t.flatParts2 2", exp.flatParts2[3], t.flatParts2[2]);
246                         
247                         Assert.IsNotNull (t.anot, "t.anot");
248                         Assert.AreEqual (((AnotherTestPart)exp.anot).lo, ((AnotherTestPart)t.anot).lo, "t.anot.lo");
249
250                         TestPart.AssertEquals ("t.ob", exp.ob as TestPart, t.ob as TestPart);
251                         TestPart.AssertEquals ("t.ob2", exp.ob2 as TestPart, t.ob2 as TestPart);
252                         
253                         AssertionHelper.AssertEqualsXml ("t.oneElem", exp.oneElem, t.oneElem);
254                         AssertionHelper.AssertEqualsXml ("t.oneElem2", exp.oneElem2, t.oneElem2);
255                         
256                         // One of the elements was null and it is ignored
257                         Assert.IsNotNull (t.someElems, "t.someElems");
258                         Assert.AreEqual (2, t.someElems.Length, "t.someElems.Length");
259                         AssertionHelper.AssertEqualsXml ("t.someElems[0]", exp.someElems[0], t.someElems[0]);
260                         AssertionHelper.AssertEqualsXml ("t.someElems[1]", exp.someElems[2], t.someElems[1]);
261
262                         Assert.IsNotNull (t.extraElems, "t.extraElems");
263                         Assert.AreEqual (exp.extraElems.Length, t.extraElems.Length, "t.extraElems.Length");
264                         for (int n=0; n<exp.extraElems.Length; n++)
265                                 AssertionHelper.AssertEqualsXml ("t.extraElems[" + n + "]", exp.extraElems[n], t.extraElems[n]);
266                         
267                         Assert.IsNotNull (t.extraElems23, "t.extraElems23");
268                         Assert.AreEqual (exp.extraElems23.Length, t.extraElems23.Length, "t.extraElems23.Length");
269                         for (int n=0; n<t.extraElems23.Length; n++)
270                                 AssertionHelper.AssertEqualsXml ("t.extraElems23[" + n + "]", exp.extraElems23[n], t.extraElems23[n]);
271                         
272                         AssertionHelper.AssertEqualsXml ("t.extraElemsRest", exp.extraElemsRest, t.extraElemsRest);
273                         
274                         UnknownAttributeTester.AssertEquals ("t.uktester", exp.uktester, t.uktester);
275
276                         Assert.AreEqual (exp.ob3, t.ob3, "t.ob3");
277                         Assert.AreEqual (exp.ob4, t.ob4, "t.ob4");
278                         Assert.AreEqual (exp.op1, t.op1, "t.op1");
279                         
280                         AssertionHelper.AssertEqualsArray ("t.opArray", exp.opArray, t.opArray);
281
282                         Assert.AreEqual (exp.ukOpt, t.ukOpt, "t.ukOpt");
283                         Assert.AreEqual (exp.opAtt, t.opAtt, "t.opAtt");
284
285                         AssertionHelper.AssertEqualsArray ("t.byteArray", exp.byteArray, t.byteArray);
286                         AssertionHelper.AssertEqualsArray ("t.byteByteArray", exp.byteByteArray, t.byteByteArray);
287                         
288                         Assert.IsNotNull (t.ttList, "t.ttList");
289                         AssertionHelper.AssertEqualsArray ("t.ttList", exp.ttList.ToArray(), t.ttList.ToArray());
290                         
291                         Assert.IsNotNull (t.RoList, "t.RoList");
292                         Assert.AreEqual (exp.RoList.Count, t.RoList.Count, "t.RoList.Count");
293                         for (int n=0; n<exp.RoList.Count; n++)
294                                 TestPart.AssertEquals ("t.RoList " + n, (TestPart)exp.RoList[n], (TestPart)t.RoList[n]);
295                         
296                         Assert.AreEqual (exp.struc.aa, t.struc.aa, "t.struc.aa");
297                         Assert.AreSame (exp.struc.cc, t.struc.cc, "t.struc.cc");
298
299                         Assert.IsNotNull (t.multiList, "t.multiList");
300                         Assert.AreEqual (exp.multiList.Length, t.multiList.Length, "t.multiList.Count");
301                         for (int n=0; n<exp.multiList.Length; n++)
302                                 AssertionHelper.AssertEqualsArray ("t.multiList " + n, exp.multiList[n].ToArray(), t.multiList[n].ToArray());
303                         
304                         Assert.AreEqual (exp.defElem, t.defElem, "t.defElem");
305                         Assert.AreEqual (exp.defAttr, t.defAttr, "t.defAttr");
306
307                         CustomHashtable.AssertEquals ("t.special", exp.special, t.special);
308
309                         Assert.AreEqual (exp.attqname, t.attqname, "t.attqname");
310
311                         Assert.IsNotNull (t.dbscontainer, "t.dbscontainer");
312                         DblStringContainer tdbca = t.dbscontainer.at as DblStringContainer;
313                         DblStringContainer expdbca = exp.dbscontainer.at as DblStringContainer;
314                         Assert.IsNotNull (tdbca, "t.dbscontainer.at");
315                         
316                         Assert.IsNotNull (tdbca, "t.dbscontainer.dbca");
317                         AssertionHelper.AssertEqualsArray ("t.dbscontainer.at.doublestring", expdbca.doublestring, tdbca.doublestring);
318                         
319                         AnotherTestPart tat = tdbca.at as AnotherTestPart;
320                         AnotherTestPart expat = expdbca.at as AnotherTestPart;
321                         Assert.IsNotNull (tat, "t.dbscontainer.dbca.at");
322                         Assert.AreEqual (expat.lo, tat.lo, "t.dbscontainer.dbca.at.lo");
323                 }
324                 
325                 void CheckParts (string id, TestPart[] exp, TestPart[] parts)
326                 {
327                         AssertionHelper.AssertType (id, exp, parts);
328                         Assert.AreEqual (exp.Length, parts.Length, id + " Len");
329                         for (int n=0; n<exp.Length; n++)
330                                 TestPart.AssertEquals (id + "[" + n + "]", exp[n], parts[n]);
331                 }
332                 
333                 void CheckTaArray (string id, TA[][][] exp, TA[][][] arr)
334                 {
335                         AssertionHelper.AssertType (id, exp, arr);
336                         Assert.AreEqual (exp.Length, arr.Length, id + " Len");
337                         for (int n=0; n<exp.Length; n++)
338                         {
339                                 TA[][] tar = arr[n];
340                                 TA[][] expar = exp[n];
341                                 
342                                 AssertionHelper.AssertType (id, expar, tar);
343                                 Assert.AreEqual (expar.Length, tar.Length);
344                                 
345                                 for (int m=0; m<expar.Length; m++)
346                                 {
347                                         TA[] tar2 = tar[m];
348                                         TA[] expar2 = expar[m];
349                                         
350                                         AssertionHelper.AssertType (id, expar2, tar2);
351                                         Assert.AreEqual (expar2.Length, tar2.Length, id);
352                                         
353                                         for (int i=0; i<expar2.Length; i++)
354                                                 TA.AssertEquals (id + "[" + n + "][" + m + "][" + i + "]", expar2[i], tar2[i]);
355                                 }
356                         }
357                 }
358         }
359         
360         public class AssertionHelper
361         {
362                 public static bool AssertType (string id, object exp, object ob)
363                 {
364                         if (exp == null) {
365                                 Assert.IsNull (ob, id);
366                                 return false;
367                         }
368                         else {
369                                 Assert.IsNotNull (ob, id);
370                                 Assert.AreEqual (exp.GetType(), ob.GetType(), id + " type");
371                                 return true;
372                         }
373                 }
374                 
375                 public static void AssertEqualsXml (string id, XmlNode exp, XmlNode ob)
376                 {
377                         if (!AssertType (id, exp, ob)) return;
378                         Assert.AreEqual (XmlSerializerTests.Infoset (exp), XmlSerializerTests.Infoset (ob), id);
379                 }
380                 
381                 public static void AssertEqualsArray (string id, Array exp, Array ob)
382                 {
383                         if (!AssertType (id, exp, ob)) return;
384                         Assert.AreEqual (exp.GetLength(0), ob.GetLength(0), id + " Length");
385                         for (int n=0; n<exp.GetLength(0); n++) {
386                                 object it = exp.GetValue(n);
387                                 if (it is Array) 
388                                         AssertEqualsArray (id + "[" + n + "]", it as Array, ob.GetValue(n) as Array);
389                                 else
390                                         Assert.AreEqual (it, ob.GetValue(n), id + "[" + n + "]");
391                         }
392                 }
393         }
394         
395         [XmlType(TypeName="")]
396         [XmlRoot(ElementName="aaaaaa",Namespace="")]
397         [XmlInclude(typeof(UknTestPart))]
398         [SoapInclude(typeof(UknTestPart))]
399         public class Test
400         {
401                 //              public option op;elem.SchemaTypeName
402                 public object anot;
403
404                 [SoapElement(ElementName="suba")]
405                 [XmlElement(ElementName="suba",Namespace="kk")]
406                 public int a;
407
408                 public string b;
409                 public string bbis;
410
411                 [SoapAttribute]
412                 [XmlAttribute (Namespace="attribns")]
413                 public byte c;
414
415                 [XmlElement(Namespace="oo")]
416                 public TestPart part;
417
418                 public TA ta;
419
420                 public TestPart[] parts;
421
422                 [SoapElement(ElementName="multita")]
423                 [XmlArray(ElementName="multita")]
424                         //              [XmlArrayItem(ElementName="itema",NestingLevel=1)]
425                 [XmlArrayItem(ElementName="itema",Type=typeof(TA),NestingLevel=1)]
426                 [XmlArrayItem(ElementName="itemb",Type=typeof(TB),NestingLevel=1)]
427                 public TA[][] tam = new TA[][] { new TA[] {new TA(), new TB()}, new TA[] {new TA(), new TA()}};
428
429 //              [SoapElement(ElementName="multita2")]
430                 [SoapIgnore]
431                 [XmlArray(ElementName="multita2")]
432                 [XmlArrayItem(ElementName="data1",NestingLevel=0)]
433
434                 [XmlArrayItem(ElementName="data2",NestingLevel=1,Namespace="da2")]
435                 [XmlArrayItem(ElementName="data3a",Type=typeof(TA),NestingLevel=2,Namespace="da3")]
436                 [XmlArrayItem(ElementName="data3b",Type=typeof(TB),NestingLevel=2,Namespace="da3")]
437                 public TA[][][] tam2;
438
439                 [SoapIgnore]
440                 public TA[][][] tam3;
441
442                 [SoapElement(IsNullable=true)]
443                 [XmlElement(IsNullable=true)]
444                 public string mayBeNull;
445
446                 public string[] strings;
447
448                 [XmlArray(Namespace="arrayNamespace")]
449                 public ushort[] ushorts;
450
451                 [XmlElement]
452                 public TestPart[] flatParts;
453
454                 [SoapElement (ElementName="flatTAs")]
455                 [XmlElement (ElementName="flatTAs")]
456                 public TA[] flatParts2;
457
458                 public object ob;
459
460                 [XmlElement (Namespace="uimp")]
461                 public object ob2;
462
463                 public object ob3;
464                 public object ob4;
465
466                 [SoapIgnore]
467                 public XmlElement oneElem;
468
469                 [SoapIgnore]
470                 [XmlElement (ElementName="unElement", Namespace="elemns")]
471                 public XmlElement oneElem2;
472
473                 [SoapIgnore]
474                 [XmlElement (ElementName="unsElements", Namespace="elemns")]
475                 public XmlNode[] someElems;
476
477                 [SoapIgnore]
478                 [XmlAnyElement ("extra1")]
479                 public XmlElement[] extraElems;
480
481                 [SoapIgnore]
482                 [XmlAnyElement ("extra2")]
483                 [XmlAnyElement ("extra3")]
484                 [XmlAnyElement ("extra3","nnn")]
485                 public XmlElement[] extraElems23;
486
487                 [SoapIgnore]
488                 [XmlAnyElement]
489                 public XmlElement extraElemsRest;
490
491                 public UnknownAttributeTester uktester;
492
493                 public option op1;
494                 public option[] opArray;
495                 public object ukOpt;
496
497                 [XmlAttribute]
498                 [SoapIgnore]
499                 public option opAtt;
500
501
502                 public byte[] byteArray;
503                 [SoapIgnore]
504                 public byte[][] byteByteArray;
505
506                 [XmlElement(Type=typeof(string))]
507                 [XmlElement(ElementName="kk",Type=typeof(int))]
508                 public object[] tt = new object[] { "aa",22 };
509
510                 public ArrayList ttList;
511
512                 ArrayList roList;
513                 public ArrayList RoList
514                 {
515                         get { return roList; }
516                         set { roList = value; }
517                 }
518
519                 [SoapIgnore]
520 //              [XmlIgnore]
521                 public ArrayList[] multiList;
522
523                 [SoapIgnore]
524                 [XmlIgnore]
525                 public OneStruct struc;
526
527                 [DefaultValue("theDefValue")]
528                 public string defElem;
529
530                 [XmlAttribute]
531                 [DefaultValue("theDefValue")]
532                 public string defAttr;
533
534                 [XmlText (Type=typeof(string))]
535                 [XmlElement (Type=typeof(int))]
536                 public object[] xmltext = new object[] {"aa",33,"bb",776};
537
538                 [SoapIgnore]
539                 public CustomHashtable special;
540
541                 [XmlAttribute]
542                 public XmlQualifiedName attqname;
543
544                 [XmlAttribute]
545                 public DateTime[] arrayAttribute;
546
547                 [XmlArray (Namespace="mm")]
548                 public string[][] dummyStringArray = new string[][] {null,null};
549                 
550                 [XmlElement (Namespace="mm")]
551                 public DblStringContainerAnm dbscontainer;
552         }
553
554         public class DblStringContainerAnm
555         {
556                 public object at;
557         }
558
559         [XmlType(Namespace="mm")]
560         public class DblStringContainer
561         {
562                 [XmlArrayItem (NestingLevel=1, IsNullable=true)]
563                 public string [][] doublestring;
564                 public object at;
565         }
566
567         [SoapType(TypeName="TC")]
568         [XmlType(TypeName="TC")]
569         [XmlInclude(typeof(TB))]
570         [SoapInclude(typeof(TB))]
571         public class TA
572         {
573                 public int xx = 1;
574
575                 [XmlText]
576                 [SoapIgnore]
577                 public XmlNode[] extraTextNodes;
578                 
579                 public static void AssertEquals (string id, TA expected, TA ob)
580                 {
581                         if (!AssertionHelper.AssertType (id, expected, ob)) return;
582                         Assert.AreEqual (expected.xx, ob.xx, id + " xx");
583                         // TODO: extraTextNodes
584                 }
585         }
586
587         public class TB: TA
588         {
589                 public int yy = 2;
590                 
591                 public static void AssertEquals (string id, TB expected, TB ob)
592                 {
593                         if (!AssertionHelper.AssertType (id, expected, ob)) return;
594                         Assert.AreEqual (expected.yy, ob.yy, id + " yy");
595                         TA.AssertEquals (id + " base", expected, ob);
596                 }
597         }
598
599         public class UnknownAttributeTester
600
601         {
602                 [SoapAttribute]
603                 [XmlAttribute]
604                 public string aa;
605         
606                 [SoapIgnore]
607                 [XmlAnyAttribute]
608                 public XmlAttribute[] extraAtts;
609
610                 //              [XmlText(Type=typeof(XmlNode))]
611                 //              public XmlNode extraText;
612                 
613                 public static void AssertEquals (string id, UnknownAttributeTester exp, UnknownAttributeTester ob)
614                 {
615                         if (!AssertionHelper.AssertType (id, exp, ob)) return;
616                         Assert.AreEqual (exp.aa, ob.aa, id + " aa");
617                         
618                         if (!AssertionHelper.AssertType (id + " extraAtts", exp.extraAtts, ob.extraAtts)) return;
619                         
620                         int p = 0;
621                         for (int n=0; n<ob.extraAtts.Length; n++)
622                         {
623                                 XmlAttribute at = ob.extraAtts [n];
624                                 if (at.NamespaceURI == "http://www.w3.org/2000/xmlns/") continue;
625                                 Assert.IsTrue (p < exp.extraAtts.Length, id + " extraAtts length");
626                                 AssertionHelper.AssertEqualsXml (id + ".extraAtts " + n, exp.extraAtts [p], ob.extraAtts[n]);
627                                 p++;
628                         }
629                 }
630         }
631
632         [SoapType(TypeName="UnTestPart", Namespace="mm")]
633         [XmlType(TypeName="UnTestPart", Namespace="mm")]
634         public class TestPart
635         {
636                 public string name;
637                 public bool bval;
638                 
639                 public static void AssertEquals (string id, TestPart expected, TestPart ob)
640                 {
641                         if (!AssertionHelper.AssertType (id, expected, ob)) return;
642                         Assert.AreEqual (expected.name, ob.name, id + " name");
643                         Assert.AreEqual (expected.bval, ob.bval, id + " bval");
644                 }
645         }
646
647         [SoapType(Namespace="mm")]
648         [XmlType(Namespace="mm")]
649         public class AnotherTestPart
650         {
651                 [XmlText]
652                 public long lo;
653         }
654
655         public class UknTestPart : Test
656         {
657                 [XmlElement(IsNullable=true)]
658                 public string uname;
659                 public bool uval;
660         }
661
662         public struct OneStruct
663         {
664                 public int aa;
665                 public string cc;
666         }
667
668 //      [XmlType(Namespace="enum_namespace")]
669         public enum option 
670         { 
671                 AA, 
672                 [SoapEnum(Name="xmlBB")]
673                 [XmlEnum(Name="xmlBB")]
674                 BB, 
675                 CC, 
676                 DD 
677         }
678
679         public class CustomHashtable : IXmlSerializable
680         {
681                 Hashtable data = new Hashtable ();
682
683                 public void Add (string key, string value)
684                 {
685                         data.Add (key, value);
686                 }
687                 
688                 public static void AssertEquals (string id, CustomHashtable exp, CustomHashtable ob)
689                 {
690                         if (!AssertionHelper.AssertType (id, exp, ob)) return;
691                         if (!AssertionHelper.AssertType (id, exp.data, ob.data)) return;
692                         
693                         Assert.AreEqual (exp.data.Count, ob.data.Count, id + " data Count");
694                         
695                         foreach (DictionaryEntry entry in exp.data)
696                                 Assert.AreEqual (entry.Value, ob.data[entry.Key]);
697                 }
698                 
699                 public void ReadXml (XmlReader reader)
700                 {
701                         // Read the element enclosing the object
702                         reader.ReadStartElement();
703                         reader.MoveToContent ();
704
705                         // Reads the "data" element
706                         reader.ReadStartElement();
707                         reader.MoveToContent ();
708                         while (reader.NodeType != XmlNodeType.EndElement)
709                         {
710                                 if (reader.NodeType == XmlNodeType.Element)
711                                 {
712                                         string key = reader.LocalName;
713                                         data [key] = reader.ReadElementString ();
714                                 }
715                                 else
716                                         reader.Skip ();
717                                 reader.MoveToContent ();
718                         }
719
720                         reader.ReadEndElement ();
721                 }
722
723                 public void WriteXml (XmlWriter writer)
724                 {
725                         writer.WriteStartElement ("data");
726                         foreach (DictionaryEntry entry in data) 
727                         {
728                                 writer.WriteElementString ((string)entry.Key, (string)entry.Value);
729                         }
730                         writer.WriteEndElement ();
731                 }
732
733                 public XmlSchema GetSchema ()
734                 {
735                         XmlSchema s = new XmlSchema ();
736                         s.TargetNamespace = "http://www.go-mono.org/schemas";
737                         s.Id = "monoschema";
738                         XmlSchemaElement e = new XmlSchemaElement ();
739                         e.Name = "data";
740                         s.Items.Add (e);
741                         XmlSchemaComplexType cs = new XmlSchemaComplexType ();
742                         XmlSchemaSequence seq = new XmlSchemaSequence ();
743                         XmlSchemaAny any = new XmlSchemaAny ();
744                         any.MinOccurs = 0;
745                         any.MaxOccurs = decimal.MaxValue;
746                         seq.Items.Add (any);
747                         cs.Particle = seq;
748                         e.SchemaType = cs;
749                         return s;
750                 }
751         }
752 }