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 13b1158f9b Fixes #1185 and Fixes #1183. Also fixes a few other otherwise undocumented issues. (Requires compiler-jx update) 13b1158f9b is described below commit 13b1158f9b2e9d0afeefe250e219009c126bd0f7 Author: greg-dove <greg.d...@gmail.com> AuthorDate: Wed Apr 6 09:50:36 2022 +1200 Fixes #1185 and Fixes #1183. Also fixes a few other otherwise undocumented issues. (Requires compiler-jx update) --- frameworks/projects/XML/src/main/royale/XML.as | 72 ++++++++++++++++----- frameworks/projects/XML/src/main/royale/XMLList.as | 25 +++++++- .../flexUnitTests/xml/XMLListTesterGeneralTest.as | 22 +++++++ .../flexUnitTests/xml/XMLTesterGeneralTest.as | 73 ++++++++++++++++++++++ 4 files changed, 174 insertions(+), 18 deletions(-) diff --git a/frameworks/projects/XML/src/main/royale/XML.as b/frameworks/projects/XML/src/main/royale/XML.as index a2ed9bf429..b589b7e7b2 100644 --- a/frameworks/projects/XML/src/main/royale/XML.as +++ b/frameworks/projects/XML/src/main/royale/XML.as @@ -196,7 +196,35 @@ package else return ret; } else return new XML(source); } - + + /** + * Compiler-only method to support null-safe, non-strict equality checks between XML-ish types + * (although both arguments are typed as XML, XMLList is also possible at runtime) + * + * @private + * @royalesuppressexport + */ + public static function equality(xml1:XML, xml2:XML):Boolean{ + if (xml1 == null) return xml2 == null; + return xml2 != null ? xml1.equals(xml2) : false; + } + + /** + * Compiler-only method to support null-safe, non-strict equality checks between XML-ish known type + * and an unknown type. Although the first argument is typed as XML, it handles runtime usage with XMLList type as well + * + * @private + * @royaleignorecoercion XMLList + * @royaleignorecoercion XML + * @royalesuppressexport + */ + public static function mixedEquality(xml1:XML, other:*):Boolean{ + if (xml1 instanceof XMLList) return XMLList.mixedEquality(xml1 as XMLList, other); + if (xml1 == null) return other == null; + if (other instanceof XML) return xml1.equals((other as XML)); + if (typeof other == 'boolean') other = ('' + other);//force a string comparison + return xml1 == other; + } private static const ELEMENT:String = "e"; private static const ATTRIBUTE:String = "a"; @@ -604,6 +632,10 @@ package // _children = []; if(xml != null) { + if (xml instanceof XML) { + //js-only hack to return a copy from the constructor: + jsUnsafeNativeInline("return xml.copy()"); + } var xmlStr:String = "" + xml; if(xmlStr.indexOf("<") == -1) { @@ -1453,38 +1485,44 @@ package 10. Return true */ var i:int; - if (xml == this) return true; - - if(!(xml instanceof XML)) + if (xml === this) return true; + if (xml instanceof XMLList) { + if ((xml as XMLList).length() != 1) return false; //single + xml = (xml as XMLList)[0]; + } + else if(!(xml instanceof XML)) return false; var typedXML:XML = xml as XML; if(typedXML.getNodeRef() != getNodeRef()) return false; - - if(!name().equals(typedXML.name())) - return false; + if (_name) { + if (!typedXML._name || !_name.equals(typedXML._name)) return false //3a,b,c, above + } else if (typedXML._name) { + return false; //4 above + } var selfAttrs:Array = getAttributeArray(); var xmlAttrs:Array = typedXML.getAttributeArray(); if(selfAttrs.length != xmlAttrs.length) - return false; - //length comparison should not be necessary because xml always has a length of 1 + return false; //5 above + + var selfChldrn:Array = getChildrenArray(); + var xmlChildren:Array = typedXML.getChildrenArray(); + if(selfChldrn.length != xmlChildren.length) + return false; //6 above + if(getValue() != typedXML.getValue()) - return false; + return false; //7 above for(i=0;i<selfAttrs.length;i++) { if(!typedXML.hasAttribute(selfAttrs[i])) - return false; + return false; //8 above (hasAttribute checks both name and value in this case) } - var selfChldrn:Array = getChildrenArray(); - var xmlChildren:Array = typedXML.getChildrenArray(); - if(selfChldrn.length != xmlChildren.length) - return false; for(i=0;i<selfChldrn.length;i++) { if(!selfChldrn[i].equals(xmlChildren[i])) - return false; + return false;//9 above } return true; } @@ -3079,7 +3117,7 @@ package { var child:XML = _children[i]; var childKind:String = child.getNodeRef(); - if(child.childKind == COMMENT || child.childKind == PROCESSING_INSTRUCTION) + if(childKind == COMMENT || childKind == PROCESSING_INSTRUCTION) continue; s = s + child.toString(); } diff --git a/frameworks/projects/XML/src/main/royale/XMLList.as b/frameworks/projects/XML/src/main/royale/XMLList.as index 937c4d8365..e5882c9a14 100644 --- a/frameworks/projects/XML/src/main/royale/XMLList.as +++ b/frameworks/projects/XML/src/main/royale/XMLList.as @@ -40,6 +40,29 @@ package if (val && val.constructor == XMLList) return val as XMLList; else return new XMLList(val); } + + /** + * Compiler-only method to support null-safe, non-strict equality checks between XMLList and + * 'unknown' type + * + * @private + * @royaleignorecoercion XMLList + * @royaleignorecoercion Object + * @royalesuppressexport + */ + public static function mixedEquality(list:XMLList, other:*):Boolean{ + if (list == null ) { + return other == null; + } + if (other === undefined) { + return list.isEmpty(); + } + if (other instanceof XMLList) { + return list.equals(other as XMLList); + } + if (typeof other == 'boolean') other = ('' + other);//force a string comparison + return (list as Object) == other; + } public function XMLList(expression:Object = null) { @@ -1365,7 +1388,7 @@ package override public function valueOf():* { if(isEmpty()) - return ""; + return undefined; if(isSingle()) return _xmlArray[0].valueOf(); diff --git a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as index 87966dae83..d36cc67d21 100644 --- a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as +++ b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLListTesterGeneralTest.as @@ -393,5 +393,27 @@ package flexUnitTests.xml var test:Object = <xml>test</xml>; return XMLList(test); } + + [Test] + public function testEquality():void{ + var node:XML = <type type="without name attribute"/>; + + var list:XMLList = node.@name; + var Null:* = null; + var Undefined:* = undefined; +//the above is just so the very last trace comparison below does not give warnings or errors in compiler, the earlier checks can also be done with the literal null/undefined + + assertFalse(node.@name == "", 'unexpected equality with empty string for empty list'); + assertFalse((node.@name == Null))//false + assertTrue((node.@name == Undefined))//true in flash (false in Royale) + + //The following passes in flash, but fails in JS: + // assertFalse((list.valueOf() == Null))//false in flash (true in Royale) + assertFalse((list.valueOf() == ""))//false in flash (true in Royale) + assertTrue((list.valueOf() == Undefined))//true in flash (false in Royale) +//conclusion: XMLList.valueOf should return undefined for empty list +//but in JS, list.valueOf() == Null, because: + assertTrue((Null == Undefined))//true + } } } diff --git a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as index 7f4ce1e981..e04cf07ab6 100644 --- a/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as +++ b/frameworks/projects/XML/src/test/royale/flexUnitTests/xml/XMLTesterGeneralTest.as @@ -1577,9 +1577,82 @@ package flexUnitTests.xml assertTrue(check, 'unexpected numeric inequality (strict)'); + //non-existent 'properties' + //non-existent attribute + check = list[0].@value == undefined; + assertTrue(check, 'unexpected undefined inequality (non-strict)'); + check = list[0].@value != undefined; + assertFalse(check, 'unexpected undefined inequality (non-strict)'); + + check = list[0].@value === undefined; + assertFalse(check, 'unexpected undefined equality (strict)'); + + check = list[0].@value !== undefined; + assertTrue(check, 'unexpected undefined inequality (strict)'); + + check = list[0].@value == null; + assertFalse(check, 'unexpected null equality (non-strict)'); + + check = list[0].@value != null; + assertTrue(check, 'unexpected null equality (non-strict)'); + + check = list[0].@value == ''; + assertFalse(check, 'unexpected undefined equality (strict)'); + + //non-existent child + check = xmlInst.notAChild == undefined; + assertTrue(check, 'unexpected undefined inequality (non-strict)'); + + check = xmlInst.notAChild != undefined; + assertFalse(check, 'unexpected undefined inequality (non-strict)'); + + check = xmlInst.notAChild === undefined; + assertFalse(check, 'unexpected undefined equality (strict)'); + + check = xmlInst.notAChild !== undefined; + assertTrue(check, 'unexpected undefined inequality (strict)'); + + check = xmlInst.notAChild == null; + assertFalse(check, 'unexpected null equality (non-strict)'); + + check = xmlInst.notAChild != null; + assertTrue(check, 'unexpected null equality (non-strict)'); + + check = xmlInst.notAChild == ''; + assertFalse(check, 'unexpected undefined equality (strict)'); + + + } + + [Test] + public function testConstructorXMLArgument():void{ + + var xml1:XML = <test something="something"></test>; + var xml2:XML = <test something="something">something</test>; + var xml3:XML = <test something="something"><something/></test>; + + var choice:XML = xml1; + var other:XML = new XML(choice); + + + assertTrue(choice == other, 'unexpected inequality'); + assertFalse(choice != other, 'unexpected inequality'); + assertFalse(choice === other, 'unexpected strict equality'); + + choice = xml2; + other = new XML(choice); + assertTrue(choice == other, 'unexpected inequality'); + assertFalse(choice != other, 'unexpected inequality'); + assertFalse(choice === other, 'unexpected strict equality'); + + choice = xml3; + other = new XML(choice); + assertTrue(choice == other, 'unexpected inequality'); + assertFalse(choice != other, 'unexpected inequality'); + assertFalse(choice === other, 'unexpected strict equality'); } } }