I added tests for these in ObjectUtilsTest.

There are six commented out asserts in that class. Where those asserts are 
uncommented to test arrays using objectsMatch, the test fails and they always 
compare as true.

I’m having trouble figuring out why. I could use another pair of eyes on this…

Thanks,
Harbs

> On Jan 15, 2022, at 11:46 PM, ha...@apache.org wrote:
> 
> This is an automated email from the ASF dual-hosted git repository.
> 
> harbs pushed a commit to branch develop
> in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
> 
> 
> The following commit(s) were added to refs/heads/develop by this push:
>     new dd9be56  Added arraysMatch and objectsMatch
> dd9be56 is described below
> 
> commit dd9be568413b2a51dd5436edbffdc1f962b20e49
> Author: Harbs <ha...@in-tools.com>
> AuthorDate: Sat Jan 15 23:46:00 2022 +0200
> 
>    Added arraysMatch and objectsMatch
> ---
> .../projects/Core/src/main/royale/CoreClasses.as   |   3 +
> .../org/apache/royale/utils/array/arraysMatch.as}  |  54 ++++----
> .../org/apache/royale/utils/object/objectsMatch.as | 138 +++++++++++++++++++++
> .../test/royale/flexUnitTests/ObjectUtilsTest.as   |  48 +++++++
> 4 files changed, 215 insertions(+), 28 deletions(-)
> 
> diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as 
> b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> index b506982..ebb47c4 100644
> --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
> +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> @@ -336,6 +336,9 @@ internal class CoreClasses
>       import org.apache.royale.utils.transformValueFromRange; 
> transformValueFromRange;
> 
>       import org.apache.royale.utils.array.rangeCheck; rangeCheck;
> +     import org.apache.royale.utils.array.arraysMatch; arraysMatch;
> +     
> +     import org.apache.royale.utils.object.objectsMatch; objectsMatch;
> 
>       import org.apache.royale.utils.string.Base64; 
> org.apache.royale.utils.string.Base64;
>       import org.apache.royale.utils.Base64; org.apache.royale.utils.Base64;
> diff --git 
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as 
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/array/arraysMatch.as
> similarity index 56%
> copy from 
> frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as
> copy to 
> frameworks/projects/Core/src/main/royale/org/apache/royale/utils/array/arraysMatch.as
> index 010025d..54e27b4 100644
> --- 
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as
> +++ 
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/array/arraysMatch.as
> @@ -16,39 +16,37 @@
> //  limitations under the License.
> //
> ////////////////////////////////////////////////////////////////////////////////
> -package flexUnitTests
> +package org.apache.royale.utils.array
> {
> -     import org.apache.royale.core.Strand;
> -     import org.apache.royale.test.asserts.*;
> -     import org.apache.royale.utils.object.classFromInstance;
> 
> -     public class ObjectUtilsTest
> +     import org.apache.royale.utils.object.objectsMatch;
> +
> +     /**
> +      *  Checks that all items in an array match.
> +      *  If deep is true, it will recursively compare properties of all 
> items.
> +      *  level is used to track the level of nesting to prevent an endless 
> loop
> +      *  @langversion 3.0
> +      *  @productversion Royale 0.9.9
> +      *  @royalesuppressexport
> +      */
> +     public function 
> arraysMatch(first:Array,second:Array,deep:Boolean=false,level:int=0):Boolean
>       {
> -             [Before]
> -             public function setUp():void
> -             {
> -             }
> -             
> -             [After]
> -             public function tearDown():void
> -             {
> -             }
> -             
> -             [BeforeClass]
> -             public static function setUpBeforeClass():void
> -             {
> -             }
> +             if(first.length != second.length)
> +                     return false;
>               
> -             [AfterClass]
> -             public static function tearDownAfterClass():void
> +             var len:int = first.length;
> +             for(var i:int=0; i<len; i++)
>               {
> +                     if(deep)
> +                     {
> +                             if(!objectsMatch(first[i], second[i], deep, 
> level+1))
> +                                     return false;
> +
> +                     }
> +                     else if(first[i] !== second[i])
> +                             return false;
> +
>               }
> -             
> -             [Test]
> -             public function testClass():void
> -             {
> -                     var strand:Strand = new Strand();
> -                     assertEquals(classFromInstance(strand), Strand, "Error 
> finding class from instance.");
> -             }
> +             return true;
>       }
> }
> \ No newline at end of file
> diff --git 
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/object/objectsMatch.as
>  
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/object/objectsMatch.as
> new file mode 100644
> index 0000000..ec71da5
> --- /dev/null
> +++ 
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/object/objectsMatch.as
> @@ -0,0 +1,138 @@
> +////////////////////////////////////////////////////////////////////////////////
> +//
> +//  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 org.apache.royale.utils.object
> +{
> +     
> +     import org.apache.royale.utils.array.arraysMatch;
> +
> +     /**
> +      *  Checks whether objects of any type match.
> +      *  If deep is true, it will recursively check objects.
> +      *  level is used to prevent an endless loop with circular references.
> +      *  Maximum level of nesting is 100
> +      *  @langversion 3.0
> +      *  @productversion Royale 0.9.9
> +      *  @royaleignorecoercion Array
> +      *  @royaleignorecoercion Date
> +      *  @royalesuppressexport
> +      */
> +     public function objectsMatch(first:*, second:*, 
> deep:Boolean=false,level:int=0):Boolean
> +     {
> +             if(level > _MAX_LEVEL_)
> +                     return false;
> +
> +             if(first == null || second == null)
> +                     return first === second;
> +             
> +             
> +             COMPILE::SWF
> +             {
> +                     if(first is Array)
> +                     {
> +                             if(!(second is Array))
> +                                     return false;
> +                             
> +                             return arraysMatch(first as Array,second as 
> Array, deep, level+1);
> +                     }
> +                     
> +                     //TODO Vectors
> +                     //TODO XML
> +                     if(first is String || first is int || first is uint || 
> first is Number || first is Boolean || first is Class)
> +                     {
> +                             return first === second;
> +                     }
> +                     else if (first is Date)
> +                     {
> +                             if(!(second is Date))
> +                                     return false;
> +                             
> +                             return (first as Date).getTime() == (second as 
> Date).getTime();
> +                     }
> +                     //TODO make sure that all object properties match
> +                     for(var x:String in first)
> +                     {
> +                             if(deep)
> +                             {
> +                                     if(!objectsMatch(first[x], second[x], 
> deep, level+1))
> +                                             return false;
> +                             }
> +                             else if(first[x] !== second[x])
> +                                     return false;
> +
> +                     }
> +                     return true;
> +
> +             }
> +             COMPILE::JS
> +             {
> +                     var firstType:String = typeof first;
> +                     var secondType:String = typeof second;
> +                     if(firstType != secondType)
> +                             return false;
> +
> +                     if(firstType == 'object' && secondType == 'object')
> +                     {
> +
> +                             // treat all array-like objects as arrays
> +                             if(first.constructor.name.indexOf("Array") != 
> -1 &&
> +                                     first.constructor.name.indexOf("Array") 
> != -1 &&
> +                                     first.propertyIsEnumerable("length") &&
> +                                     second.propertyIsEnumerable("length"))
> +                             {
> +                                     return arraysMatch(first as Array, 
> second as Array, deep, level+1);
> +                             }
> +                             // TODO Vectors that are not compiled as Arrays
> +
> +                             // TODO XML
> +                             if (first is Date)
> +                             {
> +                                     if(!(second is Date))
> +                                             return false;
> +                                     
> +                                     return (first as Date).getTime() == 
> (second as Date).getTime();
> +                             }
> +
> +                             var firstKeys:Array = Object.keys(first);
> +                             var secondKeys:Array = Object.keys(second);
> +                             if(!arraysMatch(firstKeys,secondKeys))
> +                                     return false;
> +
> +                             for(var x:String in first)
> +                             {
> +                                     if(deep)
> +                                     {
> +                                             
> if(!objectsMatch(first[x],second[x],deep,level+1))
> +                                                     return false;
> +                                     }
> +                                     else
> +                                     {
> +                                             if(first[x] !== second[x])
> +                                                     return false;
> +                                     }
> +                             }
> +                             return true;
> +                     }
> +                     else
> +                             return first === second;
> +
> +             }
> +     }
> +}
> +
> +internal const _MAX_LEVEL_:int = 100;
> diff --git 
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as 
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as
> index 010025d..1e37b30 100644
> --- 
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as
> +++ 
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/ObjectUtilsTest.as
> @@ -21,6 +21,10 @@ package flexUnitTests
>       import org.apache.royale.core.Strand;
>       import org.apache.royale.test.asserts.*;
>       import org.apache.royale.utils.object.classFromInstance;
> +     import org.apache.royale.utils.object.objectsMatch;
> +     import org.apache.royale.test.asserts.assertFalse;
> +     import org.apache.royale.test.asserts.assertTrue;
> +     import org.apache.royale.utils.array.arraysMatch;
> 
>       public class ObjectUtilsTest
>       {
> @@ -50,5 +54,49 @@ package flexUnitTests
>                       var strand:Strand = new Strand();
>                       assertEquals(classFromInstance(strand), Strand, "Error 
> finding class from instance.");
>               }
> +             [Test]
> +             public function testObjectsMatch():void
> +             {
> +                     var first:Object = 
> {name:"foo",age:10,human:false,children:[{name:"bar",age:1},{name:"baz",age:2}]}
> +                     var second:Object = 
> {name:"foo",age:10,human:false,children:[{name:"bar",age:1},{name:"baz",age:2}]}
> +                     assertTrue(objectsMatch(first,second,true),"deep 
> comparison of objects should match");
> +                     assertFalse(objectsMatch(first,second,false),"shallow 
> comparison of objects should not match");
> +             }
> +             [Test]
> +             public function testArraysMatch():void
> +             {
> +                     var firstArray:Array = [1,2,3,4,"5",6];
> +                     var secondArray:Array = [1,2,3,"4",5,6];
> +
> +                     
> assertFalse(arraysMatch(firstArray,secondArray,true),"deep comparison of 
> mismatched simple array values should not match");
> +                     
> assertFalse(arraysMatch(firstArray,secondArray,false),"shallow comparison of 
> mismatched simple array values should not match");
> +                     // 
> assertFalse(objectsMatch(firstArray,secondArray,true),"deep comparison of 
> mismatched simple array values should not match (using objectMatch)");
> +                     // 
> assertFalse(objectsMatch(firstArray,secondArray,false),"shallow comparison of 
> mismatched simple array values should not match (using objectMatch)");
> +
> +
> +                     firstArray = [1,2,3,4,5,6];
> +                     secondArray = [1,2,3,4,5,6];
> +                     
> assertTrue(arraysMatch(firstArray,secondArray,true),"deep comparison of like 
> number values should match");
> +                     
> assertTrue(arraysMatch(firstArray,secondArray,false),"shallow comparison of 
> like number values should match");
> +                     
> assertTrue(objectsMatch(firstArray,secondArray,true),"deep comparison of like 
> number values should match (using objectMatch)");
> +                     
> assertTrue(objectsMatch(firstArray,secondArray,false),"shallow comparison of 
> like number values should match (using objectMatch)");
> +
> +                     secondArray.push(7);
> +                     
> assertFalse(arraysMatch(firstArray,secondArray,true),"deep comparison should 
> not match when lengths are different");
> +                     
> assertFalse(arraysMatch(firstArray,secondArray,false),"shallow comparison 
> should not match when lengths are different");
> +                     // 
> assertFalse(objectsMatch(firstArray,secondArray,true),"deep comparison should 
> not match when lengths are different (using objectMatch)");
> +                     // 
> assertFalse(objectsMatch(firstArray,secondArray,false),"shallow comparison 
> should not match when lengths are different (using objectMatch)");
> +
> +                     var first:Object = 
> {name:"foo",age:10,human:false,children:[{name:"bar",age:1},{name:"baz",age:2}]}
> +                     var second:Object = 
> {name:"foo",age:10,human:false,children:[{name:"bar",age:1},{name:"baz",age:2}]}
> +                     firstArray = [1,2,3,"4",5,first];
> +                     secondArray = [1,2,3,"4",5,second];
> +
> +                     
> assertTrue(arraysMatch(firstArray,secondArray,true),"deep array comparison 
> with nested object should match");
> +                     
> assertFalse(arraysMatch(firstArray,secondArray,false),"shallow array 
> comparison with nested object should not match");
> +                     // 
> assertTrue(objectsMatch(firstArray,secondArray,true),"deep array comparison 
> with nested object should match (using objectMatch)");
> +                     // 
> assertFalse(objectsMatch(firstArray,secondArray,false),"shallow array 
> comparison with nested object should not match (using objectMatch)");
> +
> +             }
>       }
> }
> \ No newline at end of file

Reply via email to