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