A package for testing subprocesses.

This exposes a [`TestProcess`][TestProcess] class that wraps `dart:io`'s
[`Process`][Process] class and makes it easy to read standard output
line-by-line. `TestProcess` works the same as `Process` in many ways, but there
are a few major differences.

[TestProcess]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess-class.html
[Process]: https://api.dart.dev/stable/dart-io/Process-class.html

## Standard Output

`Process.stdout` and `Process.stderr` are binary streams, which is the most
general API but isn't the most helpful when working with a program that produces
plain text. Instead, [`TestProcess.stdout`][stdout] and
[`TestProcess.stderr`][stderr] emit a string for each line of output the process
produces. What's more, they're [`StreamQueue`][StreamQueue]s, which means
they provide a *pull-based API*. For example:

[stdout]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/stdout.html
[stderr]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/stderr.html
[StreamQueue]: https://pub.dev/documentation/async/latest/async/StreamQueue-class.html

```dart
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';

void main() {
  test("pub get gets dependencies", () async {
    // TestProcess.start() works just like Process.start() from dart:io.
    var process = await TestProcess.start("pub", ["get"]);

    // StreamQueue.next returns the next line emitted on standard out.
    var firstLine = await process.stdout.next;
    expect(firstLine, equals("Resolving dependencies..."));

    // Each call to StreamQueue.next moves one line further.
    String next;
    do {
      next = await process.stdout.next;
    } while (next != "Got dependencies!");

    // Assert that the process exits with code 0.
    await process.shouldExit(0);
  });
}
```

The `test` package's [stream matchers][] have built-in support for
`StreamQueues`, which makes them perfect for making assertions about a process's
output. We can use this to clean up the previous example:

[stream matchers]: https://github.com/dart-lang/test#stream-matchers

```dart
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';

void main() {
  test("pub get gets dependencies", () async {
    var process = await TestProcess.start("pub", ["get"]);

    // Each stream matcher will consume as many lines as it matches from a
    // StreamQueue, and no more, so it's safe to use them in sequence.
    await expectLater(process.stdout, emits("Resolving dependencies..."));

    // The emitsThrough matcher matches and consumes any number of lines, as
    // long as they end with one matching the argument.
    await expectLater(process.stdout, emitsThrough("Got dependencies!"));

    await process.shouldExit(0);
  });
}
```

If you want to access the standard output streams without consuming any values
from the queues, you can use the [`stdoutStream()`][stdoutStream] and
[`stderrStream()`][stderrStream] methods. Each time you call one of these, it
produces an entirely new stream that replays the corresponding output stream
from the beginning, regardless of what's already been produced by `stdout`,
`stderr`, or other calls to the stream method.

[stdoutStream]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/stdoutStream.html
[stderrStream]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/stderrStream.html

## Signals and Termination

The way signaling works is different from `dart:io` as well. `TestProcess` still
has a [`kill()`][kill] method, but it defaults to `SIGKILL` on Mac OS and Linux
to ensure (as best as possible) that processes die without leaving behind
zombies. If you want to send a particular signal (which is unsupported on
Windows), you can do so by explicitly calling [`signal()`][signal].

[kill]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/kill.html
[signal]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/signal.html

In addition to [`exitCode`][exitCode], which works the same as in `dart:io`,
`TestProcess` also adds a new method named [`shouldExit()`][shouldExit]. This
lets tests wait for a process to exit, and (if desired) assert what particular
exit code it produced.

[exitCode]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/exitCode.html
[shouldExit]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/shouldExit.html

## Debugging Output

When a test using `TestProcess` fails, it will print all the output produced by
that process. This makes it much easier to figure out what went wrong and why.
The debugging output uses a header based on the process's invocation by
default, but you can pass in custom `description` parameters to
[`TestProcess.start()`][start] to control the headers.

[start]: https://pub.dev/documentation/test_process/latest/test_process/TestProcess/start.html

`TestProcess` will also produce debugging output as the test runs if you pass
`forwardStdio: true` to `TestProcess.start()`. This can be particularly useful
when you're using an interactive debugger and you want to figure out what a
process is doing before the test finishes and the normal debugging output is
printed.
