Merge branch 'master' into optimize-tests
diff --git a/test/command_line_test.dart b/test/command_line_test.dart
index 5d66710..0b47668 100644
--- a/test/command_line_test.dart
+++ b/test/command_line_test.dart
@@ -13,6 +13,8 @@
import 'utils.dart';
void main() {
+ compileFormatterExecutable();
+
test('formats a directory', () async {
await d.dir('code', [
d.file('a.dart', unformattedSource),
diff --git a/test/command_test.dart b/test/command_test.dart
index 32ed262..20a1928 100644
--- a/test/command_test.dart
+++ b/test/command_test.dart
@@ -11,6 +11,8 @@
import 'utils.dart';
void main() {
+ compileCommandExecutable();
+
test('formats a directory', () async {
await d.dir('code', [
d.file('a.dart', unformattedSource),
diff --git a/test/utils.dart b/test/utils.dart
index da3d766..1ea15de 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -25,17 +25,89 @@
final _indentPattern = RegExp(r'\(indent (\d+)\)');
final _fixPattern = RegExp(r'\(fix ([a-x-]+)\)');
-/// Runs the command line formatter, passing it [args].
-Future<TestProcess> runFormatter([List<String> args]) {
+/// If tool/command_shell.dart has been compiled to a snapshot, this is the path
+/// to it.
+String _commandExecutablePath;
+
+/// If bin/format.dart has been compiled to a snapshot, this is the path to it.
+String _formatterExecutablePath;
+
+/// Compiles format.dart to a native executable for tests to use.
+void compileFormatterExecutable() {
+ setUpAll(() async {
+ _formatterExecutablePath = await _compileExecutable('bin/format.dart');
+ });
+
+ tearDownAll(() async {
+ await _deleteExecutable(_formatterExecutablePath);
+ _formatterExecutablePath = null;
+ });
+}
+
+/// Compiles command_shell.dart to a native executable for tests to use.
+void compileCommandExecutable() {
+ setUpAll(() async {
+ _commandExecutablePath =
+ await _compileExecutable('tool/command_shell.dart');
+ });
+
+ tearDownAll(() async {
+ await _deleteExecutable(_commandExecutablePath);
+ _commandExecutablePath = null;
+ });
+}
+
+/// Compile the Dart [script] to a native executable.
+///
+/// We do this instead of spawning the script from source each time because it's
+/// much faster when the same script needs to be run several times.
+Future<String> _compileExecutable(String script) async {
+ var scriptName = p.basename(script);
+ var tempDir =
+ await Directory.systemTemp.createTemp(p.withoutExtension(scriptName));
+ var executable = p.join(tempDir.path, '$scriptName.aot');
+
+ var dart2Native =
+ p.join(p.dirname(Platform.resolvedExecutable), 'dart2native');
+
// Locate the "test" directory. Use mirrors so that this works with the test
// package, which loads this suite into an isolate.
var testDir = p.dirname(currentMirrorSystem()
.findLibrary(#dart_style.test.utils)
.uri
.toFilePath());
+ var scriptPath = p.normalize(p.join(p.dirname(testDir), script));
- var formatterPath = p.normalize(p.join(testDir, '../bin/format.dart'));
- return TestProcess.start(Platform.executable, [formatterPath, ...?args],
+ var compileResult = await Process.run(
+ dart2Native, [scriptPath, '--output', executable]);
+
+ if (compileResult.exitCode != 0) {
+ fail('Could not compile $scriptName to a snapshot (exit code '
+ '${compileResult.exitCode}):\n${compileResult.stdout}\n\n'
+ '${compileResult.stderr}');
+ }
+
+ return executable;
+}
+
+/// Attempts to delete to temporary directory created for [executable] by
+/// [_createSnapshot()].
+Future<void> _deleteExecutable(String executable) async {
+ try {
+ await Directory(p.dirname(executable)).delete(recursive: true);
+ } on IOException {
+ // Do nothing if we failed to delete it. The OS will eventually clean it
+ // up.
+ }
+}
+
+/// Runs the command line formatter, passing it [args].
+Future<TestProcess> runFormatter([List<String> args]) {
+ if (_formatterExecutablePath == null) {
+ fail('Must call createFormatterExecutable() before running commands.');
+ }
+
+ return TestProcess.start(_formatterExecutablePath, args ?? <String>[],
workingDirectory: d.sandbox);
}
@@ -47,17 +119,11 @@
/// Runs the test shell for the [Command]-based formatter, passing it [args].
Future<TestProcess> runCommand([List<String> args]) {
- // Locate the "test" directory. Use mirrors so that this works with the test
- // package, which loads this suite into an isolate.
- var testDir = p.dirname(currentMirrorSystem()
- .findLibrary(#dart_style.test.utils)
- .uri
- .toFilePath());
+ if (_commandExecutablePath == null) {
+ fail('Must call createCommandExecutable() before running commands.');
+ }
- var formatterPath =
- p.normalize(p.join(testDir, '../tool/command_shell.dart'));
- return TestProcess.start(
- Platform.executable, [formatterPath, 'format', ...?args],
+ return TestProcess.start(_commandExecutablePath, ['format', ...?args],
workingDirectory: d.sandbox);
}