| OLD | NEW |
| 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; |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 /// |
| 411 /// If [outputJson] is given, validates that pub outputs stringified JSON | 411 /// If [outputJson] is given, validates that pub outputs stringified JSON |
| 412 /// matching that object, which can be a literal JSON object or any other | 412 /// matching that object, which can be a literal JSON object or any other |
| 413 /// [Matcher]. | 413 /// [Matcher]. |
| 414 /// |
| 415 /// If [environment] is given, any keys in it will override the environment |
| 416 /// variables passed to the spawned process. |
| 414 void schedulePub({List args, output, error, outputJson, | 417 void schedulePub({List args, output, error, outputJson, |
| 415 int exitCode: exit_codes.SUCCESS}) { | 418 int exitCode: exit_codes.SUCCESS, Map<String, String> environment}) { |
| 416 // Cannot pass both output and outputJson. | 419 // Cannot pass both output and outputJson. |
| 417 assert(output == null || outputJson == null); | 420 assert(output == null || outputJson == null); |
| 418 | 421 |
| 419 var pub = startPub(args: args); | 422 var pub = startPub(args: args, environment: environment); |
| 420 pub.shouldExit(exitCode); | 423 pub.shouldExit(exitCode); |
| 421 | 424 |
| 422 var failures = []; | 425 var failures = []; |
| 423 var stderr; | 426 var stderr; |
| 424 | 427 |
| 425 expect(Future.wait([ | 428 expect(Future.wait([ |
| 426 pub.stdoutStream().toList(), | 429 pub.stdoutStream().toList(), |
| 427 pub.stderrStream().toList() | 430 pub.stderrStream().toList() |
| 428 ]).then((results) { | 431 ]).then((results) { |
| 429 var stdout = results[0].join("\n"); | 432 var stdout = results[0].join("\n"); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 environment['_PUB_TEST_TOKEN_ENDPOINT'] = tokenEndpoint.toString(); | 498 environment['_PUB_TEST_TOKEN_ENDPOINT'] = tokenEndpoint.toString(); |
| 496 } | 499 } |
| 497 | 500 |
| 498 return environment; | 501 return environment; |
| 499 } | 502 } |
| 500 | 503 |
| 501 /// Starts a Pub process and returns a [ScheduledProcess] that supports | 504 /// Starts a Pub process and returns a [ScheduledProcess] that supports |
| 502 /// interaction with that process. | 505 /// interaction with that process. |
| 503 /// | 506 /// |
| 504 /// Any futures in [args] will be resolved before the process is started. | 507 /// Any futures in [args] will be resolved before the process is started. |
| 505 ScheduledProcess startPub({List args, Future<String> tokenEndpoint}) { | 508 /// |
| 509 /// If [environment] is given, any keys in it will override the environment |
| 510 /// variables passed to the spawned process. |
| 511 ScheduledProcess startPub({List args, Future<String> tokenEndpoint, |
| 512 Map<String, String> environment}) { |
| 506 ensureDir(_pathInSandbox(appPath)); | 513 ensureDir(_pathInSandbox(appPath)); |
| 507 | 514 |
| 508 // Find a Dart executable we can use to spawn. Use the same one that was | 515 // Find a Dart executable we can use to spawn. Use the same one that was |
| 509 // used to run this script itself. | 516 // used to run this script itself. |
| 510 var dartBin = Platform.executable; | 517 var dartBin = Platform.executable; |
| 511 | 518 |
| 512 // If the executable looks like a path, get its full path. That way we | 519 // If the executable looks like a path, get its full path. That way we |
| 513 // can still find it when we spawn it with a different working directory. | 520 // can still find it when we spawn it with a different working directory. |
| 514 if (dartBin.contains(Platform.pathSeparator)) { | 521 if (dartBin.contains(Platform.pathSeparator)) { |
| 515 dartBin = p.absolute(dartBin); | 522 dartBin = p.absolute(dartBin); |
| 516 } | 523 } |
| 517 | 524 |
| 518 // Always run pub from a snapshot. Since we require the SDK to be built, the | 525 // Always run pub from a snapshot. Since we require the SDK to be built, the |
| 519 // snapshot should be there. Note that this *does* mean that the snapshot has | 526 // snapshot should be there. Note that this *does* mean that the snapshot has |
| 520 // to be manually updated when changing code before running the tests. | 527 // to be manually updated when changing code before running the tests. |
| 521 // Otherwise, you will test against stale data. | 528 // Otherwise, you will test against stale data. |
| 522 // | 529 // |
| 523 // Using the snapshot makes running the tests much faster, which is why we | 530 // Using the snapshot makes running the tests much faster, which is why we |
| 524 // make this trade-off. | 531 // make this trade-off. |
| 525 var pubPath = p.join(p.dirname(dartBin), 'snapshots/pub.dart.snapshot'); | 532 var pubPath = p.join(p.dirname(dartBin), 'snapshots/pub.dart.snapshot'); |
| 526 var dartArgs = [pubPath, '--verbose']; | 533 var dartArgs = [pubPath, '--verbose']; |
| 527 dartArgs.addAll(args); | 534 dartArgs.addAll(args); |
| 528 | 535 |
| 529 if (tokenEndpoint == null) tokenEndpoint = new Future.value(); | 536 if (tokenEndpoint == null) tokenEndpoint = new Future.value(); |
| 530 var environmentFuture = tokenEndpoint.then((tokenEndpoint) { | 537 var environmentFuture = tokenEndpoint.then((tokenEndpoint) { |
| 531 var environment = getPubTestEnvironment(tokenEndpoint); | 538 var pubEnvironment = getPubTestEnvironment(tokenEndpoint); |
| 532 | 539 |
| 533 // If there is a server running, tell pub what its URL is so hosted | 540 // If there is a server running, tell pub what its URL is so hosted |
| 534 // dependencies will look there. | 541 // dependencies will look there. |
| 535 if (_hasServer) { | 542 if (_hasServer) { |
| 536 return port.then((p) { | 543 return port.then((p) { |
| 537 environment['PUB_HOSTED_URL'] = "http://localhost:$p"; | 544 pubEnvironment['PUB_HOSTED_URL'] = "http://localhost:$p"; |
| 538 return environment; | 545 return pubEnvironment; |
| 539 }); | 546 }); |
| 540 } | 547 } |
| 541 | 548 |
| 542 return environment; | 549 return pubEnvironment; |
| 550 }).then((pubEnvironment) { |
| 551 if (environment != null) pubEnvironment.addAll(environment); |
| 552 return pubEnvironment; |
| 543 }); | 553 }); |
| 544 | 554 |
| 545 return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture, | 555 return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture, |
| 546 workingDirectory: _pathInSandbox(appPath), | 556 workingDirectory: _pathInSandbox(appPath), |
| 547 description: args.isEmpty ? 'pub' : 'pub ${args.first}'); | 557 description: args.isEmpty ? 'pub' : 'pub ${args.first}'); |
| 548 } | 558 } |
| 549 | 559 |
| 550 /// A subclass of [ScheduledProcess] that parses pub's verbose logging output | 560 /// A subclass of [ScheduledProcess] that parses pub's verbose logging output |
| 551 /// and makes [stdout] and [stderr] work as though pub weren't running in | 561 /// and makes [stdout] and [stderr] work as though pub weren't running in |
| 552 /// verbose mode. | 562 /// verbose mode. |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 _lastMatcher.matches(item.last, matchState); | 977 _lastMatcher.matches(item.last, matchState); |
| 968 } | 978 } |
| 969 | 979 |
| 970 Description describe(Description description) { | 980 Description describe(Description description) { |
| 971 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); | 981 return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]); |
| 972 } | 982 } |
| 973 } | 983 } |
| 974 | 984 |
| 975 /// A [StreamMatcher] that matches multiple lines of output. | 985 /// A [StreamMatcher] that matches multiple lines of output. |
| 976 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); | 986 StreamMatcher emitsLines(String output) => inOrder(output.split("\n")); |
| OLD | NEW |