blob: dc264a254f7077c2c162fd51a697c74be61c4b3a [file] [log] [blame]
// 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.
// Checks that dart2js produces the expected static type warnings and
// compile-time errors for the provided multitests.
import 'dart:async';
import 'dart:io';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/util/uri_extras.dart' show relativize;
import 'memory_compiler.dart';
import '../../../tools/testing/dart/multitest.dart'
show ExtractTestsFromMultitest;
import '../../../tools/testing/dart/path.dart' show Path;
/// Check the analysis of the multitests in [testFiles] to result in the
/// expected static warnings and compile-time errors.
///
/// [testFiles] is a map of the test files to be checked together with their
/// associated white listing.
///
/// For instance if [testFiles] contain the mapping
/// 'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
/// the multitests in 'language/async_await_syntax_test.dart' are checked but
/// the subtests 'a03b' and 'a04c' are expected to fail.
void check(Map<String, List<String>> testFiles,
{List<String> arguments: const <String>[],
List<String> options: const <String>[]}) {
bool outcomeMismatch = false;
bool verbose = arguments.contains('-v');
var cachedCompiler;
asyncTest(() => Future.forEach(testFiles.keys, (String testFile) {
Map<String, String> testSources = {};
Map<String, Set<String>> testOutcomes = {};
String fileName = 'tests/$testFile';
ExtractTestsFromMultitest(
new Path(fileName), testSources, testOutcomes);
return Future.forEach(testSources.keys, (String testName) async {
String testFileName = '$fileName/$testName';
Set<String> expectedOutcome = testOutcomes[testName];
bool expectFailure = testFiles[testFile].contains(testName);
DiagnosticCollector collector = new DiagnosticCollector();
CompilationResult result = await runCompiler(
entryPoint: Uri.parse('memory:$testFileName'),
memorySourceFiles: {testFileName: testSources[testName]},
diagnosticHandler: collector,
options: [Flags.analyzeOnly]..addAll(options),
showDiagnostics: verbose,
cachedCompiler: cachedCompiler);
var compiler = result.compiler;
bool unexpectedResult = false;
if (expectedOutcome.contains('compile-time error')) {
if (collector.errors.isEmpty) {
print('$testFileName: Missing compile-time error.');
unexpectedResult = true;
}
} else if (expectedOutcome.contains('static type warning')) {
if (collector.warnings.isEmpty) {
print('$testFileName: Missing static type warning.');
unexpectedResult = true;
}
} else {
// Expect ok.
if (!collector.errors.isEmpty || !collector.warnings.isEmpty) {
collector.errors.forEach((message) {
print('$testFileName: Unexpected error: ${message.message}');
});
collector.warnings.forEach((message) {
print('$testFileName: Unexpected warning: ${message.message}');
});
unexpectedResult = true;
}
}
if (expectFailure) {
if (unexpectedResult) {
unexpectedResult = false;
} else {
print('$testFileName: The test is white-listed '
'and therefore expected to fail.');
unexpectedResult = true;
}
}
if (unexpectedResult) {
outcomeMismatch = true;
}
cachedCompiler = compiler;
});
}).then((_) {
if (outcomeMismatch) {
String testFileName =
relativize(Uri.base, Platform.script, Platform.isWindows);
print('''
===
=== ERROR: Unexpected result of analysis.
===
=== Please update the white-listing in $testFileName
===
''');
exit(1);
}
}));
}