| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Helper library to run tests in content_shell | 6 * Helper library to run tests in content_shell |
| 7 */ | 7 */ |
| 8 library polymer.testing.end2end; | 8 library polymer.testing.end2end; |
| 9 | 9 |
| 10 import 'dart:io'; | 10 import 'dart:io'; |
| 11 import 'package:args/args.dart'; | 11 import 'package:args/args.dart'; |
| 12 import 'package:path/path.dart' as path; | 12 import 'package:path/path.dart' as path; |
| 13 import 'package:unittest/unittest.dart'; | 13 import 'package:unittest/unittest.dart'; |
| 14 import 'package:polymer/dwc.dart' as dwc; | 14 import 'package:polymer/deploy.dart' as deploy; |
| 15 | 15 |
| 16 | 16 |
| 17 /** | 17 /** |
| 18 * Compiles [testFile] with the web-ui compiler, and then runs the output as a | 18 * Compiles [testFile] with the web-ui compiler, and then runs the output as a |
| 19 * unit test in content_shell. | 19 * unit test in content_shell. |
| 20 */ | 20 */ |
| 21 void endToEndTests(String inputDir, String outDir, {List<String> arguments}) { | 21 void endToEndTests(String inputDir, String outDir, {List<String> arguments}) { |
| 22 _testHelper(new _TestOptions(inputDir, inputDir, null, outDir, | 22 _testHelper(new _TestOptions(inputDir, inputDir, null, outDir, |
| 23 arguments: arguments)); | 23 arguments: arguments)); |
| 24 } | 24 } |
| 25 | 25 |
| 26 /** | 26 /** |
| 27 * Compiles [testFile] with the web-ui compiler, and then runs the output as a | 27 * Compiles [testFile] with the web-ui compiler, and then runs the output as a |
| 28 * render test in content_shell. | 28 * render test in content_shell. |
| 29 */ | 29 */ |
| 30 void renderTests(String baseDir, String inputDir, String expectedDir, | 30 void renderTests(String webDir, String inputDir, String expectedDir, |
| 31 String outDir, {List<String> arguments, String script, String pattern, | 31 String outDir, {List<String> arguments, String script, String pattern, |
| 32 bool deleteDir: true}) { | 32 bool deleteDir: true}) { |
| 33 _testHelper(new _TestOptions(baseDir, inputDir, expectedDir, outDir, | 33 _testHelper(new _TestOptions(webDir, inputDir, expectedDir, outDir, |
| 34 arguments: arguments, script: script, pattern: pattern, | 34 arguments: arguments, script: script, pattern: pattern, |
| 35 deleteDir: deleteDir)); | 35 deleteDir: deleteDir)); |
| 36 } | 36 } |
| 37 | 37 |
| 38 void _testHelper(_TestOptions options) { | 38 void _testHelper(_TestOptions options) { |
| 39 expect(options, isNotNull); | 39 expect(options, isNotNull); |
| 40 | 40 |
| 41 var paths = new Directory(options.inputDir).listSync() | 41 var paths = new Directory(options.inputDir).listSync() |
| 42 .where((f) => f is File).map((f) => f.path) | 42 .where((f) => f is File).map((f) => f.path) |
| 43 .where((p) => p.endsWith('_test.html') && options.pattern.hasMatch(p)); | 43 .where((p) => p.endsWith('_test.html') && options.pattern.hasMatch(p)); |
| 44 | 44 |
| 45 if (paths.isEmpty) return; | 45 if (paths.isEmpty) return; |
| 46 | 46 |
| 47 // First clear the output folder. Otherwise we can miss bugs when we fail to | 47 // First clear the output folder. Otherwise we can miss bugs when we fail to |
| 48 // generate a file. | 48 // generate a file. |
| 49 var dir = new Directory(options.outDir); | 49 var dir = new Directory(options.outDir); |
| 50 if (dir.existsSync() && options.deleteDir) { | 50 if (dir.existsSync() && options.deleteDir) { |
| 51 print('Cleaning old output for ${path.normalize(options.outDir)}'); | 51 print('Cleaning old output for ${path.normalize(options.outDir)}'); |
| 52 dir.deleteSync(recursive: true); | 52 dir.deleteSync(recursive: true); |
| 53 } | 53 } |
| 54 dir.createSync(); | 54 dir.createSync(recursive: true); |
| 55 | 55 |
| 56 for (var filePath in paths) { | 56 for (var filePath in paths) { |
| 57 var filename = path.basename(filePath); | 57 var filename = path.basename(filePath); |
| 58 test('compile $filename', () { | 58 test('compile $filename', () { |
| 59 var testArgs = ['-o', options.outDir, '--basedir', options.baseDir, | 59 return deploy.runForTest(options.webDir, options.outDir); |
| 60 '--deploy'] | |
| 61 ..addAll(options.compilerArgs) | |
| 62 ..add(filePath); | |
| 63 expect(dwc.run(testArgs, printTime: false).then((res) { | |
| 64 expect(res.messages.length, 0, reason: res.messages.join('\n')); | |
| 65 }), completes); | |
| 66 }); | 60 }); |
| 67 } | 61 } |
| 68 | 62 |
| 69 var filenames = paths.map(path.basename).toList(); | 63 var filenames = paths.map(path.basename).toList(); |
| 70 // Sort files to match the order in which run.sh runs diff. | 64 // Sort files to match the order in which run.sh runs diff. |
| 71 filenames.sort(); | 65 filenames.sort(); |
| 72 | 66 |
| 73 // Get the path from "input" relative to "baseDir" | 67 var finalOutDir = path.join(options.outDir, options.inputDir); |
| 74 var relativeToBase = path.relative(options.inputDir, from: options.baseDir); | 68 var outBaseDir = path.join(options.outDir, options.webDir); |
| 75 var finalOutDir = path.join(options.outDir, relativeToBase); | |
| 76 | 69 |
| 77 runTests(String search) { | 70 runTests(String search) { |
| 78 var output; | 71 var output; |
| 79 | 72 |
| 80 for (var filename in filenames) { | 73 for (var filename in filenames) { |
| 81 test('content_shell run $filename$search', () { | 74 test('content_shell run $filename$search', () { |
| 82 var args = ['--dump-render-tree', | 75 var lnArgs = ['-s', '$outBaseDir/packages', '$finalOutDir/packages']; |
| 83 'file://$finalOutDir/$filename$search']; | 76 return Process.run('ln', lnArgs).then((_) { |
| 84 var env = {'DART_FLAGS': '--checked'}; | 77 var args = ['--dump-render-tree', |
| 85 expect(Process.run('content_shell', args, environment: env).then((res) { | 78 'file://$finalOutDir/$filename$search']; |
| 86 expect(res.exitCode, 0, reason: 'content_shell exit code: ' | 79 var env = {'DART_FLAGS': '--checked'}; |
| 87 '${res.exitCode}. Contents of stderr: \n${res.stderr}'); | 80 return Process.run('content_shell', args, environment: env) |
| 88 var outs = res.stdout.split('#EOF\n') | 81 .then((res) { |
| 89 .where((s) => !s.trim().isEmpty).toList(); | 82 expect(res.exitCode, 0, reason: 'content_shell exit code: ' |
| 90 expect(outs.length, 1); | 83 '${res.exitCode}. Contents of stderr: \n${res.stderr}'); |
| 91 output = outs.first; | 84 var outs = res.stdout.split('#EOF\n') |
| 92 }), completes); | 85 .where((s) => !s.trim().isEmpty).toList(); |
| 86 expect(outs.length, 1); |
| 87 output = outs.first; |
| 88 }); |
| 89 }); |
| 93 }); | 90 }); |
| 94 | 91 |
| 95 test('verify $filename $search', () { | 92 test('verify $filename $search', () { |
| 96 expect(output, isNotNull, reason: | 93 expect(output, isNotNull, reason: |
| 97 'Output not available, maybe content_shell failed to run.'); | 94 'Output not available, maybe content_shell failed to run.'); |
| 98 var outPath = path.join(options.outDir, '$filename.txt'); | 95 var outPath = path.join(options.outDir, '$filename.txt'); |
| 99 new File(outPath).writeAsStringSync(output); | 96 new File(outPath).writeAsStringSync(output); |
| 100 if (options.isRenderTest) { | 97 if (options.isRenderTest) { |
| 101 var expectedPath = path.join(options.expectedDir, '$filename.txt'); | 98 var expectedPath = path.join(options.expectedDir, '$filename.txt'); |
| 102 var expected = new File(expectedPath).readAsStringSync(); | 99 var expected = new File(expectedPath).readAsStringSync(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 ensureCompileToJs(); | 140 ensureCompileToJs(); |
| 144 runTests('?js=1'); | 141 runTests('?js=1'); |
| 145 } | 142 } |
| 146 if (options.forcePolyfillShadowDom) { | 143 if (options.forcePolyfillShadowDom) { |
| 147 ensureCompileToJs(); | 144 ensureCompileToJs(); |
| 148 runTests('?js=1&shadowdomjs=1'); | 145 runTests('?js=1&shadowdomjs=1'); |
| 149 } | 146 } |
| 150 } | 147 } |
| 151 | 148 |
| 152 class _TestOptions { | 149 class _TestOptions { |
| 153 final String baseDir; | 150 final String webDir; |
| 154 final String inputDir; | 151 final String inputDir; |
| 155 | 152 |
| 156 final String expectedDir; | 153 final String expectedDir; |
| 157 bool get isRenderTest => expectedDir != null; | 154 bool get isRenderTest => expectedDir != null; |
| 158 | 155 |
| 159 final String outDir; | 156 final String outDir; |
| 160 final bool deleteDir; | 157 final bool deleteDir; |
| 161 | 158 |
| 162 final bool runAsDart; | 159 final bool runAsDart; |
| 163 final bool runAsJs; | 160 final bool runAsJs; |
| 164 final bool forcePolyfillShadowDom; | 161 final bool forcePolyfillShadowDom; |
| 165 | 162 |
| 166 final List<String> compilerArgs; | 163 final List<String> compilerArgs; |
| 167 final RegExp pattern; | 164 final RegExp pattern; |
| 168 | 165 |
| 169 factory _TestOptions(String baseDir, String inputDir, String expectedDir, | 166 factory _TestOptions(String webDir, String inputDir, String expectedDir, |
| 170 String outDir, {List<String> arguments, String script, String pattern, | 167 String outDir, {List<String> arguments, String script, String pattern, |
| 171 bool deleteDir: true}) { | 168 bool deleteDir: true}) { |
| 172 if (arguments == null) arguments = new Options().arguments; | 169 if (arguments == null) arguments = new Options().arguments; |
| 173 if (script == null) script = new Options().script; | 170 if (script == null) script = new Options().script; |
| 174 | 171 |
| 175 var args = _parseArgs(arguments, script); | 172 var args = _parseArgs(arguments, script); |
| 176 if (args == null) return null; | 173 if (args == null) return null; |
| 177 var compilerArgs = args.rest; | 174 var compilerArgs = args.rest; |
| 178 var filePattern; | 175 var filePattern; |
| 179 if (pattern != null) { | 176 if (pattern != null) { |
| 180 filePattern = new RegExp(pattern); | 177 filePattern = new RegExp(pattern); |
| 181 } else if (compilerArgs.length > 0) { | 178 } else if (compilerArgs.length > 0) { |
| 182 filePattern = new RegExp(compilerArgs[0]); | 179 filePattern = new RegExp(compilerArgs[0]); |
| 183 compilerArgs = compilerArgs.sublist(1); | 180 compilerArgs = compilerArgs.sublist(1); |
| 184 } else { | 181 } else { |
| 185 filePattern = new RegExp('.'); | 182 filePattern = new RegExp('.'); |
| 186 } | 183 } |
| 187 | 184 |
| 188 var scriptDir = path.absolute(path.dirname(script)); | 185 var scriptDir = path.absolute(path.dirname(script)); |
| 189 baseDir = path.join(scriptDir, baseDir); | 186 webDir = path.relative(path.join(scriptDir, webDir)); |
| 190 inputDir = path.join(scriptDir, inputDir); | 187 inputDir = path.relative(path.join(scriptDir, inputDir)); |
| 191 outDir = path.join(scriptDir, outDir); | 188 outDir = path.join(scriptDir, outDir); |
| 192 if (expectedDir != null) { | 189 if (expectedDir != null) { |
| 193 expectedDir = path.join(scriptDir, expectedDir); | 190 expectedDir = path.join(scriptDir, expectedDir); |
| 194 } | 191 } |
| 195 | 192 |
| 196 return new _TestOptions._(baseDir, inputDir, expectedDir, outDir, deleteDir, | 193 return new _TestOptions._(webDir, inputDir, expectedDir, outDir, deleteDir, |
| 197 args['dart'] == true, args['js'] == true, args['shadowdom'] == true, | 194 args['dart'] == true, args['js'] == true, args['shadowdom'] == true, |
| 198 compilerArgs, filePattern); | 195 compilerArgs, filePattern); |
| 199 } | 196 } |
| 200 | 197 |
| 201 _TestOptions._(this.baseDir, this.inputDir, this.expectedDir, this.outDir, | 198 _TestOptions._(this.webDir, this.inputDir, this.expectedDir, this.outDir, |
| 202 this.deleteDir, this.runAsDart, this.runAsJs, | 199 this.deleteDir, this.runAsDart, this.runAsJs, |
| 203 this.forcePolyfillShadowDom, this.compilerArgs, this.pattern); | 200 this.forcePolyfillShadowDom, this.compilerArgs, this.pattern); |
| 204 } | 201 } |
| 205 | 202 |
| 206 ArgResults _parseArgs(List<String> arguments, String script) { | 203 ArgResults _parseArgs(List<String> arguments, String script) { |
| 207 var parser = new ArgParser() | 204 var parser = new ArgParser() |
| 208 ..addFlag('dart', abbr: 'd', help: 'run on Dart VM', defaultsTo: true) | 205 ..addFlag('dart', abbr: 'd', help: 'run on Dart VM', defaultsTo: true) |
| 209 ..addFlag('js', abbr: 'j', help: 'run compiled dart2js', defaultsTo: true) | 206 ..addFlag('js', abbr: 'j', help: 'run compiled dart2js', defaultsTo: true) |
| 210 ..addFlag('shadowdom', abbr: 's', | 207 ..addFlag('shadowdom', abbr: 's', |
| 211 help: 'run dart2js and polyfilled ShadowDOM', defaultsTo: true) | 208 help: 'run dart2js and polyfilled ShadowDOM', defaultsTo: true) |
| 212 ..addFlag('help', abbr: 'h', help: 'Displays this help message', | 209 ..addFlag('help', abbr: 'h', help: 'Displays this help message', |
| 213 defaultsTo: false, negatable: false); | 210 defaultsTo: false, negatable: false); |
| 214 | 211 |
| 215 showUsage() { | 212 showUsage() { |
| 216 print('Usage: $script [options...] [test_name_regexp]'); | 213 print('Usage: $script [options...] [test_name_regexp]'); |
| 217 print(parser.getUsage()); | 214 print(parser.getUsage()); |
| 218 return null; | 215 return null; |
| 219 } | 216 } |
| 220 | 217 |
| 221 try { | 218 try { |
| 222 var results = parser.parse(arguments); | 219 var results = parser.parse(arguments); |
| 223 if (results['help']) return showUsage(); | 220 if (results['help']) return showUsage(); |
| 224 return results; | 221 return results; |
| 225 } on FormatException catch (e) { | 222 } on FormatException catch (e) { |
| 226 print(e.message); | 223 print(e.message); |
| 227 return showUsage(); | 224 return showUsage(); |
| 228 } | 225 } |
| 229 } | 226 } |
| OLD | NEW |