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

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

Issue 10914049: Added support for layout render tests. These use expected values for the text render output from Du… (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
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 /** A pipeline task for running DumpRenderTree. */ 5 /** A pipeline task for running DumpRenderTree. */
6 class DrtTask extends RunProcessTask { 6 class DrtTask extends RunProcessTask {
7 7
8 DrtTask(String htmlFileTemplate) { 8 String _testFileTemplate;
9
10 DrtTask(this._testFileTemplate, String htmlFileTemplate) {
9 init(config.drtPath, ['--no-timeout', htmlFileTemplate], config.timeout); 11 init(config.drtPath, ['--no-timeout', htmlFileTemplate], config.timeout);
10 } 12 }
13
14 var testLabelLinePrefix = ' text run';
Siggi Cherem (dart-lang) 2012/09/05 17:45:41 since these are constant: mark these two as `stati
gram 2012/09/06 18:25:25 Done.
15 var bodyLinePrefix = ' ';
Siggi Cherem (dart-lang) 2012/09/05 17:45:41 I'm not sure I understand this parsing and why is
gram 2012/09/06 18:25:25 I added a comment that hopefully explains this.
16
17 void execute(Path testfile, List stdout, List stderr, bool logging,
18 Function exitHandler) {
19
20 var testname = expandMacros(_testFileTemplate, testfile);
21 var isLayout = isLayoutRenderTest(testname) || config.generateRenders;
22
23 if (!isLayout) {
24 super.execute(testfile, stdout, stderr, logging, exitHandler);
25 } else {
26 var tmpLog = new List<String>();
27 super.execute(testfile, tmpLog, tmpLog, true,
28 (code) {
29 var layoutFile = layoutFileName(testname);
30 var layouts = getFileContents(layoutFile, false);
31 var i = 0;
32 StringBuffer sbuf = null;
33 if (config.generateRenders) {
34 sbuf = new StringBuffer();
35 }
36 while ( i < tmpLog.length) {
37 var line = tmpLog[i];
38 if (logging) {
39 stdout.add(line);
40 }
41 if (line.startsWith(testLabelLinePrefix)) {
42 var j = i+1;
43 var start = -1, end = -1;
44 // Walk forward to the next label or end of log.
45 while (j < tmpLog.length &&
46 !tmpLog[j].startsWith(testLabelLinePrefix)) {
47 // Is this a body render line?
48 if (tmpLog[j].startsWith(bodyLinePrefix)) {
49 if (start < 0) { // Is it the first?
50 start = j;
51 }
52 } else { // Not a render line.
53 if (start >= 0 && end < 0) {
54 // We were just in a set of render lines, so this
55 // line is the first non-member.
56 end = j;
57 }
58 }
59 j++;
60 }
61 if (start >= 0) { // We have some render lines.
62 if (end < 0) {
63 end = tmpLog.length; // Sanity.
64 }
65 var actualLayout = new List<String>();
66 while (start < end) {
67 actualLayout.add(
68 tmpLog[start++].substring(bodyLinePrefix.length));
69 }
70 var testName = checkTest(testfile, line, layouts,
71 actualLayout, stdout);
72 if (testName == null) {
73 code = -1;
74 } else if (config.generateRenders) {
75 sbuf.add(testName);
76 sbuf.add('\n');
77 for (var renderLine in actualLayout) {
78 sbuf.add(renderLine);
79 sbuf.add('\n');
80 }
81 }
82 }
83 i = j;
84 } else {
85 i++;
86 }
87 }
88 if (config.generateRenders) {
89 createFile(layoutFile, sbuf.toString());
90 }
91 exitHandler(code);
92 });
93 }
94 }
95
96 /**
97 * Verify whether a test passed - it must pass the code expectations,
98 * and have validated layout. Report success or failure in a test
99 * result message. Upon success the render section name is returned
100 * (useful for `config.generateRenders`); otherwise null is returned.
101 */
102 String checkTest(Path testfile, String label, List layouts,
103 List actual, List out) {
104 var testGroup = null;
105 var testName = null;
106
107 // The label line has the form:
108 // "result:duration:<test>//message"
109 // where <test> is a test name or series of one or more group names
110 // followed by a test name, separated by ###.
111
112 // First extract test state, duration, name and message. If the test
113 // passed we can ignore these and continue to layout verification, but
114 // if the test failed we want to know that so we can report failure.
115 //
116 // TODO(gram) - currently we lose the stack trace although the user
117 // will get it in the overall output if they used --verbose. We may
118 // want to fix this properly at some point.
119
120 // Trim leading text up to opening quote.
121 var idx = label.indexOf('"');
Siggi Cherem (dart-lang) 2012/09/05 17:45:41 please use regex here.
gram 2012/09/06 18:25:25 Done.
122 label = label.substring(idx+1);
123
124 // Extract the result.
125 idx = label.indexOf(':');
126 var result = label.substring(0, idx);
127
128 // Extract the duration.
129 ++idx;
130 var idx2 = label.indexOf(':', idx);
131 var duration = parseDouble(label.substring(idx, idx2)) / 1000;
132
133 // Extract the test groups and name, and the message.
134 idx = idx2+1;
135 idx2 = label.indexOf('//', idx);
136 var test = label.substring(idx, idx2);
137 var message = label.substring(idx2+2, label.length-1);
138
139 // Split name up with group.
140 idx = test.lastIndexOf('###');
141 if (idx >= 0) {
142 testGroup = test.substring(0, idx).replaceAll('###', ' ');
143 testName = test.substring(idx+3);
144 } else {
145 testGroup = '';
146 testName = test;
147 }
148 var section = '[${_pad(testGroup)}$testName]';
149
150 if (config.generateRenders) {
151 // Do nothing; fake a pass.
152 out.add(_formatMessage(config.passFormat,
153 testfile, testGroup, testName, duration, ''));
154 } else if (result != 'pass') {
155 // The test failed separately from layout; just report that
156 // failure.
157 out.add(_formatMessage(
158 (result == 'fail' ? config.failFormat : config.errorFormat),
159 testfile, testGroup, testName, duration, message));
160 return null;
161 } else {
162 // The test passed, at least the expectations. So check the layout.
163 var expected = _getLayout(layouts, section);
164 var failMessage = null;
165 var lineNum = 0;
166 if (expected != null) {
167 while (lineNum < expected.length) {
168 if (lineNum >= actual.length) {
169 failMessage = 'expected "${expected[lineNum]}" but got nothing';
170 break;
171 } else {
172 if (expected[lineNum] != actual[lineNum]) {
173 failMessage = 'expected "${expected[lineNum]}" '
174 'but got "${actual[lineNum]}"';
175 break;
176 }
177 }
178 lineNum++;
179 }
180 if (failMessage == null && lineNum < actual.length) {
181 failMessage = 'expected nothing but got "${actual[lineNum]}"';
182 }
183 }
184 if (failMessage != null) {
185 out.add(_formatMessage(config.failFormat,
186 testfile, testGroup, testName, duration,
187 'Layout content mismatch at line $lineNum: '
188 '$failMessage'));
189 return null;
190 } else {
191 out.add(_formatMessage(config.passFormat,
192 testfile, testGroup, testName, duration, ''));
193 }
194 }
195 return section;
196 }
197
198 /** Get the expected layout for a test. */
199 List _getLayout(List layouts, String section) {
200 List layout = new List();
201 for (var i = 0; i < layouts.length; i++) {
202 if (layouts[i] == section) {
203 ++i;
204 while (i < layouts.length && !layouts[i].startsWith('[')) {
205 layout.add(layouts[i++]);
206 }
207 break;
208 }
209 }
210 return layout;
211 }
212
213 /** Pad a string with a rightmost space unless it is empty. */
214 String _pad(s) => (s.length > 0) ? '$s ' : s;
Siggi Cherem (dart-lang) 2012/09/05 17:45:41 +static
gram 2012/09/06 18:25:25 Done.
215
216 /** Format a test result message. */
217 String _formatMessage(String format,
218 Path testfile, String testGroup, String testName,
219 double duration, String message) {
220 String fname = makePathAbsolute(testfile.directoryPath.toString());
221 return "###${format.
222 replaceAll(Macros.testTime, '${duration.toStringAsFixed(3)}s ').
223 replaceAll(Macros.testfile, _pad(fname)).
224 replaceAll(Macros.testGroup, _pad(testGroup)).
225 replaceAll(Macros.testDescription, _pad(testName)).
226 replaceAll(Macros.testMessage, _pad(message))}";
227 }
11 } 228 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698