platform/packages/process/test/pending_process_test.dart
2024-12-30 06:35:33 -07:00

158 lines
4.7 KiB
Dart

import 'dart:io';
import 'package:test/test.dart';
import 'package:platform_process/process.dart';
void main() {
group('PendingProcess', () {
late PendingProcess process;
setUp(() {
process = PendingProcess();
});
test('configures command', () {
process.command('echo test');
expect(process.run(), completes);
});
test('configures working directory', () async {
final result =
await process.command('pwd').path(Directory.current.path).run();
expect(result.output().trim(), equals(Directory.current.path));
});
test('configures environment variables', () async {
final result = await process
.command('printenv TEST_VAR')
.env({'TEST_VAR': 'test_value'}).run();
expect(result.output().trim(), equals('test_value'));
});
test('handles string input', () async {
final result = await process.command('cat').input('test input\n').run();
expect(result.output().trim(), equals('test input'));
});
test('handles list input', () async {
final result = await process
.command('cat')
.input([116, 101, 115, 116]) // "test" in bytes
.run();
expect(result.output(), equals('test'));
});
test('respects timeout', () async {
// Use a longer timeout to avoid flakiness
process.command('sleep 5').timeout(1);
final startTime = DateTime.now();
try {
await process.run();
fail('Expected ProcessTimeoutException');
} catch (e) {
expect(e, isA<ProcessTimeoutException>());
final duration = DateTime.now().difference(startTime);
expect(duration.inSeconds, lessThanOrEqualTo(2)); // Allow some buffer
}
});
test('runs forever when timeout disabled', () async {
final result = await process.command('echo test').forever().run();
expect(result.successful(), isTrue);
});
test('captures output in real time', () async {
final output = <String>[];
// Create a platform-independent way to generate sequential output
final command = Platform.isWindows
? 'cmd /c "(echo 1 && timeout /T 1 > nul) && (echo 2 && timeout /T 1 > nul) && echo 3"'
: 'sh -c "echo 1; sleep 0.1; echo 2; sleep 0.1; echo 3"';
final result = await process
.command(command)
.run((String data) => output.add(data.trim()));
final numbers = output
.where((s) => s.isNotEmpty)
.map((s) => s.trim())
.where((s) => s.contains(RegExp(r'^[123]$')))
.toList();
expect(numbers, equals(['1', '2', '3']));
expect(result.successful(), isTrue);
});
test('disables output when quiet', () async {
final output = <String>[];
final result = await process
.command('echo test')
.quietly()
.run((String data) => output.add(data));
expect(output, isEmpty);
expect(result.output(), isNotEmpty);
});
test('enables TTY mode', () async {
final result = await process.command('test -t 0').tty().run();
expect(result.successful(), isTrue);
});
test('starts process in background', () async {
final proc = await process.command('sleep 1').start();
expect(proc.pid, isPositive);
await proc.kill();
});
test('throws on invalid command', () {
expect(
() => process.run(),
throwsA(isA<ArgumentError>().having(
(e) => e.message,
'message',
'No command has been specified.',
)),
);
});
test('handles command as list', () async {
final result = await process.command(['echo', 'test']).run();
expect(result.output().trim(), equals('test'));
});
test('preserves environment isolation', () async {
// First process
final result1 = await process
.command('printenv TEST_VAR')
.env({'TEST_VAR': 'value1'}).run();
// Second process with different environment
final result2 = await PendingProcess()
.command('printenv TEST_VAR')
.env({'TEST_VAR': 'value2'}).run();
expect(result1.output().trim(), equals('value1'));
expect(result2.output().trim(), equals('value2'));
});
test('handles process termination', () async {
final proc = await process.command('sleep 10').start();
expect(proc.kill(), isTrue);
expect(await proc.exitCode, isNot(0));
});
test('supports chained configuration', () async {
final result = await process
.command('echo test')
.path(Directory.current.path)
.env({'TEST': 'value'})
.timeout(5)
.quietly()
.run();
expect(result.successful(), isTrue);
});
});
}