Merge pull request #1196 from tritao/master
[mono.git] / mcs / class / System.XML / Test / System.Xml.Serialization / XmlSerializerTests.cs
index ad92655ca046f2d24616e4486bc30f2c3ca06ce0..e9a161c6e3fd422f3153cc489f51483e564a02be 100644 (file)
@@ -31,6 +31,7 @@ using System.Globalization;
 using System.IO;
 using System.Text;
 using System.Xml;
+using System.Data;
 using System.Xml.Schema;
 using System.Xml.Serialization;
 #if NET_2_0
@@ -1807,6 +1808,23 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (Infoset ("<anyType at=\"\"><elem1/><elem2/></anyType>"), WriterText);
                }
 
+               [Test]
+               public void TestSerializeXmlNodeArray2 ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       Serialize (new XmlNode[] { doc.CreateElement ("elem1"), doc.CreateElement ("elem2") }, typeof (XmlNode []));
+                       Assert.AreEqual (Infoset (String.Format ("<ArrayOfXmlNode xmlns:xsd='{0}' xmlns:xsi='{1}'><XmlNode><elem1/></XmlNode><XmlNode><elem2/></XmlNode></ArrayOfXmlNode>", XmlSchema.Namespace, XmlSchema.InstanceNamespace)), WriterText);
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               [Category ("NotWorking")]
+               public void TestSerializeXmlNodeArrayIncludesAttribute ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       Serialize (new XmlNode[] { doc.CreateAttribute ("at"), doc.CreateElement ("elem1"), doc.CreateElement ("elem2") }, typeof (XmlNode []));
+               }
+
                [Test]
                public void TestSerializeXmlElementArray ()
                {
@@ -1834,6 +1852,15 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (Infoset ("<anyType><elem1/><elem2/></anyType>"), WriterText);
                }
 #endif
+               [Test]
+               public void TestSerializeXmlDocument ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       doc.LoadXml (@"<?xml version=""1.0"" encoding=""utf-8"" ?><root/>");
+                       Serialize (doc, typeof (XmlDocument));
+                       Assert.AreEqual ("<?xml version='1.0' encoding='utf-16'?><root />",
+                               sw.GetStringBuilder ().ToString ());
+               }
 
                [Test]
                public void TestSerializeXmlElement ()
@@ -1908,6 +1935,15 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (Infoset ("<ReadOnlyProperties xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' />"), WriterText);
                }
 
+               [Test]
+               public void TestSerializeReadOnlyListProp ()
+               {
+                       ReadOnlyListProperty ts = new ReadOnlyListProperty ();
+                       Serialize (ts);
+                       Assert.AreEqual (Infoset ("<ReadOnlyListProperty xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><StrList><string>listString1</string><string>listString2</string></StrList></ReadOnlyListProperty>"), WriterText);
+               }
+
+
                [Test]
                public void TestSerializeIList ()
                {
@@ -2160,8 +2196,7 @@ namespace MonoTests.System.XmlSerialization
                        ser.Deserialize (new XmlTextReader (xml, XmlNodeType.Document, null));
                }
 
-#if NET_2_0
-#if !TARGET_JVM
+#if !TARGET_JVM && !MOBILE
                [Test]
                public void GenerateSerializerGenerics ()
                {
@@ -2187,7 +2222,58 @@ namespace MonoTests.System.XmlSerialization
                        int? i = (int?) ser.Deserialize (new StringReader (sw.ToString ()));
                        Assert.AreEqual (5, i);
                }
-#endif
+
+               [Test]
+               public void NullableEnums ()
+               {
+                       WithNulls w = new WithNulls ();
+                       XmlSerializer ser = new XmlSerializer (typeof(WithNulls));
+                       StringWriter tw = new StringWriter ();
+                       ser.Serialize (tw, w);
+
+                       string expected = "<?xml version='1.0' encoding='utf-16'?>" +
+                               "<WithNulls xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
+                                       "<nint xsi:nil='true' />" +
+                                       "<nenum xsi:nil='true' />" +
+                                       "<ndate xsi:nil='true' />" +
+                                       "</WithNulls>";
+                       
+                       Assert.AreEqual (Infoset (expected), Infoset (tw.ToString ()));
+                       
+                       StringReader sr = new StringReader (tw.ToString ());
+                       w = (WithNulls) ser.Deserialize (sr);
+                       
+                       Assert.IsFalse (w.nint.HasValue);
+                       Assert.IsFalse (w.nenum.HasValue);
+                       Assert.IsFalse (w.ndate.HasValue);
+                       
+                       DateTime t = new DateTime (2008,4,1);
+                       w.nint = 4;
+                       w.ndate = t;
+                       w.nenum = TestEnumWithNulls.bb;
+                       
+                       tw = new StringWriter ();
+                       ser.Serialize (tw, w);
+                       
+                       expected = "<?xml version='1.0' encoding='utf-16'?>" +
+                               "<WithNulls xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
+                                       "<nint>4</nint>" +
+                                       "<nenum>bb</nenum>" +
+                                       "<ndate>2008-04-01T00:00:00</ndate>" +
+                                       "</WithNulls>";
+                       
+                       Assert.AreEqual (Infoset (expected), Infoset (tw.ToString ()));
+                       
+                       sr = new StringReader (tw.ToString ());
+                       w = (WithNulls) ser.Deserialize (sr);
+                       
+                       Assert.IsTrue (w.nint.HasValue);
+                       Assert.IsTrue (w.nenum.HasValue);
+                       Assert.IsTrue (w.ndate.HasValue);
+                       Assert.AreEqual (4, w.nint.Value);
+                       Assert.AreEqual (TestEnumWithNulls.bb, w.nenum.Value);
+                       Assert.AreEqual (t, w.ndate.Value);
+               }
 
                [Test]
                public void SerializeBase64Binary()
