diff --git a/lib/src/runner/configuration.dart b/lib/src/runner/configuration.dart index f2a53f927f2707635998328cf31605898fd9e458..776c2fc11b58d50e5588a33f35bcee2dc0f19317 100644 --- a/lib/src/runner/configuration.dart +++ b/lib/src/runner/configuration.dart @@ -10,6 +10,7 @@ import 'dart:math' as math; import 'package:args/args.dart'; import 'package:path/path.dart' as p; +import '../frontend/timeout.dart'; import '../backend/test_platform.dart'; import '../util/io.dart'; @@ -83,98 +84,121 @@ class Configuration { /// The usage string for the command-line arguments. static String get usage => _parser.usage; - /// The results of parsing the arguments. - final ArgResults _options; - /// Whether `--help` was passed. - bool get help => _options['help']; + final bool help; /// Whether `--version` was passed. - bool get version => _options['version']; + final bool version; /// Whether stack traces should be presented as-is or folded to remove /// irrelevant packages. - bool get verboseTrace => _options['verbose-trace']; + final bool verboseTrace; /// Whether JavaScript stack traces should be left as-is or converted to /// Dart-like traces. - bool get jsTrace => _options['js-trace']; + final bool jsTrace; /// Whether to pause for debugging after loading each test suite. - bool get pauseAfterLoad => _options['pause-after-load']; + final bool pauseAfterLoad; /// The package root for resolving "package:" URLs. - String get packageRoot => _options['package-root'] == null - ? p.join(p.current, 'packages') - : _options['package-root']; + final String packageRoot; /// The name of the reporter to use to display results. - String get reporter => _options['reporter']; + final String reporter; /// The URL for the `pub serve` instance from which to load tests, or `null` /// if tests should be loaded from the filesystem. - Uri get pubServeUrl { - if (_options['pub-serve'] == null) return null; - return Uri.parse("http://localhost:${_options['pub-serve']}"); - } + final Uri pubServeUrl; /// Whether to use command-line color escapes. - bool get color => - _options["color"] == null ? canUseSpecialChars : _options["color"]; + final bool color; /// How many tests to run concurrently. - int get concurrency => _concurrency; - int _concurrency; + final int concurrency; /// The from which to load tests. - List<String> get paths => _options.rest.isEmpty ? ["test"] : _options.rest; + final List<String> paths; /// Whether the load paths were passed explicitly or the default was used. - bool get explicitPaths => _options.rest.isNotEmpty; + final bool explicitPaths; /// The pattern to match against test names to decide which to run, or `null` /// if all tests should be run. - Pattern get pattern { - if (_options["name"] != null) { - return new RegExp(_options["name"]); - } else if (_options["plain-name"] != null) { - return _options["plain-name"]; - } else { - return null; - } - } + final Pattern pattern; /// The set of platforms on which to run tests. - List<TestPlatform> get platforms => - _options["platform"].map(TestPlatform.find).toList(); + final List<TestPlatform> platforms; /// Parses the configuration from [args]. /// /// Throws a [FormatException] if [args] are invalid. - Configuration.parse(List<String> args) - : _options = _parser.parse(args) { - if (pauseAfterLoad) { - _concurrency = 1; - } else if (_options['concurrency'] == null) { - _concurrency = _defaultConcurrency; - } else { - _concurrency = _wrapFormatException('concurrency', int.parse); + factory Configuration.parse(List<String> args) { + var options = _parser.parse(args); + + var pattern; + if (options['name'] != null) { + if (options["plain-name"] != null) { + throw new FormatException( + "--name and --plain-name may not both be passed."); + } + + pattern = _wrapFormatException( + options, 'name', (value) => new RegExp(value)); + } else if (options['plain-name'] != null) { + pattern = options['plain-name']; } - if (_options["name"] != null && _options["plain-name"] != null) { - throw new FormatException( - "--name and --plain-name may not both be passed."); - } + return new Configuration( + help: options['help'], + version: options['version'], + verboseTrace: options['verbose-trace'], + jsTrace: options['js-trace'], + pauseAfterLoad: options['pause-after-load'], + color: options['color'], + packageRoot: options['package-root'], + reporter: options['reporter'], + pubServePort: _wrapFormatException(options, 'pub-serve', int.parse), + concurrency: _wrapFormatException(options, 'concurrency', int.parse, + orElse: () => _defaultConcurrency), + pattern: pattern, + platforms: options['platforms'].map(TestPlatform.find).toList(), + paths: options.rest.isEmpty ? null : options.rest); } /// Runs [parse] on the value of the option [name], and wraps any /// [FormatException] it throws with additional information. - _wrapFormatException(String name, parse(value)) { + static _wrapFormatException(ArgResults options, String name, parse(value), + {orElse()}) { + var value = options[name]; + if (value == null) return orElse == null ? null : orElse(); + try { - return parse(_options[name]); + return parse(value); } on FormatException catch (error) { - throw new FormatException('Couldn\'t parse --$name "${_options[name]}": ' + throw new FormatException('Couldn\'t parse --$name "${options[name]}": ' '${error.message}'); } } + + Configuration({this.help: false, this.version: false, + this.verboseTrace: false, this.jsTrace: false, + bool pauseAfterLoad: false, bool color, String packageRoot, + String reporter, int pubServePort, int concurrency, this.pattern, + Iterable<TestPlatform> platforms, Iterable<String> paths}) + : pauseAfterLoad = pauseAfterLoad, + color = color == null ? canUseSpecialChars : color, + packageRoot = packageRoot == null + ? p.join(p.current, 'packages') + : packageRoot, + reporter = reporter == null ? 'compact' : reporter, + pubServeUrl = pubServePort == null + ? null + : Uri.parse("http://localhost:$pubServePort"), + concurrency = pauseAfterLoad + ? 1 + : (concurrency == null ? _defaultConcurrency : concurrency), + platforms = platforms.toList(), + paths = paths == null ? ["test"] : paths.toList(), + explicitPaths = paths != null; }