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

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

Issue 507823002: Properly serve descriptors containing URI-sensitive characters in pub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 6 years, 3 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 | « no previous file | 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;
11 11
12 import 'dart:async'; 12 import 'dart:async';
13 import 'dart:convert'; 13 import 'dart:convert';
14 import 'dart:io'; 14 import 'dart:io';
15 import 'dart:math'; 15 import 'dart:math';
16 16
17 import 'package:http/testing.dart'; 17 import 'package:http/testing.dart';
18 import 'package:path/path.dart' as path; 18 import 'package:path/path.dart' as p;
19 import 'package:scheduled_test/scheduled_process.dart'; 19 import 'package:scheduled_test/scheduled_process.dart';
20 import 'package:scheduled_test/scheduled_server.dart'; 20 import 'package:scheduled_test/scheduled_server.dart';
21 import 'package:scheduled_test/scheduled_stream.dart'; 21 import 'package:scheduled_test/scheduled_stream.dart';
22 import 'package:scheduled_test/scheduled_test.dart' hide fail; 22 import 'package:scheduled_test/scheduled_test.dart' hide fail;
23 import 'package:shelf/shelf.dart' as shelf; 23 import 'package:shelf/shelf.dart' as shelf;
24 import 'package:shelf/shelf_io.dart' as shelf_io; 24 import 'package:shelf/shelf_io.dart' as shelf_io;
25 import 'package:unittest/compact_vm_config.dart'; 25 import 'package:unittest/compact_vm_config.dart';
26 import 'package:yaml/yaml.dart'; 26 import 'package:yaml/yaml.dart';
27 27
28 import '../lib/src/entrypoint.dart'; 28 import '../lib/src/entrypoint.dart';
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 /// third_party/pkg. 99 /// third_party/pkg.
100 final _barbackDeps = { 100 final _barbackDeps = {
101 new VersionConstraint.parse("<0.15.0"): { 101 new VersionConstraint.parse("<0.15.0"): {
102 "source_maps": "0.9.4" 102 "source_maps": "0.9.4"
103 } 103 }
104 }; 104 };
105 105
106 /// Populates [_barbackVersions]. 106 /// Populates [_barbackVersions].
107 Map<Version, String> _findBarbackVersions() { 107 Map<Version, String> _findBarbackVersions() {
108 var versions = {}; 108 var versions = {};
109 var currentBarback = path.join(repoRoot, 'pkg', 'barback'); 109 var currentBarback = p.join(repoRoot, 'pkg', 'barback');
110 versions[new Pubspec.load(currentBarback, new SourceRegistry()).version] = 110 versions[new Pubspec.load(currentBarback, new SourceRegistry()).version] =
111 currentBarback; 111 currentBarback;
112 112
113 for (var dir in listDir(path.join(repoRoot, 'third_party', 'pkg'))) { 113 for (var dir in listDir(p.join(repoRoot, 'third_party', 'pkg'))) {
114 var basename = path.basename(dir); 114 var basename = p.basename(dir);
115 if (!basename.startsWith('barback')) continue; 115 if (!basename.startsWith('barback')) continue;
116 versions[new Version.parse(split1(basename, '-').last)] = dir; 116 versions[new Version.parse(split1(basename, '-').last)] = dir;
117 } 117 }
118 118
119 return versions; 119 return versions;
120 } 120 }
121 121
122 /// Runs the tests in [callback] against all versions of barback in the repo 122 /// Runs the tests in [callback] against all versions of barback in the repo
123 /// that match [versionConstraint]. 123 /// that match [versionConstraint].
124 /// 124 ///
(...skipping 10 matching lines...) Expand all
135 } 135 }
136 136
137 for (var version in validVersions) { 137 for (var version in validVersions) {
138 group("with barback $version", () { 138 group("with barback $version", () {
139 setUp(() { 139 setUp(() {
140 _packageOverrides = {}; 140 _packageOverrides = {};
141 _packageOverrides['barback'] = _barbackVersions[version]; 141 _packageOverrides['barback'] = _barbackVersions[version];
142 _barbackDeps.forEach((constraint, deps) { 142 _barbackDeps.forEach((constraint, deps) {
143 if (!constraint.allows(version)) return; 143 if (!constraint.allows(version)) return;
144 deps.forEach((packageName, version) { 144 deps.forEach((packageName, version) {
145 _packageOverrides[packageName] = path.join( 145 _packageOverrides[packageName] = p.join(
146 repoRoot, 'third_party', 'pkg', '$packageName-$version'); 146 repoRoot, 'third_party', 'pkg', '$packageName-$version');
147 }); 147 });
148 }); 148 });
149 149
150 currentSchedule.onComplete.schedule(() { 150 currentSchedule.onComplete.schedule(() {
151 _packageOverrides = null; 151 _packageOverrides = null;
152 }); 152 });
153 }); 153 });
154 154
155 callback(); 155 callback();
(...skipping 30 matching lines...) Expand all
186 /// calls to [serve] replace the previous server. 186 /// calls to [serve] replace the previous server.
187 void serve([List<d.Descriptor> contents]) { 187 void serve([List<d.Descriptor> contents]) {
188 var baseDir = d.dir("serve-dir", contents); 188 var baseDir = d.dir("serve-dir", contents);
189 189
190 _hasServer = true; 190 _hasServer = true;
191 191
192 schedule(() { 192 schedule(() {
193 return _closeServer().then((_) { 193 return _closeServer().then((_) {
194 return shelf_io.serve((request) { 194 return shelf_io.serve((request) {
195 currentSchedule.heartbeat(); 195 currentSchedule.heartbeat();
196 var path = request.url.path.replaceFirst("/", ""); 196 var path = p.posix.fromUri(request.url.path.replaceFirst("/", ""));
197 _requestedPaths.add(path); 197 _requestedPaths.add(path);
198 198
199 return validateStream(baseDir.load(path)) 199 return validateStream(baseDir.load(path))
200 .then((stream) => new shelf.Response.ok(stream)) 200 .then((stream) => new shelf.Response.ok(stream))
201 .catchError((error) { 201 .catchError((error) {
202 return new shelf.Response.notFound('File "$path" not found.'); 202 return new shelf.Response.notFound('File "$path" not found.');
203 }); 203 });
204 }, 'localhost', 0).then((server) { 204 }, 'localhost', 0).then((server) {
205 _server = server; 205 _server = server;
206 _portCompleter.complete(_server.port); 206 _portCompleter.complete(_server.port);
(...skipping 19 matching lines...) Expand all
226 bool _hasServer = false; 226 bool _hasServer = false;
227 227
228 /// Converts [value] into a YAML string. 228 /// Converts [value] into a YAML string.
229 String yaml(value) => JSON.encode(value); 229 String yaml(value) => JSON.encode(value);
230 230
231 /// The full path to the created sandbox directory for an integration test. 231 /// The full path to the created sandbox directory for an integration test.
232 String get sandboxDir => _sandboxDir; 232 String get sandboxDir => _sandboxDir;
233 String _sandboxDir; 233 String _sandboxDir;
234 234
235 /// The path to the Dart repo's packages. 235 /// The path to the Dart repo's packages.
236 final String pkgPath = path.absolute(path.join( 236 final String pkgPath = p.absolute(p.join(
237 path.dirname(Platform.executable), 237 p.dirname(Platform.executable),
238 '..', '..', '..', '..', 'pkg')); 238 '../../../../pkg'));
239 239
240 /// The path of the package cache directory used for tests, relative to the 240 /// The path of the package cache directory used for tests, relative to the
241 /// sandbox directory. 241 /// sandbox directory.
242 final String cachePath = "cache"; 242 final String cachePath = "cache";
243 243
244 /// The path of the mock app directory used for tests, relative to the sandbox 244 /// The path of the mock app directory used for tests, relative to the sandbox
245 /// directory. 245 /// directory.
246 final String appPath = "myapp"; 246 final String appPath = "myapp";
247 247
248 /// The path of the packages directory in the mock app used for tests, relative 248 /// The path of the packages directory in the mock app used for tests, relative
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 'deleting the sandbox directory'); 372 'deleting the sandbox directory');
373 373
374 // Schedule the test. 374 // Schedule the test.
375 body(); 375 body();
376 }); 376 });
377 } 377 }
378 378
379 /// Get the path to the root "pub/test" directory containing the pub 379 /// Get the path to the root "pub/test" directory containing the pub
380 /// tests. 380 /// tests.
381 String get testDirectory => 381 String get testDirectory =>
382 path.absolute(path.dirname(libraryPath('test_pub'))); 382 p.absolute(p.dirname(libraryPath('test_pub')));
383 383
384 /// Schedules renaming (moving) the directory at [from] to [to], both of which 384 /// Schedules renaming (moving) the directory at [from] to [to], both of which
385 /// are assumed to be relative to [sandboxDir]. 385 /// are assumed to be relative to [sandboxDir].
386 void scheduleRename(String from, String to) { 386 void scheduleRename(String from, String to) {
387 schedule( 387 schedule(
388 () => renameDir( 388 () => renameDir(
389 path.join(sandboxDir, from), 389 p.join(sandboxDir, from),
390 path.join(sandboxDir, to)), 390 p.join(sandboxDir, to)),
391 'renaming $from to $to'); 391 'renaming $from to $to');
392 } 392 }
393 393
394 /// Schedules creating a symlink at path [symlink] that points to [target], 394 /// Schedules creating a symlink at path [symlink] that points to [target],
395 /// both of which are assumed to be relative to [sandboxDir]. 395 /// both of which are assumed to be relative to [sandboxDir].
396 void scheduleSymlink(String target, String symlink) { 396 void scheduleSymlink(String target, String symlink) {
397 schedule( 397 schedule(
398 () => createSymlink( 398 () => createSymlink(
399 path.join(sandboxDir, target), 399 p.join(sandboxDir, target),
400 path.join(sandboxDir, symlink)), 400 p.join(sandboxDir, symlink)),
401 'symlinking $target to $symlink'); 401 'symlinking $target to $symlink');
402 } 402 }
403 403
404 /// Schedules a call to the Pub command-line utility. 404 /// Schedules a call to the Pub command-line utility.
405 /// 405 ///
406 /// Runs Pub with [args] and validates that its results match [output] (or 406 /// Runs Pub with [args] and validates that its results match [output] (or
407 /// [outputJson]), [error], and [exitCode]. 407 /// [outputJson]), [error], and [exitCode].
408 /// 408 ///
409 /// [output] and [error] can be [String]s, [RegExp]s, or [Matcher]s. 409 /// [output] and [error] can be [String]s, [RegExp]s, or [Matcher]s.
410 /// 410 ///
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 /// 480 ///
481 /// If a test suite runs pub more than once, we only need to run the compiler 481 /// If a test suite runs pub more than once, we only need to run the compiler
482 /// the first time. 482 /// the first time.
483 // TODO(rnystrom): Remove this when #104 is fixed. 483 // TODO(rnystrom): Remove this when #104 is fixed.
484 bool _compiledAsync = false; 484 bool _compiledAsync = false;
485 485
486 /// Gets the path to the pub entrypoint Dart script to run. 486 /// Gets the path to the pub entrypoint Dart script to run.
487 // TODO(rnystrom): This exists to run the async/await compiler on pub and then 487 // TODO(rnystrom): This exists to run the async/await compiler on pub and then
488 // get the path to the output of that. Once #104 is fixed, remove this. 488 // get the path to the output of that. Once #104 is fixed, remove this.
489 String _getPubPath(String dartBin) { 489 String _getPubPath(String dartBin) {
490 var buildDir = path.join(path.dirname(dartBin), '../../'); 490 var buildDir = p.join(p.dirname(dartBin), '../../');
491 491
492 // Ensure the async/await compiler has been run once for this test suite. The 492 // Ensure the async/await compiler has been run once for this test suite. The
493 // compiler itself will only re-compile source files that have actually 493 // compiler itself will only re-compile source files that have actually
494 // changed, so this is a no-op if everything is already compiled. 494 // changed, so this is a no-op if everything is already compiled.
495 if (!_compiledAsync) { 495 if (!_compiledAsync) {
496 var result = Process.runSync(dartBin, [ 496 var result = Process.runSync(dartBin, [
497 '--package-root=$_packageRoot/', 497 '--package-root=$_packageRoot/',
498 path.join(testDirectory, '..', 'bin', 'async_compile.dart'), 498 p.join(testDirectory, '..', 'bin', 'async_compile.dart'),
499 buildDir, 499 buildDir,
500 '--silent' 500 '--silent'
501 ]); 501 ]);
502 stdout.write(result.stdout); 502 stdout.write(result.stdout);
503 stderr.write(result.stderr); 503 stderr.write(result.stderr);
504 if (result.exitCode != 0) fail("Async/await compiler failed."); 504 if (result.exitCode != 0) fail("Async/await compiler failed.");
505 505
506 _compiledAsync = true; 506 _compiledAsync = true;
507 } 507 }
508 508
509 return path.join(buildDir, 'pub_async/bin/pub.dart'); 509 return p.join(buildDir, 'pub_async/bin/pub.dart');
510 } 510 }
511 511
512 /// Starts a Pub process and returns a [ScheduledProcess] that supports 512 /// Starts a Pub process and returns a [ScheduledProcess] that supports
513 /// interaction with that process. 513 /// interaction with that process.
514 /// 514 ///
515 /// Any futures in [args] will be resolved before the process is started. 515 /// Any futures in [args] will be resolved before the process is started.
516 ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) { 516 ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) {
517 String pathInSandbox(String relPath) { 517 String pathInSandbox(String relPath) {
518 return path.join(path.absolute(sandboxDir), relPath); 518 return p.join(p.absolute(sandboxDir), relPath);
519 } 519 }
520 520
521 ensureDir(pathInSandbox(appPath)); 521 ensureDir(pathInSandbox(appPath));
522 522
523 // Find a Dart executable we can use to spawn. Use the same one that was 523 // Find a Dart executable we can use to spawn. Use the same one that was
524 // used to run this script itself. 524 // used to run this script itself.
525 var dartBin = Platform.executable; 525 var dartBin = Platform.executable;
526 526
527 // If the executable looks like a path, get its full path. That way we 527 // If the executable looks like a path, get its full path. That way we
528 // can still find it when we spawn it with a different working directory. 528 // can still find it when we spawn it with a different working directory.
529 if (dartBin.contains(Platform.pathSeparator)) { 529 if (dartBin.contains(Platform.pathSeparator)) {
530 dartBin = path.absolute(dartBin); 530 dartBin = p.absolute(dartBin);
531 } 531 }
532 532
533 // Find the main pub entrypoint. 533 // Find the main pub entrypoint.
534 var pubPath = _getPubPath(dartBin); 534 var pubPath = _getPubPath(dartBin);
535 // TODO(rnystrom): Replace the above line with the following when #104 is 535 // TODO(rnystrom): Replace the above line with the following when #104 is
536 // fixed. 536 // fixed.
537 //var pubPath = path.join(testDirectory, '..', 'bin', 'pub.dart'); 537 //var pubPath = p.join(testDirectory, '..', 'bin', 'pub.dart');
538 538
539 var dartArgs = ['--package-root=$_packageRoot/', '--checked', pubPath, 539 var dartArgs = ['--package-root=$_packageRoot/', '--checked', pubPath,
540 '--verbose']; 540 '--verbose'];
541 dartArgs.addAll(args); 541 dartArgs.addAll(args);
542 542
543 if (tokenEndpoint == null) tokenEndpoint = new Future.value(); 543 if (tokenEndpoint == null) tokenEndpoint = new Future.value();
544 var environmentFuture = tokenEndpoint.then((tokenEndpoint) { 544 var environmentFuture = tokenEndpoint.then((tokenEndpoint) {
545 var environment = {}; 545 var environment = {};
546 environment['_PUB_TESTING'] = 'true'; 546 environment['_PUB_TESTING'] = 'true';
547 environment['PUB_CACHE'] = pathInSandbox(cachePath); 547 environment['PUB_CACHE'] = pathInSandbox(cachePath);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 }); 647 });
648 } 648 }
649 649
650 var pair = tee(_stderr); 650 var pair = tee(_stderr);
651 _stderr = pair.first; 651 _stderr = pair.first;
652 return pair.last; 652 return pair.last;
653 } 653 }
654 } 654 }
655 655
656 /// The path to the `packages` directory from which pub loads its dependencies. 656 /// The path to the `packages` directory from which pub loads its dependencies.
657 String get _packageRoot => path.absolute(Platform.packageRoot); 657 String get _packageRoot => p.absolute(Platform.packageRoot);
658 658
659 /// Fails the current test if Git is not installed. 659 /// Fails the current test if Git is not installed.
660 /// 660 ///
661 /// We require machines running these tests to have git installed. This 661 /// We require machines running these tests to have git installed. This
662 /// validation gives an easier-to-understand error when that requirement isn't 662 /// validation gives an easier-to-understand error when that requirement isn't
663 /// met than just failing in the middle of a test when pub invokes git. 663 /// met than just failing in the middle of a test when pub invokes git.
664 /// 664 ///
665 /// This also increases the [Schedule] timeout to 30 seconds on Windows, 665 /// This also increases the [Schedule] timeout to 30 seconds on Windows,
666 /// where Git runs really slowly. 666 /// where Git runs really slowly.
667 void ensureGit() { 667 void ensureGit() {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 /// [hosted] is a list of package names to version strings for dependencies on 720 /// [hosted] is a list of package names to version strings for dependencies on
721 /// hosted packages. 721 /// hosted packages.
722 void createLockFile(String package, {Iterable<String> sandbox, 722 void createLockFile(String package, {Iterable<String> sandbox,
723 Iterable<String> pkg, Map<String, String> hosted}) { 723 Iterable<String> pkg, Map<String, String> hosted}) {
724 var lockFile = _createLockFile(sandbox: sandbox, pkg: pkg, hosted: hosted); 724 var lockFile = _createLockFile(sandbox: sandbox, pkg: pkg, hosted: hosted);
725 725
726 var sources = new SourceRegistry(); 726 var sources = new SourceRegistry();
727 sources.register(new HostedSource()); 727 sources.register(new HostedSource());
728 sources.register(new PathSource()); 728 sources.register(new PathSource());
729 729
730 d.file(path.join(package, 'pubspec.lock'), 730 d.file(p.join(package, 'pubspec.lock'),
731 lockFile.serialize(null, sources)).create(); 731 lockFile.serialize(null, sources)).create();
732 } 732 }
733 733
734 /// Creates a lock file for [package] without running `pub get`. 734 /// Creates a lock file for [package] without running `pub get`.
735 /// 735 ///
736 /// [sandbox] is a list of path dependencies to be found in the sandbox 736 /// [sandbox] is a list of path dependencies to be found in the sandbox
737 /// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory; 737 /// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory;
738 /// each package listed here and all its dependencies will be linked to the 738 /// each package listed here and all its dependencies will be linked to the
739 /// version in the Dart repo. 739 /// version in the Dart repo.
740 /// 740 ///
(...skipping 16 matching lines...) Expand all
757 var packagePath; 757 var packagePath;
758 if (package == 'barback' && _packageOverrides == null) { 758 if (package == 'barback' && _packageOverrides == null) {
759 throw new StateError("createLockFile() can only create a lock file " 759 throw new StateError("createLockFile() can only create a lock file "
760 "with a barback dependency within a withBarbackVersions() " 760 "with a barback dependency within a withBarbackVersions() "
761 "block."); 761 "block.");
762 } 762 }
763 763
764 if (_packageOverrides.containsKey(package)) { 764 if (_packageOverrides.containsKey(package)) {
765 packagePath = _packageOverrides[package]; 765 packagePath = _packageOverrides[package];
766 } else { 766 } else {
767 packagePath = path.join(pkgPath, package); 767 packagePath = p.join(pkgPath, package);
768 } 768 }
769 769
770 dependencies[package] = packagePath; 770 dependencies[package] = packagePath;
771 var pubspec = loadYaml( 771 var pubspec = loadYaml(
772 readTextFile(path.join(packagePath, 'pubspec.yaml'))); 772 readTextFile(p.join(packagePath, 'pubspec.yaml')));
773 var packageDeps = pubspec['dependencies']; 773 var packageDeps = pubspec['dependencies'];
774 if (packageDeps == null) return; 774 if (packageDeps == null) return;
775 packageDeps.keys.forEach(_addPackage); 775 packageDeps.keys.forEach(_addPackage);
776 } 776 }
777 777
778 pkg.forEach(_addPackage); 778 pkg.forEach(_addPackage);
779 } 779 }
780 780
781 var lockFile = new LockFile.empty(); 781 var lockFile = new LockFile.empty();
782 dependencies.forEach((name, dependencyPath) { 782 dependencies.forEach((name, dependencyPath) {
783 var id = new PackageId(name, 'path', new Version(0, 0, 0), { 783 var id = new PackageId(name, 'path', new Version(0, 0, 0), {
784 'path': dependencyPath, 784 'path': dependencyPath,
785 'relative': path.isRelative(dependencyPath) 785 'relative': p.isRelative(dependencyPath)
786 }); 786 });
787 lockFile.packages[name] = id; 787 lockFile.packages[name] = id;
788 }); 788 });
789 789
790 if (hosted != null) { 790 if (hosted != null) {
791 hosted.forEach((name, version) { 791 hosted.forEach((name, version) {
792 var id = new PackageId(name, 'hosted', new Version.parse(version), name); 792 var id = new PackageId(name, 'hosted', new Version.parse(version), name);
793 lockFile.packages[name] = id; 793 lockFile.packages[name] = id;
794 }); 794 });
795 } 795 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 /// A function that creates a [Validator] subclass. 945 /// A function that creates a [Validator] subclass.
946 typedef Validator ValidatorCreator(Entrypoint entrypoint); 946 typedef Validator ValidatorCreator(Entrypoint entrypoint);
947 947
948 /// Schedules a single [Validator] to run on the [appPath]. 948 /// Schedules a single [Validator] to run on the [appPath].
949 /// 949 ///
950 /// Returns a scheduled Future that contains the errors and warnings produced 950 /// Returns a scheduled Future that contains the errors and warnings produced
951 /// by that validator. 951 /// by that validator.
952 Future<Pair<List<String>, List<String>>> schedulePackageValidation( 952 Future<Pair<List<String>, List<String>>> schedulePackageValidation(
953 ValidatorCreator fn) { 953 ValidatorCreator fn) {
954 return schedule(() { 954 return schedule(() {
955 var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath)); 955 var cache = new SystemCache.withSources(p.join(sandboxDir, cachePath));
956 956
957 return syncFuture(() { 957 return syncFuture(() {
958 var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache)); 958 var validator = fn(new Entrypoint(p.join(sandboxDir, appPath), cache));
959 return validator.validate().then((_) { 959 return validator.validate().then((_) {
960 return new Pair(validator.errors, validator.warnings); 960 return new Pair(validator.errors, validator.warnings);
961 }); 961 });
962 }); 962 });
963 }, "validating package"); 963 }, "validating package");
964 } 964 }
965 965
966 /// A matcher that matches a Pair. 966 /// A matcher that matches a Pair.
967 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) => 967 Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
968 new _PairMatcher(firstMatcher, lastMatcher); 968 new _PairMatcher(firstMatcher, lastMatcher);
(...skipping 10 matching lines...) Expand all
979 _lastMatcher.matches(item.last, matchState); 979 _lastMatcher.matches(item.last, matchState);
980 } 980 }
981 981
982 Description describe(Description description) { 982 Description describe(Description description) {
983 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); 983 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]);
984 } 984 }
985 } 985 }
986 986
987 /// A [StreamMatcher] that matches multiple lines of output. 987 /// A [StreamMatcher] that matches multiple lines of output.
988 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); 988 StreamMatcher emitsLines(String output) => inOrder(output.split("\n"));
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698