[flutter_tools] remove globals from compilers (#59184)
Refactors KernelCompiler and ResidentCompiler to no longer use globals (except as a fallback for g3 migration). Improves the compilation error when running flutter test on a package without a flutter_test dependency. Updates machine mode to output trace text to stderr
This commit is contained in:
parent
e1f4cfb4f4
commit
447e3d3f38
@ -1,4 +1,8 @@
|
||||
<<skip until matching line>>
|
||||
<<stderr>>
|
||||
<<skip until matching line>>
|
||||
Failed to load test harness\. +Are you missing a dependency on flutter_test\?
|
||||
Error: cannot run without a dependency on "package:flutter_test". Ensure the following lines are present in your pubspec.yaml:
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
@ -128,7 +128,15 @@ Future<void> main(List<String> args) async {
|
||||
// The mustache dependency is different in google3
|
||||
TemplateRenderer: () => const MustacheTemplateRenderer(),
|
||||
if (daemon)
|
||||
Logger: () => NotifyingLogger(verbose: verbose)
|
||||
Logger: () => NotifyingLogger(
|
||||
verbose: verbose,
|
||||
parent: VerboseLogger(StdoutLogger(
|
||||
timeoutConfiguration: timeoutConfiguration,
|
||||
stdio: globals.stdio,
|
||||
terminal: globals.terminal,
|
||||
outputPreferences: globals.outputPreferences,
|
||||
),
|
||||
))
|
||||
else if (verbose && !muteCommandLogging)
|
||||
Logger: () => VerboseLogger(StdoutLogger(
|
||||
timeoutConfiguration: timeoutConfiguration,
|
||||
|
@ -159,6 +159,11 @@ class EngineBuildPaths {
|
||||
|
||||
// Manages the engine artifacts of Flutter.
|
||||
abstract class Artifacts {
|
||||
/// A test-specific implementation of artifacts that returns stable paths for
|
||||
/// all artifacts.
|
||||
@visibleForTesting
|
||||
factory Artifacts.test() = _TestArtifacts;
|
||||
|
||||
static LocalEngineArtifacts getLocalEngine(EngineBuildPaths engineBuildPaths) {
|
||||
return LocalEngineArtifacts(
|
||||
engineBuildPaths.targetEngine,
|
||||
@ -183,7 +188,7 @@ abstract class Artifacts {
|
||||
|
||||
|
||||
/// Manages the engine artifacts downloaded to the local cache.
|
||||
class CachedArtifacts extends Artifacts {
|
||||
class CachedArtifacts implements Artifacts {
|
||||
CachedArtifacts({
|
||||
@required FileSystem fileSystem,
|
||||
@required Platform platform,
|
||||
@ -449,7 +454,7 @@ HostPlatform _currentHostPlatformAsHost(Platform platform) {
|
||||
}
|
||||
|
||||
/// Manages the artifacts of a locally built engine.
|
||||
class LocalEngineArtifacts extends Artifacts {
|
||||
class LocalEngineArtifacts implements Artifacts {
|
||||
LocalEngineArtifacts(
|
||||
this.engineOutPath,
|
||||
this._hostEngineOutPath, {
|
||||
@ -648,3 +653,26 @@ class OverrideArtifacts implements Artifacts {
|
||||
String _dartSdkPath(FileSystem fileSystem) {
|
||||
return fileSystem.path.join(Cache.flutterRoot, 'bin', 'cache', 'dart-sdk');
|
||||
}
|
||||
|
||||
class _TestArtifacts implements Artifacts {
|
||||
@override
|
||||
String getArtifactPath(Artifact artifact, {TargetPlatform platform, BuildMode mode}) {
|
||||
final StringBuffer buffer = StringBuffer();
|
||||
buffer.write(artifact);
|
||||
if (platform != null) {
|
||||
buffer.write('.$platform');
|
||||
}
|
||||
if (mode != null) {
|
||||
buffer.write('.$mode');
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String getEngineType(TargetPlatform platform, [ BuildMode mode ]) {
|
||||
return 'test-engine';
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isLocalEngine => false;
|
||||
}
|
||||
|
@ -4,8 +4,12 @@
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import 'artifacts.dart';
|
||||
import 'base/context.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/logger.dart';
|
||||
import 'build_info.dart';
|
||||
import 'compile.dart';
|
||||
import 'globals.dart' as globals;
|
||||
@ -63,10 +67,19 @@ abstract class CodegenDaemon {
|
||||
/// supported here. Using the build pipeline implies a fixed multi-root
|
||||
/// filesystem and requires a pubspec.
|
||||
class CodeGeneratingKernelCompiler implements KernelCompiler {
|
||||
const CodeGeneratingKernelCompiler();
|
||||
|
||||
static const KernelCompiler _delegate = KernelCompiler();
|
||||
CodeGeneratingKernelCompiler({
|
||||
@required FileSystem fileSystem,
|
||||
@required Artifacts artifacts,
|
||||
@required ProcessManager processManager,
|
||||
@required Logger logger,
|
||||
}) : _delegate = KernelCompiler(
|
||||
logger: logger,
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: fileSystem,
|
||||
);
|
||||
|
||||
final KernelCompiler _delegate;
|
||||
@override
|
||||
Future<CompilerOutput> compile({
|
||||
String mainPath,
|
||||
|
@ -209,7 +209,7 @@ class AttachCommand extends FlutterCommand {
|
||||
stdoutCommandResponse,
|
||||
notifyingLogger: (globals.logger is NotifyingLogger)
|
||||
? globals.logger as NotifyingLogger
|
||||
: NotifyingLogger(verbose: globals.logger.isVerbose),
|
||||
: NotifyingLogger(verbose: globals.logger.isVerbose, parent: globals.logger),
|
||||
logToStdout: true,
|
||||
)
|
||||
: null;
|
||||
|
@ -918,13 +918,14 @@ dynamic _toJsonable(dynamic obj) {
|
||||
}
|
||||
|
||||
class NotifyingLogger extends Logger {
|
||||
NotifyingLogger({ @required this.verbose }) {
|
||||
NotifyingLogger({ @required this.verbose, @required this.parent }) {
|
||||
_messageController = StreamController<LogMessage>.broadcast(
|
||||
onListen: _onListen,
|
||||
);
|
||||
}
|
||||
|
||||
final bool verbose;
|
||||
final Logger parent;
|
||||
final List<LogMessage> messageBuffer = <LogMessage>[];
|
||||
StreamController<LogMessage> _messageController;
|
||||
|
||||
@ -968,7 +969,7 @@ class NotifyingLogger extends Logger {
|
||||
if (!verbose) {
|
||||
return;
|
||||
}
|
||||
_sendMessage(LogMessage('trace', message));
|
||||
parent.printError(message);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -417,7 +417,7 @@ class RunCommand extends RunCommandBase {
|
||||
stdoutCommandResponse,
|
||||
notifyingLogger: (globals.logger is NotifyingLogger)
|
||||
? globals.logger as NotifyingLogger
|
||||
: NotifyingLogger(verbose: globals.logger.isVerbose),
|
||||
: NotifyingLogger(verbose: globals.logger.isVerbose, parent: globals.logger),
|
||||
logToStdout: true,
|
||||
);
|
||||
AppInstance app;
|
||||
|
@ -6,13 +6,15 @@ import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'package:usage/uuid/uuid.dart';
|
||||
|
||||
import 'artifacts.dart';
|
||||
import 'base/common.dart';
|
||||
import 'base/context.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/io.dart';
|
||||
import 'base/terminal.dart';
|
||||
import 'base/logger.dart';
|
||||
import 'build_info.dart';
|
||||
import 'codegen.dart';
|
||||
import 'convert.dart';
|
||||
@ -22,18 +24,39 @@ import 'project.dart';
|
||||
KernelCompilerFactory get kernelCompilerFactory => context.get<KernelCompilerFactory>();
|
||||
|
||||
class KernelCompilerFactory {
|
||||
const KernelCompilerFactory();
|
||||
const KernelCompilerFactory({
|
||||
@required FileSystem fileSystem,
|
||||
@required Artifacts artifacts,
|
||||
@required ProcessManager processManager,
|
||||
@required Logger logger,
|
||||
}) : _fileSystem = fileSystem,
|
||||
_artifacts = artifacts,
|
||||
_processManager = processManager,
|
||||
_logger = logger;
|
||||
|
||||
final Logger _logger;
|
||||
final Artifacts _artifacts;
|
||||
final ProcessManager _processManager;
|
||||
final FileSystem _fileSystem;
|
||||
|
||||
Future<KernelCompiler> create(FlutterProject flutterProject) async {
|
||||
if (flutterProject == null || !flutterProject.hasBuilders) {
|
||||
return const KernelCompiler();
|
||||
return KernelCompiler(
|
||||
logger: _logger,
|
||||
artifacts: _artifacts,
|
||||
fileSystem: _fileSystem,
|
||||
processManager: _processManager,
|
||||
);
|
||||
}
|
||||
return const CodeGeneratingKernelCompiler();
|
||||
return CodeGeneratingKernelCompiler(
|
||||
logger: _logger,
|
||||
artifacts: _artifacts,
|
||||
fileSystem: _fileSystem,
|
||||
processManager: _processManager,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
typedef CompilerMessageConsumer = void Function(String message, { bool emphasis, TerminalColor color });
|
||||
|
||||
/// The target model describes the set of core libraries that are available within
|
||||
/// the SDK.
|
||||
class TargetModel {
|
||||
@ -88,11 +111,14 @@ enum StdoutState { CollectDiagnostic, CollectDependencies }
|
||||
|
||||
/// Handles stdin/stdout communication with the frontend server.
|
||||
class StdoutHandler {
|
||||
StdoutHandler({this.consumer = globals.printError}) {
|
||||
StdoutHandler({
|
||||
@required Logger logger
|
||||
}) : _logger = logger {
|
||||
reset();
|
||||
}
|
||||
|
||||
final CompilerMessageConsumer consumer;
|
||||
final Logger _logger;
|
||||
|
||||
String boundaryKey;
|
||||
StdoutState state = StdoutState.CollectDiagnostic;
|
||||
Completer<CompilerOutput> compilerOutput;
|
||||
@ -128,7 +154,9 @@ class StdoutHandler {
|
||||
}
|
||||
if (state == StdoutState.CollectDiagnostic) {
|
||||
if (!_suppressCompilerMessages) {
|
||||
consumer(message);
|
||||
_logger.printError(message);
|
||||
} else {
|
||||
_logger.printTrace(message);
|
||||
}
|
||||
} else {
|
||||
assert(state == StdoutState.CollectDependencies);
|
||||
@ -140,7 +168,7 @@ class StdoutHandler {
|
||||
sources.remove(Uri.parse(message.substring(1)));
|
||||
break;
|
||||
default:
|
||||
globals.printTrace('Unexpected prefix for $message uri - ignoring');
|
||||
_logger.printTrace('Unexpected prefix for $message uri - ignoring');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,8 +210,22 @@ List<String> buildModeOptions(BuildMode mode) {
|
||||
throw Exception('Unknown BuildMode: $mode');
|
||||
}
|
||||
|
||||
/// A compiler interface for producing single (non-incremental) kernel files.
|
||||
class KernelCompiler {
|
||||
const KernelCompiler();
|
||||
KernelCompiler({
|
||||
FileSystem fileSystem, // TODO(jonahwilliams): migrate to @required after google3
|
||||
Logger logger, // TODO(jonahwilliams): migrate to @required after google3
|
||||
ProcessManager processManager, // TODO(jonahwilliams): migrate to @required after google3
|
||||
Artifacts artifacts, // TODO(jonahwilliams): migrate to @required after google3
|
||||
}) : _logger = logger ?? globals.logger,
|
||||
_fileSystem = fileSystem ?? globals.fs,
|
||||
_artifacts = artifacts ?? globals.artifacts,
|
||||
_processManager = processManager ?? globals.processManager;
|
||||
|
||||
final FileSystem _fileSystem;
|
||||
final Artifacts _artifacts;
|
||||
final ProcessManager _processManager;
|
||||
final Logger _logger;
|
||||
|
||||
Future<CompilerOutput> compile({
|
||||
String sdkRoot,
|
||||
@ -204,25 +246,23 @@ class KernelCompiler {
|
||||
@required List<String> dartDefines,
|
||||
@required PackageConfig packageConfig,
|
||||
}) async {
|
||||
final String frontendServer = globals.artifacts.getArtifactPath(
|
||||
final String frontendServer = _artifacts.getArtifactPath(
|
||||
Artifact.frontendServerSnapshotForEngineDartSdk
|
||||
);
|
||||
// This is a URI, not a file path, so the forward slash is correct even on Windows.
|
||||
if (!sdkRoot.endsWith('/')) {
|
||||
sdkRoot = '$sdkRoot/';
|
||||
}
|
||||
final String engineDartPath = globals.artifacts.getArtifactPath(Artifact.engineDartBinary);
|
||||
if (!globals.processManager.canRun(engineDartPath)) {
|
||||
final String engineDartPath = _artifacts.getArtifactPath(Artifact.engineDartBinary);
|
||||
if (!_processManager.canRun(engineDartPath)) {
|
||||
throwToolExit('Unable to find Dart binary at $engineDartPath');
|
||||
}
|
||||
Uri mainUri;
|
||||
if (packagesPath != null) {
|
||||
mainUri = packageConfig.toPackageUri(globals.fs.file(mainPath).uri);
|
||||
mainUri = packageConfig.toPackageUri(_fileSystem.file(mainPath).uri);
|
||||
}
|
||||
// TODO(jonahwilliams): The output file must already exist, but this seems
|
||||
// unnecessary.
|
||||
if (outputFilePath != null && !globals.fs.isFileSync(outputFilePath)) {
|
||||
globals.fs.file(outputFilePath).createSync(recursive: true);
|
||||
if (outputFilePath != null && !_fileSystem.isFileSync(outputFilePath)) {
|
||||
_fileSystem.file(outputFilePath).createSync(recursive: true);
|
||||
}
|
||||
final List<String> command = <String>[
|
||||
engineDartPath,
|
||||
@ -281,13 +321,13 @@ class KernelCompiler {
|
||||
mainUri?.toString() ?? mainPath,
|
||||
];
|
||||
|
||||
globals.printTrace(command.join(' '));
|
||||
final Process server = await globals.processManager.start(command);
|
||||
_logger.printTrace(command.join(' '));
|
||||
final Process server = await _processManager.start(command);
|
||||
|
||||
final StdoutHandler _stdoutHandler = StdoutHandler();
|
||||
final StdoutHandler _stdoutHandler = StdoutHandler(logger: _logger);
|
||||
server.stderr
|
||||
.transform<String>(utf8.decoder)
|
||||
.listen(globals.printError);
|
||||
.listen(_logger.printError);
|
||||
server.stdout
|
||||
.transform<String>(utf8.decoder)
|
||||
.transform<String>(const LineSplitter())
|
||||
@ -398,11 +438,13 @@ class _RejectRequest extends _CompilationRequest {
|
||||
abstract class ResidentCompiler {
|
||||
factory ResidentCompiler(String sdkRoot, {
|
||||
@required BuildMode buildMode,
|
||||
Logger logger, // TODO(jonahwilliams): migrate to @required after google3
|
||||
ProcessManager processManager, // TODO(jonahwilliams): migrate to @required after google3
|
||||
Artifacts artifacts, // TODO(jonahwilliams): migrate to @required after google3
|
||||
bool trackWidgetCreation,
|
||||
String packagesPath,
|
||||
List<String> fileSystemRoots,
|
||||
String fileSystemScheme,
|
||||
CompilerMessageConsumer compilerMessageConsumer,
|
||||
String initializeFromDill,
|
||||
TargetModel targetModel,
|
||||
bool unsafePackageSerialization,
|
||||
@ -496,11 +538,13 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
DefaultResidentCompiler(
|
||||
String sdkRoot, {
|
||||
@required this.buildMode,
|
||||
Logger logger, // TODO(jonahwilliams): migrate to @required after google3
|
||||
ProcessManager processManager, // TODO(jonahwilliams): migrate to @required after google3
|
||||
Artifacts artifacts, // TODO(jonahwilliams): migrate to @required after google3
|
||||
this.trackWidgetCreation = true,
|
||||
this.packagesPath,
|
||||
this.fileSystemRoots,
|
||||
this.fileSystemScheme,
|
||||
CompilerMessageConsumer compilerMessageConsumer = globals.printError,
|
||||
this.initializeFromDill,
|
||||
this.targetModel = TargetModel.flutter,
|
||||
this.unsafePackageSerialization,
|
||||
@ -511,11 +555,18 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
// Deprecated
|
||||
List<String> experimentalFlags, // ignore: avoid_unused_constructor_parameters
|
||||
}) : assert(sdkRoot != null),
|
||||
_stdoutHandler = StdoutHandler(consumer: compilerMessageConsumer),
|
||||
_logger = logger ?? globals.logger,
|
||||
_processManager = processManager ?? globals.processManager,
|
||||
_artifacts = artifacts ?? globals.artifacts,
|
||||
_stdoutHandler = StdoutHandler(logger: logger),
|
||||
dartDefines = dartDefines ?? const <String>[],
|
||||
// This is a URI, not a file path, so the forward slash is correct even on Windows.
|
||||
sdkRoot = sdkRoot.endsWith('/') ? sdkRoot : '$sdkRoot/';
|
||||
|
||||
final Logger _logger;
|
||||
final ProcessManager _processManager;
|
||||
final Artifacts _artifacts;
|
||||
|
||||
final BuildMode buildMode;
|
||||
final bool trackWidgetCreation;
|
||||
final String packagesPath;
|
||||
@ -584,7 +635,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
final String mainUri = request.packageConfig.toPackageUri(request.mainUri)?.toString()
|
||||
?? request.mainUri.toString();
|
||||
_server.stdin.writeln('recompile $mainUri $inputKey');
|
||||
globals.printTrace('<- recompile $mainUri $inputKey');
|
||||
_logger.printTrace('<- recompile $mainUri $inputKey');
|
||||
for (final Uri fileUri in request.invalidatedFiles) {
|
||||
String message;
|
||||
if (fileUri.scheme == 'package') {
|
||||
@ -594,10 +645,10 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
?? fileUri.toString();
|
||||
}
|
||||
_server.stdin.writeln(message);
|
||||
globals.printTrace(message);
|
||||
_logger.printTrace(message);
|
||||
}
|
||||
_server.stdin.writeln(inputKey);
|
||||
globals.printTrace('<- $inputKey');
|
||||
_logger.printTrace('<- $inputKey');
|
||||
|
||||
return _stdoutHandler.compilerOutput.future;
|
||||
}
|
||||
@ -623,11 +674,11 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
String scriptUri,
|
||||
String outputPath,
|
||||
) async {
|
||||
final String frontendServer = globals.artifacts.getArtifactPath(
|
||||
final String frontendServer = _artifacts.getArtifactPath(
|
||||
Artifact.frontendServerSnapshotForEngineDartSdk
|
||||
);
|
||||
final List<String> command = <String>[
|
||||
globals.artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
_artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
frontendServer,
|
||||
'--sdk-root',
|
||||
@ -682,8 +733,8 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
else
|
||||
arg,
|
||||
];
|
||||
globals.printTrace(command.join(' '));
|
||||
_server = await globals.processManager.start(command);
|
||||
_logger.printTrace(command.join(' '));
|
||||
_server = await _processManager.start(command);
|
||||
_server.stdout
|
||||
.transform<String>(utf8.decoder)
|
||||
.transform<String>(const LineSplitter())
|
||||
@ -701,7 +752,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
_server.stderr
|
||||
.transform<String>(utf8.decoder)
|
||||
.transform<String>(const LineSplitter())
|
||||
.listen(globals.printError);
|
||||
.listen(_logger.printError);
|
||||
|
||||
unawaited(_server.exitCode.then((int code) {
|
||||
if (code != 0) {
|
||||
@ -710,7 +761,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
}));
|
||||
|
||||
_server.stdin.writeln('compile $scriptUri');
|
||||
globals.printTrace('<- compile $scriptUri');
|
||||
_logger.printTrace('<- compile $scriptUri');
|
||||
|
||||
return _stdoutHandler.compilerOutput.future;
|
||||
}
|
||||
@ -746,15 +797,17 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
}
|
||||
|
||||
final String inputKey = Uuid().generateV4();
|
||||
_server.stdin.writeln('compile-expression $inputKey');
|
||||
_server.stdin.writeln(request.expression);
|
||||
_server.stdin
|
||||
..writeln('compile-expression $inputKey')
|
||||
..writeln(request.expression);
|
||||
request.definitions?.forEach(_server.stdin.writeln);
|
||||
_server.stdin.writeln(inputKey);
|
||||
request.typeDefinitions?.forEach(_server.stdin.writeln);
|
||||
_server.stdin.writeln(inputKey);
|
||||
_server.stdin.writeln(request.libraryUri ?? '');
|
||||
_server.stdin.writeln(request.klass ?? '');
|
||||
_server.stdin.writeln(request.isStatic ?? false);
|
||||
_server.stdin
|
||||
..writeln(inputKey)
|
||||
..writeln(request.libraryUri ?? '')
|
||||
..writeln(request.klass ?? '')
|
||||
..writeln(request.isStatic ?? false);
|
||||
|
||||
return _stdoutHandler.compilerOutput.future;
|
||||
}
|
||||
@ -782,7 +835,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
}
|
||||
|
||||
Future<CompilerOutput> _compileExpressionToJs(_CompileExpressionToJsRequest request) async {
|
||||
_stdoutHandler.reset(suppressCompilerMessages: false, expectSources: false);
|
||||
_stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false);
|
||||
|
||||
// 'compile-expression-to-js' should be invoked after compiler has been started,
|
||||
// program was compiled.
|
||||
@ -791,16 +844,18 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
}
|
||||
|
||||
final String inputKey = Uuid().generateV4();
|
||||
_server.stdin.writeln('compile-expression-to-js $inputKey');
|
||||
_server.stdin.writeln(request.libraryUri ?? '');
|
||||
_server.stdin.writeln(request.line);
|
||||
_server.stdin.writeln(request.column);
|
||||
_server.stdin
|
||||
..writeln('compile-expression-to-js $inputKey')
|
||||
..writeln(request.libraryUri ?? '')
|
||||
..writeln(request.line)
|
||||
..writeln(request.column);
|
||||
request.jsModules?.forEach((String k, String v) { _server.stdin.writeln('$k:$v'); });
|
||||
_server.stdin.writeln(inputKey);
|
||||
request.jsFrameValues?.forEach((String k, String v) { _server.stdin.writeln('$k:$v'); });
|
||||
_server.stdin.writeln(inputKey);
|
||||
_server.stdin.writeln(request.moduleName ?? '');
|
||||
_server.stdin.writeln(request.expression ?? '');
|
||||
_server.stdin
|
||||
..writeln(inputKey)
|
||||
..writeln(request.moduleName ?? '')
|
||||
..writeln(request.expression ?? '');
|
||||
|
||||
return _stdoutHandler.compilerOutput.future;
|
||||
}
|
||||
@ -809,7 +864,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
void accept() {
|
||||
if (_compileRequestNeedsConfirmation) {
|
||||
_server.stdin.writeln('accept');
|
||||
globals.printTrace('<- accept');
|
||||
_logger.printTrace('<- accept');
|
||||
}
|
||||
_compileRequestNeedsConfirmation = false;
|
||||
}
|
||||
@ -831,7 +886,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
}
|
||||
_stdoutHandler.reset(expectSources: false);
|
||||
_server.stdin.writeln('reject');
|
||||
globals.printTrace('<- reject');
|
||||
_logger.printTrace('<- reject');
|
||||
_compileRequestNeedsConfirmation = false;
|
||||
return _stdoutHandler.compilerOutput.future;
|
||||
}
|
||||
@ -839,7 +894,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
@override
|
||||
void reset() {
|
||||
_server?.stdin?.writeln('reset');
|
||||
globals.printTrace('<- reset');
|
||||
_logger.printTrace('<- reset');
|
||||
}
|
||||
|
||||
@override
|
||||
@ -848,7 +903,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
||||
if (_server == null) {
|
||||
return 0;
|
||||
}
|
||||
globals.printTrace('killing pid ${_server.pid}');
|
||||
_logger.printTrace('killing pid ${_server.pid}');
|
||||
_server.kill();
|
||||
return _server.exitCode;
|
||||
}
|
||||
|
@ -148,7 +148,12 @@ Future<T> runInContext<T>(
|
||||
xcode: globals.xcode,
|
||||
),
|
||||
IOSWorkflow: () => const IOSWorkflow(),
|
||||
KernelCompilerFactory: () => const KernelCompilerFactory(),
|
||||
KernelCompilerFactory: () => KernelCompilerFactory(
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
artifacts: globals.artifacts,
|
||||
fileSystem: globals.fs,
|
||||
),
|
||||
Logger: () => globals.platform.isWindows
|
||||
? WindowsStdoutLogger(
|
||||
terminal: globals.terminal,
|
||||
|
@ -18,7 +18,6 @@ import 'base/file_system.dart';
|
||||
import 'base/io.dart' as io;
|
||||
import 'base/logger.dart';
|
||||
import 'base/signals.dart';
|
||||
import 'base/terminal.dart';
|
||||
import 'base/utils.dart';
|
||||
import 'build_info.dart';
|
||||
import 'build_system/build_system.dart';
|
||||
@ -63,6 +62,9 @@ class FlutterDevice {
|
||||
dartDefines: buildInfo.dartDefines,
|
||||
packagesPath: globalPackagesPath,
|
||||
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: globals.processManager,
|
||||
logger: globals.logger,
|
||||
);
|
||||
|
||||
/// Create a [FlutterDevice] with optional code generation enabled.
|
||||
@ -99,9 +101,6 @@ class FlutterDevice {
|
||||
// Override the filesystem scheme so that the frontend_server can find
|
||||
// the generated entrypoint code.
|
||||
fileSystemScheme: 'org-dartlang-app',
|
||||
compilerMessageConsumer:
|
||||
(String message, {bool emphasis, TerminalColor color, }) =>
|
||||
globals.printTrace(message),
|
||||
initializeFromDill: getDefaultCachedKernelPath(
|
||||
trackWidgetCreation: buildInfo.trackWidgetCreation,
|
||||
dartDefines: buildInfo.dartDefines,
|
||||
@ -115,6 +114,9 @@ class FlutterDevice {
|
||||
librariesSpec: globals.fs.file(globals.artifacts
|
||||
.getArtifactPath(Artifact.flutterWebLibrariesJson)).uri.toString(),
|
||||
packagesPath: globalPackagesPath,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: globals.processManager,
|
||||
logger: globals.logger,
|
||||
);
|
||||
} else {
|
||||
generator = ResidentCompiler(
|
||||
@ -135,6 +137,9 @@ class FlutterDevice {
|
||||
dartDefines: buildInfo.dartDefines,
|
||||
),
|
||||
packagesPath: globalPackagesPath,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: globals.processManager,
|
||||
logger: globals.logger,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import 'package:package_config/package_config.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/terminal.dart';
|
||||
import '../build_info.dart';
|
||||
import '../bundle.dart';
|
||||
import '../codegen.dart';
|
||||
@ -71,11 +70,12 @@ class TestCompiler {
|
||||
|
||||
ResidentCompiler compiler;
|
||||
File outputDill;
|
||||
// Whether to report compiler messages.
|
||||
bool _suppressOutput = false;
|
||||
|
||||
Future<String> compile(Uri mainDart) {
|
||||
final Completer<String> completer = Completer<String>();
|
||||
if (compilerController.isClosed) {
|
||||
return null;
|
||||
}
|
||||
compilerController.add(_CompilationRequest(mainDart, completer));
|
||||
return completer.future;
|
||||
}
|
||||
@ -99,9 +99,11 @@ class TestCompiler {
|
||||
Future<ResidentCompiler> createCompiler() async {
|
||||
final ResidentCompiler residentCompiler = ResidentCompiler(
|
||||
globals.artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
|
||||
artifacts: globals.artifacts,
|
||||
logger: globals.logger,
|
||||
processManager: globals.processManager,
|
||||
buildMode: buildMode,
|
||||
trackWidgetCreation: trackWidgetCreation,
|
||||
compilerMessageConsumer: _reportCompilerMessage,
|
||||
initializeFromDill: testFilePath,
|
||||
unsafePackageSerialization: false,
|
||||
dartDefines: const <String>[],
|
||||
@ -129,10 +131,28 @@ class TestCompiler {
|
||||
if (!isEmpty) {
|
||||
return;
|
||||
}
|
||||
_packageConfig ??= await loadPackageConfigWithLogging(
|
||||
globals.fs.file(globalPackagesPath),
|
||||
logger: globals.logger,
|
||||
);
|
||||
if (_packageConfig == null) {
|
||||
_packageConfig ??= await loadPackageConfigWithLogging(
|
||||
globals.fs.file(globalPackagesPath),
|
||||
logger: globals.logger,
|
||||
);
|
||||
// Compilation will fail if there is no flutter_test dependency, since
|
||||
// this library is imported by the generated entrypoint script.
|
||||
if (_packageConfig['flutter_test'] == null) {
|
||||
globals.printError(
|
||||
'\n'
|
||||
'Error: cannot run without a dependency on "package:flutter_test". '
|
||||
'Ensure the following lines are present in your pubspec.yaml:'
|
||||
'\n\n'
|
||||
'dev_dependencies:\n'
|
||||
' flutter_test:\n'
|
||||
' sdk: flutter\n',
|
||||
);
|
||||
request.result.complete(null);
|
||||
await compilerController.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (compilationQueue.isNotEmpty) {
|
||||
final _CompilationRequest request = compilationQueue.first;
|
||||
globals.printTrace('Compiling ${request.mainUri}');
|
||||
@ -142,7 +162,6 @@ class TestCompiler {
|
||||
compiler = await createCompiler();
|
||||
firstCompile = true;
|
||||
}
|
||||
_suppressOutput = false;
|
||||
final CompilerOutput compilerOutput = await compiler.recompile(
|
||||
request.mainUri,
|
||||
<Uri>[request.mainUri],
|
||||
@ -179,20 +198,4 @@ class TestCompiler {
|
||||
compilationQueue.removeAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
void _reportCompilerMessage(String message, {bool emphasis, TerminalColor color}) {
|
||||
if (_suppressOutput) {
|
||||
return;
|
||||
}
|
||||
if (message.startsWith("Error: Could not resolve the package 'flutter_test'")) {
|
||||
globals.printTrace(message);
|
||||
globals.printError('\n\nFailed to load test harness. Are you missing a dependency on flutter_test?\n',
|
||||
emphasis: emphasis,
|
||||
color: color,
|
||||
);
|
||||
_suppressOutput = true;
|
||||
return;
|
||||
}
|
||||
globals.printError(message);
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,12 @@ import '../../src/mocks.dart';
|
||||
void main() {
|
||||
Daemon daemon;
|
||||
NotifyingLogger notifyingLogger;
|
||||
BufferLogger bufferLogger;
|
||||
|
||||
group('daemon', () {
|
||||
setUp(() {
|
||||
notifyingLogger = NotifyingLogger(verbose: false);
|
||||
bufferLogger = BufferLogger.test();
|
||||
notifyingLogger = NotifyingLogger(verbose: false, parent: bufferLogger);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
@ -299,19 +301,15 @@ void main() {
|
||||
});
|
||||
|
||||
testUsingContext('notifyingLogger outputs trace messages in verbose mode', () async {
|
||||
final NotifyingLogger logger = NotifyingLogger(verbose: true);
|
||||
final NotifyingLogger logger = NotifyingLogger(verbose: true, parent: bufferLogger);
|
||||
|
||||
final Future<LogMessage> messageResult = logger.onMessage.first;
|
||||
logger.printTrace('test');
|
||||
|
||||
final LogMessage message = await messageResult;
|
||||
|
||||
expect(message.level, 'trace');
|
||||
expect(message.message, 'test');
|
||||
expect(bufferLogger.errorText, contains('test'));
|
||||
});
|
||||
|
||||
testUsingContext('notifyingLogger ignores trace messages in non-verbose mode', () async {
|
||||
final NotifyingLogger logger = NotifyingLogger(verbose: false);
|
||||
final NotifyingLogger logger = NotifyingLogger(verbose: false, parent: bufferLogger);
|
||||
|
||||
final Future<LogMessage> messageResult = logger.onMessage.first;
|
||||
logger.printTrace('test');
|
||||
@ -321,10 +319,11 @@ void main() {
|
||||
|
||||
expect(message.level, 'status');
|
||||
expect(message.message, 'hello');
|
||||
expect(bufferLogger.errorText, contains('test'));
|
||||
});
|
||||
|
||||
testUsingContext('notifyingLogger buffers messages sent before a subscription', () async {
|
||||
final NotifyingLogger logger = NotifyingLogger(verbose: false);
|
||||
final NotifyingLogger logger = NotifyingLogger(verbose: false, parent: bufferLogger);
|
||||
|
||||
logger.printStatus('hello');
|
||||
|
||||
|
@ -4,14 +4,13 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/compile.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:process/process.dart';
|
||||
@ -27,13 +26,21 @@ void main() {
|
||||
MockStdIn mockFrontendServerStdIn;
|
||||
MockStream mockFrontendServerStdErr;
|
||||
StreamController<String> stdErrStreamController;
|
||||
BufferLogger testLogger;
|
||||
|
||||
setUp(() {
|
||||
generator = ResidentCompiler('sdkroot', buildMode: BuildMode.debug);
|
||||
testLogger = BufferLogger.test();
|
||||
mockProcessManager = MockProcessManager();
|
||||
mockFrontendServer = MockProcess();
|
||||
mockFrontendServerStdIn = MockStdIn();
|
||||
mockFrontendServerStdErr = MockStream();
|
||||
generator = ResidentCompiler(
|
||||
'sdkroot',
|
||||
buildMode: BuildMode.debug,
|
||||
artifacts: Artifacts.test(),
|
||||
processManager: mockProcessManager,
|
||||
logger: testLogger,
|
||||
);
|
||||
|
||||
when(mockFrontendServer.stdin).thenReturn(mockFrontendServerStdIn);
|
||||
when(mockFrontendServer.stderr)
|
||||
@ -52,13 +59,14 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testUsingContext('compile expression fails if not previously compiled', () async {
|
||||
testWithoutContext('compile expression fails if not previously compiled', () async {
|
||||
final CompilerOutput result = await generator.compileExpression(
|
||||
'2+2', null, null, null, null, false);
|
||||
|
||||
expect(result, isNull);
|
||||
});
|
||||
|
||||
testUsingContext('compile expression can compile single expression', () async {
|
||||
testWithoutContext('compile expression can compile single expression', () async {
|
||||
final Completer<List<int>> compileResponseCompleter =
|
||||
Completer<List<int>>();
|
||||
final Completer<List<int>> compileExpressionResponseCompleter =
|
||||
@ -76,7 +84,7 @@ void main() {
|
||||
)));
|
||||
|
||||
await generator.recompile(
|
||||
globals.fs.file('/path/to/main.dart').uri,
|
||||
Uri.file('/path/to/main.dart'),
|
||||
null, /* invalidatedFiles */
|
||||
outputPath: '/build/',
|
||||
packageConfig: PackageConfig.empty,
|
||||
@ -101,14 +109,9 @@ void main() {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
|
||||
testUsingContext('compile expressions without awaiting', () async {
|
||||
testWithoutContext('compile expressions without awaiting', () async {
|
||||
final Completer<List<int>> compileResponseCompleter = Completer<List<int>>();
|
||||
final Completer<List<int>> compileExpressionResponseCompleter1 = Completer<List<int>>();
|
||||
final Completer<List<int>> compileExpressionResponseCompleter2 = Completer<List<int>>();
|
||||
@ -174,10 +177,6 @@ void main() {
|
||||
)));
|
||||
|
||||
expect(await lastExpressionCompleted.future, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/async_guard.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/compile.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
@ -26,13 +26,21 @@ void main() {
|
||||
MockStdIn mockFrontendServerStdIn;
|
||||
MockStream mockFrontendServerStdErr;
|
||||
StreamController<String> stdErrStreamController;
|
||||
BufferLogger testLogger;
|
||||
|
||||
setUp(() {
|
||||
generator = ResidentCompiler('sdkroot', buildMode: BuildMode.debug);
|
||||
testLogger = BufferLogger.test();
|
||||
mockProcessManager = MockProcessManager();
|
||||
mockFrontendServer = MockProcess();
|
||||
mockFrontendServerStdIn = MockStdIn();
|
||||
mockFrontendServerStdErr = MockStream();
|
||||
generator = ResidentCompiler(
|
||||
'sdkroot',
|
||||
buildMode: BuildMode.debug,
|
||||
logger: testLogger,
|
||||
processManager: mockProcessManager,
|
||||
artifacts: Artifacts.test(),
|
||||
);
|
||||
|
||||
when(mockFrontendServer.stdin).thenReturn(mockFrontendServerStdIn);
|
||||
when(mockFrontendServer.stderr)
|
||||
@ -50,7 +58,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testUsingContext('incremental compile single dart compile', () async {
|
||||
testWithoutContext('incremental compile single dart compile', () async {
|
||||
when(mockFrontendServer.stdout)
|
||||
.thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
|
||||
Future<List<int>>.value(utf8.encode(
|
||||
@ -68,13 +76,9 @@ void main() {
|
||||
verifyNoMoreInteractions(mockFrontendServerStdIn);
|
||||
expect(testLogger.errorText, equals('line1\nline2\n'));
|
||||
expect(output.outputFilename, equals('/path/to/main.dart.dill'));
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
|
||||
testUsingContext('incremental compile single dart compile abnormally terminates', () async {
|
||||
testWithoutContext('incremental compile single dart compile abnormally terminates', () async {
|
||||
when(mockFrontendServer.stdout)
|
||||
.thenAnswer((Invocation invocation) => const Stream<List<int>>.empty()
|
||||
);
|
||||
@ -85,13 +89,9 @@ void main() {
|
||||
outputPath: '/build/',
|
||||
packageConfig: PackageConfig.empty,
|
||||
)), throwsToolExit());
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
|
||||
testUsingContext('incremental compile single dart compile abnormally terminates via exitCode', () async {
|
||||
testWithoutContext('incremental compile single dart compile abnormally terminates via exitCode', () async {
|
||||
when(mockFrontendServer.exitCode)
|
||||
.thenAnswer((Invocation invocation) async => 1);
|
||||
when(mockFrontendServer.stdout)
|
||||
@ -104,13 +104,9 @@ void main() {
|
||||
outputPath: '/build/',
|
||||
packageConfig: PackageConfig.empty,
|
||||
)), throwsToolExit());
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
|
||||
testUsingContext('incremental compile and recompile', () async {
|
||||
testWithoutContext('incremental compile and recompile', () async {
|
||||
final StreamController<List<int>> streamController = StreamController<List<int>>();
|
||||
when(mockFrontendServer.stdout)
|
||||
.thenAnswer((Invocation invocation) => streamController.stream);
|
||||
@ -145,13 +141,9 @@ void main() {
|
||||
'line1\nline2\n'
|
||||
'line1\nline2\n'
|
||||
));
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
|
||||
testUsingContext('incremental compile can suppress errors', () async {
|
||||
testWithoutContext('incremental compile can suppress errors', () async {
|
||||
final StreamController<List<int>> stdoutController = StreamController<List<int>>();
|
||||
when(mockFrontendServer.stdout)
|
||||
.thenAnswer((Invocation invocation) => stdoutController.stream);
|
||||
@ -179,17 +171,14 @@ void main() {
|
||||
|
||||
// Compiler message is not printed with suppressErrors: true above.
|
||||
expect(testLogger.errorText, isNot(equals(
|
||||
'line0\nline1\n'
|
||||
'line1\nline2\n'
|
||||
'line1\nline2\n'
|
||||
)));
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
expect(testLogger.traceText, contains(
|
||||
'line1\nline2\n'
|
||||
));
|
||||
});
|
||||
|
||||
testUsingContext('incremental compile and recompile twice', () async {
|
||||
testWithoutContext('incremental compile and recompile twice', () async {
|
||||
final StreamController<List<int>> streamController = StreamController<List<int>>();
|
||||
when(mockFrontendServer.stdout)
|
||||
.thenAnswer((Invocation invocation) => streamController.stream);
|
||||
@ -216,10 +205,6 @@ void main() {
|
||||
'line1\nline2\n'
|
||||
'line2\nline3\n'
|
||||
));
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/compile.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
|
||||
void main() {
|
||||
testUsingContext('StdOutHandler test', () async {
|
||||
final StdoutHandler stdoutHandler = StdoutHandler();
|
||||
testWithoutContext('StdoutHandler can produce output message', () async {
|
||||
final StdoutHandler stdoutHandler = StdoutHandler(logger: BufferLogger.test());
|
||||
stdoutHandler.handler('result 12345');
|
||||
expect(stdoutHandler.boundaryKey, '12345');
|
||||
stdoutHandler.handler('12345');
|
||||
@ -19,7 +19,7 @@ void main() {
|
||||
expect(output.outputFilename, 'message');
|
||||
});
|
||||
|
||||
test('TargetModel values', () {
|
||||
testWithoutContext('TargetModel values', () {
|
||||
expect(TargetModel('vm'), TargetModel.vm);
|
||||
expect(TargetModel.vm.toString(), 'vm');
|
||||
|
||||
|
@ -12,6 +12,7 @@ import 'package:flutter_tools/src/test/test_compiler.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
import '../src/testbed.dart';
|
||||
|
||||
final Platform linuxPlatform = FakePlatform(
|
||||
@ -32,7 +33,7 @@ void main() {
|
||||
},
|
||||
setup: () async {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
globals.fs.file('.packages').writeAsStringSync('flutter_test:flutter_test/');
|
||||
globals.fs.file('test/foo.dart').createSync(recursive: true);
|
||||
residentCompiler = MockResidentCompiler();
|
||||
testCompiler = FakeTestCompiler(
|
||||
@ -86,6 +87,19 @@ void main() {
|
||||
expect(testCompiler.compilerController.isClosed, true);
|
||||
verify(residentCompiler.shutdown()).called(1);
|
||||
}));
|
||||
|
||||
test('Reports an error when there is no dependency on flutter_test', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
|
||||
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null);
|
||||
expect(testLogger.errorText, contains('Error: cannot run without a dependency on "package:flutter_test"'));
|
||||
verifyNever(residentCompiler.recompile(
|
||||
any,
|
||||
<Uri>[Uri.parse('test/foo.dart')],
|
||||
outputPath: testCompiler.outputDill.path,
|
||||
packageConfig: anyNamed('packageConfig'),
|
||||
));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -244,11 +244,11 @@ class FakeProcess implements Process {
|
||||
FakeProcess({
|
||||
this.pid = 1,
|
||||
Future<int> exitCode,
|
||||
Stream<List<int>> stdin,
|
||||
IOSink stdin,
|
||||
this.stdout = const Stream<List<int>>.empty(),
|
||||
this.stderr = const Stream<List<int>>.empty(),
|
||||
}) : exitCode = exitCode ?? Future<int>.value(0),
|
||||
stdin = stdin as IOSink ?? MemoryIOSink();
|
||||
stdin = stdin ?? MemoryIOSink();
|
||||
|
||||
@override
|
||||
final int pid;
|
||||
|
Loading…
x
Reference in New Issue
Block a user