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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 dir(sdkPath, [ | 487 dir(sdkPath, [ |
488 file('version', '0.1.2.3') | 488 file('version', '0.1.2.3') |
489 ]).scheduleCreate(); | 489 ]).scheduleCreate(); |
490 | 490 |
491 // Schedule the test. | 491 // Schedule the test. |
492 body(); | 492 body(); |
493 | 493 |
494 // Run all of the scheduled tasks. If an error occurs, it will propagate | 494 // Run all of the scheduled tasks. If an error occurs, it will propagate |
495 // through the futures back up to here where we can hand it off to unittest. | 495 // through the futures back up to here where we can hand it off to unittest. |
496 var asyncDone = expectAsync0(() {}); | 496 var asyncDone = expectAsync0(() {}); |
497 var createdSandboxDir; | 497 var sandboxDir = createTempDir(); |
498 _setUpSandbox().then((sandboxDir) { | 498 return timeout(_runScheduled(sandboxDir, _scheduled), |
499 createdSandboxDir = sandboxDir; | 499 _TIMEOUT, 'waiting for a test to complete').catchError((e) { |
500 return timeout(_runScheduled(sandboxDir, _scheduled), | 500 return _runScheduled(sandboxDir, _scheduledOnException).then((_) { |
501 _TIMEOUT, 'waiting for a test to complete'); | |
502 }).catchError((e) { | |
503 return _runScheduled(createdSandboxDir, _scheduledOnException).then((_) { | |
504 // Rethrow the original error so it keeps propagating. | 501 // Rethrow the original error so it keeps propagating. |
505 throw e; | 502 throw e; |
506 }); | 503 }); |
507 }).whenComplete(() { | 504 }).whenComplete(() { |
508 // Clean up after ourselves. Do this first before reporting back to | 505 // Clean up after ourselves. Do this first before reporting back to |
509 // unittest because it will advance to the next test immediately. | 506 // unittest because it will advance to the next test immediately. |
510 return _runScheduled(createdSandboxDir, _scheduledCleanup).then((_) { | 507 return _runScheduled(sandboxDir, _scheduledCleanup).then((_) { |
511 _scheduled = null; | 508 _scheduled = null; |
512 _scheduledCleanup = null; | 509 _scheduledCleanup = null; |
513 _scheduledOnException = null; | 510 _scheduledOnException = null; |
514 if (createdSandboxDir != null) return deleteDir(createdSandboxDir); | 511 if (sandboxDir != null) return deleteDir(sandboxDir); |
515 }); | 512 }); |
516 }).then((_) { | 513 }).then((_) { |
517 // If we got here, the test completed successfully so tell unittest so. | 514 // If we got here, the test completed successfully so tell unittest so. |
518 asyncDone(); | 515 asyncDone(); |
519 }).catchError((e) { | 516 }).catchError((e) { |
520 // If we got here, an error occurred. We will register it with unittest | 517 // If we got here, an error occurred. We will register it with unittest |
521 // directly so that the error message isn't wrapped in any matcher stuff. | 518 // directly so that the error message isn't wrapped in any matcher stuff. |
522 // We do this call last because it will cause unittest to *synchronously* | 519 // We do this call last because it will cause unittest to *synchronously* |
523 // advance to the next test and run it. | 520 // advance to the next test and run it. |
524 registerException(e.error, e.stackTrace); | 521 registerException(e.error, e.stackTrace); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 /// Note that this will only affect HTTP requests made via http.dart in the | 670 /// Note that this will only affect HTTP requests made via http.dart in the |
674 /// parent process. | 671 /// parent process. |
675 void useMockClient(MockClient client) { | 672 void useMockClient(MockClient client) { |
676 var oldInnerClient = httpClient.inner; | 673 var oldInnerClient = httpClient.inner; |
677 httpClient.inner = client; | 674 httpClient.inner = client; |
678 _scheduleCleanup((_) { | 675 _scheduleCleanup((_) { |
679 httpClient.inner = oldInnerClient; | 676 httpClient.inner = oldInnerClient; |
680 }); | 677 }); |
681 } | 678 } |
682 | 679 |
683 Future<Directory> _setUpSandbox() => createTempDir(); | |
684 | |
685 Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) { | 680 Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) { |
686 if (scheduled == null) return new Future.immediate(null); | 681 if (scheduled == null) return new Future.immediate(null); |
687 var iterator = scheduled.iterator; | 682 var iterator = scheduled.iterator; |
688 | 683 |
689 Future runNextEvent(_) { | 684 Future runNextEvent(_) { |
690 if (_abortScheduled || !iterator.moveNext()) { | 685 if (_abortScheduled || !iterator.moveNext()) { |
691 _abortScheduled = false; | 686 _abortScheduled = false; |
692 scheduled.clear(); | 687 scheduled.clear(); |
693 return new Future.immediate(null); | 688 return new Future.immediate(null); |
694 } | 689 } |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 /// Describes a gzipped tar file and its contents. | 1092 /// Describes a gzipped tar file and its contents. |
1098 class TarFileDescriptor extends Descriptor { | 1093 class TarFileDescriptor extends Descriptor { |
1099 final List<Descriptor> contents; | 1094 final List<Descriptor> contents; |
1100 | 1095 |
1101 TarFileDescriptor(Pattern name, this.contents) | 1096 TarFileDescriptor(Pattern name, this.contents) |
1102 : super(name); | 1097 : super(name); |
1103 | 1098 |
1104 /// Creates the files and directories within this tar file, then archives | 1099 /// Creates the files and directories within this tar file, then archives |
1105 /// them, compresses them, and saves the result to [parentDir]. | 1100 /// them, compresses them, and saves the result to [parentDir]. |
1106 Future<File> create(parentDir) { | 1101 Future<File> create(parentDir) { |
1107 // TODO(rnystrom): Use withTempDir(). | 1102 return withTempDir((tempDir) { |
1108 var tempDir; | 1103 return Future.wait(contents.map((child) => child.create(tempDir))) |
1109 return createTempDir().then((_tempDir) { | 1104 .then((createdContents) { |
1110 tempDir = _tempDir; | 1105 return createTarGz(createdContents, baseDir: tempDir).toBytes(); |
1111 return Future.wait(contents.map((child) => child.create(tempDir))); | 1106 }).then((bytes) { |
1112 }).then((createdContents) { | 1107 return new File(join(parentDir, _stringName)).writeAsBytes(bytes); |
1113 return createTarGz(createdContents, baseDir: tempDir).toBytes(); | 1108 }); |
1114 }).then((bytes) { | |
1115 return new File(join(parentDir, _stringName)).writeAsBytes(bytes); | |
1116 }).then((file) { | |
1117 return deleteDir(tempDir).then((_) => file); | |
1118 }); | 1109 }); |
1119 } | 1110 } |
1120 | 1111 |
1121 /// Validates that the `.tar.gz` file at [path] contains the expected | 1112 /// Validates that the `.tar.gz` file at [path] contains the expected |
1122 /// contents. | 1113 /// contents. |
1123 Future validate(String path) { | 1114 Future validate(String path) { |
1124 throw "TODO(nweiz): implement this"; | 1115 throw "TODO(nweiz): implement this"; |
1125 } | 1116 } |
1126 | 1117 |
1127 Future delete(dir) { | 1118 Future delete(dir) { |
1128 throw new UnsupportedError(''); | 1119 throw new UnsupportedError(''); |
1129 } | 1120 } |
1130 | 1121 |
1131 /// Loads the contents of this tar file. | 1122 /// Loads the contents of this tar file. |
1132 ByteStream load(List<String> path) { | 1123 ByteStream load(List<String> path) { |
1133 if (!path.isEmpty) { | 1124 if (!path.isEmpty) { |
1134 var joinedPath = Strings.join(path, '/'); | 1125 var joinedPath = Strings.join(path, '/'); |
1135 throw "Can't load $joinedPath from within $name: not a directory."; | 1126 throw "Can't load $joinedPath from within $name: not a directory."; |
1136 } | 1127 } |
1137 | 1128 |
1138 var controller = new StreamController<List<int>>(); | 1129 var controller = new StreamController<List<int>>(); |
1139 var tempDir; | |
1140 // TODO(rnystrom): Use withTempDir() here. | |
1141 // TODO(nweiz): propagate any errors to the return value. See issue 3657. | 1130 // TODO(nweiz): propagate any errors to the return value. See issue 3657. |
1142 createTempDir().then((_tempDir) { | 1131 withTempDir((tempDir) { |
1143 tempDir = _tempDir; | 1132 return create(tempDir).then((tar) { |
1144 return create(tempDir); | 1133 var sourceStream = tar.openInputStream(); |
1145 }).then((tar) { | 1134 return store(wrapInputStream(sourceStream), controller); |
1146 var sourceStream = tar.openInputStream(); | |
1147 return store(wrapInputStream(sourceStream), controller).then((_) { | |
1148 tempDir.delete(recursive: true); | |
1149 }); | 1135 }); |
1150 }); | 1136 }); |
1151 return new ByteStream(controller.stream); | 1137 return new ByteStream(controller.stream); |
1152 } | 1138 } |
1153 } | 1139 } |
1154 | 1140 |
1155 /// A descriptor that validates that no file exists with the given name. | 1141 /// A descriptor that validates that no file exists with the given name. |
1156 class NothingDescriptor extends Descriptor { | 1142 class NothingDescriptor extends Descriptor { |
1157 NothingDescriptor(String name) : super(name); | 1143 NothingDescriptor(String name) : super(name); |
1158 | 1144 |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 /// calling [completion] is unnecessary. | 1599 /// calling [completion] is unnecessary. |
1614 void expectLater(Future actual, matcher, {String reason, | 1600 void expectLater(Future actual, matcher, {String reason, |
1615 FailureHandler failureHandler, bool verbose: false}) { | 1601 FailureHandler failureHandler, bool verbose: false}) { |
1616 _schedule((_) { | 1602 _schedule((_) { |
1617 return actual.then((value) { | 1603 return actual.then((value) { |
1618 expect(value, matcher, reason: reason, failureHandler: failureHandler, | 1604 expect(value, matcher, reason: reason, failureHandler: failureHandler, |
1619 verbose: false); | 1605 verbose: false); |
1620 }); | 1606 }); |
1621 }); | 1607 }); |
1622 } | 1608 } |
OLD | NEW |