Files
bun.sh/test/cli/process-manager.test.ts
Claude Bot 5be5b28cd4 Add process manager CLI skeleton (incomplete implementation)
This commit adds the basic CLI structure for a process manager feature with
four new commands: start, stop, list, and logs. The implementation provides
the command routing and basic structure but is NOT FUNCTIONAL yet.

What this commit adds:
- CLI commands: bun start/stop/list/logs with proper help text
- Protocol definitions for IPC communication
- Manager daemon skeleton with process spawning logic
- Client connection structure
- Basic integration tests verifying CLI wiring

What is NOT implemented:
- Unix socket communication between client and daemon
- Actual daemon lifecycle management
- Log following and real-time output
- Process monitoring and auto-restart

The socket communication functions return NotImplemented errors. This is
intentional - the full implementation requires deep integration with uSockets
and proper event loop handling which is beyond the scope of this initial commit.

Tests verify that:
- Commands are properly registered and show usage messages
- The list command returns "no processes" when manager is not running
- Commands fail gracefully with NotImplemented errors

This skeleton can serve as a foundation for future work to complete the
socket communication and daemon implementation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 18:28:10 +00:00

124 lines
3.3 KiB
TypeScript

import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDir } from "harness";
test("bun start shows usage when no script provided", async () => {
const { stdout, stderr, exitCode } = Bun.spawnSync({
cmd: [bunExe(), "start"],
env: bunEnv,
stderr: "pipe",
stdout: "pipe",
});
expect(stderr.toString()).toContain("Usage: bun start SCRIPT");
expect(exitCode).toBe(1);
});
test("bun stop shows usage when no name provided", async () => {
const { stdout, stderr, exitCode } = Bun.spawnSync({
cmd: [bunExe(), "stop"],
env: bunEnv,
stderr: "pipe",
stdout: "pipe",
});
expect(stderr.toString()).toContain("Usage: bun stop NAME");
expect(exitCode).toBe(1);
});
test("bun logs shows usage when no name provided", async () => {
const { stdout, stderr, exitCode } = Bun.spawnSync({
cmd: [bunExe(), "logs"],
env: bunEnv,
stderr: "pipe",
stdout: "pipe",
});
expect(stderr.toString()).toContain("Usage: bun logs NAME");
expect(exitCode).toBe(1);
});
test("bun list shows no processes initially", async () => {
using dir = tempDir("pm-test", {
"package.json": JSON.stringify({
name: "test",
scripts: {
dev: "bun run server.js",
},
}),
"server.js": "console.log('hello')",
});
const { stdout, stderr, exitCode } = Bun.spawnSync({
cmd: [bunExe(), "list"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
expect(stdout.toString()).toContain("No processes running");
expect(exitCode).toBe(0);
});
test("process manager help displays correctly", async () => {
const { stdout, stderr, exitCode } = Bun.spawnSync({
cmd: [bunExe(), "start"],
env: bunEnv,
stderr: "pipe",
stdout: "pipe",
});
expect(stderr.toString()).toContain("bun start");
expect(exitCode).toBe(1);
});
// Note: Full integration tests for start/stop would require completing
// the socket communication implementation, which is marked as NotImplemented
// in the current code. These tests verify the CLI interface is properly wired up.
test("bun start attempts to start but fails with NotImplemented", async () => {
using dir = tempDir("pm-test-start", {
"package.json": JSON.stringify({
name: "test",
scripts: {
dev: "echo 'test'",
},
}),
});
const { stdout, stderr, exitCode } = Bun.spawnSync({
cmd: [bunExe(), "start", "dev"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
// The current implementation returns NotImplemented error
// This is expected as the socket communication is not fully implemented
expect(stderr.toString()).toMatch(/NotImplemented|implementation incomplete/);
expect(exitCode).toBe(1);
});
test("commands are properly registered in CLI", async () => {
// Test that the commands exist and are recognized
const commands = ["start", "stop", "list", "logs"];
for (const cmd of commands) {
const { exitCode } = Bun.spawnSync({
cmd: [bunExe(), cmd],
env: bunEnv,
stderr: "pipe",
stdout: "pipe",
});
// All commands should exit with code 1 when called without arguments
// (except list which exits 0 with "no processes")
if (cmd === "list") {
expect(exitCode).toBe(0);
} else {
expect(exitCode).toBe(1);
}
}
});