| Index: pkg/polymer/lib/testing/content_shell_test.dart
|
| diff --git a/pkg/polymer/lib/testing/content_shell_test.dart b/pkg/polymer/lib/testing/content_shell_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..97398be49fa5228a7ad7097753d86221d23c5b17
|
| --- /dev/null
|
| +++ b/pkg/polymer/lib/testing/content_shell_test.dart
|
| @@ -0,0 +1,229 @@
|
| +// 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.
|
| +
|
| +/**
|
| + * Helper library to run tests in content_shell
|
| + */
|
| +library polymer.testing.end2end;
|
| +
|
| +import 'dart:io';
|
| +import 'package:args/args.dart';
|
| +import 'package:path/path.dart' as path;
|
| +import 'package:unittest/unittest.dart';
|
| +import 'package:polymer/dwc.dart' as dwc;
|
| +
|
| +
|
| +/**
|
| + * Compiles [testFile] with the web-ui compiler, and then runs the output as a
|
| + * unit test in content_shell.
|
| + */
|
| +void endToEndTests(String inputDir, String outDir, {List<String> arguments}) {
|
| + _testHelper(new _TestOptions(inputDir, inputDir, null, outDir,
|
| + arguments: arguments));
|
| +}
|
| +
|
| +/**
|
| + * Compiles [testFile] with the web-ui compiler, and then runs the output as a
|
| + * render test in content_shell.
|
| + */
|
| +void renderTests(String baseDir, String inputDir, String expectedDir,
|
| + String outDir, {List<String> arguments, String script, String pattern,
|
| + bool deleteDir: true}) {
|
| + _testHelper(new _TestOptions(baseDir, inputDir, expectedDir, outDir,
|
| + arguments: arguments, script: script, pattern: pattern,
|
| + deleteDir: deleteDir));
|
| +}
|
| +
|
| +void _testHelper(_TestOptions options) {
|
| + expect(options, isNotNull);
|
| +
|
| + var paths = new Directory(options.inputDir).listSync()
|
| + .where((f) => f is File).map((f) => f.path)
|
| + .where((p) => p.endsWith('_test.html') && options.pattern.hasMatch(p));
|
| +
|
| + if (paths.isEmpty) return;
|
| +
|
| + // First clear the output folder. Otherwise we can miss bugs when we fail to
|
| + // generate a file.
|
| + var dir = new Directory(options.outDir);
|
| + if (dir.existsSync() && options.deleteDir) {
|
| + print('Cleaning old output for ${path.normalize(options.outDir)}');
|
| + dir.deleteSync(recursive: true);
|
| + }
|
| + dir.createSync();
|
| +
|
| + for (var filePath in paths) {
|
| + var filename = path.basename(filePath);
|
| + test('compile $filename', () {
|
| + var testArgs = ['-o', options.outDir, '--basedir', options.baseDir,
|
| + '--deploy']
|
| + ..addAll(options.compilerArgs)
|
| + ..add(filePath);
|
| + expect(dwc.run(testArgs, printTime: false).then((res) {
|
| + expect(res.messages.length, 0, reason: res.messages.join('\n'));
|
| + }), completes);
|
| + });
|
| + }
|
| +
|
| + var filenames = paths.map(path.basename).toList();
|
| + // Sort files to match the order in which run.sh runs diff.
|
| + filenames.sort();
|
| +
|
| + // Get the path from "input" relative to "baseDir"
|
| + var relativeToBase = path.relative(options.inputDir, from: options.baseDir);
|
| + var finalOutDir = path.join(options.outDir, relativeToBase);
|
| +
|
| + runTests(String search) {
|
| + var output;
|
| +
|
| + for (var filename in filenames) {
|
| + test('content_shell run $filename$search', () {
|
| + var args = ['--dump-render-tree',
|
| + 'file://$finalOutDir/$filename$search'];
|
| + var env = {'DART_FLAGS': '--checked'};
|
| + expect(Process.run('content_shell', args, environment: env).then((res) {
|
| + expect(res.exitCode, 0, reason: 'content_shell exit code: '
|
| + '${res.exitCode}. Contents of stderr: \n${res.stderr}');
|
| + var outs = res.stdout.split('#EOF\n')
|
| + .where((s) => !s.trim().isEmpty).toList();
|
| + expect(outs.length, 1);
|
| + output = outs.first;
|
| + }), completes);
|
| + });
|
| +
|
| + test('verify $filename $search', () {
|
| + expect(output, isNotNull, reason:
|
| + 'Output not available, maybe content_shell failed to run.');
|
| + var outPath = path.join(options.outDir, '$filename.txt');
|
| + new File(outPath).writeAsStringSync(output);
|
| + if (options.isRenderTest) {
|
| + var expectedPath = path.join(options.expectedDir, '$filename.txt');
|
| + var expected = new File(expectedPath).readAsStringSync();
|
| + expect(output, expected, reason: 'unexpected output for <$filename>');
|
| + } else {
|
| + bool passes = matches(
|
| + new RegExp('All .* tests passed')).matches(output, {});
|
| + expect(passes, true, reason: 'unit test failed:\n$output');
|
| + }
|
| + });
|
| + }
|
| + }
|
| +
|
| + bool compiled = false;
|
| + ensureCompileToJs() {
|
| + if (compiled) return;
|
| + compiled = true;
|
| +
|
| + for (var filename in filenames) {
|
| + test('dart2js $filename', () {
|
| + // TODO(jmesserly): this depends on DWC's output scheme.
|
| + // Alternatively we could use html5lib to find the script tag.
|
| + var inPath = '${filename}_bootstrap.dart';
|
| + var outPath = '${inPath}.js';
|
| +
|
| + inPath = path.join(finalOutDir, inPath);
|
| + outPath = path.join(finalOutDir, outPath);
|
| +
|
| + expect(Process.run('dart2js', ['-o$outPath', inPath]).then((res) {
|
| + expect(res.exitCode, 0, reason: 'dart2js exit code: '
|
| + '${res.exitCode}. Contents of stderr: \n${res.stderr}. '
|
| + 'Contents of stdout: \n${res.stdout}.');
|
| + expect(new File(outPath).existsSync(), true, reason: 'input file '
|
| + '$inPath should have been compiled to $outPath.');
|
| + }), completes);
|
| + });
|
| + }
|
| + }
|
| +
|
| + if (options.runAsDart) {
|
| + runTests('');
|
| + }
|
| + if (options.runAsJs) {
|
| + ensureCompileToJs();
|
| + runTests('?js=1');
|
| + }
|
| + if (options.forcePolyfillShadowDom) {
|
| + ensureCompileToJs();
|
| + runTests('?js=1&shadowdomjs=1');
|
| + }
|
| +}
|
| +
|
| +class _TestOptions {
|
| + final String baseDir;
|
| + final String inputDir;
|
| +
|
| + final String expectedDir;
|
| + bool get isRenderTest => expectedDir != null;
|
| +
|
| + final String outDir;
|
| + final bool deleteDir;
|
| +
|
| + final bool runAsDart;
|
| + final bool runAsJs;
|
| + final bool forcePolyfillShadowDom;
|
| +
|
| + final List<String> compilerArgs;
|
| + final RegExp pattern;
|
| +
|
| + factory _TestOptions(String baseDir, String inputDir, String expectedDir,
|
| + String outDir, {List<String> arguments, String script, String pattern,
|
| + bool deleteDir: true}) {
|
| + if (arguments == null) arguments = new Options().arguments;
|
| + if (script == null) script = new Options().script;
|
| +
|
| + var args = _parseArgs(arguments, script);
|
| + if (args == null) return null;
|
| + var compilerArgs = args.rest;
|
| + var filePattern;
|
| + if (pattern != null) {
|
| + filePattern = new RegExp(pattern);
|
| + } else if (compilerArgs.length > 0) {
|
| + filePattern = new RegExp(compilerArgs[0]);
|
| + compilerArgs = compilerArgs.sublist(1);
|
| + } else {
|
| + filePattern = new RegExp('.');
|
| + }
|
| +
|
| + var scriptDir = path.absolute(path.dirname(script));
|
| + baseDir = path.join(scriptDir, baseDir);
|
| + inputDir = path.join(scriptDir, inputDir);
|
| + outDir = path.join(scriptDir, outDir);
|
| + if (expectedDir != null) {
|
| + expectedDir = path.join(scriptDir, expectedDir);
|
| + }
|
| +
|
| + return new _TestOptions._(baseDir, inputDir, expectedDir, outDir, deleteDir,
|
| + args['dart'] == true, args['js'] == true, args['shadowdom'] == true,
|
| + compilerArgs, filePattern);
|
| + }
|
| +
|
| + _TestOptions._(this.baseDir, this.inputDir, this.expectedDir, this.outDir,
|
| + this.deleteDir, this.runAsDart, this.runAsJs,
|
| + this.forcePolyfillShadowDom, this.compilerArgs, this.pattern);
|
| +}
|
| +
|
| +ArgResults _parseArgs(List<String> arguments, String script) {
|
| + var parser = new ArgParser()
|
| + ..addFlag('dart', abbr: 'd', help: 'run on Dart VM', defaultsTo: true)
|
| + ..addFlag('js', abbr: 'j', help: 'run compiled dart2js', defaultsTo: true)
|
| + ..addFlag('shadowdom', abbr: 's',
|
| + help: 'run dart2js and polyfilled ShadowDOM', defaultsTo: true)
|
| + ..addFlag('help', abbr: 'h', help: 'Displays this help message',
|
| + defaultsTo: false, negatable: false);
|
| +
|
| + showUsage() {
|
| + print('Usage: $script [options...] [test_name_regexp]');
|
| + print(parser.getUsage());
|
| + return null;
|
| + }
|
| +
|
| + try {
|
| + var results = parser.parse(arguments);
|
| + if (results['help']) return showUsage();
|
| + return results;
|
| + } on FormatException catch (e) {
|
| + print(e.message);
|
| + return showUsage();
|
| + }
|
| +}
|
|
|