You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2020/11/24 05:46:17 UTC

[royale-asjs] branch develop updated: Fixes for Array sort with RETURNINDEXEDARRAY with new unit tests added. More Array.sort/Array.sortOn test variations need to be added (e.g. UNIQUESORT)

This is an automated email from the ASF dual-hosted git repository.

gregdove 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 fd434cc  Fixes for Array sort with RETURNINDEXEDARRAY with new unit tests added. More Array.sort/Array.sortOn test variations need to be added (e.g. UNIQUESORT)
fd434cc is described below

commit fd434cc560fb684e876edef760e245ac22828b23
Author: greg-dove <gr...@gmail.com>
AuthorDate: Tue Nov 24 18:05:57 2020 +1300

    Fixes for Array sort with RETURNINDEXEDARRAY with new unit tests added. More Array.sort/Array.sortOn test variations need to be added (e.g. UNIQUESORT)
---
 .../src/test/royale/flexUnitTests/CoreTester.as    |   2 +-
 .../language/LanguageTesterArraySort.as            | 140 +++++++++++++++++++++
 .../language/LanguageTesterTestLoopVariants.as     |   2 +-
 .../royale/org/apache/royale/utils/Language.as     |  56 +++++++--
 4 files changed, 187 insertions(+), 13 deletions(-)

diff --git a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
index 551890d..bf2ead4 100644
--- a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
@@ -31,7 +31,7 @@ package flexUnitTests
         public var languageTestVector:LanguageTesterTestVector;
         public var languageTestClass:LanguageTesterTestClass;
         public var languageTestLoopVariants:LanguageTesterTestLoopVariants;
-        
+        public var languageTestArraySort:LanguageTesterArraySort;
         
         //core tests
         public var strandTesterTest:StrandTesterTest;
