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

Unified Diff: packages/analyzer/test/reflective_tests.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: packages/analyzer/test/reflective_tests.dart
diff --git a/packages/analyzer/test/reflective_tests.dart b/packages/analyzer/test/reflective_tests.dart
new file mode 100644
index 0000000000000000000000000000000000000000..8180cf7800bd85737844932ba1fbdd051637b7fc
--- /dev/null
+++ b/packages/analyzer/test/reflective_tests.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library reflective_tests;
+
+@MirrorsUsed(metaTargets: 'ReflectiveTest')
+import 'dart:mirrors';
+import 'dart:async';
+
+import 'package:unittest/unittest.dart';
+
+/**
+ * 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.
+ *
+ * Each method is run with a new instance of [type].
+ * So, [type] should have a default constructor.
+ *
+ * If [type] declares method `setUp`, it methods will be invoked before any test
+ * method invocation.
+ *
+ * If [type] declares method `tearDown`, it will be invoked after any test
+ * method invocation. If method returns [Future] to test some asyncronous
+ * behavior, then `tearDown` will be invoked in `Future.complete`.
+ */
+void runReflectiveTests(Type type) {
+ ClassMirror classMirror = reflectClass(type);
+ if (!classMirror.metadata.any((InstanceMirror annotation) =>
+ 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) {
+ // we need only methods
+ if (memberMirror is! MethodMirror || !memberMirror.isRegularMethod) {
+ return;
+ }
+ String memberName = MirrorSystem.getName(symbol);
+ // test_
+ if (memberName.startsWith('test_')) {
+ test(memberName, () {
+ return _runTest(classMirror, symbol);
+ });
+ return;
+ }
+ // solo_test_
+ if (memberName.startsWith('solo_test_')) {
+ solo_test(memberName, () {
+ return _runTest(classMirror, symbol);
+ });
+ }
+ // fail_test_
+ if (memberName.startsWith('fail_')) {
+ test(memberName, () {
+ return _runFailingTest(classMirror, symbol);
+ });
+ }
+ // solo_fail_test_
+ if (memberName.startsWith('solo_fail_')) {
+ solo_test(memberName, () {
+ return _runFailingTest(classMirror, symbol);
+ });
+ }
+ });
+ });
+}
+
+Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
+ var invocationResult = null;
+ try {
+ invocationResult = instanceMirror.invoke(symbol, []).reflectee;
+ } on NoSuchMethodError {}
+ if (invocationResult is Future) {
+ return invocationResult;
+ } else {
+ return new Future.value(invocationResult);
+ }
+}
+
+/**
+ * Run a test that is expected to fail, and confirm that it fails.
+ *
+ * This properly handles the following cases:
+ * - The test fails by throwing an exception
+ * - The test returns a future which completes with an error.
+ *
+ * However, it does not handle the case where the test creates an asynchronous
+ * callback using expectAsync(), and that callback generates a failure.
+ */
+Future _runFailingTest(ClassMirror classMirror, Symbol symbol) {
+ return new Future(() => _runTest(classMirror, symbol)).then((_) {
+ fail('Test passed - expected to fail.');
+ }, onError: (_) {});
+}
+
+_runTest(ClassMirror classMirror, Symbol symbol) {
+ InstanceMirror instanceMirror = classMirror.newInstance(new Symbol(''), []);
+ return _invokeSymbolIfExists(instanceMirror, #setUp)
+ .then((_) => instanceMirror.invoke(symbol, []).reflectee)
+ .whenComplete(() => _invokeSymbolIfExists(instanceMirror, #tearDown));
+}
+
+/**
+ * A marker annotation used to instruct dart2js to keep reflection information
+ * for the annotated classes.
+ */
+class ReflectiveTest {
+ const ReflectiveTest();
+}
+
+/**
+ * A marker annotation used to instruct dart2js to keep reflection information
+ * for the annotated classes.
+ */
+const ReflectiveTest reflectiveTest = const ReflectiveTest();

Powered by Google App Engine
This is Rietveld 408576698