@@ -2265,6 +2351,104 @@ namespace MonoTests.System.XmlSerialization
                        Assert.AreEqual (Infoset (expected), WriterText);
                }
 
+               [Test] // bug #338705
+               public void SerializeTimeSpan ()
+               {
+                       // TimeSpan itself is not for duration. Hence it is just regarded as one of custom types.
+                       XmlSerializer ser = new XmlSerializer (typeof (TimeSpan));
+                       ser.Serialize (TextWriter.Null, TimeSpan.Zero);
+               }
+
+               [Test]
+               public void SerializeDurationToString ()
+               {
+                       XmlSerializer ser = new XmlSerializer (typeof (TimeSpanContainer1));
+                       ser.Serialize (TextWriter.Null, new TimeSpanContainer1 ());
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void SerializeDurationToTimeSpan ()
+               {
+                       XmlSerializer ser = new XmlSerializer (typeof (TimeSpanContainer2));
+                       ser.Serialize (TextWriter.Null, new TimeSpanContainer2 ());
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void SerializeInvalidDataType ()
+               {
+                       XmlSerializer ser = new XmlSerializer (typeof (InvalidTypeContainer));
+                       ser.Serialize (TextWriter.Null, new InvalidTypeContainer ());
+               }
+
+               [Test]
+#if !NET_2_0
+               [ExpectedException (typeof (ApplicationException))]
+#endif
+               public void SerializeErrorneousIXmlSerializable ()
+               {
+                       Serialize (new ErrorneousGetSchema ());
+                       Assert.AreEqual ("<:ErrorneousGetSchema></>", Infoset (sw.ToString ()));
+               }
+
+#if NET_2_0
+               public void DateTimeRoundtrip ()
+               {
+                       // bug #337729
+                       XmlSerializer ser = new XmlSerializer (typeof (DateTime));
+                       StringWriter sw = new StringWriter ();
+                       ser.Serialize (sw, DateTime.UtcNow);
+                       DateTime d = (DateTime) ser.Deserialize (new StringReader (sw.ToString ()));
+                       Assert.AreEqual (DateTimeKind.Utc, d.Kind);
+               }
+#endif
+
+               [Test]
+               public void SupportIXmlSerializableImplicitlyConvertible ()
+               {
+                       XmlAttributes attrs = new XmlAttributes ();
+                       XmlElementAttribute attr = new XmlElementAttribute ();
+                       attr.ElementName = "XmlSerializable";
+                       attr.Type = typeof (XmlSerializableImplicitConvertible.XmlSerializable);
+                       attrs.XmlElements.Add (attr);
+                       XmlAttributeOverrides attrOverrides = new
+                       XmlAttributeOverrides ();
+                       attrOverrides.Add (typeof (XmlSerializableImplicitConvertible), "B", attrs);
+
+                       XmlSerializableImplicitConvertible x = new XmlSerializableImplicitConvertible ();
+                       new XmlSerializer (typeof (XmlSerializableImplicitConvertible), attrOverrides).Serialize (TextWriter.Null, x);
+               }
+
+               [Test] // bug #566370
+               public void SerializeEnumWithCSharpKeyword ()
+               {
+                       var ser = new XmlSerializer (typeof (DoxCompoundKind));
+                       for (int i = 0; i < 100; i++) // test serialization code generator
+                               ser.Serialize (Console.Out, DoxCompoundKind.@class);
+               }
+
+               public enum DoxCompoundKind
+               {
+                       [XmlEnum("class")]
+                       @class,
+                       [XmlEnum("struct")]
+                       @struct,
+                       union,
+                       [XmlEnum("interface")]
+                       @interface,
+                       protocol,
+                       category,
+                       exception,
+                       file,
+                       [XmlEnum("namespace")]
+                       @namespace,
+                       group,
+                       page,
+                       example,
+                       dir
+               }
+
                #region GenericsSeralizationTests
 
 #if NET_2_0
@@ -2636,6 +2820,147 @@ namespace MonoTests.System.XmlSerialization
                        xs.Serialize (sw, PrivateCtorOnly.Instance);
                        xs.Deserialize (new StringReader (sw.ToString ()));
                }
+
+               [Test]
+               public void XmlSchemaProviderQNameBecomesRootName ()
+               {
+                       xs = new XmlSerializer (typeof (XmlSchemaProviderQNameBecomesRootNameType));
+                       Serialize (new XmlSchemaProviderQNameBecomesRootNameType ());
+                       Assert.AreEqual (Infoset ("<foo />"), WriterText);
+                       xs.Deserialize (new StringReader ("<foo/>"));
+               }
+
+               [Test]
+               public void XmlSchemaProviderQNameBecomesRootName2 ()
+               {
+                       string xml = "<XmlSchemaProviderQNameBecomesRootNameType2 xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><Foo><foo /></Foo></XmlSchemaProviderQNameBecomesRootNameType2>";
+                       xs = new XmlSerializer (typeof (XmlSchemaProviderQNameBecomesRootNameType2));
+                       Serialize (new XmlSchemaProviderQNameBecomesRootNameType2 ());
+                       Assert.AreEqual (Infoset (xml), WriterText);
+                       xs.Deserialize (new StringReader (xml));
+               }
+
+               [Test]
+               public void XmlAnyElementForObjects () // bug #553032
+               {
+                       new XmlSerializer (typeof (XmlAnyElementForObjectsType));
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void XmlAnyElementForObjects2 () // bug #553032-2
+               {
+                       new XmlSerializer (typeof (XmlAnyElementForObjectsType)).Serialize (TextWriter.Null, new XmlAnyElementForObjectsType ());
+               }
+
+
+               public class Bug2893 {
+                       public Bug2893 ()
+                       {                       
+                               Contents = new XmlDataDocument();
+                       }
+                       
+                       [XmlAnyElement("Contents")]
+                       public XmlNode Contents;
+               }
+
+               // Bug Xamarin #2893
+               [Test]
+               public void XmlAnyElementForXmlNode ()
+               {
+                       var obj = new Bug2893 ();
+                       XmlSerializer mySerializer = new XmlSerializer(typeof(Bug2893));
+                       XmlWriterSettings settings = new XmlWriterSettings();
+
+                       var xsn = new XmlSerializerNamespaces();
+                       xsn.Add(string.Empty, string.Empty);
+
+                       byte[] buffer = new byte[2048];
+                       var ms = new MemoryStream(buffer);
+                       using (var xw = XmlWriter.Create(ms, settings))
+                       {
+                               mySerializer.Serialize(xw, obj, xsn);
+                               xw.Flush();
+                       }
+
+                       mySerializer.Serialize(ms, obj);
+               }
+
+               [Test]
+               public void XmlRootOverridesSchemaProviderQName ()
+               {
+                       var obj = new XmlRootOverridesSchemaProviderQNameType ();
+
+                       XmlSerializer xs = new XmlSerializer (obj.GetType ());
+
+                       var sw = new StringWriter ();
+                       using (XmlWriter xw = XmlWriter.Create (sw))
+                               xs.Serialize (xw, obj);
+                       Assert.IsTrue (sw.ToString ().IndexOf ("foo") > 0, "#1");
+               }
+
+               public class AnotherArrayListType
+               {
+                       [XmlAttribute]
+                       public string one = "aaa";
+                       [XmlAttribute]
+                       public string another = "bbb";
+               }
+
+               public class DerivedArrayListType : AnotherArrayListType
+               {
+
+               }
+
+               public class ClassWithArrayList
+               {
+                       [XmlElement (Type = typeof(int), ElementName = "int_elem")]
+                       [XmlElement (Type = typeof(string), ElementName = "string_elem")]
+                       [XmlElement (Type = typeof(AnotherArrayListType), ElementName = "another_elem")]
+                       [XmlElement (Type = typeof(DerivedArrayListType), ElementName = "derived_elem")]
+                       public ArrayList list;
+               }
+
+               public class ClassWithArray
+               {
+                       [XmlElement (Type = typeof(int), ElementName = "int_elem")]
+                       [XmlElement (Type = typeof(string), ElementName = "string_elem")]
+                       [XmlElement (Type = typeof(AnotherArrayListType), ElementName = "another_elem")]
+                       [XmlElement (Type = typeof(DerivedArrayListType), ElementName = "derived_elem")]
+                       public object[] list;
+
+               }
+
+               [Test]
+               public void MultipleXmlElementAttributesOnArrayList()
+               {
+                       var test = new ClassWithArrayList();
+
+                       test.list = new ArrayList();
+                       test.list.Add(3);
+                       test.list.Add("apepe");
+                       test.list.Add(new AnotherArrayListType());
+                       test.list.Add(new DerivedArrayListType());
+
+                       Serialize(test);
+                       var expected_text = "<:ClassWithArrayList http://www.w3.org/2000/xmlns/:xsd='http://www.w3.org/2001/XMLSchema' http://www.w3.org/2000/xmlns/:xsi='http://www.w3.org/2001/XMLSchema-instance'><:int_elem>3</><:string_elem>apepe</><:another_elem :another='bbb' :one='aaa'></><:derived_elem :another='bbb' :one='aaa'></></>";
+
+                       Assert.AreEqual(WriterText, expected_text, WriterText);
+               }
+
+               [Test]
+               public void MultipleXmlElementAttributesOnArray()
+               {
+                       var test = new ClassWithArray();
+
+                       test.list = new object[] { 3, "apepe", new AnotherArrayListType(), new DerivedArrayListType() };
+
+                       Serialize(test);
+                       var expected_text = "<:ClassWithArray http://www.w3.org/2000/xmlns/:xsd='http://www.w3.org/2001/XMLSchema' http://www.w3.org/2000/xmlns/:xsi='http://www.w3.org/2001/XMLSchema-instance'><:int_elem>3</><:string_elem>apepe</><:another_elem :another='bbb' :one='aaa'></><:derived_elem :another='bbb' :one='aaa'></></>";
+
+                       Assert.AreEqual(WriterText, expected_text, WriterText);
+               }
+
 #endif
 
                #endregion //GenericsSeralizationTests
@@ -2717,6 +3042,24 @@ namespace MonoTests.System.XmlSerialization
                        public string Value;
                }
 
+               public class InvalidTypeContainer
+               {
+                       [XmlElement (DataType = "invalid")]
+                       public string InvalidTypeItem = "aaa";
+               }
+
+               public class TimeSpanContainer1
+               {
+                       [XmlElement (DataType = "duration")]
+                       public string StringDuration = "aaa";
+               }
+
+               public class TimeSpanContainer2
+               {
+                       [XmlElement (DataType = "duration")]
+                       public TimeSpan StringDuration = TimeSpan.FromSeconds (1);
+               }
+
 #if NET_2_0
                public class Bug80759
                {
@@ -2734,6 +3077,75 @@ namespace MonoTests.System.XmlSerialization
                                get { return NullableInt.HasValue; }
                        }
                }
