New test.
[mono.git] / mcs / class / System.XML / Test / System.Xml.Schema / XmlSchemaTests.cs
1 //
2 // System.Xml.XmlSchemaTests.cs
3 //
4 // Author:
5 //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // (C) 2002 Atsushi Enomoto
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 NUnit.Framework;
16
17 namespace MonoTests.System.Xml
18 {
19         [TestFixture]
20         public class XmlSchemaTests : XmlSchemaAssertion
21         {
22                 [Test]
23                 public void TestRead ()
24                 {
25                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/1.xsd");
26                         AssertEquals (6, schema.Items.Count);
27
28                         bool fooValidated = false;
29                         bool barValidated = false;
30                         string ns = "urn:bar";
31
32                         foreach (XmlSchemaObject obj in schema.Items) {
33                                 XmlSchemaElement element = obj as XmlSchemaElement;
34                                 if (element == null)
35                                         continue;
36                                 if (element.Name == "Foo") {
37                                         AssertElement (element, "Foo", 
38                                                 XmlQualifiedName.Empty, null,
39                                                 QName ("string", XmlSchema.Namespace), null);
40                                         fooValidated = true;
41                                 }
42                                 if (element.Name == "Bar") {
43                                         AssertElement (element, "Bar",
44                                                 XmlQualifiedName.Empty, null, QName ("FugaType", ns), null);
45                                         barValidated = true;
46                                 }
47                         }
48                         Assert (fooValidated);
49                         Assert (barValidated);
50                 }
51
52                 [Test]
53                 public void TestReadFlags ()
54                 {
55                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/2.xsd");
56                         schema.Compile (null);
57                         XmlSchemaElement el = schema.Items [0] as XmlSchemaElement;
58                         AssertNotNull (el);
59                         AssertEquals (XmlSchemaDerivationMethod.Extension, el.Block);
60
61                         el = schema.Items [1] as XmlSchemaElement;
62                         AssertNotNull (el);
63                         AssertEquals (XmlSchemaDerivationMethod.Extension |
64                                 XmlSchemaDerivationMethod.Restriction, el.Block);
65                 }
66
67                 [Test]
68                 public void TestWriteFlags ()
69                 {
70                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/2.xsd");
71                         StringWriter sw = new StringWriter ();
72                         XmlTextWriter xtw = new XmlTextWriter (sw);
73                         schema.Write (xtw);
74                 }
75
76                 [Test]
77                 public void TestCompile ()
78                 {
79                         XmlQualifiedName qname;
80                         XmlSchemaComplexContentExtension xccx;
81                         XmlSchemaComplexType cType;
82                         XmlSchemaSequence seq;
83
84                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/1.xsd");
85 //                      Assert (!schema.IsCompiled);
86                         schema.Compile (null);
87                         Assert (schema.IsCompiled);
88                         string ns = "urn:bar";
89
90                         XmlSchemaElement foo = (XmlSchemaElement) schema.Elements [QName ("Foo", ns)];
91                         AssertNotNull (foo);
92                         XmlSchemaDatatype stringDatatype = foo.ElementType as XmlSchemaDatatype;
93                         AssertNotNull (stringDatatype);
94
95                         // HogeType
96                         qname = QName ("HogeType", ns);
97                         cType = schema.SchemaTypes [qname] as XmlSchemaComplexType;
98                         AssertNotNull (cType);
99                         AssertNull (cType.ContentModel);
100                         AssertCompiledComplexType (cType, qname, 0, 0,
101                                 false, null, true, XmlSchemaContentType.ElementOnly);
102                         seq = cType.ContentTypeParticle as XmlSchemaSequence;
103                         AssertNotNull (seq);
104                         AssertEquals (2, seq.Items.Count);
105                         XmlSchemaElement refFoo = seq.Items [0] as XmlSchemaElement;
106                         AssertCompiledElement (refFoo, QName ("Foo", ns), stringDatatype);
107
108                         // FugaType
109                         qname = QName ("FugaType", ns);
110                         cType = schema.SchemaTypes [qname] as XmlSchemaComplexType;
111                         AssertNotNull (cType);
112                         xccx = cType.ContentModel.Content as XmlSchemaComplexContentExtension;
113                         AssertCompiledComplexContentExtension (
114                                 xccx, 0, false, QName ("HogeType", ns));
115
116                         AssertCompiledComplexType (cType, qname, 0, 0,
117                                 false, typeof (XmlSchemaComplexContent),
118                                 true, XmlSchemaContentType.ElementOnly);
119                         AssertNotNull (cType.BaseSchemaType);
120
121                         seq = xccx.Particle as XmlSchemaSequence;
122                         AssertNotNull (seq);
123                         AssertEquals (1, seq.Items.Count);
124                         XmlSchemaElement refBaz = seq.Items [0] as XmlSchemaElement;
125                         AssertNotNull (refBaz);
126                         AssertCompiledElement (refBaz, QName ("Baz", ""), stringDatatype);
127
128                         qname = QName ("Bar", ns);
129                         XmlSchemaElement element = schema.Elements [qname] as XmlSchemaElement;
130                         AssertCompiledElement (element, qname, cType);
131                 }
132
133                 [Test]
134                 [ExpectedException (typeof (XmlSchemaException))]
135                 public void TestCompile_ZeroLength_TargetNamespace ()
136                 {
137                         XmlSchema schema = new XmlSchema ();
138                         schema.TargetNamespace = string.Empty;
139                         Assert (!schema.IsCompiled);
140
141                         // MS.NET 1.x: The Namespace '' is an invalid URI.
142                         // MS.NET 2.0: The targetNamespace attribute cannot have empty string as its value.
143                         schema.Compile (null);
144                 }
145
146                 [Test]
147                 [ExpectedException (typeof (XmlSchemaException))]
148                 public void TestCompileNonSchema ()
149                 {
150                         XmlTextReader xtr = new XmlTextReader ("<root/>", XmlNodeType.Document, null);
151                         XmlSchema schema = XmlSchema.Read (xtr, null);
152                         xtr.Close ();
153                 }
154
155                 [Test]
156                 public void TestSimpleImport ()
157                 {
158                         XmlSchema schema = XmlSchema.Read (new XmlTextReader ("Test/XmlFiles/xsd/3.xsd"), null);
159                         AssertEquals ("urn:foo", schema.TargetNamespace);
160                         XmlSchemaImport import = schema.Includes [0] as XmlSchemaImport;
161                         AssertNotNull (import);
162
163                         schema.Compile (null);
164                         AssertEquals (4, schema.Elements.Count);
165                         AssertNotNull (schema.Elements [QName ("Foo", "urn:foo")]);
166                         AssertNotNull (schema.Elements [QName ("Bar", "urn:foo")]);
167                         AssertNotNull (schema.Elements [QName ("Foo", "urn:bar")]);
168                         AssertNotNull (schema.Elements [QName ("Bar", "urn:bar")]);
169                         
170                 }
171
172                 [Test]
173                 public void TestSimpleMutualImport ()
174                 {
175                         XmlReader r = new XmlTextReader ("Test/XmlFiles/xsd/inter-inc-1.xsd");
176                         try {
177                                 XmlSchema.Read (r, null).Compile (null);
178                         } finally {
179                                 r.Close ();
180                         }
181                 }
182
183                 [Test]
184                 public void TestQualification ()
185                 {
186                         XmlSchema schema = XmlSchema.Read (new XmlTextReader ("Test/XmlFiles/xsd/5.xsd"), null);
187                         schema.Compile (null);
188                         XmlSchemaElement el = schema.Elements [QName ("Foo", "urn:bar")] as XmlSchemaElement;
189                         AssertNotNull (el);
190                         XmlSchemaComplexType ct = el.ElementType as XmlSchemaComplexType;
191                         XmlSchemaSequence seq = ct.ContentTypeParticle as XmlSchemaSequence;
192                         XmlSchemaElement elp = seq.Items [0] as XmlSchemaElement;
193                         AssertEquals (QName ("Bar", ""), elp.QualifiedName);
194
195                         schema = XmlSchema.Read (new XmlTextReader ("Test/XmlFiles/xsd/6.xsd"), null);
196                         schema.Compile (null);
197                         el = schema.Elements [QName ("Foo", "urn:bar")] as XmlSchemaElement;
198                         AssertNotNull (el);
199                         ct = el.ElementType as XmlSchemaComplexType;
200                         seq = ct.ContentTypeParticle as XmlSchemaSequence;
201                         elp = seq.Items [0] as XmlSchemaElement;
202                         AssertEquals (QName ("Bar", "urn:bar"), elp.QualifiedName);
203                 }
204
205                 [Test]
206                 public void TestWriteNamespaces ()
207                 {
208                         XmlDocument doc = new XmlDocument ();
209                         XmlSchema xs;
210                         StringWriter sw;
211                         XmlTextWriter xw;
212
213                         // empty
214                         xs = new XmlSchema ();
215                         sw = new StringWriter ();
216                         xw = new XmlTextWriter (sw);
217                         xs.Write (xw);
218                         doc.LoadXml (sw.ToString ());
219                         AssertEquals ("#1", "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
220
221                         // TargetNamespace
222                         xs = new XmlSchema ();
223                         sw = new StringWriter ();
224                         xw = new XmlTextWriter (sw);
225                         xs.TargetNamespace = "urn:foo";
226                         xs.Write (xw);
227                         doc.LoadXml (sw.ToString ());
228                         AssertEquals ("#2", "<xs:schema xmlns:tns=\"urn:foo\" targetNamespace=\"urn:foo\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
229
230                         // Zero-length TargetNamespace
231                         xs = new XmlSchema ();
232                         sw = new StringWriter ();
233                         xw = new XmlTextWriter (sw);
234                         xs.TargetNamespace = string.Empty;
235                         xs.Write (xw);
236                         doc.LoadXml (sw.ToString ());
237                         AssertEquals ("#2b", "<xs:schema targetNamespace=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
238
239                         // XmlSerializerNamespaces
240                         xs = new XmlSchema ();
241                         sw = new StringWriter ();
242                         xw = new XmlTextWriter (sw);
243                         xs.Namespaces.Add ("hoge", "urn:hoge");
244                         xs.Write (xw);
245                         doc.LoadXml (sw.ToString ());
246                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
247                         // AssertEquals ("#3", "<schema xmlns:hoge=\"urn:hoge\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
248
249                         // TargetNamespace + XmlSerializerNamespaces
250                         xs = new XmlSchema ();
251                         sw = new StringWriter ();
252                         xw = new XmlTextWriter (sw);
253                         xs.TargetNamespace = "urn:foo";
254                         xs.Namespaces.Add ("hoge", "urn:hoge");
255                         xs.Write (xw);
256                         doc.LoadXml (sw.ToString ());
257                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
258                         // AssertEquals ("#4", "<schema xmlns:hoge=\"urn:hoge\" targetNamespace=\"urn:foo\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
259
260                         // Add XmlSchema.Namespace to XmlSerializerNamespaces
261                         xs = new XmlSchema ();
262                         sw = new StringWriter ();
263                         xw = new XmlTextWriter (sw);
264                         xs.Namespaces.Add ("a", XmlSchema.Namespace);
265                         xs.Write (xw);
266                         doc.LoadXml (sw.ToString ());
267                         AssertEquals ("#5", "<a:schema xmlns:a=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
268
269                         // UnhandledAttributes + XmlSerializerNamespaces
270                         xs = new XmlSchema ();
271                         sw = new StringWriter ();
272                         xw = new XmlTextWriter (sw);
273                         XmlAttribute attr = doc.CreateAttribute ("hoge");
274                         xs.UnhandledAttributes = new XmlAttribute [] {attr};
275                         xs.Namespaces.Add ("hoge", "urn:hoge");
276                         xs.Write (xw);
277                         doc.LoadXml (sw.ToString ());
278                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
279                         // AssertEquals ("#6", "<schema xmlns:hoge=\"urn:hoge\" hoge=\"\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
280
281                         // Adding xmlns to UnhandledAttributes -> no output
282                         xs = new XmlSchema ();
283                         sw = new StringWriter ();
284                         xw = new XmlTextWriter (sw);
285                         attr = doc.CreateAttribute ("xmlns");
286                         attr.Value = "urn:foo";
287                         xs.UnhandledAttributes = new XmlAttribute [] {attr};
288                         xs.Write (xw);
289                         doc.LoadXml (sw.ToString ());
290                         AssertEquals ("#7", "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
291                 }
292
293                 [Category ("NotWorking")]
294                 [Test]
295                 public void TestWriteNamespaces2 ()
296                 {
297                         string xmldecl = "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
298                         XmlSchema xs = new XmlSchema ();
299                         XmlSerializerNamespaces nss =
300                                 new XmlSerializerNamespaces ();
301                         StringWriter sw;
302                         sw = new StringWriter ();
303                         xs.Write (new XmlTextWriter (sw));
304                         AssertEquals ("#1", xmldecl + "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
305
306                         xs.Namespaces = nss;
307                         sw = new StringWriter ();
308                         xs.Write (new XmlTextWriter (sw));
309                         AssertEquals ("#2", xmldecl + "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
310
311                         nss.Add ("foo", "urn:foo");
312                         sw = new StringWriter ();
313                         xs.Write (new XmlTextWriter (sw));
314                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
315                         // AssertEquals ("#3", xmldecl + "<schema xmlns:foo=\"urn:foo\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
316
317                         nss.Add ("", "urn:foo");
318                         sw = new StringWriter ();
319                         xs.Write (new XmlTextWriter (sw));
320                         // commenting out. .NET 2.0 outputs xs:schema instead of q1:schema, that also makes sense.
321                         // AssertEquals ("#4", xmldecl + "<q1:schema xmlns:foo=\"urn:foo\" xmlns=\"urn:foo\" xmlns:q1=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
322
323                         nss.Add ("q1", "urn:q1");
324                         sw = new StringWriter ();
325                         xs.Write (new XmlTextWriter (sw));
326                         //Not sure if testing for exact order of these name spaces is
327                         // relevent, so using less strict test that passes on MS.NET
328                         //AssertEquals (xmldecl + "<q2:schema xmlns:foo=\"urn:foo\" xmlns:q1=\"urn:q1\" xmlns=\"urn:foo\" xmlns:q2=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
329                         Assert("q1", sw.ToString ().IndexOf ("xmlns:q1=\"urn:q1\"") != -1);
330                 }
331
332                 [Test]
333                 public void ReaderPositionAfterRead ()
334                 {
335                         string xsd = @"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' elementFormDefault='qualified'>  <xs:element name='test' type='xs:integer'/></xs:schema>";
336                         XmlTextReader xtr = new XmlTextReader (xsd, XmlNodeType.Document, null);
337                         xtr.Read ();
338                         XmlSchema xs = XmlSchema.Read (xtr, null);
339                         AssertEquals (XmlNodeType.EndElement, xtr.NodeType);
340                 }
341
342                 [Test]
343                 // bug #76865
344                 public void AmbiguityDetectionOnChameleonAnyOther ()
345                 {
346                         string xsd = @"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
347 <xs:complexType name='TestType'>
348   <xs:sequence>
349     <xs:any namespace='##other' minOccurs='0' />
350     <xs:element name='Item' /> 
351     <xs:any namespace='##other' minOccurs='0' />
352   </xs:sequence> 
353 </xs:complexType>
354 </xs:schema>";
355                         XmlSchema.Read (new XmlTextReader (xsd, XmlNodeType.Document, null), null);
356                 }
357
358                 [Test]
359                 // bug #77685
360                 public void ReadDoesNotIgnoreDocumentationEmptyElement ()
361                 {
362                         string schemaxml = @"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
363   <xs:element name='choice'>
364     <xs:annotation><xs:documentation /></xs:annotation>
365   </xs:element>
366 </xs:schema>";
367                         XmlTextReader tr = new XmlTextReader (
368                                 schemaxml, XmlNodeType.Document, null);
369                         XmlSchema schema = XmlSchema.Read (tr, null);
370                         XmlSchemaElement element =
371                                 schema.Items [0] as XmlSchemaElement;
372                         XmlSchemaAnnotation annotation = element.Annotation;
373                         XmlSchemaDocumentation doc =
374                                 annotation.Items [0] as XmlSchemaDocumentation;
375                         AssertEquals (0, doc.Markup.Length);
376                 }
377
378
379                 [Test]
380                 // bug #77687
381                 public void CompileFillsSchemaPropertyInExternal ()
382                 {
383                         string schemaFileName = "Test/XmlFiles/xsd/77687.xsd";
384                         XmlTextReader tr = new XmlTextReader (schemaFileName);
385
386                         XmlSchema schema = XmlSchema.Read (tr, null);
387                         XmlSchemaInclude inc = (XmlSchemaInclude) schema.Includes [0];
388                         AssertNull (inc.Schema);
389                         schema.Compile (null);
390                         tr.Close ();
391                         AssertNotNull (inc.Schema);
392                 }
393
394                 [Test]
395                 // bug #78985 (contains two identical field path "@key" in 
396                 // two different keys where one is in scope within another)
397                 public void DuplicateKeyFieldAttributePath ()
398                 {
399                         string schemaFileName = "Test/XmlFiles/xsd/78985.xsd";
400                         string xmlFileName = "Test/XmlFiles/xsd/78985.xml";
401                         XmlTextReader tr = new XmlTextReader (schemaFileName);
402
403                         XmlValidatingReader vr = new XmlValidatingReader (
404                                 new XmlTextReader (xmlFileName));
405                         vr.Schemas.Add (XmlSchema.Read (tr, null));
406                         while (!vr.EOF)
407                                 vr.Read ();
408                 }
409         }
410 }