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

Unified Diff: lib/src/runner.dart

Issue 1490973003: Clean up the warning for unknown tags. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 5 years 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
« no previous file with comments | « no previous file | lib/src/runner/load_suite.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/runner.dart
diff --git a/lib/src/runner.dart b/lib/src/runner.dart
index 7ab303211157a41ec2d73cd53f4c15da15a55ce9..7ff651d13cfcc49cb1e5b1c8507f51bb423bfca8 100644
--- a/lib/src/runner.dart
+++ b/lib/src/runner.dart
@@ -9,6 +9,10 @@ import 'dart:io';
import 'package:async/async.dart';
+import 'backend/group.dart';
+import 'backend/group_entry.dart';
+import 'backend/suite.dart';
+import 'backend/test.dart';
import 'backend/test_platform.dart';
import 'runner/application_exception.dart';
import 'runner/configuration.dart';
@@ -45,6 +49,13 @@ class Runner {
/// The subscription to the stream returned by [_loadSuites].
StreamSubscription _suiteSubscription;
+ /// The set of suite paths for which [_warnForUnknownTags] has already been
+ /// called.
+ ///
+ /// This is used to avoid printing duplicate warnings when a suite is loaded
+ /// on multiple platforms.
+ final _tagWarningSuites = new Set<String>();
+
/// The memoizer for ensuring [close] only runs once.
final _closeMemo = new AsyncMemoizer();
bool get _closed => _closeMemo.hasRun;
@@ -170,30 +181,9 @@ class Runner {
]);
})).map((loadSuite) {
return loadSuite.changeSuite((suite) {
- return suite.filter((test) {
- // Warn if any test has tags that don't appear on the command line.
- //
- // TODO(nweiz): Only print this once per test, even if it's run on
- // multiple runners.
- //
- // TODO(nweiz): If groups or suites are tagged, don't print this for
- // every test they contain.
- //
- // TODO(nweiz): Print this as part of the test's output so it's easy
- // to associate with the correct test.
- var specifiedTags = _config.tags.union(_config.excludeTags);
- var unrecognizedTags = test.metadata.tags.difference(specifiedTags);
- if (unrecognizedTags.isNotEmpty) {
- // Pause the reporter while we print to ensure that we don't
- // interfere with its output.
- _reporter.pause();
- warn(
- 'Unknown ${pluralize('tag', unrecognizedTags.length)} '
- '${toSentence(unrecognizedTags)} in test "${test.name}".',
- color: _config.color);
- _reporter.resume();
- }
+ _warnForUnknownTags(suite);
+ return suite.filter((test) {
// Skip any tests that don't match the given pattern.
if (_config.pattern != null && !test.name.contains(_config.pattern)) {
return false;
@@ -216,6 +206,81 @@ class Runner {
});
}
+ /// Prints a warning for any unknown tags referenced in [suite] or its
+ /// children.
+ void _warnForUnknownTags(Suite suite) {
+ if (_tagWarningSuites.contains(suite.path)) return;
+ _tagWarningSuites.add(suite.path);
+
+ var unknownTags = _collectUnknownTags(suite);
+ if (unknownTags.isEmpty) return;
+
+ var yellow = _config.color ? '\u001b[33m' : '';
+ var bold = _config.color ? '\u001b[1m' : '';
+ var noColor = _config.color ? '\u001b[0m' : '';
+
+ var buffer = new StringBuffer()
+ ..write("${yellow}Warning:$noColor ")
+ ..write(unknownTags.length == 1 ? "A tag was " : "Tags were ")
+ ..write("used that ")
+ ..write(unknownTags.length == 1 ? "wasn't " : "weren't ")
+ ..writeln("specified on the command line.");
+
+ unknownTags.forEach((tag, entries) {
+ buffer.write(" $bold$tag$noColor was used in");
+
+ if (entries.length == 1) {
+ buffer.writeln(" ${_entryDescription(entries.single)}");
+ return;
+ }
+
+ buffer.write(":");
+ for (var entry in entries) {
+ buffer.write("\n ${_entryDescription(entry)}");
+ }
+ buffer.writeln();
+ });
+
+ print(buffer.toString());
+ }
+
+ /// Collects all tags used by [suite] or its children that aren't also passed
+ /// on the command line.
+ ///
+ /// This returns a map from tag names to lists of entries that use those tags.
+ Map<String, List<GroupEntry>> _collectUnknownTags(Suite suite) {
+ var knownTags = _config.tags.union(_config.excludeTags);
+ var unknownTags = {};
+ var currentTags = new Set();
+
+ collect(entry) {
+ var newTags = new Set();
+ for (var unknownTag in entry.metadata.tags.difference(knownTags)) {
+ if (currentTags.contains(unknownTag)) continue;
+ unknownTags.putIfAbsent(unknownTag, () => []).add(entry);
+ newTags.add(unknownTag);
+ }
+
+ if (entry is! Group) return;
+
+ currentTags.addAll(newTags);
+ for (var child in entry.entries) {
+ collect(child);
+ }
+ currentTags.removeAll(newTags);
+ }
+
+ collect(suite.group);
+ return unknownTags;
+ }
+
+ /// Returns a human-readable description of [entry], including its type.
+ String _entryDescription(GroupEntry entry) {
+ if (entry is Test) return 'the test "${entry.name}"';
+ if (entry.name != null) return 'the group "${entry.name}"';
+ return 'the suite itself';
+ }
+
/// Loads each suite in [suites] in order, pausing after load for platforms
/// that support debugging.
Future<bool> _loadThenPause(Stream<LoadSuite> suites) async {
« no previous file with comments | « no previous file | lib/src/runner/load_suite.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698