OLD | NEW |
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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 pub.writeLine("y"); | 567 pub.writeLine("y"); |
568 } | 568 } |
569 | 569 |
570 | 570 |
571 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] | 571 /// Calls [fn] with appropriately modified arguments to run a pub process. [fn] |
572 /// should have the same signature as [startProcess], except that the returned | 572 /// should have the same signature as [startProcess], except that the returned |
573 /// [Future] may have a type other than [Process]. | 573 /// [Future] may have a type other than [Process]. |
574 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { | 574 Future _doPub(Function fn, sandboxDir, List args, Future<Uri> tokenEndpoint) { |
575 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); | 575 String pathInSandbox(path) => join(getFullPath(sandboxDir), path); |
576 | 576 |
577 return Futures.wait([ | 577 return Future.wait([ |
578 ensureDir(pathInSandbox(appPath)), | 578 ensureDir(pathInSandbox(appPath)), |
579 _awaitObject(args), | 579 _awaitObject(args), |
580 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint | 580 tokenEndpoint == null ? new Future.immediate(null) : tokenEndpoint |
581 ]).then((results) { | 581 ]).then((results) { |
582 var args = results[1]; | 582 var args = results[1]; |
583 var tokenEndpoint = results[2]; | 583 var tokenEndpoint = results[2]; |
584 // Find a Dart executable we can use to spawn. Use the same one that was | 584 // Find a Dart executable we can use to spawn. Use the same one that was |
585 // used to run this script itself. | 585 // used to run this script itself. |
586 var dartBin = new Options().executable; | 586 var dartBin = new Options().executable; |
587 | 587 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 /// the creation is done. | 908 /// the creation is done. |
909 Future<Directory> create(parentDir) { | 909 Future<Directory> create(parentDir) { |
910 // Create the directory. | 910 // Create the directory. |
911 return ensureDir(join(parentDir, _stringName)).then((dir) { | 911 return ensureDir(join(parentDir, _stringName)).then((dir) { |
912 if (contents == null) return new Future<Directory>.immediate(dir); | 912 if (contents == null) return new Future<Directory>.immediate(dir); |
913 | 913 |
914 // Recursively create all of its children. | 914 // Recursively create all of its children. |
915 final childFutures = | 915 final childFutures = |
916 contents.mappedBy((child) => child.create(dir)).toList(); | 916 contents.mappedBy((child) => child.create(dir)).toList(); |
917 // Only complete once all of the children have been created too. | 917 // Only complete once all of the children have been created too. |
918 return Futures.wait(childFutures).then((_) => dir); | 918 return Future.wait(childFutures).then((_) => dir); |
919 }); | 919 }); |
920 } | 920 } |
921 | 921 |
922 /// Deletes the directory within [dir]. Returns a [Future] that is completed | 922 /// Deletes the directory within [dir]. Returns a [Future] that is completed |
923 /// after the deletion is done. | 923 /// after the deletion is done. |
924 Future delete(dir) { | 924 Future delete(dir) { |
925 return deleteDir(join(dir, _stringName)); | 925 return deleteDir(join(dir, _stringName)); |
926 } | 926 } |
927 | 927 |
928 /// Validates that the directory at [path] contains all of the expected | 928 /// Validates that the directory at [path] contains all of the expected |
929 /// contents in this descriptor. Note that this does *not* check that the | 929 /// contents in this descriptor. Note that this does *not* check that the |
930 /// directory doesn't contain other unexpected stuff, just that it *does* | 930 /// directory doesn't contain other unexpected stuff, just that it *does* |
931 /// contain the stuff we do expect. | 931 /// contain the stuff we do expect. |
932 Future validate(String path) { | 932 Future validate(String path) { |
933 return _validateOneMatch(path, (dir) { | 933 return _validateOneMatch(path, (dir) { |
934 // Validate each of the items in this directory. | 934 // Validate each of the items in this directory. |
935 final entryFutures = | 935 final entryFutures = |
936 contents.mappedBy((entry) => entry.validate(dir)).toList(); | 936 contents.mappedBy((entry) => entry.validate(dir)).toList(); |
937 | 937 |
938 // If they are all valid, the directory is valid. | 938 // If they are all valid, the directory is valid. |
939 return Futures.wait(entryFutures).then((entries) => null); | 939 return Future.wait(entryFutures).then((entries) => null); |
940 }); | 940 }); |
941 } | 941 } |
942 | 942 |
943 /// Loads [path] from within this directory. | 943 /// Loads [path] from within this directory. |
944 InputStream load(List<String> path) { | 944 InputStream load(List<String> path) { |
945 if (path.isEmpty) { | 945 if (path.isEmpty) { |
946 throw "Can't load the contents of $name: is a directory."; | 946 throw "Can't load the contents of $name: is a directory."; |
947 } | 947 } |
948 | 948 |
949 for (var descriptor in contents) { | 949 for (var descriptor in contents) { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 TarFileDescriptor(Pattern name, this.contents) | 1065 TarFileDescriptor(Pattern name, this.contents) |
1066 : super(name); | 1066 : super(name); |
1067 | 1067 |
1068 /// Creates the files and directories within this tar file, then archives | 1068 /// Creates the files and directories within this tar file, then archives |
1069 /// them, compresses them, and saves the result to [parentDir]. | 1069 /// them, compresses them, and saves the result to [parentDir]. |
1070 Future<File> create(parentDir) { | 1070 Future<File> create(parentDir) { |
1071 // TODO(rnystrom): Use withTempDir(). | 1071 // TODO(rnystrom): Use withTempDir(). |
1072 var tempDir; | 1072 var tempDir; |
1073 return createTempDir().then((_tempDir) { | 1073 return createTempDir().then((_tempDir) { |
1074 tempDir = _tempDir; | 1074 tempDir = _tempDir; |
1075 return Futures.wait(contents.mappedBy((child) => child.create(tempDir))); | 1075 return Future.wait(contents.mappedBy((child) => child.create(tempDir))); |
1076 }).then((createdContents) { | 1076 }).then((createdContents) { |
1077 return consumeInputStream(createTarGz(createdContents, baseDir: tempDir)); | 1077 return consumeInputStream(createTarGz(createdContents, baseDir: tempDir)); |
1078 }).then((bytes) { | 1078 }).then((bytes) { |
1079 return new File(join(parentDir, _stringName)).writeAsBytes(bytes); | 1079 return new File(join(parentDir, _stringName)).writeAsBytes(bytes); |
1080 }).then((file) { | 1080 }).then((file) { |
1081 return deleteDir(tempDir).then((_) => file); | 1081 return deleteDir(tempDir).then((_) => file); |
1082 }); | 1082 }); |
1083 } | 1083 } |
1084 | 1084 |
1085 /// Validates that the `.tar.gz` file at [path] contains the expected | 1085 /// Validates that the `.tar.gz` file at [path] contains the expected |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 } | 1475 } |
1476 } | 1476 } |
1477 | 1477 |
1478 /// Takes a simple data structure (composed of [Map]s, [List]s, scalar objects, | 1478 /// Takes a simple data structure (composed of [Map]s, [List]s, scalar objects, |
1479 /// and [Future]s) and recursively resolves all the [Future]s contained within. | 1479 /// and [Future]s) and recursively resolves all the [Future]s contained within. |
1480 /// Completes with the fully resolved structure. | 1480 /// Completes with the fully resolved structure. |
1481 Future _awaitObject(object) { | 1481 Future _awaitObject(object) { |
1482 // Unroll nested futures. | 1482 // Unroll nested futures. |
1483 if (object is Future) return object.then(_awaitObject); | 1483 if (object is Future) return object.then(_awaitObject); |
1484 if (object is Collection) { | 1484 if (object is Collection) { |
1485 return Futures.wait(object.mappedBy(_awaitObject).toList()); | 1485 return Future.wait(object.mappedBy(_awaitObject).toList()); |
1486 } | 1486 } |
1487 if (object is! Map) return new Future.immediate(object); | 1487 if (object is! Map) return new Future.immediate(object); |
1488 | 1488 |
1489 var pairs = <Future<Pair>>[]; | 1489 var pairs = <Future<Pair>>[]; |
1490 object.forEach((key, value) { | 1490 object.forEach((key, value) { |
1491 pairs.add(_awaitObject(value) | 1491 pairs.add(_awaitObject(value) |
1492 .then((resolved) => new Pair(key, resolved))); | 1492 .then((resolved) => new Pair(key, resolved))); |
1493 }); | 1493 }); |
1494 return Futures.wait(pairs).then((resolvedPairs) { | 1494 return Future.wait(pairs).then((resolvedPairs) { |
1495 var map = {}; | 1495 var map = {}; |
1496 for (var pair in resolvedPairs) { | 1496 for (var pair in resolvedPairs) { |
1497 map[pair.first] = pair.last; | 1497 map[pair.first] = pair.last; |
1498 } | 1498 } |
1499 return map; | 1499 return map; |
1500 }); | 1500 }); |
1501 } | 1501 } |
1502 | 1502 |
1503 /// Schedules a callback to be called as part of the test case. | 1503 /// Schedules a callback to be called as part of the test case. |
1504 void _schedule(_ScheduledEvent event) { | 1504 void _schedule(_ScheduledEvent event) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1539 /// calling [completion] is unnecessary. | 1539 /// calling [completion] is unnecessary. |
1540 void expectLater(Future actual, matcher, {String reason, | 1540 void expectLater(Future actual, matcher, {String reason, |
1541 FailureHandler failureHandler, bool verbose: false}) { | 1541 FailureHandler failureHandler, bool verbose: false}) { |
1542 _schedule((_) { | 1542 _schedule((_) { |
1543 return actual.then((value) { | 1543 return actual.then((value) { |
1544 expect(value, matcher, reason: reason, failureHandler: failureHandler, | 1544 expect(value, matcher, reason: reason, failureHandler: failureHandler, |
1545 verbose: false); | 1545 verbose: false); |
1546 }); | 1546 }); |
1547 }); | 1547 }); |
1548 } | 1548 } |
OLD | NEW |