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

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

Issue 12208138: Take Sam Elkhateeb's path for "path" dependencies and clean it up some. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise. Created 7 years, 10 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 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub 5 /// Test infrastructure for testing pub. Unlike typical unit tests, most pub
6 /// tests are integration tests that stage some stuff on the file system, run 6 /// tests are integration tests that stage some stuff on the file system, run
7 /// pub, and then validate the results. This library provides an API to build 7 /// pub, and then validate the results. This library provides an API to build
8 /// tests like that. 8 /// tests like that.
9 library test_pub; 9 library test_pub;
10 10
(...skipping 13 matching lines...) Expand all
24 import '../../lib/file_system.dart' as fs; 24 import '../../lib/file_system.dart' as fs;
25 import '../../pub/entrypoint.dart'; 25 import '../../pub/entrypoint.dart';
26 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides 26 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides
27 // with the git descriptor method. Maybe we should try to clean up the top level 27 // with the git descriptor method. Maybe we should try to clean up the top level
28 // scope a bit? 28 // scope a bit?
29 import '../../pub/git.dart' as gitlib; 29 import '../../pub/git.dart' as gitlib;
30 import '../../pub/git_source.dart'; 30 import '../../pub/git_source.dart';
31 import '../../pub/hosted_source.dart'; 31 import '../../pub/hosted_source.dart';
32 import '../../pub/http.dart'; 32 import '../../pub/http.dart';
33 import '../../pub/io.dart'; 33 import '../../pub/io.dart';
34 import '../../pub/path_source.dart';
34 import '../../pub/sdk_source.dart'; 35 import '../../pub/sdk_source.dart';
35 import '../../pub/system_cache.dart'; 36 import '../../pub/system_cache.dart';
36 import '../../pub/utils.dart'; 37 import '../../pub/utils.dart';
37 import '../../pub/validator.dart'; 38 import '../../pub/validator.dart';
38 import 'command_line_config.dart'; 39 import 'command_line_config.dart';
39 40
40 /// This should be called at the top of a test file to set up an appropriate 41 /// This should be called at the top of a test file to set up an appropriate
41 /// test configuration for the machine running the tests. 42 /// test configuration for the machine running the tests.
42 initConfig() { 43 initConfig() {
43 // If we aren't running on the bots, use the human-friendly config. 44 // If we aren't running on the bots, use the human-friendly config.
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 var keys = dependency.keys.where((key) => key != "version"); 398 var keys = dependency.keys.where((key) => key != "version");
398 var sourceName = only(keys); 399 var sourceName = only(keys);
399 var source; 400 var source;
400 switch (sourceName) { 401 switch (sourceName) {
401 case "git": 402 case "git":
402 source = new GitSource(); 403 source = new GitSource();
403 break; 404 break;
404 case "hosted": 405 case "hosted":
405 source = new HostedSource(); 406 source = new HostedSource();
406 break; 407 break;
408 case "path":
409 source = new PathSource();
410 break;
407 case "sdk": 411 case "sdk":
408 source = new SdkSource(); 412 source = new SdkSource();
409 break; 413 break;
410 default: 414 default:
411 throw 'Unknown source "$sourceName"'; 415 throw 'Unknown source "$sourceName"';
412 } 416 }
413 417
414 result[_packageName(sourceName, dependency[sourceName])] = dependency; 418 result[_packageName(sourceName, dependency[sourceName])] = dependency;
415 } 419 }
416 return result; 420 return result;
417 }); 421 });
418 } 422 }
419 423
420 /// Return the name for the package described by [description] and from 424 /// Return the name for the package described by [description] and from
421 /// [sourceName]. 425 /// [sourceName].
422 String _packageName(String sourceName, description) { 426 String _packageName(String sourceName, description) {
423 switch (sourceName) { 427 switch (sourceName) {
424 case "git": 428 case "git":
425 var url = description is String ? description : description['url']; 429 var url = description is String ? description : description['url'];
426 return basename(url.replaceFirst(new RegExp(r"(\.git)?/?$"), "")); 430 return basename(url.replaceFirst(new RegExp(r"(\.git)?/?$"), ""));
427 case "hosted": 431 case "hosted":
428 if (description is String) return description; 432 if (description is String) return description;
429 return description['name']; 433 return description['name'];
434 case "path":
435 return basename(description);
430 case "sdk": 436 case "sdk":
431 return description; 437 return description;
432 default: 438 default:
433 return description; 439 return description;
434 } 440 }
435 } 441 }
436 442
443 /// The full path to the created sandbox directory for an integration test.
444 String get sandboxDir => _sandboxDir.path;
445 Directory _sandboxDir;
446
437 /// The path of the package cache directory used for tests. Relative to the 447 /// The path of the package cache directory used for tests. Relative to the
438 /// sandbox directory. 448 /// sandbox directory.
439 final String cachePath = "cache"; 449 final String cachePath = "cache";
440 450
441 /// The path of the mock SDK directory used for tests. Relative to the sandbox 451 /// The path of the mock SDK directory used for tests. Relative to the sandbox
442 /// directory. 452 /// directory.
443 final String sdkPath = "sdk"; 453 final String sdkPath = "sdk";
444 454
445 /// The path of the mock app directory used for tests. Relative to the sandbox 455 /// The path of the mock app directory used for tests. Relative to the sandbox
446 /// directory. 456 /// directory.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 void solo_integration(String description, void body()) => 491 void solo_integration(String description, void body()) =>
482 _integration(description, body, solo_test); 492 _integration(description, body, solo_test);
483 493
484 void _integration(String description, void body(), [Function testFn]) { 494 void _integration(String description, void body(), [Function testFn]) {
485 testFn(description, () { 495 testFn(description, () {
486 // Ensure the SDK version is always available. 496 // Ensure the SDK version is always available.
487 dir(sdkPath, [ 497 dir(sdkPath, [
488 file('version', '0.1.2.3') 498 file('version', '0.1.2.3')
489 ]).scheduleCreate(); 499 ]).scheduleCreate();
490 500
501 _sandboxDir = createTempDir();
502
491 // Schedule the test. 503 // Schedule the test.
492 body(); 504 body();
493 505
494 // Run all of the scheduled tasks. If an error occurs, it will propagate 506 // Run all of the scheduled tasks. If an error occurs, it will propagate
495 // through the futures back up to here where we can hand it off to unittest. 507 // through the futures back up to here where we can hand it off to unittest.
496 var asyncDone = expectAsync0(() {}); 508 var asyncDone = expectAsync0(() {});
497 var sandboxDir = createTempDir(); 509 return timeout(_runScheduled(_scheduled),
498 return timeout(_runScheduled(sandboxDir, _scheduled),
499 _TIMEOUT, 'waiting for a test to complete').catchError((e) { 510 _TIMEOUT, 'waiting for a test to complete').catchError((e) {
500 return _runScheduled(sandboxDir, _scheduledOnException).then((_) { 511 return _runScheduled(_scheduledOnException).then((_) {
501 // Rethrow the original error so it keeps propagating. 512 // Rethrow the original error so it keeps propagating.
502 throw e; 513 throw e;
503 }); 514 });
504 }).whenComplete(() { 515 }).whenComplete(() {
505 // Clean up after ourselves. Do this first before reporting back to 516 // Clean up after ourselves. Do this first before reporting back to
506 // unittest because it will advance to the next test immediately. 517 // unittest because it will advance to the next test immediately.
507 return _runScheduled(sandboxDir, _scheduledCleanup).then((_) { 518 return _runScheduled(_scheduledCleanup).then((_) {
508 _scheduled = null; 519 _scheduled = null;
509 _scheduledCleanup = null; 520 _scheduledCleanup = null;
510 _scheduledOnException = null; 521 _scheduledOnException = null;
511 if (sandboxDir != null) return deleteDir(sandboxDir); 522 if (_sandboxDir != null) {
523 var dir = _sandboxDir;
524 _sandboxDir = null;
525 return deleteDir(dir);
526 }
512 }); 527 });
513 }).then((_) { 528 }).then((_) {
514 // If we got here, the test completed successfully so tell unittest so. 529 // If we got here, the test completed successfully so tell unittest so.
515 asyncDone(); 530 asyncDone();
516 }).catchError((e) { 531 }).catchError((e) {
517 // If we got here, an error occurred. We will register it with unittest 532 // If we got here, an error occurred. We will register it with unittest
518 // directly so that the error message isn't wrapped in any matcher stuff. 533 // directly so that the error message isn't wrapped in any matcher stuff.
519 // We do this call last because it will cause unittest to *synchronously* 534 // We do this call last because it will cause unittest to *synchronously*
520 // advance to the next test and run it. 535 // advance to the next test and run it.
521 registerException(e.error, e.stackTrace); 536 registerException(e.error, e.stackTrace);
522 }); 537 });
523 }); 538 });
524 } 539 }
525 540
526 /// Get the path to the root "util/test/pub" directory containing the pub 541 /// Get the path to the root "util/test/pub" directory containing the pub
527 /// tests. 542 /// tests.
528 String get testDirectory { 543 String get testDirectory {
529 var dir = new Options().script; 544 var dir = new Options().script;
530 while (basename(dir) != 'pub') dir = dirname(dir); 545 while (basename(dir) != 'pub') dir = dirname(dir);
531 546
532 return getFullPath(dir); 547 return getFullPath(dir);
533 } 548 }
534 549
550 /// Schedules renaming (moving) the directory at [from] to [to], both of which
551 /// are assumed to be relative to [sandboxDir].
552 void scheduleRename(String from, String to) {
553 _schedule((sandboxDir) {
554 return renameDir(join(sandboxDir, from), join(sandboxDir, to));
555 });
556 }
557
535 /// Schedules a call to the Pub command-line utility. Runs Pub with [args] and 558 /// Schedules a call to the Pub command-line utility. Runs Pub with [args] and
536 /// validates that its results match [output], [error], and [exitCode]. 559 /// validates that its results match [output], [error], and [exitCode].
537 void schedulePub({List args, Pattern output, Pattern error, 560 void schedulePub({List args, Pattern output, Pattern error,
538 Future<Uri> tokenEndpoint, int exitCode: 0}) { 561 Future<Uri> tokenEndpoint, int exitCode: 0}) {
539 _schedule((sandboxDir) { 562 _schedule((sandboxDir) {
540 return _doPub(runProcess, sandboxDir, args, tokenEndpoint).then((result) { 563 return _doPub(runProcess, sandboxDir, args, tokenEndpoint).then((result) {
541 var failures = []; 564 var failures = [];
542 565
543 _validateOutput(failures, 'stdout', output, result.stdout); 566 _validateOutput(failures, 'stdout', output, result.stdout);
544 _validateOutput(failures, 'stderr', error, result.stderr); 567 _validateOutput(failures, 'stderr', error, result.stderr);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 expectLater(pub.nextLine(), equals('Publishing "test_pkg" 1.0.0:')); 618 expectLater(pub.nextLine(), equals('Publishing "test_pkg" 1.0.0:'));
596 expectLater(pub.nextLine(), equals("|-- LICENSE")); 619 expectLater(pub.nextLine(), equals("|-- LICENSE"));
597 expectLater(pub.nextLine(), equals("|-- lib")); 620 expectLater(pub.nextLine(), equals("|-- lib"));
598 expectLater(pub.nextLine(), equals("| '-- test_pkg.dart")); 621 expectLater(pub.nextLine(), equals("| '-- test_pkg.dart"));
599 expectLater(pub.nextLine(), equals("'-- pubspec.yaml")); 622 expectLater(pub.nextLine(), equals("'-- pubspec.yaml"));
600 expectLater(pub.nextLine(), equals("")); 623 expectLater(pub.nextLine(), equals(""));
601 624
602 pub.writeLine("y"); 625 pub.writeLine("y");
603 } 626 }
604 627
605
606 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] 628 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
607 /// should have the same signature as [startProcess], except that the returned 629 /// should have the same signature as [startProcess], except that the returned
608 /// [Future] may have a type other than [Process]. 630 /// [Future] may have a type other than [Process].
609 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { 631 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
610 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); 632 String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
611 return defer(() { 633 return defer(() {
612 ensureDir(pathInSandbox(appPath)); 634 ensureDir(pathInSandbox(appPath));
613 return Future.wait([ 635 return Future.wait([
614 _awaitObject(args), 636 _awaitObject(args),
615 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint 637 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 /// Note that this will only affect HTTP requests made via http.dart in the 692 /// Note that this will only affect HTTP requests made via http.dart in the
671 /// parent process. 693 /// parent process.
672 void useMockClient(MockClient client) { 694 void useMockClient(MockClient client) {
673 var oldInnerClient = httpClient.inner; 695 var oldInnerClient = httpClient.inner;
674 httpClient.inner = client; 696 httpClient.inner = client;
675 _scheduleCleanup((_) { 697 _scheduleCleanup((_) {
676 httpClient.inner = oldInnerClient; 698 httpClient.inner = oldInnerClient;
677 }); 699 });
678 } 700 }
679 701
680 Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) { 702 Future _runScheduled(List<_ScheduledEvent> scheduled) {
681 if (scheduled == null) return new Future.immediate(null); 703 if (scheduled == null) return new Future.immediate(null);
682 var iterator = scheduled.iterator; 704 var iterator = scheduled.iterator;
683 705
684 Future runNextEvent(_) { 706 Future runNextEvent(_) {
685 if (_abortScheduled || !iterator.moveNext()) { 707 if (_abortScheduled || !iterator.moveNext()) {
686 _abortScheduled = false; 708 _abortScheduled = false;
687 scheduled.clear(); 709 scheduled.clear();
688 return new Future.immediate(null); 710 return new Future.immediate(null);
689 } 711 }
690 712
691 var future = iterator.current(parentDir); 713 var future = iterator.current(_sandboxDir);
692 if (future != null) { 714 if (future != null) {
693 return future.then(runNextEvent); 715 return future.then(runNextEvent);
694 } else { 716 } else {
695 return runNextEvent(null); 717 return runNextEvent(null);
696 } 718 }
697 } 719 }
698 720
699 return runNextEvent(null); 721 return runNextEvent(null);
700 } 722 }
701 723
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 throw "Can't load ${Strings.join(path, '/')} from within $name: $name " 1182 throw "Can't load ${Strings.join(path, '/')} from within $name: $name "
1161 "doesn't exist."; 1183 "doesn't exist.";
1162 } 1184 }
1163 } 1185 }
1164 } 1186 }
1165 1187
1166 /// A function that creates a [Validator] subclass. 1188 /// A function that creates a [Validator] subclass.
1167 typedef Validator ValidatorCreator(Entrypoint entrypoint); 1189 typedef Validator ValidatorCreator(Entrypoint entrypoint);
1168 1190
1169 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled 1191 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
1170 /// Future that contains the erros and warnings produced by that validator. 1192 /// Future that contains the errors and warnings produced by that validator.
1171 Future<Pair<List<String>, List<String>>> schedulePackageValidation( 1193 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
1172 ValidatorCreator fn) { 1194 ValidatorCreator fn) {
1173 return _scheduleValue((sandboxDir) { 1195 return _scheduleValue((sandboxDir) {
1174 var cache = new SystemCache.withSources(join(sandboxDir, cachePath)); 1196 var cache = new SystemCache.withSources(join(sandboxDir, cachePath));
1175 1197
1176 return defer(() { 1198 return defer(() {
1177 var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache)); 1199 var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache));
1178 return validator.validate().then((_) { 1200 return validator.validate().then((_) {
1179 return new Pair(validator.errors, validator.warnings); 1201 return new Pair(validator.errors, validator.warnings);
1180 }); 1202 });
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 /// calling [completion] is unnecessary. 1621 /// calling [completion] is unnecessary.
1600 void expectLater(Future actual, matcher, {String reason, 1622 void expectLater(Future actual, matcher, {String reason,
1601 FailureHandler failureHandler, bool verbose: false}) { 1623 FailureHandler failureHandler, bool verbose: false}) {
1602 _schedule((_) { 1624 _schedule((_) {
1603 return actual.then((value) { 1625 return actual.then((value) {
1604 expect(value, matcher, reason: reason, failureHandler: failureHandler, 1626 expect(value, matcher, reason: reason, failureHandler: failureHandler,
1605 verbose: false); 1627 verbose: false);
1606 }); 1628 });
1607 }); 1629 });
1608 } 1630 }
OLDNEW
« no previous file with comments | « utils/tests/pub/install/path/relative_path_test.dart ('k') | utils/tests/pub/validator_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698