OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import "package:expect/expect.dart"; | 5 import "package:expect/expect.dart"; |
6 | 6 |
7 // Invocation and noSuchMethod testing. | 7 // Invocation and noSuchMethod testing. |
8 | 8 |
9 Map<Symbol, dynamic> listToNamedArguments(list) { | 9 Map<Symbol, dynamic> listToNamedArguments(list) { |
10 var iterator = list.iterator; | 10 var iterator = list.iterator; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 } | 51 } |
52 } | 52 } |
53 | 53 |
54 /** | 54 /** |
55 * Checks the data of an Invocation. | 55 * Checks the data of an Invocation. |
56 * | 56 * |
57 * Call without optionals for getters, with only positional for setters, | 57 * Call without optionals for getters, with only positional for setters, |
58 * and with both optionals for everything else. | 58 * and with both optionals for everything else. |
59 */ | 59 */ |
60 testInvocationMirror(Invocation im, Symbol name, | 60 testInvocationMirror(Invocation im, Symbol name, |
61 [List positional, List named]) { | 61 [List positional, List named, List typeArgs]) { |
62 Expect.isTrue(im is Invocation, "is Invocation"); | 62 Expect.isTrue(im is Invocation, "is Invocation"); |
63 Expect.equals(name, im.memberName, "name"); | 63 Expect.equals(name, im.memberName, "name"); |
64 if (named == null) { | 64 if (named == null) { |
65 Expect.isTrue(im.isAccessor, "$name:isAccessor"); | 65 Expect.isTrue(im.isAccessor, "$name:isAccessor"); |
66 Expect.isFalse(im.isMethod, "$name:isMethod"); | 66 Expect.isFalse(im.isMethod, "$name:isMethod"); |
67 if (positional == null) { | 67 if (positional == null) { |
68 Expect.isTrue(im.isGetter, "$name:isGetter"); | 68 Expect.isTrue(im.isGetter, "$name:isGetter"); |
69 Expect.isFalse(im.isSetter, "$name:isSetter"); | 69 Expect.isFalse(im.isSetter, "$name:isSetter"); |
70 Expect.equals(0, im.positionalArguments.length, "$name:#positional"); | 70 Expect.equals(0, im.positionalArguments.length, "$name:#positional"); |
71 Expect.equals(0, im.namedArguments.length, "$name:#named"); | 71 Expect.equals(0, im.namedArguments.length, "$name:#named"); |
(...skipping 15 matching lines...) Expand all Loading... |
87 | 87 |
88 Expect.listEquals(positional, im.positionalArguments); | 88 Expect.listEquals(positional, im.positionalArguments); |
89 | 89 |
90 Expect.equals( | 90 Expect.equals( |
91 namedArguments.length, im.namedArguments.length, "$name:#named"); | 91 namedArguments.length, im.namedArguments.length, "$name:#named"); |
92 namedArguments.forEach((k, v) { | 92 namedArguments.forEach((k, v) { |
93 Expect.isTrue( | 93 Expect.isTrue( |
94 im.namedArguments.containsKey(k), "$name:?namedArguments[$k]"); | 94 im.namedArguments.containsKey(k), "$name:?namedArguments[$k]"); |
95 Expect.equals(v, im.namedArguments[k], "$name:namedArguments[$k]"); | 95 Expect.equals(v, im.namedArguments[k], "$name:namedArguments[$k]"); |
96 }); | 96 }); |
| 97 var imTypeArgs = (im as dynamic).typeArguments as List<Type>; |
| 98 Expect.listEquals(typeArgs ?? [], imTypeArgs); |
97 } | 99 } |
98 | 100 |
99 // Test different ways that noSuchMethod can be called. | 101 // Test different ways that noSuchMethod can be called. |
100 testInvocationMirrors() { | 102 testInvocationMirrors() { |
101 var n = new N(); | 103 dynamic n = new N(); |
102 var c = new C(); | 104 dynamic c = new C(); |
103 | 105 |
104 // Missing property/method access. | 106 // Missing property/method access. |
105 testInvocationMirror(n.bar, const Symbol('bar')); | 107 testInvocationMirror(n.bar, const Symbol('bar')); |
106 testInvocationMirror((n..bar = 42).last, const Symbol('bar='), [42]); | 108 testInvocationMirror((n..bar = 42).last, const Symbol('bar='), [42]); |
107 testInvocationMirror(n.bar(), const Symbol('bar'), [], []); | 109 testInvocationMirror(n.bar(), const Symbol('bar'), [], []); |
108 testInvocationMirror(n.bar(42), const Symbol('bar'), [42], []); | 110 testInvocationMirror(n.bar(42), const Symbol('bar'), [42], []); |
109 testInvocationMirror( | 111 testInvocationMirror( |
110 n.bar(x: 42), const Symbol('bar'), [], [const Symbol("x"), 42]); | 112 n.bar(x: 42), const Symbol('bar'), [], [const Symbol("x"), 42]); |
111 testInvocationMirror( | 113 testInvocationMirror( |
112 n.bar(37, x: 42), const Symbol('bar'), [37], [const Symbol("x"), 42]); | 114 n.bar(37, x: 42), const Symbol('bar'), [37], [const Symbol("x"), 42]); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 var x = n.flif; | 188 var x = n.flif; |
187 x(37, 42); | 189 x(37, 42); |
188 }, (e) => e is NoSuchMethodError); | 190 }, (e) => e is NoSuchMethodError); |
189 Expect.throws(() { | 191 Expect.throws(() { |
190 var x = c.call; | 192 var x = c.call; |
191 x(37, 42); | 193 x(37, 42); |
192 }, (e) => e is NoSuchMethodError); | 194 }, (e) => e is NoSuchMethodError); |
193 } | 195 } |
194 | 196 |
195 class M extends N { | 197 class M extends N { |
196 noSuchMethod(Invocation m) { | 198 testSelfCalls() { |
197 throw "never get here"; | |
198 } | |
199 | |
200 testSuperCalls() { | |
201 // Missing property/method access. | 199 // Missing property/method access. |
202 testInvocationMirror(super.bar, const Symbol('bar')); | 200 dynamic self = this; |
| 201 testInvocationMirror(self.bar, const Symbol('bar')); |
203 testInvocationMirror(() { | 202 testInvocationMirror(() { |
204 super.bar = 42; | 203 self.bar = 42; |
205 return last; | 204 return last; |
206 }(), const Symbol('bar='), [42]); | 205 }(), const Symbol('bar='), [42]); |
207 testInvocationMirror(super.bar(), const Symbol('bar'), [], []); | 206 testInvocationMirror(self.bar(), const Symbol('bar'), [], []); |
208 testInvocationMirror(super.bar(42), const Symbol('bar'), [42], []); | 207 testInvocationMirror(self.bar(42), const Symbol('bar'), [42], []); |
209 testInvocationMirror( | 208 testInvocationMirror( |
210 super.bar(x: 42), const Symbol('bar'), [], [const Symbol("x"), 42]); | 209 self.bar(x: 42), const Symbol('bar'), [], [const Symbol("x"), 42]); |
211 testInvocationMirror(super.bar(37, x: 42), const Symbol('bar'), [37], | 210 testInvocationMirror(self.bar(37, x: 42), const Symbol('bar'), [37], |
212 [const Symbol("x"), 42]); | 211 [const Symbol("x"), 42]); |
213 | 212 |
214 // Missing operator access. | 213 // Missing operator access. |
215 testInvocationMirror(super + 4, const Symbol('+'), [4], []); | 214 testInvocationMirror(self + 4, const Symbol('+'), [4], []); |
216 testInvocationMirror(super - 4, const Symbol('-'), [4], []); | 215 testInvocationMirror(self - 4, const Symbol('-'), [4], []); |
217 testInvocationMirror(-super, const Symbol('unary-'), [], []); | 216 testInvocationMirror(-self, const Symbol('unary-'), [], []); |
218 testInvocationMirror(super[42], const Symbol('[]'), [42], []); | 217 testInvocationMirror(self[42], const Symbol('[]'), [42], []); |
219 testInvocationMirror(() { | 218 testInvocationMirror(() { |
220 super[37] = 42; | 219 self[37] = 42; |
221 return last; | 220 return last; |
222 }(), const Symbol('[]='), [37, 42], []); | 221 }(), const Symbol('[]='), [37, 42], []); |
223 | 222 |
224 // Wrong arguments to existing function. | 223 // Wrong arguments to existing function. |
225 testInvocationMirror(super.flif(), const Symbol("flif"), [], []); | 224 testInvocationMirror(self.flif(), const Symbol("flif"), [], []); |
| 225 testInvocationMirror(self.flif(37, 42), const Symbol("flif"), [37, 42], []); |
226 testInvocationMirror( | 226 testInvocationMirror( |
227 super.flif(37, 42), const Symbol("flif"), [37, 42], []); | 227 self.flif(x: 42), const Symbol("flif"), [], [const Symbol("x"), 42]); |
228 testInvocationMirror( | 228 testInvocationMirror(self.flif(37, x: 42), const Symbol("flif"), [37], |
229 super.flif(x: 42), const Symbol("flif"), [], [const Symbol("x"), 42]); | |
230 testInvocationMirror(super.flif(37, x: 42), const Symbol("flif"), [37], | |
231 [const Symbol("x"), 42]); | 229 [const Symbol("x"), 42]); |
232 testInvocationMirror(() { | 230 testInvocationMirror(() { |
233 super.flif = 42; | 231 self.flif = 42; |
234 return last; | 232 return last; |
235 }(), const Symbol("flif="), [42]); | 233 }(), const Symbol("flif="), [42]); |
236 | 234 |
| 235 testInvocationMirror(self.flaf(37, 42), const Symbol("flaf"), [37, 42], []); |
237 testInvocationMirror( | 236 testInvocationMirror( |
238 super.flaf(37, 42), const Symbol("flaf"), [37, 42], []); | 237 self.flaf(x: 42), const Symbol("flaf"), [], [const Symbol("x"), 42]); |
239 testInvocationMirror( | 238 testInvocationMirror(self.flaf(37, x: 42), const Symbol("flaf"), [37], |
240 super.flaf(x: 42), const Symbol("flaf"), [], [const Symbol("x"), 42]); | |
241 testInvocationMirror(super.flaf(37, x: 42), const Symbol("flaf"), [37], | |
242 [const Symbol("x"), 42]); | 239 [const Symbol("x"), 42]); |
243 testInvocationMirror(() { | 240 testInvocationMirror(() { |
244 super.flaf = 42; | 241 self.flaf = 42; |
245 return last; | 242 return last; |
246 }(), const Symbol("flaf="), [42]); | 243 }(), const Symbol("flaf="), [42]); |
247 | 244 |
| 245 testInvocationMirror(self.flof(37, 42), const Symbol("flof"), [37, 42], []); |
248 testInvocationMirror( | 246 testInvocationMirror( |
249 super.flof(37, 42), const Symbol("flof"), [37, 42], []); | 247 self.flof(x: 42), const Symbol("flof"), [], [const Symbol("x"), 42]); |
250 testInvocationMirror( | 248 testInvocationMirror(self.flof(37, y: 42), const Symbol("flof"), [37], |
251 super.flof(x: 42), const Symbol("flof"), [], [const Symbol("x"), 42]); | |
252 testInvocationMirror(super.flof(37, y: 42), const Symbol("flof"), [37], | |
253 [const Symbol("y"), 42]); | 249 [const Symbol("y"), 42]); |
254 testInvocationMirror(() { | 250 testInvocationMirror(() { |
255 super.flof = 42; | 251 self.flof = 42; |
256 return last; | 252 return last; |
257 }(), const Symbol("flof="), [42]); | 253 }(), const Symbol("flof="), [42]); |
258 | 254 |
259 // Reading works. | 255 // Reading works. |
260 Expect.isTrue(super.flif is Function); | 256 Expect.isTrue(self.flif is Function); |
261 Expect.isTrue(super.flaf is Function); | 257 Expect.isTrue(self.flaf is Function); |
262 Expect.isTrue(super.flof is Function); | 258 Expect.isTrue(self.flof is Function); |
263 | 259 |
264 // Writing to read-only fields. | 260 // Writing to read-only fields. |
265 testInvocationMirror(() { | 261 testInvocationMirror(() { |
266 super.wut = 42; | 262 self.wut = 42; |
267 return last; | 263 return last; |
268 }(), const Symbol("wut="), [42]); | 264 }(), const Symbol("wut="), [42]); |
269 testInvocationMirror(() { | 265 testInvocationMirror(() { |
270 super.plif = 42; | 266 self.plif = 42; |
271 return last; | 267 return last; |
272 }(), const Symbol("plif="), [42]); | 268 }(), const Symbol("plif="), [42]); |
273 testInvocationMirror(() { | 269 testInvocationMirror(() { |
274 super.plaf = 42; | 270 self.plaf = 42; |
275 return last; | 271 return last; |
276 }(), const Symbol("plaf="), [42]); | 272 }(), const Symbol("plaf="), [42]); |
277 | 273 |
278 // Calling noSuchMethod itself, badly. | 274 // Calling noSuchMethod itself, badly. |
279 testInvocationMirror( | 275 testInvocationMirror( |
280 super.noSuchMethod(), const Symbol("noSuchMethod"), [], []); | 276 self.noSuchMethod(), const Symbol("noSuchMethod"), [], []); |
281 testInvocationMirror( | 277 testInvocationMirror( |
282 super.noSuchMethod(37, 42), const Symbol("noSuchMethod"), [37, 42], []); | 278 self.noSuchMethod(37, 42), const Symbol("noSuchMethod"), [37, 42], []); |
283 testInvocationMirror(super.noSuchMethod(37, x: 42), | 279 testInvocationMirror(self.noSuchMethod(37, x: 42), |
284 const Symbol("noSuchMethod"), [37], [const Symbol("x"), 42]); | 280 const Symbol("noSuchMethod"), [37], [const Symbol("x"), 42]); |
285 testInvocationMirror(super.noSuchMethod(x: 42), | 281 testInvocationMirror(self.noSuchMethod(x: 42), const Symbol("noSuchMethod"), |
286 const Symbol("noSuchMethod"), [], [const Symbol("x"), 42]); | 282 [], [const Symbol("x"), 42]); |
287 | 283 |
288 // Closurizing a method means that calling it badly will not hit the | 284 // Closurizing a method means that calling it badly will not hit the |
289 // original receivers noSuchMethod, only the one inherited from Object | 285 // original receivers noSuchMethod, only the one inherited from Object |
290 // by the closure object. | 286 // by the closure object. |
291 Expect.throws(() { | 287 Expect.throws(() { |
292 var x = super.flif; | 288 var x = self.flif; |
293 x(37, 42); | 289 x(37, 42); |
294 }, (e) => e is NoSuchMethodError); | 290 }, (e) => e is NoSuchMethodError); |
295 } | 291 } |
296 } | 292 } |
297 | 293 |
298 // Test the NoSuchMethodError thrown by different incorrect calls. | 294 // Test the NoSuchMethodError thrown by different incorrect calls. |
299 testNoSuchMethodErrors() { | 295 testNoSuchMethodErrors() { |
300 test(Function block) { | 296 test(block()) { |
301 Expect.throws(block, (e) => e is NoSuchMethodError); | 297 Expect.throws(block, (e) => e is NoSuchMethodError); |
302 } | 298 } |
303 | 299 |
304 var n = new N(); | 300 dynamic n = new N(); |
305 var o = new Object(); | 301 dynamic o = new Object(); |
306 test(() => o.bar); | 302 test(() => o.bar); |
307 test(() => o.bar = 42); | 303 test(() => o.bar = 42); |
308 test(() => o.bar()); | 304 test(() => o.bar()); |
309 test(() => o + 2); | 305 test(() => o + 2); |
310 test(() => -o); | 306 test(() => -o); |
311 test(() => o[0]); | 307 test(() => o[0]); |
312 test(() => o[0] = 42); | 308 test(() => o[0] = 42); |
313 test(() => o()); | 309 test(() => o()); |
314 test(() => o.toString = 42); | 310 test(() => o.toString = 42); |
315 test(() => o.toString(42)); | 311 test(() => o.toString(42)); |
316 test(() => o.toString(x: 37)); | 312 test(() => o.toString(x: 37)); |
317 test(() => o.hashCode = 42); | 313 test(() => o.hashCode = 42); |
318 test(() => o.hashCode()); // Thrown by int.noSuchMethod. | 314 test(() => o.hashCode()); // Thrown by int.noSuchMethod. |
319 test(() => (n.flif)()); // Extracted method has no noSuchMethod. | 315 test(() => (n.flif)()); // Extracted method has no noSuchMethod. |
320 } | 316 } |
321 | 317 |
322 main() { | 318 main() { |
323 testInvocationMirrors(); | 319 testInvocationMirrors(); |
324 testNoSuchMethodErrors(); | 320 testNoSuchMethodErrors(); |
325 new M().testSuperCalls(); | 321 new M().testSelfCalls(); |
326 } | 322 } |
OLD | NEW |