1
16
17 import org.as2lib.env.except.IllegalArgumentException;
18 import org.as2lib.env.overload.Overload;
19 import org.as2lib.env.reflect.MethodInfo;
20 import org.as2lib.env.reflect.ConstructorInfo;
21 import org.as2lib.env.reflect.ClassInfo;
22 import org.as2lib.test.speed.AbstractTest;
23 import org.as2lib.test.speed.Test;
24 import org.as2lib.test.speed.SimpleTestSuiteResult;
25 import org.as2lib.test.speed.MethodInvocation;
26
27
34 class org.as2lib.test.speed.MethodTestCase extends AbstractTest implements Test {
35
36
37 private static var __proto__:Function = AbstractTest;
38
39
40 private static var p:MethodInvocation;
41
42
43 private var method:MethodInfo;
44
45
46 private var s;
47
48
49 private var n:String;
50
51
57 public function MethodTestCase() {
58 var o:Overload = new Overload(this);
59 o.addHandler([], MethodTestCaseByVoid);
60 o.addHandler([MethodInfo], MethodTestCaseByMethod);
61 o.addHandler([MethodInfo, Object, String], MethodTestCaseByMethod);
62 o.addHandler([Object, Function], MethodTestCaseByObjectAndMethod);
63 o.addHandler([Object, String], MethodTestCaseByObjectAndName);
64 o.forward(arguments);
65 }
66
67
71 private function MethodTestCaseByVoid(Void):Void {
72 MethodTestCaseByObjectAndName(this, "doRun");
73 }
74
75
89 private function MethodTestCaseByMethod(method:MethodInfo, referenceScope, referenceName:String):Void {
90 if (!method) {
91 throw new IllegalArgumentException("Argument 'method' [" + method + "] must not be 'null' nor 'undefined' or this instance must declare a method named 'doRun'.", this, arguments);
92 }
93 this.method = method.snapshot();
94 if (referenceScope) {
95 this.s = referenceScope;
96 } else {
97 if (method instanceof ConstructorInfo) {
98 this.s = method.getDeclaringType().getPackage().getPackage();
99 } else if (method.isStatic()) {
100 this.s = method.getDeclaringType().getType();
101 } else {
102 this.s = method.getDeclaringType().getType().prototype;
103 }
104 }
105 if (referenceName) {
106 this.n = referenceName;
107 } else {
108 if (method instanceof ConstructorInfo) {
109 this.n = method.getDeclaringType().getName();
110 } else {
111 this.n = method.getName();
112 }
113 }
114 setResult(new SimpleTestSuiteResult(method.getFullName()));
115 }
116
117
125 private function MethodTestCaseByObjectAndMethod(object, method:Function):Void {
126 if (object == null || !method) {
127 throw new IllegalArgumentException("Neither argument 'object' [" + object + "] nor 'method' [" + method + "] is allowed to be 'null' or 'undefined'.");
128 }
129 var c:ClassInfo = ClassInfo.forObject(object);
130 MethodTestCaseByMethod(c.getMethodByMethod(method));
131 }
132
133
141 private function MethodTestCaseByObjectAndName(object, methodName:String):Void {
142 if (!object[methodName]) {
143 throw new IllegalArgumentException("Method [" + object[methodName] + "] with name '" + methodName + "' on object [" + object + "] must not be 'null' nor 'undefined'.");
144 }
145 if (typeof(object[methodName]) != "function") {
146 throw new IllegalArgumentException("Method [" + object[methodName] + "] with name '" + methodName + "' on object [" + object + "] must be of type 'function'.");
147 }
148 var c:ClassInfo = ClassInfo.forObject(object);
149 if (c.hasMethod(methodName)) {
150 MethodTestCaseByMethod(c.getMethodByName(methodName));
151 } else {
152 var m:MethodInfo = new MethodInfo(methodName, c, false, object[methodName]);
153 MethodTestCaseByMethod(m, object, methodName);
154 }
155 }
156
157
162 public function getMethod(Void):MethodInfo {
163 return this.method;
164 }
165
166
169 public function run(Void):Void {
170 this.s[this.n] = createClosure();
171 }
172
173
178 private function createClosure(Void):Function {
179 var t:MethodTestCase = this;
180 var mi:MethodInfo = this.method;
181 var m:Function = this.method.getMethod();
182 var closure:Function = function() {
183 var i:MethodInvocation = t["c"]();
184 i.setPreviousMethodInvocation(MethodTestCase["p"]);
185 i.setArguments(arguments);
186 i.setCaller(arguments.caller.__as2lib__i);
187 m.__as2lib__i = i;
188 var b:Number = getTimer();
189 try {
190 var r = mi.invoke(this, arguments);
191 i.setTime(getTimer() - b);
192 i.setReturnValue(r);
193 return r;
194 } catch (e) {
195 i.setTime(getTimer() - b);
196 i.setException(e);
197 throw e;
198 } finally {
199 t["a"](i);
200 MethodTestCase["p"] = i;
201 delete m.__as2lib__i;
202 }
203 };
204 closure.valueOf = function():Object {
205 return m;
206 };
207
208 closure.__proto__ = m.__proto__;
209 closure.prototype = m.prototype;
210 closure.__constructor__ = m.__constructor__;
211 closure.constructor = m.constructor;
212 return closure;
213 }
214
215
220 private function c(Void):MethodInvocation {
221 return new MethodInvocation(this.method);
222 }
223
224
229 private function a(m:MethodInvocation):Void {
230 this.result.addTestResult(m);
231 }
232
233 }