diff --git a/test/js/bun/shell/file-io.test.ts b/test/js/bun/shell/file-io.test.ts index 5b10f0351a8e..d85fddc954aa 100644 --- a/test/js/bun/shell/file-io.test.ts +++ b/test/js/bun/shell/file-io.test.ts @@ -225,14 +225,32 @@ describe("IOWriter file output redirection", () => { // command caused the same file descriptor to be closed twice, resulting // in an EBADF error. The issue was that two separate IOWriter instances // were created for the same fd when both stdout and stderr were redirected. - TestBuilder.command`pwd &> pwd_output.txt`.exitCode(0).runAsTest("builtin pwd with &> redirect"); + TestBuilder.command`pwd &> pwd_output.txt` + .exitCode(0) + .fileEquals("pwd_output.txt", "$TEMP_DIR\n") + .runAsTest("builtin pwd with &> redirect"); TestBuilder.command`echo "hello" &> echo_output.txt` .exitCode(0) .fileEquals("echo_output.txt", "hello\n") .runAsTest("builtin echo with &> redirect"); - TestBuilder.command`pwd &>> append_output.txt`.exitCode(0).runAsTest("builtin pwd with &>> append redirect"); + TestBuilder.command`pwd extra-arg &> stderr_output.txt` + .exitCode(1) + .stderr("") + .fileEquals("stderr_output.txt", "pwd: too many arguments\n") + .runAsTest("builtin stderr with &> redirect"); + + TestBuilder.command`pwd &>> append_output.txt` + .file("append_output.txt", "existing line\n") + .exitCode(0) + .fileEquals("append_output.txt", "existing line\n$TEMP_DIR\n") + .runAsTest("builtin pwd with &>> append redirect"); + + TestBuilder.command`pwd &>> new_append_output.txt` + .exitCode(0) + .fileEquals("new_append_output.txt", "$TEMP_DIR\n") + .runAsTest("builtin pwd with &>> redirect creates a missing file"); }); }); diff --git a/test/js/bun/shell/test_builder.ts b/test/js/bun/shell/test_builder.ts index 64a90a805548..5d6033f3c74f 100644 --- a/test/js/bun/shell/test_builder.ts +++ b/test/js/bun/shell/test_builder.ts @@ -171,6 +171,10 @@ export function createTestBuilder(path: string) { return this; } + /** + * Expect a file in the temp directory to have the given contents. Like + * `stdout()`, a string `expected` has `$TEMP_DIR` replaced with the temp directory. + */ fileEquals(filename: string, expected: string | (() => string | Promise)): this { this.getTempDir(); this.file_equals[filename] = expected; @@ -228,7 +232,8 @@ export function createTestBuilder(path: string) { } else if (typeof this.expected_exit_code === "function") this.expected_exit_code(exitCode); for (const [filename, expected_raw] of Object.entries(this.file_equals)) { - const expected = typeof expected_raw === "string" ? expected_raw : await expected_raw(); + const expected = + typeof expected_raw === "string" ? expected_raw.replaceAll("$TEMP_DIR", tempdir) : await expected_raw(); const actual = await Bun.file(join(this.tempdir!, filename)).text(); expect(actual).toEqual(expected); } @@ -256,7 +261,7 @@ export function createTestBuilder(path: string) { if (stdout === undefined || stderr === undefined || exitCode === undefined) { throw err_; } - this.doChecks(stdout, stderr, exitCode); + await this.doChecks(stdout, stderr, exitCode); return; } if (this.expected_error === true) return undefined;