hey Alex, just letting you know I'll get back to you on Monday, when I'm working again.
On 18 February 2016 at 07:32, Alex Harui <aha...@adobe.com> wrote: > Looks like some nice new capabilities for ArrayUtil and ObjectUtil. Did > you rule out using describeType for isDynamicObject? I know it is slow, > but it should always be right. What should isDynamicObject return for > XML, Proxy and ObjectProxy? > > Thanks, > -Alex > > On 2/17/16, 8:00 AM, "mih...@apache.org" <mih...@apache.org> wrote: > >>FLEX-35031 >>-Since I'm planning to use ObjectUtil.isDynamicObject() in the fix, I >>wanted to unit test it. >>-Also, I introduced a new function in ObjectUtil to be used in the >>solution, getEnumerableProperties(), which returns all the dynamic >>properties of an object. In order to unit test this new method I needed a >>function with which to compare Arrays. So I added it to ArrayUtil, >>including the unit tests needed to validate it. >>-Also edited an asdoc entry and renamed a function parameter. >> >> >>Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo >>Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/680b405d >>Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/680b405d >>Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/680b405d >> >>Branch: refs/heads/develop >>Commit: 680b405dfc4559ecf81239352b5bd9676d00adc8 >>Parents: e68c148 >>Author: Mihai Chira <mih...@apache.org> >>Authored: Wed Feb 17 13:35:31 2016 +0100 >>Committer: Mihai Chira <mih...@apache.org> >>Committed: Wed Feb 17 13:35:31 2016 +0100 >> >>---------------------------------------------------------------------- >> .../framework/src/mx/utils/ArrayUtil.as | 92 ++++++ >> .../framework/src/mx/utils/ObjectUtil.as | 33 ++- >> .../framework/tests/mx/utils/ArrayUtil_Tests.as | 293 +++++++++++++++++++ >> .../tests/mx/utils/ObjectUtil_Tests.as | 167 +++++++++++ >> 4 files changed, 581 insertions(+), 4 deletions(-) >>---------------------------------------------------------------------- >> >> >>http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/680b405d/frameworks/p >>rojects/framework/src/mx/utils/ArrayUtil.as >>---------------------------------------------------------------------- >>diff --git a/frameworks/projects/framework/src/mx/utils/ArrayUtil.as >>b/frameworks/projects/framework/src/mx/utils/ArrayUtil.as >>index c41cccf..85ec79c 100644 >>--- a/frameworks/projects/framework/src/mx/utils/ArrayUtil.as >>+++ b/frameworks/projects/framework/src/mx/utils/ArrayUtil.as >>@@ -107,6 +107,98 @@ public class ArrayUtil >> >> return -1; >> } >>+ >>+ /** >>+ * Checks if the Array instances contain the same values >>+ * against the same indexes. >>+ * >>+ * @param a The first Array instance. >>+ * @param b The second Array instance. >>+ * @return true if the two Arrays contain the same values >>+ * (determined using the strict equality operator) associated >>+ * with the same indexes. >>+ * >>+ * @langversion 3.0 >>+ * @playerversion Flash 9 >>+ * @playerversion AIR 1.1 >>+ * @productversion Flex 3 >>+ */ >>+ public static function arraysMatch(a:Array, b:Array):Boolean >>+ { >>+ if(!a || !b) >>+ return false; >>+ >>+ if(a.length != b.length) >>+ return false; >>+ >>+ var indexesA:Array = ObjectUtil.getEnumerableProperties(a); >>+ >>+ for (var i:int = 0; i < indexesA.length; i++) >>+ { >>+ var index:String = indexesA[i]; >>+ >>+ if(!b.hasOwnProperty(index) || a[index] !== b[index]) >>+ return false; >>+ } >>+ >>+ return true; >>+ } >>+ >>+ /** >>+ * Checks if the Array instances contain the same values, >>+ * even if in different orders. >>+ * >>+ * @param a The first Array instance. >>+ * @param b The second Array instance. >>+ * @return true if the two Arrays contain the same values. >>+ * >>+ * @langversion 3.0 >>+ * @playerversion Flash 9 >>+ * @playerversion AIR 1.1 >>+ * @productversion Flex 3 >>+ */ >>+ public static function arrayValuesMatch(a:Array, b:Array):Boolean >>+ { >>+ if(!a || !b) >>+ return false; >>+ >>+ var valuesOfA:Array = getArrayValues(a); >>+ valuesOfA.sort(); >>+ >>+ var valuesOfB:Array = getArrayValues(b); >>+ valuesOfB.sort(); >>+ >>+ return arraysMatch(valuesOfA, valuesOfB); >>+ } >>+ >>+ /** >>+ * Used to obtain the values in an Array, whether indexed >>+ * or associative. >>+ * >>+ * @param value The Array instance. >>+ * @return an indexed Array with the values found in >><code>value</code>. >>+ * >>+ * @langversion 3.0 >>+ * @playerversion Flash 9 >>+ * @playerversion AIR 1.1 >>+ * @productversion Flex 3 >>+ */ >>+ public static function getArrayValues(value:Array):Array >>+ { >>+ var result:Array = []; >>+ >>+ if(!value) >>+ return result; >>+ >>+ var indexes:Array = ObjectUtil.getEnumerableProperties(value); >>+ >>+ for each(var index:String in indexes) >>+ { >>+ result.push(value[index]); >>+ } >>+ >>+ return result; >>+ } >> } >> >> } >> >>http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/680b405d/frameworks/p >>rojects/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 6b1e79a..b1f23cc 100644 >>--- a/frameworks/projects/framework/src/mx/utils/ObjectUtil.as >>+++ b/frameworks/projects/framework/src/mx/utils/ObjectUtil.as >>@@ -1173,7 +1173,7 @@ public class ObjectUtil >> /** >> * Returns <code>true</code> if the object is an instance of a >>dynamic class. >> * >>- * @param obj The object. >>+ * @param object The object. >> * >> * @return <code>true</code> if the object is an instance of a >>dynamic class. >> * >>@@ -1182,24 +1182,49 @@ public class ObjectUtil >> * @playerversion AIR 1.1 >> * @productversion Flex 3 >> */ >>- public static function isDynamicObject(obj:Object):Boolean >>+ public static function isDynamicObject(object:Object):Boolean >> { >> try >> { >> // this test for checking whether an object is dynamic or >>not is >> // pretty hacky, but it assumes that no-one actually has a >> // property defined called "wootHackwoot" >>- obj["wootHackwoot"]; >>+ object["wootHackwoot"]; >> } >> catch (e:Error) >> { >>- // our object isn't from a dynamic class >>+ // our object isn't an instance of a dynamic class >> return false; >> } >> return true; >> } >> >> /** >>+ * Returns all the properties defined dynamically on an object. >>+ * >>+ * @param object The object to inspect. >>+ * >>+ * @return an <code>Array</code> of the enumerable properties of >>the object. >>+ * >>+ * @langversion 3.0 >>+ * @playerversion Flash 9 >>+ * @playerversion AIR 1.1 >>+ * @productversion Flex 3 >>+ */ >>+ public static function getEnumerableProperties(object:Object):Array >>+ { >>+ var result:Array = []; >>+ >>+ if(!isDynamicObject(object)) >>+ return result; >>+ >>+ for (var property:String in object) >>+ result.push(property); >>+ >>+ return result; >>+ } >>+ >>+ /** >> * 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, >> * <code>undefined</code> is returned. >> >>http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/680b405d/frameworks/p >>rojects/framework/tests/mx/utils/ArrayUtil_Tests.as >>---------------------------------------------------------------------- >>diff --git >>a/frameworks/projects/framework/tests/mx/utils/ArrayUtil_Tests.as >>b/frameworks/projects/framework/tests/mx/utils/ArrayUtil_Tests.as >>new file mode 100644 >>index 0000000..d11f468 >>--- /dev/null >>+++ b/frameworks/projects/framework/tests/mx/utils/ArrayUtil_Tests.as >>@@ -0,0 +1,293 @@ >>+///////////////////////////////////////////////////////////////////////// >>/////// >>+// >>+// Licensed to the Apache Software Foundation (ASF) under one or more >>+// contributor license agreements. See the NOTICE file distributed with >>+// this work for additional information regarding copyright ownership. >>+// The ASF licenses this file to You under the Apache License, Version >>2.0 >>+// (the "License"); you may not use this file except in compliance with >>+// the License. You may obtain a copy of the License at >>+// >>+// http://www.apache.org/licenses/LICENSE-2.0 >>+// >>+// Unless required by applicable law or agreed to in writing, software >>+// distributed under the License is distributed on an "AS IS" BASIS, >>+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>implied. >>+// See the License for the specific language governing permissions and >>+// limitations under the License. >>+// >>+///////////////////////////////////////////////////////////////////////// >>/////// >>+ >>+package mx.utils >>+{ >>+ import org.flexunit.asserts.assertEquals; >>+ import org.flexunit.asserts.assertFalse; >>+ import org.flexunit.asserts.assertNotNull; >>+ import org.flexunit.asserts.assertTrue; >>+ >>+ public class ArrayUtil_Tests >>+ { >>+ >>//------------------------------------------------------------------------ >>-- >>+ // >>+ // arraysMatch() >>+ // >>+ >>//------------------------------------------------------------------------ >>-- >>+ >>+ [Test] >>+ public function test_array_matches_with_itself():void >>+ { >>+ //given >>+ var array:Array = [1, 2, 3]; >>+ >>+ //then >>+ assertTrue(ArrayUtil.arraysMatch(array, array)); >>+ } >>+ >>+ [Test] >>+ public function test_empty_arrays_match():void >>+ { >>+ //then >>+ assertTrue(ArrayUtil.arraysMatch([], [])); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_with_same_values_in_different_indexes_dont_match():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch(["name", "age"], ["age", >>"name"])); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_match_when_properties_created_in_different_orders():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA["name"] = "AName"; >>+ arrayA["age"] = 22; >>+ >>+ arrayB["age"] = 22; >>+ arrayB["name"] = "AName"; >>+ >>+ //then >>+ assertTrue(ArrayUtil.arraysMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_dont_match_when_indexes_match_but_values_different():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA["name"] = "AName"; >>+ arrayA["age"] = 444; >>+ >>+ arrayB["age"] = 22; >>+ arrayB["name"] = "BName"; >>+ >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_dont_match_when_they_have_same_number_of_different_indexes():v >>oid >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA["name"] = "AName"; >>+ arrayA["age"] = 444; >>+ >>+ arrayB["radius"] = "AName"; >>+ arrayB[9] = 444; >>+ >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_match_when_indexes_expressed_in_string_and_int():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA[3] = "value"; >>+ arrayA["4"] = "value"; >>+ >>+ arrayB["3"] = "value"; >>+ arrayB[4] = "value"; >>+ >>+ //then >>+ assertTrue(ArrayUtil.arraysMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_dont_match_when_values_expressed_in_string_and_int():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA[3] = 3; >>+ arrayA[4] = 4; >>+ >>+ arrayB[3] = "3"; >>+ arrayB[4] = "4"; >>+ >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ public function test_array_and_null_dont_match():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch([1, 2, 3], null)); >>+ } >>+ >>+ [Test] >>+ public function test_null_and_null_dont_match():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch(null, null)); >>+ } >>+ >>+ [Test] >>+ public function >>test_arrays_with_null_in_different_positions_dont_match():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arraysMatch([null, 0], [0, null])); >>+ } >>+ >>+ >>//------------------------------------------------------------------------ >>-- >>+ // >>+ // arrayValuesMatch() >>+ // >>+ >>//------------------------------------------------------------------------ >>-- >>+ >>+ [Test] >>+ public function >>test_arrays_with_same_values_in_different_indexes_match_in_terms_of_values >>():void >>+ { >>+ //then >>+ assertTrue(ArrayUtil.arrayValuesMatch(["name", "age"], >>["age", "name"])); >>+ } >>+ >>+ [Test] >>+ public function test_array_values_dont_match_with_null():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arrayValuesMatch(["name", "age"], >>null)); >>+ } >>+ >>+ [Test] >>+ public function test_null_doesnt_match_values_with_array():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arrayValuesMatch(null, ["name", >>"age"])); >>+ } >>+ >>+ [Test] >>+ public function >>test_null_and_null_dont_have_matching_values():void >>+ { >>+ //then >>+ assertFalse(ArrayUtil.arrayValuesMatch(null, null)); >>+ } >>+ >>+ [Test] >>+ public function >>test_array_values_match_although_they_have_different_indexes():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA["name"] = "AName"; >>+ arrayA["age"] = 444; >>+ >>+ arrayB["label"] = "AName"; >>+ arrayB["spin"] = 444; >>+ >>+ //then >>+ assertTrue(ArrayUtil.arrayValuesMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ public function >>test_array_values_dont_match_although_they_have_same_indexes():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA["name"] = "AName"; >>+ arrayA["age"] = 444; >>+ >>+ arrayB["name"] = "BName"; >>+ arrayB["age"] = 21; >>+ >>+ //then >>+ assertFalse(ArrayUtil.arrayValuesMatch(arrayA, arrayB)); >>+ } >>+ >>+ [Test] >>+ //relevant because the array length is changed when a numeric >>index is used >>+ public function >>test_array_values_match_even_when_one_of_their_indexes_is_numeric():void >>+ { >>+ //given >>+ var arrayA:Array = []; >>+ var arrayB:Array = []; >>+ >>+ //when >>+ arrayA["name"] = "AName"; >>+ arrayA["age"] = 444; >>+ >>+ arrayB["label"] = "AName"; >>+ arrayB[9] = 444; >>+ >>+ //then >>+ assertTrue(ArrayUtil.arrayValuesMatch(arrayA, arrayB)); >>+ } >>+ >>+ >>+ >>//------------------------------------------------------------------------ >>-- >>+ // >>+ // getArrayValues() >>+ // >>+ >>//------------------------------------------------------------------------ >>-- >>+ [Test] >>+ public function test_values_of_null_is_an_empty_array():void >>+ { >>+ //when >>+ var values:Array = ArrayUtil.getArrayValues(null); >>+ >>+ //then >>+ assertNotNull(values); >>+ assertEquals(0, values.length); >>+ } >>+ >>+ [Test] >>+ public function >>test_values_of_array_whose_index_was_set_manually_to_a_number_include_only >>_that_value():void >>+ { >>+ //given >>+ var array:Array = []; >>+ array[2] = "hey"; >>+ >>+ //when >>+ var values:Array = ArrayUtil.getArrayValues(array); >>+ >>+ //then >>+ assertNotNull(values); >>+ assertEquals(3, array.length); >>+ assertEquals(1, values.length); >>+ assertEquals("hey", values[0]); >>+ } >>+ } >>+} >>\ No newline at end of file >> >>http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/680b405d/frameworks/p >>rojects/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 >>new file mode 100644 >>index 0000000..a373267 >>--- /dev/null >>+++ b/frameworks/projects/framework/tests/mx/utils/ObjectUtil_Tests.as >>@@ -0,0 +1,167 @@ >>+///////////////////////////////////////////////////////////////////////// >>/////// >>+// >>+// Licensed to the Apache Software Foundation (ASF) under one or more >>+// contributor license agreements. See the NOTICE file distributed with >>+// this work for additional information regarding copyright ownership. >>+// The ASF licenses this file to You under the Apache License, Version >>2.0 >>+// (the "License"); you may not use this file except in compliance with >>+// the License. You may obtain a copy of the License at >>+// >>+// http://www.apache.org/licenses/LICENSE-2.0 >>+// >>+// Unless required by applicable law or agreed to in writing, software >>+// distributed under the License is distributed on an "AS IS" BASIS, >>+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>implied. >>+// See the License for the specific language governing permissions and >>+// limitations under the License. >>+// >>+///////////////////////////////////////////////////////////////////////// >>/////// >>+ >>+package mx.utils { >>+ import flash.utils.Dictionary; >>+ >>+ import org.flexunit.asserts.assertEquals; >>+ >>+ import org.flexunit.asserts.assertFalse; >>+ import org.flexunit.asserts.assertTrue; >>+ >>+ public class ObjectUtil_Tests >>+ { >>+ >>//------------------------------------------------------------------------ >>-- >>+ // >>+ // isDynamicObject() >>+ // >>+ >>//------------------------------------------------------------------------ >>-- >>+ >>+ [Test] >>+ public function >>test_dynamic_class_instance_recognized_as_dynamic_object():void >>+ { >>+ //then >>+ assertTrue(ObjectUtil.isDynamicObject(new >>DynamicVO("John"))); >>+ } >>+ >>+ [Test] >>+ public function >>test_anonymous_class_instance_recognized_as_dynamic_object():void >>+ { >>+ //then >>+ assertTrue(ObjectUtil.isDynamicObject({name:"John"})); >>+ } >>+ >>+ [Test] >>+ public function >>test_array_instance_recognized_as_dynamic_object():void >>+ { >>+ //then >>+ assertTrue(ObjectUtil.isDynamicObject([])); >>+ } >>+ >>+ [Test] >>+ public function >>test_dictionary_instance_recognized_as_dynamic_object():void >>+ { >>+ //then >>+ assertTrue(ObjectUtil.isDynamicObject(new Dictionary())); >>+ } >>+ >>+ [Test] >>+ public function >>test_sealed_class_instance_recognized_as_non_dynamic_object():void >>+ { >>+ //then >>+ assertFalse(ObjectUtil.isDynamicObject(new >>NonDynamicVO("John"))); >>+ } >>+ >>+ [Test] >>+ public function test_null_does_not_throw_fatal():void >>+ { >>+ //then >>+ assertFalse(ObjectUtil.isDynamicObject(null)); >>+ } >>+ >>+ >>//------------------------------------------------------------------------ >>-- >>+ // >>+ // getEnumerableProperties() >>+ // >>+ >>//------------------------------------------------------------------------ >>-- >>+ >>+ [Test] >>+ public function >>test_enumerable_properties_of_anonymous_object():void >>+ { >>+ //given >>+ var object:Object = {name:"John", age:32}; >>+ >>+ //when >>+ var enumerableProperties:Array = >>ObjectUtil.getEnumerableProperties(object); >>+ >>+ //then >>+ assertTrue(ArrayUtil.arrayValuesMatch(["age", "name"], >>enumerableProperties)); >>+ } >>+ >>+ [Test] >>+ public function test_enumerable_properties_of_null():void >>+ { >>+ //when >>+ var enumerableProperties:Array = >>ObjectUtil.getEnumerableProperties(null); >>+ >>+ //then >>+ assertEquals(0, enumerableProperties.length); >>+ } >>+ >>+ [Test] >>+ public function test_enumerable_properties_of_dictionary():void >>+ { >>+ //given >>+ var object:Object = new Dictionary(false); >>+ object["name"] = "John"; >>+ object["age"] = 9; >>+ >>+ //when >>+ var enumerableProperties:Array = >>ObjectUtil.getEnumerableProperties(object); >>+ >>+ //then >>+ assertTrue(ArrayUtil.arrayValuesMatch(["age", "name"], >>enumerableProperties)); >>+ } >>+ >>+ [Test] >>+ public function >>test_enumerable_properties_of_dynamic_object():void >>+ { >>+ //given >>+ var object:Object = new DynamicVO("John"); >>+ object["age"] = 9; >>+ >>+ //when >>+ var enumerableProperties:Array = >>ObjectUtil.getEnumerableProperties(object); >>+ >>+ //then >>+ assertTrue(ArrayUtil.arrayValuesMatch(["age", "name"], >>enumerableProperties)); >>+ } >>+ >>+ [Test] >>+ public function >>test_enumerable_properties_of_sealed_class_instance():void >>+ { >>+ //given >>+ var object:Object = new NonDynamicVO("John"); >>+ >>+ //when >>+ var enumerableProperties:Array = >>ObjectUtil.getEnumerableProperties(object); >>+ >>+ //then >>+ assertEquals(0, enumerableProperties.length); >>+ } >>+ } >>+} >>+ >>+dynamic class DynamicVO >>+{ >>+ public function DynamicVO(name:String) >>+ { >>+ this.name = name; >>+ } >>+} >>+ >>+class NonDynamicVO >>+{ >>+ public var name:String; >>+ >>+ public function NonDynamicVO(name:String) >>+ { >>+ this.name = name; >>+ } >>+} >>\ No newline at end of file >> >