fixed TodoMVC tests to include deploying to JS

R=kustermann@google.com, sigmund@google.com

Review URL: https://codereview.chromium.org//23678009

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27222 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
jmesserly@google.com
2013-09-05 23:00:41 +00:00
parent 77a766e06b
commit 337880c0d4
6 changed files with 150 additions and 56 deletions
+67 -28
View File
@@ -33,12 +33,47 @@ import 'package:args/args.dart';
main() {
var args = _parseArgs(new Options().arguments);
if (args == null) return;
var test = args['test'];
if (test != null) {
_initForTest(test);
}
print('polymer/deploy.dart: creating a deploy target for "$_currentPackage"');
var outDir = args['out'];
_run(args['webdir'], outDir).then(
_run(outDir, test != null).then(
(_) => print('Done! All files written to "$outDir"'));
}
// TODO(jmesserly): the current deploy/barback architecture is very unfriendly
// to deploying a single test. We need to fix it somehow but it isn't clear yet.
void _initForTest(String testFile) {
var testDir = path.normalize(path.dirname(testFile));
// A test must be allowed to import things in the package.
// So we must find its package root, given the entry point. We can do this
// by walking up to find pubspec.yaml.
var pubspecDir = _findDirWithFile(path.absolute(testDir), 'pubspec.yaml');
if (pubspecDir == null) {
print('error: pubspec.yaml file not found, please run this script from '
'your package root directory or a subdirectory.');
exit(1);
}
_currentPackage = '_test';
_packageDirs = {'_test' : pubspecDir};
}
String _findDirWithFile(String dir, String filename) {
while (!new File(path.join(dir, filename)).existsSync()) {
var parentDir = path.dirname(dir);
// If we reached root and failed to find it, bail.
if (parentDir == dir) return null;
dir = parentDir;
}
return dir;
}
/**
* API exposed for testing purposes. Runs this deploy command but prentend that
* the sources under [webDir] belong to package 'test'.
@@ -48,46 +83,49 @@ Future runForTest(String webDir, String outDir) {
// associate package dirs with their location in the repo:
_packageDirs = {'test' : '.'};
addPackages(String dir) {
for (var packageDir in new Directory(dir).listSync().map((d) => d.path)) {
_packageDirs[path.basename(packageDir)] = packageDir;
}
}
addPackages('..');
addPackages('../third_party');
addPackages('../../third_party/pkg');
_addPackages('..');
_addPackages('../third_party');
_addPackages('../../third_party/pkg');
return _run(webDir, outDir);
}
Future _run(String webDir, String outDir) {
_addPackages(String dir) {
for (var packageDir in new Directory(dir).listSync().map((d) => d.path)) {
_packageDirs[path.basename(packageDir)] = packageDir;
}
}
Future _run(String outDir, bool includeTests) {
var barback = new Barback(new _PolymerDeployProvider());
_initializeBarback(barback, webDir);
_initializeBarback(barback, includeTests);
_attachListeners(barback);
return _emitAllFiles(barback, webDir, outDir);
return _emitAllFiles(barback, 'web', outDir).then(
(_) => includeTests ? _emitAllFiles(barback, 'test', outDir) : null);
}
/** Tell barback which transformers to use and which assets to process. */
void _initializeBarback(Barback barback, String webDir) {
void _initializeBarback(Barback barback, bool includeTests) {
var assets = [];
void addAssets(String package, String subDir) {
for (var filepath in _listDir(package, subDir)) {
assets.add(new AssetId(package, filepath));
}
}
for (var package in _packageDirs.keys) {
// Do not process packages like 'polymer' where there is nothing to do.
if (_ignoredPackages.contains(package)) continue;
barback.updateTransformers(package, phases);
// notify barback to process anything under 'lib' and 'asset'
for (var filepath in _listDir(package, 'lib')) {
assets.add(new AssetId(package, filepath));
}
for (var filepath in _listDir(package, 'asset')) {
assets.add(new AssetId(package, filepath));
}
addAssets(package, 'lib');
addAssets(package, 'asset');
}
// In case of the current package, include also 'web'.
for (var filepath in _listDir(_currentPackage, webDir)) {
assets.add(new AssetId(_currentPackage, filepath));
}
addAssets(_currentPackage, 'web');
if (includeTests) addAssets(_currentPackage, 'test');
barback.updateSources(assets);
}
@@ -235,12 +273,13 @@ final Set<String> _ignoredPackages =
ArgResults _parseArgs(arguments) {
var parser = new ArgParser()
..addFlag('help', abbr: 'h', help: 'Displays this help message',
..addFlag('help', abbr: 'h', help: 'Displays this help message.',
defaultsTo: false, negatable: false)
..addOption('webdir', help: 'Directory containing the application',
defaultsTo: 'web')
..addOption('out', abbr: 'o', help: 'Directory where to generated files',
defaultsTo: 'out');
..addOption('out', abbr: 'o', help: 'Directory where to generated files.',
defaultsTo: 'out')
..addOption('test', help: 'Deploy the test at the given path.\n'
'Note: currently this will deploy all tests in its directory,\n'
'but it will eventually deploy only the specified test.');
try {
var results = parser.parse(arguments);
if (results['help']) {
@@ -30,6 +30,7 @@ class PolyfillInjector extends Transformer {
return readPrimaryAsHtml(transform).then((document) {
bool shadowDomFound = false;
bool jsInteropFound = false;
bool pkgJsInteropFound = false;
bool dartScriptTags = false;
for (var tag in document.queryAll('script')) {
@@ -38,6 +39,8 @@ class PolyfillInjector extends Transformer {
var last = src.split('/').last;
if (last == 'interop.js') {
jsInteropFound = true;
} else if (last == 'dart_interop.js') {
pkgJsInteropFound = true;
} else if (_shadowDomJS.hasMatch(last)) {
shadowDomFound = true;
}
@@ -54,6 +57,12 @@ class PolyfillInjector extends Transformer {
return;
}
if (!pkgJsInteropFound) {
// JS interop code is required for Polymer CSS shimming.
document.body.nodes.insert(0, parseFragment(
'<script src="packages/js/dart_interop.js"></script>\n'));
}
if (!jsInteropFound) {
// JS interop code is required for Polymer CSS shimming.
document.body.nodes.insert(0, parseFragment(
@@ -63,8 +72,9 @@ class PolyfillInjector extends Transformer {
if (!shadowDomFound) {
// Insert at the beginning (this polyfill needs to run as early as
// possible).
// TODO(jmesserly): this is .debug to workaround issue 13046.
document.body.nodes.insert(0, parseFragment(
'<script src="packages/shadow_dom/shadow_dom.min.js"></script>\n'));
'<script src="packages/shadow_dom/shadow_dom.debug.js"></script>\n'));
}
transform.addOutput(
@@ -36,6 +36,7 @@ void main() {
'<!DOCTYPE html><html><head></head><body>'
'$SHADOW_DOM_TAG'
'$INTEROP_TAG'
'$PKG_JS_INTEROP_TAG'
'<script type="application/dart" '
'src="test.html_bootstrap.dart"></script>'
'<script src="packages/browser/dart.js"></script>'
@@ -68,6 +69,7 @@ void main() {
'<!DOCTYPE html><html><head></head><body>'
'$SHADOW_DOM_TAG'
'$INTEROP_TAG'
'$PKG_JS_INTEROP_TAG'
'<script type="application/dart" '
'src="test.html_bootstrap.dart"></script>'
'<script src="packages/browser/dart.js"></script>'
@@ -107,6 +109,7 @@ void main() {
'<!DOCTYPE html><html><head></head><body>'
'$SHADOW_DOM_TAG'
'$INTEROP_TAG'
'$PKG_JS_INTEROP_TAG'
'<div></div>'
'<script type="application/dart" '
'src="test.html_bootstrap.dart"></script>'
@@ -158,6 +161,7 @@ void main() {
'<!DOCTYPE html><html><head></head><body>'
'$SHADOW_DOM_TAG'
'$INTEROP_TAG'
'$PKG_JS_INTEROP_TAG'
'<polymer-element>1</polymer-element>'
'<script type="application/dart" '
'src="index.html_bootstrap.dart"></script>'
@@ -207,7 +211,7 @@ class $className extends ChangeNotifierBase {
set $fieldName(int value) {
__\$$fieldName = notifyPropertyChange(const Symbol('$fieldName'), __\$$fieldName, value);
}
$className($fieldName) : __\$$fieldName = $fieldName;
}
''';
+6 -2
View File
@@ -23,7 +23,7 @@ AssetId idFromString(String s) {
class TestHelper implements PackageProvider {
/**
* Maps from an asset string identifier of the form 'package|path' to the
* file contents.
* file contents.
*/
final Map<String, String> files;
final Iterable<String> packages;
@@ -95,7 +95,11 @@ testPhases(String testName, List<List<Transformer>> phases,
});
}
// TODO(jmesserly): this is .debug to workaround issue 13046.
const SHADOW_DOM_TAG =
'<script src="packages/shadow_dom/shadow_dom.min.js"></script>\n';
'<script src="packages/shadow_dom/shadow_dom.debug.js"></script>\n';
const INTEROP_TAG = '<script src="packages/browser/interop.js"></script>\n';
const PKG_JS_INTEROP_TAG =
'<script src="packages/js/dart_interop.js"></script>\n';
@@ -35,7 +35,7 @@ void main() {
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'$SHADOW_DOM_TAG$INTEROP_TAG'
'$SHADOW_DOM_TAG$INTEROP_TAG$PKG_JS_INTEROP_TAG'
'<script type="application/dart" src="a.dart"></script>'
'</body></html>',
});
@@ -45,12 +45,15 @@ void main() {
'<!DOCTYPE html><html><head></head><body>'
'<script type="application/dart" src="a.dart"></script>'
'$SHADOW_DOM_TAG'
'$INTEROP_TAG',
'$INTEROP_TAG'
'$PKG_JS_INTEROP_TAG',
}, {
'a|web/test.html':
'<!DOCTYPE html><html><head></head><body>'
'<script type="application/dart" src="a.dart"></script>'
'$SHADOW_DOM_TAG'
'$INTEROP_TAG</body></html>',
'$INTEROP_TAG'
'$PKG_JS_INTEROP_TAG'
'</body></html>',
});
}
+55 -21
View File
@@ -969,33 +969,56 @@ class StandardTestSuite extends TestSuite {
String dartWrapperFilename = '$tempDir/test.dart';
String compiledDartWrapperFilename = '$tempDir/test.js';
String htmlPath = '$tempDir/test.html';
if (isWrappingRequired && !isWebTest) {
// test.dart will import the dart test.
_createWrapperFile(dartWrapperFilename, filePath);
} else {
dartWrapperFilename = filename;
}
String scriptPath = (compiler == 'none') ?
dartWrapperFilename : compiledDartWrapperFilename;
scriptPath = _createUrlPathFromFile(new Path(scriptPath));
// Create the HTML file for the test.
RandomAccessFile htmlTest =
new File(htmlPath).openSync(mode: FileMode.WRITE);
String content = null;
Path dir = filePath.directoryPath;
String nameNoExt = filePath.filenameWithoutExtension;
Path pngPath = dir.append('$nameNoExt.png');
Path txtPath = dir.append('$nameNoExt.txt');
Path customHtmlPath = dir.append('$nameNoExt.html');
String customHtmlPath = dir.append('$nameNoExt.html').toNativePath();
File customHtml = new File(customHtmlPath);
Path expectedOutput = null;
if (new File(customHtmlPath.toNativePath()).existsSync()) {
// Use existing HTML document if available.
htmlPath = customHtmlPath.toNativePath();
// Construct the command(s) that compile all the inputs needed by the
// browser test. For running Dart in DRT, this will be noop commands.
List<Command> commands = [];
// Use existing HTML document if available.
String htmlPath;
if (customHtml.existsSync()) {
// If necessary, run the Polymer deploy steps.
// TODO(jmesserly): this should be generalized for any tests that
// require Pub deploy, not just polymer.
if (compiler != 'none' &&
customHtml.readAsStringSync().contains('polymer/boot.js')) {
commands.add(_polymerDeployCommand(
customHtmlPath, tempDir, optionsFromFile));
htmlPath = '$tempDir/test/$nameNoExt.html';
dartWrapperFilename = '${htmlPath}_bootstrap.dart';
compiledDartWrapperFilename = '$dartWrapperFilename.js';
} else {
htmlPath = customHtmlPath;
}
} else {
htmlPath = '$tempDir/test.html';
if (isWrappingRequired && !isWebTest) {
// test.dart will import the dart test.
_createWrapperFile(dartWrapperFilename, filePath);
} else {
dartWrapperFilename = filename;
}
// Create the HTML file for the test.
RandomAccessFile htmlTest =
new File(htmlPath).openSync(mode: FileMode.WRITE);
String scriptPath = (compiler == 'none') ?
dartWrapperFilename : compiledDartWrapperFilename;
scriptPath = _createUrlPathFromFile(new Path(scriptPath));
if (new File(pngPath.toNativePath()).existsSync()) {
expectedOutput = pngPath;
content = getHtmlLayoutContents(scriptType, new Path("$scriptPath"));
@@ -1010,9 +1033,6 @@ class StandardTestSuite extends TestSuite {
htmlTest.closeSync();
}
// Construct the command(s) that compile all the inputs needed by the
// browser test. For running Dart in DRT, this will be noop commands.
List<Command> commands = [];
if (compiler != 'none') {
commands.add(_compileCommand(
dartWrapperFilename, compiledDartWrapperFilename,
@@ -1152,6 +1172,20 @@ class StandardTestSuite extends TestSuite {
dart2JsBootstrapDependencies, compilerPath, args, configurationDir);
}
/** Helper to create a Polymer deploy command for a single HTML file. */
Command _polymerDeployCommand(String inputFile, String outputDir,
optionsFromFile) {
List<String> args = [];
String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
if (packageRoot != null) args.add(packageRoot);
args..add('package:polymer/deploy.dart')
..add('--test')..add(inputFile)
..add('--out')..add(outputDir);
return CommandBuilder.instance.getCommand(
'polymer_deploy', vmFileName, args, configurationDir);
}
/**
* Create a directory for the generated test. If a Dart language test
* needs to be run in a browser, the Dart test needs to be embedded in