Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: lib/test_reflective_loader.dart

Issue 2300503003: Update with implementation from 'analyzer'. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « codereview.settings ('k') | pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 test_reflective_loader; 5 library test_reflective_loader;
6 6
7 import 'dart:async';
7 @MirrorsUsed(metaTargets: 'ReflectiveTest') 8 @MirrorsUsed(metaTargets: 'ReflectiveTest')
8 import 'dart:mirrors'; 9 import 'dart:mirrors';
9 import 'dart:async';
10 10
11 import 'package:unittest/unittest.dart'; 11 import 'package:unittest/unittest.dart';
12 12
13 /** 13 /**
14 * Define tests using methods existing in the given [type]. 14 * A marker annotation used to annotate overridden test methods (so we cannot
15 * rename them to `fail_`) which are expected to fail at `assert` in the
16 * checked mode.
17 */
18 const _AssertFailingTest assertFailingTest = const _AssertFailingTest();
19
20 /**
21 * A marker annotation used to annotate overridden test methods (so we cannot
22 * rename them to `fail_`) which are expected to fail.
23 */
24 const _FailingTest failingTest = const _FailingTest();
25
26 /**
27 * A marker annotation used to instruct dart2js to keep reflection information
28 * for the annotated classes.
29 */
30 const ReflectiveTest reflectiveTest = const ReflectiveTest();
31
32 /**
33 * Test classes annotated with this annotation are run using [solo_group].
34 */
35 const _SoloTest soloTest = const _SoloTest();
36
37 /**
38 * Is `true` the application is running in the checked mode.
39 */
40 final bool _isCheckedMode = () {
41 try {
42 assert(false);
43 return false;
44 } catch (_) {
45 return true;
46 }
47 }();
48
49 /**
50 * Runs test methods existing in the given [type].
15 * 51 *
16 * Methods with names starting with `test` are run using [test] function. 52 * Methods with names starting with `test` are run using [test] function.
17 * Methods with names starting with `solo_test` are run using [solo_test] functi on. 53 * Methods with names starting with `solo_test` are run using [solo_test] functi on.
18 * 54 *
19 * Each method is run with a new instance of [type]. 55 * Each method is run with a new instance of [type].
20 * So, [type] should have a default constructor. 56 * So, [type] should have a default constructor.
21 * 57 *
22 * If [type] declares method `setUp`, it methods will be invoked before any test 58 * If [type] declares method `setUp`, it methods will be invoked before any test
23 * method invocation. 59 * method invocation.
24 * 60 *
25 * If [type] declares method `tearDown`, it will be invoked after any test 61 * If [type] declares method `tearDown`, it will be invoked after any test
26 * method invocation. If method returns [Future] to test some asyncronous 62 * method invocation. If method returns [Future] to test some asynchronous
27 * behavior, then `tearDown` will be invoked in `Future.complete`. 63 * behavior, then `tearDown` will be invoked in `Future.complete`.
28 */ 64 */
29 void defineReflectiveTests(Type type) { 65 void defineReflectiveTests(Type type) {
30 ClassMirror classMirror = reflectClass(type); 66 ClassMirror classMirror = reflectClass(type);
31 if (!classMirror.metadata.any((InstanceMirror annotation) => 67 if (!classMirror.metadata.any((InstanceMirror annotation) =>
32 annotation.type.reflectedType == ReflectiveTest)) { 68 annotation.type.reflectedType == ReflectiveTest)) {
33 String name = MirrorSystem.getName(classMirror.qualifiedName); 69 String name = MirrorSystem.getName(classMirror.qualifiedName);
34 throw new Exception('Class $name must have annotation "@reflectiveTest" ' 70 throw new Exception('Class $name must have annotation "@reflectiveTest" '
35 'in order to be run by runReflectiveTests.'); 71 'in order to be run by runReflectiveTests.');
36 } 72 }
37 String className = MirrorSystem.getName(classMirror.simpleName); 73 void runMembers() {
38 group(className, () { 74 classMirror.instanceMembers
39 classMirror.instanceMembers.forEach((symbol, memberMirror) { 75 .forEach((Symbol symbol, MethodMirror memberMirror) {
40 // we need only methods 76 // we need only methods
41 if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) { 77 if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) {
42 return; 78 return;
43 } 79 }
44 String memberName = MirrorSystem.getName(symbol); 80 String memberName = MirrorSystem.getName(symbol);
45 // test_ 81 // test_
46 if (memberName.startsWith('test_')) { 82 if (memberName.startsWith('test_')) {
47 test(memberName, () { 83 test(memberName, () {
48 return _runTest(classMirror, symbol); 84 if (_hasFailingTestAnnotation(memberMirror) ||
85 _isCheckedMode && _hasAssertFailingTestAnnotation(memberMirror)) {
86 return _runFailingTest(classMirror, symbol);
87 } else {
88 return _runTest(classMirror, symbol);
89 }
49 }); 90 });
50 return; 91 return;
51 } 92 }
52 // solo_test_ 93 // solo_test_
53 if (memberName.startsWith('solo_test_')) { 94 if (memberName.startsWith('solo_test_')) {
54 solo_test(memberName, () { 95 solo_test(memberName, () {
55 return _runTest(classMirror, symbol); 96 return _runTest(classMirror, symbol);
56 }); 97 });
57 } 98 }
58 // fail_test_ 99 // fail_test_
59 if (memberName.startsWith('fail_')) { 100 if (memberName.startsWith('fail_')) {
60 test(memberName, () { 101 test(memberName, () {
61 return _runFailingTest(classMirror, symbol); 102 return _runFailingTest(classMirror, symbol);
62 }); 103 });
63 } 104 }
64 // solo_fail_test_ 105 // solo_fail_test_
65 if (memberName.startsWith('solo_fail_')) { 106 if (memberName.startsWith('solo_fail_')) {
66 solo_test(memberName, () { 107 solo_test(memberName, () {
67 return _runFailingTest(classMirror, symbol); 108 return _runFailingTest(classMirror, symbol);
68 }); 109 });
69 } 110 }
70 }); 111 });
71 }); 112 }
113 String className = MirrorSystem.getName(classMirror.simpleName);
114 if (_hasAnnotationInstance(classMirror, soloTest)) {
115 solo_group(className, runMembers);
116 } else {
117 group(className, runMembers);
118 }
72 } 119 }
73 120
121 bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
122 declaration.metadata.any((InstanceMirror annotation) =>
123 identical(annotation.reflectee, instance));
124
125 bool _hasAssertFailingTestAnnotation(MethodMirror method) =>
126 _hasAnnotationInstance(method, assertFailingTest);
127
128 bool _hasFailingTestAnnotation(MethodMirror method) =>
129 _hasAnnotationInstance(method, failingTest);
130
74 Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) { 131 Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
75 var invocationResult = null; 132 var invocationResult = null;
133 InstanceMirror closure;
76 try { 134 try {
77 invocationResult = instanceMirror.invoke(symbol, []).reflectee; 135 closure = instanceMirror.getField(symbol);
78 } on NoSuchMethodError {} 136 } on NoSuchMethodError {}
79 if (invocationResult is Future) { 137
80 return invocationResult; 138 if (closure is ClosureMirror) {
81 } else { 139 invocationResult = closure.apply([]).reflectee;
82 return new Future.value(invocationResult);
83 } 140 }
141 return new Future.value(invocationResult);
84 } 142 }
85 143
86 /** 144 /**
87 * Run a test that is expected to fail, and confirm that it fails. 145 * Run a test that is expected to fail, and confirm that it fails.
88 * 146 *
89 * This properly handles the following cases: 147 * This properly handles the following cases:
90 * - The test fails by throwing an exception 148 * - The test fails by throwing an exception
91 * - The test returns a future which completes with an error. 149 * - The test returns a future which completes with an error.
92 * 150 *
93 * However, it does not handle the case where the test creates an asynchronous 151 * However, it does not handle the case where the test creates an asynchronous
(...skipping 14 matching lines...) Expand all
108 166
109 /** 167 /**
110 * A marker annotation used to instruct dart2js to keep reflection information 168 * A marker annotation used to instruct dart2js to keep reflection information
111 * for the annotated classes. 169 * for the annotated classes.
112 */ 170 */
113 class ReflectiveTest { 171 class ReflectiveTest {
114 const ReflectiveTest(); 172 const ReflectiveTest();
115 } 173 }
116 174
117 /** 175 /**
118 * A marker annotation used to instruct dart2js to keep reflection information 176 * A marker annotation used to annotate overridden test methods (so we cannot
119 * for the annotated classes. 177 * rename them to `fail_`) which are expected to fail at `assert` in the
178 * checked mode.
120 */ 179 */
121 const ReflectiveTest reflectiveTest = const ReflectiveTest(); 180 class _AssertFailingTest {
181 const _AssertFailingTest();
182 }
183
184 /**
185 * A marker annotation used to annotate overridden test methods (so we cannot
186 * rename them to `fail_`) which are expected to fail.
187 */
188 class _FailingTest {
189 const _FailingTest();
190 }
191
192 /**
193 * A marker annotation used to annotate a test class to run it using
194 * [solo_group].
195 */
196 class _SoloTest {
197 const _SoloTest();
198 }
OLDNEW
« no previous file with comments | « codereview.settings ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698