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

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

Issue 12253054: Get rid of join() and encapsulate File and Directory in io.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase. 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') | utils/tests/pub/validator_test.dart » ('j') | 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 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 var dir = new Options().script; 546 var dir = new Options().script;
547 while (path.basename(dir) != 'pub') dir = path.dirname(dir); 547 while (path.basename(dir) != 'pub') dir = path.dirname(dir);
548 548
549 return path.absolute(dir); 549 return path.absolute(dir);
550 } 550 }
551 551
552 /// Schedules renaming (moving) the directory at [from] to [to], both of which 552 /// Schedules renaming (moving) the directory at [from] to [to], both of which
553 /// are assumed to be relative to [sandboxDir]. 553 /// are assumed to be relative to [sandboxDir].
554 void scheduleRename(String from, String to) { 554 void scheduleRename(String from, String to) {
555 _schedule((sandboxDir) { 555 _schedule((sandboxDir) {
556 return renameDir(join(sandboxDir, from), join(sandboxDir, to)); 556 return renameDir(path.join(sandboxDir, from), path.join(sandboxDir, to));
557 }); 557 });
558 } 558 }
559 559
560 /// Schedules a call to the Pub command-line utility. Runs Pub with [args] and 560 /// Schedules a call to the Pub command-line utility. Runs Pub with [args] and
561 /// validates that its results match [output], [error], and [exitCode]. 561 /// validates that its results match [output], [error], and [exitCode].
562 void schedulePub({List args, Pattern output, Pattern error, 562 void schedulePub({List args, Pattern output, Pattern error,
563 Future<Uri> tokenEndpoint, int exitCode: 0}) { 563 Future<Uri> tokenEndpoint, int exitCode: 0}) {
564 _schedule((sandboxDir) { 564 _schedule((sandboxDir) {
565 return _doPub(runProcess, sandboxDir, args, tokenEndpoint).then((result) { 565 return _doPub(runProcess, sandboxDir, args, tokenEndpoint).then((result) {
566 var failures = []; 566 var failures = [];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 expectLater(pub.nextLine(), equals("")); 625 expectLater(pub.nextLine(), equals(""));
626 626
627 pub.writeLine("y"); 627 pub.writeLine("y");
628 } 628 }
629 629
630 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] 630 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
631 /// should have the same signature as [startProcess], except that the returned 631 /// should have the same signature as [startProcess], except that the returned
632 /// [Future] may have a type other than [Process]. 632 /// [Future] may have a type other than [Process].
633 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { 633 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) {
634 String pathInSandbox(String relPath) { 634 String pathInSandbox(String relPath) {
635 return join(path.absolute(sandboxDir), relPath); 635 return path.join(path.absolute(sandboxDir), relPath);
636 } 636 }
637 637
638 return defer(() { 638 return defer(() {
639 ensureDir(pathInSandbox(appPath)); 639 ensureDir(pathInSandbox(appPath));
640 return Future.wait([ 640 return Future.wait([
641 _awaitObject(args), 641 _awaitObject(args),
642 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint 642 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint
643 ]); 643 ]);
644 }).then((results) { 644 }).then((results) {
645 var args = results[0]; 645 var args = results[0];
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 846
847 /// Asserts that the name of the descriptor is a [String] and returns it. 847 /// Asserts that the name of the descriptor is a [String] and returns it.
848 String get _stringName { 848 String get _stringName {
849 if (name is String) return name; 849 if (name is String) return name;
850 throw 'Pattern $name must be a string.'; 850 throw 'Pattern $name must be a string.';
851 } 851 }
852 852
853 /// Validates that at least one file in [dir] matching [name] is valid 853 /// Validates that at least one file in [dir] matching [name] is valid
854 /// according to [validate]. [validate] should throw or complete to an 854 /// according to [validate]. [validate] should throw or complete to an
855 /// exception if the input path is invalid. 855 /// exception if the input path is invalid.
856 Future _validateOneMatch(String dir, Future validate(String path)) { 856 Future _validateOneMatch(String dir, Future validate(String entry)) {
857 // Special-case strings to support multi-level names like "myapp/packages". 857 // Special-case strings to support multi-level names like "myapp/packages".
858 if (name is String) { 858 if (name is String) {
859 var path = join(dir, name); 859 var entry = path.join(dir, name);
860 return defer(() { 860 return defer(() {
861 if (!entryExists(path)) { 861 if (!entryExists(entry)) {
862 throw new ExpectException('Entry $path not found.'); 862 throw new ExpectException('Entry $entry not found.');
863 } 863 }
864 return validate(path); 864 return validate(entry);
865 }); 865 });
866 } 866 }
867 867
868 // TODO(nweiz): remove this when issue 4061 is fixed. 868 // TODO(nweiz): remove this when issue 4061 is fixed.
869 var stackTrace; 869 var stackTrace;
870 try { 870 try {
871 throw ""; 871 throw "";
872 } catch (_, localStackTrace) { 872 } catch (_, localStackTrace) {
873 stackTrace = localStackTrace; 873 stackTrace = localStackTrace;
874 } 874 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 922
923 String get textContents => new String.fromCharCodes(contents); 923 String get textContents => new String.fromCharCodes(contents);
924 924
925 FileDescriptor.bytes(Pattern name, this.contents) : super(name); 925 FileDescriptor.bytes(Pattern name, this.contents) : super(name);
926 926
927 FileDescriptor(Pattern name, String contents) : 927 FileDescriptor(Pattern name, String contents) :
928 this.bytes(name, encodeUtf8(contents)); 928 this.bytes(name, encodeUtf8(contents));
929 929
930 /// Creates the file within [dir]. Returns a [Future] that is completed after 930 /// Creates the file within [dir]. Returns a [Future] that is completed after
931 /// the creation is done. 931 /// the creation is done.
932 Future<File> create(dir) => 932 Future<String> create(dir) =>
933 defer(() => writeBinaryFile(join(dir, _stringName), contents)); 933 defer(() => writeBinaryFile(path.join(dir, _stringName), contents));
934 934
935 /// Deletes the file within [dir]. Returns a [Future] that is completed after 935 /// Deletes the file within [dir]. Returns a [Future] that is completed after
936 /// the deletion is done. 936 /// the deletion is done.
937 Future delete(dir) => 937 Future delete(dir) =>
938 defer(() => deleteFile(join(dir, _stringName))); 938 defer(() => deleteFile(path.join(dir, _stringName)));
939 939
940 /// Validates that this file correctly matches the actual file at [path]. 940 /// Validates that this file correctly matches the actual file at [path].
941 Future validate(String path) { 941 Future validate(String path) {
942 return _validateOneMatch(path, (file) { 942 return _validateOneMatch(path, (file) {
943 var text = readTextFile(file); 943 var text = readTextFile(file);
944 if (text == textContents) return null; 944 if (text == textContents) return null;
945 945
946 throw new ExpectException( 946 throw new ExpectException(
947 'File $file should contain:\n\n$textContents\n\n' 947 'File $file should contain:\n\n$textContents\n\n'
948 'but contained:\n\n$text'); 948 'but contained:\n\n$text');
(...skipping 16 matching lines...) Expand all
965 class DirectoryDescriptor extends Descriptor { 965 class DirectoryDescriptor extends Descriptor {
966 /// The files and directories contained in this directory. 966 /// The files and directories contained in this directory.
967 final List<Descriptor> contents; 967 final List<Descriptor> contents;
968 968
969 DirectoryDescriptor(Pattern name, List<Descriptor> contents) 969 DirectoryDescriptor(Pattern name, List<Descriptor> contents)
970 : this.contents = contents == null ? <Descriptor>[] : contents, 970 : this.contents = contents == null ? <Descriptor>[] : contents,
971 super(name); 971 super(name);
972 972
973 /// Creates the file within [dir]. Returns a [Future] that is completed after 973 /// Creates the file within [dir]. Returns a [Future] that is completed after
974 /// the creation is done. 974 /// the creation is done.
975 Future<Directory> create(parentDir) { 975 Future<String> create(parentDir) {
976 return defer(() { 976 return defer(() {
977 // Create the directory. 977 // Create the directory.
978 var dir = ensureDir(join(parentDir, _stringName)); 978 var dir = ensureDir(path.join(parentDir, _stringName));
979 if (contents == null) return dir; 979 if (contents == null) return dir;
980 980
981 // Recursively create all of its children. 981 // Recursively create all of its children.
982 var childFutures = contents.map((child) => child.create(dir)).toList(); 982 var childFutures = contents.map((child) => child.create(dir)).toList();
983 // Only complete once all of the children have been created too. 983 // Only complete once all of the children have been created too.
984 return Future.wait(childFutures).then((_) => dir); 984 return Future.wait(childFutures).then((_) => dir);
985 }); 985 });
986 } 986 }
987 987
988 /// Deletes the directory within [dir]. Returns a [Future] that is completed 988 /// Deletes the directory within [dir]. Returns a [Future] that is completed
989 /// after the deletion is done. 989 /// after the deletion is done.
990 Future delete(dir) { 990 Future delete(dir) {
991 return deleteDir(join(dir, _stringName)); 991 return deleteDir(path.join(dir, _stringName));
992 } 992 }
993 993
994 /// Validates that the directory at [path] contains all of the expected 994 /// Validates that the directory at [path] contains all of the expected
995 /// contents in this descriptor. Note that this does *not* check that the 995 /// contents in this descriptor. Note that this does *not* check that the
996 /// directory doesn't contain other unexpected stuff, just that it *does* 996 /// directory doesn't contain other unexpected stuff, just that it *does*
997 /// contain the stuff we do expect. 997 /// contain the stuff we do expect.
998 Future validate(String path) { 998 Future validate(String path) {
999 return _validateOneMatch(path, (dir) { 999 return _validateOneMatch(path, (dir) {
1000 // Validate each of the items in this directory. 1000 // Validate each of the items in this directory.
1001 final entryFutures = 1001 final entryFutures =
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 return new ByteStream(controller.stream); 1043 return new ByteStream(controller.stream);
1044 } 1044 }
1045 } 1045 }
1046 1046
1047 /// Describes a Git repository and its contents. 1047 /// Describes a Git repository and its contents.
1048 class GitRepoDescriptor extends DirectoryDescriptor { 1048 class GitRepoDescriptor extends DirectoryDescriptor {
1049 GitRepoDescriptor(Pattern name, List<Descriptor> contents) 1049 GitRepoDescriptor(Pattern name, List<Descriptor> contents)
1050 : super(name, contents); 1050 : super(name, contents);
1051 1051
1052 /// Creates the Git repository and commits the contents. 1052 /// Creates the Git repository and commits the contents.
1053 Future<Directory> create(parentDir) { 1053 Future create(parentDir) {
1054 return _runGitCommands(parentDir, [ 1054 return _runGitCommands(parentDir, [
1055 ['init'], 1055 ['init'],
1056 ['add', '.'], 1056 ['add', '.'],
1057 ['commit', '-m', 'initial commit'] 1057 ['commit', '-m', 'initial commit']
1058 ]); 1058 ]);
1059 } 1059 }
1060 1060
1061 /// Commits any changes to the Git repository. 1061 /// Commits any changes to the Git repository.
1062 Future commit(parentDir) { 1062 Future commit(parentDir) {
1063 return _runGitCommands(parentDir, [ 1063 return _runGitCommands(parentDir, [
(...skipping 10 matching lines...) Expand all
1074 Future<String> revParse(String ref) { 1074 Future<String> revParse(String ref) {
1075 return _scheduleValue((parentDir) { 1075 return _scheduleValue((parentDir) {
1076 return super.create(parentDir).then((rootDir) { 1076 return super.create(parentDir).then((rootDir) {
1077 return _runGit(['rev-parse', ref], rootDir); 1077 return _runGit(['rev-parse', ref], rootDir);
1078 }).then((output) => output[0]); 1078 }).then((output) => output[0]);
1079 }); 1079 });
1080 } 1080 }
1081 1081
1082 /// Schedule a Git command to run in this repository. 1082 /// Schedule a Git command to run in this repository.
1083 void scheduleGit(List<String> args) { 1083 void scheduleGit(List<String> args) {
1084 _schedule((parentDir) { 1084 _schedule((parentDir) => _runGit(args, path.join(parentDir, name)));
1085 var gitDir = new Directory(join(parentDir, name));
1086 return _runGit(args, gitDir);
1087 });
1088 } 1085 }
1089 1086
1090 Future _runGitCommands(parentDir, List<List<String>> commands) { 1087 Future _runGitCommands(parentDir, List<List<String>> commands) {
1091 var workingDir; 1088 var workingDir;
1092 1089
1093 Future runGitStep(_) { 1090 Future runGitStep(_) {
1094 if (commands.isEmpty) return new Future.immediate(workingDir); 1091 if (commands.isEmpty) return new Future.immediate(workingDir);
1095 var command = commands.removeAt(0); 1092 var command = commands.removeAt(0);
1096 return _runGit(command, workingDir).then(runGitStep); 1093 return _runGit(command, workingDir).then(runGitStep);
1097 } 1094 }
1098 1095
1099 return super.create(parentDir).then((rootDir) { 1096 return super.create(parentDir).then((rootDir) {
1100 workingDir = rootDir; 1097 workingDir = rootDir;
1101 return runGitStep(null); 1098 return runGitStep(null);
1102 }); 1099 });
1103 } 1100 }
1104 1101
1105 Future<List<String>> _runGit(List<String> args, Directory workingDir) { 1102 Future<List<String>> _runGit(List<String> args, String workingDir) {
1106 // Explicitly specify the committer information. Git needs this to commit 1103 // Explicitly specify the committer information. Git needs this to commit
1107 // and we don't want to rely on the buildbots having this already set up. 1104 // and we don't want to rely on the buildbots having this already set up.
1108 var environment = { 1105 var environment = {
1109 'GIT_AUTHOR_NAME': 'Pub Test', 1106 'GIT_AUTHOR_NAME': 'Pub Test',
1110 'GIT_AUTHOR_EMAIL': 'pub@dartlang.org', 1107 'GIT_AUTHOR_EMAIL': 'pub@dartlang.org',
1111 'GIT_COMMITTER_NAME': 'Pub Test', 1108 'GIT_COMMITTER_NAME': 'Pub Test',
1112 'GIT_COMMITTER_EMAIL': 'pub@dartlang.org' 1109 'GIT_COMMITTER_EMAIL': 'pub@dartlang.org'
1113 }; 1110 };
1114 1111
1115 return gitlib.run(args, workingDir: workingDir.path, 1112 return gitlib.run(args, workingDir: workingDir, environment: environment);
1116 environment: environment);
1117 } 1113 }
1118 } 1114 }
1119 1115
1120 /// Describes a gzipped tar file and its contents. 1116 /// Describes a gzipped tar file and its contents.
1121 class TarFileDescriptor extends Descriptor { 1117 class TarFileDescriptor extends Descriptor {
1122 final List<Descriptor> contents; 1118 final List<Descriptor> contents;
1123 1119
1124 TarFileDescriptor(Pattern name, this.contents) 1120 TarFileDescriptor(Pattern name, this.contents)
1125 : super(name); 1121 : super(name);
1126 1122
1127 /// Creates the files and directories within this tar file, then archives 1123 /// Creates the files and directories within this tar file, then archives
1128 /// them, compresses them, and saves the result to [parentDir]. 1124 /// them, compresses them, and saves the result to [parentDir].
1129 Future<File> create(parentDir) { 1125 Future<String> create(parentDir) {
1130 return withTempDir((tempDir) { 1126 return withTempDir((tempDir) {
1131 return Future.wait(contents.map((child) => child.create(tempDir))) 1127 return Future.wait(contents.map((child) => child.create(tempDir)))
1132 .then((createdContents) { 1128 .then((createdContents) {
1133 return createTarGz(createdContents, baseDir: tempDir).toBytes(); 1129 return createTarGz(createdContents, baseDir: tempDir).toBytes();
1134 }).then((bytes) { 1130 }).then((bytes) {
1135 return new File(join(parentDir, _stringName)).writeAsBytes(bytes); 1131 var file = path.join(parentDir, _stringName);
1132 writeBinaryFile(file, bytes);
1133 return file;
1136 }); 1134 });
1137 }); 1135 });
1138 } 1136 }
1139 1137
1140 /// Validates that the `.tar.gz` file at [path] contains the expected 1138 /// Validates that the `.tar.gz` file at [path] contains the expected
1141 /// contents. 1139 /// contents.
1142 Future validate(String path) { 1140 Future validate(String path) {
1143 throw "TODO(nweiz): implement this"; 1141 throw "TODO(nweiz): implement this";
1144 } 1142 }
1145 1143
1146 Future delete(dir) { 1144 Future delete(dir) {
1147 throw new UnsupportedError(''); 1145 throw new UnsupportedError('');
1148 } 1146 }
1149 1147
1150 /// Loads the contents of this tar file. 1148 /// Loads the contents of this tar file.
1151 ByteStream load(List<String> path) { 1149 ByteStream load(List<String> path) {
1152 if (!path.isEmpty) { 1150 if (!path.isEmpty) {
1153 throw "Can't load ${path.join('/')} from within $name: not a directory."; 1151 throw "Can't load ${path.join('/')} from within $name: not a directory.";
1154 } 1152 }
1155 1153
1156 var controller = new StreamController<List<int>>(); 1154 var controller = new StreamController<List<int>>();
1157 // TODO(nweiz): propagate any errors to the return value. See issue 3657. 1155 // TODO(nweiz): propagate any errors to the return value. See issue 3657.
1158 withTempDir((tempDir) { 1156 withTempDir((tempDir) {
1159 return create(tempDir).then((tar) { 1157 return create(tempDir).then((tar) {
1160 var sourceStream = tar.openInputStream(); 1158 var sourceStream = new File(tar).openInputStream();
1161 return store(wrapInputStream(sourceStream), controller); 1159 return store(wrapInputStream(sourceStream), controller);
1162 }); 1160 });
1163 }); 1161 });
1164 return new ByteStream(controller.stream); 1162 return new ByteStream(controller.stream);
1165 } 1163 }
1166 } 1164 }
1167 1165
1168 /// A descriptor that validates that no file exists with the given name. 1166 /// A descriptor that validates that no file exists with the given name.
1169 class NothingDescriptor extends Descriptor { 1167 class NothingDescriptor extends Descriptor {
1170 NothingDescriptor(String name) : super(name); 1168 NothingDescriptor(String name) : super(name);
1171 1169
1172 Future create(dir) => new Future.immediate(null); 1170 Future create(dir) => new Future.immediate(null);
1173 Future delete(dir) => new Future.immediate(null); 1171 Future delete(dir) => new Future.immediate(null);
1174 1172
1175 Future validate(String dir) { 1173 Future validate(String dir) {
1176 return defer(() { 1174 return defer(() {
1177 if (entryExists(join(dir, name))) { 1175 if (entryExists(path.join(dir, name))) {
1178 throw new ExpectException('File $name in $dir should not exist.'); 1176 throw new ExpectException('File $name in $dir should not exist.');
1179 } 1177 }
1180 }); 1178 });
1181 } 1179 }
1182 1180
1183 ByteStream load(List<String> path) { 1181 ByteStream load(List<String> path) {
1184 if (path.isEmpty) { 1182 if (path.isEmpty) {
1185 throw "Can't load the contents of $name: it doesn't exist."; 1183 throw "Can't load the contents of $name: it doesn't exist.";
1186 } else { 1184 } else {
1187 throw "Can't load ${path.join('/')} from within $name: $name doesn't " 1185 throw "Can't load ${path.join('/')} from within $name: $name doesn't "
1188 "exist."; 1186 "exist.";
1189 } 1187 }
1190 } 1188 }
1191 } 1189 }
1192 1190
1193 /// A function that creates a [Validator] subclass. 1191 /// A function that creates a [Validator] subclass.
1194 typedef Validator ValidatorCreator(Entrypoint entrypoint); 1192 typedef Validator ValidatorCreator(Entrypoint entrypoint);
1195 1193
1196 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled 1194 /// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
1197 /// Future that contains the errors and warnings produced by that validator. 1195 /// Future that contains the errors and warnings produced by that validator.
1198 Future<Pair<List<String>, List<String>>> schedulePackageValidation( 1196 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
1199 ValidatorCreator fn) { 1197 ValidatorCreator fn) {
1200 return _scheduleValue((sandboxDir) { 1198 return _scheduleValue((sandboxDir) {
1201 var cache = new SystemCache.withSources(join(sandboxDir, cachePath)); 1199 var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath));
1202 1200
1203 return defer(() { 1201 return defer(() {
1204 var validator = fn(new Entrypoint(join(sandboxDir, appPath), cache)); 1202 var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache));
1205 return validator.validate().then((_) { 1203 return validator.validate().then((_) {
1206 return new Pair(validator.errors, validator.warnings); 1204 return new Pair(validator.errors, validator.warnings);
1207 }); 1205 });
1208 }); 1206 });
1209 }); 1207 });
1210 } 1208 }
1211 1209
1212 /// A matcher that matches a Pair. 1210 /// A matcher that matches a Pair.
1213 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) => 1211 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
1214 new _PairMatcher(firstMatcher, lastMatcher); 1212 new _PairMatcher(firstMatcher, lastMatcher);
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 /// calling [completion] is unnecessary. 1624 /// calling [completion] is unnecessary.
1627 void expectLater(Future actual, matcher, {String reason, 1625 void expectLater(Future actual, matcher, {String reason,
1628 FailureHandler failureHandler, bool verbose: false}) { 1626 FailureHandler failureHandler, bool verbose: false}) {
1629 _schedule((_) { 1627 _schedule((_) {
1630 return actual.then((value) { 1628 return actual.then((value) {
1631 expect(value, matcher, reason: reason, failureHandler: failureHandler, 1629 expect(value, matcher, reason: reason, failureHandler: failureHandler,
1632 verbose: false); 1630 verbose: false);
1633 }); 1631 });
1634 }); 1632 });
1635 } 1633 }
OLDNEW
« no previous file with comments | « utils/tests/pub/io_test.dart ('k') | utils/tests/pub/validator_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698