| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library test.runner.configuration; | 5 library test.runner.configuration; |
| 6 | 6 |
| 7 import 'dart:io'; | 7 import 'dart:io'; |
| 8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'package:args/args.dart'; | 10 import 'package:args/args.dart'; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 'compact': 'A single line, updated continuously.', | 71 'compact': 'A single line, updated continuously.', |
| 72 'expanded': 'A separate line for each update.' | 72 'expanded': 'A separate line for each update.' |
| 73 }); | 73 }); |
| 74 parser.addFlag("verbose-trace", negatable: false, | 74 parser.addFlag("verbose-trace", negatable: false, |
| 75 help: 'Whether to emit stack traces with core library frames.'); | 75 help: 'Whether to emit stack traces with core library frames.'); |
| 76 parser.addFlag("js-trace", negatable: false, | 76 parser.addFlag("js-trace", negatable: false, |
| 77 help: 'Whether to emit raw JavaScript stack traces for browser tests.'); | 77 help: 'Whether to emit raw JavaScript stack traces for browser tests.'); |
| 78 parser.addFlag("color", defaultsTo: null, | 78 parser.addFlag("color", defaultsTo: null, |
| 79 help: 'Whether to use terminal colors.\n(auto-detected by default)'); | 79 help: 'Whether to use terminal colors.\n(auto-detected by default)'); |
| 80 parser.addOption("tags", | 80 parser.addOption("tags", |
| 81 help: 'Comma-separated list of tags to run', | 81 abbr: 't', |
| 82 allowMultiple: true, | 82 help: 'Comma-separated list of tags to run', |
| 83 splitCommas: true); | 83 allowMultiple: true, |
| 84 splitCommas: true); |
| 85 parser.addOption("tag", |
| 86 hide: true, |
| 87 allowMultiple: true, |
| 88 splitCommas: true); |
| 89 parser.addOption("exclude-tags", |
| 90 abbr: 'x', |
| 91 help: 'Comma-separated list of tags not to run', |
| 92 allowMultiple: true, |
| 93 splitCommas: true); |
| 94 parser.addOption("exclude-tag", |
| 95 hide: true, |
| 96 allowMultiple: true, |
| 97 splitCommas: true); |
| 84 | 98 |
| 85 return parser; | 99 return parser; |
| 86 })(); | 100 })(); |
| 87 | 101 |
| 88 /// The usage string for the command-line arguments. | 102 /// The usage string for the command-line arguments. |
| 89 static String get usage => _parser.usage; | 103 static String get usage => _parser.usage; |
| 90 | 104 |
| 91 /// Whether `--help` was passed. | 105 /// Whether `--help` was passed. |
| 92 final bool help; | 106 final bool help; |
| 93 | 107 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 final bool explicitPaths; | 142 final bool explicitPaths; |
| 129 | 143 |
| 130 /// The pattern to match against test names to decide which to run, or `null` | 144 /// The pattern to match against test names to decide which to run, or `null` |
| 131 /// if all tests should be run. | 145 /// if all tests should be run. |
| 132 final Pattern pattern; | 146 final Pattern pattern; |
| 133 | 147 |
| 134 /// The set of platforms on which to run tests. | 148 /// The set of platforms on which to run tests. |
| 135 final List<TestPlatform> platforms; | 149 final List<TestPlatform> platforms; |
| 136 | 150 |
| 137 /// Restricts the set of tests to a set of tags | 151 /// Restricts the set of tests to a set of tags |
| 138 final List<String> tags; | 152 final Set<String> tags; |
| 153 |
| 154 /// Does not run tests with tags from this set |
| 155 final Set<String> excludeTags; |
| 139 | 156 |
| 140 /// The global test metadata derived from this configuration. | 157 /// The global test metadata derived from this configuration. |
| 141 Metadata get metadata => | 158 Metadata get metadata => |
| 142 new Metadata( | 159 new Metadata( |
| 143 timeout: pauseAfterLoad ? Timeout.none : null, | 160 timeout: pauseAfterLoad ? Timeout.none : null, |
| 144 verboseTrace: verboseTrace); | 161 verboseTrace: verboseTrace); |
| 145 | 162 |
| 146 /// Parses the configuration from [args]. | 163 /// Parses the configuration from [args]. |
| 147 /// | 164 /// |
| 148 /// Throws a [FormatException] if [args] are invalid. | 165 /// Throws a [FormatException] if [args] are invalid. |
| 149 factory Configuration.parse(List<String> args) { | 166 factory Configuration.parse(List<String> args) { |
| 150 var options = _parser.parse(args); | 167 var options = _parser.parse(args); |
| 151 | 168 |
| 152 var pattern; | 169 var pattern; |
| 153 if (options['name'] != null) { | 170 if (options['name'] != null) { |
| 154 if (options["plain-name"] != null) { | 171 if (options["plain-name"] != null) { |
| 155 throw new FormatException( | 172 throw new FormatException( |
| 156 "--name and --plain-name may not both be passed."); | 173 "--name and --plain-name may not both be passed."); |
| 157 } | 174 } |
| 158 | 175 |
| 159 pattern = _wrapFormatException( | 176 pattern = _wrapFormatException( |
| 160 options, 'name', (value) => new RegExp(value)); | 177 options, 'name', (value) => new RegExp(value)); |
| 161 } else if (options['plain-name'] != null) { | 178 } else if (options['plain-name'] != null) { |
| 162 pattern = options['plain-name']; | 179 pattern = options['plain-name']; |
| 163 } | 180 } |
| 164 | 181 |
| 182 var tags = new Set<String>(); |
| 183 tags.addAll(options['tags'] ?? []); |
| 184 tags.addAll(options['tag'] ?? []); |
| 185 |
| 186 var excludeTags = new Set<String>(); |
| 187 excludeTags.addAll(options['exclude-tags'] ?? []); |
| 188 excludeTags.addAll(options['exclude-tag'] ?? []); |
| 189 |
| 190 var tagIntersection = tags.intersection(excludeTags); |
| 191 if (tagIntersection.isNotEmpty) { |
| 192 throw new FormatException('Included and excluded tag sets may not' |
| 193 ' intersect. Found intersection: ${tagIntersection.join(', ')}'); |
| 194 } |
| 195 |
| 165 return new Configuration( | 196 return new Configuration( |
| 166 help: options['help'], | 197 help: options['help'], |
| 167 version: options['version'], | 198 version: options['version'], |
| 168 verboseTrace: options['verbose-trace'], | 199 verboseTrace: options['verbose-trace'], |
| 169 jsTrace: options['js-trace'], | 200 jsTrace: options['js-trace'], |
| 170 pauseAfterLoad: options['pause-after-load'], | 201 pauseAfterLoad: options['pause-after-load'], |
| 171 color: options['color'], | 202 color: options['color'], |
| 172 packageRoot: options['package-root'], | 203 packageRoot: options['package-root'], |
| 173 reporter: options['reporter'], | 204 reporter: options['reporter'], |
| 174 pubServePort: _wrapFormatException(options, 'pub-serve', int.parse), | 205 pubServePort: _wrapFormatException(options, 'pub-serve', int.parse), |
| 175 concurrency: _wrapFormatException(options, 'concurrency', int.parse, | 206 concurrency: _wrapFormatException(options, 'concurrency', int.parse, |
| 176 orElse: () => _defaultConcurrency), | 207 orElse: () => _defaultConcurrency), |
| 177 pattern: pattern, | 208 pattern: pattern, |
| 178 platforms: options['platform'].map(TestPlatform.find), | 209 platforms: options['platform'].map(TestPlatform.find), |
| 179 paths: options.rest.isEmpty ? null : options.rest, | 210 paths: options.rest.isEmpty ? null : options.rest, |
| 180 tags: options['tags']); | 211 tags: tags, |
| 212 excludeTags: excludeTags); |
| 181 } | 213 } |
| 182 | 214 |
| 183 /// Runs [parse] on the value of the option [name], and wraps any | 215 /// Runs [parse] on the value of the option [name], and wraps any |
| 184 /// [FormatException] it throws with additional information. | 216 /// [FormatException] it throws with additional information. |
| 185 static _wrapFormatException(ArgResults options, String name, parse(value), | 217 static _wrapFormatException(ArgResults options, String name, parse(value), |
| 186 {orElse()}) { | 218 {orElse()}) { |
| 187 var value = options[name]; | 219 var value = options[name]; |
| 188 if (value == null) return orElse == null ? null : orElse(); | 220 if (value == null) return orElse == null ? null : orElse(); |
| 189 | 221 |
| 190 try { | 222 try { |
| 191 return parse(value); | 223 return parse(value); |
| 192 } on FormatException catch (error) { | 224 } on FormatException catch (error) { |
| 193 throw new FormatException('Couldn\'t parse --$name "${options[name]}": ' | 225 throw new FormatException('Couldn\'t parse --$name "${options[name]}": ' |
| 194 '${error.message}'); | 226 '${error.message}'); |
| 195 } | 227 } |
| 196 } | 228 } |
| 197 | 229 |
| 198 Configuration({this.help: false, this.version: false, | 230 Configuration({this.help: false, this.version: false, |
| 199 this.verboseTrace: false, this.jsTrace: false, | 231 this.verboseTrace: false, this.jsTrace: false, |
| 200 bool pauseAfterLoad: false, bool color, String packageRoot, | 232 bool pauseAfterLoad: false, bool color, String packageRoot, |
| 201 String reporter, int pubServePort, int concurrency, this.pattern, | 233 String reporter, int pubServePort, int concurrency, this.pattern, |
| 202 Iterable<TestPlatform> platforms, Iterable<String> paths, | 234 Iterable<TestPlatform> platforms, Iterable<String> paths, |
| 203 List<String> tags}) | 235 Set<String> tags, Set<String> excludeTags}) |
| 204 : pauseAfterLoad = pauseAfterLoad, | 236 : pauseAfterLoad = pauseAfterLoad, |
| 205 color = color == null ? canUseSpecialChars : color, | 237 color = color == null ? canUseSpecialChars : color, |
| 206 packageRoot = packageRoot == null | 238 packageRoot = packageRoot == null |
| 207 ? p.join(p.current, 'packages') | 239 ? p.join(p.current, 'packages') |
| 208 : packageRoot, | 240 : packageRoot, |
| 209 reporter = reporter == null ? 'compact' : reporter, | 241 reporter = reporter == null ? 'compact' : reporter, |
| 210 pubServeUrl = pubServePort == null | 242 pubServeUrl = pubServePort == null |
| 211 ? null | 243 ? null |
| 212 : Uri.parse("http://localhost:$pubServePort"), | 244 : Uri.parse("http://localhost:$pubServePort"), |
| 213 concurrency = pauseAfterLoad | 245 concurrency = pauseAfterLoad |
| 214 ? 1 | 246 ? 1 |
| 215 : (concurrency == null ? _defaultConcurrency : concurrency), | 247 : (concurrency == null ? _defaultConcurrency : concurrency), |
| 216 platforms = platforms == null ? [TestPlatform.vm] : platforms.toList(), | 248 platforms = platforms == null ? [TestPlatform.vm] : platforms.toList(), |
| 217 paths = paths == null ? ["test"] : paths.toList(), | 249 paths = paths == null ? ["test"] : paths.toList(), |
| 218 explicitPaths = paths != null, | 250 explicitPaths = paths != null, |
| 219 this.tags = tags == null | 251 this.tags = tags, |
| 220 ? const <String>[] | 252 this.excludeTags = excludeTags; |
| 221 : tags; | |
| 222 } | 253 } |
| OLD | NEW |