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 2019/11/08 21:15:59 UTC
[royale-asjs] branch develop updated: Adding coercion to reflection
setters. Should fix an issue reported in discussion thread. Added recent
Reflection test updates.
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 2dc3e90 Adding coercion to reflection setters. Should fix an issue reported in discussion thread. Added recent Reflection test updates.
2dc3e90 is described below
commit 2dc3e90b3c56ba2ccecd32ee3eae2e8ea19c892c
Author: greg-dove <gr...@gmail.com>
AuthorDate: Sat Nov 9 10:15:40 2019 +1300
Adding coercion to reflection setters. Should fix an issue reported in discussion thread.
Added recent Reflection test updates.
---
.../apache/royale/reflection/AccessorDefinition.as | 6 +
.../apache/royale/reflection/VariableDefinition.as | 6 +
.../test/royale/flexUnitTests/ReflectionTester.as | 5 +-
.../reflection/ReflectionTesterTestEdgeCases.as | 321 +++++++++++++++++++++
.../flexUnitTests/reflection/support/TestClass6.as | 91 ++++++
.../reflection/support/testnamespace.as | 26 ++
6 files changed, 454 insertions(+), 1 deletion(-)
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/AccessorDefinition.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/AccessorDefinition.as
index 72bea88..bc2c7b8 100644
--- a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/AccessorDefinition.as
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/AccessorDefinition.as
@@ -20,6 +20,7 @@ package org.apache.royale.reflection {
COMPILE::JS{
import goog.DEBUG;
+ import org.apache.royale.utils.Language;
}
COMPILE::SWF{
@@ -121,8 +122,11 @@ package org.apache.royale.reflection {
}
var fieldName:String = name;
if (uri) fieldName = QName.getAsObjectAccessFormat(uri, fieldName);
+ var valueClass:Class = getDefinitionByName(_rawData.type);
if (isStatic) {
_setter = function(value:*):* {
+ //coerce
+ value = Language.as(value, valueClass, true);
cl[fieldName] = value
}
} else {
@@ -130,6 +134,8 @@ package org.apache.royale.reflection {
if (goog.DEBUG) {
if (arguments.length != 2 || (!(instance is cl))) throw 'invalid setValue parameters';
}
+ //coerce
+ value = Language.as(value, valueClass, true);
instance[fieldName] = value;
}
}
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/VariableDefinition.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/VariableDefinition.as
index 8fef888..1c9b161 100755
--- a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/VariableDefinition.as
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/VariableDefinition.as
@@ -20,6 +20,7 @@ package org.apache.royale.reflection
{
COMPILE::JS{
import goog.DEBUG;
+ import org.apache.royale.utils.Language;
}
COMPILE::SWF{
@@ -121,12 +122,15 @@ package org.apache.royale.reflection
COMPILE::JS {
var f:Function = _rawData.get_set;
+ var valueClass:Class = getDefinitionByName(_rawData.type);
if (isStatic) {
_setter = function(value:*):* {
if (goog.DEBUG) {
if (arguments.length != 1) throw 'invalid setValue parameters';
//todo: more robust runtime checking of value here for debug mode
}
+ //coerce
+ value = Language.as(value, valueClass, true);
f(value);
}
} else {
@@ -135,6 +139,8 @@ package org.apache.royale.reflection
if (arguments.length != 2 || !instance) throw 'invalid setValue parameters';
//todo: more robust runtime checking of value here for debug mode
}
+ //coerce
+ value = Language.as(value, valueClass, true);
f(instance, value);
}
}
diff --git a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/ReflectionTester.as b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/ReflectionTester.as
index 63005aa..b9282b9 100644
--- a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/ReflectionTester.as
+++ b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/ReflectionTester.as
@@ -35,7 +35,8 @@ package flexUnitTests
ReflectionTesterTestUseCache,
ReflectionTesterTestAlias,
ReflectionTesterTestDynamic,
- ReflectionTesterNativeTypes
+ ReflectionTesterNativeTypes,
+ ReflectionTesterTestEdgeCases
];
}
@@ -48,5 +49,7 @@ package flexUnitTests
public var reflectionTesterDynamicTest:ReflectionTesterTestDynamic;
public var reflectionTesterNativeTypes:ReflectionTesterNativeTypes;
+
+ public var reflectionTesterTestEdgeCases:ReflectionTesterTestEdgeCases;
}
}
diff --git a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTestEdgeCases.as b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTestEdgeCases.as
new file mode 100644
index 0000000..ff4f6c0
--- /dev/null
+++ b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTestEdgeCases.as
@@ -0,0 +1,321 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.reflection
+{
+ import org.apache.royale.test.asserts.*;
+
+ import flexUnitTests.reflection.support.*;
+
+ import org.apache.royale.reflection.*;
+ import org.apache.royale.reflection.utils.getMembersWithNameMatch;
+ import org.apache.royale.reflection.utils.getMembersWithQNameMatch;
+ import org.apache.royale.reflection.utils.MemberTypes;
+ import org.apache.royale.reflection.utils.getMembers;
+
+
+ /**
+ * @royalesuppresspublicvarwarning
+ */
+ public class ReflectionTesterTestEdgeCases
+ {
+
+ 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 testUndefined():void
+ {
+ var test:* = getDefinitionByName('undefined');
+ assertTrue(test === undefined, 'getDefinitionByName for undefined should return undefined reference')
+
+ }
+
+
+ [Test]
+ public function testNull():void
+ {
+ var err:Boolean;
+ try{
+ var test:* = getDefinitionByName('null');
+ } catch(e:Error) {
+ err = true;
+ }
+ assertTrue(err, 'getDefinitionByName for null should throw an error')
+ }
+
+
+ [Test]
+ public function testCustomNamespace():void
+ {
+ var inst:TestClass6 = new TestClass6();
+ var def:TypeDefinition = describeType(inst);
+
+ var collection:Array;
+ var subset:Array;
+ collection = getMembers(def,false,MemberTypes.VARIABLES);
+
+ assertEquals(collection.length, 2, 'unexpected variable count');
+
+ subset = getMembersWithNameMatch(collection,'myVar');
+ assertEquals(subset.length, 1, 'unexpected variable count');
+ //default is public namespace
+ assertEquals(MemberDefinitionBase(subset[0]).uri, '', 'unexpected namespace from query');
+
+ subset = getMembersWithNameMatch(collection,'myVar', null, true);
+ assertEquals(subset.length, 2, 'unexpected variable count');
+
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myVar'), null);
+ assertEquals(subset.length, 1, 'unexpected variable count');
+
+ assertEquals(MemberDefinitionBase(subset[0]).uri, String(testnamespace), 'unexpected namespace from query');
+
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, '*'), null);
+ assertEquals(subset.length, 1, 'unexpected variable count');
+
+ assertEquals(MemberDefinitionBase(subset[0]).uri, String(testnamespace), 'unexpected namespace from query');
+
+ subset = getMembersWithQNameMatch(collection,null, null);
+ assertEquals(subset.length, 2, 'unexpected variable count');
+
+ collection = getMembers(def,false,MemberTypes.ACCESSORS);
+ assertEquals(collection.length, 2, 'unexpected accessor count');
+
+ collection = getMembers(def,false,MemberTypes.METHODS);
+ assertEquals(collection.length, 2, 'unexpected method count');
+
+ //no need to use extra scrutiny on the last two queries, because the variable tests already verified that.
+
+ //now try read/write
+ //first vars
+ var varDefinition:VariableDefinition;
+ collection = getMembers(def,false,MemberTypes.VARIABLES);
+ //public myVar
+ subset = getMembersWithNameMatch(collection,'myVar');
+ varDefinition = subset[0];
+ //read
+ assertEquals(varDefinition.getValue(inst), inst.myVar, 'unexpected variable read result');
+
+ //write
+ varDefinition.setValue(inst, 'setViaPublicReflection');
+ assertEquals('setViaPublicReflection', inst.myVar, 'unexpected variable write result');
+ //testnamespace::myVar
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myVar'), null);
+ varDefinition= subset[0];
+ //read
+ assertEquals(varDefinition.getValue(inst), inst.testnamespace::myVar, 'unexpected variable read result');
+ //write
+ varDefinition.setValue(inst, 'setViaCustomNSReflection');
+ assertEquals('setViaCustomNSReflection', inst.testnamespace::myVar, 'unexpected variable write result');
+ //next methods
+ var methodDefinition:MethodDefinition;
+ collection = getMembers(def,false,MemberTypes.METHODS);
+ subset = getMembersWithNameMatch(collection,'myMethod');
+ methodDefinition = subset[0];
+ //public myMethod
+ assertEquals(methodDefinition.getMethod(inst), inst.myMethod, 'unexpected method access result');
+ //testnamespace::myMethod
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myMethod'), null);
+ methodDefinition= subset[0];
+ //testnamespace myMethod
+ assertEquals(methodDefinition.getMethod(inst), inst.testnamespace::myMethod, 'unexpected method access result');
+
+ //next accessors
+ var accessorDefinition:AccessorDefinition;
+ collection = getMembers(def,false,MemberTypes.ACCESSORS);
+ subset = getMembersWithNameMatch(collection,'myAccessor');
+ accessorDefinition = subset[0];
+ //public myAccessor
+ //read
+ assertEquals(accessorDefinition.getValue(inst), inst.myAccessor, 'unexpected accessor access result');
+ //write
+ //this is readOnly, so...
+ var hasError:Boolean;
+ try{
+ accessorDefinition.setValue(inst, 'setViaPublicReflection');
+ } catch(e:Error) {
+ hasError = true;
+ }
+ assertTrue(hasError, 'unexpected non-error read-only access write result');
+
+ //testnamespace::myAccessor
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myAccessor'), null);
+ accessorDefinition = subset[0];
+ //testnamespace::myAccessor
+ //read
+ assertEquals(accessorDefinition.getValue(inst), inst.testnamespace::myAccessor, 'unexpected accessor access result');
+
+ accessorDefinition.setValue(inst, 'setViaCustomNSReflection');
+
+ assertEquals( inst.testnamespace::myAccessor,'setViaCustomNSReflection', 'unexpected accessor post-write access result');
+
+ }
+
+ [Test]
+ public function testCustomNamespaceStatic():void
+ {
+
+ var def:TypeDefinition = describeType(TestClass6);
+
+ var collection:Array;
+ var subset:Array;
+ collection = getMembers(def,true,MemberTypes.VARIABLES|MemberTypes.STATIC_ONLY);
+
+ assertEquals(collection.length, 2, 'unexpected variable count');
+
+ subset = getMembersWithNameMatch(collection,'myStaticVar');
+ assertEquals(subset.length, 1, 'unexpected variable count');
+ //default is public namespace
+ assertEquals(MemberDefinitionBase(subset[0]).uri, '', 'unexpected namespace from query');
+
+ subset = getMembersWithNameMatch(collection,'myStaticVar', null, true);
+ assertEquals(subset.length, 2, 'unexpected variable count');
+
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myStaticVar'), null);
+ assertEquals(subset.length, 1, 'unexpected variable count');
+
+ assertEquals(MemberDefinitionBase(subset[0]).uri, String(testnamespace), 'unexpected namespace from query');
+
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, '*'), null);
+ assertEquals(subset.length, 1, 'unexpected variable count');
+
+ assertEquals(MemberDefinitionBase(subset[0]).uri, String(testnamespace), 'unexpected namespace from query');
+
+ subset = getMembersWithQNameMatch(collection,null, null);
+ assertEquals(subset.length, 2, 'unexpected variable count');
+
+ collection = getMembers(def,true,MemberTypes.ACCESSORS|MemberTypes.STATIC_ONLY);
+ var expectedCount:uint = isJS ? 2 : 3; //SWF has 'prototype' also as a readonly accessor
+ assertEquals(collection.length, expectedCount, 'unexpected accessor count');
+
+ collection = getMembers(def,true,MemberTypes.METHODS|MemberTypes.STATIC_ONLY);
+ assertEquals(collection.length, 2, 'unexpected method count');
+
+ //no need to use extra scrutiny on the last two queries, because the variable tests already verified that.
+
+ //now try read/write
+ //first: vars
+ var varDefinition:VariableDefinition;
+ collection = getMembers(def,true,MemberTypes.VARIABLES|MemberTypes.STATIC_ONLY);
+ //public myVar
+ subset = getMembersWithNameMatch(collection,'myStaticVar');
+ varDefinition = subset[0];
+ //read
+ assertEquals(varDefinition.getValue(), TestClass6.myStaticVar, 'unexpected variable read result');
+
+ //write
+ varDefinition.setValue('setViaPublicReflection');
+ assertEquals('setViaPublicReflection', TestClass6.myStaticVar, 'unexpected variable write result');
+ //testnamespace::myVar
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myStaticVar'), null);
+ varDefinition= subset[0];
+ //read
+ assertEquals(varDefinition.getValue(), TestClass6.testnamespace::myStaticVar, 'unexpected variable read result');
+ //write
+ varDefinition.setValue('setViaCustomNSReflection');
+ assertEquals('setViaCustomNSReflection', TestClass6.testnamespace::myStaticVar, 'unexpected variable write result');
+ //next: methods
+ var methodDefinition:MethodDefinition;
+ collection = getMembers(def,true,MemberTypes.METHODS|MemberTypes.STATIC_ONLY);
+ subset = getMembersWithNameMatch(collection,'myStaticMethod');
+ methodDefinition = subset[0];
+ //public myMethod
+ assertEquals(methodDefinition.getMethod(), TestClass6.myStaticMethod, 'unexpected method access result');
+ //testnamespace::myMethod
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myStaticMethod'), null);
+ methodDefinition= subset[0];
+ //testnamespace myMethod
+ assertEquals(methodDefinition.getMethod(), TestClass6.testnamespace::myStaticMethod, 'unexpected method access result');
+
+ //next: accessors
+ var accessorDefinition:AccessorDefinition;
+ collection = getMembers(def,true,MemberTypes.ACCESSORS|MemberTypes.STATIC_ONLY);
+ subset = getMembersWithNameMatch(collection,'myStaticAccessor');
+ accessorDefinition = subset[0];
+ //public myAccessor
+ //read
+ assertEquals(accessorDefinition.getValue(), TestClass6.myStaticAccessor, 'unexpected accessor access result');
+ //write
+ //this is readOnly, so...
+ var hasError:Boolean;
+ try{
+ accessorDefinition.setValue('setViaPublicReflection');
+ } catch(e:Error) {
+ hasError = true;
+ }
+ assertTrue(hasError, 'unexpected non-error read-only access write result');
+
+ //testnamespace::myAccessor
+ subset = getMembersWithQNameMatch(collection,new QName(testnamespace, 'myStaticAccessor'), null);
+ accessorDefinition = subset[0];
+
+ //testnamespace::myAccessor
+ //read
+ assertEquals(accessorDefinition.getValue(), TestClass6.testnamespace::myStaticAccessor, 'unexpected accessor access result');
+
+ accessorDefinition.setValue('setViaCustomNSReflection');
+
+ assertEquals( TestClass6.testnamespace::myStaticAccessor,'setViaCustomNSReflection', 'unexpected accessor post-write access result');
+
+ }
+
+ [Test]
+ public function testWrongSetValueType():void{
+ var inst:TestClass1 = new TestClass1();
+
+ var def:TypeDefinition = describeType(inst);
+ var collection:Array;
+ var subset:Array;
+ collection = getMembers(def,false,MemberTypes.VARIABLES);
+ subset = getMembersWithNameMatch(collection,'testVar');
+ var testVarDef:VariableDefinition = subset[0];
+ //assign a Number to the String typed testVar member:
+ testVarDef.setValue(inst, 0.0);
+ assertStrictlyEquals(inst.testVar, '0', 'unexpected assigned value');
+ collection = getMembers(def,false,MemberTypes.ACCESSORS);
+ subset = getMembersWithNameMatch(collection,'accessorTest');
+ var accessorTestDef:AccessorDefinition = subset[0];
+ accessorTestDef.setValue(inst, 0.0);
+ assertStrictlyEquals(inst.accessorTest, '0', 'unexpected assigned value');
+ }
+
+ }
+}
diff --git a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/support/TestClass6.as b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/support/TestClass6.as
new file mode 100644
index 0000000..c5c34bf
--- /dev/null
+++ b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/support/TestClass6.as
@@ -0,0 +1,91 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.reflection.support
+{
+
+
+ /**
+ * @royalesuppresspublicvarwarning
+ */
+ public class TestClass6
+ {
+ //Note: do not change this test class unless you change the related tests to
+ //support any changes that might appear when testing reflection into it
+
+ public static var myStaticVar:String = 'publicStaticMyVar';
+
+ testnamespace static var myStaticVar:String = 'testnamespaceStaticMyVar';
+
+ public static function myStaticMethod():String{
+ return 'public myStaticMethod';
+ }
+
+ testnamespace static function myStaticMethod():String{
+ return 'testnamespace myStaticMethod';
+ }
+
+ private static var _vstatic:String = 'public static accessor';
+ public static function get myStaticAccessor():String{
+ return _vstatic;
+ }
+
+ private static var _v2static:String = 'testnamespace static accessor';
+ testnamespace static function get myStaticAccessor():String{
+ return _v2static;
+ }
+ testnamespace static function set myStaticAccessor(value:String):void{
+ _v2static = value;
+ }
+
+
+
+ public function TestClass6()
+ {
+
+ }
+
+ public var myVar:String = 'publicMyVar';
+
+ testnamespace var myVar:String = 'testnamespaceMyVar';
+
+ public function myMethod():String{
+ return 'public myMethod';
+ }
+
+ testnamespace function myMethod():String{
+ return 'testnamespace myMethod';
+ }
+
+ private var _v:String = 'public accessor';
+ public function get myAccessor():String{
+ return _v;
+ }
+
+ private var _v2:String = 'testnamespace accessor';
+ testnamespace function get myAccessor():String{
+ return _v2;
+ }
+ testnamespace function set myAccessor(value:String):void{
+ _v2 = value;
+ }
+
+ }
+
+
+}
diff --git a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/support/testnamespace.as b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/support/testnamespace.as
new file mode 100644
index 0000000..2544e8c
--- /dev/null
+++ b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/support/testnamespace.as
@@ -0,0 +1,26 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.reflection.support
+{
+
+
+
+ public namespace testnamespace = 'http://testnamespace.com';
+
+}