blob: 969a1bb1a1cd5bbe427d0e714457257d31461620 [file] [log] [blame]
// Copyright (c) 2013, 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.
// OtherResources=skipping_dart2js_compilations_helper.dart
* This test makes sure that the "skipping Dart2Js compilations if the output is
* already up to date" feature does work as it should.
* Therefore this test ensures that compilations are only skipped if the last
* modified date of the output of a dart2js compilation is newer than
* - the dart application to compile (including it's dependencies)
* - the dart2js snapshot
* Furthermore it ensures that a compilation is not skipped if any of the
* necessary files could not be found (dart2js snapshots, previous dart2js
* output (+deps file), dart application)
import 'dart:async';
import 'dart:io';
import 'package:expect/expect.dart';
import 'package:test_runner/src/command.dart';
import 'package:test_runner/src/command_output.dart';
import 'package:test_runner/src/path.dart';
import 'package:test_runner/src/repository.dart';
import 'package:test_runner/src/test_case.dart';
import 'utils.dart';
/// This class is reponsible for setting up the files necessary for this test
/// as well as touching a file.
class FileUtils {
late Directory tempDir;
File? testJs;
File? testJsDeps;
File? testDart;
File? testSnapshot;
{required bool createJs,
required bool createJsDeps,
required bool createDart,
required bool createSnapshot}) {
tempDir = Directory.systemTemp
if (createJs) {
testJs = _createFile(testJsFilePath);
_writeToFile(testJs!, "test.js content");
if (createSnapshot) {
testSnapshot = _createFile(testSnapshotFilePath);
_writeToFile(testSnapshot!, "dart2js snapshot");
if (createDart) {
testDart = _createFile(testDartFilePath);
_writeToFile(testDart!, "dart code");
if (createJsDeps) {
testJsDeps = _createFile(testJsDepsFilePath);
var path = Path(tempDir.path).append("test.dart").absolute;
_writeToFile(testJsDeps!, "file://$path");
void cleanup() {
if (testJs != null) testJs!.deleteSync();
if (testJsDeps != null) testJsDeps!.deleteSync();
if (testDart != null) testDart!.deleteSync();
if (testSnapshot != null) testSnapshot!.deleteSync();
// if the script did run, it created this file, so we need to delete it
var file = File(scriptOutputPath.toNativePath());
if (file.existsSync()) {
Path get scriptOutputPath {
return Path(tempDir.path).append('created_if_command_did_run.txt').absolute;
Path get testDartFilePath {
return Path(tempDir.path).append('test.dart').absolute;
Path get testJsFilePath {
return Path(tempDir.path).append('test.js').absolute;
Path get testJsDepsFilePath {
return Path(tempDir.path).append('test.js.deps').absolute;
Path get testSnapshotFilePath {
return Path(tempDir.path).append('test_dart2js.snapshot').absolute;
void touchFile(File file) {
_writeToFile(file, _readFile(file));
void _writeToFile(File file, String content) {
File(file.resolveSymbolicLinksSync()).openSync(mode: FileMode.write)
String _readFile(File file) {
return file.readAsStringSync();
File _createFile(Path path) {
var file = File(path.toNativePath());
return file;
class CommandCompletedHandler {
FileUtils fileUtils;
final bool _shouldHaveRun;
CommandCompletedHandler(this.fileUtils, this._shouldHaveRun);
void processCompletedTest(CommandOutput output) {
Expect.equals(0, output.exitCode);
Expect.equals(0, output.stderr.length);
if (_shouldHaveRun) {
Expect.equals(0, output.stdout.length);
} else {
Command makeCompilationCommand(String testName, FileUtils fileUtils) {
var createFileScript = Platform.script
var executable = Platform.executable;
var arguments = <String>[]
var bootstrapDeps = [Uri.parse("file://${fileUtils.testSnapshotFilePath}")];
return CompilationCommand('dart2js', fileUtils.testJsFilePath.toNativePath(),
bootstrapDeps, executable, arguments, {},
alwaysCompile: false, workingDirectory: Directory.current.path);
void main() {
// This script is in [sdk]/pkg/test_runner/test.
Repository.uri = Platform.script.resolve('../../..');
var fs_noTestJs = FileUtils(
createJs: false,
createJsDeps: true,
createDart: true,
createSnapshot: true);
var fs_noTestJsDeps = FileUtils(
createJs: true,
createJsDeps: false,
createDart: true,
createSnapshot: true);
var fs_noTestDart = FileUtils(
createJs: true,
createJsDeps: true,
createDart: false,
createSnapshot: true);
var fs_noTestSnapshot = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: false);
var fs_notUpToDate_snapshot = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: true);
var fs_notUpToDate_dart = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: true);
var fs_upToDate = FileUtils(
createJs: true,
createJsDeps: true,
createDart: true,
createSnapshot: true);
void cleanup() {
Future<void> touchFilesAndRunTests() async {
Future runTest(String name, FileUtils fileUtils, bool shouldRun) {
var completedHandler = CommandCompletedHandler(fileUtils, shouldRun);
var command = makeCompilationCommand(name, fileUtils) as ProcessCommand;
var process = RunningProcess(command, 60,
configuration: makeConfiguration([], 'dummy'));
return output) {
try {
// We run the tests in sequence, so that if one of them fails we clean up
// everything and throw.
await runTest("fs_noTestJs", fs_noTestJs, true);
await runTest("fs_noTestJsDeps", fs_noTestJsDeps, true);
await runTest("fs_noTestDart", fs_noTestDart, true);
await runTest("fs_noTestSnapshot", fs_noTestSnapshot, true);
await runTest("fs_notUpToDate_snapshot", fs_notUpToDate_snapshot, true);
await runTest("fs_notUpToDate_dart", fs_notUpToDate_dart, true);
// This is the only test where all dependencies are present and the
// test.js file is newer than all the others. So we pass 'false' for
// shouldRun.
await runTest("fs_upToDate", fs_upToDate, false);
} finally {
// We need to wait some time to make sure that the files we 'touch' get a
// bigger timestamp than the old ones
Timer(const Duration(seconds: 1), touchFilesAndRunTests);