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()); 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 = []; // 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 = []; 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().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); }); }); }