OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 /// Common test code that is run by 3 tests: mirrors_test.dart, |
| 6 /// mirrors_used_test.dart, and static_test.dart. |
| 7 library smoke.test.common; |
| 8 |
| 9 import 'package:smoke/smoke.dart' as smoke; |
| 10 import 'package:unittest/unittest.dart'; |
| 11 |
| 12 main() { |
| 13 test('read value', () { |
| 14 var a = new A(); |
| 15 expect(smoke.read(a, #i), 42); |
| 16 expect(smoke.read(a, #j), 44); |
| 17 expect(smoke.read(a, #j2), 44); |
| 18 }); |
| 19 |
| 20 test('write value', () { |
| 21 var a = new A(); |
| 22 smoke.write(a, #i, 43); |
| 23 expect(a.i, 43); |
| 24 smoke.write(a, #j2, 46); |
| 25 expect(a.j, 46); |
| 26 expect(a.j2, 46); |
| 27 expect(smoke.read(a, #j), 46); |
| 28 expect(smoke.read(a, #j2), 46); |
| 29 }); |
| 30 |
| 31 test('invoke', () { |
| 32 var a = new A(); |
| 33 |
| 34 smoke.invoke(a, #inc0, []); |
| 35 expect(a.i, 43); |
| 36 expect(smoke.read(a, #i), 43); |
| 37 expect(() => smoke.invoke(a, #inc0, [2]), throws); |
| 38 expect(a.i, 43); |
| 39 expect(() => smoke.invoke(a, #inc0, [1, 2, 3]), throws); |
| 40 expect(a.i, 43); |
| 41 |
| 42 // TODO(jakemac): Restore this once http://dartbug.com/22917 is fixed. |
| 43 // expect(() => smoke.invoke(a, #inc1, []), throws); |
| 44 expect(a.i, 43); |
| 45 smoke.invoke(a, #inc1, [4]); |
| 46 expect(a.i, 47); |
| 47 |
| 48 smoke.invoke(a, #inc2, []); |
| 49 expect(a.i, 37); |
| 50 smoke.invoke(a, #inc2, [4]); |
| 51 expect(a.i, 41); |
| 52 |
| 53 expect(() => smoke.invoke(a, #inc1, [4, 5]), throws); |
| 54 expect(a.i, 41); |
| 55 }); |
| 56 |
| 57 test('static invoke', () { |
| 58 A.staticValue = 42; |
| 59 smoke.invoke(A, #staticInc, []); |
| 60 expect(A.staticValue, 43); |
| 61 }); |
| 62 |
| 63 test('read and invoke function', () { |
| 64 var a = new A(); |
| 65 expect(a.i, 42); |
| 66 var f = smoke.read(a, #inc1); |
| 67 f(4); |
| 68 expect(a.i, 46); |
| 69 Function.apply(f, [4]); |
| 70 expect(a.i, 50); |
| 71 }); |
| 72 |
| 73 test('invoke with adjust', () { |
| 74 var a = new A(); |
| 75 smoke.invoke(a, #inc0, [], adjust: true); |
| 76 expect(a.i, 43); |
| 77 smoke.invoke(a, #inc0, [2], adjust: true); |
| 78 expect(a.i, 44); |
| 79 smoke.invoke(a, #inc0, [1, 2, 3], adjust: true); |
| 80 expect(a.i, 45); |
| 81 |
| 82 smoke.invoke(a, #inc1, [], adjust: true); // treat as null (-10) |
| 83 expect(a.i, 35); |
| 84 smoke.invoke(a, #inc1, [4], adjust: true); |
| 85 expect(a.i, 39); |
| 86 |
| 87 smoke.invoke(a, #inc2, [], adjust: true); // default is null (-10) |
| 88 expect(a.i, 29); |
| 89 smoke.invoke(a, #inc2, [4, 5], adjust: true); |
| 90 expect(a.i, 33); |
| 91 }); |
| 92 |
| 93 test('has getter', () { |
| 94 expect(smoke.hasGetter(A, #i), isTrue); |
| 95 expect(smoke.hasGetter(A, #j2), isTrue); |
| 96 expect(smoke.hasGetter(A, #inc2), isTrue); |
| 97 expect(smoke.hasGetter(B, #a), isTrue); |
| 98 expect(smoke.hasGetter(B, #i), isFalse); |
| 99 expect(smoke.hasGetter(B, #f), isTrue); |
| 100 expect(smoke.hasGetter(D, #i), isTrue); |
| 101 |
| 102 expect(smoke.hasGetter(E, #x), isFalse); |
| 103 expect(smoke.hasGetter(E, #y), isTrue); |
| 104 expect(smoke.hasGetter(E, #z), isFalse); // don't consider noSuchMethod |
| 105 }); |
| 106 |
| 107 test('has setter', () { |
| 108 expect(smoke.hasSetter(A, #i), isTrue); |
| 109 expect(smoke.hasSetter(A, #j2), isTrue); |
| 110 expect(smoke.hasSetter(A, #inc2), isFalse); |
| 111 expect(smoke.hasSetter(B, #a), isTrue); |
| 112 expect(smoke.hasSetter(B, #i), isFalse); |
| 113 expect(smoke.hasSetter(B, #f), isFalse); |
| 114 expect(smoke.hasSetter(D, #i), isTrue); |
| 115 |
| 116 // TODO(sigmund): should we support declaring a setter with no getter? |
| 117 // expect(smoke.hasSetter(E, #x), isTrue); |
| 118 expect(smoke.hasSetter(E, #y), isFalse); |
| 119 expect(smoke.hasSetter(E, #z), isFalse); // don't consider noSuchMethod |
| 120 }); |
| 121 |
| 122 test('no such method', () { |
| 123 expect(smoke.hasNoSuchMethod(A), isFalse); |
| 124 expect(smoke.hasNoSuchMethod(E), isTrue); |
| 125 expect(smoke.hasNoSuchMethod(E2), isTrue); |
| 126 expect(smoke.hasNoSuchMethod(int), isFalse); |
| 127 }); |
| 128 |
| 129 test('has instance method', () { |
| 130 expect(smoke.hasInstanceMethod(A, #inc0), isTrue); |
| 131 expect(smoke.hasInstanceMethod(A, #inc3), isFalse); |
| 132 expect(smoke.hasInstanceMethod(C, #inc), isTrue); |
| 133 expect(smoke.hasInstanceMethod(D, #inc), isTrue); |
| 134 expect(smoke.hasInstanceMethod(D, #inc0), isTrue); |
| 135 expect(smoke.hasInstanceMethod(F, #staticMethod), isFalse); |
| 136 expect(smoke.hasInstanceMethod(F2, #staticMethod), isFalse); |
| 137 }); |
| 138 |
| 139 test('has static method', () { |
| 140 expect(smoke.hasStaticMethod(A, #inc0), isFalse); |
| 141 expect(smoke.hasStaticMethod(C, #inc), isFalse); |
| 142 expect(smoke.hasStaticMethod(D, #inc), isFalse); |
| 143 expect(smoke.hasStaticMethod(D, #inc0), isFalse); |
| 144 expect(smoke.hasStaticMethod(F, #staticMethod), isTrue); |
| 145 expect(smoke.hasStaticMethod(F2, #staticMethod), isFalse); |
| 146 }); |
| 147 |
| 148 test('get declaration', () { |
| 149 var d = smoke.getDeclaration(B, #a); |
| 150 expect(d.name, #a); |
| 151 expect(d.isField, isTrue); |
| 152 expect(d.isProperty, isFalse); |
| 153 expect(d.isMethod, isFalse); |
| 154 expect(d.isFinal, isFalse); |
| 155 expect(d.isStatic, isFalse); |
| 156 expect(d.annotations, []); |
| 157 expect(d.type, A); |
| 158 |
| 159 d = smoke.getDeclaration(B, #w); |
| 160 expect(d.name, #w); |
| 161 expect(d.isField, isFalse); |
| 162 expect(d.isProperty, isTrue); |
| 163 expect(d.isMethod, isFalse); |
| 164 expect(d.isFinal, isFalse); |
| 165 expect(d.isStatic, isFalse); |
| 166 expect(d.annotations, []); |
| 167 expect(d.type, int); |
| 168 |
| 169 d = smoke.getDeclaration(A, #inc1); |
| 170 expect(d.name, #inc1); |
| 171 expect(d.isField, isFalse); |
| 172 expect(d.isProperty, isFalse); |
| 173 expect(d.isMethod, isTrue); |
| 174 expect(d.isFinal, isFalse); |
| 175 expect(d.isStatic, isFalse); |
| 176 expect(d.annotations, []); |
| 177 expect(d.type, Function); |
| 178 |
| 179 d = smoke.getDeclaration(F, #staticMethod); |
| 180 expect(d.name, #staticMethod); |
| 181 expect(d.isField, isFalse); |
| 182 expect(d.isProperty, isFalse); |
| 183 expect(d.isMethod, isTrue); |
| 184 expect(d.isFinal, isFalse); |
| 185 expect(d.isStatic, isTrue); |
| 186 expect(d.annotations, []); |
| 187 expect(d.type, Function); |
| 188 |
| 189 d = smoke.getDeclaration(G, #b); |
| 190 expect(d.name, #b); |
| 191 expect(d.isField, isTrue); |
| 192 expect(d.isProperty, isFalse); |
| 193 expect(d.isMethod, isFalse); |
| 194 expect(d.isFinal, isFalse); |
| 195 expect(d.isStatic, isFalse); |
| 196 expect(d.annotations, [const Annot()]); |
| 197 expect(d.type, int); |
| 198 |
| 199 d = smoke.getDeclaration(G, #d); |
| 200 expect(d.name, #d); |
| 201 expect(d.isField, isTrue); |
| 202 expect(d.isProperty, isFalse); |
| 203 expect(d.isMethod, isFalse); |
| 204 expect(d.isFinal, isFalse); |
| 205 expect(d.isStatic, isFalse); |
| 206 expect(d.annotations, [32]); |
| 207 expect(d.type, int); |
| 208 }); |
| 209 |
| 210 test('isSuperclass', () { |
| 211 expect(smoke.isSubclassOf(D, C), isTrue); |
| 212 expect(smoke.isSubclassOf(H, G), isTrue); |
| 213 expect(smoke.isSubclassOf(H, H), isTrue); |
| 214 expect(smoke.isSubclassOf(H, Object), isTrue); |
| 215 expect(smoke.isSubclassOf(B, Object), isTrue); |
| 216 expect(smoke.isSubclassOf(A, Object), isTrue); |
| 217 expect(smoke.isSubclassOf(AnnotB, Annot), isTrue); |
| 218 |
| 219 expect(smoke.isSubclassOf(D, A), isFalse); |
| 220 expect(smoke.isSubclassOf(H, B), isFalse); |
| 221 expect(smoke.isSubclassOf(B, A), isFalse); |
| 222 expect(smoke.isSubclassOf(Object, A), isFalse); |
| 223 }); |
| 224 |
| 225 group('query', () { |
| 226 _checkQuery(result, names) { |
| 227 expect(result.map((e) => e.name), unorderedEquals(names)); |
| 228 } |
| 229 |
| 230 test('default', () { |
| 231 var options = new smoke.QueryOptions(); |
| 232 var res = smoke.query(A, options); |
| 233 _checkQuery(res, [#i, #j, #j2]); |
| 234 }); |
| 235 |
| 236 test('only fields', () { |
| 237 var options = new smoke.QueryOptions(includeProperties: false); |
| 238 var res = smoke.query(A, options); |
| 239 _checkQuery(res, [#i, #j]); |
| 240 expect(res[0].isField, true); |
| 241 }); |
| 242 |
| 243 test('only properties', () { |
| 244 var options = new smoke.QueryOptions(includeFields: false); |
| 245 var res = smoke.query(A, options); |
| 246 _checkQuery(res, [#j2]); |
| 247 expect(res[0].isProperty, true); |
| 248 }); |
| 249 |
| 250 test('properties and methods', () { |
| 251 var options = new smoke.QueryOptions(includeMethods: true); |
| 252 var res = smoke.query(A, options); |
| 253 _checkQuery(res, [#i, #j, #j2, #inc0, #inc1, #inc2]); |
| 254 }); |
| 255 |
| 256 test('inherited properties and fields', () { |
| 257 var options = new smoke.QueryOptions(includeInherited: true); |
| 258 var res = smoke.query(D, options); |
| 259 _checkQuery(res, [#x, #y, #b, #i, #j, #j2, #x2, #i2]); |
| 260 }); |
| 261 |
| 262 test('inherited fields only', () { |
| 263 var options = new smoke.QueryOptions( |
| 264 includeInherited: true, includeProperties: false); |
| 265 var res = smoke.query(D, options); |
| 266 _checkQuery(res, [#x, #y, #b, #i, #j]); |
| 267 }); |
| 268 |
| 269 test('exact annotation', () { |
| 270 var options = new smoke.QueryOptions( |
| 271 includeInherited: true, withAnnotations: const [a1]); |
| 272 var res = smoke.query(H, options); |
| 273 _checkQuery(res, [#b, #f, #g]); |
| 274 |
| 275 options = new smoke.QueryOptions( |
| 276 includeInherited: true, withAnnotations: const [a2]); |
| 277 res = smoke.query(H, options); |
| 278 _checkQuery(res, [#d, #h]); |
| 279 |
| 280 options = new smoke.QueryOptions( |
| 281 includeInherited: true, withAnnotations: const [a1, a2]); |
| 282 res = smoke.query(H, options); |
| 283 _checkQuery(res, [#b, #d, #f, #g, #h]); |
| 284 }); |
| 285 |
| 286 test('type annotation', () { |
| 287 var options = new smoke.QueryOptions( |
| 288 includeInherited: true, withAnnotations: const [Annot]); |
| 289 var res = smoke.query(H, options); |
| 290 _checkQuery(res, [#b, #f, #g, #i]); |
| 291 }); |
| 292 |
| 293 test('mixed annotations (type and exact)', () { |
| 294 var options = new smoke.QueryOptions( |
| 295 includeInherited: true, withAnnotations: const [a2, Annot]); |
| 296 var res = smoke.query(H, options); |
| 297 _checkQuery(res, [#b, #d, #f, #g, #h, #i]); |
| 298 }); |
| 299 |
| 300 test('overriden symbols', () { |
| 301 var options = new smoke.QueryOptions( |
| 302 excludeOverriden: true, includeInherited: true, includeMethods: true); |
| 303 var res = smoke.query(L2, options); |
| 304 _checkQuery(res, [#m, #incM, #n]); |
| 305 // Check that the concrete #m is there |
| 306 var overriden = res.firstWhere((value) => value.name == #m); |
| 307 expect(overriden.isFinal, false); |
| 308 expect(overriden.isField, true); |
| 309 }); |
| 310 |
| 311 test('symbol to name', () { |
| 312 expect(smoke.symbolToName(#i), 'i'); |
| 313 }); |
| 314 |
| 315 test('name to symbol', () { |
| 316 expect(smoke.nameToSymbol('i'), #i); |
| 317 }); |
| 318 }); |
| 319 |
| 320 test('invoke Type instance methods', () { |
| 321 var a = new A(); |
| 322 expect( |
| 323 smoke.invoke(a.runtimeType, #toString, []), a.runtimeType.toString()); |
| 324 }); |
| 325 } |
| 326 |
| 327 class A { |
| 328 int i = 42; |
| 329 int j = 44; |
| 330 int get j2 => j; |
| 331 void set j2(int v) { |
| 332 j = v; |
| 333 } |
| 334 void inc0() { |
| 335 i++; |
| 336 } |
| 337 void inc1(int v) { |
| 338 i = i + (v == null ? -10 : v); |
| 339 } |
| 340 void inc2([int v]) { |
| 341 i = i + (v == null ? -10 : v); |
| 342 } |
| 343 |
| 344 static int staticValue = 42; |
| 345 static void staticInc() { |
| 346 staticValue++; |
| 347 } |
| 348 } |
| 349 |
| 350 class B { |
| 351 final int f = 3; |
| 352 int _w; |
| 353 int get w => _w; |
| 354 set w(int v) { |
| 355 _w = v; |
| 356 } |
| 357 |
| 358 String z; |
| 359 A a; |
| 360 |
| 361 B(this._w, this.z, this.a); |
| 362 } |
| 363 |
| 364 class C { |
| 365 int x; |
| 366 String y; |
| 367 B b; |
| 368 |
| 369 inc(int n) { |
| 370 x = x + n; |
| 371 } |
| 372 dec(int n) { |
| 373 x = x - n; |
| 374 } |
| 375 |
| 376 C(this.x, this.y, this.b); |
| 377 } |
| 378 |
| 379 class D extends C with A { |
| 380 int get x2 => x; |
| 381 int get i2 => i; |
| 382 |
| 383 D(x, y, b) : super(x, y, b); |
| 384 } |
| 385 |
| 386 class E { |
| 387 set x(int v) {} |
| 388 int get y => 1; |
| 389 |
| 390 noSuchMethod(i) => y; |
| 391 } |
| 392 |
| 393 class E2 extends E {} |
| 394 |
| 395 class F { |
| 396 static int staticMethod(A a) => a.i; |
| 397 } |
| 398 |
| 399 class F2 extends F {} |
| 400 |
| 401 class Annot { |
| 402 const Annot(); |
| 403 } |
| 404 class AnnotB extends Annot { |
| 405 const AnnotB(); |
| 406 } |
| 407 class AnnotC { |
| 408 const AnnotC({bool named: false}); |
| 409 } |
| 410 const a1 = const Annot(); |
| 411 const a2 = 32; |
| 412 const a3 = const AnnotB(); |
| 413 |
| 414 class G { |
| 415 int a; |
| 416 @a1 int b; |
| 417 int c; |
| 418 @a2 int d; |
| 419 } |
| 420 |
| 421 class H extends G { |
| 422 int e; |
| 423 @a1 int f; |
| 424 @a1 int g; |
| 425 @a2 int h; |
| 426 @a3 int i; |
| 427 } |
| 428 |
| 429 class K { |
| 430 @AnnotC(named: true) int k; |
| 431 @AnnotC() int k2; |
| 432 } |
| 433 |
| 434 abstract class L { |
| 435 int get m; |
| 436 incM(); |
| 437 } |
| 438 |
| 439 class L2 extends L { |
| 440 int m; |
| 441 incM() { ++m; } |
| 442 int n; |
| 443 } |
OLD | NEW |