71eaf3209b
This CL fixes some bugs and regressions in the 'fasta testing sdk' tool:
* Plugs the excessive memory leak in suite.dart (thanks to jensj
for helping tracking it down)
* Fixes the signature of MultitestTransformer.bind such that it no
longer causes a type error to happen at runtime.
* Removes the code that disallows test name "none".
* Updates the exclude list in testing.json
Change-Id: Ie850139c2228550c9847883d4fdaed839a052200
Reviewed-on: https://dart-review.googlesource.com/76840
Reviewed-by: Peter von der Ahé <ahe@google.com>
Commit-Queue: Daniel Hillerström <hillerstrom@google.com>
143 lines
4.8 KiB
Dart
143 lines
4.8 KiB
Dart
// 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, StreamTransformerBase;
|
|
|
|
import 'dart:io' show Directory, File;
|
|
|
|
import 'log.dart' show splitLines;
|
|
|
|
import 'test_description.dart' show FileBasedTestDescription, TestDescription;
|
|
|
|
bool isError(Set<String> expectations) {
|
|
if (expectations.contains("compile-time error")) return true;
|
|
if (expectations.contains("runtime error")) return true;
|
|
return false;
|
|
}
|
|
|
|
bool isCheckedModeError(Set<String> expectations) {
|
|
if (expectations.contains("checked mode compile-time error")) return true;
|
|
if (expectations.contains("dynamic type error")) return true;
|
|
return isError(expectations);
|
|
}
|
|
|
|
class MultitestTransformer
|
|
extends StreamTransformerBase<TestDescription, TestDescription> {
|
|
static RegExp multitestMarker = new RegExp(r"//[#/]");
|
|
static int _multitestMarkerLength = 3;
|
|
|
|
static const List<String> validOutcomesList = const <String>[
|
|
"ok",
|
|
"syntax error",
|
|
"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) {
|
|
FileBasedTestDescription multitest;
|
|
String contents;
|
|
if (test is FileBasedTestDescription) {
|
|
contents = await test.file.readAsString();
|
|
if (contents.contains(multitestMarker)) {
|
|
multitest = test;
|
|
}
|
|
}
|
|
|
|
if (multitest == null) {
|
|
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 + _multitestMarkerLength).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 (subtestOutcomesList.isEmpty) {
|
|
reportError(multitest
|
|
.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(multitest.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(multitest.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");
|
|
FileBasedTestDescription subtest =
|
|
new FileBasedTestDescription(root, new File.fromUri(uri));
|
|
subtest.multitestExpectations = outcomes[name];
|
|
await subtest.file.writeAsString(lines.join(""));
|
|
yield subtest;
|
|
}
|
|
}
|
|
if (errors.isNotEmpty) {
|
|
throw "Error: ${errors.join("\n")}";
|
|
}
|
|
}
|
|
}
|