blob: aa14d54759a426bf9fca25c069e48b5e73b2d567 [file] [log] [blame]
// Copyright (c) 2017, 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.
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:sourcemap_testing/src/annotated_code_helper.dart';
import 'package:sourcemap_testing/src/stacktrace_helper.dart';
import 'package:testing/testing.dart';
import 'common.dart';
abstract class DdcRunner {
ProcessResult runDDC(String ddcDir, String inputFile, String outputFile,
String outWrapperPath);
}
class Compile extends Step<Data, Data, ChainContext> {
final DdcRunner ddcRunner;
const Compile(this.ddcRunner);
String get name => "compile";
Future<Result<Data>> run(Data data, ChainContext context) async {
var dartScriptAbsolute = new File.fromUri(data.uri).absolute;
var inputFile = dartScriptAbsolute.path;
data.outDir = await Directory.systemTemp.createTemp("ddc_step_test");
data.code = new AnnotatedCode.fromText(
new File(inputFile).readAsStringSync(), commentStart, commentEnd);
var testFile = "${data.outDir.path}/test.dart";
new File(testFile).writeAsStringSync(data.code.sourceCode);
var outputPath = data.outDir.path;
var outputFilename = "js.js";
var outputFile = path.join(outputPath, outputFilename);
var outWrapperPath = path.join(outputPath, "wrapper.js");
ddcRunner.runDDC(getDdcDir().path, testFile, outputFile, outWrapperPath);
return pass(data);
}
}
class TestStackTrace extends Step<Data, Data, ChainContext> {
final DdcRunner ddcRunner;
final String marker;
final List<String> knownMarkers;
const TestStackTrace(this.ddcRunner, this.marker, this.knownMarkers);
String get name => "TestStackTrace";
Future<Result<Data>> run(Data data, ChainContext context) async {
data.outDir = await Directory.systemTemp.createTemp("stacktrace-test");
String code = await new File.fromUri(data.uri).readAsString();
Test test = processTestCode(code, knownMarkers);
await testStackTrace(test, marker, _compile,
jsPreambles: _getPreambles,
useJsMethodNamesOnAbsence: true,
jsNameConverter: _convertName,
forcedTmpDir: data.outDir);
return pass(data);
}
Future<bool> _compile(String input, String output) async {
var outWrapperPath = _getWrapperPathFromDirectoryFile(input);
ddcRunner.runDDC(getDdcDir().path, input, output, outWrapperPath);
return true;
}
List<String> _getPreambles(input, output) {
return ['--module', _getWrapperPathFromDirectoryFile(input), '--'];
}
String _getWrapperPathFromDirectoryFile(input) {
return new File.fromUri(new File(input).uri.resolve("wrapper.js")).path;
}
String _convertName(String name) {
if (name == null) return null;
// Hack for DDC naming scheme.
String result = name;
if (result.startsWith("new ")) result = result.substring(4);
if (result.startsWith("Object.")) result = result.substring(7);
String inputName =
INPUT_FILE_NAME.substring(0, INPUT_FILE_NAME.indexOf(".") + 1);
if (result.startsWith(inputName))
result = result.substring(inputName.length);
return result;
}
}
Directory _cachedDdcDir;
Directory getDdcDir() {
Directory search() {
Directory dir = new File.fromUri(Platform.script).parent;
Uri dirUrl = dir.uri;
if (dirUrl.pathSegments.contains("dev_compiler")) {
for (int i = dirUrl.pathSegments.length - 2; i >= 0; --i) {
// Directory uri ends in empty string
if (dirUrl.pathSegments[i] == "dev_compiler") break;
dir = dir.parent;
}
return dir;
}
throw "Cannot find DDC directory.";
}
return _cachedDdcDir ??= search();
}
String getWrapperContent(Uri jsSdkPath, String inputFileName, Uri outputFile) {
assert(!jsSdkPath.isAbsolute);
assert(!outputFile.isAbsolute);
return """
import { dart, _isolate_helper } from '$jsSdkPath';
import { $inputFileName } from '$outputFile';
let main = $inputFileName.main;
dart.ignoreWhitelistedErrors(false);
try {
_isolate_helper.startRootIsolate(main, []);
} catch(e) {
console.error(e.toString(), dart.stackTrace(e).toString());
}
""";
}
void createHtmlWrapper(String ddcDir, File sdkJsFile, String outputFile,
String jsContent, Uri outFileRelative, String outDir) {
// For debugging via HTML, Chrome and ./tools/testing/dart/http_server.dart.
String sdkPath = new File(ddcDir).parent.parent.path;
String jsRootDart =
"/root_dart/${new File(path.relative(sdkJsFile.path, from: sdkPath))
.uri}";
new File(outputFile + ".html.js").writeAsStringSync(
jsContent.replaceFirst("from 'dart_sdk'", "from '$jsRootDart'"));
new File(outputFile + ".html.html").writeAsStringSync(getWrapperHtmlContent(
jsRootDart, "/root_build/$outFileRelative.html.js"));
print("You should now be able to run\n\n"
"dart $sdkPath/tools/testing/dart/http_server.dart -p 39550 "
"--network 127.0.0.1"
"--build-directory=$outDir"
"\n\nand go to\n\n"
"http://127.0.0.1:39550/root_build/$outFileRelative.html.html"
"\n\nto step through via the browser.");
}
String getWrapperHtmlContent(String jsRootDart, String outFileRootBuild) {
return """
<!DOCTYPE html>
<html>
<head>
<title>ddc test</title>
<script type="module">
import { dart, _isolate_helper } from '$jsRootDart';
import { test } from '$outFileRootBuild';
let main = test.main;
dart.ignoreWhitelistedErrors(false);
_isolate_helper.startRootIsolate(() => {}, []);
main();
</script>
</head>
<body>
<h1>ddc test</h1>
</body>
</html>
""";
}