diff --git a/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterArraySort.as b/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterArraySort.as
new file mode 100644
index 0000000..149ebaa
--- /dev/null
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterArraySort.as
@@ -0,0 +1,140 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flexUnitTests.language
+{
+    
+    
+    import org.apache.royale.test.asserts.*;
+    
+    import flexUnitTests.language.support.*;
+
+
+
+/**
+     * @royalesuppresspublicvarwarning
+     */
+    public class LanguageTesterArraySort
+    {
+    
+        public static var isJS:Boolean = COMPILE::JS;
+    
+    
+        [BeforeClass]
+        public static function setUpBeforeClass():void
+        {
+        }
+        
+        [AfterClass]
+        public static function tearDownAfterClass():void
+        {
+        }
+        
+        [Before]
+        public function setUp():void
+        {
+        
+        }
+        
+        [After]
+        public function tearDown():void
+        {
+        }
+
+
+        [Test]
+        public function testSortOnIndexedArray():void
+        {
+            var arr:Array = [{'value':2},{'value':4},{'value':6},{'value':8},{'value':10}];
+            var ret:Array;
+            //without Array.RETURNINDEXEDARRAY
+            ret = arr.sortOn('value', Array.NUMERIC|Array.DESCENDING);
+
+            assertEquals(JSON.stringify(arr), '[{"value":10},{"value":8},{"value":6},{"value":4},{"value":2}]', 'unexpected result');
+            assertEquals(arr,ret, 'unexpected result');
+            //with Array.RETURNINDEXEDARRAY
+            arr = [{'value':2},{'value':4},{'value':6},{'value':8},{'value':10}];
+            ret = arr.sortOn('value',Array.NUMERIC|Array.DESCENDING|Array.RETURNINDEXEDARRAY);
+
+
+            assertEquals(JSON.stringify(arr), '[{"value":2},{"value":4},{"value":6},{"value":8},{"value":10}]', 'unexpected result');
+            assertNotEquals(arr,ret, 'unexpected result');
+            assertEquals(ret.join(','), '4,3,2,1,0', 'unexpected result');
+
+            //with duplicate sortables
+            arr = [{'value':2, 'idx':0},{'value':4, 'idx':1},{'value':6, 'idx':2},{'value':8, 'idx':3},{'value':6, 'idx':4},{'value':2, 'idx':5},{'value':10, 'idx':6}];
+            //[{'value':10},{'value':8},{'value':6},{'value':6},{'value':4},{'value':2},{'value':2}]
+            //[6,3,4,2,1,0,5] or [6,3,2,4,1,0,5] or [6,3,4,2,1,5,0] or [6,3,2,4,1,5,0]
+            ret = arr.sortOn('value',Array.NUMERIC|Array.DESCENDING|Array.RETURNINDEXEDARRAY);
+            //"The array is modified to reflect the sort order; multiple elements that have identical sort fields
+            // are placed consecutively in the sorted array in no particular order."
+            var validResults:Array = ["6,3,4,2,1,0,5" , "6,3,2,4,1,0,5" , "6,3,4,2,1,5,0" , "6,3,2,4,1,5,0"];
+            //JSON field order can vary
+            var validJSONs:Array = [
+                '[{"value":2,"idx":0},{"value":4,"idx":1},{"value":6,"idx":2},{"value":8,"idx":3},{"value":6,"idx":4},{"value":2,"idx":5},{"value":10,"idx":6}]',
+                '[{"idx":0,"value":2},{"idx":1,"value":4},{"idx":2,"value":6},{"idx":3,"value":8},{"idx":4,"value":6},{"idx":5,"value":2},{"idx":6,"value":10}]'
+            ]
+
+            assertTrue(validJSONs.indexOf(JSON.stringify(arr))!=-1, 'unexpected result');
+            assertNotEquals(arr,ret, 'unexpected result');
+            assertTrue(validResults.indexOf(ret.join(',')) != -1, 'unexpected result');
+
+        }
+
+        [Test]
+        public function testSortIndexedArray():void
+        {
+            var arr:Array = [2,4,6,8,10];
+            var ret:Array;
+            //without Array.RETURNINDEXEDARRAY
+            ret = arr.sort(Array.NUMERIC|Array.DESCENDING);
+
+            assertEquals(arr.join(','), '10,8,6,4,2', 'unexpected result');
+            assertEquals(arr,ret, 'unexpected result');
+
+            //with Array.RETURNINDEXEDARRAY
+            arr = [2,4,6,8,10];
+            ret = arr.sort(Array.NUMERIC|Array.DESCENDING|Array.RETURNINDEXEDARRAY);
+
+            assertEquals(arr.join(','), '2,4,6,8,10', 'unexpected result');
+            assertNotEquals(arr,ret, 'unexpected result');
+            assertEquals(ret.join(','), '4,3,2,1,0', 'unexpected result');
+
+
+
+            //with duplicates
+            arr = [2,4,6,8,6,2,10];
+            //[10,8,6,6,4,2,2]
+            //[6,3,4,2,1,0,5] or [6,3,2,4,1,0,5] or [6,3,4,2,1,5,0] or [6,3,2,4,1,5,0]
+            ret = arr.sort(Array.NUMERIC|Array.DESCENDING|Array.RETURNINDEXEDARRAY);
+
+
+
+            //"The array is modified to reflect the sort order; multiple elements that have identical sort fields
+            // are placed consecutively in the sorted array in no particular order."
+            var validResults:Array = ["6,3,4,2,1,0,5" , "6,3,2,4,1,0,5" , "6,3,4,2,1,5,0" , "6,3,2,4,1,5,0"];
+
+            assertEquals(arr.join(','), '2,4,6,8,6,2,10', 'unexpected result');
+            assertNotEquals(arr,ret, 'unexpected result');
+            assertTrue(validResults.indexOf(ret.join(',')) != -1, 'unexpected result');
+        }
+
+
+        
+    }
+}
diff --git a/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterTestLoopVariants.as b/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterTestLoopVariants.as
index 65d72f5..5daf036 100644
--- a/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterTestLoopVariants.as
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/language/LanguageTesterTestLoopVariants.as
@@ -22,7 +22,7 @@ package flexUnitTests.language
     import org.apache.royale.test.asserts.*;
     import flexUnitTests.language.support.*;
     
