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 2022/04/06 01:44:17 UTC

[royale-asjs] 02/02: Fix for an issue encountered with ObjectUtil.clone for Strings. Related: restored some commented-out code in UIDUtil. Added some initial ObjectUtil cloning tests.

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

commit 32555dea1f1b661f95f36c1f2b1beb9d9c2251fb
Author: greg-dove <gr...@gmail.com>
AuthorDate: Wed Apr 6 13:43:57 2022 +1200

    Fix for an issue encountered with ObjectUtil.clone for Strings. Related: restored some commented-out code in UIDUtil. Added some initial ObjectUtil cloning tests.
---
 .../src/main/royale/mx/utils/ObjectUtil.as         | 22 +++++++++-
 .../src/main/royale/mx/utils/UIDUtil.as            | 13 +++---
 .../flexUnitTests/mxroyale/ObjectUtilTest.as       | 47 ++++++++++++++++++----
 3 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/ObjectUtil.as b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/ObjectUtil.as
index 48d18c0abc..4392fa0ad2 100644
--- a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/ObjectUtil.as
+++ b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/ObjectUtil.as
@@ -199,13 +199,31 @@ public class ObjectUtil
         return result;
     }
 
+    /**
+     * Helper to abstract some VM-level differences
+     * @param value
+     * @return true if the value argument has a 'uid' property
+     */
+    private static function isUIDObject(value:Object):Boolean{
+        var ret:Boolean = false;
+        COMPILE::JS{
+            //in JS, the getter/setter for 'uid' is not considered an 'own' property, in SWF, it is, so we check also in the prototype chain if needed
+            ret = (value && (value.hasOwnProperty("uid") || ("uid" in value.constructor.prototype)))
+        }
+        COMPILE::SWF{
+            ret = (value && value.hasOwnProperty("uid"));
+        }
+        return ret;
+    }
+
     /**
      *  Recursive helper used by the public clone method.
      *  @private
      */
     private static function cloneInternal(result:Object, value:Object):void
     {
-        if (value && /*value.hasOwnProperty*/("uid" in value))
+
+        if (isUIDObject(value))
             result.uid = value.uid;
     
         var classInfo:Object = getClassInfo(value);
@@ -214,7 +232,7 @@ public class ObjectUtil
         {
             //@todo the following 'v = value[p]' will only be emulated safely in js by using reflection library:
             v = value[p];
-            if (v && /*v.hasOwnProperty*/("uid" in v))
+            if (isUIDObject(v))
                 cloneInternal(result[p], v);
         }
     }
diff --git a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/UIDUtil.as b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/UIDUtil.as
index f6f3cc5798..b0fb4465d8 100644
--- a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/UIDUtil.as
+++ b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/utils/UIDUtil.as
@@ -198,7 +198,11 @@ public class UIDUtil
                 IUID(item).uid = result;
             }
         }
-        else if ((item is IPropertyChangeNotifier) &&
+        //(GD) commented out the following 'else if' clause because I don't expect it should ever execute
+        // why: IPropertyChangeNotifier extends IUID, so any such item will have already passed the (item is IUID) check and caused previous code block to execute instead)
+        // therefore the (item is IPropertyChangeNotifier) check should always be false in 'else if' below
+        //@todo check this against Flex:
+        /*else if ((item is IPropertyChangeNotifier) &&
                  !(item is IUIComponent))
         {
             result = IPropertyChangeNotifier(item).uid;
@@ -207,7 +211,7 @@ public class UIDUtil
                 result = createUID();
                 IPropertyChangeNotifier(item).uid = result;
             }
-        }
+        }*/
         else if (item is String)
         {
             return item as String;
@@ -221,7 +225,7 @@ public class UIDUtil
                 if (item is XMLList && item.length == 1)
                     item = item[0];
 
-                /* LATER
+
                 if (item is XML)
                 {
                     // XML nodes carry their UID on the
@@ -255,7 +259,6 @@ public class UIDUtil
                 }
                 else
                 {
-                */
                     if ("mx_internal_uid" in item)
                         return item['mx_internal_uid']
 
@@ -283,7 +286,7 @@ public class UIDUtil
                             }
                         }
                     }
-                //}
+                }
             }
             catch(e:Error)
             {
diff --git a/frameworks/projects/MXRoyaleBase/src/test/royale/flexUnitTests/mxroyale/ObjectUtilTest.as b/frameworks/projects/MXRoyaleBase/src/test/royale/flexUnitTests/mxroyale/ObjectUtilTest.as
index 7c2bc51718..4a1797ae14 100644
--- a/frameworks/projects/MXRoyaleBase/src/test/royale/flexUnitTests/mxroyale/ObjectUtilTest.as
+++ b/frameworks/projects/MXRoyaleBase/src/test/royale/flexUnitTests/mxroyale/ObjectUtilTest.as
@@ -21,8 +21,9 @@ package flexUnitTests.mxroyale
     
     
     import mx.utils.ObjectUtil;
-    
-    import org.apache.royale.test.asserts.*;
+import mx.utils.UIDUtil;
+
+import org.apache.royale.test.asserts.*;
     import flexUnitTests.mxroyale.support.*;
     //import testshim.RoyaleUnitTestRunner;
     
@@ -357,12 +358,44 @@ package flexUnitTests.mxroyale
         }
     
     
-        /*[Test]
+        [Test]
         public function testCloning():void{
-            var item:TestClass6 = new TestClass6();
-        
-            
-        }*/
+            var s:String = "myString";
+
+            var out:Object = ObjectUtil.clone(s);
+
+            assertStrictlyEquals(s, out, 'unexpected String clone result');
+
+            var obj:Object = { test:'test'};
+            var inJSON:String = JSON.stringify(obj);
+            out = ObjectUtil.clone(obj);
+            assertStrictlyEquals(inJSON, JSON.stringify(out), 'unexpected dyn Object clone result');
+
+            UIDUtil.getUID(obj);
+            out = ObjectUtil.clone(obj);
+            //field order variation means JSON is not a valid way to compare:
+            assertTrue(simpleObjectCheckFields(obj, out), 'unexpected dyn Object clone result');
+
+        }
+
+        private static function simpleObjectCheckFields(obj1:Object, obj2:Object):Boolean{
+            if (obj1) {
+                if (!obj2) return false;
+                if (obj1 is String || obj1 is Number || obj1 is Boolean) return obj1 === obj2;
+                var obj1Count:uint = 0;
+                for (var field:String in obj1) {
+                    if (obj1[field] !== obj2[field]) return false;
+                    obj1Count++;
+                }
+                for (field in obj1) {
+                    obj1Count--;
+                }
+                if (obj1Count != 0) return false //mismatched field count
+            } else {
+                if (obj2) return false;
+            }
+            return true;
+        }
         
     }
 }