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

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: Fix after merge. 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
« no previous file with comments | « 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 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 597
598 pub.writeLine("y"); 598 pub.writeLine("y");
599 } 599 }
600 600
601 601
602 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] 602 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
603 /// should have the same signature as [startProcess], except that the returned 603 /// should have the same signature as [startProcess], except that the returned
604 /// [Future] may have a type other than [Process]. 604 /// [Future] may have a type other than [Process].
605 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { 605 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
606 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); 606 String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
607 607 return defer(() {
608 return Future.wait([ 608 ensureDir(pathInSandbox(appPath));
609 ensureDir(pathInSandbox(appPath)), 609 return Future.wait([
610 _awaitObject(args), 610 _awaitObject(args),
611 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint 611 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
612 ]).then((results) { 612 ]);
613 var args = results[1]; 613 }).then((results) {
614 var tokenEndpoint = results[2]; 614 var args = results[0];
615 var tokenEndpoint = results[1];
615 // Find a Dart executable we can use to spawn. Use the same one that was 616 // Find a Dart executable we can use to spawn. Use the same one that was
616 // used to run this script itself. 617 // used to run this script itself.
617 var dartBin = new Options().executable; 618 var dartBin = new Options().executable;
618 619
619 // If the executable looks like a path, get its full path. That way we 620 // If the executable looks like a path, get its full path. That way we
620 // can still find it when we spawn it with a different working directory. 621 // can still find it when we spawn it with a different working directory.
621 if (dartBin.contains(Platform.pathSeparator)) { 622 if (dartBin.contains(Platform.pathSeparator)) {
622 dartBin = new File(dartBin).fullPathSync(); 623 dartBin = new File(dartBin).fullPathSync();
623 } 624 }
624 625
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 /// directory. 813 /// directory.
813 void scheduleValidate() => _schedule((parentDir) => validate(parentDir.path)); 814 void scheduleValidate() => _schedule((parentDir) => validate(parentDir.path));
814 815
815 /// Asserts that the name of the descriptor is a [String] and returns it. 816 /// Asserts that the name of the descriptor is a [String] and returns it.
816 String get _stringName { 817 String get _stringName {
817 if (name is String) return name; 818 if (name is String) return name;
818 throw 'Pattern $name must be a string.'; 819 throw 'Pattern $name must be a string.';
819 } 820 }
820 821
821 /// Validates that at least one file in [dir] matching [name] is valid 822 /// Validates that at least one file in [dir] matching [name] is valid
822 /// according to [validate]. [validate] should complete to an exception if 823 /// according to [validate]. [validate] should throw or complete to an
823 /// the input path is invalid. 824 /// exception if the input path is invalid.
824 Future _validateOneMatch(String dir, Future validate(String path)) { 825 Future _validateOneMatch(String dir, Future validate(String path)) {
825 // Special-case strings to support multi-level names like "myapp/packages". 826 // Special-case strings to support multi-level names like "myapp/packages".
826 if (name is String) { 827 if (name is String) {
827 var path = join(dir, name); 828 var path = join(dir, name);
828 return exists(path).then((exists) { 829 return defer(() {
829 if (!exists) { 830 if (!entryExists(path)) {
830 throw new ExpectException('File $name in $dir not found.'); 831 throw new ExpectException('File $name in $dir not found.');
831 } 832 }
832 return validate(path); 833 return validate(path);
833 }); 834 });
834 } 835 }
835 836
836 // TODO(nweiz): remove this when issue 4061 is fixed. 837 // TODO(nweiz): remove this when issue 4061 is fixed.
837 var stackTrace; 838 var stackTrace;
838 try { 839 try {
839 throw ""; 840 throw "";
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 891
891 String get textContents => new String.fromCharCodes(contents); 892 String get textContents => new String.fromCharCodes(contents);
892 893
893 FileDescriptor.bytes(Pattern name, this.contents) : super(name); 894 FileDescriptor.bytes(Pattern name, this.contents) : super(name);
894 895
895 FileDescriptor(Pattern name, String contents) : 896 FileDescriptor(Pattern name, String contents) :
896 this.bytes(name, encodeUtf8(contents)); 897 this.bytes(name, encodeUtf8(contents));
897 898
898 /// Creates the file within [dir]. Returns a [Future] that is completed after 899 /// Creates the file within [dir]. Returns a [Future] that is completed after
899 /// the creation is done. 900 /// the creation is done.
900 Future<File> create(dir) => new Future.immediate(null).then((_) => 901 Future<File> create(dir) =>
901 writeBinaryFile(join(dir, _stringName), contents)); 902 defer(() => writeBinaryFile(join(dir, _stringName), contents));
902 903
903 /// Deletes the file within [dir]. Returns a [Future] that is completed after 904 /// Deletes the file within [dir]. Returns a [Future] that is completed after
904 /// the deletion is done. 905 /// the deletion is done.
905 Future delete(dir) { 906 Future delete(dir) =>
906 return deleteFile(join(dir, _stringName)); 907 defer(() => deleteFile(join(dir, _stringName)));
907 }
908 908
909 /// Validates that this file correctly matches the actual file at [path]. 909 /// Validates that this file correctly matches the actual file at [path].
910 Future validate(String path) { 910 Future validate(String path) {
911 return _validateOneMatch(path, (file) { 911 return _validateOneMatch(path, (file) {
912 return readTextFile(file).then((text) { 912 var text = readTextFile(file);
913 if (text == textContents) return null; 913 if (text == textContents) return null;
914 914
915 throw new ExpectException( 915 throw new ExpectException(
916 'File $file should contain:\n\n$textContents\n\n' 916 'File $file should contain:\n\n$textContents\n\n'
917 'but contained:\n\n$text'); 917 'but contained:\n\n$text');
918 });
919 }); 918 });
920 } 919 }
921 920
922 /// Loads the contents of the file. 921 /// Loads the contents of the file.
923 ByteStream load(List<String> path) { 922 ByteStream load(List<String> path) {
924 if (!path.isEmpty) { 923 if (!path.isEmpty) {
925 var joinedPath = Strings.join(path, '/'); 924 var joinedPath = Strings.join(path, '/');
926 throw "Can't load $joinedPath from within $name: not a directory."; 925 throw "Can't load $joinedPath from within $name: not a directory.";
927 } 926 }
928 927
929 return new ByteStream.fromBytes(contents); 928 return new ByteStream.fromBytes(contents);
930 } 929 }
931 } 930 }
932 931
933 /// Describes a directory and its contents. These are used both for setting up 932 /// Describes a directory and its contents. These are used both for setting up
934 /// an expected directory tree before running a test, and for validating that 933 /// an expected directory tree before running a test, and for validating that
935 /// the file system matches some expectations after running it. 934 /// the file system matches some expectations after running it.
936 class DirectoryDescriptor extends Descriptor { 935 class DirectoryDescriptor extends Descriptor {
937 /// The files and directories contained in this directory. 936 /// The files and directories contained in this directory.
938 final List<Descriptor> contents; 937 final List<Descriptor> contents;
939 938
940 DirectoryDescriptor(Pattern name, List<Descriptor> contents) 939 DirectoryDescriptor(Pattern name, List<Descriptor> contents)
941 : this.contents = contents == null ? <Descriptor>[] : contents, 940 : this.contents = contents == null ? <Descriptor>[] : contents,
942 super(name); 941 super(name);
943 942
944 /// Creates the file within [dir]. Returns a [Future] that is completed after 943 /// Creates the file within [dir]. Returns a [Future] that is completed after
945 /// the creation is done. 944 /// the creation is done.
946 Future<Directory> create(parentDir) { 945 Future<Directory> create(parentDir) {
947 // Create the directory. 946 return defer(() {
948 return ensureDir(join(parentDir, _stringName)).then((dir) { 947 // Create the directory.
949 if (contents == null) return new Future<Directory>.immediate(dir); 948 var dir = ensureDir(join(parentDir, _stringName));
949 if (contents == null) return dir;
950 950
951 // Recursively create all of its children. 951 // Recursively create all of its children.
952 final childFutures = 952 var childFutures = contents.map((child) => child.create(dir)).toList();
953 contents.map((child) => child.create(dir)).toList();
954 // Only complete once all of the children have been created too. 953 // Only complete once all of the children have been created too.
955 return Future.wait(childFutures).then((_) => dir); 954 return Future.wait(childFutures).then((_) => dir);
956 }); 955 });
957 } 956 }
958 957
959 /// Deletes the directory within [dir]. Returns a [Future] that is completed 958 /// Deletes the directory within [dir]. Returns a [Future] that is completed
960 /// after the deletion is done. 959 /// after the deletion is done.
961 Future delete(dir) { 960 Future delete(dir) {
962 return deleteDir(join(dir, _stringName)); 961 return deleteDir(join(dir, _stringName));
963 } 962 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 } 1146 }
1148 1147
1149 /// A descriptor that validates that no file exists with the given name. 1148 /// A descriptor that validates that no file exists with the given name.
1150 class NothingDescriptor extends Descriptor { 1149 class NothingDescriptor extends Descriptor {
1151 NothingDescriptor(String name) : super(name); 1150 NothingDescriptor(String name) : super(name);
1152 1151
1153 Future create(dir) => new Future.immediate(null); 1152 Future create(dir) => new Future.immediate(null);
1154 Future delete(dir) => new Future.immediate(null); 1153 Future delete(dir) => new Future.immediate(null);
1155 1154
1156 Future validate(String dir) { 1155 Future validate(String dir) {
1157 return exists(join(dir, name)).then((exists) { 1156 return defer(() {
1158 if (exists) { 1157 if (entryExists(join(dir, name))) {
1159 throw new ExpectException('File $name in $dir should not exist.'); 1158 throw new ExpectException('File $name in $dir should not exist.');
1160 } 1159 }
1161 }); 1160 });
1162 } 1161 }
1163 1162
1164 ByteStream load(List<String> path) { 1163 ByteStream load(List<String> path) {
1165 if (path.isEmpty) { 1164 if (path.isEmpty) {
1166 throw "Can't load the contents of $name: it doesn't exist."; 1165 throw "Can't load the contents of $name: it doesn't exist.";
1167 } else { 1166 } else {
1168 throw "Can't load ${Strings.join(path, '/')} from within $name: $name " 1167 throw "Can't load ${Strings.join(path, '/')} from within $name: $name "
1169 "doesn't exist."; 1168 "doesn't exist.";
1170 } 1169 }
1171 } 1170 }
1172 } 1171 }
1173 1172
1174 /// A function that creates a [Validator] subclass. 1173 /// A function that creates a [Validator] subclass.
1175 typedef Validator ValidatorCreator(Entrypoint entrypoint); 1174 typedef Validator ValidatorCreator(Entrypoint entrypoint);
1176 1175
1177 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled 1176 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
1178 /// Future that contains the erros and warnings produced by that validator. 1177 /// Future that contains the erros and warnings produced by that validator.
1179 Future<Pair<List<String>, List<String>>> schedulePackageValidation( 1178 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
1180 ValidatorCreator fn) { 1179 ValidatorCreator fn) {
1181 return _scheduleValue((sandboxDir) { 1180 return _scheduleValue((sandboxDir) {
1182 var cache = new SystemCache.withSources( 1181 var cache = new SystemCache.withSources(join(sandboxDir, cachePath));
1183 join(sandboxDir, cachePath));
1184 1182
1185 return Entrypoint.load(join(sandboxDir, appPath), cache) 1183 return defer(() {
1186 .then((entrypoint) { 1184 var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache));
1187 var validator = fn(entrypoint);
1188 return validator.validate().then((_) { 1185 return validator.validate().then((_) {
1189 return new Pair(validator.errors, validator.warnings); 1186 return new Pair(validator.errors, validator.warnings);
1190 }); 1187 });
1191 }); 1188 });
1192 }); 1189 });
1193 } 1190 }
1194 1191
1195 /// A matcher that matches a Pair. 1192 /// A matcher that matches a Pair.
1196 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) => 1193 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
1197 new _PairMatcher(firstMatcher, lastMatcher); 1194 new _PairMatcher(firstMatcher, lastMatcher);
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 } 1519 }
1523 1520
1524 /// Ignore all requests with the given [method] and [path]. If one is 1521 /// Ignore all requests with the given [method] and [path]. If one is
1525 /// received, don't respond to it. 1522 /// received, don't respond to it.
1526 void ignore(String method, String path) => 1523 void ignore(String method, String path) =>
1527 _ignored.add(new Pair(method, path)); 1524 _ignored.add(new Pair(method, path));
1528 1525
1529 /// Raises an error complaining of an unexpected request. 1526 /// Raises an error complaining of an unexpected request.
1530 void _awaitHandle(HttpRequest request, HttpResponse response) { 1527 void _awaitHandle(HttpRequest request, HttpResponse response) {
1531 if (_ignored.contains(new Pair(request.method, request.path))) return; 1528 if (_ignored.contains(new Pair(request.method, request.path))) return;
1532 var future = timeout(new Future.immediate(null).then((_) { 1529 var future = timeout(defer(() {
1533 if (_handlers.isEmpty) { 1530 if (_handlers.isEmpty) {
1534 fail('Unexpected ${request.method} request to ${request.path}.'); 1531 fail('Unexpected ${request.method} request to ${request.path}.');
1535 } 1532 }
1536 return _handlers.removeFirst(); 1533 return _handlers.removeFirst();
1537 }).then((handler) { 1534 }).then((handler) {
1538 handler(request, response); 1535 handler(request, response);
1539 }), _SCHEDULE_TIMEOUT, "waiting for a handler for ${request.method} " 1536 }), _SCHEDULE_TIMEOUT, "waiting for a handler for ${request.method} "
1540 "${request.path}"); 1537 "${request.path}");
1541 expect(future, completes); 1538 expect(future, completes);
1542 } 1539 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 /// calling [completion] is unnecessary. 1603 /// calling [completion] is unnecessary.
1607 void expectLater(Future actual, matcher, {String reason, 1604 void expectLater(Future actual, matcher, {String reason,
1608 FailureHandler failureHandler, bool verbose: false}) { 1605 FailureHandler failureHandler, bool verbose: false}) {
1609 _schedule((_) { 1606 _schedule((_) {
1610 return actual.then((value) { 1607 return actual.then((value) {
1611 expect(value, matcher, reason: reason, failureHandler: failureHandler, 1608 expect(value, matcher, reason: reason, failureHandler: failureHandler,
1612 verbose: false); 1609 verbose: false);
1613 }); 1610 });
1614 }); 1611 });
1615 } 1612 }
OLDNEW
« no previous file with comments | « utils/tests/pub/io_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698