public void TestEquality() { var attrType1 = new AttributeType("xkcd", typeof(string)); var attrInfo1 = new AttributeInfo("xkcd", attrType1); var domNodeType = new DomNodeType("WebComic", DomNodeType.BaseOfAllTypes); var childInfo1 = new ChildInfo("xkcd", domNodeType); attrInfo1.DefaultValue = "Firefly"; var desc1 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", true); int originalHashCode = desc1.GetHashCode(); // test if two identically created property descriptors compare as being equal var desc2 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", true); Assert.AreEqual(desc1, desc2); Assert.AreEqual(desc1.GetHashCode(), desc2.GetHashCode()); // test category being different; oddly, although I think they should not be considered equal, // the .Net PropertyDescriptor ignores the difference in category name. So, I'm guessing that // the AttributePropertyDescriptor should behave the same as PropertyDescriptor. var desc3 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 2", "A commonly used word or phrase in the xkcd comic", true); Assert.AreEqual(desc1, desc3); Assert.AreEqual(desc1.GetHashCode(), desc3.GetHashCode()); // test description being different; similarly here, the .Net PropertyDescriptor doesn't care. var desc4 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "slightly different description", true); Assert.AreEqual(desc1, desc4); Assert.AreEqual(desc1.GetHashCode(), desc4.GetHashCode()); // test readOnly being different; ditto for read-only flag! var desc5 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", false); Assert.AreEqual(desc1, desc5); Assert.AreEqual(desc1.GetHashCode(), desc5.GetHashCode()); // test that the hash code hasn't changed after using the AttributeInfo var attrInfo2 = new AttributeInfo("xkcd", attrType1); domNodeType.Define(attrInfo2); Assert.AreEqual(desc1.GetHashCode(), originalHashCode); // test that the hash code hasn't changed after creating a derived DomNodeType var derivedDomNodeType = new DomNodeType("ScientificWebComic", domNodeType); var derivedAttrInfo = new AttributeInfo("xkcd", attrType1); var derivedChildInfo = new ChildInfo("xkcd", derivedDomNodeType); derivedDomNodeType.Define(derivedAttrInfo); Assert.AreEqual(desc1.GetHashCode(), originalHashCode); // test that an AttributeInfo used in a derived DomNodeType doesn't change equality or hash code var desc6 = new ChildAttributePropertyDescriptor( "xkcd", derivedAttrInfo, derivedChildInfo, "Category 1", "A commonly used word or phrase in the xkcd comic", true); Assert.AreEqual(desc1, desc6); Assert.AreEqual(desc1.GetHashCode(), desc6.GetHashCode()); }
public void TestEquality() { var attrType1 = new AttributeType("xkcd", typeof(string)); var attrInfo1 = new AttributeInfo("xkcd", attrType1); var domNodeType = new DomNodeType("WebComic", DomNodeType.BaseOfAllTypes); var childInfo1 = new ChildInfo("xkcd", domNodeType); attrInfo1.DefaultValue = "Firefly"; var desc1 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", true); int originalHashCode = desc1.GetHashCode(); // test if two identically created property descriptors compare as being equal var desc2 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", true); Assert.AreEqual(desc1, desc2); Assert.AreEqual(desc1.GetHashCode(), desc2.GetHashCode()); // test category being different; oddly, although I think they should not be considered equal, // the .NET PropertyDescriptor ignores the difference in category name. For our purposes, we // want to allow for two different property editors to appear with the same name but different // categories. This is how our PropertyUtils.PropertyDescriptorsEqual() and GetPropertyDescriptorHash() // work. var desc3 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 2", "A commonly used word or phrase in the xkcd comic", true); Assert.AreNotEqual(desc1, desc3); Assert.AreNotEqual(desc1.GetHashCode(), desc3.GetHashCode()); // test description being different; similarly here, the .Net PropertyDescriptor doesn't care. var desc4 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "slightly different description", true); Assert.AreEqual(desc1, desc4); Assert.AreEqual(desc1.GetHashCode(), desc4.GetHashCode()); // test readOnly being different; ditto for read-only flag! var desc5 = new ChildAttributePropertyDescriptor( "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", false); Assert.AreEqual(desc1, desc5); Assert.AreEqual(desc1.GetHashCode(), desc5.GetHashCode()); // test that the hash code hasn't changed after using the AttributeInfo var attrInfo2 = new AttributeInfo("xkcd", attrType1); domNodeType.Define(attrInfo2); Assert.AreEqual(desc1.GetHashCode(), originalHashCode); // test that the hash code hasn't changed after creating a derived DomNodeType var derivedDomNodeType = new DomNodeType("ScientificWebComic", domNodeType); var derivedAttrInfo = new AttributeInfo("xkcd", attrType1); var derivedChildInfo = new ChildInfo("xkcd", derivedDomNodeType); derivedDomNodeType.Define(derivedAttrInfo); Assert.AreEqual(desc1.GetHashCode(), originalHashCode); // test that an AttributeInfo used in a derived DomNodeType doesn't change equality or hash code var desc6 = new ChildAttributePropertyDescriptor( "xkcd", derivedAttrInfo, derivedChildInfo, "Category 1", "A commonly used word or phrase in the xkcd comic", true); Assert.AreEqual(desc1, desc6); Assert.AreEqual(desc1.GetHashCode(), desc6.GetHashCode()); // test that a different name counts as a different property descriptor var desc7 = new ChildAttributePropertyDescriptor( "xkcd2", attrInfo1, childInfo1, "Category 1", "different name", true); Assert.AreNotEqual(desc1, desc7); Assert.AreNotEqual(desc1.GetHashCode(), desc7.GetHashCode()); }
private static PropertyDescriptor GetDescriptor( DomNodeType type, XmlNode annotation, string name, string[] segments) { PropertyDescriptor desc = null; // Get mandatory display name XmlAttribute displayNameAttr = annotation.Attributes["displayName"]; if (displayNameAttr != null) { if (string.IsNullOrEmpty(name)) { throw new AnnotationException(string.Format( "Required name attribute is null or empty.\r\nType: {0}\r\nElement: {1}", type.Name, annotation.Name)); } string displayName = displayNameAttr.Value; if (string.IsNullOrEmpty(displayName)) { displayName = name; } // Get optional annotations string category = GetAnnotation(annotation, "category"); string description = GetAnnotation(annotation, "description"); bool readOnly = GetAnnotation(annotation, "readOnly") == "true"; object editor = CreateObject <object>(type, annotation, "editor"); TypeConverter typeConverter = CreateObject <TypeConverter>(type, annotation, "converter"); if (annotation.Name == "scea.dom.editors.attribute") { // Attribute annotation if (segments == null) { throw new AnnotationException("Unnamed attribute"); } if (segments.Length == 1) // local attribute { AttributeInfo metaAttr = type.GetAttributeInfo(name); if (metaAttr == null) { throw new AnnotationException("Type doesn't have this attribute"); } desc = new AttributePropertyDescriptor( displayName, metaAttr, category, description, readOnly, editor, typeConverter); } else // descendant attribute { ChildInfo[] metaElements = GetPath(type, segments, segments.Length - 1); DomNodeType childType = metaElements[segments.Length - 2].Type; AttributeInfo metaAttr = childType.GetAttributeInfo(segments[segments.Length - 1]); if (metaAttr == null) { throw new AnnotationException("Descendant type doesn't have this attribute"); } desc = new ChildAttributePropertyDescriptor( displayName, metaAttr, metaElements, category, description, readOnly, editor, typeConverter); } } else if (annotation.Name == "scea.dom.editors.child") { // Child value annotation ChildInfo element = type.GetChildInfo(name); if (element == null) { throw new AnnotationException("Type doesn't have this element"); } desc = new ChildPropertyDescriptor( displayName, element, category, description, readOnly, editor, typeConverter); } } return(desc); }
/// <summary> /// Creates an array of property descriptors that are associated with the adapted DomNode's /// DomNodeType. No duplicates are in the array (based on the property descriptor's Name /// property).</summary> /// <returns>Array of property descriptors</returns> protected override System.ComponentModel.PropertyDescriptor[] GetPropertyDescriptors() { System.ComponentModel.PropertyDescriptor[] baseDescriptors = base.GetPropertyDescriptors(); IList<DomNode> dynamicPropertyChildren = DomNode.GetChildList(Schema.groupType.dynamicPropertyChild); if (dynamicPropertyChildren.Count == 0) return baseDescriptors; var result = new List<System.ComponentModel.PropertyDescriptor>(baseDescriptors); int childIndex = 0; foreach (var child in dynamicPropertyChildren) { var displayName = (string)child.GetAttribute(Schema.dynamicPropertyType.nameAttribute); var category = (string)child.GetAttribute(Schema.dynamicPropertyType.categoryAttribute); var description = (string)child.GetAttribute(Schema.dynamicPropertyType.descriptionAttribute); bool readOnly = false; var editorTypeAndParameters = (string)child.GetAttribute(Schema.dynamicPropertyType.editorAttribute); object editor = CreateObject(editorTypeAndParameters); var typeConverterAndParameters = (string)child.GetAttribute(Schema.dynamicPropertyType.converterAttribute); var typeConverter = (TypeConverter)CreateObject(typeConverterAndParameters); string valueType = (string)child.GetAttribute(Schema.dynamicPropertyType.valueTypeAttribute); PropertyDescriptor newDescriptor; if (valueType == "stringValue") { newDescriptor = new ChildAttributePropertyDescriptor( displayName, Schema.dynamicPropertyType.stringValueAttribute, Schema.moduleType.dynamicPropertyChild, childIndex, category, description, readOnly, editor, typeConverter); } else if (valueType == "floatValue") { newDescriptor = new ChildAttributePropertyDescriptor( displayName, Schema.dynamicPropertyType.floatValueAttribute, Schema.moduleType.dynamicPropertyChild, childIndex, category, description, readOnly, editor, typeConverter); } else if (valueType == "vector3Value") { newDescriptor = new ChildAttributePropertyDescriptor( displayName, Schema.dynamicPropertyType.vector3ValueAttribute, Schema.moduleType.dynamicPropertyChild, childIndex, category, description, readOnly, editor, typeConverter); } else if (valueType == "boolValue") { newDescriptor = new ChildAttributePropertyDescriptor( displayName, Schema.dynamicPropertyType.boolValueAttribute, Schema.moduleType.dynamicPropertyChild, childIndex, category, description, readOnly, editor, typeConverter); } else if (valueType == "intValue") { newDescriptor = new ChildAttributePropertyDescriptor( displayName, Schema.dynamicPropertyType.intValueAttribute, Schema.moduleType.dynamicPropertyChild, childIndex, category, description, readOnly, editor, typeConverter); } else throw new InvalidOperationException("Unknown valueType attribute '" + valueType + "' for dynamic property: " + displayName); result.Add(newDescriptor); childIndex++; } return result.ToArray(); }