From 5a2f2aff685d72f35eaff295491f6c76655de738 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Mon, 13 Oct 2025 06:32:33 +0000 Subject: [PATCH] Add tests for watch mode polling for missing modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests verify that: 1. Watch mode starts polling when a required module doesn't exist 2. Polling detects when the file is created and triggers reload 3. Works with both direct imports and relative paths in subdirectories Note: Tests verify the polling and reload trigger, but not the success output after reload since process restart (via bun.reloadProcess) creates a new process that can't be captured by the test harness. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- test/cli/watch/watch-missing-module.test.ts | 116 ++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 test/cli/watch/watch-missing-module.test.ts diff --git a/test/cli/watch/watch-missing-module.test.ts b/test/cli/watch/watch-missing-module.test.ts new file mode 100644 index 0000000000..23952fa1d1 --- /dev/null +++ b/test/cli/watch/watch-missing-module.test.ts @@ -0,0 +1,116 @@ +import { expect, test } from "bun:test"; +import fs from "fs"; +import { bunEnv, bunExe, tempDir } from "harness"; +import { join } from "path"; + +test("watch mode should poll and reload when a missing required file is created", async () => { + using dir = tempDir("watch-missing-module", { + "file1.ts": ` + import { message } from "./file2.ts"; + console.log("SUCCESS:", message); + `, + }); + + // Start bun in watch mode (file2.ts doesn't exist yet) + await using proc = Bun.spawn({ + cmd: [bunExe(), "--watch", "file1.ts"], + cwd: String(dir), + env: bunEnv, + stdout: "pipe", + stderr: "pipe", + stdin: "ignore", + }); + + let stdout = ""; + let stderr = ""; + + const stdoutReader = (async () => { + for await (const chunk of proc.stdout) { + stdout += new TextDecoder().decode(chunk); + } + })(); + + const stderrReader = (async () => { + for await (const chunk of proc.stderr) { + stderr += new TextDecoder().decode(chunk); + } + })(); + + // Wait for polling to start and for output to be captured + await Bun.sleep(1500); + + const combined1 = stdout + stderr; + + // Should see the polling message + expect(combined1).toContain("Module not found"); + expect(combined1).toContain("Polling every 50ms"); + + // Now create the missing file + fs.writeFileSync(join(String(dir), "file2.ts"), `export const message = "Hello from file2!";\n`); + + // Wait for polling to detect it and reload + await Bun.sleep(300); + + proc.kill(); + await Promise.race([proc.exited, Bun.sleep(2000)]); + + await Promise.race([Promise.all([stdoutReader, stderrReader]), Bun.sleep(500)]); + + const combined2 = stdout + stderr; + + // Should see the reload message + // Note: The actual "SUCCESS" output happens after the process restart, + // which creates a new process that we can't capture in this test. + // But we can verify that the polling detected the file and triggered reload. + expect(combined2).toContain("now exists, reloading"); +}, 10000); + +test("watch mode should handle relative path imports that don't exist", async () => { + using dir = tempDir("watch-missing-relative", { + "index.ts": ` + import { data } from "./lib/helper.ts"; + console.log("LOADED:", data); + `, + }); + + await using proc = Bun.spawn({ + cmd: [bunExe(), "--watch", "index.ts"], + cwd: String(dir), + env: bunEnv, + stdout: "pipe", + stderr: "pipe", + stdin: "ignore", + }); + + let output = ""; + + const reader = (async () => { + for await (const chunk of proc.stdout) { + output += new TextDecoder().decode(chunk); + } + })(); + + const errReader = (async () => { + for await (const chunk of proc.stderr) { + output += new TextDecoder().decode(chunk); + } + })(); + + await Bun.sleep(1500); + + // Should be polling for the missing file + expect(output).toContain("Polling every 50ms"); + + // Create the directory and file + fs.mkdirSync(join(String(dir), "lib"), { recursive: true }); + fs.writeFileSync(join(String(dir), "lib", "helper.ts"), `export const data = 42;\n`); + + await Bun.sleep(300); + + proc.kill(); + await Promise.race([proc.exited, Bun.sleep(2000)]); + await Promise.race([Promise.all([reader, errReader]), Bun.sleep(500)]); + + // Should see the reload message + expect(output).toContain("now exists, reloading"); +}, 10000);