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

Side by Side Diff: utils/testrunner/layout_test_controller.dart

Issue 10909240: Support for pixel layout tests. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // The following set of variables should be set by the caller.
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 several comments here: - add copyright notice head
gram 2012/09/20 18:58:03 This is #sourced by the generated Dart file, hence
2 /** Whether to include elapsed time. */
3 bool includeTime;
4
5 /** Path to DRT executable. */
6 String drt;
7
8 /** Whether to regenerate layout test files. */
9 bool regenerate;
10
11 /** Whether to output test summary. */
12 bool summarize;
13
14 /** Format strings to use for test result messages. */
15 String passFormat, failFormat, errorFormat, listFormat;
16
17 /** Location of the running test file. */
18 String sourceDir;
19
20 /** Path of the running test file. */
21 String testfile;
22
23 /** URL of the child test file. */
24 String baseUrl;
25
26 // Variable below here are local to this file.
27 var passCount = 0, failCount = 0, errorCount = 0;
28 Date start;
29
30 void tprint(msg) {
31 print('###$msg');
32 }
33
34 class Macros {
35 static const String testTime = '<TIME>';
36 static const String testfile = '<FILENAME>';
37 static const String testGroup = '<GROUPNAME>';
38 static const String testDescription = '<TESTNAME>';
39 static const String testMessage = '<MESSAGE>';
40 static const String testStacktrace = '<STACK>';
41 }
42
43 String formatMessage(filename, groupname,
44 [ testname = '', testTime = '', result = '',
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 nit: no extra space after [ and before ]
gram 2012/09/20 18:58:03 Done.
45 message = '', stack = '' ]) {
46 var format = errorFormat;
47 if (result == 'pass') format = passFormat;
48 else if (result == 'fail') format = failFormat;
49 return format.
50 replaceAll(Macros.testTime, testTime).
51 replaceAll(Macros.testfile, filename).
52 replaceAll(Macros.testGroup, groupname).
53 replaceAll(Macros.testDescription, testname).
54 replaceAll(Macros.testMessage, message).
55 replaceAll(Macros.testStacktrace, stack);
56 }
57
58 void outputResult(start, label, result, [message = '']) {
59 var idx = label.lastIndexOf('###');
60 var group = '', test = '';
61 if (idx >= 0) {
62 group = '${label.substring(0, idx).replaceAll("###", " ")} ';
63 test = '${label.substring(idx+3)} ';
64 } else {
65 test = '$label ';
66 }
67 var elapsed = '';
68 if (includeTime) {
69 var end = new Date.now();
70 double duration = (end.difference(start)).inMilliseconds.toDouble();
71 duration /= 1000;
72 elapsed = '${duration.toStringAsFixed(3)}s ';
73 }
74 tprint(formatMessage('$testfile ', group, test, elapsed, result, message));
75 }
76
77 pass(start, label) {
78 ++passCount;
79 outputResult(start, label, 'pass');
80 }
81
82 fail(start, label, message) {
83 ++failCount;
84 outputResult(start, label, 'fail', message);
85 }
86
87 error(start, label, message) {
88 ++errorCount;
89 outputResult(start, label, 'error', message);
90 }
91
92 void printSummary(String testFile, int passed, int failed, int errors,
93 [String uncaughtError = '']) {
94 tprint('');
95 if (passed == 0 && failed == 0 && errors == 0) {
96 tprint('$testFile: No tests found.');
97 } else if (failed == 0 && errors == 0 && uncaughtError == null) {
98 tprint('$testFile: All $passed tests passed.');
99 } else {
100 if (uncaughtError != null) {
101 tprint('$testFile: Top-level uncaught error: $uncaughtError');
102 }
103 tprint('$testFile: $passed PASSED, $failed FAILED, $errors ERRORS');
104 }
105 }
106
107 complete() {
108 if (summarize) {
109 printSummary(testfile, passCount, failCount, errorCount);
110 }
111 exit(failCount > -0 ? -1 : 0);
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 -0 ?
gram 2012/09/20 18:58:03 Done.
112 }
113
114 runTextLayoutTest(testNum) {
115 var url = '$baseUrl?test=$testNum';
116 var stdout = new List();
117 start = new Date.now();
118 var process = Process.start(drt, [ url ]);
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 nit: [ url ] => [url] (no spaces)
gram 2012/09/20 18:58:03 Done.
119 StringInputStream stdoutStringStream = new StringInputStream(process.stdout);
120 stdoutStringStream.onLine = () {
121 if (stdoutStringStream.closed) return;
122 var line = stdoutStringStream.readLine();
123 while (null != line) {
124 stdout.add(line);
125 line = stdoutStringStream.readLine();
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 I feel like this logic occurs a lot, is there any
gram 2012/09/20 18:58:03 It would be nice if the IO library had that; I don
Siggi Cherem (dart-lang) 2012/09/20 19:56:27 We could put it in utils.dart for now?
126 }
127 };
128 process.onExit = (exitCode) {
129 process.close();
130 if (stdout.length > 0 && stdout[stdout.length-1].startsWith('#EOF')) {
131 stdout.removeLast();
132 }
133 var done = false;
134 var i = 0;
135 var label = null;
136 var labelMarker = 'CONSOLE MESSAGE: #TEST ';
137 var contentMarker = 'layer at ';
138 while (i < stdout.length) {
139 if (label == null && stdout[i].startsWith(labelMarker)) {
140 label = stdout[i].substring(labelMarker.length);
141 if (label == 'NONEXISTENT') {
142 complete();
143 }
144 } else if (stdout[i].startsWith(contentMarker)) {
145 if (label == null) {
146 complete();
147 }
148 var expectedFileName =
149 '$sourceDir${Platform.pathSeparator}'
150 '${label.replaceAll("###", "_")
151 .replaceAll(const RegExp("[^A-Za-z0-9]"),"_")}.txt';
152 var expected = new File(expectedFileName);
153 if (regenerate) {
154 var ostream = expected.openOutputStream(FileMode.WRITE);
155 while (i < stdout.length) {
156 ostream.writeString(stdout[i]);
157 ostream.writeString('\n');
158 i++;
159 }
160 ostream.close();
161 pass(start, label);
162 } else {
163 if (!expected.existsSync()) {
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 combine with prev line (flatten): } else if (!expe
gram 2012/09/20 18:58:03 Done.
164 fail(start, label, 'No expectation file');
165 } else {
166 var lines = expected.readAsLinesSync();
167 if (lines.length != stdout.length - i) {
168 fail(start, label, 'Expectation file has wrong length');
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 it's still useful to show some diffs in this case
gram 2012/09/20 18:58:03 Done.
169 } else {
170 var match = true;
171 for (var j = 0; j < lines.length; j++) {
172 if (lines[j] != stdout[i+j]) {
173 fail(start, label, 'Expectation differs at line ${j+1}');
174 match = false;
175 break;
176 }
177 }
178 if (match) pass(start, label);
179 }
180 }
181 }
182 done = true;
183 break;
184 }
185 i++;
186 }
187 if (label != null) {
188 if (!done) error(start, label, 'Failed to parse output');
189 runTextLayoutTest(testNum + 1);
190 }
191 };
192 }
193
194 runPixelLayoutTest(int testNum) {
195 var url = '$baseUrl?test=$testNum';
196 var stdout = new List();
197 start = new Date.now();
198 var process = Process.start(drt, [ "$url'-p" ]);
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 nit: [ "$url'-p" ] => ["$url'-p"] (no spaces)
gram 2012/09/20 18:58:03 Done.
199 ListInputStream stdoutStream = process.stdout;
200 stdoutStream.onData = () {
201 if (!stdoutStream.closed) {
202 var data = stdoutStream.read();
203 stdout.addAll(data);
204 }
205 };
206 stdoutStream.onError = (e) {
207 print(e);
208 };
209 process.onExit = (exitCode) {
210 stdout.addAll(process.stdout.read());
211 process.close();
212 var labelMarker = 'CONSOLE MESSAGE: #TEST ';
213 var contentMarker = 'Content-Length: ';
214 var eol = '\n'.charCodeAt(0);
215 var pos = -1;
216 var label = null;
217 var done = false;
218
219 while(pos < stdout.length) {
220 var idx = stdout.indexOf(eol, ++pos);
221 if (idx < 0) break;
222 StringBuffer sb = new StringBuffer();
223 for (var i = pos; i < idx; i++) {
224 sb.addCharCode(stdout[i]);
225 }
226 var line = sb.toString();
227
228 if (label == null && line.startsWith(labelMarker)) {
229 label = line.substring(labelMarker.length);
230 if (label == 'NONEXISTENT') {
231 complete();
232 }
233 } else if (line.startsWith(contentMarker)) {
234 if (label == null) {
235 complete();
236 }
237 var len = int.parse(line.substring(contentMarker.length));
238 pos = idx+1;
Siggi Cherem (dart-lang) 2012/09/20 17:37:27 nit: spaces around +
gram 2012/09/20 18:58:03 Done.
239 var expectedFileName =
240 '$sourceDir${Platform.pathSeparator}'
241 '${label.replaceAll("###","_").
242 replaceAll(const RegExp("[^A-Za-z0-9]"),"_")}.png';
243 var expected = new File(expectedFileName);
244 if (regenerate) {
245 var ostream = expected.openOutputStream(FileMode.WRITE);
246 ostream.writeFrom(stdout, pos, len);
247 ostream.close();
248 pass(start, label);
249 } else {
250 if (!expected.existsSync()) {
251 fail(start, label, 'No expectation file');
252 } else {
253 var bytes = expected.readAsBytesSync();
254 if (bytes.length != len) {
255 fail(start, label, 'Expectation file has wrong length');
256 } else {
257 var match = true;
258 for (var j = 0; j < len; j++) {
259 if (bytes[j] != stdout[pos+j]) {
260 fail(start, label, 'Expectation differs at byte ${j+1}');
261 match = false;
262 break;
263 }
264 }
265 if (match) pass(start, label);
266 }
267 }
268 }
269 done = true;
270 break;
271 }
272 pos = idx;
273 }
274 if (label != null) {
275 if (!done) error(start, label, 'Failed to parse output');
276 runPixelLayoutTest(testNum + 1);
277 }
278 };
279 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698