| 1 | import os |
| 2 | import time |
| 3 | |
| 4 | const ready_marker = 'ready\n' |
| 5 | |
| 6 | fn test_stdout_is_flushed_by_default() { |
| 7 | $if windows { |
| 8 | return |
| 9 | } |
| 10 | mut cap := os.stdio_capture()! |
| 11 | println('ready') |
| 12 | mut pending := false |
| 13 | for _ in 0 .. 100 { |
| 14 | if os.fd_is_pending(cap.stdout.read_fd) { |
| 15 | pending = true |
| 16 | break |
| 17 | } |
| 18 | time.sleep(10 * time.millisecond) |
| 19 | } |
| 20 | cap.stop() |
| 21 | stdout := cap.stdout.slurp().join('') |
| 22 | stderr := cap.stderr.slurp().join('') |
| 23 | cap.close() |
| 24 | assert pending |
| 25 | assert stdout == ready_marker, stdout |
| 26 | assert stderr == '' |
| 27 | } |
| 28 | |
| 29 | fn redirected_stdout_bytes(snippet string) ![]u8 { |
| 30 | stamp := time.now().unix_milli() |
| 31 | source_path := os.join_path(os.vtmp_dir(), 'redirected_stdout_${stamp}.v') |
| 32 | output_path := os.join_path(os.vtmp_dir(), 'redirected_stdout_${stamp}.bin') |
| 33 | os.write_file(source_path, 'fn main() {\n\t${snippet}\n}\n')! |
| 34 | defer { |
| 35 | os.rm(source_path) or {} |
| 36 | os.rm(output_path) or {} |
| 37 | } |
| 38 | cmd := '${os.quoted_path(@VEXE)} run ${os.quoted_path(source_path)} > ${os.quoted_path(output_path)}' |
| 39 | res := os.execute(cmd) |
| 40 | assert res.exit_code == 0, 'command failed: ${cmd}\noutput:\n${res.output}' |
| 41 | return os.read_bytes(output_path)! |
| 42 | } |
| 43 | |
| 44 | fn assert_redirected_stdout_bytes(snippet string, expected []u8) ! { |
| 45 | bytes := redirected_stdout_bytes(snippet)! |
| 46 | assert bytes == expected, 'expected ${expected}, got ${bytes}' |
| 47 | } |
| 48 | |
| 49 | fn test_redirected_stdout_preserves_newline_bytes() ! { |
| 50 | assert_redirected_stdout_bytes(r"print('\n')", [u8(`\n`)])! |
| 51 | assert_redirected_stdout_bytes(r"print('\r\n')", [u8(`\r`), `\n`])! |
| 52 | } |
| 53 | |