blob: 60dd8b9889f76e4930e3504b1541118f8887f9b1 [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.
// Helpers for writing compiler tests running in browser.
library trydart.web_compiler_test_case;
import 'dart:async' show
EventSink,
Future;
import 'dart:html' show
HttpRequest;
import '../poi/compiler_test_case.dart' show
customUri,
CompilerTestCase;
import 'package:dart2js_incremental/dart2js_incremental.dart' show
IncrementalCompiler;
import 'package:compiler/compiler.dart' show
Diagnostic;
const String WEB_SCHEME = 'org.trydart.web';
/// A CompilerTestCase which runs in a browser.
class WebCompilerTestCase extends CompilerTestCase {
final IncrementalCompiler incrementalCompiler;
WebCompilerTestCase.init(String source, Uri uri)
: this.incrementalCompiler = makeCompiler(source, uri),
super.init(source, uri, null);
WebCompilerTestCase(String source, [String path])
: this.init(source, customUri(path == null ? 'main.dart' : path));
Future run() {
return incrementalCompiler.compile(scriptUri).then((success) {
if (!success) throw 'Compilation failed';
OutputProvider outputProvider = incrementalCompiler.outputProvider;
return outputProvider['.js'];
});
}
static IncrementalCompiler makeCompiler(String source, Uri mainUri) {
Uri libraryRoot = new Uri(scheme: WEB_SCHEME, path: '/sdk/');
Uri packageRoot = new Uri(scheme: WEB_SCHEME, path: '/packages/');
WebInputProvider inputProvider =
new WebInputProvider(source, mainUri, libraryRoot, packageRoot);
void diagnosticHandler(
Uri uri, int begin, int end, String message, Diagnostic kind) {
if (uri == null) {
print('[$kind] $message');
} else {
print('$uri@$begin+${end - begin}: [$kind] $message');
}
}
return new IncrementalCompiler(
libraryRoot: libraryRoot,
packageRoot: packageRoot,
inputProvider: inputProvider,
diagnosticHandler: diagnosticHandler,
outputProvider: new OutputProvider());
}
}
/// An input provider which provides input via [HttpRequest].
/// Includes one in-memory compilation unit [source] which is returned when
/// [mainUri] is requested.
class WebInputProvider {
final String source;
final Uri mainUri;
final Uri libraryRoot;
final Uri packageRoot;
final Map<Uri, Future> cachedSources = new Map<Uri, Future>();
WebInputProvider(
this.source, this.mainUri, this.libraryRoot, this.packageRoot);
Future call(Uri uri) {
return cachedSources.putIfAbsent(uri, () {
if (uri == mainUri) return new Future.value(source);
if (uri.scheme == WEB_SCHEME) {
return HttpRequest.getString('/root_dart${uri.path}');
} else {
return HttpRequest.getString('$uri');
}
});
}
}
/// Output provider which collect output in [output].
class OutputProvider {
final Map<String, String> output = new Map<String, String>();
EventSink<String> call(String name, String extension) {
return new StringEventSink((String data) {
output['$name.$extension'] = data;
});
}
String operator[] (String key) => output[key];
}
/// Helper class to collect sources.
class StringEventSink implements EventSink<String> {
List<String> data = <String>[];
final Function onClose;
StringEventSink(this.onClose);
void add(String event) {
if (data == null) throw 'StringEventSink is closed.';
data.add(event);
}
void addError(errorEvent, [StackTrace stackTrace]) {
throw 'addError($errorEvent, $stackTrace)';
}
void close() {
if (data != null) {
onClose(data.join());
data = null;
}
}
}