Skip to content

Commit e3ebd46

Browse files
feat(cli): Improve bunfig.toml handling and test (#13)
1 parent aeb8452 commit e3ebd46

File tree

2 files changed

+140
-5
lines changed

2 files changed

+140
-5
lines changed

cli.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bun
22

3-
import { mkdir, writeFile, access } from "node:fs/promises"
3+
import { mkdir, writeFile, access, readFile, appendFile } from "node:fs/promises"
44
import { spawn } from "node:child_process"
55

66
const EXAMPLE_TEST = `import { expect, test } from "bun:test"
@@ -21,7 +21,7 @@ const PRELOAD_FILE = `import "bun-match-svg"`
2121
const BUNFIG = `[test]
2222
preload = ["./tests/fixtures/preload.ts"]`
2323

24-
async function installDependency() {
24+
export async function installDependency() {
2525
return new Promise((resolve, reject) => {
2626
const install = spawn('bun', ['add', '-d', 'bun-match-svg'], {
2727
stdio: 'inherit'
@@ -37,7 +37,7 @@ async function installDependency() {
3737
})
3838
}
3939

40-
async function fileExists(path: string): Promise<boolean> {
40+
export async function fileExists(path: string): Promise<boolean> {
4141
try {
4242
await access(path)
4343
return true
@@ -46,7 +46,7 @@ async function fileExists(path: string): Promise<boolean> {
4646
}
4747
}
4848

49-
async function init() {
49+
export async function init() {
5050
try {
5151
console.log("📦 Installing bun-match-svg...")
5252
await installDependency()
@@ -71,7 +71,20 @@ async function init() {
7171
await writeFile("bunfig.toml", BUNFIG)
7272
console.log("✅ Created bunfig.toml")
7373
} else {
74-
console.log("🔒 bunfig.toml already exists, skipping.")
74+
const bunfigContent = await readFile("bunfig.toml", "utf-8")
75+
if (bunfigContent.includes('preload = ["./tests/fixtures/preload.ts"]')) {
76+
console.log("🔒 bunfig.toml already has preload configuration, skipping.")
77+
} else if (bunfigContent.match(/^\s*\[test\]\s*$/m)) {
78+
const updatedContent = bunfigContent.replace(
79+
/(^\s*\[test\]\s*$)/m,
80+
`$1\npreload = ["./tests/fixtures/preload.ts"]`,
81+
)
82+
await writeFile("bunfig.toml", updatedContent)
83+
console.log("✅ Updated bunfig.toml with preload configuration.")
84+
} else {
85+
await appendFile("bunfig.toml", `\n\n${BUNFIG}`)
86+
console.log("✅ Added preload configuration to bunfig.toml.")
87+
}
7588
}
7689

7790
console.log("\n🎉 You can now run: bun test")

tests/cli.test.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import {
2+
afterAll,
3+
afterEach,
4+
beforeAll,
5+
beforeEach,
6+
describe,
7+
expect,
8+
spyOn,
9+
test,
10+
type Mock,
11+
} from "bun:test"
12+
import * as fs from "node:fs/promises"
13+
import * as path from "node:path"
14+
import * as cli from "../cli"
15+
16+
const tempDir = path.join(__dirname, "cli-test-temp")
17+
const originalCwd = process.cwd()
18+
19+
describe("cli init", () => {
20+
let installSpy: Mock<typeof cli.installDependency>
21+
let consoleSpy: Mock<typeof console.log>
22+
23+
beforeAll(async () => {
24+
await fs.mkdir(tempDir, { recursive: true })
25+
})
26+
27+
afterAll(async () => {
28+
await fs.rm(tempDir, { recursive: true, force: true })
29+
})
30+
31+
beforeEach(async () => {
32+
process.chdir(tempDir)
33+
installSpy = spyOn(cli, "installDependency").mockImplementation(async () => {})
34+
consoleSpy = spyOn(console, "log").mockImplementation(() => {})
35+
})
36+
37+
afterEach(async () => {
38+
process.chdir(originalCwd)
39+
const files = await fs.readdir(tempDir)
40+
for (const file of files) {
41+
await fs.rm(path.join(tempDir, file), { recursive: true, force: true })
42+
}
43+
installSpy.mockRestore()
44+
consoleSpy.mockRestore()
45+
})
46+
47+
test("should create files and config on a fresh project", async () => {
48+
await cli.init()
49+
50+
expect(installSpy).toHaveBeenCalledTimes(1)
51+
52+
// Check files
53+
const testFileExists = await cli.fileExists("tests/svg.test.ts")
54+
expect(testFileExists).toBe(true)
55+
const preloadFileExists = await cli.fileExists("tests/fixtures/preload.ts")
56+
expect(preloadFileExists).toBe(true)
57+
const bunfigExists = await cli.fileExists("bunfig.toml")
58+
expect(bunfigExists).toBe(true)
59+
60+
// Check bunfig.toml content
61+
const bunfigContent = await fs.readFile("bunfig.toml", "utf-8")
62+
expect(bunfigContent).toContain(`[test]`)
63+
expect(bunfigContent).toContain(`preload = ["./tests/fixtures/preload.ts"]`)
64+
65+
// Check console logs
66+
const logs = consoleSpy.mock.calls.flat().join("\n")
67+
expect(logs).toContain("✅ Created example test in tests/svg.test.ts")
68+
expect(logs).toContain("✅ Created preload file in tests/fixtures/preload.ts")
69+
expect(logs).toContain("✅ Created bunfig.toml")
70+
})
71+
72+
test("should skip creating files that already exist", async () => {
73+
// Pre-create files
74+
await fs.mkdir("tests/fixtures", { recursive: true })
75+
await fs.writeFile("tests/svg.test.ts", "test")
76+
await fs.writeFile("tests/fixtures/preload.ts", "preload")
77+
await fs.writeFile(
78+
"bunfig.toml",
79+
`[test]\npreload = ["./tests/fixtures/preload.ts"]`,
80+
)
81+
82+
await cli.init()
83+
84+
const logs = consoleSpy.mock.calls.flat().join("\n")
85+
expect(logs).toContain("🔒 tests/svg.test.ts already exists, skipping.")
86+
expect(logs).toContain(
87+
"🔒 tests/fixtures/preload.ts already exists, skipping.",
88+
)
89+
expect(logs).toContain(
90+
"🔒 bunfig.toml already has preload configuration, skipping.",
91+
)
92+
})
93+
94+
test("should update bunfig.toml if [test] section exists", async () => {
95+
await fs.writeFile("bunfig.toml", "[test]")
96+
97+
await cli.init()
98+
99+
const bunfigContent = await fs.readFile("bunfig.toml", "utf-8")
100+
expect(bunfigContent).toBe(
101+
`[test]\npreload = ["./tests/fixtures/preload.ts"]`,
102+
)
103+
104+
const logs = consoleSpy.mock.calls.flat().join("\n")
105+
expect(logs).toContain("✅ Updated bunfig.toml with preload configuration.")
106+
})
107+
108+
test("should append to bunfig.toml if it exists but is unrelated", async () => {
109+
await fs.writeFile("bunfig.toml", "[some-other-section]")
110+
111+
await cli.init()
112+
113+
const bunfigContent = await fs.readFile("bunfig.toml", "utf-8")
114+
expect(bunfigContent).toContain("[some-other-section]")
115+
expect(bunfigContent).toContain(
116+
`\n\n[test]\npreload = ["./tests/fixtures/preload.ts"]`,
117+
)
118+
119+
const logs = consoleSpy.mock.calls.flat().join("\n")
120+
expect(logs).toContain("✅ Added preload configuration to bunfig.toml.")
121+
})
122+
})

0 commit comments

Comments
 (0)