// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Test infrastructure for testing pub. Unlike typical unit tests, most pub
/// tests are integration tests that stage some stuff on the file system, run
/// pub, and then validate the results. This library provides an API to build
/// tests like that.
library test_pub;

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:http/testing.dart';
import 'package:path/path.dart' as path;
import 'package:scheduled_test/scheduled_process.dart';
import 'package:scheduled_test/scheduled_server.dart';
import 'package:scheduled_test/scheduled_stream.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'package:unittest/compact_vm_config.dart';
import 'package:yaml/yaml.dart';

import '../lib/src/entrypoint.dart';
import '../lib/src/exit_codes.dart' as exit_codes;
// TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides
// with the git descriptor method. Maybe we should try to clean up the top level
// scope a bit?
import '../lib/src/git.dart' as gitlib;
import '../lib/src/http.dart';
import '../lib/src/io.dart';
import '../lib/src/lock_file.dart';
import '../lib/src/log.dart' as log;
import '../lib/src/package.dart';
import '../lib/src/source/hosted.dart';
import '../lib/src/source/path.dart';
import '../lib/src/source_registry.dart';
import '../lib/src/system_cache.dart';
import '../lib/src/utils.dart';
import '../lib/src/validator.dart';
import '../lib/src/version.dart';
import 'descriptor.dart' as d;

/// This should be called at the top of a test file to set up an appropriate
/// test configuration for the machine running the tests.
initConfig() {
  useCompactVMConfiguration();
  filterStacks = true;
  unittestConfiguration.timeout = null;
}

/// The current [HttpServer] created using [serve].
var _server;

/// The list of paths that have been requested from the server since the last
/// call to [getRequestedPaths].
final _requestedPaths = <String>[];

/// The cached value for [_portCompleter].
Completer<int> _portCompleterCache;

/// A [Matcher] that matches JavaScript generated by dart2js with minification
/// enabled.
Matcher isMinifiedDart2JSOutput =
    isNot(contains("// The code supports the following hooks"));

/// A [Matcher] that matches JavaScript generated by dart2js with minification
/// disabled.
Matcher isUnminifiedDart2JSOutput =
    contains("// The code supports the following hooks");

/// The completer for [port].
Completer<int> get _portCompleter {
  if (_portCompleterCache != null) return _portCompleterCache;
  _portCompleterCache = new Completer<int>();
  currentSchedule.onComplete.schedule(() {
    _portCompleterCache = null;
  }, 'clearing the port completer');
  return _portCompleterCache;
}

/// A future that will complete to the port used for the current server.
Future<int> get port => _portCompleter.future;

/// Gets the list of paths that have been requested from the server since the
/// last time this was called (or since the server was first spun up).
Future<List<String>> getRequestedPaths() {
  return schedule(() {
    var paths = _requestedPaths.toList();
    _requestedPaths.clear();
    return paths;
  }, "get previous network requests");
}

/// Creates an HTTP server to serve [contents] as static files. This server will
/// exist only for the duration of the pub run.
///
/// Subsequent calls to [serve] will replace the previous server.
void serve([List<d.Descriptor> contents]) {
  var baseDir = d.dir("serve-dir", contents);

  _hasServer = true;

  schedule(() {
    return _closeServer().then((_) {
      return HttpServer.bind("127.0.0.1", 0).then((server) {
        _server = server;
        server.listen((request) {
          currentSchedule.heartbeat();
          var response = request.response;
          try {
            var path = request.uri.path.replaceFirst("/", "");
            _requestedPaths.add(path);

            response.persistentConnection = false;
            var stream = baseDir.load(path);

            new ByteStream(stream).toBytes().then((data) {
              currentSchedule.heartbeat();
              response.statusCode = 200;
              response.contentLength = data.length;
              response.add(data);
              response.close();
            }).catchError((e) {
              response.statusCode = 404;
              response.contentLength = 0;
              response.close();
            });
          } catch (e) {
            currentSchedule.signalError(e);
            response.statusCode = 500;
            response.close();
            return;
          }
        });
        _portCompleter.complete(_server.port);
        currentSchedule.onComplete.schedule(_closeServer);
        return null;
      });
    });
  }, 'starting a server serving:\n${baseDir.describe()}');
}

