OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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 library reflective_tests; | 5 library reflective_tests; |
6 | 6 |
7 @MirrorsUsed(metaTargets: 'ReflectiveTestCase') | 7 @MirrorsUsed(metaTargets: 'ReflectiveTest') |
8 import 'dart:mirrors'; | 8 import 'dart:mirrors'; |
9 import 'dart:async'; | 9 import 'dart:async'; |
10 | 10 |
11 import 'package:unittest/unittest.dart'; | 11 import 'package:unittest/unittest.dart'; |
12 | 12 |
13 | 13 |
14 /** | 14 /** |
15 * Runs test methods existing in the given [type]. | 15 * Runs test methods existing in the given [type]. |
16 * | 16 * |
17 * Methods with names starting with `test` are run using [test] function. | 17 * Methods with names starting with `test` are run using [test] function. |
18 * Methods with names starting with `solo_test` are run using [solo_test] functi
on. | 18 * Methods with names starting with `solo_test` are run using [solo_test] functi
on. |
19 * | 19 * |
20 * Each method is run with a new instance of [type]. | 20 * Each method is run with a new instance of [type]. |
21 * So, [type] should have a default constructor. | 21 * So, [type] should have a default constructor. |
22 * | 22 * |
23 * If [type] declares method `setUp`, it methods will be invoked before any test | 23 * If [type] declares method `setUp`, it methods will be invoked before any test |
24 * method invocation. | 24 * method invocation. |
25 * | 25 * |
26 * If [type] declares method `tearDown`, it will be invoked after any test | 26 * If [type] declares method `tearDown`, it will be invoked after any test |
27 * method invocation. If method returns [Future] to test some asyncronous | 27 * method invocation. If method returns [Future] to test some asyncronous |
28 * behavior, then `tearDown` will be invoked in `Future.complete`. | 28 * behavior, then `tearDown` will be invoked in `Future.complete`. |
29 */ | 29 */ |
30 void runReflectiveTests(Type type) { | 30 void runReflectiveTests(Type type) { |
31 ClassMirror classMirror = reflectClass(type); | 31 ClassMirror classMirror = reflectClass(type); |
32 if (!classMirror.metadata.any( | 32 if (!classMirror.metadata.any( |
33 (InstanceMirror annotation) => | 33 (InstanceMirror annotation) => |
34 annotation.type.reflectedType == ReflectiveTestCase)) { | 34 annotation.type.reflectedType == ReflectiveTest)) { |
35 String name = MirrorSystem.getName(classMirror.qualifiedName); | 35 String name = MirrorSystem.getName(classMirror.qualifiedName); |
36 throw new Exception( | 36 throw new Exception( |
37 'Class $name must have annotation "@ReflectiveTestCase()" ' | 37 'Class $name must have annotation "@reflectiveTest" ' |
38 'in order to be run by runReflectiveTests.'); | 38 'in order to be run by runReflectiveTests.'); |
39 } | 39 } |
40 String className = MirrorSystem.getName(classMirror.simpleName); | 40 String className = MirrorSystem.getName(classMirror.simpleName); |
41 group(className, () { | 41 group(className, () { |
42 classMirror.instanceMembers.forEach((symbol, memberMirror) { | 42 classMirror.instanceMembers.forEach((symbol, memberMirror) { |
43 // we need only methods | 43 // we need only methods |
44 if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) { | 44 if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) { |
45 return; | 45 return; |
46 } | 46 } |
47 String memberName = MirrorSystem.getName(symbol); | 47 String memberName = MirrorSystem.getName(symbol); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 [ | 117 [ |
118 ]).reflectee).whenComplete( | 118 ]).reflectee).whenComplete( |
119 () => _invokeSymbolIfExists(instanceMirror, #tearDown)
); | 119 () => _invokeSymbolIfExists(instanceMirror, #tearDown)
); |
120 } | 120 } |
121 | 121 |
122 | 122 |
123 /** | 123 /** |
124 * A marker annotation used to instruct dart2js to keep reflection information | 124 * A marker annotation used to instruct dart2js to keep reflection information |
125 * for the annotated classes. | 125 * for the annotated classes. |
126 */ | 126 */ |
127 class ReflectiveTestCase { | 127 class ReflectiveTest { |
128 const ReflectiveTestCase(); | 128 const ReflectiveTest(); |
129 } | 129 } |
| 130 |
| 131 /** |
| 132 * A marker annotation used to instruct dart2js to keep reflection information |
| 133 * for the annotated classes. |
| 134 */ |
| 135 const ReflectiveTest reflectiveTest = const ReflectiveTest(); |
OLD | NEW |