2 // System.Xml.XmlSchemaDatatypeTests.cs
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 // Wojciech Kotlarski <wojciech.kotlarski@7digital.com>
7 // Andres G. Aragoneses <andres.aragoneses@7digital.com>
9 // (C) 2002 Atsushi Enomoto
10 // (C) 2012 7digital Media Ltd.
16 using System.Xml.Schema;
17 using System.Collections.Generic;
18 using NUnit.Framework;
20 using QName = System.Xml.XmlQualifiedName;
21 using SimpleType = System.Xml.Schema.XmlSchemaSimpleType;
22 using SimpleRest = System.Xml.Schema.XmlSchemaSimpleTypeRestriction;
23 using AssertType = NUnit.Framework.Assert;
25 namespace MonoTests.System.Xml
28 public class XmlSchemaDatatypeTests
30 private XmlSchema GetSchema (string path)
32 return XmlSchema.Read (new XmlTextReader (path), null);
35 private XmlQualifiedName QName (string name, string ns)
37 return new XmlQualifiedName (name, ns);
40 private void AssertDatatype (XmlSchema schema, int index,
41 XmlTokenizedType tokenizedType, Type type, string rawValue, object parsedValue)
43 XmlSchemaElement element = schema.Items [index] as XmlSchemaElement;
44 XmlSchemaDatatype dataType = element.ElementType as XmlSchemaDatatype;
45 Assert.AreEqual (tokenizedType, dataType.TokenizedType, "#1");
46 Assert.AreEqual (type, dataType.ValueType, "#2");
47 Assert.AreEqual (parsedValue, dataType.ParseValue (rawValue, null, null), "#3");
51 [Ignore ("The behavior has been inconsistent between versions, so it is not worthy of testing.")]
52 // Note that it could also apply to BaseTypeName (since if
53 // it is xs:anyType and BaseType is empty, BaseTypeName
54 // should be xs:anyType).
55 public void TestAnyType ()
57 XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/datatypesTest.xsd");
58 schema.Compile (null);
59 XmlSchemaElement any = schema.Elements [QName ("e00", "urn:bar")] as XmlSchemaElement;
60 XmlSchemaComplexType cType = any.ElementType as XmlSchemaComplexType;
61 Assert.AreEqual (typeof (XmlSchemaComplexType), cType.GetType (), "#1");
62 Assert.IsNotNull (cType, "#2");
63 Assert.AreEqual (XmlQualifiedName.Empty, cType.QualifiedName, "#3");
64 Assert.IsNull (cType.BaseSchemaType, "#4"); // In MS.NET 2.0 its null. In 1.1 it is not null.
65 Assert.IsNotNull (cType.ContentTypeParticle, "#5");
69 public void TestAll ()
71 XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/datatypesTest.xsd");
72 schema.Compile (null);
74 AssertDatatype (schema, 1, XmlTokenizedType.CDATA, typeof (string), " f o o ", " f o o ");
75 AssertDatatype (schema, 2, XmlTokenizedType.CDATA, typeof (string), " f o o ", " f o o ");
76 // token shouldn't allow " f o o "
77 AssertDatatype (schema, 3, XmlTokenizedType.CDATA, typeof (string), "f o o", "f o o");
78 // language seems to be checked strictly
79 AssertDatatype (schema, 4, XmlTokenizedType.CDATA, typeof (string), "x-foo", "x-foo");
81 // NMTOKEN shouldn't allow " f o o "
82 // AssertDatatype (schema, 5, XmlTokenizedType.NMTOKEN, typeof (string), "foo", "foo");
83 // AssertDatatype (schema, 6, XmlTokenizedType.NMTOKEN, typeof (string []), "f o o", new string [] {"f", "o", "o"});
87 public void AnyUriRelativePath ()
89 XmlValidatingReader vr = new XmlValidatingReader (
91 // relative path value that contains ':' should be still valid.
92 "<root>../copy/myserver/</root>",
93 XmlNodeType.Document, null));
94 vr.Schemas.Add (XmlSchema.Read (
95 new XmlTextReader ("<xs:schema xmlns:xs='"
96 + XmlSchema.Namespace +
97 "'><xs:element name='root' type='xs:anyURI' /></xs:schema>",
98 XmlNodeType.Document, null), null));
106 [Category ("NotDotNet")]
108 public void AnyUriRelativePathContainsColon ()
110 XmlValidatingReader vr = new XmlValidatingReader (
112 // relative path value that contains ':' should be still valid.
113 "<root>../copy/myserver/c:/foo</root>",
114 XmlNodeType.Document, null));
115 vr.Schemas.Add (XmlSchema.Read (
116 new XmlTextReader ("<xs:schema xmlns:xs='"
117 + XmlSchema.Namespace +
118 "'><xs:element name='root' type='xs:anyURI' /></xs:schema>",
119 XmlNodeType.Document, null), null));
125 string [] allTypes = new string [] {
126 "string", "boolean", "float", "double", "decimal",
127 "duration", "dateTime", "time", "date", "gYearMonth",
128 "gYear", "gMonthDay", "gDay", "gMonth", "hexBinary",
129 "base64Binary", "anyURI", "QName", "NOTATION",
130 "normalizedString", "token", "language", "IDREFS",
131 "ENTITIES", "NMTOKEN", "NMTOKENS", "Name", "NCName",
132 "ID", "IDREF", "ENTITY", "integer",
133 "nonPositiveInteger", "negativeInteger", "long",
134 "int", "short", "byte", "nonNegativeInteger",
135 "unsignedLong", "unsignedInt", "unsignedShort",
136 "unsignedByte", "positiveInteger"
139 XmlSchemaSet allWrappers;
141 void SetupSimpleTypeWrappers ()
143 XmlSchema schema = new XmlSchema ();
144 List<QName> qnames = new List<QName> ();
145 foreach (string name in allTypes) {
146 SimpleType st = new SimpleType ();
147 st.Name = "x-" + name;
148 SimpleRest r = new SimpleRest ();
150 QName qname = new QName (name, XmlSchema.Namespace);
151 r.BaseTypeName = qname;
153 schema.Items.Add (st);
155 XmlSchemaSet sset = new XmlSchemaSet ();
161 XmlSchemaDatatype GetDatatype (string name)
163 return (allWrappers.GlobalTypes [new QName ("x-" + name,
164 String.Empty)] as SimpleType).Datatype;
167 string [] GetDerived (string target)
169 XmlSchemaDatatype strType = GetDatatype (target);
170 List<string> results = new List<string> ();
171 foreach (string name in allTypes) {
174 XmlSchemaDatatype deriv = GetDatatype (name);
175 if (deriv.IsDerivedFrom (strType))
177 else Console.Error.WriteLine (deriv.GetType () + " is not derived from " + strType.GetType ());
179 return results.ToArray ();
183 public void IsDerivedFrom ()
185 SetupSimpleTypeWrappers ();
187 // Funky, but XmlSchemaDatatype.IsDerivedFrom() is
188 // documented to always return false, but actually
189 // matches the same type - which could be guessed that
190 // this method is used only to detect user-defined
191 // simpleType derivation.
192 foreach (string b in allTypes)
193 foreach (string d in allTypes)
194 AssertType.AreEqual (b == d, GetDatatype (d).IsDerivedFrom (GetDatatype (b)), b);
196 AssertType.IsFalse (GetDatatype ("string").IsDerivedFrom (null), "null arg");
200 public void ChangeType_StringTest()
202 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).Datatype;
203 Assert.IsTrue (datatype != null);
204 Assert.AreEqual (XmlTypeCode.String, datatype.TypeCode);
205 Assert.AreEqual (typeof(string), datatype.ValueType);
207 Assert.AreEqual ("test", datatype.ChangeType("test", typeof(string)));
211 public void ChangeType_StringToObjectTest()
213 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).Datatype;
214 Assert.IsTrue (datatype != null);
215 Assert.AreEqual (XmlTypeCode.String, datatype.TypeCode);
216 Assert.AreEqual (typeof(string), datatype.ValueType);
218 Assert.AreEqual ("test", datatype.ChangeType("test", typeof(object)));
222 public void ChangeType_IntegerTest()
224 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).Datatype;
225 Assert.IsTrue (datatype != null);
226 Assert.AreEqual (XmlTypeCode.Integer, datatype.TypeCode);
227 Assert.AreEqual (typeof(decimal), datatype.ValueType);
229 Assert.AreEqual (300, datatype.ChangeType("300", typeof(int)));
233 public void ChangeType_FromDateTimeTest()
235 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.DateTime).Datatype;
236 Assert.IsTrue (datatype != null);
237 Assert.AreEqual (XmlTypeCode.DateTime, datatype.TypeCode);
238 Assert.AreEqual (typeof(DateTime), datatype.ValueType);
240 DateTime date = new DateTime (2012, 06, 27, 0, 0, 0, DateTimeKind.Utc);
241 Assert.AreEqual ("2012-06-27T00:00:00Z", datatype.ChangeType(date, typeof(string)));
245 public void ChangeType_FromTimeSpanTest()
247 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.DayTimeDuration).Datatype;
248 Assert.IsTrue (datatype != null);
249 Assert.AreEqual (XmlTypeCode.DayTimeDuration, datatype.TypeCode);
250 Assert.AreEqual (typeof(TimeSpan), datatype.ValueType);
252 TimeSpan span = new TimeSpan(1, 2, 3);
253 Assert.AreEqual ("PT1H2M3S", datatype.ChangeType(span, typeof(string)));
257 public void ChangeType_ToDateTimeTest()
259 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.DateTime).Datatype;
260 Assert.IsTrue (datatype != null);
261 Assert.AreEqual (XmlTypeCode.DateTime, datatype.TypeCode);
262 Assert.AreEqual (typeof(DateTime), datatype.ValueType);
264 DateTime date = new DateTime (2012, 06, 27, 0, 0, 0, DateTimeKind.Utc);
265 Assert.AreEqual (date, datatype.ChangeType("2012-06-27T00:00:00Z", typeof(DateTime)));
269 public void ChangeType_ToTimeSpanTest()
271 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.DayTimeDuration).Datatype;
272 Assert.IsTrue (datatype != null);
273 Assert.AreEqual (XmlTypeCode.DayTimeDuration, datatype.TypeCode);
274 Assert.AreEqual (typeof(TimeSpan), datatype.ValueType);
276 TimeSpan span = new TimeSpan(1, 2, 3);
277 Assert.AreEqual (span, datatype.ChangeType("PT1H2M3S", typeof(TimeSpan)));
281 [ExpectedException(typeof(ArgumentNullException))]
282 public void ChangeType_NullValueArgumentInFromStringTest()
284 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).Datatype;
285 datatype.ChangeType(null, typeof(string));
289 [ExpectedException(typeof(ArgumentNullException))]
290 public void ChangeType_NullValueArgumentInToStringTest()
292 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).Datatype;
293 datatype.ChangeType(null, typeof(int));
297 [ExpectedException(typeof(ArgumentNullException))]
298 public void ChangeType_NullTargetArgumentInFromStringTest()
300 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).Datatype;
301 datatype.ChangeType("100", null);
305 [ExpectedException(typeof(ArgumentNullException))]
306 public void ChangeType_NullNamespaceResolverArgumentInFromStringTest()
308 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).Datatype;
309 datatype.ChangeType("100", typeof(string), null);
313 [Category("NotWorking")]
314 [ExpectedException (typeof(InvalidCastException))]
315 public void InvalidCastExceptionTest()
317 XmlSchemaDatatype datatype = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.DateTime).Datatype;
318 Assert.IsTrue (datatype != null);
319 Assert.AreEqual (XmlTypeCode.DateTime, datatype.TypeCode);
320 Assert.AreEqual (typeof(DateTime), datatype.ValueType);
322 datatype.ChangeType(300, typeof (int));
326 public void Bug12469 ()
328 Dictionary<string, string> validValues = new Dictionary<string, string> {
331 {"normalizedString", "abc"},
343 {"nonPositiveInteger", "0"},
344 {"negativeInteger", "-1"},
345 {"long", "9223372036854775807"},
346 {"int", "2147483647"},
349 {"nonNegativeInteger", "0"},
350 {"unsignedLong", "18446744073709551615"},
351 {"unsignedInt", "4294967295"},
352 {"unsignedShort", "65535"},
353 {"unsignedByte", "255"},
354 {"positiveInteger", "1"},
357 {"time", "00:00:00"},
358 {"date", "1999-12-31"},
359 {"dateTime", "1999-12-31T00:00:00.000"},
360 {"duration", "P1Y2M3DT10H30M"},
361 {"gYearMonth", "1999-01"},
363 {"gMonthDay", "--12-31"},
367 {"base64Binary", "AbCd eFgH IjKl 019+"},
368 {"hexBinary", "0123456789ABCDEF"},
370 {"anyURI", "https://www.server.com"},
371 {"QName", "xml:abc"},
374 // FIXME: implement validation
375 Dictionary<string, string> invalidValues = new Dictionary<string, string> {
385 {"nonPositiveInteger", "5"},
386 {"negativeInteger", "10"},
387 {"long", "999999999999999999999999999999999999999"},
388 {"int", "999999999999999999999999999999999999999"},
391 {"nonNegativeInteger", "-1"},
392 {"unsignedLong", "-1"},
393 {"unsignedInt", "-1"},
394 {"unsignedShort", "-1"},
395 {"unsignedByte", "-1"},
396 {"positiveInteger", "0"},
403 {"gYearMonth", "1999"},
405 {"gMonthDay", "-12-31"},
409 {"base64Binary", "####"},
412 // anyURI passes everything (as long as I observed)
416 const string schemaTemplate = @"
417 <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' elementFormDefault='qualified'>
418 <xs:element name='EL'>
420 <xs:attribute name='attr' type='xs:{0}' use='required' />
425 const string documentTemplate = @"<EL attr='{0}' />";
427 foreach (var type in validValues.Keys) {
429 var schema = string.Format (schemaTemplate, type);
430 var document = string.Format (documentTemplate, validValues[type]);
432 var schemaSet = new XmlSchemaSet ();
433 using (var reader = new StringReader (schema))
434 schemaSet.Add (XmlSchema.Read (reader, null));
435 schemaSet.Compile ();
436 var doc = new XmlDocument ();
437 using (var reader = new StringReader (document))
439 doc.Schemas = schemaSet;
442 // FIXME: implement validation
444 if (!invalidValues.ContainsKey (type))
447 doc = new XmlDocument ();
448 document = string.Format (documentTemplate, invalidValues [type]);
449 using (var reader = new StringReader (document))
451 doc.Schemas = schemaSet;
453 Assert.Fail (string.Format ("Failed to invalidate {0} for {1}", document, type));
454 } catch (XmlSchemaException) {
457 } catch (Exception) {
458 Console.Error.WriteLine (type);