/// Closes [_server]. Returns a [Future] that will complete after the [_server]
/// is closed.
Future _closeServer() {
  if (_server == null) return new Future.value();
  var future = _server.close();
  _server = null;
  _hasServer = false;
  _portCompleterCache = null;
  return future;
}

/// `true` if the current test spins up an HTTP server.
bool _hasServer = false;

/// The [d.DirectoryDescriptor] describing the server layout of `/api/packages`
/// on the test server.
///
/// This contains metadata for packages that are being served via
/// [servePackages]. It's `null` if [servePackages] has not yet been called for
/// this test.
d.DirectoryDescriptor _servedApiPackageDir;

/// The [d.DirectoryDescriptor] describing the server layout of `/packages` on
/// the test server.
///
/// This contains the tarballs for packages that are being served via
/// [servePackages]. It's `null` if [servePackages] has not yet been called for
/// this test.
d.DirectoryDescriptor _servedPackageDir;

/// A map from package names to parsed pubspec maps for those packages. This
/// represents the packages currently being served by [servePackages], and is
/// `null` if [servePackages] has not yet been called for this test.
Map<String, List<Map>> _servedPackages;

/// Creates an HTTP server that replicates the structure of pub.dartlang.org.
/// [pubspecs] is a list of unserialized pubspecs representing the packages to
/// serve.
///
/// Subsequent calls to [servePackages] will add to the set of packages that
/// are being served. Previous packages will continue to be served.
void servePackages(List<Map> pubspecs) {
  if (_servedPackages == null || _servedPackageDir == null) {
    _servedPackages = <String, List<Map>>{};
    _servedApiPackageDir = d.dir('packages', []);
    _servedPackageDir = d.dir('packages', []);
    serve([
      d.dir('api', [_servedApiPackageDir]),
      _servedPackageDir
    ]);

    currentSchedule.onComplete.schedule(() {
      _servedPackages = null;
      _servedApiPackageDir = null;
      _servedPackageDir = null;
    }, 'cleaning up served packages');
  }

  schedule(() {
    return awaitObject(pubspecs).then((resolvedPubspecs) {
      for (var spec in resolvedPubspecs) {
        var name = spec['name'];
        var version = spec['version'];
        var versions = _servedPackages.putIfAbsent(name, () => []);
        versions.add(spec);
      }

      _servedApiPackageDir.contents.clear();
      _servedPackageDir.contents.clear();
      for (var name in _servedPackages.keys) {
        _servedApiPackageDir.contents.addAll([
          d.file('$name', JSON.encode({
            'name': name,
            'uploaders': ['nweiz@google.com'],
            'versions': _servedPackages[name].map(packageVersionApiMap).toList()
          })),
          d.dir(name, [
            d.dir('versions', _servedPackages[name].map((pubspec) {
              return d.file(pubspec['version'], JSON.encode(
                  packageVersionApiMap(pubspec, full: true)));
            }))
          ])
        ]);

        _servedPackageDir.contents.add(d.dir(name, [
          d.dir('versions', _servedPackages[name].map((pubspec) {
            var version = pubspec['version'];
            return d.tar('$version.tar.gz', [
              d.file('pubspec.yaml', JSON.encode(pubspec)),
              d.libDir(name, '$name $version')
            ]);
          }))
        ]));
      }
    });
  }, 'initializing the package server');
}

/// Converts [value] into a YAML string.
String yaml(value) => JSON.encode(value);

/// The full path to the created sandbox directory for an integration test.
String get sandboxDir => _sandboxDir;
String _sandboxDir;

/// The path of the package cache directory used for tests. Relative to the
/// sandbox directory.
final String cachePath = "cache";

/// The path of the mock app directory used for tests. Relative to the sandbox
/// directory.
final String appPath = "myapp";

/// The path of the packages directory in the mock app used for tests. Relative
/// to the sandbox directory.
final String packagesPath = "$appPath/packages";

