FLEX-35031 FLEX-33058 -Moved the valuesAreSubsetOfObject() function in ObjectUtil and added some unit tests for it. -Instead of iterating through the object's properties using a String object in ObjectUtil.getEnumerableProperties(), we are now using an Object instance. In this way, int properties will not be converted to String anymore.
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/0f811ec0 Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/0f811ec0 Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/0f811ec0 Branch: refs/heads/develop Commit: 0f811ec0a2c1109b2ef51c3cafecbf1d5a4abe05 Parents: e255d6d Author: Mihai Chira <[email protected]> Authored: Wed Feb 17 16:24:48 2016 +0100 Committer: Mihai Chira <[email protected]> Committed: Wed Feb 17 16:24:48 2016 +0100 ---------------------------------------------------------------------- .../HierarchicalCollectionViewCursor.as | 30 +----- .../framework/src/mx/utils/ObjectUtil.as | 45 +++++++- .../tests/mx/utils/ObjectUtil_Tests.as | 104 ++++++++++++++++++- 3 files changed, 149 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0f811ec0/frameworks/projects/advancedgrids/src/mx/collections/HierarchicalCollectionViewCursor.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/advancedgrids/src/mx/collections/HierarchicalCollectionViewCursor.as b/frameworks/projects/advancedgrids/src/mx/collections/HierarchicalCollectionViewCursor.as index dfe45a0..15584ff 100644 --- a/frameworks/projects/advancedgrids/src/mx/collections/HierarchicalCollectionViewCursor.as +++ b/frameworks/projects/advancedgrids/src/mx/collections/HierarchicalCollectionViewCursor.as @@ -324,7 +324,7 @@ public class HierarchicalCollectionViewCursor extends EventDispatcher var done:Boolean = false; while (!done) { - if (valuesAreSubsetOfObject(valuesToMatch, hierarchicalData.getData(current))) + if (ObjectUtil.valuesAreSubsetOfObject(valuesToMatch, hierarchicalData.getData(current))) return true; done = !moveNext(); @@ -333,32 +333,6 @@ public class HierarchicalCollectionViewCursor extends EventDispatcher return false; } - private static function valuesAreSubsetOfObject(values:Object, object:Object):Boolean - { - if(!object && !values) - return true; - - if(!object || !values) - return false; - - if(object === values) - return true; - - var enumerableProperties:Array = ObjectUtil.getEnumerableProperties(values); - var matches:Boolean = enumerableProperties.length > 0 || ObjectUtil.isDynamicObject(values); - - for each(var property:String in enumerableProperties) - { - if (!object.hasOwnProperty(property) || object[property] != values[property]) - { - matches = false; - break; - } - } - - return matches; - } - /** * @inheritDoc * @@ -393,7 +367,7 @@ public class HierarchicalCollectionViewCursor extends EventDispatcher var done:Boolean = false; while (!done) { - if (valuesAreSubsetOfObject(valuesToMatch, hierarchicalData.getData(current))) + if (ObjectUtil.valuesAreSubsetOfObject(valuesToMatch, hierarchicalData.getData(current))) return true; done = !movePrevious(); http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0f811ec0/frameworks/projects/framework/src/mx/utils/ObjectUtil.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/framework/src/mx/utils/ObjectUtil.as b/frameworks/projects/framework/src/mx/utils/ObjectUtil.as index b1f23cc..74aa9d6 100644 --- a/frameworks/projects/framework/src/mx/utils/ObjectUtil.as +++ b/frameworks/projects/framework/src/mx/utils/ObjectUtil.as @@ -1218,12 +1218,55 @@ public class ObjectUtil if(!isDynamicObject(object)) return result; - for (var property:String in object) + for (var property:Object in object) result.push(property); return result; } + + /** + * Verifies if the first object is dynamic and is a subset of the second object. + * + * @param values The values which need to be shared by <code>object</object> + * @param object The object to verify against. + * + * @return true if and only if the objects are the same, or if <code>values</code> + * is dynamic and <code>object</code> shares all its properties and values. + * (Even if <code>object</code> contains other properties and values, we still + * consider it a match). + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public static function valuesAreSubsetOfObject(values:Object, object:Object):Boolean + { + if(!object && !values) + return true; + + if(!object || !values) + return false; + + if(object === values) + return true; + + var enumerableProperties:Array = ObjectUtil.getEnumerableProperties(values); + var matches:Boolean = enumerableProperties.length > 0 || ObjectUtil.isDynamicObject(values); + + for each(var property:String in enumerableProperties) + { + if (!object.hasOwnProperty(property) || object[property] != values[property]) + { + matches = false; + break; + } + } + + return matches; + } + /** * Returns the value at the end of the property chain <code>path</code>. * If the value cannot be reached due to null links on the chain, http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0f811ec0/frameworks/projects/framework/tests/mx/utils/ObjectUtil_Tests.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/framework/tests/mx/utils/ObjectUtil_Tests.as b/frameworks/projects/framework/tests/mx/utils/ObjectUtil_Tests.as index 7a1b2e4..5c6e570 100644 --- a/frameworks/projects/framework/tests/mx/utils/ObjectUtil_Tests.as +++ b/frameworks/projects/framework/tests/mx/utils/ObjectUtil_Tests.as @@ -125,12 +125,13 @@ package mx.utils { //given var object:DynamicVO = new DynamicVO("John"); object["age"] = 9; + object["height"] = 6.1; //when var enumerableProperties:Array = ObjectUtil.getEnumerableProperties(object); //then - assertTrue(ArrayUtil.arrayValuesMatch(["age", "name"], enumerableProperties)); + assertTrue(ArrayUtil.arrayValuesMatch(["height", "age"], enumerableProperties)); } [Test] @@ -188,11 +189,112 @@ package mx.utils { //then assertEquals(0, enumerableProperties.length); } + + + //-------------------------------------------------------------------------- + // + // valuesAreSubsetOfObject() + // + //-------------------------------------------------------------------------- + + [Test] + public function test_empty_anonymous_object_is_subset_of_empty_anonymous_instance():void + { + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject({}, {})); + } + + [Test] + public function test_empty_anonymous_object_is_subset_of_sealed_class_instance():void + { + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject({}, new NonDynamicVO("John"))); + } + + [Test] + public function test_empty_anonymous_object_is_subset_of_dynamic_class_instance():void + { + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject({}, new DynamicVO("John"))); + } + + [Test] + public function test_anonymous_object_with_same_name_is_subset_of_similar_dynamic_class_instance():void + { + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject({name:"John"}, new DynamicVO("John"))); + } + + [Test] + public function test_anonymous_object_with_same_properties_and_values_is_subset_of_similar_dynamic_class_instance_with_one_property_manually_set():void + { + //given + var john:DynamicVO = new DynamicVO("John"); + john.age = 23; + john.height = 6; + + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject({name:"John", age:23}, john)); + } + + [Test] + public function test_anonymous_object_with_different_name_is_not_subset_of_similar_dynamic_class_instance():void + { + //then + assertFalse(ObjectUtil.valuesAreSubsetOfObject({name:"Max"}, new DynamicVO("John"))); + } + + [Test] + public function test_anonymous_object_with_same_name_is_subset_of_similar_sealed_class_instance():void + { + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject({name:"John"}, new NonDynamicVO("John"))); + } + + [Test] + public function test_anonymous_object_with_different_name_is_not_subset_of_similar_sealed_class_instance():void + { + //then + assertFalse(ObjectUtil.valuesAreSubsetOfObject({name:"Max"}, new NonDynamicVO("John"))); + } + + [Test] + public function test_anonymous_object_with_extra_property_is_not_subset_of_similar_sealed_class_instance():void + { + //then + assertFalse(ObjectUtil.valuesAreSubsetOfObject({name:"Max", age:23}, new NonDynamicVO("John"))); + } + + [Test] + public function test_sealed_object_is_a_subset_of_itself():void + { + //given + var max:NonDynamicVO = new NonDynamicVO("Max"); + + //then + assertTrue(ObjectUtil.valuesAreSubsetOfObject(max, max)); + } + + [Test] + public function test_sealed_object_is_not_a_subset_of_similar_dynamic_object():void + { + //then + assertFalse(ObjectUtil.valuesAreSubsetOfObject(new NonDynamicVO("Max"), {name:"Max"})); + } + + [Test] + public function test_sealed_object_is_not_a_subset_of_similar_sealed_object():void + { + //then + assertFalse(ObjectUtil.valuesAreSubsetOfObject(new NonDynamicVO("Max"), new NonDynamicVO("Max"))); + } } } dynamic class DynamicVO { + public var name:String; + public function DynamicVO(name:String) { this.name = name;
