// 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:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
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 shelf_io.serve((request) {
        currentSchedule.heartbeat();
        var path = request.url.path.replaceFirst("/", "");
        _requestedPaths.add(path);

        return validateStream(baseDir.load(path))
            .then((stream) => new shelf.Response.ok(stream))
            .catchError((error) {
          return new shelf.Response.notFound('File "$path" not found.');
        });
      }, '127.0.0.1', 0).then((server) {
        _server = server;
        _portCompleter.complete(_server.port);
        currentSchedule.onComplete.schedule(_closeServer);
      });
    });
  }, '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].
///
/// [output] and [error] can be [String]s, [RegExp]s, or [Matcher]s.
///
/// 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, output, 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].
///
/// If [expected] is a [String], ignores leading and trailing whitespace
/// differences and tries to report the offending difference in a nice way.
///
/// If it's a [RegExp] or [Matcher], just reports whether the output matches.
void _validateOutput(List<String> failures, String pipe, expected,
                     String actual) {
  if (expected == null) return;

  if (expected is String) {
    _validateOutputString(failures, pipe, expected, actual);
  } else {
    if (expected is RegExp) expected = matches(expected);
    expect(actual, expected);
  }
}

void _validateOutputString(List<String> failures, String pipe,
                           String expected, String actual) {
  var actualLines = actual.split("\n");
  var expectedLines = expected.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 (expectedLines.last.trim() == '') {
    expectedLines.removeLast();
  }

  var results = [];
  var failed = false;

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

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

  // If any lines mismatched, show the expected and actual.
  if (failed) {
    failures.add('Expected $pipe:');
    failures.addAll(expectedLines.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"));
