Index: pkg/testing/lib/src/multitest.dart |
diff --git a/pkg/testing/lib/src/multitest.dart b/pkg/testing/lib/src/multitest.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4679633922f1f2e97e14429022fb4a1d9935df7d |
--- /dev/null |
+++ b/pkg/testing/lib/src/multitest.dart |
@@ -0,0 +1,124 @@ |
+// Copyright (c) 2016, 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.md file. |
+ |
+library testing.multitest; |
+ |
+import 'dart:async' show |
+ Stream, |
+ StreamTransformer; |
+ |
+import 'dart:io' show |
+ Directory, |
+ File; |
+ |
+import 'log.dart' show |
+ splitLines; |
+ |
+import 'test_description.dart' show |
+ TestDescription; |
+ |
+class MultitestTransformer |
+ implements StreamTransformer<TestDescription, TestDescription> { |
+ static const String multitestMarker = "///"; |
+ |
+ static const List<String> validOutcomesList = const <String>[ |
+ 'ok', |
+ 'compile-time error', |
+ 'runtime error', |
+ 'static type warning', |
+ 'dynamic type error', |
+ 'checked mode compile-time error', |
+ ]; |
+ |
+ static final Set<String> validOutcomes = |
+ new Set<String>.from(validOutcomesList); |
+ |
+ Stream<TestDescription> bind(Stream<TestDescription> stream) async* { |
+ List<String> errors = <String>[]; |
+ reportError(String error) { |
+ errors.add(error); |
+ print(error); |
+ } |
+ nextTest: await for (TestDescription test in stream) { |
+ String contents = await test.file.readAsString(); |
+ if (!contents.contains(multitestMarker)) { |
+ yield test; |
+ continue nextTest; |
+ } |
+ // Note: this is modified in the loop below. |
+ List<String> linesWithoutAnnotations = <String>[]; |
+ Map<String, List<String>> testsAsLines = <String, List<String>>{ |
+ "none": linesWithoutAnnotations, |
+ }; |
+ Map<String, Set<String>> outcomes = <String, Set<String>>{ |
+ "none": new Set<String>(), |
+ }; |
+ int lineNumber = 0; |
+ for (String line in splitLines(contents)) { |
+ lineNumber++; |
+ int index = line.indexOf(multitestMarker); |
+ String subtestName; |
+ List<String> subtestOutcomesList; |
+ if (index != -1) { |
+ String annotationText = |
+ line.substring(index + multitestMarker.length).trim(); |
+ index = annotationText.indexOf(":"); |
+ if (index != -1) { |
+ subtestName = annotationText.substring(0, index).trim(); |
+ subtestOutcomesList = annotationText.substring(index + 1).split(",") |
+ .map((s) => s.trim()).toList(); |
+ if (subtestName == "none") { |
+ reportError(test.formatError( |
+ "$lineNumber: $subtestName can't be used as test name.")); |
+ continue nextTest; |
+ } |
+ if (subtestOutcomesList.isEmpty) { |
+ reportError(test.formatError( |
+ "$lineNumber: Expected <testname>:<outcomes>")); |
+ continue nextTest; |
+ } |
+ } |
+ } |
+ if (subtestName != null) { |
+ List<String> lines = testsAsLines.putIfAbsent(subtestName, |
+ () => new List<String>.from(linesWithoutAnnotations)); |
+ lines.add(line); |
+ Set<String> subtestOutcomes = outcomes.putIfAbsent(subtestName, |
+ () => new Set<String>()); |
+ if (subtestOutcomesList.length != 1 || |
+ subtestOutcomesList.single != "continued") { |
+ for (String outcome in subtestOutcomesList) { |
+ if (validOutcomes.contains(outcome)) { |
+ subtestOutcomes.add(outcome); |
+ } else { |
+ reportError(test.formatError( |
+ "$lineNumber: '$outcome' isn't a recognized outcome.")); |
+ continue nextTest; |
+ } |
+ } |
+ } |
+ } else { |
+ for (List<String> lines in testsAsLines.values) { |
+ // This will also modify [linesWithoutAnnotations]. |
+ lines.add(line); |
+ } |
+ } |
+ } |
+ Uri root = Uri.base.resolve("generated/"); |
+ Directory generated = new Directory.fromUri(root.resolve(test.shortName)); |
+ generated = await generated.create(recursive: true); |
+ for (String name in testsAsLines.keys) { |
+ List<String> lines = testsAsLines[name]; |
+ Uri uri = generated.uri.resolve("${name}_generated.dart"); |
+ TestDescription subtest = |
+ new TestDescription(root, new File.fromUri(uri)); |
+ await subtest.file.writeAsString(lines.join("")); |
+ yield subtest; |
+ } |
+ } |
+ if (errors.isNotEmpty) { |
+ throw "Error: ${errors.join("\n")}"; |
+ } |
+ } |
+} |