blob: 0d921928e06ed474f288c4fb22aafd6cdfd39608 [file] [log] [blame]
// Copyright (c) 2015, 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.
import 'dart:async';
import 'dart:io';
import 'package:package_resolver/package_resolver.dart';
import 'package:path/path.dart' as p;
import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';
import 'package:test/test.dart';
/// The path to the root directory of the `test` package.
final Future<String> packageDir = PackageResolver.current.packagePath('test');
/// The path to the `pub` executable in the current Dart SDK.
final _pubPath = p.absolute(p.join(p.dirname(Platform.resolvedExecutable),
Platform.isWindows ? 'pub.bat' : 'pub'));
/// The platform-specific message emitted when a nonexistent file is loaded.
final String noSuchFileMessage = Platform.isWindows
? 'The system cannot find the file specified.'
: 'No such file or directory';
/// A regular expression that matches the output of "pub serve".
final _servingRegExp =
RegExp(r'^Serving myapp [a-z]+ on http://localhost:(\d+)$');
/// An operating system name that's different than the current operating system.
final otherOS = Platform.isWindows ? 'mac-os' : 'windows';
/// The port of a pub serve instance run via [runPubServe].
///
/// This is only set after [runPubServe] is called.
int get pubServePort => _pubServePort;
int _pubServePort;
/// Expects that the entire stdout stream of [test] equals [expected].
void expectStdoutEquals(TestProcess test, String expected) =>
_expectStreamEquals(test.stdoutStream(), expected);
/// Expects that the entire stderr stream of [test] equals [expected].
void expectStderrEquals(TestProcess test, String expected) =>
_expectStreamEquals(test.stderrStream(), expected);
/// Expects that the entirety of the line stream [stream] equals [expected].
void _expectStreamEquals(Stream<String> stream, String expected) {
expect((() async {
var lines = await stream.toList();
expect(lines.join('\n').trim(), equals(expected.trim()));
})(), completes);
}
/// Returns a [StreamMatcher] that asserts that the stream emits strings
/// containing each string in [strings] in order.
///
/// This expects each string in [strings] to match a different string in the
/// stream.
StreamMatcher containsInOrder(Iterable<String> strings) =>
emitsInOrder(strings.map((string) => emitsThrough(contains(string))));
/// Runs the test executable with the package root set properly.
Future<TestProcess> runTest(Iterable<String> args,
{String reporter,
String fileReporter,
int concurrency,
Map<String, String> environment,
bool forwardStdio = false}) async {
concurrency ??= 1;
var allArgs = [
p.absolute(p.join(await packageDir, 'bin/test.dart')),
'--concurrency=$concurrency',
if (reporter != null) '--reporter=$reporter',
if (fileReporter != null) '--file-reporter=$fileReporter',
...?args,
];
environment ??= {};
environment.putIfAbsent('_DART_TEST_TESTING', () => 'true');
return await runDart(allArgs,
environment: environment,
description: 'dart bin/test.dart',
forwardStdio: forwardStdio);
}
/// Runs Dart.
Future<TestProcess> runDart(Iterable<String> args,
{Map<String, String> environment,
String description,
bool forwardStdio = false}) async {
var allArgs = <String>[
...Platform.executableArguments.where((arg) =>
!arg.startsWith('--package-root=') && !arg.startsWith('--packages=')),
await PackageResolver.current.processArgument,
...args
];
return await TestProcess.start(
p.absolute(Platform.resolvedExecutable), allArgs,
workingDirectory: d.sandbox,
environment: environment,
description: description,
forwardStdio: forwardStdio);
}
/// Runs Pub.
Future<TestProcess> runPub(Iterable<String> args,
{Map<String, String> environment}) {
return TestProcess.start(_pubPath, args,
workingDirectory: d.sandbox,
environment: environment,
description: 'pub ${args.first}');
}
/// Runs "pub serve".
///
/// This returns assigns [_pubServePort] to a future that will complete to the
/// port of the "pub serve" instance.
Future<TestProcess> runPubServe(
{Iterable<String> args,
String workingDirectory,
Map<String, String> environment}) async {
var allArgs = ['serve', '--port', '0'];
if (args != null) allArgs.addAll(args);
var pub = await runPub(allArgs, environment: environment);
Match match;
while (match == null) {
match = _servingRegExp.firstMatch(await pub.stdout.next);
}
_pubServePort = int.parse(match[1]);
return pub;
}