| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 // | |
| 5 // Dart test program for checking implemention of MirrorSystem when | |
| 6 // inspecting the current isolate. | |
| 7 // | |
| 8 // VMOptions=--enable_type_checks | |
| 9 | |
| 10 library isolate_mirror_local_test; | |
| 11 | |
| 12 import "package:expect/expect.dart"; | |
| 13 import 'dart:async'; | |
| 14 import 'dart:isolate'; | |
| 15 import 'dart:mirrors'; | |
| 16 | |
| 17 ReceivePort exit_port; | |
| 18 Set expectedTests; | |
| 19 | |
| 20 void testDone(String test) { | |
| 21 if (!expectedTests.contains(test)) { | |
| 22 throw "Unexpected test name '$test'"; | |
| 23 } | |
| 24 expectedTests.remove(test); | |
| 25 if (expectedTests.isEmpty) { | |
| 26 // All tests are done. | |
| 27 exit_port.close(); | |
| 28 } | |
| 29 } | |
| 30 | |
| 31 int global_var = 0; | |
| 32 final int final_global_var = 0; | |
| 33 | |
| 34 // Top-level getter and setter. | |
| 35 int get myVar { return 5; } | |
| 36 void set myVar(x) {} | |
| 37 | |
| 38 // This function will be invoked reflectively. | |
| 39 int function(int x) { | |
| 40 global_var = x; | |
| 41 return x + 1; | |
| 42 } | |
| 43 | |
| 44 typedef void FuncType(String a); | |
| 45 | |
| 46 FuncType myFunc = null; | |
| 47 | |
| 48 _stringCompare(String a, String b) => a.compareTo(b); | |
| 49 sort(list) => list.sort(_stringCompare); | |
| 50 | |
| 51 String buildMethodString(MethodMirror func) { | |
| 52 var result = '${MirrorSystem.getName(func.simpleName)} ' | |
| 53 'return(${MirrorSystem.getName(func.returnType.simpleName)})'; | |
| 54 if (func.isPrivate) { | |
| 55 result = '$result private'; | |
| 56 } | |
| 57 if (func.isTopLevel) { | |
| 58 result = '$result toplevel'; | |
| 59 } | |
| 60 if (func.isStatic) { | |
| 61 result = '$result static'; | |
| 62 } | |
| 63 if (func.isAbstract) { | |
| 64 result = '$result abstract'; | |
| 65 } | |
| 66 if (func.isRegularMethod) { | |
| 67 result = '$result method'; | |
| 68 } | |
| 69 if (func.isGetter) { | |
| 70 result = '$result getter'; | |
| 71 } | |
| 72 if (func.isSetter) { | |
| 73 result = '$result setter'; | |
| 74 } | |
| 75 if (func.isConstructor) { | |
| 76 result = '$result constructor'; | |
| 77 } | |
| 78 if (func.isConstConstructor) { | |
| 79 result = '$result const'; | |
| 80 } | |
| 81 if (func.isGenerativeConstructor) { | |
| 82 result = '$result generative'; | |
| 83 } | |
| 84 if (func.isRedirectingConstructor) { | |
| 85 result = '$result redirecting'; | |
| 86 } | |
| 87 if (func.isFactoryConstructor) { | |
| 88 result = '$result factory'; | |
| 89 } | |
| 90 return result; | |
| 91 } | |
| 92 | |
| 93 String buildVariableString(VariableMirror variable) { | |
| 94 var result = '${MirrorSystem.getName(variable.simpleName)} ' | |
| 95 'type(${MirrorSystem.getName(variable.type.simpleName)})'; | |
| 96 if (variable.isPrivate) { | |
| 97 result = '$result private'; | |
| 98 } | |
| 99 if (variable.isTopLevel) { | |
| 100 result = '$result toplevel'; | |
| 101 } | |
| 102 if (variable.isStatic) { | |
| 103 result = '$result static'; | |
| 104 } | |
| 105 if (variable.isFinal) { | |
| 106 result = '$result final'; | |
| 107 } | |
| 108 return result; | |
| 109 } | |
| 110 | |
| 111 void testRootLibraryMirror(LibraryMirror lib_mirror) { | |
| 112 Expect.equals(const Symbol('isolate_mirror_local_test'), | |
| 113 lib_mirror.simpleName); | |
| 114 Expect.equals(const Symbol('isolate_mirror_local_test'), | |
| 115 lib_mirror.qualifiedName); | |
| 116 Expect.equals(null, lib_mirror.owner); | |
| 117 Expect.isFalse(lib_mirror.isPrivate); | |
| 118 Expect.isTrue(lib_mirror.uri.path.contains('isolate_mirror_local_test.dart')); | |
| 119 Expect.equals("LibraryMirror on 'isolate_mirror_local_test'", | |
| 120 lib_mirror.toString()); | |
| 121 | |
| 122 // Test library invocation by calling function(123). | |
| 123 Expect.equals(0, global_var); | |
| 124 lib_mirror.invokeAsync(const Symbol('function'), [123]).then( | |
| 125 (InstanceMirror retval) { | |
| 126 Expect.equals(123, global_var); | |
| 127 testImplements(retval.type, #int); | |
| 128 Expect.isTrue(retval.hasReflectee); | |
| 129 Expect.equals(124, retval.reflectee); | |
| 130 testDone('testRootLibraryMirror'); | |
| 131 }); | |
| 132 | |
| 133 // Check that the members map is complete. | |
| 134 List keys = lib_mirror.members.keys.map(MirrorSystem.getName).toList(); | |
| 135 sort(keys); | |
| 136 Expect.equals('[' | |
| 137 'FuncType, ' | |
| 138 'GenericClass, ' | |
| 139 'MyClass, ' | |
| 140 'MyException, ' | |
| 141 'MyInterface, ' | |
| 142 'MySuperClass, ' | |
| 143 '_stringCompare, ' | |
| 144 'buildMethodString, ' | |
| 145 'buildVariableString, ' | |
| 146 'exit_port, ' | |
| 147 'expectedTests, ' | |
| 148 'final_global_var, ' | |
| 149 'function, ' | |
| 150 'global_var, ' | |
| 151 'main, ' | |
| 152 'myFunc, ' | |
| 153 'myVar, ' | |
| 154 'myVar=, ' | |
| 155 'sort, ' | |
| 156 'testBoolInstanceMirror, ' | |
| 157 'testCustomInstanceMirror, ' | |
| 158 'testDone, ' | |
| 159 'testImplements, ' | |
| 160 'testIntegerInstanceMirror, ' | |
| 161 'testLibrariesMap, ' | |
| 162 'testMirrorSystem, ' | |
| 163 'testNullInstanceMirror, ' | |
| 164 'testRootLibraryMirror, ' | |
| 165 'testStringInstanceMirror]', | |
| 166 '$keys'); | |
| 167 | |
| 168 // Check that the classes map is complete. | |
| 169 keys = lib_mirror.classes.keys.map(MirrorSystem.getName).toList(); | |
| 170 sort(keys); | |
| 171 print(keys); | |
| 172 Expect.equals('[' | |
| 173 'GenericClass, ' | |
| 174 'MyClass, ' | |
| 175 'MyException, ' | |
| 176 'MyInterface, ' | |
| 177 'MySuperClass]', | |
| 178 '$keys'); | |
| 179 | |
| 180 // Check that the types map is complete. | |
| 181 keys = lib_mirror.types.keys.map(MirrorSystem.getName).toList(); | |
| 182 sort(keys); | |
| 183 print(keys); | |
| 184 Expect.equals('[' | |
| 185 'FuncType, ' | |
| 186 'GenericClass, ' | |
| 187 'MyClass, ' | |
| 188 'MyException, ' | |
| 189 'MyInterface, ' | |
| 190 'MySuperClass]', | |
| 191 '$keys'); | |
| 192 | |
| 193 // Check that the functions map is complete. | |
| 194 keys = lib_mirror.functions.keys.map(MirrorSystem.getName).toList(); | |
| 195 sort(keys); | |
| 196 Expect.equals('[' | |
| 197 '_stringCompare, ' | |
| 198 'buildMethodString, ' | |
| 199 'buildVariableString, ' | |
| 200 'function, ' | |
| 201 'main, ' | |
| 202 'myVar, ' | |
| 203 'myVar=, ' | |
| 204 'sort, ' | |
| 205 'testBoolInstanceMirror, ' | |
| 206 'testCustomInstanceMirror, ' | |
| 207 'testDone, ' | |
| 208 'testImplements, ' | |
| 209 'testIntegerInstanceMirror, ' | |
| 210 'testLibrariesMap, ' | |
| 211 'testMirrorSystem, ' | |
| 212 'testNullInstanceMirror, ' | |
| 213 'testRootLibraryMirror, ' | |
| 214 'testStringInstanceMirror]', | |
| 215 '$keys'); | |
| 216 | |
| 217 // Check that the getters map is complete. | |
| 218 keys = lib_mirror.getters.keys.map(MirrorSystem.getName).toList(); | |
| 219 sort(keys); | |
| 220 Expect.equals('[myVar]', '$keys'); | |
| 221 | |
| 222 // Check that the setters map is complete. | |
| 223 keys = lib_mirror.setters.keys.map(MirrorSystem.getName).toList(); | |
| 224 sort(keys); | |
| 225 Expect.equals('[myVar=]', '$keys'); | |
| 226 | |
| 227 // Check that the variables map is complete. | |
| 228 keys = lib_mirror.variables.keys.map(MirrorSystem.getName).toList(); | |
| 229 sort(keys); | |
| 230 Expect.equals('[' | |
| 231 'exit_port, ' | |
| 232 'expectedTests, ' | |
| 233 'final_global_var, ' | |
| 234 'global_var, ' | |
| 235 'myFunc]', | |
| 236 '$keys'); | |
| 237 | |
| 238 ClassMirror cls_mirror = lib_mirror.members[const Symbol('MyClass')]; | |
| 239 ClassMirror generic_cls_mirror = | |
| 240 lib_mirror.members[const Symbol('GenericClass')]; | |
| 241 | |
| 242 // Test function mirrors. | |
| 243 MethodMirror func = lib_mirror.members[const Symbol('function')]; | |
| 244 Expect.isTrue(func is MethodMirror); | |
| 245 Expect.equals('function return(int) toplevel static method', | |
| 246 buildMethodString(func)); | |
| 247 | |
| 248 func = lib_mirror.members[const Symbol('myVar')]; | |
| 249 Expect.isTrue(func is MethodMirror); | |
| 250 Expect.equals('myVar return(int) toplevel static getter', | |
| 251 buildMethodString(func)); | |
| 252 | |
| 253 func = lib_mirror.members[const Symbol('myVar=')]; | |
| 254 Expect.isTrue(func is MethodMirror); | |
| 255 Expect.equals('myVar= return(void) toplevel static setter', | |
| 256 buildMethodString(func)); | |
| 257 | |
| 258 func = cls_mirror.members[const Symbol('method')]; | |
| 259 Expect.isTrue(func is MethodMirror); | |
| 260 Expect.equals('method return(int) method', buildMethodString(func)); | |
| 261 | |
| 262 func = cls_mirror.constructors[const Symbol('MyClass')]; | |
| 263 Expect.isTrue(func is MethodMirror); | |
| 264 Expect.equals('MyClass return(MyClass) constructor generative', | |
| 265 buildMethodString(func)); | |
| 266 | |
| 267 func = cls_mirror.constructors[const Symbol('MyClass.named')]; | |
| 268 Expect.isTrue(func is MethodMirror); | |
| 269 Expect.equals('MyClass.named return(MyClass) constructor generative', | |
| 270 buildMethodString(func)); | |
| 271 | |
| 272 func = generic_cls_mirror.members[const Symbol('method')]; | |
| 273 Expect.isTrue(func is MethodMirror); | |
| 274 Expect.equals('method return(T) method', buildMethodString(func)); | |
| 275 | |
| 276 // Test variable mirrors. | |
| 277 VariableMirror variable = lib_mirror.members[const Symbol('global_var')]; | |
| 278 Expect.isTrue(variable is VariableMirror); | |
| 279 Expect.equals('global_var type(int) toplevel static', | |
| 280 buildVariableString(variable)); | |
| 281 | |
| 282 variable = lib_mirror.members[const Symbol('final_global_var')]; | |
| 283 Expect.isTrue(variable is VariableMirror); | |
| 284 Expect.equals('final_global_var type(int) toplevel static final', | |
| 285 buildVariableString(variable)); | |
| 286 | |
| 287 variable = cls_mirror.members[const Symbol('value')]; | |
| 288 Expect.isTrue(variable is VariableMirror); | |
| 289 Expect.equals('value type(dynamic) final', buildVariableString(variable)); | |
| 290 | |
| 291 // Test type variable mirrors. | |
| 292 var type_var = generic_cls_mirror.members[const Symbol('method')].returnType; | |
| 293 Expect.isTrue(type_var is TypeVariableMirror); | |
| 294 Expect.equals(const Symbol('GenericClass'), type_var.owner.simpleName); | |
| 295 Expect.equals(const Symbol('Object'), type_var.upperBound.simpleName); | |
| 296 | |
| 297 // Test typedef mirrors. | |
| 298 var typedef_mirror = lib_mirror.members[const Symbol('myFunc')].type; | |
| 299 Expect.isTrue(typedef_mirror is TypedefMirror); | |
| 300 Expect.equals(const Symbol('isolate_mirror_local_test'), | |
| 301 typedef_mirror.owner.simpleName); | |
| 302 | |
| 303 // Test function type mirrors. | |
| 304 var func_cls_mirror = typedef_mirror.referent; | |
| 305 Expect.isTrue(func_cls_mirror is FunctionTypeMirror); | |
| 306 // Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName); | |
| 307 Expect.equals(const Symbol('void'), func_cls_mirror.returnType.simpleName); | |
| 308 } | |
| 309 | |
| 310 void testLibrariesMap(Map libraries) { | |
| 311 // Just look for a couple of well-known libs. | |
| 312 LibraryMirror core_lib = libraries[Uri.parse('dart:core')]; | |
| 313 Expect.isTrue(core_lib is LibraryMirror); | |
| 314 | |
| 315 LibraryMirror mirror_lib = libraries[Uri.parse('dart:mirrors')]; | |
| 316 Expect.isTrue(mirror_lib is LibraryMirror); | |
| 317 | |
| 318 // Lookup an interface from a library and make sure it is sane. | |
| 319 ClassMirror list_intf = core_lib.members[const Symbol('List')]; | |
| 320 Expect.isTrue(list_intf is ClassMirror); | |
| 321 Expect.equals(const Symbol('List'), list_intf.simpleName); | |
| 322 Expect.equals(const Symbol('dart.core.List'), list_intf.qualifiedName); | |
| 323 Expect.isFalse(list_intf.isPrivate); | |
| 324 Expect.equals(const Symbol('Object'), list_intf.superclass.simpleName); | |
| 325 Expect.equals(const Symbol('dart.core'), list_intf.owner.simpleName); | |
| 326 Expect.isTrue(list_intf.isClass); | |
| 327 Expect.equals(const Symbol('Iterable'), | |
| 328 list_intf.superinterfaces[0].simpleName); | |
| 329 Expect.equals("ClassMirror on 'List'", list_intf.toString()); | |
| 330 | |
| 331 // Lookup a class from a library and make sure it is sane. | |
| 332 ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')]; | |
| 333 Expect.isTrue(oom_cls is ClassMirror); | |
| 334 Expect.equals(const Symbol('OutOfMemoryError'), oom_cls.simpleName); | |
| 335 Expect.equals(const Symbol('dart.core.OutOfMemoryError'), | |
| 336 oom_cls.qualifiedName); | |
| 337 Expect.isFalse(oom_cls.isPrivate); | |
| 338 Expect.equals(const Symbol('Object'), oom_cls.superclass.simpleName); | |
| 339 Expect.isTrue(oom_cls.defaultFactory == null); | |
| 340 Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName); | |
| 341 Expect.isTrue(oom_cls.isClass); | |
| 342 Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName); | |
| 343 Expect.equals("ClassMirror on 'OutOfMemoryError'", | |
| 344 oom_cls.toString()); | |
| 345 testDone('testLibrariesMap'); | |
| 346 } | |
| 347 | |
| 348 void testMirrorSystem(MirrorSystem mirrors) { | |
| 349 Expect.isTrue(mirrors.isolate.debugName.contains('main')); | |
| 350 testRootLibraryMirror(mirrors.isolate.rootLibrary); | |
| 351 testLibrariesMap(mirrors.libraries); | |
| 352 Expect.equals(const Symbol('void'), mirrors.voidType.simpleName); | |
| 353 Expect.equals(const Symbol('dynamic'), mirrors.dynamicType.simpleName); | |
| 354 Expect.isTrue(mirrors.voidType is TypeMirror); | |
| 355 Expect.isTrue(mirrors.dynamicType is TypeMirror); | |
| 356 Expect.isFalse(mirrors.voidType is ClassMirror); | |
| 357 Expect.isFalse(mirrors.dynamicType is ClassMirror); | |
| 358 testDone('testMirrorSystem'); | |
| 359 } | |
| 360 | |
| 361 void testImplements(klass, intfName) { | |
| 362 bool foundInterface = false; | |
| 363 for (ClassMirror cm = klass; cm != null; cm = cm.superclass) { | |
| 364 if (cm.simpleName == intfName) foundInterface = true; | |
| 365 cm.superinterfaces.forEach((intf) { | |
| 366 if (intf.simpleName == intfName) foundInterface = true; | |
| 367 }); | |
| 368 } | |
| 369 Expect.isTrue(foundInterface, '$klass should implement $intfName'); | |
| 370 } | |
| 371 | |
| 372 void testIntegerInstanceMirror(InstanceMirror mirror) { | |
| 373 testImplements(mirror.type, #int); | |
| 374 Expect.isTrue(mirror.hasReflectee); | |
| 375 Expect.equals(1001, mirror.reflectee); | |
| 376 Expect.equals("InstanceMirror on 1001", mirror.toString()); | |
| 377 | |
| 378 // Invoke (mirror + mirror). | |
| 379 mirror.invokeAsync(const Symbol('+'), [ mirror ]).then( | |
| 380 (InstanceMirror retval) { | |
| 381 testImplements(retval.type, #int); | |
| 382 Expect.isTrue(retval.hasReflectee); | |
| 383 Expect.equals(2002, retval.reflectee); | |
| 384 testDone('testIntegerInstanceMirror'); | |
| 385 }); | |
| 386 } | |
| 387 | |
| 388 void testStringInstanceMirror(InstanceMirror mirror) { | |
| 389 testImplements(mirror.type, #String); | |
| 390 Expect.isTrue(mirror.hasReflectee); | |
| 391 Expect.equals('This\nis\na\nString', mirror.reflectee); | |
| 392 Expect.equals('InstanceMirror on "This\\nis\\na\\nString"', | |
| 393 mirror.toString()); | |
| 394 | |
| 395 // Invoke mirror[0]. | |
| 396 mirror.invokeAsync(const Symbol('[]'), [ 0 ]).then( | |
| 397 (InstanceMirror retval) { | |
| 398 testImplements(retval.type, #String); | |
| 399 Expect.isTrue(retval.hasReflectee); | |
| 400 Expect.equals('T', retval.reflectee); | |
| 401 testDone('testStringInstanceMirror'); | |
| 402 }); | |
| 403 } | |
| 404 | |
| 405 void testBoolInstanceMirror(InstanceMirror mirror) { | |
| 406 testImplements(mirror.type, #bool); | |
| 407 Expect.isTrue(mirror.hasReflectee); | |
| 408 Expect.equals(true, mirror.reflectee); | |
| 409 Expect.equals("InstanceMirror on true", mirror.toString()); | |
| 410 testDone('testBoolInstanceMirror'); | |
| 411 } | |
| 412 | |
| 413 void testNullInstanceMirror(InstanceMirror mirror) { | |
| 414 testImplements(mirror.type, #Null); | |
| 415 Expect.isTrue(mirror.hasReflectee); | |
| 416 Expect.equals(null, mirror.reflectee); | |
| 417 Expect.equals("InstanceMirror on null", mirror.toString()); | |
| 418 testDone('testNullInstanceMirror'); | |
| 419 } | |
| 420 | |
| 421 class MySuperClass { | |
| 422 } | |
| 423 | |
| 424 class MyInterface { | |
| 425 } | |
| 426 | |
| 427 class MyClass extends MySuperClass implements MyInterface { | |
| 428 MyClass(this.value) {} | |
| 429 MyClass.named() {} | |
| 430 | |
| 431 final value; | |
| 432 | |
| 433 int method(int arg) { | |
| 434 return arg + value; | |
| 435 } | |
| 436 } | |
| 437 | |
| 438 class GenericClass<T> { | |
| 439 T method(int arg) { | |
| 440 return null; | |
| 441 } | |
| 442 } | |
| 443 | |
| 444 void testCustomInstanceMirror(InstanceMirror mirror) { | |
| 445 Expect.isTrue(mirror.hasReflectee); | |
| 446 bool saw_exception = false; | |
| 447 try { | |
| 448 mirror.reflectee; | |
| 449 } on MirrorException catch (me) { | |
| 450 saw_exception = true; | |
| 451 } | |
| 452 Expect.isFalse(saw_exception); | |
| 453 Expect.equals("InstanceMirror on Instance of 'MyClass'", | |
| 454 mirror.toString()); | |
| 455 | |
| 456 ClassMirror cls = mirror.type; | |
| 457 Expect.isTrue(cls is ClassMirror); | |
| 458 Expect.equals(const Symbol('MyClass'), cls.simpleName); | |
| 459 Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName); | |
| 460 Expect.isTrue(cls.defaultFactory == null); | |
| 461 Expect.equals(const Symbol('isolate_mirror_local_test'), | |
| 462 cls.owner.simpleName); | |
| 463 Expect.isTrue(cls.isClass); | |
| 464 Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName); | |
| 465 Expect.equals("ClassMirror on 'MyClass'", cls.toString()); | |
| 466 | |
| 467 // Invoke mirror.method(1000). | |
| 468 mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then( | |
| 469 (InstanceMirror retval) { | |
| 470 testImplements(retval.type, #int); | |
| 471 Expect.isTrue(retval.hasReflectee); | |
| 472 Expect.equals(1017, retval.reflectee); | |
| 473 testDone('testCustomInstanceMirror'); | |
| 474 }); | |
| 475 | |
| 476 } | |
| 477 | |
| 478 class MyException implements Exception { | |
| 479 MyException(this._message); | |
| 480 final String _message; | |
| 481 String toString() { return 'MyException: $_message'; } | |
| 482 } | |
| 483 | |
| 484 void main() { | |
| 485 // When all of the expected tests complete, the exit_port is closed, | |
| 486 // allowing the program to terminate. | |
| 487 exit_port = new ReceivePort(); | |
| 488 expectedTests = new Set<String>.from(['testRootLibraryMirror', | |
| 489 'testLibrariesMap', | |
| 490 'testMirrorSystem', | |
| 491 'testIntegerInstanceMirror', | |
| 492 'testStringInstanceMirror', | |
| 493 'testBoolInstanceMirror', | |
| 494 'testNullInstanceMirror', | |
| 495 'testCustomInstanceMirror']); | |
| 496 | |
| 497 // Test that an isolate can reflect on itself. | |
| 498 mirrorSystemOf(exit_port.sendPort).then(testMirrorSystem); | |
| 499 | |
| 500 testIntegerInstanceMirror(reflect(1001)); | |
| 501 testStringInstanceMirror(reflect('This\nis\na\nString')); | |
| 502 testBoolInstanceMirror(reflect(true)); | |
| 503 testNullInstanceMirror(reflect(null)); | |
| 504 testCustomInstanceMirror(reflect(new MyClass(17))); | |
| 505 } | |
| OLD | NEW |