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

Side by Side Diff: tools/testing/dart/status_file.dart

Issue 2901923003: Replace the configuration map with a typed object. (Closed)
Patch Set: Revise. Created 3 years, 6 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 | « tools/testing/dart/status_expression.dart ('k') | tools/testing/dart/status_reporter.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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 'environment.dart';
7 import 'expectation.dart'; 8 import 'expectation.dart';
9 import 'path.dart';
8 import 'status_expression.dart'; 10 import 'status_expression.dart';
9 11
10 /// Splits out a trailing line comment 12 /// Splits out a trailing line comment
11 final _commentPattern = new RegExp("^([^#]*)(#.*)?\$"); 13 final _commentPattern = new RegExp("^([^#]*)(#.*)?\$");
12 14
13 /// Matches the header that begins a new section, like: 15 /// Matches the header that begins a new section, like:
14 /// 16 ///
15 /// [ $compiler == dart2js && $minified ] 17 /// [ $compiler == dart2js && $minified ]
16 final _sectionPattern = new RegExp(r"^\[([^\]]+)\]"); 18 final _sectionPattern = new RegExp(r"^\[([^\]]+)\]");
17 19
(...skipping 18 matching lines...) Expand all
36 /// an environment. If it evaluates to true, then the entries after the header 38 /// an environment. If it evaluates to true, then the entries after the header
37 /// take effect. 39 /// take effect.
38 /// 40 ///
39 /// Each entry is a glob-like file path followed by a colon and then a 41 /// Each entry is a glob-like file path followed by a colon and then a
40 /// comma-separated list of [Expectation]s. The path may point to an individual 42 /// comma-separated list of [Expectation]s. The path may point to an individual
41 /// file, or a directory, in which case it applies to all files under that path. 43 /// file, or a directory, in which case it applies to all files under that path.
42 /// 44 ///
43 /// Entries may also appear before any section header, in which case they 45 /// Entries may also appear before any section header, in which case they
44 /// always apply. 46 /// always apply.
45 class StatusFile { 47 class StatusFile {
48 final String _path;
46 final List<StatusSection> sections = []; 49 final List<StatusSection> sections = [];
47 50
48 /// Parses the status file at [path]. 51 /// Parses the status file at [_path].
49 StatusFile.read(String path) { 52 StatusFile.read(this._path) {
50 var lines = new File(path).readAsLinesSync(); 53 var lines = new File(_path).readAsLinesSync();
51 54
52 // The current section whose rules are being parsed. 55 // The current section whose rules are being parsed.
53 StatusSection section; 56 StatusSection section;
54 57
55 var lineNumber = 0; 58 var lineNumber = 0;
59
56 for (var line in lines) { 60 for (var line in lines) {
57 lineNumber++; 61 lineNumber++;
58 62
63 fail(String message, [List<String> errors]) {
64 print('$message in "$_shortPath" line $lineNumber:\n$line');
65
66 if (errors != null) {
67 for (var error in errors) {
68 print("- ${error.replaceAll('\n', '\n ')}");
69 }
70 }
71 exit(1);
72 }
73
59 // Strip off the comment and whitespace. 74 // Strip off the comment and whitespace.
60 var match = _commentPattern.firstMatch(line); 75 var match = _commentPattern.firstMatch(line);
61 var source = ""; 76 var source = "";
62 var comment = ""; 77 var comment = "";
63 if (match != null) { 78 if (match != null) {
64 source = match[1].trim(); 79 source = match[1].trim();
65 comment = match[2] ?? ""; 80 comment = match[2] ?? "";
66 } 81 }
67 82
68 // Ignore empty (or comment-only) lines. 83 // Ignore empty (or comment-only) lines.
69 if (source.isEmpty) continue; 84 if (source.isEmpty) continue;
70 85
71 // See if we are starting a new section. 86 // See if we are starting a new section.
72 match = _sectionPattern.firstMatch(source); 87 match = _sectionPattern.firstMatch(source);
73 if (match != null) { 88 if (match != null) {
74 var condition = Expression.parse(match[1].trim()); 89 try {
75 section = new StatusSection(condition); 90 var condition = Expression.parse(match[1].trim());
76 sections.add(section); 91
92 var errors = <String>[];
93 condition.validate(errors);
94
95 if (errors.isNotEmpty) {
96 var s = errors.length > 1 ? "s" : "";
97 fail('Validation error$s', errors);
98 }
99
100 section = new StatusSection(condition);
101 sections.add(section);
102 } on FormatException {
103 fail("Status expression syntax error");
104 }
77 continue; 105 continue;
78 } 106 }
79 107
80 // Otherwise, it should be a new entry under the current section. 108 // Otherwise, it should be a new entry under the current section.
81 match = _entryPattern.firstMatch(source); 109 match = _entryPattern.firstMatch(source);
82 if (match != null) { 110 if (match != null) {
83 var path = match[1].trim(); 111 var path = match[1].trim();
84 // TODO(whesse): Handle test names ending in a wildcard (*). 112 // TODO(whesse): Handle test names ending in a wildcard (*).
85 var expectations = _parseExpectations(match[2]); 113 var expectations = <Expectation>[];
114 for (var name in match[2].split(",")) {
115 name = name.trim();
116 try {
117 expectations.add(Expectation.find(name));
118 } on ArgumentError {
119 fail('Unrecognized test expectation "$name"');
120 }
121 }
122
86 var issue = _issueNumber(comment); 123 var issue = _issueNumber(comment);
87 124
88 // If we haven't found a section header yet, create an implicit section 125 // If we haven't found a section header yet, create an implicit section
89 // that matches everything. 126 // that matches everything.
90 if (section == null) { 127 if (section == null) {
91 section = new StatusSection(null); 128 section = new StatusSection(null);
92 sections.add(section); 129 sections.add(section);
93 } 130 }
94 131
95 section.entries.add(new StatusEntry(path, expectations, issue)); 132 section.entries.add(new StatusEntry(path, expectations, issue));
96 continue; 133 continue;
97 } 134 }
98 135
99 throw new FormatException( 136 fail("Unrecognized input");
100 "Could not parse line $lineNumber of status file '$path':\n$line");
101 } 137 }
102 } 138 }
103 139
104 /// Parses a comma-separated list of expectation names from [text]. 140 /// Gets the path to this status file relative to the Dart repo root.
105 List<Expectation> _parseExpectations(String text) { 141 String get _shortPath {
106 return text 142 var repoRoot = new Path(Platform.script
107 .split(",") 143 .toFilePath(windows: Platform.operatingSystem == "windows"))
108 .map((name) => Expectation.find(name.trim())) 144 .join(new Path("../../../../"));
109 .toList(); 145 return new Path(_path).relativeTo(repoRoot).toString();
110 } 146 }
111 147
112 /// Returns the issue number embedded in [comment] or `null` if there is none. 148 /// Returns the issue number embedded in [comment] or `null` if there is none.
113 int _issueNumber(String comment) { 149 int _issueNumber(String comment) {
114 var match = _issuePattern.firstMatch(comment); 150 var match = _issuePattern.firstMatch(comment);
115 if (match == null) return null; 151 if (match == null) return null;
116 152
117 return int.parse(match[1], onError: (_) => null); 153 return int.parse(match[1], onError: (_) => null);
118 } 154 }
119 155
(...skipping 21 matching lines...) Expand all
141 /// the entries within the section. 177 /// the entries within the section.
142 class StatusSection { 178 class StatusSection {
143 /// The expression that determines when this section is applied. 179 /// The expression that determines when this section is applied.
144 /// 180 ///
145 /// May be `null` for paths that appear before any section header in the file. 181 /// May be `null` for paths that appear before any section header in the file.
146 /// In that case, the section always applies. 182 /// In that case, the section always applies.
147 final Expression _condition; 183 final Expression _condition;
148 final List<StatusEntry> entries = []; 184 final List<StatusEntry> entries = [];
149 185
150 /// Returns true if this section should apply in the given [environment]. 186 /// Returns true if this section should apply in the given [environment].
151 bool isEnabled(Map<String, dynamic> environment) => 187 bool isEnabled(Environment environment) =>
152 _condition == null || _condition.evaluate(environment); 188 _condition == null || _condition.evaluate(environment);
153 189
154 StatusSection(this._condition); 190 StatusSection(this._condition);
155 } 191 }
156 192
157 /// Describes the test status of the file or files at a given path. 193 /// Describes the test status of the file or files at a given path.
158 class StatusEntry { 194 class StatusEntry {
159 final String path; 195 final String path;
160 final List<Expectation> expectations; 196 final List<Expectation> expectations;
161 final int issue; 197 final int issue;
162 198
163 StatusEntry(this.path, this.expectations, this.issue); 199 StatusEntry(this.path, this.expectations, this.issue);
164 } 200 }
OLDNEW
« no previous file with comments | « tools/testing/dart/status_expression.dart ('k') | tools/testing/dart/status_reporter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698