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

Side by Side Diff: sdk/lib/_internal/pub/test/test_pub.dart

Issue 354763006: Add a "pub global run" command. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise! Created 6 years, 5 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 | « sdk/lib/_internal/pub/test/run/utils.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /// Test infrastructure for testing pub. 5 /// Test infrastructure for testing pub.
6 /// 6 ///
7 /// Unlike typical unit tests, most pub tests are integration tests that stage 7 /// Unlike typical unit tests, most pub tests are integration tests that stage
8 /// some stuff on the file system, run pub, and then validate the results. This 8 /// some stuff on the file system, run pub, and then validate the results. This
9 /// library provides an API to build tests like that. 9 /// library provides an API to build tests like that.
10 library test_pub; 10 library test_pub;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 Map<String, List<Map>> _servedPackages; 218 Map<String, List<Map>> _servedPackages;
219 219
220 /// Creates an HTTP server that replicates the structure of pub.dartlang.org. 220 /// Creates an HTTP server that replicates the structure of pub.dartlang.org.
221 /// 221 ///
222 /// [pubspecs] is a list of unserialized pubspecs representing the packages to 222 /// [pubspecs] is a list of unserialized pubspecs representing the packages to
223 /// serve. 223 /// serve.
224 /// 224 ///
225 /// If [replace] is false, subsequent calls to [servePackages] will add to the 225 /// If [replace] is false, subsequent calls to [servePackages] will add to the
226 /// set of packages that are being served. Previous packages will continue to be 226 /// set of packages that are being served. Previous packages will continue to be
227 /// served. Otherwise, the previous packages will no longer be served. 227 /// served. Otherwise, the previous packages will no longer be served.
228 void servePackages(List<Map> pubspecs, {bool replace: false}) { 228 ///
229 /// If [contents] is given, its contents are added to every served
230 /// package.
231 void servePackages(List<Map> pubspecs, {bool replace: false,
232 Iterable<d.Descriptor> contents}) {
229 if (_servedPackages == null || _servedPackageDir == null) { 233 if (_servedPackages == null || _servedPackageDir == null) {
230 _servedPackages = <String, List<Map>>{}; 234 _servedPackages = <String, List<Map>>{};
231 _servedApiPackageDir = d.dir('packages', []); 235 _servedApiPackageDir = d.dir('packages', []);
232 _servedPackageDir = d.dir('packages', []); 236 _servedPackageDir = d.dir('packages', []);
233 serve([ 237 serve([
234 d.dir('api', [_servedApiPackageDir]), 238 d.dir('api', [_servedApiPackageDir]),
235 _servedPackageDir 239 _servedPackageDir
236 ]); 240 ]);
237 241
238 currentSchedule.onComplete.schedule(() { 242 currentSchedule.onComplete.schedule(() {
239 _servedPackages = null; 243 _servedPackages = null;
240 _servedApiPackageDir = null; 244 _servedApiPackageDir = null;
241 _servedPackageDir = null; 245 _servedPackageDir = null;
242 }, 'cleaning up served packages'); 246 }, 'cleaning up served packages');
243 } 247 }
244 248
245 schedule(() { 249 schedule(() {
246 return awaitObject(pubspecs).then((resolvedPubspecs) { 250 return awaitObject(pubspecs).then((resolvedPubspecs) {
247 if (replace) _servedPackages.clear(); 251 if (replace) _servedPackages.clear();
248 252
249 for (var spec in resolvedPubspecs) { 253 for (var pubspec in resolvedPubspecs) {
250 var name = spec['name']; 254 var name = pubspec['name'];
251 var version = spec['version']; 255 var version = pubspec['version'];
252 var versions = _servedPackages.putIfAbsent(name, () => []); 256 var versions = _servedPackages.putIfAbsent(name, () => []);
253 versions.add(spec); 257 versions.add(pubspec);
254 } 258 }
255 259
256 _servedApiPackageDir.contents.clear(); 260 _servedApiPackageDir.contents.clear();
257 _servedPackageDir.contents.clear(); 261 _servedPackageDir.contents.clear();
258 for (var name in _servedPackages.keys) { 262 for (var name in _servedPackages.keys) {
259 _servedApiPackageDir.contents.addAll([ 263 _servedApiPackageDir.contents.addAll([
260 d.file('$name', JSON.encode({ 264 d.file('$name', JSON.encode({
261 'name': name, 265 'name': name,
262 'uploaders': ['nweiz@google.com'], 266 'uploaders': ['nweiz@google.com'],
263 'versions': _servedPackages[name].map(packageVersionApiMap).toList() 267 'versions': _servedPackages[name].map(packageVersionApiMap).toList()
264 })), 268 })),
265 d.dir(name, [ 269 d.dir(name, [
266 d.dir('versions', _servedPackages[name].map((pubspec) { 270 d.dir('versions', _servedPackages[name].map((pubspec) {
267 return d.file(pubspec['version'], JSON.encode( 271 return d.file(pubspec['version'], JSON.encode(
268 packageVersionApiMap(pubspec, full: true))); 272 packageVersionApiMap(pubspec, full: true)));
269 })) 273 }))
270 ]) 274 ])
271 ]); 275 ]);
272 276
273 _servedPackageDir.contents.add(d.dir(name, [ 277 _servedPackageDir.contents.add(d.dir(name, [
274 d.dir('versions', _servedPackages[name].map((pubspec) { 278 d.dir('versions', _servedPackages[name].map((pubspec) {
275 var version = pubspec['version']; 279 var version = pubspec['version'];
276 return d.tar('$version.tar.gz', [ 280
277 d.file('pubspec.yaml', JSON.encode(pubspec)), 281 var archiveContents = [
278 d.libDir(name, '$name $version') 282 d.file('pubspec.yaml', JSON.encode(pubspec)),
279 ]); 283 d.libDir(name, '$name $version')
284 ];
285
286 if (contents != null) {
287 archiveContents.addAll(contents);
288 }
289
290 return d.tar('$version.tar.gz', archiveContents);
280 })) 291 }))
281 ])); 292 ]));
282 } 293 }
283 }); 294 });
284 }, 'initializing the package server'); 295 }, 'initializing the package server');
285 } 296 }
286 297
287 /// Converts [value] into a YAML string. 298 /// Converts [value] into a YAML string.
288 String yaml(value) => JSON.encode(value); 299 String yaml(value) => JSON.encode(value);
289 300
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 void pubGet({Iterable<String> args, output, error, warning, int exitCode}) { 381 void pubGet({Iterable<String> args, output, error, warning, int exitCode}) {
371 pubCommand(RunCommand.get, args: args, output: output, error: error, 382 pubCommand(RunCommand.get, args: args, output: output, error: error,
372 warning: warning, exitCode: exitCode); 383 warning: warning, exitCode: exitCode);
373 } 384 }
374 385
375 void pubUpgrade({Iterable<String> args, output, error, warning, int exitCode}) { 386 void pubUpgrade({Iterable<String> args, output, error, warning, int exitCode}) {
376 pubCommand(RunCommand.upgrade, args: args, output: output, error: error, 387 pubCommand(RunCommand.upgrade, args: args, output: output, error: error,
377 warning: warning, exitCode: exitCode); 388 warning: warning, exitCode: exitCode);
378 } 389 }
379 390
391 /// Schedules starting the "pub [global] run" process and validates the
392 /// expected startup output.
393 ///
394 /// If [global] is `true`, this invokes "pub global run", otherwise it does
395 /// "pub run".
396 ///
397 /// Returns the `pub run` process.
398 ScheduledProcess pubRun({bool global: false, Iterable<String> args}) {
399 var pubArgs = global ? ["global", "run"] : ["run"];
400 pubArgs.addAll(args);
401 var pub = startPub(args: pubArgs);
402
403 // Loading sources and transformers isn't normally printed, but the pub test
404 // infrastructure runs pub in verbose mode, which enables this.
405 pub.stdout.expect(consumeWhile(startsWith("Loading")));
406
407 return pub;
408 }
409
380 /// Defines an integration test. 410 /// Defines an integration test.
381 /// 411 ///
382 /// The [body] should schedule a series of operations which will be run 412 /// The [body] should schedule a series of operations which will be run
383 /// asynchronously. 413 /// asynchronously.
384 void integration(String description, void body()) => 414 void integration(String description, void body()) =>
385 _integration(description, body, test); 415 _integration(description, body, test);
386 416
387 /// Like [integration], but causes only this test to run. 417 /// Like [integration], but causes only this test to run.
388 void solo_integration(String description, void body()) => 418 void solo_integration(String description, void body()) =>
389 _integration(description, body, solo_test); 419 _integration(description, body, solo_test);
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 void ensureGit() { 693 void ensureGit() {
664 if (Platform.operatingSystem == "windows") { 694 if (Platform.operatingSystem == "windows") {
665 currentSchedule.timeout = new Duration(seconds: 30); 695 currentSchedule.timeout = new Duration(seconds: 30);
666 } 696 }
667 697
668 if (!gitlib.isInstalled) { 698 if (!gitlib.isInstalled) {
669 throw new Exception("Git must be installed to run this test."); 699 throw new Exception("Git must be installed to run this test.");
670 } 700 }
671 } 701 }
672 702
703 /// Schedules activating a global package [package] without running
704 /// "pub global activate".
705 ///
706 /// This is useful because global packages must be hosted, but the test hosted
707 /// server doesn't serve barback. The other parameters here follow
708 /// [createLockFile].
709 void makeGlobalPackage(String package, String version,
710 Iterable<d.Descriptor> contents, {Iterable<String> pkg,
711 Map<String, String> hosted}) {
712 // Start the server so we know what port to use in the cache directory name.
713 servePackages([]);
714
715 // Create the package in the hosted cache.
716 d.hostedCache([
717 d.dir("$package-$version", contents)
718 ]).create();
719
720 var lockFile = _createLockFile(pkg: pkg, hosted: hosted);
721
722 // Add the root package to the lockfile.
723 var id = new PackageId(package, "hosted", new Version.parse(version),
724 package);
725 lockFile.packages[package] = id;
726
727 // Write the lockfile to the global cache.
728 var sources = new SourceRegistry();
729 sources.register(new HostedSource());
730 sources.register(new PathSource());
731
732 d.dir(cachePath, [
733 d.dir("global_packages", [
734 d.file("$package.lock", lockFile.serialize(null, sources))
735 ])
736 ]).create();
737 }
738
673 /// Creates a lock file for [package] without running `pub get`. 739 /// Creates a lock file for [package] without running `pub get`.
674 /// 740 ///
675 /// [sandbox] is a list of path dependencies to be found in the sandbox 741 /// [sandbox] is a list of path dependencies to be found in the sandbox
676 /// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory; 742 /// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory;
677 /// each package listed here and all its dependencies will be linked to the 743 /// each package listed here and all its dependencies will be linked to the
678 /// version in the Dart repo. 744 /// version in the Dart repo.
679 /// 745 ///
680 /// [hosted] is a list of package names to version strings for dependencies on 746 /// [hosted] is a list of package names to version strings for dependencies on
681 /// hosted packages. 747 /// hosted packages.
682 void createLockFile(String package, {Iterable<String> sandbox, 748 void createLockFile(String package, {Iterable<String> sandbox,
683 Iterable<String> pkg, Map<String, String> hosted}) { 749 Iterable<String> pkg, Map<String, String> hosted}) {
750 var lockFile = _createLockFile(sandbox: sandbox, pkg: pkg, hosted: hosted);
751
752 var sources = new SourceRegistry();
753 sources.register(new HostedSource());
754 sources.register(new PathSource());
755
756 d.file(path.join(package, 'pubspec.lock'),
757 lockFile.serialize(null, sources)).create();
758 }
759
760 /// Creates a lock file for [package] without running `pub get`.
761 ///
762 /// [sandbox] is a list of path dependencies to be found in the sandbox
763 /// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory;
764 /// each package listed here and all its dependencies will be linked to the
765 /// version in the Dart repo.
766 ///
767 /// [hosted] is a list of package names to version strings for dependencies on
768 /// hosted packages.
769 LockFile _createLockFile({Iterable<String> sandbox,
770 Iterable<String> pkg, Map<String, String> hosted}) {
684 var dependencies = {}; 771 var dependencies = {};
685 772
686 if (sandbox != null) { 773 if (sandbox != null) {
687 for (var package in sandbox) { 774 for (var package in sandbox) {
688 dependencies[package] = '../$package'; 775 dependencies[package] = '../$package';
689 } 776 }
690 } 777 }
691 778
692 if (pkg != null) { 779 if (pkg != null) {
693 _addPackage(String package) { 780 _addPackage(String package) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 lockFile.packages[name] = id; 812 lockFile.packages[name] = id;
726 }); 813 });
727 814
728 if (hosted != null) { 815 if (hosted != null) {
729 hosted.forEach((name, version) { 816 hosted.forEach((name, version) {
730 var id = new PackageId(name, 'hosted', new Version.parse(version), name); 817 var id = new PackageId(name, 'hosted', new Version.parse(version), name);
731 lockFile.packages[name] = id; 818 lockFile.packages[name] = id;
732 }); 819 });
733 } 820 }
734 821
735 var sources = new SourceRegistry(); 822 return lockFile;
736 sources.register(new HostedSource());
737 sources.register(new PathSource());
738
739 d.file(path.join(package, 'pubspec.lock'),
740 lockFile.serialize(null, sources)).create();
741 } 823 }
742 824
743 /// Uses [client] as the mock HTTP client for this test. 825 /// Uses [client] as the mock HTTP client for this test.
744 /// 826 ///
745 /// Note that this will only affect HTTP requests made via http.dart in the 827 /// Note that this will only affect HTTP requests made via http.dart in the
746 /// parent process. 828 /// parent process.
747 void useMockClient(MockClient client) { 829 void useMockClient(MockClient client) {
748 var oldInnerClient = httpClient.inner; 830 var oldInnerClient = httpClient.inner;
749 httpClient.inner = client; 831 httpClient.inner = client;
750 currentSchedule.onComplete.schedule(() { 832 currentSchedule.onComplete.schedule(() {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 _lastMatcher.matches(item.last, matchState); 1004 _lastMatcher.matches(item.last, matchState);
923 } 1005 }
924 1006
925 Description describe(Description description) { 1007 Description describe(Description description) {
926 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); 1008 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]);
927 } 1009 }
928 } 1010 }
929 1011
930 /// A [StreamMatcher] that matches multiple lines of output. 1012 /// A [StreamMatcher] that matches multiple lines of output.
931 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); 1013 StreamMatcher emitsLines(String output) => inOrder(output.split("\n"));
OLDNEW
« no previous file with comments | « sdk/lib/_internal/pub/test/run/utils.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698