/// Set to true when the current batch of scheduled events should be aborted.
bool _abortScheduled = false;

/// Enum identifying a pub command that can be run with a well-defined success
/// output.
class RunCommand {
  static final get = new RunCommand('get', new RegExp(r'Got dependencies!$'));
  static final upgrade = new RunCommand('upgrade', new RegExp(
      r'(No dependencies changed\.|Changed \d+ dependenc(y|ies)!)$'));

  final String name;
  final RegExp success;
  RunCommand(this.name, this.success);
}

/// Many tests validate behavior that is the same between pub get and
/// upgrade have the same behavior. Instead of duplicating those tests, this
/// takes a callback that defines get/upgrade agnostic tests and runs them
/// with both commands.
void forBothPubGetAndUpgrade(void callback(RunCommand command)) {
  group(RunCommand.get.name, () => callback(RunCommand.get));
  group(RunCommand.upgrade.name, () => callback(RunCommand.upgrade));
}

/// Schedules an invocation of pub [command] and validates that it completes
/// in an expected way.
///
/// By default, this validates that the command completes successfully and
/// understands the normal output of a successful pub command. If [warning] is
/// given, it expects the command to complete successfully *and* print
/// [warning] to stderr. If [error] is given, it expects the command to *only*
/// print [error] to stderr.
// TODO(rnystrom): Clean up other tests to call this when possible.
void pubCommand(RunCommand command,
    {Iterable<String> args, Pattern output, Pattern error, Pattern warning}) {
  if (error != null && warning != null) {
    throw new ArgumentError("Cannot pass both 'error' and 'warning'.");
  }

  var allArgs = [command.name];
  if (args != null) allArgs.addAll(args);

  if (output == null) output = command.success;

  var exitCode = null;
  if (error != null) exitCode = 1;

  // No success output on an error.
  if (error != null) output = null;
  if (warning != null) error = warning;

  schedulePub(args: allArgs, output: output, error: error, exitCode: exitCode);
}

void pubGet({Iterable<String> args, Pattern error,
    Pattern warning}) {
  pubCommand(RunCommand.get, args: args, error: error, warning: warning);
}

void pubUpgrade({Iterable<String> args, Pattern output, Pattern error,
    Pattern warning}) {
  pubCommand(RunCommand.upgrade, args: args, output: output, error: error,
      warning: warning);
}

/// Defines an integration test. The [body] should schedule a series of
/// operations which will be run asynchronously.
void integration(String description, void body()) =>
  _integration(description, body, test);

/// Like [integration], but causes only this test to run.
void solo_integration(String description, void body()) =>
  _integration(description, body, solo_test);

void _integration(String description, void body(), [Function testFn]) {
  testFn(description, () {
    // TODO(nweiz): remove this when issue 15362 is fixed.
    currentSchedule.timeout *= 2;

    // The windows bots are very slow, so we increase the default timeout.
    if (Platform.operatingSystem == "windows") {
      currentSchedule.timeout *= 2;
    }

    _sandboxDir = createSystemTempDir();
    d.defaultRoot = sandboxDir;
    currentSchedule.onComplete.schedule(() => deleteEntry(_sandboxDir),
        'deleting the sandbox directory');

    // Schedule the test.
    body();
  });
}

/// Get the path to the root "pub/test" directory containing the pub
/// tests.
String get testDirectory =>
  path.absolute(path.dirname(libraryPath('test_pub')));

/// Schedules renaming (moving) the directory at [from] to [to], both of which
/// are assumed to be relative to [sandboxDir].
void scheduleRename(String from, String to) {
  schedule(
      () => renameDir(
          path.join(sandboxDir, from),
          path.join(sandboxDir, to)),
      'renaming $from to $to');
}

/// Schedules creating a symlink at path [symlink] that points to [target],
/// both of which are assumed to be relative to [sandboxDir].
void scheduleSymlink(String target, String symlink) {
  schedule(
      () => createSymlink(
          path.join(sandboxDir, target),
          path.join(sandboxDir, symlink)),
      'symlinking $target to $symlink');
}

