Update with implementation from 'analyzer'. R=brianwilkerson@google.com BUG= Review URL: https://codereview.chromium.org/2300503003 .
diff --git a/pkgs/test_reflective_loader/CHANGELOG.md b/pkgs/test_reflective_loader/CHANGELOG.md index 2a2d63c..da6f2f7 100644 --- a/pkgs/test_reflective_loader/CHANGELOG.md +++ b/pkgs/test_reflective_loader/CHANGELOG.md
@@ -1,5 +1,9 @@ # Changelog +## 0.0.4 + +- Added @failingTest, @assertFailingTest and @soloTest annotations. + ## 0.0.1 - Initial version
diff --git a/pkgs/test_reflective_loader/codereview.settings b/pkgs/test_reflective_loader/codereview.settings new file mode 100644 index 0000000..3ba713c --- /dev/null +++ b/pkgs/test_reflective_loader/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/pkgs/test_reflective_loader/lib/test_reflective_loader.dart b/pkgs/test_reflective_loader/lib/test_reflective_loader.dart index f8387e3..6e3c945 100644 --- a/pkgs/test_reflective_loader/lib/test_reflective_loader.dart +++ b/pkgs/test_reflective_loader/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/pkgs/test_reflective_loader/pubspec.yaml b/pkgs/test_reflective_loader/pubspec.yaml index 60d4ec8..8b93c1e 100644 --- a/pkgs/test_reflective_loader/pubspec.yaml +++ b/pkgs/test_reflective_loader/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