Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library status_file_parser; | 5 library status_file_parser; |
| 6 | 6 |
| 7 import "dart:async"; | 7 import "dart:async"; |
| 8 import "dart:io"; | 8 import "dart:io"; |
| 9 import "status_expression.dart"; | 9 import "status_expression.dart"; |
| 10 | 10 |
| 11 /** Possible outcomes of running a test. */ | 11 /** Possible outcomes of running a test. */ |
| 12 const CRASH = "crash"; | 12 const CRASH = "crash"; |
| 13 const TIMEOUT = "timeout"; | 13 const TIMEOUT = "timeout"; |
| 14 const FAIL = "fail"; | 14 const FAIL = "fail"; |
| 15 const PASS = "pass"; | 15 const PASS = "pass"; |
| 16 /** | 16 /** |
| 17 * An indication to skip the test. The caller is responsible for skipping it. | 17 * An indication to skip the test. The caller is responsible for skipping it. |
| 18 */ | 18 */ |
| 19 const SKIP = "skip"; | 19 const SKIP = "skip"; |
| 20 const OK = "ok"; | 20 const OK = "ok"; |
| 21 /** | 21 /** |
| 22 * An indication that a test is slow and we should allow extra time for | 22 * An indication that a test is slow and we should allow extra time for |
| 23 * completion. | 23 * completion. |
| 24 */ | 24 */ |
| 25 const SLOW = "slow"; | 25 const SLOW = "slow"; |
| 26 | 26 |
| 27 final RegExp StripComment = new RegExp("^[^#]*"); | 27 final RegExp SplitComment = new RegExp("(^[^#]*)(:?#(.*))?"); |
|
kustermann
2013/08/20 14:29:56
"(^[^#]*)(:?#(.*))?" --> "^([^#]*)(#.*)?$" ?
Th
Søren Gjesse
2013/08/20 14:55:49
Done. I only did it the other way to avoid having
| |
| 28 final RegExp HeaderPattern = new RegExp(r"^\[([^\]]+)\]"); | 28 final RegExp HeaderPattern = new RegExp(r"^\[([^\]]+)\]"); |
| 29 final RegExp RulePattern = new RegExp(r"\s*([^: ]*)\s*:(.*)"); | 29 final RegExp RulePattern = new RegExp(r"\s*([^: ]*)\s*:(.*)"); |
| 30 final RegExp IssueNumberPattern = | |
| 31 new RegExp("Issue ([0-9]+)|dartbug.com/([0-9]+)", caseSensitive: false); | |
|
kustermann
2013/08/20 14:29:56
I think there are more patterns, like:
"Issue: 12
Søren Gjesse
2013/08/20 14:55:49
I know, but I think we should stick to these two,
| |
| 30 | 32 |
| 31 // TODO(whesse): Implement configuration_info library that contains data | 33 // TODO(whesse): Implement configuration_info library that contains data |
| 32 // structures for test configuration, including Section. | 34 // structures for test configuration, including Section. |
| 33 class Section { | 35 class Section { |
| 34 BooleanExpression condition; | 36 BooleanExpression condition; |
| 35 List<TestRule> testRules; | 37 List<TestRule> testRules; |
| 36 | 38 |
| 37 Section.always() : condition = null, testRules = new List<TestRule>(); | 39 Section.always() : condition = null, testRules = new List<TestRule>(); |
| 38 Section(this.condition) : testRules = new List<TestRule>(); | 40 Section(this.condition) : testRules = new List<TestRule>(); |
| 39 | 41 |
| 40 bool isEnabled(environment) => | 42 bool isEnabled(environment) => |
| 41 condition == null || condition.evaluate(environment); | 43 condition == null || condition.evaluate(environment); |
| 44 | |
| 45 String toString() { | |
| 46 return "Section: $condition"; | |
| 47 } | |
| 42 } | 48 } |
| 43 | 49 |
| 44 void ReadTestExpectationsInto(TestExpectations expectations, | 50 void ReadTestExpectationsInto(TestExpectations expectations, |
| 45 String statusFilePath, | 51 String statusFilePath, |
| 46 environment, | 52 environment, |
| 47 onDone) { | 53 onDone) { |
| 48 List<Section> sections = new List<Section>(); | 54 List<Section> sections = new List<Section>(); |
| 49 | 55 |
| 50 void sectionsRead() { | 56 void sectionsRead() { |
| 51 for (Section section in sections) { | 57 for (Section section in sections) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 68 } | 74 } |
| 69 Stream<String> lines = | 75 Stream<String> lines = |
| 70 file.openRead() | 76 file.openRead() |
| 71 .transform(new StringDecoder()) | 77 .transform(new StringDecoder()) |
| 72 .transform(new LineTransformer()); | 78 .transform(new LineTransformer()); |
| 73 | 79 |
| 74 Section current = new Section.always(); | 80 Section current = new Section.always(); |
| 75 sections.add(current); | 81 sections.add(current); |
| 76 | 82 |
| 77 lines.listen((String line) { | 83 lines.listen((String line) { |
| 78 Match match = StripComment.firstMatch(line); | 84 Match match = SplitComment.firstMatch(line); |
| 79 line = (match == null) ? "" : match[0]; | 85 line = (match == null) ? "" : match[1]; |
| 80 line = line.trim(); | 86 line = line.trim(); |
| 81 if (line.isEmpty) return; | 87 if (line.isEmpty) return; |
| 82 | 88 |
| 89 // Extract the comment to get the issue number if needed. | |
| 90 String comment = (match == null || match[2] == null) ? "" : match[2]; | |
| 91 | |
| 83 match = HeaderPattern.firstMatch(line); | 92 match = HeaderPattern.firstMatch(line); |
| 84 if (match != null) { | 93 if (match != null) { |
| 85 String condition_string = match[1].trim(); | 94 String condition_string = match[1].trim(); |
| 86 List<String> tokens = new Tokenizer(condition_string).tokenize(); | 95 List<String> tokens = new Tokenizer(condition_string).tokenize(); |
| 87 ExpressionParser parser = new ExpressionParser(new Scanner(tokens)); | 96 ExpressionParser parser = new ExpressionParser(new Scanner(tokens)); |
| 88 current = new Section(parser.parseBooleanExpression()); | 97 current = new Section(parser.parseBooleanExpression()); |
| 89 sections.add(current); | 98 sections.add(current); |
| 90 return; | 99 return; |
| 91 } | 100 } |
| 92 | 101 |
| 93 match = RulePattern.firstMatch(line); | 102 match = RulePattern.firstMatch(line); |
| 94 if (match != null) { | 103 if (match != null) { |
| 95 String name = match[1].trim(); | 104 String name = match[1].trim(); |
| 96 // TODO(whesse): Handle test names ending in a wildcard (*). | 105 // TODO(whesse): Handle test names ending in a wildcard (*). |
| 97 String expression_string = match[2].trim(); | 106 String expression_string = match[2].trim(); |
| 98 List<String> tokens = new Tokenizer(expression_string).tokenize(); | 107 List<String> tokens = new Tokenizer(expression_string).tokenize(); |
| 99 SetExpression expression = | 108 SetExpression expression = |
| 100 new ExpressionParser(new Scanner(tokens)).parseSetExpression(); | 109 new ExpressionParser(new Scanner(tokens)).parseSetExpression(); |
| 101 current.testRules.add(new TestRule(name, expression)); | 110 |
| 111 // Look for issue number in comment. | |
| 112 String issueString = null; | |
| 113 match = IssueNumberPattern.firstMatch(comment); | |
| 114 if (match != null) { | |
| 115 issueString = match[1]; | |
| 116 if (issueString == null) issueString = match[2]; | |
|
kustermann
2013/08/20 14:29:56
Are you sure that if a optional group was not matc
Søren Gjesse
2013/08/20 14:55:49
Yes - I tested it manually.
| |
| 117 } | |
| 118 int issue = issueString != null ? int.parse(issueString) : null; | |
| 119 current.testRules.add(new TestRule(name, expression, issue)); | |
| 102 return; | 120 return; |
| 103 } | 121 } |
| 104 | 122 |
| 105 print("unmatched line: $line"); | 123 print("unmatched line: $line"); |
| 106 }, | 124 }, |
| 107 onDone: onDone); | 125 onDone: onDone); |
| 108 } | 126 } |
| 109 | 127 |
| 110 | 128 |
| 111 class TestRule { | 129 class TestRule { |
| 112 String name; | 130 String name; |
| 113 SetExpression expression; | 131 SetExpression expression; |
| 132 int issue; | |
| 114 | 133 |
| 115 TestRule(this.name, this.expression); | 134 TestRule(this.name, this.expression, this.issue); |
| 116 | 135 |
| 117 String toString() => 'TestRule($name, $expression)'; | 136 bool get hasIssue => issue != null; |
| 137 | |
| 138 String toString() => 'TestRule($name, $expression, $issue)'; | |
| 118 } | 139 } |
| 119 | 140 |
| 120 | 141 |
| 121 class TestExpectations { | 142 class TestExpectations { |
| 122 Map _map; | 143 Map _map; |
| 123 bool _preprocessed = false; | 144 bool _preprocessed = false; |
| 124 Map _regExpCache; | 145 Map _regExpCache; |
| 125 Map _keyToRegExps; | 146 Map _keyToRegExps; |
| 126 | 147 |
| 127 /** | 148 /** |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 } | 224 } |
| 204 regExps[i] = regExp; | 225 regExps[i] = regExp; |
| 205 } | 226 } |
| 206 _keyToRegExps[key] = regExps; | 227 _keyToRegExps[key] = regExps; |
| 207 }); | 228 }); |
| 208 | 229 |
| 209 _regExpCache = null; | 230 _regExpCache = null; |
| 210 _preprocessed = true; | 231 _preprocessed = true; |
| 211 } | 232 } |
| 212 } | 233 } |
| OLD | NEW |