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

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

Issue 10091014: Start implementing pub object model. Rudimentary package cache class, and a simple pub command to l… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Platform is static now. 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
« no previous file with comments | « utils/tests/pub/pub_tests.dart ('k') | 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) 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 */
11 #library('test_pub'); 11 #library('test_pub');
12 12
13 #import('dart:io'); 13 #import('dart:io');
14 14
15 #import('../../../lib/unittest/unittest.dart'); 15 #import('../../../lib/unittest/unittest.dart');
16 #import('../../lib/file_system.dart'); 16 #import('../../lib/file_system.dart', prefix: 'fs');
17 #import('../../pub/io.dart');
17 18
18 void testOutput(String description, List<String> pubArgs, String expected, 19 /**
19 [int exitCode = 0]) { 20 * Creates a new [FileDescriptor] with [name] and [contents].
21 */
22 FileDescriptor file(String name, String contents) =>
23 new FileDescriptor(name, contents);
24
25 /**
26 * Creates a new [DirectoryDescriptor] with [name] and [contents].
27 */
28 DirectoryDescriptor dir(String name, [List<Descriptor> contents]) =>
29 new DirectoryDescriptor(name, contents);
30
31 void testPub(String description, [List<Descriptor> cache, List<String> args,
32 String output, int exitCode = 0]) {
20 asyncTest(description, 1, () { 33 asyncTest(description, 1, () {
21 // Find a dart executable we can use to run pub. Uses the one that the 34 var createdSandboxDir;
22 // test infrastructure uses.
23 final scriptDir = new File(new Options().script).directorySync().path;
24 final platform = Platform.operatingSystem();
25 final dartBin = joinPaths(scriptDir,
26 '../../../tools/testing/bin/$platform/dart');
27 35
28 // Find the main pub entrypoint. 36 deleteSandboxIfCreated() {
29 final pubPath = joinPaths(scriptDir, '../../pub/pub.dart'); 37 if (createdSandboxDir != null) {
30 38 deleteDir(createdSandboxDir).then((_) {
31 final args = [pubPath]; 39 callbackDone();
32 args.addAll(pubArgs); 40 });
33 41 } else {
34 final process = new Process.start(dartBin, args); 42 callbackDone();
35 final outStream = new StringInputStream(process.stdout); 43 }
36 final output = <String>[];
37 bool processDone = false;
38
39 checkComplete() {
40 if (!outStream.closed) return;
41 if (!processDone) return;
42
43 _validateOutput(expected, output);
44 callbackDone();
45 } 44 }
46 45
47 process.stderr.pipe(stderr, close: false); 46 final future = _setUpSandbox().chain((sandboxDir) {
47 createdSandboxDir = sandboxDir;
48 return _setUpCache(sandboxDir, cache);
49 }).chain((cacheDir) {
50 if (cacheDir != null) {
51 // TODO(rnystrom): Hack in the cache directory path. Should pass this
52 // in using environment var once #752 is done.
53 args.add('--cachedir=${cacheDir.path}');
54 }
48 55
49 outStream.onLine = () { 56 return _runPub(args);
50 output.add(outStream.readLine()); 57 });
51 };
52 58
53 outStream.onClosed = checkComplete; 59 future.then((result) {
60 _validateOutput(output, result.stdout);
54 61
55 process.onError = (error) { 62 Expect.equals(result.stderr.length, 0,
56 Expect.fail('Failed to run pub: $error'); 63 'Did not expect any output on stderr, and got:\n' +
57 processDone = true; 64 Strings.join(result.stderr, '\n'));
58 };
59 65
60 process.onExit = (actualExitCode) { 66 Expect.equals(result.exitCode, exitCode,
61 Expect.equals(actualExitCode, exitCode, 67 'Pub returned exit code ${result.exitCode}, expected $exitCode.');
62 'Pub returned exit code $actualExitCode, expected $exitCode.'); 68
63 processDone = true; 69 deleteSandboxIfCreated();
64 checkComplete(); 70 });
65 }; 71
72 future.handleException((error) {
73 deleteSandboxIfCreated();
74 });
66 }); 75 });
67 } 76 }
68 77
78 Future<Directory> _setUpSandbox() {
79 return createTempDir('pub-test-sandbox-');
80 }
81
82 Future _setUpCache(Directory sandboxDir, List<Descriptor> cache) {
83 // No cache.
84 if (cache == null) return new Future.immediate(null);
85
86 return dir('pub-cache', cache).create(sandboxDir);
87 }
88
89 Future<ProcessResult> _runPub(List<String> pubArgs) {
90 // Find a dart executable we can use to run pub. Uses the one that the
91 // test infrastructure uses.
92 final scriptDir = new File(new Options().script).directorySync().path;
93 final platform = Platform.operatingSystem();
94 final dartBin = join(scriptDir, '../../../tools/testing/bin/$platform/dart');
95
96 // Find the main pub entrypoint.
97 final pubPath = fs.joinPaths(scriptDir, '../../pub/pub.dart');
98
99 final args = [pubPath];
100 args.addAll(pubArgs);
101
102 return runProcess(dartBin, args);
103 }
104
69 /** 105 /**
70 * Compares the [actual] output from running pub with [expectedText]. Ignores 106 * Compares the [actual] output from running pub with [expectedText]. Ignores
71 * leading and trailing whitespace differences and tries to report the 107 * leading and trailing whitespace differences and tries to report the
72 * offending difference in a nice way. 108 * offending difference in a nice way.
73 */ 109 */
74 void _validateOutput(String expectedText, List<String> actual) { 110 void _validateOutput(String expectedText, List<String> actual) {
75 final expected = expectedText.split('\n'); 111 final expected = expectedText.split('\n');
76 112
77 final length = Math.min(expected.length, actual.length); 113 final length = Math.min(expected.length, actual.length);
78 for (var i = 0; i < length; i++) { 114 for (var i = 0; i < length; i++) {
(...skipping 18 matching lines...) Expand all
97 final message = new StringBuffer(); 133 final message = new StringBuffer();
98 message.add('Unexpected output:\n'); 134 message.add('Unexpected output:\n');
99 for (var i = expected.length; i < actual.length; i++) { 135 for (var i = expected.length; i < actual.length; i++) {
100 message.add(actual[i]); 136 message.add(actual[i]);
101 message.add('\n'); 137 message.add('\n');
102 } 138 }
103 139
104 Expect.fail(message.toString()); 140 Expect.fail(message.toString());
105 } 141 }
106 } 142 }
143
144 /**
145 * Base class for [FileDescriptor] and [DirectoryDescriptor] so that a
146 * directory can contain a heterogeneous collection of files and
147 * subdirectories.
148 */
149 class Descriptor {
150 /**
151 * The short name of this file or directory.
152 */
153 final String name;
154
155 Descriptor(this.name);
156
157 /**
158 * Creates the file or directory within [dir]. Returns a [Future] that is
159 * completed after the creation is done.
160 */
161 abstract Future create(String dir);
162 }
163
164 /**
165 * 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
167 * some expectations after running it.
168 */
169 class FileDescriptor extends Descriptor {
170 /**
171 * The text contents of the file.
172 */
173 final String contents;
174
175 FileDescriptor(String name, this.contents) : super(name);
176
177 /**
178 * Creates the file within [dir]. Returns a [Future] that is completed after
179 * the creation is done.
180 */
181 Future<File> create(String dir) {
182 return writeTextFile(join(dir, name), contents);
183 }
184 }
185
186 /**
187 * 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
189 * the file system matches some expectations after running it.
190 */
191 class DirectoryDescriptor extends Descriptor {
192 /**
193 * The files and directories contained in this directory.
194 */
195 final List<Descriptor> contents;
196
197 DirectoryDescriptor(String name, this.contents) : super(name);
198
199 /**
200 * Creates the file within [dir]. Returns a [Future] that is completed after
201 * the creation is done.
202 */
203 Future<Directory> create(String parentDir) {
204 final completer = new Completer<Directory>();
205
206 // Create the directory.
207 createDir(join(parentDir, name)).then((dir) {
208 if (contents == null) {
209 completer.complete(dir);
210 } else {
211 // Recursively create all of its children.
212 final childFutures = contents.map((child) => child.create(dir.path));
213 Futures.wait(childFutures).then((_) {
214 // Only complete once all of the children have been created too.
215 completer.complete(dir);
216 });
217 }
218 });
219
220 return completer.future;
221 }
222 }
OLDNEW
« no previous file with comments | « utils/tests/pub/pub_tests.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698