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