-    import testshim.RoyaleUnitTestRunner;
+
     
     /**
      * @royalesuppresspublicvarwarning
diff --git a/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as b/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as
index 50810a8..368521e 100644
--- a/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as
+++ b/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as
@@ -294,15 +294,21 @@ package org.apache.royale.utils
         }
         
         /**
+         * Note this might mean testing for results is not matching across implementations:
+         * "The array is modified to reflect the sort order; multiple elements that have identical sort fields
+         *  are placed consecutively in the sorted array in no particular order."
+         *
+         *
          * @param arr
          * @param names
          * @param opt
-         *
+
          * @royaleignorecoercion Function
          */
-        public static function sort(arr:Array, ...args):void
+        public static function sort(arr:Array, ...args):Object
         {
             var compareFunction:Function = null;
+            var ret:Object;
             var opt:int = 0;
             if (args.length == 1)
             {
@@ -317,6 +323,11 @@ package org.apache.royale.utils
             }
             
             muler = (Array.DESCENDING & opt) > 0 ? -1 : 1;
+            var originals:Array;
+            if (opt & Array.RETURNINDEXEDARRAY) {
+                originals = arr;
+                arr = arr.slice(); //don't change the original
+            }
             if (compareFunction)
                 arr.sort(compareFunction);
             else if (opt & Array.NUMERIC)
@@ -329,6 +340,13 @@ package org.apache.royale.utils
             {
                 arr.sort(compareAsString);
             }
+            if (!(opt & Array.RETURNINDEXEDARRAY)) {
+                ret = arr;
+            } else {
+                ret = getIndexedArray(originals, arr);
+            }
+
+            return ret;
         }
         
         private static function compareAsStringCaseinsensitive(a:Object, b:Object):int
@@ -366,10 +384,15 @@ package org.apache.royale.utils
         }
         
         /**
+         * Note this might mean testing for results is not matching across implementations:
+         * "The array is modified to reflect the sort order; multiple elements that have identical sort fields
+         * are placed consecutively in the sorted array in no particular order."
+         *
          * @param arr
          * @param names
          * @param opt
          * @royaleignorecoercion Array
+         *
          */
         public static function sortOn(arr:Array, names:Object, opt:Object = 0):Array
         {
@@ -396,7 +419,8 @@ package org.apache.royale.utils
             var orig:Array;               
             if (opt2 & Array.RETURNINDEXEDARRAY)
             {
-                orig = arr.slice();                
+                orig = arr; //keep original unchanged
+                arr = arr.slice(); //work on a copy
             }
             if (opt2 & Array.NUMERIC)
             {
@@ -410,17 +434,27 @@ package org.apache.royale.utils
             }
             if (opt2 & Array.RETURNINDEXEDARRAY)
             {
-                var retArr:Array = [];
-                var n:int = arr.length;
-                for (var i:int = 0; i < n; i++)
-                {
-                    var item:Object = orig[i];
-                    retArr.push(arr.indexOf(item));
-                }
-                return retArr;
+                return getIndexedArray(orig, arr)
             }
             return arr;
         }
+
+        /**
+         *
+         */
+        private static function getIndexedArray(originals:Array, sorted:Array):Array{
+            var indexedOriginals:Array = originals.slice();
+            const substituteForFoundItem:Function = getIndexedArray; //use this reference as an 'impossible' substitute item to avoid finding the same value index twice
+            var n:int = sorted.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                var item:Object = sorted[i];
+                var idx:int = indexedOriginals.indexOf(item);
+                indexedOriginals[idx] = substituteForFoundItem; //substitute so don't find it again next time in case of duplicates
+                sorted[i] = idx;
+            }
+            return sorted;
+        }
         
         private static function compareStringCaseinsensitive(a:Object, b:Object):int
         {