/// Schedules a call to the Pub command-line utility.
///
/// Runs Pub with [args] and validates that its results match [output] (or
/// [outputJson]), [error], and [exitCode].
///
/// If [outputJson] is given, validates that pub outputs stringified JSON
/// matching that object, which can be a literal JSON object or any other
/// [Matcher].
void schedulePub({List args, Pattern output, Pattern error, outputJson,
    Future<Uri> tokenEndpoint, int exitCode: exit_codes.SUCCESS}) {
  // Cannot pass both output and outputJson.
  assert(output == null || outputJson == null);

  var pub = startPub(args: args, tokenEndpoint: tokenEndpoint);
  pub.shouldExit(exitCode);

  var failures = [];
  var stderr;

  expect(Future.wait([
    pub.stdoutStream().toList(),
    pub.stderrStream().toList()
  ]).then((results) {
    var stdout = results[0].join("\n");
    stderr = results[1].join("\n");

    if (outputJson == null) {
      _validateOutput(failures, 'stdout', output, stdout);
      return null;
    }

    // Allow the expected JSON to contain futures.
    return awaitObject(outputJson).then((resolved) {
      _validateOutputJson(failures, 'stdout', resolved, stdout);
    });
  }).then((_) {
    _validateOutput(failures, 'stderr', error, stderr);

    if (!failures.isEmpty) throw new TestFailure(failures.join('\n'));
  }), completes);
}

/// Like [startPub], but runs `pub lish` in particular with [server] used both
/// as the OAuth2 server (with "/token" as the token endpoint) and as the
/// package server.
///
/// Any futures in [args] will be resolved before the process is started.
ScheduledProcess startPublish(ScheduledServer server, {List args}) {
  var tokenEndpoint = server.url.then((url) =>
      url.resolve('/token').toString());
  if (args == null) args = [];
  args = flatten(['lish', '--server', tokenEndpoint, args]);
  return startPub(args: args, tokenEndpoint: tokenEndpoint);
}

/// Handles the beginning confirmation process for uploading a packages.
/// Ensures that the right output is shown and then enters "y" to confirm the
/// upload.
void confirmPublish(ScheduledProcess pub) {
  // TODO(rnystrom): This is overly specific and inflexible regarding different
  // test packages. Should validate this a little more loosely.
  pub.stdout.expect(startsWith('Publishing test_pkg 1.0.0 to '));
  pub.stdout.expect(emitsLines(
      "|-- LICENSE\n"
      "|-- lib\n"
      "|   '-- test_pkg.dart\n"
      "'-- pubspec.yaml\n"
      "\n"
      "Looks great! Are you ready to upload your package (y/n)?"));
  pub.writeLine("y");
}

/// Starts a Pub process and returns a [ScheduledProcess] that supports
/// interaction with that process.
///
/// Any futures in [args] will be resolved before the process is started.
ScheduledProcess startPub({List args, Future<Uri> tokenEndpoint}) {
  String pathInSandbox(String relPath) {
    return path.join(path.absolute(sandboxDir), relPath);
  }

  ensureDir(pathInSandbox(appPath));

  // Find a Dart executable we can use to spawn. Use the same one that was
  // used to run this script itself.
  var dartBin = Platform.executable;

  // If the executable looks like a path, get its full path. That way we
  // can still find it when we spawn it with a different working directory.
  if (dartBin.contains(Platform.pathSeparator)) {
    dartBin = path.absolute(dartBin);
  }

  // Find the main pub entrypoint.
  var pubPath = path.join(testDirectory, '..', 'bin', 'pub.dart');

  var dartArgs = ['--package-root=$_packageRoot/', '--checked', pubPath,
      '--verbose'];
  dartArgs.addAll(args);

  if (tokenEndpoint == null) tokenEndpoint = new Future.value();
  var environmentFuture = tokenEndpoint.then((tokenEndpoint) {
    var environment = {};
    environment['_PUB_TESTING'] = 'true';
    environment['PUB_CACHE'] = pathInSandbox(cachePath);

    // Ensure a known SDK version is set for the tests that rely on that.
    environment['_PUB_TEST_SDK_VERSION'] = "0.1.2+3";

    if (tokenEndpoint != null) {
      environment['_PUB_TEST_TOKEN_ENDPOINT'] =
        tokenEndpoint.toString();
    }

    // If there is a server running, tell pub what its URL is so hosted
    // dependencies will look there.
    if (_hasServer) {
      return port.then((p) {
        environment['PUB_HOSTED_URL'] = "http://127.0.0.1:$p";
        return environment;
      });
    }

    return environment;
  });

  return new PubProcess.start(dartBin, dartArgs, environment: environmentFuture,
      workingDirectory: pathInSandbox(appPath),
      description: args.isEmpty ? 'pub' : 'pub ${args.first}');
}

