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

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

Issue 9565001: Enable use of #import stmts containing relative paths in Dart multitests (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 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 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("multitest"); 5 #library("multitest");
6 6
7 #import("dart:io"); 7 #import("dart:io");
8 8
9 // Multitests are Dart test scripts containing lines of the form 9 // Multitests are Dart test scripts containing lines of the form
10 // " [some dart code] /// [key]: [error type]" 10 // " [some dart code] /// [key]: [error type]"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 Set<String> validMultitestOutcomes = new Set<String>.from( 70 Set<String> validMultitestOutcomes = new Set<String>.from(
71 ['compile-time error', 'runtime error', 71 ['compile-time error', 'runtime error',
72 'static type error', 'dynamic type error', '']); 72 'static type error', 'dynamic type error', '']);
73 73
74 List<String> testTemplate = new List<String>(); 74 List<String> testTemplate = new List<String>();
75 testTemplate.add('// Test created from multitest named $filename.'); 75 testTemplate.add('// Test created from multitest named $filename.');
76 // Create the set of multitests, which will have a new test added each 76 // Create the set of multitests, which will have a new test added each
77 // time we see a multitest line with a new key. 77 // time we see a multitest line with a new key.
78 Map<String, List<String>> testsAsLines = new Map<String, List<String>>(); 78 Map<String, List<String>> testsAsLines = new Map<String, List<String>>();
79 79
80 // Matches #import( or #source( followed by " or ' followed by anything
81 // except dart: or /, at the beginning of a line.
82 RegExp relativeImportRegExp =
83 const RegExp('^#(import|source)[(]["\'](?!(dart:|/))');
84 int lineCount = 0; 80 int lineCount = 0;
85 for (String line in lines) { 81 for (String line in lines) {
86 lineCount++; 82 lineCount++;
87 if (line.contains('///')) { 83 if (line.contains('///')) {
88 var parts = line.split('///')[1].split(':'); 84 var parts = line.split('///')[1].split(':');
89 var key = parts[0].trim(); 85 var key = parts[0].trim();
90 var rest = parts[1].trim(); 86 var rest = parts[1].trim();
91 if (testsAsLines.containsKey(key)) { 87 if (testsAsLines.containsKey(key)) {
92 Expect.equals('continued', rest); 88 Expect.equals('continued', rest);
93 testsAsLines[key].add(line); 89 testsAsLines[key].add(line);
94 } else { 90 } else {
95 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line); 91 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line);
96 outcomes[key] = rest; 92 outcomes[key] = rest;
97 if (!validMultitestOutcomes.contains(rest)) { 93 if (!validMultitestOutcomes.contains(rest)) {
98 Expect.fail("Invalid test directive on line ${lineCount}: $rest "); 94 Expect.fail("Invalid test directive on line ${lineCount}: $rest ");
99 } 95 }
100 } 96 }
101 } else { 97 } else {
102 testTemplate.add(line); 98 testTemplate.add(line);
103 for (var test in testsAsLines.getValues()) test.add(line); 99 for (var test in testsAsLines.getValues()) test.add(line);
104 } 100 }
105 // Warn if any import or source tags have relative paths.
106 if (relativeImportRegExp.hasMatch(line)) {
107 print('Warning: Multitest cannot contain relative imports:');
108 print(' $filename: $line');
109 }
110 } 101 }
111 // Add the template, with no multitest lines, as a test with key 'none'. 102 // Add the template, with no multitest lines, as a test with key 'none'.
112 testsAsLines['none'] = testTemplate; 103 testsAsLines['none'] = testTemplate;
113 outcomes['none'] = ''; 104 outcomes['none'] = '';
114 105
115 // Copy all the tests into the output map tests, as multiline strings. 106 // Copy all the tests into the output map tests, as multiline strings.
116 for (String key in testsAsLines.getKeys()) { 107 for (String key in testsAsLines.getKeys()) {
117 tests[key] = 108 tests[key] =
118 Strings.join(testsAsLines[key], line_separator) + line_separator; 109 Strings.join(testsAsLines[key], line_separator) + line_separator;
119 } 110 }
120 } 111 }
121 112
113 void _copyFile(File source, File dest) {
zundel 2012/03/01 06:06:58 is there already a canned way to do this somewhere
Bill Hesse 2012/03/01 15:01:52 Not that I know of, except by calling the shell.
zundel 2012/03/01 18:06:01 Moved to TestUtils class.
114 List contents = source.readAsBytesSync();
115 RandomAccessFile handle = dest.openSync(FileMode.WRITE);
Bill Hesse 2012/03/01 15:01:52 This will not work except for files in the same di
zundel 2012/03/01 18:06:01 the generated test files don't go away between tes
116 handle.writeListSync(contents, 0, contents.length);
117 handle.closeSync();
118 }
119
120 // Find all relative imports and copy them into the dir that contains
121 // the generated tests.
122 Set<String> _findAllRelativeImports(String topLibrary) {
123 Set<String> toSearch = new Set<String>.from([topLibrary]);
124 Set<String> foundImports = new HashSet<String>();
125 String pathSep = new Platform().pathSeparator();
Bill Hesse 2012/03/01 15:01:52 Rather than use pathSeparator, I would use "/" eve
zundel 2012/03/01 18:06:01 Done.
126 int end = topLibrary.lastIndexOf(pathSep);
127 String libraryDir = topLibrary.substring(0, end);
128
129 // Matches #import( or #source( followed by " or ' followed by anything
130 // except dart: or /, at the beginning of a line.
131 RegExp relativeImportRegExp1 =
132 const RegExp('^#(import|source)[(]["\'](?!(dart:|/))');
133 // Like the above, but captures the path in the import
134 RegExp relativeImportRegExp2 =
135 const RegExp('^#(import|source)[(]["\']([^"\']*)["\']');
136 while (!toSearch.isEmpty()) {
137 var thisPass = toSearch;
138 toSearch = new HashSet<String>();
139 for (String filename in thisPass) {
140 File f = new File(filename);
141 for (String line in f.readAsLinesSync()) {
142 if (relativeImportRegExp1.hasMatch(line)) {
Bill Hesse 2012/03/01 15:01:52 I think you can combine the two regexp to '.....
zundel 2012/03/01 18:06:01 i've never used the non-capturing before, but it d
143 // remember relative import so we can copy it later
144 Match match = relativeImportRegExp2.firstMatch(line);
145 String relativePath = match.group(2);
146 if (foundImports.contains(relativePath)) {
147 continue;
148 }
149 foundImports.add(relativePath);
150 toSearch.add('$libraryDir$pathSep$relativePath');
151 }
152 }
153 }
154 }
155 return foundImports;
156 }
122 157
123 void DoMultitest(String filename, 158 void DoMultitest(String filename,
124 String outputDir, 159 String outputDir,
125 String testDir, 160 String testDir,
126 Function doTest(String filename, 161 Function doTest(String filename,
127 bool isNegative, 162 bool isNegative,
128 [bool isNegativeIfChecked, 163 [bool isNegativeIfChecked,
129 bool hasFatalTypeErrors, 164 bool hasFatalTypeErrors,
130 bool hasRuntimeErrors]), 165 bool hasRuntimeErrors]),
131 Function multitestDone) { 166 Function multitestDone) {
132 // Each new test is a single String value in the Map tests. 167 // Each new test is a single String value in the Map tests.
133 Map<String, String> tests = new Map<String, String>(); 168 Map<String, String> tests = new Map<String, String>();
134 Map<String, String> outcomes = new Map<String, String>(); 169 Map<String, String> outcomes = new Map<String, String>();
170 Set<String> importsToCopy = new Set<String>();
Bill Hesse 2012/03/01 15:01:52 This initializer is overwritten - can be omitted.
zundel 2012/03/01 18:06:01 Done.
135 ExtractTestsFromMultitest(filename, tests, outcomes); 171 ExtractTestsFromMultitest(filename, tests, outcomes);
136 172
137 String directory = CreateMultitestDirectory(outputDir, testDir); 173 String directory = CreateMultitestDirectory(outputDir, testDir);
Bill Hesse 2012/03/01 15:01:52 extra space before testDir?
zundel 2012/03/01 18:06:01 Done.
138 String pathSeparator = new Platform().pathSeparator(); 174 Expect.isNotNull(directory);
139 int start = filename.lastIndexOf(pathSeparator) + 1; 175 String pathSep = new Platform().pathSeparator();
176 int start = filename.lastIndexOf(pathSep) + 1;
140 int end = filename.indexOf('.dart', start); 177 int end = filename.indexOf('.dart', start);
141 String baseFilename = filename.substring(start, end); 178 String baseFilename = filename.substring(start, end);
179 String sourceDirectory = filename.substring(0, start - 1);
180 importsToCopy = _findAllRelativeImports(filename);
181 for (String import in importsToCopy) {
182 File source = new File('$sourceDirectory$pathSep$import');
Bill Hesse 2012/03/01 15:01:52 Again, no need for $pathSep. "/" works on all pla
zundel 2012/03/01 18:06:01 Done.
183 // assumes no subdirs
184 var dest = new File('$directory$pathSep$import');
185 _copyFile(source, dest);
186 }
142 for (String key in tests.getKeys()) { 187 for (String key in tests.getKeys()) {
143 final String filename = '$directory/${baseFilename}_$key.dart'; 188 final String filename = '$directory/${baseFilename}_$key.dart';
144 final File file = new File(filename); 189 final File file = new File(filename);
145 190
146 file.createSync(); 191 file.createSync();
147 RandomAccessFile openedFile = file.openSync(FileMode.WRITE); 192 RandomAccessFile openedFile = file.openSync(FileMode.WRITE);
148 var bytes = tests[key].charCodes(); 193 var bytes = tests[key].charCodes();
149 openedFile.writeListSync(bytes, 0, bytes.length); 194 openedFile.writeListSync(bytes, 0, bytes.length);
150 openedFile.closeSync(); 195 openedFile.closeSync();
151 var outcome = outcomes[key]; 196 var outcome = outcomes[key];
(...skipping 24 matching lines...) Expand all
176 var split = testDir.split('/'); 221 var split = testDir.split('/');
177 var lastComponent = split.removeLast(); 222 var lastComponent = split.removeLast();
178 Expect.isTrue(lastComponent == 'src'); 223 Expect.isTrue(lastComponent == 'src');
179 String path = '${generatedTestDir.path}/${split.last()}'; 224 String path = '${generatedTestDir.path}/${split.last()}';
180 Directory dir = new Directory(path); 225 Directory dir = new Directory(path);
181 if (!dir.existsSync()) { 226 if (!dir.existsSync()) {
182 dir.createSync(); 227 dir.createSync();
183 } 228 }
184 return path; 229 return path;
185 } 230 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698