+
+               [XmlSchemaProvider ("GetXsdType")]
+               public class XmlSchemaProviderQNameBecomesRootNameType : IXmlSerializable
+               {
+                       public XmlSchema GetSchema ()
+                       {
+                               return null;
+                       }
+
+                       public void ReadXml (XmlReader reader)
+                       {
+                               reader.Skip ();
+                       }
+
+                       public void WriteXml (XmlWriter writer)
+                       {
+                       }
+
+                       public static XmlQualifiedName GetXsdType (XmlSchemaSet xss)
+                       {
+                               if (xss.Count == 0) {
+                                       XmlSchema xs = new XmlSchema ();
+                                       XmlSchemaComplexType ct = new XmlSchemaComplexType ();
+                                       ct.Name = "foo";
+                                       xs.Items.Add (ct);
+                                       xss.Add (xs);
+                               }
+                               return new XmlQualifiedName ("foo");
+                       }
+               }
+
+               public class XmlSchemaProviderQNameBecomesRootNameType2
+               {
+                       [XmlArrayItem (typeof (XmlSchemaProviderQNameBecomesRootNameType))]
+                       public object [] Foo = new object [] {new XmlSchemaProviderQNameBecomesRootNameType ()};
+               }
+
+               public class XmlAnyElementForObjectsType
+               {
+                       [XmlAnyElement]
+                       public object [] arr = new object [] {3,4,5};
+               }
+
+               [XmlRoot ("foo")]
+               [XmlSchemaProvider ("GetSchema")]
+               public class XmlRootOverridesSchemaProviderQNameType : IXmlSerializable
+               {
+                       public static XmlQualifiedName GetSchema (XmlSchemaSet xss)
+                       {
+                               var xs = new XmlSchema ();
+                               var xse = new XmlSchemaComplexType () { Name = "bar" };
+                               xs.Items.Add (xse);
+                               xss.Add (xs);
+                               return new XmlQualifiedName ("bar");
+                       }
+
+                       XmlSchema IXmlSerializable.GetSchema ()
+                       {
+                               return null;
+                       }
+
+                       void IXmlSerializable.ReadXml (XmlReader reader)
+                       {
+                       }
+                       void IXmlSerializable.WriteXml (XmlWriter writer)
+                       {
+                       }
+               }
+
 #endif
 
                void CDataTextNodes_BadNode (object s, XmlNodeEventArgs e)