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

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

Issue 12079112: Make a bunch of stuff in pub synchronous. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
« utils/pub/utils.dart ('K') | « utils/tests/pub/io_test.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 /// 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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 578
579 pub.writeLine("y"); 579 pub.writeLine("y");
580 } 580 }
581 581
582 582
583 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] 583 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
584 /// should have the same signature as [startProcess], except that the returned 584 /// should have the same signature as [startProcess], except that the returned
585 /// [Future] may have a type other than [Process]. 585 /// [Future] may have a type other than [Process].
586 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { 586 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
587 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); 587 String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
588 588 // Make sure all errors propagate through future.
589 return Future.wait([ 589 return defer(() {
590 ensureDir(pathInSandbox(appPath)), 590 ensureDir(pathInSandbox(appPath));
591 _awaitObject(args), 591 return Future.wait([
592 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint 592 _awaitObject(args),
593 ]).then((results) { 593 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
594 var args = results[1]; 594 ]);
595 var tokenEndpoint = results[2]; 595 }).then((results) {
596 var args = results[0];
597 var tokenEndpoint = results[1];
596 // Find a Dart executable we can use to spawn. Use the same one that was 598 // Find a Dart executable we can use to spawn. Use the same one that was
597 // used to run this script itself. 599 // used to run this script itself.
598 var dartBin = new Options().executable; 600 var dartBin = new Options().executable;
599 601
600 // If the executable looks like a path, get its full path. That way we 602 // If the executable looks like a path, get its full path. That way we
601 // can still find it when we spawn it with a different working directory. 603 // can still find it when we spawn it with a different working directory.
602 if (dartBin.contains(Platform.pathSeparator)) { 604 if (dartBin.contains(Platform.pathSeparator)) {
603 dartBin = new File(dartBin).fullPathSync(); 605 dartBin = new File(dartBin).fullPathSync();
604 } 606 }
605 607
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 /// directory. 795 /// directory.
794 void scheduleValidate() => _schedule((parentDir) => validate(parentDir.path)); 796 void scheduleValidate() => _schedule((parentDir) => validate(parentDir.path));
795 797
796 /// Asserts that the name of the descriptor is a [String] and returns it. 798 /// Asserts that the name of the descriptor is a [String] and returns it.
797 String get _stringName { 799 String get _stringName {
798 if (name is String) return name; 800 if (name is String) return name;
799 throw 'Pattern $name must be a string.'; 801 throw 'Pattern $name must be a string.';
800 } 802 }
801 803
802 /// Validates that at least one file in [dir] matching [name] is valid 804 /// Validates that at least one file in [dir] matching [name] is valid
803 /// according to [validate]. [validate] should complete to an exception if 805 /// according to [validate]. [validate] should throw or complete to an
804 /// the input path is invalid. 806 /// exception if the input path is invalid.
805 Future _validateOneMatch(String dir, Future validate(String path)) { 807 Future _validateOneMatch(String dir, Future validate(String path)) {
806 // Special-case strings to support multi-level names like "myapp/packages". 808 // Special-case strings to support multi-level names like "myapp/packages".
807 if (name is String) { 809 if (name is String) {
808 var path = join(dir, name); 810 var path = join(dir, name);
809 return exists(path).then((exists) { 811 // Make sure errors propagate through future.
810 if (!exists) { 812 return defer(() {
813 if (!entryExists(path)) {
811 throw new ExpectException('File $name in $dir not found.'); 814 throw new ExpectException('File $name in $dir not found.');
812 } 815 }
813 return validate(path); 816 return validate(path);
814 }); 817 });
815 } 818 }
816 819
817 // TODO(nweiz): remove this when issue 4061 is fixed. 820 // TODO(nweiz): remove this when issue 4061 is fixed.
818 var stackTrace; 821 var stackTrace;
819 try { 822 try {
820 throw ""; 823 throw "";
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 /// tree before running a test, and for validating that the file system matches 869 /// tree before running a test, and for validating that the file system matches
867 /// some expectations after running it. 870 /// some expectations after running it.
868 class FileDescriptor extends Descriptor { 871 class FileDescriptor extends Descriptor {
869 /// The text contents of the file. 872 /// The text contents of the file.
870 final String contents; 873 final String contents;
871 874
872 FileDescriptor(Pattern name, this.contents) : super(name); 875 FileDescriptor(Pattern name, this.contents) : super(name);
873 876
874 /// Creates the file within [dir]. Returns a [Future] that is completed after 877 /// Creates the file within [dir]. Returns a [Future] that is completed after
875 /// the creation is done. 878 /// the creation is done.
876 Future<File> create(dir) { 879 Future<File> create(dir) =>
877 return writeTextFile(join(dir, _stringName), contents); 880 defer(() => writeTextFile(join(dir, _stringName), contents));
878 }
879 881
880 /// Deletes the file within [dir]. Returns a [Future] that is completed after 882 /// Deletes the file within [dir]. Returns a [Future] that is completed after
881 /// the deletion is done. 883 /// the deletion is done.
882 Future delete(dir) { 884 Future delete(dir) =>
883 return deleteFile(join(dir, _stringName)); 885 defer(() => deleteFile(join(dir, _stringName)));
884 }
885 886
886 /// Validates that this file correctly matches the actual file at [path]. 887 /// Validates that this file correctly matches the actual file at [path].
887 Future validate(String path) { 888 Future validate(String path) {
888 return _validateOneMatch(path, (file) { 889 return _validateOneMatch(path, (file) {
889 return readTextFile(file).then((text) { 890 var text = readTextFile(file);
890 if (text == contents) return null; 891 if (text == contents) return null;
891 892
892 throw new ExpectException( 893 throw new ExpectException(
893 'File $file should contain:\n\n$contents\n\n' 894 'File $file should contain:\n\n$contents\n\n'
894 'but contained:\n\n$text'); 895 'but contained:\n\n$text');
895 });
896 }); 896 });
897 } 897 }
898 898
899 /// Loads the contents of the file. 899 /// Loads the contents of the file.
900 InputStream load(List<String> path) { 900 InputStream load(List<String> path) {
901 if (!path.isEmpty) { 901 if (!path.isEmpty) {
902 var joinedPath = Strings.join(path, '/'); 902 var joinedPath = Strings.join(path, '/');
903 throw "Can't load $joinedPath from within $name: not a directory."; 903 throw "Can't load $joinedPath from within $name: not a directory.";
904 } 904 }
905 905
(...skipping 11 matching lines...) Expand all
917 /// The files and directories contained in this directory. 917 /// The files and directories contained in this directory.
918 final List<Descriptor> contents; 918 final List<Descriptor> contents;
919 919
920 DirectoryDescriptor(Pattern name, List<Descriptor> contents) 920 DirectoryDescriptor(Pattern name, List<Descriptor> contents)
921 : this.contents = contents == null ? <Descriptor>[] : contents, 921 : this.contents = contents == null ? <Descriptor>[] : contents,
922 super(name); 922 super(name);
923 923
924 /// Creates the file within [dir]. Returns a [Future] that is completed after 924 /// Creates the file within [dir]. Returns a [Future] that is completed after
925 /// the creation is done. 925 /// the creation is done.
926 Future<Directory> create(parentDir) { 926 Future<Directory> create(parentDir) {
927 // Create the directory. 927 // Make sure all errors propagate through the future.
928 return ensureDir(join(parentDir, _stringName)).then((dir) { 928 return defer(() {
929 if (contents == null) return new Future<Directory>.immediate(dir); 929 // Create the directory.
930 var dir = ensureDir(join(parentDir, _stringName));
931 if (contents == null) return dir;
930 932
931 // Recursively create all of its children. 933 // Recursively create all of its children.
932 final childFutures = 934 var childFutures = contents.map((child) => child.create(dir)).toList();
933 contents.map((child) => child.create(dir)).toList();
934 // Only complete once all of the children have been created too. 935 // Only complete once all of the children have been created too.
935 return Future.wait(childFutures).then((_) => dir); 936 return Future.wait(childFutures).then((_) => dir);
936 }); 937 });
937 } 938 }
938 939
939 /// Deletes the directory within [dir]. Returns a [Future] that is completed 940 /// Deletes the directory within [dir]. Returns a [Future] that is completed
940 /// after the deletion is done. 941 /// after the deletion is done.
941 Future delete(dir) { 942 Future delete(dir) {
942 return deleteDir(join(dir, _stringName)); 943 return deleteDir(join(dir, _stringName));
943 } 944 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 } 1128 }
1128 1129
1129 /// A descriptor that validates that no file exists with the given name. 1130 /// A descriptor that validates that no file exists with the given name.
1130 class NothingDescriptor extends Descriptor { 1131 class NothingDescriptor extends Descriptor {
1131 NothingDescriptor(String name) : super(name); 1132 NothingDescriptor(String name) : super(name);
1132 1133
1133 Future create(dir) => new Future.immediate(null); 1134 Future create(dir) => new Future.immediate(null);
1134 Future delete(dir) => new Future.immediate(null); 1135 Future delete(dir) => new Future.immediate(null);
1135 1136
1136 Future validate(String dir) { 1137 Future validate(String dir) {
1137 return exists(join(dir, name)).then((exists) { 1138 // Make sure errors propagate through future.
1138 if (exists) { 1139 return defer(() {
1140 if (entryExists(join(dir, name))) {
1139 throw new ExpectException('File $name in $dir should not exist.'); 1141 throw new ExpectException('File $name in $dir should not exist.');
1140 } 1142 }
1141 }); 1143 });
1142 } 1144 }
1143 1145
1144 InputStream load(List<String> path) { 1146 InputStream load(List<String> path) {
1145 if (path.isEmpty) { 1147 if (path.isEmpty) {
1146 throw "Can't load the contents of $name: it doesn't exist."; 1148 throw "Can't load the contents of $name: it doesn't exist.";
1147 } else { 1149 } else {
1148 throw "Can't load ${Strings.join(path, '/')} from within $name: $name " 1150 throw "Can't load ${Strings.join(path, '/')} from within $name: $name "
1149 "doesn't exist."; 1151 "doesn't exist.";
1150 } 1152 }
1151 } 1153 }
1152 } 1154 }
1153 1155
1154 /// A function that creates a [Validator] subclass. 1156 /// A function that creates a [Validator] subclass.
1155 typedef Validator ValidatorCreator(Entrypoint entrypoint); 1157 typedef Validator ValidatorCreator(Entrypoint entrypoint);
1156 1158
1157 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled 1159 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
1158 /// Future that contains the erros and warnings produced by that validator. 1160 /// Future that contains the erros and warnings produced by that validator.
1159 Future<Pair<List<String>, List<String>>> schedulePackageValidation( 1161 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
1160 ValidatorCreator fn) { 1162 ValidatorCreator fn) {
1161 return _scheduleValue((sandboxDir) { 1163 return _scheduleValue((sandboxDir) {
1162 var cache = new SystemCache.withSources( 1164 var cache = new SystemCache.withSources(join(sandboxDir, cachePath));
1163 join(sandboxDir, cachePath));
1164 1165
1165 return Entrypoint.load(join(sandboxDir, appPath), cache) 1166 return defer(() {
1166 .then((entrypoint) { 1167 var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache));
1167 var validator = fn(entrypoint);
1168 return validator.validate().then((_) { 1168 return validator.validate().then((_) {
1169 return new Pair(validator.errors, validator.warnings); 1169 return new Pair(validator.errors, validator.warnings);
1170 }); 1170 });
1171 }); 1171 });
1172 }); 1172 });
1173 } 1173 }
1174 1174
1175 /// A matcher that matches a Pair. 1175 /// A matcher that matches a Pair.
1176 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) => 1176 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
1177 new _PairMatcher(firstMatcher, lastMatcher); 1177 new _PairMatcher(firstMatcher, lastMatcher);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 } 1466 }
1467 1467
1468 /// Ignore all requests with the given [method] and [path]. If one is 1468 /// Ignore all requests with the given [method] and [path]. If one is
1469 /// received, don't respond to it. 1469 /// received, don't respond to it.
1470 void ignore(String method, String path) => 1470 void ignore(String method, String path) =>
1471 _ignored.add(new Pair(method, path)); 1471 _ignored.add(new Pair(method, path));
1472 1472
1473 /// Raises an error complaining of an unexpected request. 1473 /// Raises an error complaining of an unexpected request.
1474 void _awaitHandle(HttpRequest request, HttpResponse response) { 1474 void _awaitHandle(HttpRequest request, HttpResponse response) {
1475 if (_ignored.contains(new Pair(request.method, request.path))) return; 1475 if (_ignored.contains(new Pair(request.method, request.path))) return;
1476 var future = timeout(new Future.immediate(null).then((_) { 1476 // Make sure all errors propagate through future.
1477 var future = timeout(defer(() {
1477 if (_handlers.isEmpty) { 1478 if (_handlers.isEmpty) {
1478 fail('Unexpected ${request.method} request to ${request.path}.'); 1479 fail('Unexpected ${request.method} request to ${request.path}.');
1479 } 1480 }
1480 return _handlers.removeFirst(); 1481 return _handlers.removeFirst();
1481 }).then((handler) { 1482 }).then((handler) {
1482 handler(request, response); 1483 handler(request, response);
1483 }), _SCHEDULE_TIMEOUT, "waiting for a handler for ${request.method} " 1484 }), _SCHEDULE_TIMEOUT, "waiting for a handler for ${request.method} "
1484 "${request.path}"); 1485 "${request.path}");
1485 expect(future, completes); 1486 expect(future, completes);
1486 } 1487 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 /// calling [completion] is unnecessary. 1551 /// calling [completion] is unnecessary.
1551 void expectLater(Future actual, matcher, {String reason, 1552 void expectLater(Future actual, matcher, {String reason,
1552 FailureHandler failureHandler, bool verbose: false}) { 1553 FailureHandler failureHandler, bool verbose: false}) {
1553 _schedule((_) { 1554 _schedule((_) {
1554 return actual.then((value) { 1555 return actual.then((value) {
1555 expect(value, matcher, reason: reason, failureHandler: failureHandler, 1556 expect(value, matcher, reason: reason, failureHandler: failureHandler,
1556 verbose: false); 1557 verbose: false);
1557 }); 1558 });
1558 }); 1559 });
1559 } 1560 }
OLDNEW
« utils/pub/utils.dart ('K') | « utils/tests/pub/io_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698