Update with implementation from 'analyzer'.
R=brianwilkerson@google.com
BUG=
Review URL: https://codereview.chromium.org/2300503003 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a2d63c..da6f2f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 0.0.4
+
+- Added @failingTest, @assertFailingTest and @soloTest annotations.
+
## 0.0.1
- Initial version
diff --git a/codereview.settings b/codereview.settings
new file mode 100644
index 0000000..3ba713c
--- /dev/null
+++ b/codereview.settings
@@ -0,0 +1,4 @@
+# This file is used by gcl to get repository specific information.
+CODE_REVIEW_SERVER: http://codereview.chromium.org
+VIEW_VC: https://github.com/dart-lang/test_reflective_loader/commit/
+CC_LIST: reviews@dartlang.org
diff --git a/lib/test_reflective_loader.dart b/lib/test_reflective_loader.dart
index f8387e3..6e3c945 100644
--- a/lib/test_reflective_loader.dart
+++ b/lib/test_reflective_loader.dart
@@ -4,14 +4,50 @@
library test_reflective_loader;
+import 'dart:async';
@MirrorsUsed(metaTargets: 'ReflectiveTest')
import 'dart:mirrors';
-import 'dart:async';
import 'package:unittest/unittest.dart';
/**
- * Define tests using methods existing in the given [type].
+ * A marker annotation used to annotate overridden test methods (so we cannot
+ * rename them to `fail_`) which are expected to fail at `assert` in the
+ * checked mode.
+ */
+const _AssertFailingTest assertFailingTest = const _AssertFailingTest();
+
+/**
+ * A marker annotation used to annotate overridden test methods (so we cannot
+ * rename them to `fail_`) which are expected to fail.
+ */
+const _FailingTest failingTest = const _FailingTest();
+
+/**
+ * A marker annotation used to instruct dart2js to keep reflection information
+ * for the annotated classes.
+ */
+const ReflectiveTest reflectiveTest = const ReflectiveTest();
+
+/**
+ * Test classes annotated with this annotation are run using [solo_group].
+ */
+const _SoloTest soloTest = const _SoloTest();
+
+/**
+ * Is `true` the application is running in the checked mode.
+ */
+final bool _isCheckedMode = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+
+/**
+ * Runs test methods existing in the given [type].
*
* Methods with names starting with `test` are run using [test] function.
* Methods with names starting with `solo_test` are run using [solo_test] function.
@@ -23,20 +59,20 @@
* method invocation.
*
* If [type] declares method `tearDown`, it will be invoked after any test
- * method invocation. If method returns [Future] to test some asyncronous
+ * method invocation. If method returns [Future] to test some asynchronous
* behavior, then `tearDown` will be invoked in `Future.complete`.
*/
void defineReflectiveTests(Type type) {
ClassMirror classMirror = reflectClass(type);
if (!classMirror.metadata.any((InstanceMirror annotation) =>
- annotation.type.reflectedType == ReflectiveTest)) {
+ annotation.type.reflectedType == ReflectiveTest)) {
String name = MirrorSystem.getName(classMirror.qualifiedName);
throw new Exception('Class $name must have annotation "@reflectiveTest" '
'in order to be run by runReflectiveTests.');
}
- String className = MirrorSystem.getName(classMirror.simpleName);
- group(className, () {
- classMirror.instanceMembers.forEach((symbol, memberMirror) {
+ void runMembers() {
+ classMirror.instanceMembers
+ .forEach((Symbol symbol, MethodMirror memberMirror) {
// we need only methods
if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) {
return;
@@ -45,7 +81,12 @@
// test_
if (memberName.startsWith('test_')) {
test(memberName, () {
- return _runTest(classMirror, symbol);
+ if (_hasFailingTestAnnotation(memberMirror) ||
+ _isCheckedMode && _hasAssertFailingTestAnnotation(memberMirror)) {
+ return _runFailingTest(classMirror, symbol);
+ } else {
+ return _runTest(classMirror, symbol);
+ }
});
return;
}
@@ -68,19 +109,36 @@
});
}
});
- });
+ }
+ String className = MirrorSystem.getName(classMirror.simpleName);
+ if (_hasAnnotationInstance(classMirror, soloTest)) {
+ solo_group(className, runMembers);
+ } else {
+ group(className, runMembers);
+ }
}
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+ declaration.metadata.any((InstanceMirror annotation) =>
+ identical(annotation.reflectee, instance));
+
+bool _hasAssertFailingTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, assertFailingTest);
+
+bool _hasFailingTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, failingTest);
+
Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
var invocationResult = null;
+ InstanceMirror closure;
try {
- invocationResult = instanceMirror.invoke(symbol, []).reflectee;
+ closure = instanceMirror.getField(symbol);
} on NoSuchMethodError {}
- if (invocationResult is Future) {
- return invocationResult;
- } else {
- return new Future.value(invocationResult);
+
+ if (closure is ClosureMirror) {
+ invocationResult = closure.apply([]).reflectee;
}
+ return new Future.value(invocationResult);
}
/**
@@ -115,7 +173,26 @@
}
/**
- * A marker annotation used to instruct dart2js to keep reflection information
- * for the annotated classes.
+ * A marker annotation used to annotate overridden test methods (so we cannot
+ * rename them to `fail_`) which are expected to fail at `assert` in the
+ * checked mode.
*/
-const ReflectiveTest reflectiveTest = const ReflectiveTest();
+class _AssertFailingTest {
+ const _AssertFailingTest();
+}
+
+/**
+ * A marker annotation used to annotate overridden test methods (so we cannot
+ * rename them to `fail_`) which are expected to fail.
+ */
+class _FailingTest {
+ const _FailingTest();
+}
+
+/**
+ * A marker annotation used to annotate a test class to run it using
+ * [solo_group].
+ */
+class _SoloTest {
+ const _SoloTest();
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 60d4ec8..8b93c1e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: test_reflective_loader
-version: 0.0.3
+version: 0.0.4
description: Support for discovering tests and test suites using reflection.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/test_reflective_loader