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

Side by Side Diff: utils/tests/pub/test_pub.dart

Issue 10214006: Refactor command code and add support for --help and --version. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 /** 5 /**
6 * Test infrastructure for testing pub. Unlike typical unit tests, most pub 6 * Test infrastructure for testing pub. Unlike typical unit tests, most pub
7 * tests are integration tests that stage some stuff on the file system, run 7 * tests are integration tests that stage some stuff on the file system, run
8 * pub, and then validate the results. This library provides an API to build 8 * pub, and then validate the results. This library provides an API to build
9 * tests like that. 9 * tests like that.
10 */ 10 */
(...skipping 10 matching lines...) Expand all
21 */ 21 */
22 FileDescriptor file(String name, String contents) => 22 FileDescriptor file(String name, String contents) =>
23 new FileDescriptor(name, contents); 23 new FileDescriptor(name, contents);
24 24
25 /** 25 /**
26 * Creates a new [DirectoryDescriptor] with [name] and [contents]. 26 * Creates a new [DirectoryDescriptor] with [name] and [contents].
27 */ 27 */
28 DirectoryDescriptor dir(String name, [List<Descriptor> contents]) => 28 DirectoryDescriptor dir(String name, [List<Descriptor> contents]) =>
29 new DirectoryDescriptor(name, contents); 29 new DirectoryDescriptor(name, contents);
30 30
31 void testPub(String description, [List<Descriptor> cache, List<String> args, 31 void testPub(String description, [List<Descriptor> cache, Descriptor app,
32 List<String> args, List<Descriptor> expectedPackageDir,
32 String output, int exitCode = 0]) { 33 String output, int exitCode = 0]) {
33 asyncTest(description, 1, () { 34 asyncTest(description, 1, () {
34 var createdSandboxDir; 35 var createdSandboxDir;
36 var createdAppDir;
35 37
36 deleteSandboxIfCreated() { 38 deleteSandboxIfCreated() {
37 if (createdSandboxDir != null) { 39 if (createdSandboxDir != null) {
38 deleteDir(createdSandboxDir).then((_) { 40 deleteDir(createdSandboxDir).then((_) {
39 callbackDone(); 41 callbackDone();
40 }); 42 });
41 } else { 43 } else {
42 callbackDone(); 44 callbackDone();
43 } 45 }
44 } 46 }
45 47
46 final future = _setUpSandbox().chain((sandboxDir) { 48 final future = _setUpSandbox().chain((sandboxDir) {
47 createdSandboxDir = sandboxDir; 49 createdSandboxDir = sandboxDir;
48 return _setUpCache(sandboxDir, cache); 50 return _setUpApp(sandboxDir, app);
51 }).chain((appDir) {
52 createdAppDir = appDir;
53 return _setUpCache(createdSandboxDir, cache);
49 }).chain((cacheDir) { 54 }).chain((cacheDir) {
55 var workingDir;
56 if (createdAppDir != null) workingDir = createdAppDir.path;
57
50 if (cacheDir != null) { 58 if (cacheDir != null) {
51 // TODO(rnystrom): Hack in the cache directory path. Should pass this 59 // TODO(rnystrom): Hack in the cache directory path. Should pass this
52 // in using environment var once #752 is done. 60 // in using environment var once #752 is done.
53 args.add('--cachedir=${cacheDir.path}'); 61 args.add('--cachedir=${getFullPath(cacheDir)}');
54 } 62 }
55 63
56 return _runPub(args); 64 return _runPub(args, workingDir);
57 }); 65 }).chain((result) {
58
59 future.then((result) {
60 _validateOutput(output, result.stdout); 66 _validateOutput(output, result.stdout);
61 67
62 Expect.equals(result.stderr.length, 0, 68 Expect.equals(result.stderr.length, 0,
63 'Did not expect any output on stderr, and got:\n' + 69 'Did not expect any output on stderr, and got:\n' +
64 Strings.join(result.stderr, '\n')); 70 Strings.join(result.stderr, '\n'));
65 71
66 Expect.equals(result.exitCode, exitCode, 72 Expect.equals(result.exitCode, exitCode,
67 'Pub returned exit code ${result.exitCode}, expected $exitCode.'); 73 'Pub returned exit code ${result.exitCode}, expected $exitCode.');
68 74
75 return _validateExpectedPackages(createdAppDir, expectedPackageDir);
76 });
77
78 future.then((valid) {
79 Expect.isTrue(valid); // TODO(bob): Report which expectation failed.
69 deleteSandboxIfCreated(); 80 deleteSandboxIfCreated();
70 }); 81 });
71 82
72 future.handleException((error) { 83 future.handleException((error) {
73 deleteSandboxIfCreated(); 84 deleteSandboxIfCreated();
74 }); 85 });
75 }); 86 });
76 } 87 }
77 88
78 Future<Directory> _setUpSandbox() { 89 Future<Directory> _setUpSandbox() {
79 return createTempDir('pub-test-sandbox-'); 90 return cleanDir('pub-test-sandbox');
80 } 91 }
81 92
82 Future _setUpCache(Directory sandboxDir, List<Descriptor> cache) { 93 Future _setUpCache(Directory sandboxDir, List<Descriptor> cache) {
83 // No cache. 94 // No cache.
84 if (cache == null) return new Future.immediate(null); 95 if (cache == null) return new Future.immediate(null);
85 96
86 return dir('pub-cache', cache).create(sandboxDir); 97 return dir('pub-cache', cache).create(sandboxDir);
87 } 98 }
88 99
89 Future<ProcessResult> _runPub(List<String> pubArgs) { 100 Future _setUpApp(Directory sandboxDir, Descriptor app) {
101 // No app directory.
102 if (app == null) return new Future.immediate(null);
103
104 return app.create(sandboxDir);
105 }
106
107 Future<ProcessResult> _runPub(List<String> pubArgs, String workingDir) {
90 // Find a dart executable we can use to run pub. Uses the one that the 108 // Find a dart executable we can use to run pub. Uses the one that the
91 // test infrastructure uses. 109 // test infrastructure uses.
92 final scriptDir = new File(new Options().script).directorySync().path; 110 final scriptDir = new File(new Options().script).directorySync().path;
93 final platform = Platform.operatingSystem(); 111 final platform = Platform.operatingSystem();
94 final dartBin = join(scriptDir, '../../../tools/testing/bin/$platform/dart'); 112 final dartBin = join(scriptDir, '../../../tools/testing/bin/$platform/dart');
95 113
96 // Find the main pub entrypoint. 114 // Find the main pub entrypoint.
97 final pubPath = fs.joinPaths(scriptDir, '../../pub/pub.dart'); 115 final pubPath = fs.joinPaths(scriptDir, '../../pub/pub.dart');
98 116
99 final args = [pubPath]; 117 final args = [pubPath];
100 args.addAll(pubArgs); 118 args.addAll(pubArgs);
101 119
102 return runProcess(dartBin, args); 120 return runProcess(dartBin, args, workingDir);
121 }
122
123 Future<bool> _validateExpectedPackages(Directory appDir,
124 List<Descriptor> expectedPackageDir) {
125 // No expectation.
126 if (expectedPackageDir == null) return new Future.immediate(true);
127
128 return dir('packages', expectedPackageDir).validate(appDir.path);
103 } 129 }
104 130
105 /** 131 /**
106 * Compares the [actual] output from running pub with [expectedText]. Ignores 132 * Compares the [actual] output from running pub with [expectedText]. Ignores
107 * leading and trailing whitespace differences and tries to report the 133 * leading and trailing whitespace differences and tries to report the
108 * offending difference in a nice way. 134 * offending difference in a nice way.
109 */ 135 */
110 void _validateOutput(String expectedText, List<String> actual) { 136 void _validateOutput(String expectedText, List<String> actual) {
111 final expected = expectedText.split('\n'); 137 final expected = expectedText.split('\n');
112 138
139 // Strip off the last line. This lets us have expected multiline strings
140 // where the closing ''' is on its own line. It also fixes '' expected output
141 // to expect zero lines of output, not a single empty line.
142 expected.removeLast();
143
113 final length = Math.min(expected.length, actual.length); 144 final length = Math.min(expected.length, actual.length);
114 for (var i = 0; i < length; i++) { 145 for (var i = 0; i < length; i++) {
115 if (expected[i].trim() != actual[i].trim()) { 146 if (expected[i].trim() != actual[i].trim()) {
116 Expect.fail( 147 Expect.fail(
117 'Output line ${i + 1} was: ${actual[i]}\nexpected: ${expected[i]}'); 148 'Output line ${i + 1} was: ${actual[i]}\nexpected: ${expected[i]}');
118 } 149 }
119 } 150 }
120 151
121 if (expected.length > actual.length) { 152 if (expected.length > actual.length) {
122 final message = new StringBuffer(); 153 final message = new StringBuffer();
(...skipping 29 matching lines...) Expand all
152 */ 183 */
153 final String name; 184 final String name;
154 185
155 Descriptor(this.name); 186 Descriptor(this.name);
156 187
157 /** 188 /**
158 * Creates the file or directory within [dir]. Returns a [Future] that is 189 * Creates the file or directory within [dir]. Returns a [Future] that is
159 * completed after the creation is done. 190 * completed after the creation is done.
160 */ 191 */
161 abstract Future create(String dir); 192 abstract Future create(String dir);
193
194 /**
195 * Validates that this descriptor correctly matches the actual file system
196 * entry at [path]. Returns a [Future] that completes when the validation is
197 * done.
198 */
199 abstract Future<bool> validate(String path);
nweiz 2012/04/25 20:49:41 I'd make it clearer that path is always a director
Bob Nystrom 2012/04/25 22:56:40 Done.
162 } 200 }
163 201
164 /** 202 /**
165 * Describes a file. These are used both for setting up an expected directory 203 * Describes a file. These are used both for setting up an expected directory
166 * tree before running a test, and for validating that the file system matches 204 * tree before running a test, and for validating that the file system matches
167 * some expectations after running it. 205 * some expectations after running it.
168 */ 206 */
169 class FileDescriptor extends Descriptor { 207 class FileDescriptor extends Descriptor {
170 /** 208 /**
171 * The text contents of the file. 209 * The text contents of the file.
172 */ 210 */
173 final String contents; 211 final String contents;
174 212
175 FileDescriptor(String name, this.contents) : super(name); 213 FileDescriptor(String name, this.contents) : super(name);
176 214
177 /** 215 /**
178 * Creates the file within [dir]. Returns a [Future] that is completed after 216 * Creates the file within [dir]. Returns a [Future] that is completed after
179 * the creation is done. 217 * the creation is done.
180 */ 218 */
181 Future<File> create(String dir) { 219 Future<File> create(String dir) {
182 return writeTextFile(join(dir, name), contents); 220 return writeTextFile(join(dir, name), contents);
183 } 221 }
222
223 /**
224 * Validates that this file correctly matches the actual file at [path].
225 */
226 Future<bool> validate(String path) {
227 path = join(path, name);
228 return fileExists(path).chain((exists) {
229 if (!exists) return new Future.immediate(false);
230
231 return readTextFile(path).transform((text) => text == contents);
232 });
233 }
184 } 234 }
185 235
186 /** 236 /**
187 * Describes a directory and its contents. These are used both for setting up 237 * Describes a directory and its contents. These are used both for setting up
188 * an expected directory tree before running a test, and for validating that 238 * an expected directory tree before running a test, and for validating that
189 * the file system matches some expectations after running it. 239 * the file system matches some expectations after running it.
190 */ 240 */
191 class DirectoryDescriptor extends Descriptor { 241 class DirectoryDescriptor extends Descriptor {
192 /** 242 /**
193 * The files and directories contained in this directory. 243 * The files and directories contained in this directory.
(...skipping 18 matching lines...) Expand all
212 final childFutures = contents.map((child) => child.create(dir.path)); 262 final childFutures = contents.map((child) => child.create(dir.path));
213 Futures.wait(childFutures).then((_) { 263 Futures.wait(childFutures).then((_) {
214 // Only complete once all of the children have been created too. 264 // Only complete once all of the children have been created too.
215 completer.complete(dir); 265 completer.complete(dir);
216 }); 266 });
217 } 267 }
218 }); 268 });
219 269
220 return completer.future; 270 return completer.future;
221 } 271 }
272
273 /**
274 * Validates that the directory at [path] contains all of the expected
275 * contents in this descriptor. Note that this does *not* check that the
276 * directory doesn't contain other unexpected stuff, just that it *does*
277 * contain the stuff we do expect.
278 */
279 Future<bool> validate(String path) {
280 // Validate each of the items in this directory.
281 final entryFutures = contents.map(
282 (entry) => entry.validate(join(path, name)));
283
284 // If they are all valid, the directory is valid.
285 return Futures.wait(entryFutures).transform((entries) {
286 return !entries.some((valid) => !valid);
287 });
288 }
222 } 289 }
OLDNEW
« utils/tests/pub/pub_tests.dart ('K') | « utils/tests/pub/pub_tests.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698