| 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 |