/// A subclass of [ScheduledProcess] that parses pub's verbose logging output
/// and makes [stdout] and [stderr] work as though pub weren't running in
/// verbose mode.
class PubProcess extends ScheduledProcess {
  Stream<Pair<log.Level, String>> _log;
  Stream<String> _stdout;
  Stream<String> _stderr;

  PubProcess.start(executable, arguments,
      {workingDirectory, environment, String description,
       Encoding encoding: UTF8})
    : super.start(executable, arguments,
        workingDirectory: workingDirectory,
        environment: environment,
        description: description,
        encoding: encoding);

  Stream<Pair<log.Level, String>> _logStream() {
    if (_log == null) {
      _log = mergeStreams(
        _outputToLog(super.stdoutStream(), log.Level.MESSAGE),
        _outputToLog(super.stderrStream(), log.Level.ERROR));
    }

    var pair = tee(_log);
    _log = pair.first;
    return pair.last;
  }

  final _logLineRegExp = new RegExp(r"^([A-Z ]{4})[:|] (.*)$");
  final _logLevels = [
    log.Level.ERROR, log.Level.WARNING, log.Level.MESSAGE, log.Level.IO,
    log.Level.SOLVER, log.Level.FINE
  ].fold(<String, log.Level>{}, (levels, level) {
    levels[level.name] = level;
    return levels;
  });

  Stream<Pair<log.Level, String>> _outputToLog(Stream<String> stream,
      log.Level defaultLevel) {
    var lastLevel;
    return stream.map((line) {
      var match = _logLineRegExp.firstMatch(line);
      if (match == null) return new Pair<log.Level, String>(defaultLevel, line);

      var level = _logLevels[match[1]];
      if (level == null) level = lastLevel;
      lastLevel = level;
      return new Pair<log.Level, String>(level, match[2]);
    });
  }

  Stream<String> stdoutStream() {
    if (_stdout == null) {
      _stdout = _logStream().expand((entry) {
        if (entry.first != log.Level.MESSAGE) return [];
        return [entry.last];
      });
    }

    var pair = tee(_stdout);
    _stdout = pair.first;
    return pair.last;
  }

  Stream<String> stderrStream() {
    if (_stderr == null) {
      _stderr = _logStream().expand((entry) {
        if (entry.first != log.Level.ERROR &&
            entry.first != log.Level.WARNING) {
          return [];
        }
        return [entry.last];
      });
    }

    var pair = tee(_stderr);
    _stderr = pair.first;
    return pair.last;
  }
}

/// The path to the `packages` directory from which pub loads its dependencies.
String get _packageRoot => path.absolute(Platform.packageRoot);

/// Fails the current test if Git is not installed.
///
/// We require machines running these tests to have git installed. This
/// validation gives an easier-to-understand error when that requirement isn't
/// met than just failing in the middle of a test when pub invokes git.
///
/// This also increases the [Schedule] timeout to 30 seconds on Windows,
/// where Git runs really slowly.
void ensureGit() {
  if (Platform.operatingSystem == "windows") {
    currentSchedule.timeout = new Duration(seconds: 30);
  }

  schedule(() {
    return gitlib.isInstalled.then((installed) {
      if (!installed) {
        throw new Exception("Git must be installed to run this test.");
      }
    });
  }, 'ensuring that Git is installed');
}

