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

Side by Side Diff: tools/testing/dart/multitest.dart

Issue 8715006: tools/test.dart: Add multitest support to Dart implementation of test runner. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 9 years 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
« no previous file with comments | « no previous file | tools/testing/dart/test_suite.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
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.
4
5 #library("multitest");
6
7 // Multitests are Dart test scripts containing lines of the form
8 // " [some dart code] /// [key]: [error type]"
9 //
10 // For each key in the file, a new test file is made containing all
11 // the normal lines of the file, and all of the multitest lines containing
12 // that key, in the same order as in the source file. The new test
13 // is expected to fail if there is a non-empty error type listed, of
14 // type 'compile-time error', 'runtime error', 'static type error', or
15 // 'dynamic type error'. The type error tests fail only in checked mode.
16 // There is also a test created from only the untagged lines of the file,
17 // with key "none", which is expected to pass. This library extracts these
18 // tests, writes them into a temporary directory, and passes them to the test
19 // runner. These tests may be referred to in the status files with the
20 // pattern [test name]/[key].
21 //
22 // For example: file I_am_a_multitest.dart
23 // aaa
24 // bbb /// 02: runtime error
25 // ccc /// 02: continued
26 // ddd /// 07: static type error
27 // eee
28 //
29 // should create three tests:
30 // I_am_a_multitest_none.dart
31 // aaa
32 // eee
33 //
34 // I_am_a_multitest_02.dart
35 // aaa
36 // bbb /// 02: runtime error
37 // ccc /// 02: continued
38 // eee
39 //
40 // and I_am_a_multitest_07.dart
41 // aaa
42 // ddd /// 07: static type error
43 // eee
44
45 void ExtractTestsFromMultitest(String filename,
46 Map<String, String> tests,
47 Map<String, String> outcomes) {
48 // Read the entire file into a byte buffer and transform it to a
49 // String. This will treat the file as ascii but the only parts
50 // we are interested in will be ascii in any case.
51 File file = new File(filename);
52 file.openSync();
53 List chars = new List(file.lengthSync());
54 int offset = 0;
55 while (offset != chars.length) {
56 offset += file.readListSync(chars, offset, chars.length - offset);
57 }
58 file.closeSync();
59 String contents = new String.fromCharCodes(chars);
60 chars = null;
61 int first_newline = contents.indexOf('\n');
62 final String line_separator =
63 (first_newline == 0 || contents[first_newline - 1] != '\r')
64 ? '\n'
65 : '\r\n';
66 List<String> lines = contents.split(line_separator);
67 if (lines.last() == '') lines.removeLast();
68 contents = null;
69 Set<String> validMultitestOutcomes = new Set<String>.from(
70 ['compile-time error', 'runtime error',
71 'static type error', 'dynamic type error', '']);
72
73 List<String> testTemplate = new List<String>();
74 testTemplate.add('// Test created from multitest named $filename.');
75 // Create the set of multitests, which will have a new test added each
76 // time we see a multitest line with a new key.
77 Map<String, List<String>> testsAsLines = new Map<String, List<String>>();
78
79 for (String line in lines) {
80 if (line.contains('///')) {
81 var parts = line.split('///')[1].split(':');
82 var key = parts[0].trim();
83 var rest = parts[1].trim();
84 if (testsAsLines.containsKey(key)) {
85 Expect.equals('continued', rest);
86 testsAsLines[key].add(line);
87 } else {
88 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line);
89 outcomes[key] = rest;
90 Expect.isTrue(validMultitestOutcomes.contains(rest));
91 }
92 } else {
93 if ((line.startsWith('#import(') || line.startsWith('#source(')) &&
94 !line.contains("dart:")) {
95 // TODO(whesse): Rewrite relative paths to reflect temporary directory.
96 tests = [];
97 outcomes = [];
98 return;
99 }
100 testTemplate.add(line);
101 for (var test in testsAsLines.getValues()) test.add(line);
102 }
103 }
104 // Add the template, with no multitest lines, as a test with key 'none'.
105 testsAsLines['none'] = testTemplate;
106 outcomes['none'] = '';
107
108 // Copy all the tests into the output map tests, as multiline strings.
109 for (String key in testsAsLines.getKeys()) {
110 tests[key] =
111 Strings.join(testsAsLines[key], line_separator) + line_separator;
112 }
113 }
114
115
116 void DoMultitest(String filename,
117 Function doTest(List<String> args,
118 bool isNegative,
119 bool isNegativeIfChecked)) {
120 // Each new test is a single String value in the Map tests.
121 Map<String, String> tests = new Map<String, String>();
122 Map<String, String> outcomes = new Map<String, String>();
123 ExtractTestsFromMultitest(filename, tests, outcomes);
124 String pathSeparator = new Platform().pathSeparator();
125 int start = filename.lastIndexOf(pathSeparator) + 1;
126 int end = filename.indexOf('.dart', start);
127 String baseFilename = filename.substring(start, end);
128 Directory dir = new Directory("");
129 dir.errorHandler =
130 (error) { Expect.fail("Error creating temp directory: $error"); };
131
132 dir.createTempHandler = () {
133 String path = dir.path + new Platform().pathSeparator();
134 Iterator currentKey = tests.getKeys().iterator();
135 WriteMultitestToFileAndQueueIt(tests, outcomes, currentKey,
136 '$path$baseFilename', doTest);
137 };
138
139 dir.createTemp();
140 }
141
142
143 // Write multiple tests to files, using tail recursion in a callback
144 // to serialize the file operations, rather than opening all files at once.
145 WriteMultitestToFileAndQueueIt(Map<String, String> tests,
146 Map<String, String> outcomes,
147 Iterator currentKey,
148 String basePath,
149 Function doTest) {
150 if (!currentKey.hasNext()) return;
151 final String key = currentKey.next();
152 final String filename = '${basePath}_$key.dart';
153 final File file = new File(filename);
154 file.errorHandler = (error) {
155 Expect.fail("Error creating temp file: $error");
156 };
157 file.createHandler = () {
158 file.open(writable: true);
159 };
160 file.openHandler = () {
161 var bytes = tests[key].charCodes();
162 file.writeList(bytes, 0, bytes.length);
163 };
164 file.noPendingWriteHandler =() {
165 file.close();
166 };
167 file.closeHandler = () {
168 var outcome = outcomes[key];
169 bool isNegative = outcome.contains('compile-time error') ||
170 outcome.contains('runtime error');
171 bool isNegativeIfChecked = outcome.contains('type error');
172 doTest(filename, isNegative, isNegativeIfChecked);
173 // TODO(whesse): Register files and directories to be deleted.
174 // They should be registered in a persistent list, so they can
175 // be deleted later even if the test script is interrupted.
176 WriteMultitestToFileAndQueueIt(tests, outcomes, currentKey,
177 basePath, doTest);
178 };
179 file.create();
180 }
OLDNEW
« no previous file with comments | « no previous file | tools/testing/dart/test_suite.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698