Add Dictionary reader test and made some fixes towards it.
authorAtsushi Eno <atsushi@ximian.com>
Tue, 19 Oct 2010 09:39:02 +0000 (18:39 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Tue, 19 Oct 2010 09:39:02 +0000 (18:39 +0900)
mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs
mcs/class/System.Xaml/System.Xaml/XamlType.cs
mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs
mcs/class/System.Xaml/Test/System.Xaml/XamlTypeTest.cs

index 8f0c471779049f9caf0f9287d704166b96a069df..d560769818ac22d1b889abbb7e31069b9320bc99 100644 (file)
@@ -394,8 +394,10 @@ namespace System.Xaml
                        // FIXME: should I use GetAllObjectReaderMembers()?
                        foreach (var xm in xt.GetAllMembers ()) {
                                ns = xm.PreferredXamlNamespace;
-                               if (xm is XamlDirective && ns == XamlLanguage.Xaml2006Namespace)
+                               if (xm is XamlDirective && ns == XamlLanguage.Xaml2006Namespace) {
+                                       CheckAddNamespace (d, ns);
                                        continue;
+                               }
                                if (!xm.IsReadPublic)
                                        continue;
                                if (xm.Type.IsCollection || xm.Type.IsDictionary || xm.Type.IsArray)
index af818a8ed295a66963ca73377f189fd693e8b089..c1e2dddf61b61a1b253d67f2ec5731439dead277 100644 (file)
@@ -375,11 +375,35 @@ namespace System.Xaml
 
                IEnumerable<XamlMember> DoLookupAllMembers ()
                {
-                       foreach (var pi in UnderlyingType.GetProperties (BindingFlags.Public | BindingFlags.Instance))
-                               if (pi.CanRead && pi.CanWrite && pi.GetIndexParameters ().Length == 0)
+                       // This is a hack that is likely required due to internal implementation difference in System.Uri. Our Uri has two readonly collection properties
+                       if (this == XamlLanguage.Uri)
+                               yield break;
+
+                       foreach (var pi in UnderlyingType.GetProperties (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
+                               if (pi.CanRead && (pi.CanWrite && pi.GetIndexParameters ().Length == 0 || IsCollectionType (pi.PropertyType)))
                                        yield return new XamlMember (pi, SchemaContext);
                }
 
+               static bool IsCollectionType (Type type)
+               {
+                       if (type.IsArray)
+                               return true;
+
+                       Type [] ifaces = type.GetInterfaces ();
+                       foreach (Type i in ifaces)
+                               if (i.IsGenericType && i.GetGenericTypeDefinition ().Equals (typeof (ICollection<>)))
+                                       return true;
+                       foreach (Type i in ifaces)
+                               if (i == typeof (IList))
+                                       return true;
+
+                       foreach (var iface in type.GetInterfaces ())
+                               if (iface == typeof (IDictionary) || (iface.IsGenericType && iface.GetGenericTypeDefinition () == typeof (IDictionary<,>)))
+                                       return true;
+
+                       return false;
+               }
+
                protected virtual IList<XamlType> LookupAllowedContentTypes ()
                {
                        // the actual implementation is very different from what is documented :(
index 7d6db50797624c8a1a89c8e91a04f6ef08eae9dd..e34d5be1d2039c882b93d4ecf2454df77b1a9608 100644 (file)
@@ -891,6 +891,83 @@ namespace MonoTests.System.Xaml
                        Assert.AreEqual ("bar", args [1], "#2");
                }
 
+               [Test]
+               [Category ("NotWorking")]
+               public void Read_Dictionary ()
+               {
+                       var obj = new Dictionary<string,object> ();
+                       obj ["Foo"] = 5.0;
+                       obj ["Bar"] = -6.5;
+                       var r = new XamlObjectReader (obj);
+
+                       Assert.IsTrue (r.Read (), "ns#1-1");
+                       Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "ns#1-2");
+                       Assert.IsNotNull (r.Namespace, "ns#1-3");
+                       Assert.AreEqual (String.Empty, r.Namespace.Prefix, "ns#1-4");
+                       Assert.AreEqual ("clr-namespace:System.Collections.Generic;assembly=mscorlib", r.Namespace.Namespace, "ns#1-5");
+
+                       Assert.IsTrue (r.Read (), "ns#2-1");
+                       Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "ns#2-2");
+                       Assert.IsNotNull (r.Namespace, "ns#2-3");
+                       Assert.AreEqual ("x", r.Namespace.Prefix, "ns#2-4");
+                       Assert.AreEqual (XamlLanguage.Xaml2006Namespace, r.Namespace.Namespace, "ns#2-5");
+
+                       Assert.IsTrue (r.Read (), "so#1-1");
+                       Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "so#1-2");
+                       var xt = new XamlType (typeof (Dictionary<string,object>), r.SchemaContext);
+                       Assert.AreEqual (xt, r.Type, "so#1-3");
+                       Assert.AreEqual (obj, r.Instance, "so#1-4");
+
+                       // This assumption on member ordering ("Type" then "Items") is somewhat wrong, and we might have to adjust it in the future.
+
+                       Assert.IsTrue (r.Read (), "smitems#1");
+                       Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "smitems#2");
+                       Assert.AreEqual (XamlLanguage.Items, r.Member, "smitems#3");
+
+                       for (int i = 0; i < 2; i++) {
+
+                               // start of an item
+                               Assert.IsTrue (r.Read (), "soi#1-1." + i);
+                               Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "soi#1-2." + i);
+                               var xt2 = new XamlType (typeof (double), r.SchemaContext);
+                               Assert.AreEqual (xt2, r.Type, "soi#1-3." + i);
+
+                               Assert.IsTrue (r.Read (), "smi#1-1." + i);
+                               Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "smi#1-2." + i);
+                               Assert.AreEqual (XamlLanguage.Key, r.Member, "smi#1-3." + i);
+
+                               Assert.IsTrue (r.Read (), "svi#1-1." + i);
+                               Assert.AreEqual (XamlNodeType.Value, r.NodeType, "svi#1-2." + i);
+                               Assert.AreEqual (i == 0 ? "Foo" : "Bar", r.Value, "svi#1-3." + i);
+
+                               Assert.IsTrue (r.Read (), "emi#1-1." + i);
+                               Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "emi#1-2." + i);
+
+                               Assert.IsTrue (r.Read (), "smi#2-1." + i);
+                               Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "smi#2-2." + i);
+                               Assert.AreEqual (XamlLanguage.Initialization, r.Member, "smi#2-3." + i);
+
+                               Assert.IsTrue (r.Read (), "svi#2-1." + i);
+                               Assert.AreEqual (XamlNodeType.Value, r.NodeType, "svi#2-2." + i);
+                               Assert.AreEqual (i == 0 ? "5" : "-6.5", r.Value, "svi#2-3." + i); // converted to string(!)
+
+                               Assert.IsTrue (r.Read (), "emi#2-1." + i);
+                               Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "emi#2-2." + i);
+
+                               Assert.IsTrue (r.Read (), "eoi#1-1." + i);
+                               Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "eoi#1-2." + i);
+                               // end of an item
+                       }
+
+                       Assert.IsTrue (r.Read (), "emitems#1");
+                       Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "emitems#2"); // XamlLanguage.Items
+
+                       Assert.IsTrue (r.Read (), "eo#1-1");
+                       Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "eo#1-2"); // Dictionary
+
+                       Assert.IsFalse (r.Read (), "end");
+               }
+
                void SimpleReadStandardType (object instance)
                {
                        var r = new XamlObjectReader (instance);
index 30aa314d7a6d9ca4d68431e0aeea5083697648b6..06c59c30205d38c16f0e6d6902adf53be7445ed2 100644 (file)
@@ -240,6 +240,11 @@ namespace MonoTests.System.Xaml
                        Assert.IsFalse (t.IsCollection, "#3.1-2");
                        Assert.IsNotNull (t.KeyType, "#3.2");
                        Assert.AreEqual ("Int32", t.KeyType.Name, "#3.3");
+
+                       var ml = t.GetAllMembers ();
+                       Assert.AreEqual (2, ml.Count, "#3.4");
+                       Assert.IsTrue (ml.Any (mi => mi.Name == "Keys"), "#3.4-2");
+                       Assert.IsTrue (ml.Any (mi => mi.Name == "Values"), "#3.4-3");
                }
 
                public class TestClass1