Skip to content
This repository has been archived by the owner on Jan 14, 2025. It is now read-only.

Commit

Permalink
Update with implementation from 'analyzer'.
Browse files Browse the repository at this point in the history
R=brianwilkerson@google.com
BUG=

Review URL: https://codereview.chromium.org/2300503003 .
  • Loading branch information
scheglov committed Aug 31, 2016
1 parent d7e0f5c commit 1630a63
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.0.4

- Added @failingTest, @assertFailingTest and @soloTest annotations.

## 0.0.1

- Initial version
4 changes: 4 additions & 0 deletions codereview.settings
Original file line number Diff line number Diff line change
@@ -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
111 changes: 94 additions & 17 deletions lib/test_reflective_loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -23,20 +59,20 @@ import 'package:unittest/unittest.dart';
* 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;
Expand All @@ -45,7 +81,12 @@ void defineReflectiveTests(Type type) {
// 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;
}
Expand All @@ -68,19 +109,36 @@ void defineReflectiveTests(Type type) {
});
}
});
});
}
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);
}

/**
Expand Down Expand Up @@ -115,7 +173,26 @@ class ReflectiveTest {
}

/**
* 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();
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit 1630a63

Please sign in to comment.