/// Create a lock file for [package] without running `pub get`.
///
/// [sandbox] is a list of path dependencies to be found in the sandbox
/// directory. [pkg] is a list of packages in the Dart repo's "pkg" directory;
/// each package listed here and all its dependencies will be linked to the
/// version in the Dart repo.
///
/// [hosted] is a list of package names to version strings for dependencies on
/// hosted packages.
void createLockFile(String package, {Iterable<String> sandbox,
    Iterable<String> pkg, Map<String, Version> hosted}) {
  var dependencies = {};

  if (sandbox != null) {
    for (var package in sandbox) {
      dependencies[package] = '../$package';
    }
  }

  if (pkg != null) {
    var pkgDir = path.absolute(path.join(
        path.dirname(Platform.executable),
        '..', '..', '..', '..', 'pkg'));

    _addPackage(String package) {
      if (dependencies.containsKey(package)) return;
      var packagePath = path.join(pkgDir, package);
      dependencies[package] = packagePath;
      var pubspec = loadYaml(
          readTextFile(path.join(packagePath, 'pubspec.yaml')));
      var packageDeps = pubspec['dependencies'];
      if (packageDeps == null) return;
      packageDeps.keys.forEach(_addPackage);
    }

    pkg.forEach(_addPackage);
  }

  var lockFile = new LockFile.empty();
  dependencies.forEach((name, dependencyPath) {
    var id = new PackageId(name, 'path', new Version(0, 0, 0), {
      'path': dependencyPath,
      'relative': path.isRelative(dependencyPath)
    });
    lockFile.packages[name] = id;
  });

  if (hosted != null) {
    hosted.forEach((name, version) {
      var id = new PackageId(name, 'hosted', new Version.parse(version), name);
      lockFile.packages[name] = id;
    });
  }

  var sources = new SourceRegistry();
  sources.register(new HostedSource());
  sources.register(new PathSource());

  d.file(path.join(package, 'pubspec.lock'),
      lockFile.serialize(null, sources)).create();
}

/// Use [client] as the mock HTTP client for this test.
///
/// Note that this will only affect HTTP requests made via http.dart in the
/// parent process.
void useMockClient(MockClient client) {
  var oldInnerClient = httpClient.inner;
  httpClient.inner = client;
  currentSchedule.onComplete.schedule(() {
    httpClient.inner = oldInnerClient;
  }, 'de-activating the mock client');
}

/// Describes a map representing a library package with the given [name],
/// [version], and [dependencies].
Map packageMap(String name, String version, [Map dependencies]) {
  var package = {
    "name": name,
    "version": version,
    "author": "Nathan Weizenbaum <nweiz@google.com>",
    "homepage": "http://pub.dartlang.org",
    "description": "A package, I guess."
  };

  if (dependencies != null) package["dependencies"] = dependencies;

  return package;
}

/// Returns a Map in the format used by the pub.dartlang.org API to represent a
/// package version.
///
/// [pubspec] is the parsed pubspec of the package version. If [full] is true,
/// this returns the complete map, including metadata that's only included when
/// requesting the package version directly.
Map packageVersionApiMap(Map pubspec, {bool full: false}) {
  var name = pubspec['name'];
  var version = pubspec['version'];
  var map = {
    'pubspec': pubspec,
    'version': version,
    'url': '/api/packages/$name/versions/$version',
    'archive_url': '/packages/$name/versions/$version.tar.gz',
    'new_dartdoc_url': '/api/packages/$name/versions/$version'
        '/new_dartdoc',
    'package_url': '/api/packages/$name'
  };

  if (full) {
    map.addAll({
      'downloads': 0,
      'created': '2012-09-25T18:38:28.685260',
      'libraries': ['$name.dart'],
      'uploader': ['nweiz@google.com']
    });
  }

  return map;
}

/// Compares the [actual] output from running pub with [expected]. For [String]
/// patterns, ignores leading and trailing whitespace differences and tries to
/// report the offending difference in a nice way. For other [Pattern]s, just
/// reports whether the output contained the pattern.
void _validateOutput(List<String> failures, String pipe, Pattern expected,
                     String actual) {
  if (expected == null) return;

  var actualLines = actual.split("\n");
  if (expected is RegExp) {
    _validateOutputRegex(failures, pipe, expected, actualLines);
  } else {
    _validateOutputString(failures, pipe, expected, actualLines);
  }
}

