Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: lib/src/runner/configuration/load.dart

Issue 1691173002: Support tag configuration. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/runner/configuration/args.dart ('k') | lib/src/utils.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'dart:io'; 5 import 'dart:io';
6 6
7 import 'package:glob/glob.dart'; 7 import 'package:glob/glob.dart';
8 import 'package:path/path.dart' as p; 8 import 'package:path/path.dart' as p;
9 import 'package:source_span/source_span.dart'; 9 import 'package:source_span/source_span.dart';
10 import 'package:yaml/yaml.dart'; 10 import 'package:yaml/yaml.dart';
(...skipping 26 matching lines...) Expand all
37 /// A helper for [load] that tracks the YAML document. 37 /// A helper for [load] that tracks the YAML document.
38 class _ConfigurationLoader { 38 class _ConfigurationLoader {
39 /// The parsed configuration document. 39 /// The parsed configuration document.
40 final YamlMap _document; 40 final YamlMap _document;
41 41
42 /// The source string for [_document]. 42 /// The source string for [_document].
43 /// 43 ///
44 /// Used for error reporting. 44 /// Used for error reporting.
45 final String _source; 45 final String _source;
46 46
47 _ConfigurationLoader(this._document, this._source); 47 /// Whether runner configuration is allowed at this level.
48 final bool _runnerConfig;
49
50 _ConfigurationLoader(this._document, this._source, {bool runnerConfig: true})
51 : _runnerConfig = runnerConfig;
48 52
49 /// Loads the configuration in [_document]. 53 /// Loads the configuration in [_document].
50 Configuration load() { 54 Configuration load() => _loadTestConfig().merge(_loadRunnerConfig());
55
56 /// Loads test configuration (but not runner configuration).
57 Configuration _loadTestConfig() {
51 var verboseTrace = _getBool("verbose_trace"); 58 var verboseTrace = _getBool("verbose_trace");
52 var jsTrace = _getBool("js_trace"); 59 var jsTrace = _getBool("js_trace");
53 60
61 var timeout = _parseValue("timeout", (value) => new Timeout.parse(value));
62
63 var tags = _getMap("tags", key: (keyNode) {
64 _validate(keyNode, "tags key must be a string.",
65 (value) => value is String);
66 _validate(
67 keyNode,
68 "Invalid tag. Tags must be (optionally hyphenated) Dart identifiers.",
69 (value) => value.contains(anchoredHyphenatedIdentifier));
70
71 return keyNode.value;
72 }, value: (valueNode) {
73 return _nestedConfig(valueNode, "tag value", runnerConfig: false);
74 });
75
76 return new Configuration(
77 verboseTrace: verboseTrace,
78 jsTrace: jsTrace,
79 timeout: timeout,
80 tags: tags);
81 }
82
83 /// Loads runner configuration (but not test configuration).
84 ///
85 /// If [_runnerConfig] is `false`, this will error if there are any
86 /// runner-level configuration fields.
87 Configuration _loadRunnerConfig() {
88 if (!_runnerConfig) {
89 _disallow("reporter");
90 _disallow("pub_serve");
91 _disallow("concurrency");
92 _disallow("platforms");
93 _disallow("paths");
94 _disallow("filename");
95 return new Configuration();
96 }
97
54 var reporter = _getString("reporter"); 98 var reporter = _getString("reporter");
55 if (reporter != null && !allReporters.contains(reporter)) { 99 if (reporter != null && !allReporters.contains(reporter)) {
56 _error('Unknown reporter "$reporter".', "reporter"); 100 _error('Unknown reporter "$reporter".', "reporter");
57 } 101 }
58 102
59 var pubServePort = _getInt("pub_serve"); 103 var pubServePort = _getInt("pub_serve");
60 var concurrency = _getInt("concurrency"); 104 var concurrency = _getInt("concurrency");
61 var timeout = _parseValue("timeout", (value) => new Timeout.parse(value));
62 105
63 var allPlatformIdentifiers = 106 var allPlatformIdentifiers =
64 TestPlatform.all.map((platform) => platform.identifier).toSet(); 107 TestPlatform.all.map((platform) => platform.identifier).toSet();
65 var platforms = _getList("platforms", (platformNode) { 108 var platforms = _getList("platforms", (platformNode) {
66 _validate(platformNode, "Platforms must be strings.", 109 _validate(platformNode, "Platforms must be strings.",
67 (value) => value is String); 110 (value) => value is String);
68 _validate(platformNode, 'Unknown platform "${platformNode.value}".', 111 _validate(platformNode, 'Unknown platform "${platformNode.value}".',
69 allPlatformIdentifiers.contains); 112 allPlatformIdentifiers.contains);
70 113
71 return TestPlatform.find(platformNode.value); 114 return TestPlatform.find(platformNode.value);
72 }); 115 });
73 116
74 var paths = _getList("paths", (pathNode) { 117 var paths = _getList("paths", (pathNode) {
75 _validate(pathNode, "Paths must be strings.", (value) => value is String); 118 _validate(pathNode, "Paths must be strings.", (value) => value is String);
76 _validate(pathNode, "Paths must be relative.", p.url.isRelative); 119 _validate(pathNode, "Paths must be relative.", p.url.isRelative);
77 120
78 return _parseNode(pathNode, "path", p.fromUri); 121 return _parseNode(pathNode, "path", p.fromUri);
79 }); 122 });
80 123
81 var filename = _parseValue("filename", (value) => new Glob(value)); 124 var filename = _parseValue("filename", (value) => new Glob(value));
82 125
83 return new Configuration( 126 return new Configuration(
84 verboseTrace: verboseTrace,
85 jsTrace: jsTrace,
86 reporter: reporter, 127 reporter: reporter,
87 pubServePort: pubServePort, 128 pubServePort: pubServePort,
88 concurrency: concurrency, 129 concurrency: concurrency,
89 timeout: timeout,
90 platforms: platforms, 130 platforms: platforms,
91 paths: paths, 131 paths: paths,
92 filename: filename); 132 filename: filename);
93 } 133 }
94 134
95 /// Throws an exception with [message] if [test] returns `false` when passed 135 /// Throws an exception with [message] if [test] returns `false` when passed
96 /// [node]'s value. 136 /// [node]'s value.
97 void _validate(YamlNode node, String message, bool test(value)) { 137 void _validate(YamlNode node, String message, bool test(value)) {
98 if (test(node.value)) return; 138 if (test(node.value)) return;
99 throw new SourceSpanFormatException(message, node.span, _source); 139 throw new SourceSpanFormatException(message, node.span, _source);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 /// Asserts that [field] is a list and runs [forElement] for each element it 175 /// Asserts that [field] is a list and runs [forElement] for each element it
136 /// contains. 176 /// contains.
137 /// 177 ///
138 /// Returns a list of values returned by [forElement]. 178 /// Returns a list of values returned by [forElement].
139 List _getList(String field, forElement(YamlNode elementNode)) { 179 List _getList(String field, forElement(YamlNode elementNode)) {
140 var node = _getNode(field, "list", (value) => value is List); 180 var node = _getNode(field, "list", (value) => value is List);
141 if (node == null) return []; 181 if (node == null) return [];
142 return node.nodes.map(forElement).toList(); 182 return node.nodes.map(forElement).toList();
143 } 183 }
144 184
185 /// Asserts that [field] is a map and runs [key] and [value] for each pair.
186 ///
187 /// Returns a map with the keys and values returned by [key] and [value]. Each
188 /// of these defaults to asserting that the value is a string.
189 Map _getMap(String field, {key(YamlNode keyNode),
190 value(YamlNode valueNode)}) {
191 var node = _getNode(field, "map", (value) => value is Map);
192 if (node == null) return {};
193
194 key ??= (keyNode) {
195 _validate(keyNode, "$field keys must be strings.",
196 (value) => value is String);
197
198 return keyNode.value;
199 };
200
201 value ??= (valueNode) {
202 _validate(valueNode, "$field values must be strings.",
203 (value) => value is String);
204
205 return valueNode.value;
206 };
207
208 return mapMap(node.nodes,
209 key: (keyNode, _) => key(keyNode),
210 value: (_, valueNode) => value(valueNode));
211 }
212
145 /// Asserts that [node] is a string, passes its value to [parse], and returns 213 /// Asserts that [node] is a string, passes its value to [parse], and returns
146 /// the result. 214 /// the result.
147 /// 215 ///
148 /// If [parse] throws a [FormatException], it's wrapped to include [node]'s 216 /// If [parse] throws a [FormatException], it's wrapped to include [node]'s
149 /// span. 217 /// span.
150 _parseNode(YamlNode node, String name, parse(String value)) { 218 _parseNode(YamlNode node, String name, parse(String value)) {
151 _validate(node, "$name must be a string.", (value) => value is String); 219 _validate(node, "$name must be a string.", (value) => value is String);
152 220
153 try { 221 try {
154 return parse(node.value); 222 return parse(node.value);
155 } on FormatException catch (error) { 223 } on FormatException catch (error) {
156 throw new SourceSpanFormatException( 224 throw new SourceSpanFormatException(
157 'Invalid $name: ${error.message}', node.span, _source); 225 'Invalid $name: ${error.message}', node.span, _source);
158 } 226 }
159 } 227 }
160 228
161 /// Asserts that [field] is a string, passes it to [parse], and returns the 229 /// Asserts that [field] is a string, passes it to [parse], and returns the
162 /// result. 230 /// result.
163 /// 231 ///
164 /// If [parse] throws a [FormatException], it's wrapped to include [field]'s 232 /// If [parse] throws a [FormatException], it's wrapped to include [field]'s
165 /// span. 233 /// span.
166 _parseValue(String field, parse(String value)) { 234 _parseValue(String field, parse(String value)) {
167 var node = _document.nodes[field]; 235 var node = _document.nodes[field];
168 if (node == null) return null; 236 if (node == null) return null;
169 return _parseNode(node, field, parse); 237 return _parseNode(node, field, parse);
170 } 238 }
171 239
240 /// Parses a nested configuration document.
241 ///
242 /// [name] is the name of the field, which is used for error-handling.
243 /// [runnerConfig] controls whether runner configuration is allowed in the
244 /// nested configuration. It defaults to [_runnerConfig].
245 Configuration _nestedConfig(YamlNode node, String name,
246 {bool runnerConfig}) {
247 if (node == null || node.value == null) return new Configuration();
248
249 _validate(node, "$name must be a map.", (value) => value is Map);
250 var loader = new _ConfigurationLoader(node, _source,
251 runnerConfig: runnerConfig ?? _runnerConfig);
252 return loader.load();
253 }
254
255 /// Throws an error if a field named [field] exists at this level.
256 void _disallow(String field) {
257 if (!_document.containsKey(field)) return;
258 _error("$field isn't supported here.", field);
259 }
260
172 /// Throws a [SourceSpanFormatException] with [message] about [field]. 261 /// Throws a [SourceSpanFormatException] with [message] about [field].
173 void _error(String message, String field) { 262 void _error(String message, String field) {
174 throw new SourceSpanFormatException( 263 throw new SourceSpanFormatException(
175 message, _document.nodes[field].span, _source); 264 message, _document.nodes[field].span, _source);
176 } 265 }
177 } 266 }
OLDNEW
« no previous file with comments | « lib/src/runner/configuration/args.dart ('k') | lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698