OLD | NEW |
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 'environment.dart'; |
8 import 'expectation.dart'; | 8 import 'expectation.dart'; |
9 import 'path.dart'; | 9 import 'path.dart'; |
10 import 'status_expression.dart'; | 10 import 'status_expression.dart'; |
11 | 11 |
12 /// Splits out a trailing line comment | |
13 final _commentPattern = new RegExp("^([^#]*)(#.*)?\$"); | |
14 | |
15 /// Matches the header that begins a new section, like: | 12 /// Matches the header that begins a new section, like: |
16 /// | 13 /// |
17 /// [ $compiler == dart2js && $minified ] | 14 /// [ $compiler == dart2js && $minified ] |
18 final _sectionPattern = new RegExp(r"^\[([^\]]+)\]"); | 15 final _sectionPattern = new RegExp(r"^\[(.+?)\]"); |
19 | 16 |
20 /// Matches an entry that defines the status for a path in the current section, | 17 /// Matches an entry that defines the status for a path in the current section, |
21 /// like: | 18 /// like: |
22 /// | 19 /// |
23 /// some/path/to/some_test: Pass || Fail | 20 /// some/path/to/some_test: Pass || Fail |
24 final _entryPattern = new RegExp(r"\s*([^: ]*)\s*:(.*)"); | 21 final _entryPattern = new RegExp(r"\s*([^: ]*)\s*:(.*)"); |
25 | 22 |
26 /// Matches an issue number in a comment, like: | 23 /// Matches an issue number in a comment, like: |
27 /// | 24 /// |
28 /// blah_test: Fail # Issue 1234 | 25 /// blah_test: Fail # Issue 1234 |
29 /// ^^^^ | 26 /// ^^^^ |
30 final _issuePattern = new RegExp("[Ii]ssue ([0-9]+)"); | 27 final _issuePattern = new RegExp(r"[Ii]ssue (\d+)"); |
31 | 28 |
32 /// A parsed status file, which describes how a collection of tests are | 29 /// A parsed status file, which describes how a collection of tests are |
33 /// expected to behave under various configurations and conditions. | 30 /// expected to behave under various configurations and conditions. |
34 /// | 31 /// |
35 /// Each status file is made of a series of sections. Each section begins with | 32 /// Each status file is made of a series of sections. Each section begins with |
36 /// a header, followed by a series of entries. A header is enclosed in square | 33 /// a header, followed by a series of entries. A header is enclosed in square |
37 /// brackets and contains a Boolean expression. That expression is evaluated in | 34 /// brackets and contains a Boolean expression. That expression is evaluated in |
38 /// an environment. If it evaluates to true, then the entries after the header | 35 /// an environment. If it evaluates to true, then the entries after the header |
39 /// take effect. | 36 /// take effect. |
40 /// | 37 /// |
(...skipping 24 matching lines...) Expand all Loading... |
65 | 62 |
66 if (errors != null) { | 63 if (errors != null) { |
67 for (var error in errors) { | 64 for (var error in errors) { |
68 print("- ${error.replaceAll('\n', '\n ')}"); | 65 print("- ${error.replaceAll('\n', '\n ')}"); |
69 } | 66 } |
70 } | 67 } |
71 exit(1); | 68 exit(1); |
72 } | 69 } |
73 | 70 |
74 // Strip off the comment and whitespace. | 71 // Strip off the comment and whitespace. |
75 var match = _commentPattern.firstMatch(line); | 72 var source = line; |
76 var source = ""; | |
77 var comment = ""; | 73 var comment = ""; |
78 if (match != null) { | 74 var hashIndex = line.indexOf('#'); |
79 source = match[1].trim(); | 75 if (hashIndex >= 0) { |
80 comment = match[2] ?? ""; | 76 source = line.substring(0, hashIndex); |
| 77 comment = line.substring(hashIndex); |
81 } | 78 } |
| 79 source = source.trim(); |
82 | 80 |
83 // Ignore empty (or comment-only) lines. | 81 // Ignore empty (or comment-only) lines. |
84 if (source.isEmpty) continue; | 82 if (source.isEmpty) continue; |
85 | 83 |
86 // See if we are starting a new section. | 84 // See if we are starting a new section. |
87 match = _sectionPattern.firstMatch(source); | 85 var match = _sectionPattern.firstMatch(source); |
88 if (match != null) { | 86 if (match != null) { |
89 try { | 87 try { |
90 var condition = Expression.parse(match[1].trim()); | 88 var condition = Expression.parse(match[1].trim()); |
91 | 89 |
92 var errors = <String>[]; | 90 var errors = <String>[]; |
93 condition.validate(errors); | 91 condition.validate(errors); |
94 | 92 |
95 if (errors.isNotEmpty) { | 93 if (errors.isNotEmpty) { |
96 var s = errors.length > 1 ? "s" : ""; | 94 var s = errors.length > 1 ? "s" : ""; |
97 fail('Validation error$s', errors); | 95 fail('Validation error$s', errors); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 .toFilePath(windows: Platform.operatingSystem == "windows")) | 141 .toFilePath(windows: Platform.operatingSystem == "windows")) |
144 .join(new Path("../../../../")); | 142 .join(new Path("../../../../")); |
145 return new Path(_path).relativeTo(repoRoot).toString(); | 143 return new Path(_path).relativeTo(repoRoot).toString(); |
146 } | 144 } |
147 | 145 |
148 /// Returns the issue number embedded in [comment] or `null` if there is none. | 146 /// Returns the issue number embedded in [comment] or `null` if there is none. |
149 int _issueNumber(String comment) { | 147 int _issueNumber(String comment) { |
150 var match = _issuePattern.firstMatch(comment); | 148 var match = _issuePattern.firstMatch(comment); |
151 if (match == null) return null; | 149 if (match == null) return null; |
152 | 150 |
153 return int.parse(match[1], onError: (_) => null); | 151 return int.parse(match[1]); |
154 } | 152 } |
155 | 153 |
156 String toString() { | 154 String toString() { |
157 var buffer = new StringBuffer(); | 155 var buffer = new StringBuffer(); |
158 for (var section in sections) { | 156 for (var section in sections) { |
159 buffer.writeln("[${section._condition}]"); | 157 buffer.writeln("[${section._condition}]"); |
160 | 158 |
161 for (var entry in section.entries) { | 159 for (var entry in section.entries) { |
162 buffer.write("${entry.path}: ${entry.expectations.join(', ')}"); | 160 buffer.write("${entry.path}: ${entry.expectations.join(', ')}"); |
163 if (entry.issue != null) buffer.write(" # Issue ${entry.issue}"); | 161 if (entry.issue != null) buffer.write(" # Issue ${entry.issue}"); |
(...skipping 27 matching lines...) Expand all Loading... |
191 } | 189 } |
192 | 190 |
193 /// Describes the test status of the file or files at a given path. | 191 /// Describes the test status of the file or files at a given path. |
194 class StatusEntry { | 192 class StatusEntry { |
195 final String path; | 193 final String path; |
196 final List<Expectation> expectations; | 194 final List<Expectation> expectations; |
197 final int issue; | 195 final int issue; |
198 | 196 |
199 StatusEntry(this.path, this.expectations, this.issue); | 197 StatusEntry(this.path, this.expectations, this.issue); |
200 } | 198 } |
OLD | NEW |