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 // TODO(jmesserly): this was factored out of | 5 // TODO(jmesserly): this was factored out of |
6 // dart-lang/sdk/tools/testing/dart/multitest.dart | 6 // dart-lang/sdk/tools/testing/dart/multitest.dart |
7 library dev_compiler.test.tools.multitest; | 7 library dev_compiler.test.tools.multitest; |
8 | 8 |
9 final validMultitestOutcomes = new Set<String>.from([ | 9 final validMultitestOutcomes = new Set<String>.from([ |
10 'ok', | 10 'ok', |
11 'compile-time error', | 11 'compile-time error', |
12 'runtime error', | 12 'runtime error', |
13 'static type warning', | 13 'static type warning', |
14 'dynamic type error', | 14 'dynamic type error', |
15 'checked mode compile-time error' | 15 'checked mode compile-time error' |
16 ]); | 16 ]); |
17 | 17 |
18 // Require at least one non-space character before '///' | 18 // Require at least one non-space character before '//#' |
19 final _multiTestRegExp = new RegExp(r"\S */// \w+:(.*)"); | 19 // Handle both //# and the legacy /// multitest regexp patterns. |
Emily Fortuna
2017/03/21 00:49:06
Are you going to have a followup CL where you remo
| |
20 final _multiTestRegExp = new RegExp(r"\S *//[#/] \w+:(.*)"); | |
21 | |
22 final _multiTestRegExpSeperator = new RegExp(r"//[#/]"); | |
20 | 23 |
21 bool isMultiTest(String contents) => _multiTestRegExp.hasMatch(contents); | 24 bool isMultiTest(String contents) => _multiTestRegExp.hasMatch(contents); |
22 | 25 |
23 // Multitests are Dart test scripts containing lines of the form | 26 // Multitests are Dart test scripts containing lines of the form |
24 // " [some dart code] /// [key]: [error type]" | 27 // " [some dart code] /// [key]: [error type]" |
25 // | 28 // |
26 // For each key in the file, a new test file is made containing all | 29 // For each key in the file, a new test file is made containing all |
27 // the normal lines of the file, and all of the multitest lines containing | 30 // the normal lines of the file, and all of the multitest lines containing |
28 // that key, in the same order as in the source file. The new test is expected | 31 // that key, in the same order as in the source file. The new test is expected |
29 // to pass if the error type listed is 'ok', or to fail if there is an error | 32 // to pass if the error type listed is 'ok', or to fail if there is an error |
30 // type of type 'compile-time error', 'runtime error', 'static type warning', or | 33 // type of type 'compile-time error', 'runtime error', 'static type warning', or |
31 // 'dynamic type error'. The type error tests fail only in checked mode. | 34 // 'dynamic type error'. The type error tests fail only in checked mode. |
32 // There is also a test created from only the untagged lines of the file, | 35 // There is also a test created from only the untagged lines of the file, |
33 // with key "none", which is expected to pass. This library extracts these | 36 // with key "none", which is expected to pass. This library extracts these |
34 // tests, writes them into a temporary directory, and passes them to the test | 37 // tests, writes them into a temporary directory, and passes them to the test |
35 // runner. These tests may be referred to in the status files with the | 38 // runner. These tests may be referred to in the status files with the |
36 // pattern [test name]/[key]. | 39 // pattern [test name]/[key]. |
37 // | 40 // |
38 // For example: file I_am_a_multitest.dart | 41 // For example: file I_am_a_multitest.dart |
39 // aaa | 42 // aaa |
40 // bbb /// 02: runtime error | 43 // bbb //# 02: runtime error |
41 // ccc /// 02: continued | 44 // ccc //# 02: continued |
42 // ddd /// 07: static type warning | 45 // ddd //# 07: static type warning |
43 // eee /// 10: ok | 46 // eee //# 10: ok |
44 // fff | 47 // fff |
45 // | 48 // |
46 // should create four tests: | 49 // should create four tests: |
47 // I_am_a_multitest_none.dart | 50 // I_am_a_multitest_none.dart |
48 // aaa | 51 // aaa |
49 // fff | 52 // fff |
50 // | 53 // |
51 // I_am_a_multitest_02.dart | 54 // I_am_a_multitest_02.dart |
52 // aaa | 55 // aaa |
53 // bbb /// 02: runtime error | 56 // bbb //# 02: runtime error |
54 // ccc /// 02: continued | 57 // ccc //# 02: continued |
55 // fff | 58 // fff |
56 // | 59 // |
57 // I_am_a_multitest_07.dart | 60 // I_am_a_multitest_07.dart |
58 // aaa | 61 // aaa |
59 // ddd /// 07: static type warning | 62 // ddd //# 07: static type warning |
60 // fff | 63 // fff |
61 // | 64 // |
62 // and I_am_a_multitest_10.dart | 65 // and I_am_a_multitest_10.dart |
63 // aaa | 66 // aaa |
64 // eee /// 10: ok | 67 // eee //# 10: ok |
65 // fff | 68 // fff |
66 // | 69 // |
67 // Note that it is possible to indicate more than one acceptable outcome | 70 // Note that it is possible to indicate more than one acceptable outcome |
68 // in the case of dynamic and static type warnings | 71 // in the case of dynamic and static type warnings |
69 // aaa | 72 // aaa |
70 // ddd /// 07: static type warning, dynamic type error | 73 // ddd //# 07: static type warning, dynamic type error |
71 // fff | 74 // fff |
72 | 75 |
73 void extractTestsFromMultitest(String filePath, String contents, | 76 void extractTestsFromMultitest(String filePath, String contents, |
74 Map<String, String> tests, Map<String, Set<String>> outcomes) { | 77 Map<String, String> tests, Map<String, Set<String>> outcomes) { |
75 int first_newline = contents.indexOf('\n'); | 78 int first_newline = contents.indexOf('\n'); |
76 final String line_separator = | 79 final String line_separator = |
77 (first_newline == 0 || contents[first_newline - 1] != '\r') | 80 (first_newline == 0 || contents[first_newline - 1] != '\r') |
78 ? '\n' | 81 ? '\n' |
79 : '\r\n'; | 82 : '\r\n'; |
80 List<String> lines = contents.split(line_separator); | 83 List<String> lines = contents.split(line_separator); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 // If a key/multitest was marked for deletion, do the necessary cleanup. | 138 // If a key/multitest was marked for deletion, do the necessary cleanup. |
136 keysToDelete.forEach(outcomes.remove); | 139 keysToDelete.forEach(outcomes.remove); |
137 keysToDelete.forEach(testsAsLines.remove); | 140 keysToDelete.forEach(testsAsLines.remove); |
138 | 141 |
139 // Copy all the tests into the output map tests, as multiline strings. | 142 // Copy all the tests into the output map tests, as multiline strings. |
140 for (String key in testsAsLines.keys) { | 143 for (String key in testsAsLines.keys) { |
141 tests[key] = testsAsLines[key].join(line_separator); | 144 tests[key] = testsAsLines[key].join(line_separator); |
142 } | 145 } |
143 } | 146 } |
144 | 147 |
145 // Represents a mutlitest annotation in the special /// comment. | 148 // Represents a mutlitest annotation in the special //# comment. |
146 class _Annotation { | 149 class _Annotation { |
147 String key; | 150 String key; |
148 String rest; | 151 String rest; |
149 List<String> outcomesList; | 152 List<String> outcomesList; |
150 _Annotation() {} | 153 _Annotation() {} |
151 factory _Annotation.from(String line) { | 154 factory _Annotation.from(String line) { |
152 // Do an early return with "null" if this is not a valid multitest | 155 // Do an early return with "null" if this is not a valid multitest |
153 // annotation. | 156 // annotation. |
154 if (!line.contains('///')) { | 157 if (!line.contains(_multiTestRegExpSeperator)) { |
155 return null; | 158 return null; |
156 } | 159 } |
157 var parts = line | 160 var parts = line |
158 .split('///')[1] | 161 .split(_multiTestRegExpSeperator)[1] |
159 .split(':') | 162 .split(':') |
160 .map((s) => s.trim()) | 163 .map((s) => s.trim()) |
161 .where((s) => s.length > 0) | 164 .where((s) => s.length > 0) |
162 .toList(); | 165 .toList(); |
163 if (parts.length <= 1) { | 166 if (parts.length <= 1) { |
164 return null; | 167 return null; |
165 } | 168 } |
166 | 169 |
167 var annotation = new _Annotation(); | 170 var annotation = new _Annotation(); |
168 annotation.key = parts[0]; | 171 annotation.key = parts[0]; |
169 annotation.rest = parts[1]; | 172 annotation.rest = parts[1]; |
170 annotation.outcomesList = | 173 annotation.outcomesList = |
171 annotation.rest.split(',').map((s) => s.trim()).toList(); | 174 annotation.rest.split(',').map((s) => s.trim()).toList(); |
172 return annotation; | 175 return annotation; |
173 } | 176 } |
174 } | 177 } |
OLD | NEW |