| import 'dart:async'; |
| import 'dart:io'; |
| import 'package:fxtest/fxtest.dart'; |
| |
| abstract class BaseOutput { |
| final String content; |
| BaseOutput(this.content); |
| } |
| |
| /// Content for the stdout. |
| class Output extends BaseOutput { |
| Output(String content) : super(content); |
| @override |
| String toString() => '<Output "$content">'; |
| } |
| |
| /// Content for the stderr. |
| class ErrOutput extends BaseOutput { |
| ErrOutput(String content) : super(content); |
| @override |
| String toString() => '<ErrOutput "$content">'; |
| } |
| |
| /// Fake "TestRunner" which emits scripted output at scripted intervals. |
| class ScriptedTestRunner extends TestRunner { |
| /// Series of [BaseOutput]s and [Duration]s which this class will funnel into |
| /// [realtimeOutputSink] and [realtimeErrorSink]. |
| final List scriptedOutput; |
| final int exitCode; |
| final int pid; |
| |
| ScriptedTestRunner({ |
| required this.scriptedOutput, |
| this.exitCode = 0, |
| this.pid = 1, |
| }) : super(); |
| |
| Future<ProcessResult> easyRun() { |
| return run( |
| '/some-cmd', |
| ['meaningless', 'args'], |
| workingDirectory: '/whatever', |
| ); |
| } |
| |
| @override |
| Future<ProcessResult> run( |
| String command, |
| List<String> args, { |
| required String workingDirectory, |
| Map<String, String>? environment, |
| }) async { |
| var _out = StringBuffer(); |
| var _err = StringBuffer(); |
| for (var _output in scriptedOutput) { |
| if (_output is Output) { |
| _out.writeln(_output.content); |
| addOutput(_output.content); |
| } else if (_output is ErrOutput) { |
| _err.writeln(_output.content); |
| addOutput(_output.content); |
| // addError(_output.content); |
| } else if (_output is Duration) { |
| await Future.delayed(_output); |
| } else { |
| throw Exception('`output` variable must only contain `BaseOutput` ' |
| 'and `Duration` instances'); |
| } |
| } |
| return ProcessResult(pid, exitCode, _out.toString(), _err.toString()); |
| } |
| } |
| |
| /// Fake version of [TestRunner] whose [run] method returns a contrived |
| /// [ProcessResult] instance without ever creating a process. |
| class FakeTestRunner extends TestRunner { |
| final int exitCode; |
| |
| FakeTestRunner._(this.exitCode) : super(); |
| factory FakeTestRunner.passing() => FakeTestRunner._(0); |
| factory FakeTestRunner.failing() => FakeTestRunner._(2); |
| |
| @override |
| Future<ProcessResult> run( |
| String command, |
| List<String> args, { |
| required String workingDirectory, |
| Map<String, String>? environment, |
| }) async { |
| String _stdout = args.join(' '); |
| addOutput(_stdout); |
| |
| String _stderr = workingDirectory.toString(); |
| addOutput(_stderr); |
| |
| await close(); |
| |
| return Future.value(ProcessResult(1, exitCode, _stdout, _stderr)); |
| } |
| } |
| |
| class AlwaysAllowChecklist implements Checklist { |
| @override |
| Future<bool> isDeviceReady(List<TestBundle> bundles) => Future.value(true); |
| } |