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

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

Issue 9583016: Re-apply "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 | tools/testing/dart/test_suite.dart » ('j') | tools/testing/dart/test_suite.dart » ('J')
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 #import("test_suite.dart");
8 9
9 // Multitests are Dart test scripts containing lines of the form 10 // Multitests are Dart test scripts containing lines of the form
10 // " [some dart code] /// [key]: [error type]" 11 // " [some dart code] /// [key]: [error type]"
11 // 12 //
12 // For each key in the file, a new test file is made containing all 13 // For each key in the file, a new test file is made containing all
13 // the normal lines of the file, and all of the multitest lines containing 14 // the normal lines of the file, and all of the multitest lines containing
14 // that key, in the same order as in the source file. The new test 15 // that key, in the same order as in the source file. The new test
15 // is expected to fail if there is a non-empty error type listed, of 16 // is expected to fail if there is a non-empty error type listed, of
16 // type 'compile-time error', 'runtime error', 'static type error', or 17 // type 'compile-time error', 'runtime error', 'static type error', or
17 // 'dynamic type error'. The type error tests fail only in checked mode. 18 // 'dynamic type error'. The type error tests fail only in checked mode.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 Set<String> validMultitestOutcomes = new Set<String>.from( 71 Set<String> validMultitestOutcomes = new Set<String>.from(
71 ['compile-time error', 'runtime error', 72 ['compile-time error', 'runtime error',
72 'static type error', 'dynamic type error', '']); 73 'static type error', 'dynamic type error', '']);
73 74
74 List<String> testTemplate = new List<String>(); 75 List<String> testTemplate = new List<String>();
75 testTemplate.add('// Test created from multitest named $filename.'); 76 testTemplate.add('// Test created from multitest named $filename.');
76 // Create the set of multitests, which will have a new test added each 77 // Create the set of multitests, which will have a new test added each
77 // time we see a multitest line with a new key. 78 // time we see a multitest line with a new key.
78 Map<String, List<String>> testsAsLines = new Map<String, List<String>>(); 79 Map<String, List<String>> testsAsLines = new Map<String, List<String>>();
79 80
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; 81 int lineCount = 0;
85 for (String line in lines) { 82 for (String line in lines) {
86 lineCount++; 83 lineCount++;
87 if (line.contains('///')) { 84 if (line.contains('///')) {
88 var parts = line.split('///')[1].split(':'); 85 var parts = line.split('///')[1].split(':');
89 var key = parts[0].trim(); 86 var key = parts[0].trim();
90 var rest = parts[1].trim(); 87 var rest = parts[1].trim();
91 if (testsAsLines.containsKey(key)) { 88 if (testsAsLines.containsKey(key)) {
92 Expect.equals('continued', rest); 89 Expect.equals('continued', rest);
93 testsAsLines[key].add(line); 90 testsAsLines[key].add(line);
94 } else { 91 } else {
95 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line); 92 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line);
96 outcomes[key] = rest; 93 outcomes[key] = rest;
97 if (!validMultitestOutcomes.contains(rest)) { 94 if (!validMultitestOutcomes.contains(rest)) {
98 Expect.fail("Invalid test directive on line ${lineCount}: $rest "); 95 Expect.fail("Invalid test directive on line ${lineCount}: $rest ");
99 } 96 }
100 } 97 }
101 } else { 98 } else {
102 testTemplate.add(line); 99 testTemplate.add(line);
103 for (var test in testsAsLines.getValues()) test.add(line); 100 for (var test in testsAsLines.getValues()) test.add(line);
104 } 101 }
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 } 102 }
111 // Add the template, with no multitest lines, as a test with key 'none'. 103 // Add the template, with no multitest lines, as a test with key 'none'.
112 testsAsLines['none'] = testTemplate; 104 testsAsLines['none'] = testTemplate;
113 outcomes['none'] = ''; 105 outcomes['none'] = '';
114 106
115 // Copy all the tests into the output map tests, as multiline strings. 107 // Copy all the tests into the output map tests, as multiline strings.
116 for (String key in testsAsLines.getKeys()) { 108 for (String key in testsAsLines.getKeys()) {
117 tests[key] = 109 tests[key] =
118 Strings.join(testsAsLines[key], line_separator) + line_separator; 110 Strings.join(testsAsLines[key], line_separator) + line_separator;
119 } 111 }
120 } 112 }
121 113
114 // Find all relative imports and copy them into the dir that contains
115 // the generated tests.
116 Set<String> _findAllRelativeImports(String topLibrary) {
117 Set<String> toSearch = new Set<String>.from([topLibrary]);
118 Set<String> foundImports = new HashSet<String>();
119 String pathSep = new Platform().pathSeparator();
120 int end = topLibrary.lastIndexOf(pathSep);
121 String libraryDir = topLibrary.substring(0, end);
122
123 // Matches #import( or #source( followed by " or ' followed by anything
124 // except dart: or /, at the beginning of a line.
125 RegExp relativeImportRegExp =
126 const RegExp('^#(import|source)[(]["\'](?!(dart:|/))([^"\']*)["\']');
127 while (!toSearch.isEmpty()) {
128 var thisPass = toSearch;
129 toSearch = new HashSet<String>();
130 for (String filename in thisPass) {
131 File f = new File(filename);
132 for (String line in f.readAsLinesSync()) {
133 Match match = relativeImportRegExp.firstMatch(line);
134 if (match != null) {
135 String relativePath = match.group(3);
136 if (foundImports.contains(relativePath)) {
137 continue;
138 }
139 if (relativePath.contains(@'\.\.')) {
140 // This is just for safety reasons, we don't want
141 // to unintentionally clobber files relative to the destination
142 // dir when copying them ove.
143 Expect.fail("relative paths containing .. are not allowed.");
144 }
145 foundImports.add(relativePath);
146 toSearch.add('$libraryDir/$relativePath');
147 }
148 }
149 }
150 }
151 return foundImports;
152 }
122 153
123 void DoMultitest(String filename, 154 void DoMultitest(String filename,
124 String outputDir, 155 String outputDir,
125 String testDir, 156 String testDir,
126 Function doTest(String filename, 157 Function doTest(String filename,
127 bool isNegative, 158 bool isNegative,
128 [bool isNegativeIfChecked, 159 [bool isNegativeIfChecked,
129 bool hasFatalTypeErrors, 160 bool hasFatalTypeErrors,
130 bool hasRuntimeErrors]), 161 bool hasRuntimeErrors]),
131 Function multitestDone) { 162 Function multitestDone) {
132 // Each new test is a single String value in the Map tests. 163 // Each new test is a single String value in the Map tests.
133 Map<String, String> tests = new Map<String, String>(); 164 Map<String, String> tests = new Map<String, String>();
134 Map<String, String> outcomes = new Map<String, String>(); 165 Map<String, String> outcomes = new Map<String, String>();
135 ExtractTestsFromMultitest(filename, tests, outcomes); 166 ExtractTestsFromMultitest(filename, tests, outcomes);
136 167
137 String directory = CreateMultitestDirectory(outputDir, testDir); 168 String directory = CreateMultitestDirectory(outputDir, testDir);
138 String pathSeparator = new Platform().pathSeparator(); 169 Expect.isNotNull(directory);
139 int start = filename.lastIndexOf(pathSeparator) + 1; 170 String pathSep = new Platform().pathSeparator();
171 int start = filename.lastIndexOf(pathSep) + 1;
140 int end = filename.indexOf('.dart', start); 172 int end = filename.indexOf('.dart', start);
141 String baseFilename = filename.substring(start, end); 173 String baseFilename = filename.substring(start, end);
174 String sourceDirectory = filename.substring(0, start - 1);
175 Set<String> importsToCopy = _findAllRelativeImports(filename);
176 Directory destDir = new Directory("directory");
177 for (String import in importsToCopy) {
178 File source = new File('$sourceDirectory/$import');
179 var dest = new File('$directory/$import');
180 var basenameStart = import.lastIndexOf('/');
181 if (basenameStart > 0) {
182 // make sure we have a dir for it
183 var importDir = import.substring(0, basenameStart);
184 TestUtils.mkdirRecursive(directory, importDir);
185 }
186 TestUtils.copyFile(source, dest);
187 }
142 for (String key in tests.getKeys()) { 188 for (String key in tests.getKeys()) {
143 final String filename = '$directory/${baseFilename}_$key.dart'; 189 final String filename = '$directory/${baseFilename}_$key.dart';
144 final File file = new File(filename); 190 final File file = new File(filename);
145 191
146 file.createSync(); 192 file.createSync();
147 RandomAccessFile openedFile = file.openSync(FileMode.WRITE); 193 RandomAccessFile openedFile = file.openSync(FileMode.WRITE);
148 var bytes = tests[key].charCodes(); 194 var bytes = tests[key].charCodes();
149 openedFile.writeListSync(bytes, 0, bytes.length); 195 openedFile.writeListSync(bytes, 0, bytes.length);
150 openedFile.closeSync(); 196 openedFile.closeSync();
151 var outcome = outcomes[key]; 197 var outcome = outcomes[key];
(...skipping 24 matching lines...) Expand all
176 var split = testDir.split('/'); 222 var split = testDir.split('/');
177 var lastComponent = split.removeLast(); 223 var lastComponent = split.removeLast();
178 Expect.isTrue(lastComponent == 'src'); 224 Expect.isTrue(lastComponent == 'src');
179 String path = '${generatedTestDir.path}/${split.last()}'; 225 String path = '${generatedTestDir.path}/${split.last()}';
180 Directory dir = new Directory(path); 226 Directory dir = new Directory(path);
181 if (!dir.existsSync()) { 227 if (!dir.existsSync()) {
182 dir.createSync(); 228 dir.createSync();
183 } 229 }
184 return path; 230 return path;
185 } 231 }
OLDNEW
« no previous file with comments | « no previous file | tools/testing/dart/test_suite.dart » ('j') | tools/testing/dart/test_suite.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698