// // System.Xml.XmlSerializerTests // // Author: // Erik LeBel // // (C) 2003 Erik LeBel // // // NOTES: // Where possible, these tests avoid testing the order of // an object's members serialization. Mono and .NET do not // reflect members in the same order. // // Only serializations tests so far, no deserialization. // // FIXME // test XmlArrayAttribute // test XmlArrayItemAttribute // test serialization of decimal type // test serialization of Guid type // test XmlNode serialization with and without modifying attributes. // test deserialization // FIXMEs found in this file using System; using System.Collections; using System.Globalization; using System.IO; using System.Text; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using NUnit.Framework; using MonoTests.System.Xml.TestClasses; namespace MonoTests.System.XmlSerialization { [TestFixture] public class XmlSerializerTests { const string XmlSchemaNamespace = "http://www.w3.org/2001/XMLSchema"; const string XmlSchemaInstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance"; const string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/"; const string WsdlTypesNamespace = "http://microsoft.com/wsdl/types/"; const string ANamespace = "some:urn"; const string AnotherNamespace = "another:urn"; StringWriter sw; XmlTextWriter xtw; XmlSerializer xs; private void SetUpWriter() { sw = new StringWriter (); xtw = new XmlTextWriter (sw); xtw.QuoteChar = '\''; xtw.Formatting = Formatting.None; } private string WriterText { get { string val = sw.GetStringBuilder().ToString(); int offset = val.IndexOf('>') + 1; val = val.Substring(offset); return Infoset(val); } } private void Serialize(object o) { SetUpWriter(); xs = new XmlSerializer(o.GetType()); xs.Serialize(xtw, o); } private void Serialize(object o, Type type) { SetUpWriter(); xs = new XmlSerializer(type); xs.Serialize(xtw, o); } private void Serialize(object o, XmlSerializerNamespaces ns) { SetUpWriter(); xs = new XmlSerializer(o.GetType()); xs.Serialize(xtw, o, ns); } private void Serialize(object o, XmlAttributeOverrides ao) { SetUpWriter(); xs = new XmlSerializer(o.GetType(), ao); xs.Serialize(xtw, o); } private void Serialize(object o, XmlRootAttribute root) { SetUpWriter(); xs = new XmlSerializer(o.GetType(), root); xs.Serialize(xtw, o); } private void Serialize (object o, XmlTypeMapping typeMapping) { SetUpWriter (); xs = new XmlSerializer (typeMapping); xs.Serialize (xtw, o); } private void SerializeEncoded (object o) { SerializeEncoded (o, o.GetType ()); } private void SerializeEncoded (object o, Type type) { XmlTypeMapping mapping = CreateSoapMapping (type); SetUpWriter (); xs = new XmlSerializer (mapping); xs.Serialize (xtw, o); } // test constructors #if USE_VERSION_1_1 // It doesn't pass on MS.NET 1.1. [Test] public void TestConstructor() { XmlSerializer ser = new XmlSerializer (null, ""); } #else #endif // test basic types //////////////////////////////////////////////////////// [Test] public void TestSerializeInt() { Serialize(10); Assert.AreEqual (Infoset("10"), WriterText); } [Test] public void TestSerializeBool() { Serialize(true); Assert.AreEqual (Infoset ("true"), WriterText); Serialize(false); Assert.AreEqual (Infoset ("false"), WriterText); } [Test] public void TestSerializeString() { Serialize("hello"); Assert.AreEqual (Infoset ("hello"), WriterText); } [Test] public void TestSerializeEmptyString() { Serialize(String.Empty); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeNullObject() { Serialize(null, typeof(object)); Assert.AreEqual (Infoset (""), WriterText); } [Test] [Ignore ("The generated XML is not exact but it is equivalent")] public void TestSerializeNullString() { Serialize(null, typeof(string)); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeIntArray() { Serialize(new int[] {1, 2, 3, 4}); Assert.AreEqual (Infoset ("1234"), WriterText); } [Test] public void TestSerializeEmptyArray() { Serialize(new int[] {}); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeChar() { Serialize('A'); Assert.AreEqual (Infoset ("65"), WriterText); Serialize('\0'); Assert.AreEqual (Infoset ("0"), WriterText); Serialize('\n'); Assert.AreEqual (Infoset ("10"), WriterText); Serialize('\uFF01'); Assert.AreEqual (Infoset ("65281"), WriterText); } [Test] public void TestSerializeFloat() { Serialize(10.78); Assert.AreEqual (Infoset ("10.78"), WriterText); Serialize(-1e8); Assert.AreEqual (Infoset ("-100000000"), WriterText); // FIXME test INF and other boundary conditions that may exist with floats } [Test] public void TestSerializeEnumeration_FromValue () { Serialize ((int) SimpleEnumeration.SECOND, typeof (SimpleEnumeration)); Assert.AreEqual ( "" + "SECOND", sw.ToString ()); } [Test] [Category ("NotWorking")] public void TestSerializeEnumeration_FromValue_Encoded () { SerializeEncoded ((int) SimpleEnumeration.SECOND, typeof (SimpleEnumeration)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "SECOND", XmlSchemaInstanceNamespace), sw.ToString ()); } [Test] public void TestSerializeEnumeration() { Serialize(SimpleEnumeration.FIRST); Assert.AreEqual (Infoset ("FIRST"), WriterText, "#1"); Serialize(SimpleEnumeration.SECOND); Assert.AreEqual (Infoset ("SECOND"), WriterText, "#2"); } [Test] public void TestSerializeEnumeration_Encoded() { SerializeEncoded (SimpleEnumeration.FIRST); Assert.AreEqual (string.Format(CultureInfo.InvariantCulture, "" + "FIRST", XmlSchemaInstanceNamespace), sw.ToString (), "#B1"); SerializeEncoded (SimpleEnumeration.SECOND); Assert.AreEqual (string.Format(CultureInfo.InvariantCulture, "" + "SECOND", XmlSchemaInstanceNamespace), sw.ToString (), "#B2"); } [Test] public void TestSerializeEnumDefaultValue () { Serialize (new EnumDefaultValue ()); Assert.AreEqual (Infoset (""), WriterText, "#1"); Serialize (new SimpleEnumeration ()); Assert.AreEqual (Infoset ("FIRST"), WriterText, "#2"); Serialize (3, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("e3"), WriterText, "#3"); Serialize (EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("e3"), WriterText, "#4"); Serialize (EnumDefaultValue.e1 | EnumDefaultValue.e2, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("e3"), WriterText, "#5"); Serialize (EnumDefaultValue.e1 | EnumDefaultValue.e2 | EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("e3"), WriterText, "#6"); Serialize (EnumDefaultValue.e1 | EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("e3"), WriterText, "#7"); Serialize (EnumDefaultValue.e2 | EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("e3"), WriterText, "#8"); Serialize (3, typeof (FlagEnum)); Assert.AreEqual (Infoset ("one two"), WriterText, "#9"); Serialize (5, typeof (FlagEnum)); Assert.AreEqual (Infoset ("one four"), WriterText, "#10"); Serialize (FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (Infoset ("four"), WriterText, "#11"); Serialize (FlagEnum.e1 | FlagEnum.e2, typeof (FlagEnum)); Assert.AreEqual (Infoset ("one two"), WriterText, "#12"); Serialize (FlagEnum.e1 | FlagEnum.e2 | FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (Infoset ("one two four"), WriterText, "#13"); Serialize (FlagEnum.e1 | FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (Infoset ("one four"), WriterText, "#14"); Serialize (FlagEnum.e2 | FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (Infoset ("two four"), WriterText, "#15"); Serialize (3, typeof (EnumDefaultValueNF)); Assert.AreEqual (Infoset ("e3"), WriterText, "#16"); Serialize (EnumDefaultValueNF.e2, typeof (EnumDefaultValueNF)); Assert.AreEqual (Infoset ("e2"), WriterText, "#17"); Serialize (2, typeof (ZeroFlagEnum)); Assert.AreEqual (Infoset ("tns:t<w>o"), WriterText, "#18"); Serialize (new ZeroFlagEnum ()); // enum actually has a field with value 0 Assert.AreEqual (Infoset ("zero"), WriterText, "#19"); } [Test] [Category ("NotWorking")] public void TestSerializeEnumDefaultValue_Encoded () { SerializeEncoded (new EnumDefaultValue ()); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "", XmlSchemaInstanceNamespace), sw.ToString (), "#1"); SerializeEncoded (new SimpleEnumeration ()); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "FIRST", XmlSchemaInstanceNamespace), sw.ToString (), "#2"); SerializeEncoded (3, typeof (EnumDefaultValue)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#3"); SerializeEncoded (EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#4"); SerializeEncoded (EnumDefaultValue.e1 | EnumDefaultValue.e2, typeof (EnumDefaultValue)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#5"); SerializeEncoded (EnumDefaultValue.e1 | EnumDefaultValue.e2 | EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#6"); SerializeEncoded (EnumDefaultValue.e1 | EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#7"); SerializeEncoded (EnumDefaultValue.e2 | EnumDefaultValue.e3, typeof (EnumDefaultValue)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#8"); SerializeEncoded (3, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e1 e2", XmlSchemaInstanceNamespace), sw.ToString (), "#9"); SerializeEncoded (5, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e1 e4", XmlSchemaInstanceNamespace), sw.ToString (), "#10"); SerializeEncoded (FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e4", XmlSchemaInstanceNamespace), sw.ToString (), "#11"); SerializeEncoded (FlagEnum.e1 | FlagEnum.e2, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e1 e2", XmlSchemaInstanceNamespace), sw.ToString (), "#12"); SerializeEncoded (FlagEnum.e1 | FlagEnum.e2 | FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e1 e2 e4", XmlSchemaInstanceNamespace), sw.ToString (), "#13"); SerializeEncoded (FlagEnum.e1 | FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e1 e4", XmlSchemaInstanceNamespace), sw.ToString (), "#14"); SerializeEncoded (FlagEnum.e2 | FlagEnum.e4, typeof (FlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e2 e4", XmlSchemaInstanceNamespace), sw.ToString (), "#15"); SerializeEncoded (3, typeof (EnumDefaultValueNF)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e3", XmlSchemaInstanceNamespace), sw.ToString (), "#16"); SerializeEncoded (EnumDefaultValueNF.e2, typeof (EnumDefaultValueNF)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e2", XmlSchemaInstanceNamespace), sw.ToString (), "#17"); SerializeEncoded (2, typeof (ZeroFlagEnum)); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e2", XmlSchemaInstanceNamespace), sw.ToString (), "#18"); SerializeEncoded (new ZeroFlagEnum ()); // enum actually has a field with value 0 Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + "e0", XmlSchemaInstanceNamespace), sw.ToString (), "#19"); } [Test] public void TestSerializeEnumDefaultValue_InvalidValue1 () { try { Serialize ("b", typeof (EnumDefaultValue)); Assert.Fail ("#A1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#A2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#A3"); } try { Serialize ("e1", typeof (EnumDefaultValue)); Assert.Fail ("#B1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#B2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#B3"); } try { Serialize ("e1,e2", typeof (EnumDefaultValue)); Assert.Fail ("#C1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#C2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#C3"); } try { Serialize (string.Empty, typeof (EnumDefaultValue)); Assert.Fail ("#D1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#D2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#D3"); } try { Serialize ("1", typeof (EnumDefaultValue)); Assert.Fail ("#E1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#E2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#E3"); } try { Serialize ("0", typeof (EnumDefaultValue)); Assert.Fail ("#F1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#F2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#F3"); } try { Serialize (new SimpleClass (), typeof (EnumDefaultValue)); Assert.Fail ("#G1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#G2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#G3"); } } [Test] public void TestSerializeEnumDefaultValue_InvalidValue2 () { #if NET_2_0 try { Serialize (5, typeof (EnumDefaultValue)); Assert.Fail ("#1"); } catch (InvalidOperationException ex) { Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); Assert.IsNotNull (ex.InnerException, "#3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#4"); Assert.IsNotNull (ex.InnerException.Message, "#5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("'5'") != -1, "#6"); Assert.IsTrue (ex.InnerException.Message.IndexOf (typeof (EnumDefaultValue).FullName) != -1, "#7"); } #else Serialize (5, typeof (EnumDefaultValue)); Assert.AreEqual (Infoset ("5"), WriterText); #endif } [Test] public void TestSerializeEnumDefaultValueNF_InvalidValue1 () { #if NET_2_0 try { Serialize (new EnumDefaultValueNF ()); Assert.Fail ("#1"); } catch (InvalidOperationException ex) { Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); Assert.IsNotNull (ex.InnerException, "#3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#4"); Assert.IsNotNull (ex.InnerException.Message, "#5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("'0'") != -1, "#6"); Assert.IsTrue (ex.InnerException.Message.IndexOf (typeof (EnumDefaultValueNF).FullName) != -1, "#7"); } #else Serialize (new EnumDefaultValueNF ()); Assert.AreEqual (Infoset ("0"), WriterText); #endif } [Test] public void TestSerializeEnumDefaultValueNF_InvalidValue2 () { #if NET_2_0 try { Serialize (15, typeof (EnumDefaultValueNF)); Assert.Fail ("#1"); } catch (InvalidOperationException ex) { Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); Assert.IsNotNull (ex.InnerException, "#3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#4"); Assert.IsNotNull (ex.InnerException.Message, "#5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("'15'") != -1, "#6"); Assert.IsTrue (ex.InnerException.Message.IndexOf (typeof (EnumDefaultValueNF).FullName) != -1, "#7"); } #else Serialize (15, typeof (EnumDefaultValueNF)); Assert.AreEqual (Infoset ("15"), WriterText); #endif } [Test] public void TestSerializeEnumDefaultValueNF_InvalidValue3 () { try { Serialize ("b", typeof (EnumDefaultValueNF)); Assert.Fail ("#A1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#A2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#A3"); } try { Serialize ("e2", typeof (EnumDefaultValueNF)); Assert.Fail ("#B1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#B2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#B3"); } try { Serialize (string.Empty, typeof (EnumDefaultValueNF)); Assert.Fail ("#C1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#C2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#C3"); } try { Serialize ("1", typeof (EnumDefaultValueNF)); Assert.Fail ("#D1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#D2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#D3"); } try { Serialize ("0", typeof (EnumDefaultValueNF)); Assert.Fail ("#E1"); } catch (InvalidOperationException ex) { Assert.IsNotNull (ex.InnerException, "#E2"); Assert.AreEqual (typeof (InvalidCastException), ex.InnerException.GetType (), "#E3"); } } [Test] public void TestSerializeZeroFlagEnum_InvalidValue () { #if NET_2_0 try { Serialize (4, typeof (ZeroFlagEnum)); // corresponding enum field is marked XmlIgnore Assert.Fail ("#1"); } catch (InvalidOperationException ex) { Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); Assert.IsNotNull (ex.InnerException, "#3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#4"); Assert.IsNotNull (ex.InnerException.Message, "#5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("'4'") != -1, "#6"); Assert.IsTrue (ex.InnerException.Message.IndexOf (typeof (ZeroFlagEnum).FullName) != -1, "#7"); } #else Serialize (4, typeof (ZeroFlagEnum)); // corresponding enum field is marked XmlIgnore Assert.AreEqual (Infoset ("4"), WriterText); #endif } [Test] public void TestSerializeQualifiedName() { Serialize(new XmlQualifiedName("me", "home.urn")); Assert.AreEqual (Infoset ("q1:me"), WriterText); } [Test] public void TestSerializeBytes() { Serialize((byte)0xAB); Assert.AreEqual (Infoset ("171"), WriterText); Serialize((byte)15); Assert.AreEqual (Infoset ("15"), WriterText); } [Test] public void TestSerializeByteArrays() { Serialize(new byte[] {}); Assert.AreEqual (Infoset (""), WriterText); Serialize(new byte[] {0xAB, 0xCD}); Assert.AreEqual (Infoset ("q80="), WriterText); } [Test] public void TestSerializeDateTime() { DateTime d = new DateTime(); Serialize(d); TimeZone tz = TimeZone.CurrentTimeZone; TimeSpan off = tz.GetUtcOffset (d); string sp = string.Format ("{0}{1:00}:{2:00}", off.Ticks >= 0 ? "+" : "", off.Hours, off.Minutes); Assert.AreEqual (Infoset ("0001-01-01T00:00:00.0000000" + sp + ""), WriterText); } /* FIXME - decimal - Guid - XmlNode objects [Test] public void TestSerialize() { Serialize(); Assert.AreEqual (WriterText, ""); } */ // test basic class serialization ///////////////////////////////////// [Test] public void TestSerializeSimpleClass() { SimpleClass simple = new SimpleClass(); Serialize(simple); Assert.AreEqual (Infoset (""), WriterText); simple.something = "hello"; Serialize(simple); Assert.AreEqual (Infoset ("hello"), WriterText); } [Test] public void TestSerializeStringCollection() { StringCollection strings = new StringCollection(); Serialize(strings); Assert.AreEqual (Infoset (""), WriterText); strings.Add("hello"); strings.Add("goodbye"); Serialize(strings); Assert.AreEqual (Infoset ("hellogoodbye"), WriterText); } [Test] public void TestSerializePlainContainer() { StringCollectionContainer container = new StringCollectionContainer(); Serialize(container); Assert.AreEqual (Infoset (""), WriterText); container.Messages.Add("hello"); container.Messages.Add("goodbye"); Serialize(container); Assert.AreEqual (Infoset ("hellogoodbye"), WriterText); } [Test] public void TestSerializeArrayContainer() { ArrayContainer container = new ArrayContainer(); Serialize(container); Assert.AreEqual (Infoset (""), WriterText); container.items = new object[] {10, 20}; Serialize(container); Assert.AreEqual (Infoset ("1020"), WriterText); container.items = new object[] {10, "hello"}; Serialize(container); Assert.AreEqual (Infoset ("10hello"), WriterText); } [Test] public void TestSerializeClassArrayContainer() { ClassArrayContainer container = new ClassArrayContainer(); Serialize(container); Assert.AreEqual (Infoset (""), WriterText); SimpleClass simple1 = new SimpleClass(); simple1.something = "hello"; SimpleClass simple2 = new SimpleClass(); simple2.something = "hello"; container.items = new SimpleClass[2]; container.items[0] = simple1; container.items[1] = simple2; Serialize(container); Assert.AreEqual (Infoset ("hellohello"), WriterText); } // test basic attributes /////////////////////////////////////////////// [Test] public void TestSerializeSimpleClassWithXmlAttributes() { SimpleClassWithXmlAttributes simple = new SimpleClassWithXmlAttributes(); Serialize(simple); Assert.AreEqual (Infoset (""), WriterText); simple.something = "hello"; Serialize(simple); Assert.AreEqual (Infoset (""), WriterText); } // test overrides /////////////////////////////////////////////////////// [Test] public void TestSerializeSimpleClassWithOverrides() { // Also tests XmlIgnore XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes attr = new XmlAttributes(); attr.XmlIgnore = true; overrides.Add(typeof(SimpleClassWithXmlAttributes), "something", attr); SimpleClassWithXmlAttributes simple = new SimpleClassWithXmlAttributes(); simple.something = "hello"; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeSchema () { XmlSchema schema = new XmlSchema (); schema.Items.Add (new XmlSchemaAttribute ()); schema.Items.Add (new XmlSchemaAttributeGroup ()); schema.Items.Add (new XmlSchemaComplexType ()); schema.Items.Add (new XmlSchemaNotation ()); schema.Items.Add (new XmlSchemaSimpleType ()); schema.Items.Add (new XmlSchemaGroup ()); schema.Items.Add (new XmlSchemaElement ()); StringWriter sw = new StringWriter (); XmlTextWriter xtw = new XmlTextWriter (sw); xtw.QuoteChar = '\''; xtw.Formatting = Formatting.Indented; XmlSerializer xs = new XmlSerializer (schema.GetType ()); xs.Serialize (xtw, schema); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "{0}" + "{0}" + " {0}" + " {0}" + " {0}" + " {0}" + " {0}" + " {0}" + " {0}" + "", Environment.NewLine), sw.ToString ()); } // test xmlText ////////////////////////////////////////////////////////// [Test] public void TestSerializeXmlTextAttribute() { SimpleClass simple = new SimpleClass(); simple.something = "hello"; XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes attr = new XmlAttributes(); overrides.Add(typeof(SimpleClass), "something", attr); attr.XmlText = new XmlTextAttribute(); Serialize(simple, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#1"); attr.XmlText = new XmlTextAttribute(typeof(string)); Serialize(simple, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#2"); try { attr.XmlText = new XmlTextAttribute(typeof(byte[])); Serialize(simple, overrides); Assert.Fail("XmlText.Type does not match the type it serializes: this should have failed"); } catch (InvalidOperationException ex) { // FIXME /* // there was an error reflecting type 'MonoTests.System.Xml.TestClasses.SimpleClass'. Assert.IsNotNull (ex.Message, "#A1"); Assert.IsTrue (ex.Message.IndexOf (typeof (SimpleClass).FullName) != -1, "#A2"); // there was an error reflecting field 'something'. Assert.IsNotNull (ex.InnerException, "#A3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#A4"); Assert.IsNotNull (ex.InnerException.Message, "#A5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("something") != -1, "#A6"); // the type for XmlText may not be specified for primitive types. Assert.IsNotNull (ex.InnerException.InnerException, "#A7"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#A8"); Assert.IsNotNull (ex.InnerException.Message, "#A9"); Assert.IsNull (ex.InnerException.InnerException.InnerException, "#A10"); */ } try { attr.XmlText = new XmlTextAttribute(); attr.XmlText.DataType = "sometype"; Serialize(simple, overrides); Assert.Fail("XmlText.DataType does not match the type it serializes: this should have failed"); } catch (InvalidOperationException ex) { // there was an error reflecting type 'MonoTests.System.Xml.TestClasses.SimpleClass'. Assert.IsNotNull (ex.Message, "#B1"); Assert.IsTrue (ex.Message.IndexOf (typeof (SimpleClass).FullName) != -1, "#B2"); // there was an error reflecting field 'something'. Assert.IsNotNull (ex.InnerException, "#B3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#B4"); Assert.IsNotNull (ex.InnerException.Message, "#B5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("something") != -1, "#B6"); // there was an error reflecting type 'System.String'. Assert.IsNotNull (ex.InnerException.InnerException, "#B7"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.InnerException.GetType (), "#B8"); Assert.IsNotNull (ex.InnerException.InnerException.Message, "#B9"); Assert.IsTrue (ex.InnerException.InnerException.Message.IndexOf (typeof (string).FullName) != -1, "#B10"); // Value 'sometype' cannot be used for the XmlElementAttribute.DataType property. // The datatype 'http://www.w3.org/2001/XMLSchema:sometype' is missing. Assert.IsNotNull (ex.InnerException.InnerException.InnerException, "#B11"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.InnerException.InnerException.GetType (), "#B12"); Assert.IsNotNull (ex.InnerException.InnerException.InnerException.Message, "#B13"); Assert.IsTrue (ex.InnerException.InnerException.InnerException.Message.IndexOf ("http://www.w3.org/2001/XMLSchema:sometype") != -1, "#B14"); } catch (NotSupportedException ex) { // FIXME: we should report InvalidOperationException } } // test xmlRoot ////////////////////////////////////////////////////////// [Test] public void TestSerializeXmlRootAttribute() { // constructor override & element name XmlRootAttribute root = new XmlRootAttribute(); root.ElementName = "renamed"; SimpleClassWithXmlAttributes simpleWithAttributes = new SimpleClassWithXmlAttributes(); Serialize(simpleWithAttributes, root); Assert.AreEqual (Infoset (""), WriterText); SimpleClass simple = null; root.IsNullable = false; try { Serialize(simple, root); Assert.Fail("Cannot serialize null object if XmlRoot's IsNullable == false"); } catch (NullReferenceException) { } root.IsNullable = true; try { Serialize(simple, root); Assert.Fail("Cannot serialize null object if XmlRoot's IsNullable == true"); } catch (NullReferenceException) { } simple = new SimpleClass(); root.ElementName = null; root.Namespace = "some.urn"; Serialize(simple, root); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeXmlRootAttributeOnMember() { // nested root XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes childAttr = new XmlAttributes(); childAttr.XmlRoot = new XmlRootAttribute("simple"); overrides.Add(typeof(SimpleClass), childAttr); XmlAttributes attr = new XmlAttributes(); attr.XmlRoot = new XmlRootAttribute("simple"); overrides.Add(typeof(ClassArrayContainer), attr); ClassArrayContainer container = new ClassArrayContainer(); container.items = new SimpleClass[1]; container.items[0] = new SimpleClass(); Serialize(container, overrides); Assert.AreEqual (Infoset (""), WriterText); // FIXME test data type } // test XmlAttribute ///////////////////////////////////////////////////// [Test] public void TestSerializeXmlAttributeAttribute() { // null XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes attr = new XmlAttributes(); attr.XmlAttribute = new XmlAttributeAttribute(); overrides.Add(typeof(SimpleClass), "something", attr); SimpleClass simple = new SimpleClass();; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#1"); // regular simple.something = "hello"; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#2"); // AttributeName attr.XmlAttribute.AttributeName = "somethingelse"; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#3"); // Type // FIXME this should work, shouldnt it? // attr.XmlAttribute.Type = typeof(string); // Serialize(simple, overrides); // Assert(WriterText.EndsWith(" something='hello' />")); // Namespace attr.XmlAttribute.Namespace = "some:urn"; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#4"); // FIXME DataType // FIXME XmlSchemaForm Form // FIXME write XmlQualifiedName as attribute } // test XmlElement /////////////////////////////////////////////////////// [Test] public void TestSerializeXmlElementAttribute() { XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes attr = new XmlAttributes(); XmlElementAttribute element = new XmlElementAttribute(); attr.XmlElements.Add(element); overrides.Add(typeof(SimpleClass), "something", attr); // null SimpleClass simple = new SimpleClass();; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#1"); // not null simple.something = "hello"; Serialize(simple, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#2"); //ElementName element.ElementName = "saying"; Serialize(simple, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#3"); //IsNullable element.IsNullable = false; simple.something = null; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#4"); element.IsNullable = true; simple.something = null; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#5"); //Namespace element.ElementName = null; element.IsNullable = false; element.Namespace = "some:urn"; simple.something = "hello"; Serialize(simple, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#6"); //FIXME DataType //FIXME Form //FIXME Type } // test XmlElementAttribute with arrays and collections ////////////////// [Test] public void TestSerializeCollectionWithXmlElementAttribute() { // the rule is: // if no type is specified or the specified type // matches the contents of the collection, // serialize each element in an element named after the member. // if the type does not match, or matches the collection itself, // create a base wrapping element for the member, and then // wrap each collection item in its own wrapping element based on type. XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes attr = new XmlAttributes(); XmlElementAttribute element = new XmlElementAttribute(); attr.XmlElements.Add(element); overrides.Add(typeof(StringCollectionContainer), "Messages", attr); // empty collection & no type info in XmlElementAttribute StringCollectionContainer container = new StringCollectionContainer(); Serialize(container, overrides); Assert.AreEqual (Infoset (""), WriterText, "#1"); // non-empty collection & no type info in XmlElementAttribute container.Messages.Add("hello"); Serialize(container, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#2"); // non-empty collection & only type info in XmlElementAttribute element.Type = typeof(StringCollection); Serialize(container, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#3"); // non-empty collection & only type info in XmlElementAttribute element.Type = typeof(string); Serialize(container, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#4"); // two elements container.Messages.Add("goodbye"); element.Type = null; Serialize(container, overrides); Assert.AreEqual (Infoset ("hellogoodbye"), WriterText, "#5"); } // test DefaultValue ///////////////////////////////////////////////////// [Test] public void TestSerializeDefaultValueAttribute() { XmlAttributeOverrides overrides = new XmlAttributeOverrides(); XmlAttributes attr = new XmlAttributes(); string defaultValueInstance = "nothing"; attr.XmlDefaultValue = defaultValueInstance; overrides.Add(typeof(SimpleClass), "something", attr); // use the default SimpleClass simple = new SimpleClass(); Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#1"); // same value as default simple.something = defaultValueInstance; Serialize(simple, overrides); Assert.AreEqual (Infoset (""), WriterText, "#2"); // some other value simple.something = "hello"; Serialize(simple, overrides); Assert.AreEqual (Infoset ("hello"), WriterText, "#3"); } // test XmlEnum ////////////////////////////////////////////////////////// [Test] public void TestSerializeXmlEnumAttribute() { Serialize(XmlSchemaForm.Qualified); Assert.AreEqual (Infoset ("qualified"), WriterText, "#1"); Serialize(XmlSchemaForm.Unqualified); Assert.AreEqual (Infoset ("unqualified"), WriterText, "#2"); } [Test] public void TestSerializeXmlEnumAttribute_IgnoredValue () { // technically XmlSchemaForm.None has an XmlIgnore attribute, // but it is not being serialized as a member. #if NET_2_0 try { Serialize (XmlSchemaForm.None); Assert.Fail ("#1"); } catch (InvalidOperationException ex) { Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); Assert.IsNotNull (ex.InnerException, "#3"); Assert.AreEqual (typeof (InvalidOperationException), ex.InnerException.GetType (), "#4"); Assert.IsNotNull (ex.InnerException.Message, "#5"); Assert.IsTrue (ex.InnerException.Message.IndexOf ("'0'") != -1, "#6"); Assert.IsTrue (ex.InnerException.Message.IndexOf (typeof (XmlSchemaForm).FullName) != -1, "#7"); } #else Serialize (XmlSchemaForm.None); Assert.AreEqual (Infoset ("0"), WriterText); #endif } [Test] public void TestSerializeXmlNodeArray () { XmlDocument doc = new XmlDocument (); Serialize (new XmlNode [] { doc.CreateAttribute("at"), doc.CreateElement("elem1"), doc.CreateElement("elem2") }, typeof(object)); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeXmlElement () { XmlDocument doc = new XmlDocument (); Serialize (doc.CreateElement("elem"), typeof(XmlElement)); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeXmlElementSubclass () { XmlDocument doc = new XmlDocument (); Serialize (new MyElem (doc), typeof(XmlElement)); Assert.AreEqual (Infoset (""), WriterText, "#1"); Serialize (new MyElem (doc), typeof(MyElem)); Assert.AreEqual (Infoset (""), WriterText, "#2"); } [Test] public void TestSerializeXmlCDataSection () { XmlDocument doc = new XmlDocument (); CDataContainer c = new CDataContainer (); c.cdata = doc.CreateCDataSection("data section contents"); Serialize (c); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeXmlNode () { XmlDocument doc = new XmlDocument (); NodeContainer c = new NodeContainer (); c.node = doc.CreateTextNode("text"); Serialize (c); Assert.AreEqual (Infoset ("text"), WriterText); } [Test] public void TestSerializeChoice () { Choices ch = new Choices (); ch.MyChoice = "choice text"; ch.ItemType = ItemChoiceType.ChoiceZero; Serialize (ch); Assert.AreEqual (Infoset ("choice text"), WriterText, "#1"); ch.ItemType = ItemChoiceType.StrangeOne; Serialize (ch); Assert.AreEqual (Infoset ("choice text"), WriterText, "#2"); ch.ItemType = ItemChoiceType.ChoiceTwo; Serialize (ch); Assert.AreEqual (Infoset ("choice text"), WriterText, "#3"); } [Test] public void TestSerializeNamesWithSpaces () { TestSpace ts = new TestSpace(); ts.elem = 4; ts.attr = 5; Serialize (ts); Assert.AreEqual (Infoset ("4"), WriterText); } [Test] public void TestSerializeReadOnlyProps () { ReadOnlyProperties ts = new ReadOnlyProperties(); Serialize (ts); Assert.AreEqual (Infoset (""), WriterText); } [Test] public void TestSerializeIList() { clsPerson k = new clsPerson(); k.EmailAccounts = new ArrayList(); k.EmailAccounts.Add("a"); k.EmailAccounts.Add("b"); Serialize (k); Assert.AreEqual (Infoset ("ab"), WriterText); } [Test] public void TestSerializeArrayEnc () { SoapReflectionImporter imp = new SoapReflectionImporter (); XmlTypeMapping map = imp.ImportTypeMapping (typeof(ArrayClass)); XmlSerializer ser = new XmlSerializer (map); StringWriter sw = new StringWriter (); XmlTextWriter tw = new XmlTextWriter (sw); tw.WriteStartElement ("aa"); ser.Serialize (tw, new ArrayClass ()); tw.WriteEndElement (); } [Test] public void TestIncludeType() { // Test for bug #76049 XmlReflectionImporter imp = new XmlReflectionImporter (); XmlTypeMapping map = imp.ImportTypeMapping (typeof(object)); imp.IncludeType (typeof(TestSpace)); XmlSerializer ser = new XmlSerializer (map); ser.Serialize (new StringWriter (), new TestSpace ()); } [Test] public void TestSerializeChoiceArray() { CompositeValueType v = new CompositeValueType (); v.Init (); Serialize (v); Assert.AreEqual (Infoset ("12"), WriterText); } [Test] public void TestArrayAttributeWithDataType () { Serialize (new ArrayAttributeWithType ()); string res = ""; Assert.AreEqual (Infoset (res), WriterText); } [Test] [ExpectedException (typeof(InvalidOperationException))] public void TestArrayAttributeWithWrongDataType () { Serialize (new ArrayAttributeWithWrongType ()); } [Test] [Category ("NotWorking")] public void TestSerializePrimitiveTypesContainer () { Serialize (new PrimitiveTypesContainer ()); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + #if NET_2_0 "" + #else "" + #endif "2004" + "some name" + "56" + "8w8=" + "47" + "", XmlSchemaNamespace, XmlSchemaInstanceNamespace), sw.ToString (), "#1"); SerializeEncoded (new PrimitiveTypesContainer ()); Assert.AreEqual (string.Format (CultureInfo.InvariantCulture, "" + #if NET_2_0 "" + #else "" + #endif "2004" + "some name" + "56" + "8w8=" + "47" + "", XmlSchemaNamespace, XmlSchemaInstanceNamespace, AnotherNamespace, WsdlTypesNamespace), sw.ToString (), "#2"); } [Test] public void TestSchemaForm () { TestSchemaForm1 t1 = new TestSchemaForm1 (); t1.p1 = new PrintTypeResponse (); t1.p1.Init (); t1.p2 = new PrintTypeResponse (); t1.p2.Init (); TestSchemaForm2 t2 = new TestSchemaForm2 (); t2.p1 = new PrintTypeResponse (); t2.p1.Init (); t2.p2 = new PrintTypeResponse (); t2.p2.Init (); Serialize (t1); string res = ""; res += ""; res += ""; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += ""; Assert.AreEqual (Infoset (res), WriterText); Serialize (t2); res = ""; res += ""; res += ""; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += ""; Assert.AreEqual (Infoset (res), WriterText); XmlReflectionImporter imp = new XmlReflectionImporter (); XmlTypeMapping map = imp.ImportTypeMapping (typeof(TestSchemaForm1), "urn:extra"); Serialize (t1, map); res = ""; res += ""; res += ""; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += ""; Assert.AreEqual (Infoset (res), WriterText); imp = new XmlReflectionImporter (); map = imp.ImportTypeMapping (typeof(TestSchemaForm2), "urn:extra"); Serialize (t2, map); res = ""; res += ""; res += ""; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += " "; res += " "; res += " data1"; res += " "; res += " "; res += " "; res += " data2"; res += " "; res += " "; res += " "; res += ""; Assert.AreEqual (Infoset (res), WriterText); } // Helper methods public static string Infoset (string sx) { XmlDocument doc = new XmlDocument (); doc.LoadXml (sx); StringBuilder sb = new StringBuilder (); GetInfoset (doc.DocumentElement, sb); return sb.ToString (); } public static string Infoset (XmlNode nod) { StringBuilder sb = new StringBuilder (); GetInfoset (nod, sb); return sb.ToString (); } static void GetInfoset (XmlNode nod, StringBuilder sb) { switch (nod.NodeType) { case XmlNodeType.Attribute: if (nod.LocalName == "xmlns" && nod.NamespaceURI == "http://www.w3.org/2000/xmlns/") return; sb.Append (" " + nod.NamespaceURI + ":" + nod.LocalName + "='" + nod.Value + "'"); break; case XmlNodeType.Element: XmlElement elem = (XmlElement) nod; sb.Append ("<" + elem.NamespaceURI + ":" + elem.LocalName); ArrayList ats = new ArrayList (); foreach (XmlAttribute at in elem.Attributes) ats.Add (at.LocalName + " " + at.NamespaceURI); ats.Sort (); foreach (string name in ats) { string[] nn = name.Split (' '); GetInfoset (elem.Attributes[nn[0],nn[1]], sb); } sb.Append (">"); foreach (XmlNode cn in elem.ChildNodes) GetInfoset (cn, sb); sb.Append (""); break; default: sb.Append (nod.OuterXml); break; } } static XmlTypeMapping CreateSoapMapping (Type type) { SoapReflectionImporter importer = new SoapReflectionImporter (); return importer.ImportTypeMapping (type); } } }