Merge pull request #1410 from alesliehughes/master
[mono.git] / mcs / class / System.Runtime.Serialization / Test / System.Runtime.Serialization / XsdDataContractExporterTest.cs
1 //
2 // XsdDataContractExporterTest.cs
3 //
4 // Author:
5 //      Ankit Jain  <JAnkit@novell.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if !MOBILE
30
31 using System;
32 using System.Collections.Generic;
33
34 using System.IO;
35 using System.Runtime.Serialization;
36 using NUnit.Framework;
37 using System.Xml.Schema;
38 using System.Collections;
39 using System.Xml.Serialization;
40 using System.Reflection;
41 using System.Xml;
42
43 using QName = System.Xml.XmlQualifiedName;
44
45 namespace MonoTests.System.Runtime.Serialization
46 {
47         [TestFixture]
48         public class XsdDataContractExporterTest
49         {
50                 internal const string MSSimpleNamespace =
51                         "http://schemas.microsoft.com/2003/10/Serialization/";
52                 internal const string MSArraysNamespace =
53                         "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
54                 internal const string DefaultClrNamespaceBase =
55                         "http://schemas.datacontract.org/2004/07/";
56
57                 [Test]
58                 public void Ctor1 ()
59                 {
60                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
61                         Assert.IsNotNull (xdce.Schemas);
62                 }
63
64                 [Test]
65                 public void PrimitiveType ()
66                 {
67                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
68                         Assert.AreEqual (1, xdce.Schemas.Count);
69
70                         Assert.IsNull (xdce.GetSchemaType (typeof (int)));
71                         Assert.AreEqual (new QName ("int", XmlSchema.Namespace), xdce.GetSchemaTypeName (typeof (int)));
72
73                         xdce.Export (typeof (int));
74                         Assert.IsNull (xdce.GetSchemaType (typeof (int)));
75                         Assert.AreEqual (new QName ("int", XmlSchema.Namespace), xdce.GetSchemaTypeName (typeof (int)));
76                 }
77
78                 [Test]
79                 public void CanExportTest ()
80                 {
81                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
82                         Assert.IsTrue (xdce.CanExport (typeof (int)), "#1");
83                         Assert.IsTrue (xdce.CanExport (typeof (dc)), "#2");
84
85                         //No DataContract/Serializable etc -> changed in 3.5
86                         Assert.IsTrue (xdce.CanExport (this.GetType ()), "#3");
87                 }
88
89                 [Test]
90                 public void GetSchemaTypeTest ()
91                 {
92                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
93                         Assert.IsNull (xdce.GetSchemaType (typeof (dc)));
94                         Assert.AreEqual (new QName ("_dc", "http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization"), xdce.GetSchemaTypeName (typeof (dc)));
95                 }
96
97                 [Test]
98                 public void Test2 ()
99                 {
100                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
101                         xdce.Export (typeof (dc));
102                         XmlSchemaSet set = xdce.Schemas;
103
104                         xdce = new XsdDataContractExporter (set);
105                         try {
106                                 xdce.Export (typeof (dc));
107                         } catch (XmlSchemaException xe) {
108                                 return;
109                         } catch (Exception e) {
110                                 Assert.Fail ("Expected XmlSchemaException, but got " + e.GetType ().ToString ());
111                         }
112
113                         Assert.Fail ("Expected XmlSchemaException");
114                 }
115
116                 [Test]
117                 public void EnumTest ()
118                 {
119                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
120                         xdce.Export (typeof (XColors));
121
122                         CheckEnum (xdce.Schemas, colors_qname, new List<string> (new string [] { "_Red" }));
123                 }
124
125                 [Test]
126                 public void EnumNoDcTest ()
127                 {
128                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
129                         xdce.Export (typeof (EnumNoDc));
130
131                         CheckEnum (xdce.Schemas,
132                                 new QName ("EnumNoDc",
133                                         "http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization"),
134                                 new List<string> (new string [] { "Red", "Green", "Blue" }));
135                 }
136
137                 //Test case for class dc
138                 [Test]
139                 public void DcTest ()
140                 {
141                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
142                         xdce.Export (typeof (dc));
143                         CheckDcFull (xdce.Schemas);
144                 }
145
146                 [Test]
147                 public void Dc3Test ()
148                 {
149                         //Check for duplicate dc2 ?
150                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
151                         xdce.Export (typeof (dc3));
152                         CheckDcFull (xdce.Schemas);
153                 }
154
155                 [Test]
156                 public void Dc3Test2 ()
157                 {
158                         //Check for duplicate dc2 ?
159                         XsdDataContractExporter xdce = new XsdDataContractExporter ();
160                         xdce.Export (typeof (dc3));
161                         xdce.Export (typeof (dc3));
162                         CheckDcFull (xdce.Schemas);
163                 }
164
165                 [Test]
166                 public void GetSchemaTypeName ()
167                 {
168                         var xdce = new XsdDataContractExporter ();
169                         // bug #670539
170                         Assert.AreEqual (new XmlQualifiedName ("ArrayOfstring", MSArraysNamespace), xdce.GetSchemaTypeName (typeof (IEnumerable<string>)), "#1");
171                 }
172
173                 //Helper methods
174
175                 XmlSchemas GetSchemas (XmlSchemaSet set)
176                 {
177                         XmlSchemas schemas = new XmlSchemas ();
178                         foreach (XmlSchema schema in set.Schemas ())
179                                 schemas.Add (schema);
180
181                         return schemas;
182                 }
183
184                 void CheckEnum (XmlSchemaSet schemas, QName qname, List<string> values)
185                 {
186                         XmlSchemaSimpleType simple = schemas.GlobalTypes [qname] as XmlSchemaSimpleType;
187                         Assert.IsNotNull (simple, "#ce1");
188
189                         XmlSchemaSimpleTypeRestriction restriction = simple.Content as XmlSchemaSimpleTypeRestriction;
190                         Assert.IsNotNull (restriction, "#ce2");
191                         Assert.AreEqual (new QName ("string", XmlSchema.Namespace), restriction.BaseTypeName, "#ce3");
192
193                         //Check the values
194                         Assert.AreEqual (values.Count, restriction.Facets.Count, "#ce4");
195                         values.Sort ();
196
197                         List<string> facets = new List<string> ();
198                         foreach (XmlSchemaObject obj in restriction.Facets) {
199                                 XmlSchemaEnumerationFacet facet = obj as XmlSchemaEnumerationFacet;
200                                 Assert.IsNotNull (facet, "#ce5");
201                                 facets.Add (facet.Value);
202                         }
203
204                         facets.Sort ();
205                         for (int i = 0;i < values.Count;i++)
206                                 Assert.AreEqual (values [i], facets [i], "#ce6");
207
208                         //Check the corresponding element
209                         CheckElement (schemas, qname);
210                 }
211
212                 void CheckElement (XmlSchemaSet schemas, QName qname)
213                 {
214                         XmlSchemaElement element = schemas.GlobalElements [qname] as XmlSchemaElement;
215                         Assert.IsNotNull (element, "#c1");
216                         Assert.IsTrue (element.IsNillable, "#c2");
217                         Assert.AreEqual (qname, element.SchemaTypeName, "#c3");
218                 }
219
220                 XmlSchemaComplexType GetSchemaComplexType (XmlSchemaSet schemas, QName qname)
221                 {
222                         XmlSchemaComplexType type = schemas.GlobalTypes [qname] as XmlSchemaComplexType;
223                         Assert.IsNotNull (type, "ComplexType " + qname.ToString () + " not found.");
224
225                         return type;
226                 }
227
228                 //Check the <element .. > in a sequence
229                 void CheckElementReference (XmlSchemaObject obj, string name, QName schema_type, bool nillable)
230                 {
231                         XmlSchemaElement element = obj as XmlSchemaElement;
232                         Assert.IsNotNull (element, "XmlSchemaElement not found for " + schema_type.ToString ());
233
234                         Assert.AreEqual (name, element.Name, "#v1, Element name did not match");
235                         //FIXME: Assert.AreEqual (0, element.MinOccurs, "#v0, MinOccurs should be 0 for element '" + name + "'");
236                         Assert.AreEqual (schema_type, element.SchemaTypeName, "#v2, SchemaTypeName for element '" + element.Name + "' did not match.");
237                         Assert.AreEqual (nillable, element.IsNillable, "#v3, Element '" + element.Name + "', schema type = '" + schema_type + "' should have nillable = " + nillable);
238                 }
239
240                 void CheckArray (XmlSchemaSet schemas, QName qname, QName element_qname)
241                 {
242                         XmlSchemaComplexType type = GetSchemaComplexType (schemas, qname);
243                         XmlSchemaSequence sequence = type.Particle as XmlSchemaSequence;
244                         Assert.IsNotNull (sequence, "#ca1");
245
246                         Assert.AreEqual (1, sequence.Items.Count, "#ca2, Sequence.Items.Count");
247                         CheckElementReference (
248                                 sequence.Items [0],
249                                 element_qname.Name,
250                                 element_qname,
251                                 element_qname.Namespace != XmlSchema.Namespace);
252
253                         XmlSchemaElement element = (XmlSchemaElement) sequence.Items [0];
254                         Assert.AreEqual ("unbounded", element.MaxOccursString, "#ca3");
255
256                         CheckElement (schemas, qname);
257                 }
258
259                 QName colors_qname = new QName ("_XColors", "http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization");
260                 QName dc_qname = new QName ("_dc", "http://schemas.datacontract.org/2004/07/MonoTests.System.Runtime.Serialization");
261                 QName other_qname = new QName ("_other", "http://schemas.datacontract.org/2004/07/OtherNs");
262
263
264                 void CheckDcFull (XmlSchemaSet schemas)
265                 {
266                         Assert.IsTrue (schemas.IsCompiled, "#dt0, XmlSchemaSet not compiled");
267                         XmlSchemaComplexType type = GetSchemaComplexType (schemas, dc_qname);
268                         XmlSchemaSequence sequence = type.Particle as XmlSchemaSequence;
269                         Assert.IsNotNull (sequence, "#dt1");
270
271                         Assert.AreEqual (5, sequence.Items.Count, "#dt2, Sequence.Items.Count");
272                         CheckElementReference (sequence.Items [0], "_color",
273                                 colors_qname, false);
274                         CheckEnum (schemas, colors_qname, new List<string> (new string [] { "_Red" }));
275
276                         CheckElementReference (sequence.Items [1], "_foo",
277                                 new QName ("string", XmlSchema.Namespace), true);
278
279                         CheckElementReference (sequence.Items [2], "_o",
280                                 new QName ("ArrayOf_other", "http://schemas.datacontract.org/2004/07/OtherNs"), true);
281                         CheckArray (schemas, new QName ("ArrayOf_other", "http://schemas.datacontract.org/2004/07/OtherNs"), other_qname);
282
283                         CheckElementReference (sequence.Items [3], "_single_o",
284                                 new QName ("_other", "http://schemas.datacontract.org/2004/07/OtherNs"), true);
285                         CheckOther (schemas);
286
287                         CheckElementReference (sequence.Items [4], "i_array",
288                                 new QName ("ArrayOfint", "http://schemas.microsoft.com/2003/10/Serialization/Arrays"), true);
289                         CheckArray (schemas, new QName ("ArrayOfint", "http://schemas.microsoft.com/2003/10/Serialization/Arrays"),
290                                 new QName ("int", XmlSchema.Namespace));
291
292                         CheckElement (schemas, dc_qname);
293                 }
294
295                 void CheckOther (XmlSchemaSet schemas)
296                 {
297                         XmlSchemaComplexType type = GetSchemaComplexType (schemas, other_qname);
298                         XmlSchemaSequence sequence = type.Particle as XmlSchemaSequence;
299                         Assert.IsNotNull (sequence, "#ct0");
300
301                         Assert.AreEqual (1, sequence.Items.Count, "#ct1");
302                         CheckElementReference (sequence.Items [0], "_field_int", new QName ("int", XmlSchema.Namespace), false);
303                 }
304
305         }
306
307         [DataContract (Name = "_XColors")]
308         public enum XColors
309         {
310                 [EnumMember (Value = "_Red")]
311                 Red,
312                 Green,
313                 Blue
314         }
315
316         public enum EnumNoDc
317         {
318                 Red,
319                 Green,
320                 Blue
321         }
322
323         [DataContract (Name = "_dc")]
324         public class dc
325         {
326                 [DataMember (Name = "_foo")]
327                 public string foo;
328
329                 int not_used;
330
331                 [DataMember (Name = "_color")]
332                 XColors color;
333
334                 //[DataMember]
335                 public dc me;
336
337                 [DataMember (Name = "_o")]
338                 public OtherNs.other [] o;
339
340                 [DataMember (Name = "_single_o")]
341                 public OtherNs.other single_o;
342
343                 [DataMember]
344                 public int [] i_array;
345         }
346
347         [DataContract (Name = "_dc2")]
348         public class dc2 : dc
349         {
350                 [DataMember (Name = "_foo2")]
351                 string foo2;
352         }
353
354         [DataContract]
355         public abstract class abstract_class
356         {
357                 [DataMember]
358                 public string foo;
359         }
360
361         [Serializable]
362         public class base_xs
363         {
364                 public int base_int;
365                 private string base_string;
366         }
367
368         [Serializable]
369         public class xs : base_xs
370         {
371                 private string ignore;
372                 public string useme;
373         }
374
375         [DataContract]
376         public class dc_with_basexs : base_xs
377         {
378                 [DataMember (Name = "_foo")]
379                 public string foo;
380         }
381
382         [XmlRoot]
383         public class xa
384         {
385                 [XmlElement]
386                 public string foo;
387
388                 [XmlAttribute]
389                 public int bar;
390         }
391
392         [DataContract (Name = "_dc3")]
393         public class dc3
394         {
395                 [DataMember (Name = "_first")]
396                 dc2 first;
397
398                 [DataMember (Name = "_second")]
399                 dc2 second;
400         }
401
402 }
403
404 namespace OtherNs
405 {
406         [DataContract (Name = "_other")]
407         public class other /*: MonoTests.System.Runtime.Serialization.dc*/
408         {
409                 [DataMember (Name = "_field_int")]
410                 public int field_int;
411         }
412 }
413
414 #endif