| // 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'; |
| |
| /// This class is reponsible for setting up the files necessary for this test |
| /// as well as touching a file. |
| class FileUtils { |
| Directory tempDir; |
| File testJs; |
| File testJsDeps; |
| File testDart; |
| File testSnapshot; |
| |
| FileUtils( |
| {bool createJs, |
| bool createJsDeps, |
| bool createDart, |
| bool createSnapshot}) { |
| tempDir = Directory.systemTemp |
| .createTempSync('dart_skipping_dart2js_compilations'); |
| 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()) { |
| file.deleteSync(); |
| } |
| |
| tempDir.deleteSync(); |
| } |
| |
| 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) { |
| if (content != null) { |
| var fd = |
| File(file.resolveSymbolicLinksSync()).openSync(mode: FileMode.write); |
| fd.writeStringSync(content); |
| fd.closeSync(); |
| } |
| } |
| |
| String _readFile(File file) { |
| return file.readAsStringSync(); |
| } |
| |
| File _createFile(Path path) { |
| var file = File(path.toNativePath()); |
| file.createSync(); |
| 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); |
| Expect.isTrue( |
| File(fileUtils.scriptOutputPath.toNativePath()).existsSync()); |
| } else { |
| Expect.isFalse( |
| File(fileUtils.scriptOutputPath.toNativePath()).existsSync()); |
| } |
| } |
| } |
| |
| Command makeCompilationCommand(String testName, FileUtils fileUtils) { |
| var createFileScript = Platform.script |
| .resolve('skipping_dart2js_compilations_helper.dart') |
| .toFilePath(); |
| var executable = Platform.executable; |
| var arguments = <String>[] |
| ..addAll(Platform.executableArguments) |
| ..add(createFileScript) |
| ..add(fileUtils.scriptOutputPath.toNativePath()); |
| var bootstrapDeps = [Uri.parse("file://${fileUtils.testSnapshotFilePath}")]; |
| return CompilationCommand('dart2js', fileUtils.testJsFilePath.toNativePath(), |
| bootstrapDeps, executable, arguments, {}, |
| alwaysCompile: false); |
| } |
| |
| 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() { |
| fs_noTestJs.cleanup(); |
| fs_noTestJsDeps.cleanup(); |
| fs_noTestDart.cleanup(); |
| fs_noTestSnapshot.cleanup(); |
| fs_notUpToDate_snapshot.cleanup(); |
| fs_notUpToDate_dart.cleanup(); |
| fs_upToDate.cleanup(); |
| } |
| |
| void touchFilesAndRunTests() { |
| fs_notUpToDate_snapshot.touchFile(fs_notUpToDate_snapshot.testSnapshot); |
| fs_notUpToDate_dart.touchFile(fs_notUpToDate_dart.testDart); |
| fs_upToDate.touchFile(fs_upToDate.testJs); |
| |
| 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); |
| return process.run().then((CommandOutput output) { |
| completedHandler.processCompletedTest(output); |
| }); |
| } |
| |
| // We run the tests in sequence, so that if one of them fails we clean up |
| // everything and throw. |
| runTest("fs_noTestJs", fs_noTestJs, true).then((_) { |
| return runTest("fs_noTestJsDeps", fs_noTestJsDeps, true); |
| }).then((_) { |
| return runTest("fs_noTestDart", fs_noTestDart, true); |
| }).then((_) { |
| return runTest("fs_noTestSnapshot", fs_noTestSnapshot, true); |
| }).then((_) { |
| return runTest("fs_notUpToDate_snapshot", fs_notUpToDate_snapshot, true); |
| }).then((_) { |
| return runTest("fs_notUpToDate_dart", fs_notUpToDate_dart, true); |
| }).then((_) { |
| // 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. |
| return runTest("fs_upToDate", fs_upToDate, false); |
| }).catchError((error) { |
| cleanup(); |
| throw error; |
| }).then((_) { |
| cleanup(); |
| }); |
| } |
| |
| // 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); |
| } |