| 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 |