void _validateOutputRegex(List<String> failures, String pipe,
                          RegExp expected, List<String> actual) {
  var actualText = actual.join('\n');
  if (actualText.contains(expected)) return;

  if (actual.length == 0) {
    failures.add('Expected $pipe to match "${expected.pattern}" but got none.');
  } else {
    failures.add('Expected $pipe to match "${expected.pattern}" but got:');
    failures.addAll(actual.map((line) => '| $line'));
  }
}

void _validateOutputString(List<String> failures, String pipe,
                           String expectedText, List<String> actual) {
  final expected = expectedText.split('\n');

  // Strip off the last line. This lets us have expected multiline strings
  // where the closing ''' is on its own line. It also fixes '' expected output
  // to expect zero lines of output, not a single empty line.
  if (expected.last.trim() == '') {
    expected.removeLast();
  }

  var results = [];
  var failed = false;

  // Compare them line by line to see which ones match.
  var length = max(expected.length, actual.length);
  for (var i = 0; i < length; i++) {
    if (i >= actual.length) {
      // Missing output.
      failed = true;
      results.add('? ${expected[i]}');
    } else if (i >= expected.length) {
      // Unexpected extra output.
      failed = true;
      results.add('X ${actual[i]}');
    } else {
      var expectedLine = expected[i].trim();
      var actualLine = actual[i].trim();

      if (expectedLine != actualLine) {
        // Mismatched lines.
        failed = true;
        results.add('X ${actual[i]}');
      } else {
        // Output is OK, but include it in case other lines are wrong.
        results.add('| ${actual[i]}');
      }
    }
  }

  // If any lines mismatched, show the expected and actual.
  if (failed) {
    failures.add('Expected $pipe:');
    failures.addAll(expected.map((line) => '| $line'));
    failures.add('Got:');
    failures.addAll(results);
  }
}

/// Validates that [actualText] is a string of JSON that matches [expected],
/// which may be a literal JSON object, or any other [Matcher].
void _validateOutputJson(List<String> failures, String pipe,
                         expected, String actualText) {
  var actual;
  try {
    actual = JSON.decode(actualText);
  } on FormatException catch(error) {
    failures.add('Expected $pipe JSON:');
    failures.add(expected);
    failures.add('Got invalid JSON:');
    failures.add(actualText);
  }

  // Match against the expectation.
  expect(actual, expected);
}

/// A function that creates a [Validator] subclass.
typedef Validator ValidatorCreator(Entrypoint entrypoint);

/// Schedules a single [Validator] to run on the [appPath]. Returns a scheduled
/// Future that contains the errors and warnings produced by that validator.
Future<Pair<List<String>, List<String>>> schedulePackageValidation(
    ValidatorCreator fn) {
  return schedule(() {
    var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath));

    return syncFuture(() {
      var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache));
      return validator.validate().then((_) {
        return new Pair(validator.errors, validator.warnings);
      });
    });
  }, "validating package");
}

/// A matcher that matches a Pair.
Matcher pairOf(Matcher firstMatcher, Matcher lastMatcher) =>
   new _PairMatcher(firstMatcher, lastMatcher);

class _PairMatcher extends Matcher {
  final Matcher _firstMatcher;
  final Matcher _lastMatcher;

  _PairMatcher(this._firstMatcher, this._lastMatcher);

  bool matches(item, Map matchState) {
    if (item is! Pair) return false;
    return _firstMatcher.matches(item.first, matchState) &&
        _lastMatcher.matches(item.last, matchState);
  }

  Description describe(Description description) {
    return description.addAll("(", ", ", ")", [_firstMatcher, _lastMatcher]);
  }
}

/// A [StreamMatcher] that matches multiple lines of output.
StreamMatcher emitsLines(String output) => inOrder(output.split("\n"));
