Skip to content

Commit e761c46

Browse files
committed
test: add integration tests for CLI flags (--help, --dry-run, --verbose)
Signed-off-by: leocavalcante <[email protected]>
1 parent bc44179 commit e761c46

File tree

1 file changed

+291
-0
lines changed

1 file changed

+291
-0
lines changed

tests/install.test.ts

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,297 @@ The agent handles various tasks and operations in the system.
17381738
})
17391739
})
17401740

1741+
describe("CLI flags: --help", () => {
1742+
it("postinstall --help shows usage and exits 0", async () => {
1743+
const proc = Bun.spawn(["node", "postinstall.mjs", "--help"], {
1744+
cwd: process.cwd(),
1745+
stdout: "pipe",
1746+
stderr: "pipe",
1747+
})
1748+
1749+
const exitCode = await proc.exited
1750+
const stdout = await new Response(proc.stdout).text()
1751+
const stderr = await new Response(proc.stderr).text()
1752+
1753+
expect(exitCode).toBe(0)
1754+
expect(stdout).toContain("Usage:")
1755+
expect(stdout).toContain("--dry-run")
1756+
expect(stdout).toContain("--verbose")
1757+
expect(stdout).toContain("--help")
1758+
expect(stdout).toContain("Examples:")
1759+
expect(stderr).toBe("")
1760+
})
1761+
1762+
it("preuninstall --help shows usage and exits 0", async () => {
1763+
const proc = Bun.spawn(["node", "preuninstall.mjs", "--help"], {
1764+
cwd: process.cwd(),
1765+
stdout: "pipe",
1766+
stderr: "pipe",
1767+
})
1768+
1769+
const exitCode = await proc.exited
1770+
const stdout = await new Response(proc.stdout).text()
1771+
const stderr = await new Response(proc.stderr).text()
1772+
1773+
expect(exitCode).toBe(0)
1774+
expect(stdout).toContain("Usage:")
1775+
expect(stdout).toContain("--dry-run")
1776+
expect(stdout).toContain("--verbose")
1777+
expect(stdout).toContain("--help")
1778+
expect(stdout).toContain("Examples:")
1779+
expect(stderr).toBe("")
1780+
})
1781+
1782+
it("postinstall --help does not perform installation", async () => {
1783+
// Track state before --help
1784+
const { AGENTS_TARGET_DIR } = await import("../src/paths.mjs")
1785+
const agentFiles = ["opencoder.md", "opencoder-planner.md", "opencoder-builder.md"]
1786+
1787+
// Ensure agents are NOT installed
1788+
for (const file of agentFiles) {
1789+
const targetPath = join(AGENTS_TARGET_DIR, file)
1790+
if (existsSync(targetPath)) {
1791+
rmSync(targetPath)
1792+
}
1793+
}
1794+
1795+
const proc = Bun.spawn(["node", "postinstall.mjs", "--help"], {
1796+
cwd: process.cwd(),
1797+
stdout: "pipe",
1798+
stderr: "pipe",
1799+
})
1800+
1801+
await proc.exited
1802+
1803+
// Verify no files were created
1804+
for (const file of agentFiles) {
1805+
const targetPath = join(AGENTS_TARGET_DIR, file)
1806+
expect(existsSync(targetPath)).toBe(false)
1807+
}
1808+
})
1809+
})
1810+
1811+
describe("CLI flags: --dry-run", () => {
1812+
it("postinstall --dry-run does not create files", async () => {
1813+
const { AGENTS_TARGET_DIR } = await import("../src/paths.mjs")
1814+
const agentFiles = ["opencoder.md", "opencoder-planner.md", "opencoder-builder.md"]
1815+
1816+
// Ensure agents are NOT installed
1817+
for (const file of agentFiles) {
1818+
const targetPath = join(AGENTS_TARGET_DIR, file)
1819+
if (existsSync(targetPath)) {
1820+
rmSync(targetPath)
1821+
}
1822+
}
1823+
1824+
const proc = Bun.spawn(["node", "postinstall.mjs", "--dry-run"], {
1825+
cwd: process.cwd(),
1826+
stdout: "pipe",
1827+
stderr: "pipe",
1828+
})
1829+
1830+
const exitCode = await proc.exited
1831+
const stdout = await new Response(proc.stdout).text()
1832+
1833+
expect(exitCode).toBe(0)
1834+
expect(stdout).toContain("[DRY-RUN]")
1835+
expect(stdout).toContain("Would install:")
1836+
1837+
// Verify no files were actually created
1838+
for (const file of agentFiles) {
1839+
const targetPath = join(AGENTS_TARGET_DIR, file)
1840+
expect(existsSync(targetPath)).toBe(false)
1841+
}
1842+
})
1843+
1844+
it("preuninstall --dry-run does not delete files", async () => {
1845+
const { AGENTS_TARGET_DIR } = await import("../src/paths.mjs")
1846+
const agentFiles = ["opencoder.md", "opencoder-planner.md", "opencoder-builder.md"]
1847+
1848+
// Ensure target directory exists
1849+
mkdirSync(AGENTS_TARGET_DIR, { recursive: true })
1850+
1851+
// Install agents first
1852+
for (const file of agentFiles) {
1853+
const sourcePath = join(process.cwd(), "agents", file)
1854+
const targetPath = join(AGENTS_TARGET_DIR, file)
1855+
if (existsSync(sourcePath)) {
1856+
const content = readFileSync(sourcePath, "utf-8")
1857+
writeFileSync(targetPath, content)
1858+
}
1859+
}
1860+
1861+
const proc = Bun.spawn(["node", "preuninstall.mjs", "--dry-run"], {
1862+
cwd: process.cwd(),
1863+
stdout: "pipe",
1864+
stderr: "pipe",
1865+
})
1866+
1867+
const exitCode = await proc.exited
1868+
const stdout = await new Response(proc.stdout).text()
1869+
1870+
expect(exitCode).toBe(0)
1871+
expect(stdout).toContain("[DRY-RUN]")
1872+
expect(stdout).toContain("Would remove:")
1873+
1874+
// Verify files were NOT deleted
1875+
for (const file of agentFiles) {
1876+
const targetPath = join(AGENTS_TARGET_DIR, file)
1877+
expect(existsSync(targetPath)).toBe(true)
1878+
}
1879+
1880+
// Clean up
1881+
for (const file of agentFiles) {
1882+
const targetPath = join(AGENTS_TARGET_DIR, file)
1883+
if (existsSync(targetPath)) {
1884+
rmSync(targetPath)
1885+
}
1886+
}
1887+
})
1888+
1889+
it("postinstall --dry-run does not create target directory", async () => {
1890+
const { AGENTS_TARGET_DIR } = await import("../src/paths.mjs")
1891+
1892+
// Remove the target directory if it exists
1893+
if (existsSync(AGENTS_TARGET_DIR)) {
1894+
// Only remove if empty or contains only our agents
1895+
const files = readdirSync(AGENTS_TARGET_DIR)
1896+
const agentFiles = ["opencoder.md", "opencoder-planner.md", "opencoder-builder.md"]
1897+
const onlyOurAgents = files.every((f) => agentFiles.includes(f))
1898+
1899+
if (onlyOurAgents) {
1900+
rmSync(AGENTS_TARGET_DIR, { recursive: true })
1901+
}
1902+
}
1903+
1904+
// Only run test if we successfully removed the directory
1905+
if (!existsSync(AGENTS_TARGET_DIR)) {
1906+
const proc = Bun.spawn(["node", "postinstall.mjs", "--dry-run"], {
1907+
cwd: process.cwd(),
1908+
stdout: "pipe",
1909+
stderr: "pipe",
1910+
})
1911+
1912+
const exitCode = await proc.exited
1913+
const stdout = await new Response(proc.stdout).text()
1914+
1915+
expect(exitCode).toBe(0)
1916+
expect(stdout).toContain("Would create")
1917+
1918+
// Verify directory was NOT created
1919+
expect(existsSync(AGENTS_TARGET_DIR)).toBe(false)
1920+
}
1921+
})
1922+
})
1923+
1924+
describe("CLI flags: --verbose", () => {
1925+
it("postinstall --verbose shows detailed output", async () => {
1926+
const proc = Bun.spawn(["node", "postinstall.mjs", "--dry-run", "--verbose"], {
1927+
cwd: process.cwd(),
1928+
stdout: "pipe",
1929+
stderr: "pipe",
1930+
})
1931+
1932+
const exitCode = await proc.exited
1933+
const stdout = await new Response(proc.stdout).text()
1934+
1935+
expect(exitCode).toBe(0)
1936+
expect(stdout).toContain("[VERBOSE]")
1937+
expect(stdout).toContain("Package root:")
1938+
expect(stdout).toContain("Source directory:")
1939+
expect(stdout).toContain("Target directory:")
1940+
expect(stdout).toContain("Dry run:")
1941+
})
1942+
1943+
it("preuninstall --verbose shows detailed output", async () => {
1944+
const { AGENTS_TARGET_DIR } = await import("../src/paths.mjs")
1945+
const agentFiles = ["opencoder.md", "opencoder-planner.md", "opencoder-builder.md"]
1946+
1947+
// Ensure target directory exists with agents
1948+
mkdirSync(AGENTS_TARGET_DIR, { recursive: true })
1949+
for (const file of agentFiles) {
1950+
const sourcePath = join(process.cwd(), "agents", file)
1951+
const targetPath = join(AGENTS_TARGET_DIR, file)
1952+
if (existsSync(sourcePath)) {
1953+
const content = readFileSync(sourcePath, "utf-8")
1954+
writeFileSync(targetPath, content)
1955+
}
1956+
}
1957+
1958+
const proc = Bun.spawn(["node", "preuninstall.mjs", "--dry-run", "--verbose"], {
1959+
cwd: process.cwd(),
1960+
stdout: "pipe",
1961+
stderr: "pipe",
1962+
})
1963+
1964+
const exitCode = await proc.exited
1965+
const stdout = await new Response(proc.stdout).text()
1966+
1967+
expect(exitCode).toBe(0)
1968+
expect(stdout).toContain("[VERBOSE]")
1969+
expect(stdout).toContain("Package root:")
1970+
expect(stdout).toContain("Source directory:")
1971+
expect(stdout).toContain("Target directory:")
1972+
expect(stdout).toContain("Dry run:")
1973+
1974+
// Clean up
1975+
for (const file of agentFiles) {
1976+
const targetPath = join(AGENTS_TARGET_DIR, file)
1977+
if (existsSync(targetPath)) {
1978+
rmSync(targetPath)
1979+
}
1980+
}
1981+
})
1982+
1983+
it("postinstall --verbose shows file processing details", async () => {
1984+
const proc = Bun.spawn(["node", "postinstall.mjs", "--dry-run", "--verbose"], {
1985+
cwd: process.cwd(),
1986+
stdout: "pipe",
1987+
stderr: "pipe",
1988+
})
1989+
1990+
const exitCode = await proc.exited
1991+
const stdout = await new Response(proc.stdout).text()
1992+
1993+
expect(exitCode).toBe(0)
1994+
expect(stdout).toContain("Processing:")
1995+
expect(stdout).toContain("Source path:")
1996+
expect(stdout).toContain("Target path:")
1997+
expect(stdout).toContain("Validation passed")
1998+
})
1999+
2000+
it("postinstall without --verbose does not show verbose markers", async () => {
2001+
const proc = Bun.spawn(["node", "postinstall.mjs", "--dry-run"], {
2002+
cwd: process.cwd(),
2003+
stdout: "pipe",
2004+
stderr: "pipe",
2005+
})
2006+
2007+
const exitCode = await proc.exited
2008+
const stdout = await new Response(proc.stdout).text()
2009+
2010+
expect(exitCode).toBe(0)
2011+
expect(stdout).not.toContain("[VERBOSE]")
2012+
expect(stdout).not.toContain("Processing:")
2013+
expect(stdout).not.toContain("Validation passed")
2014+
})
2015+
2016+
it("preuninstall without --verbose does not show verbose markers", async () => {
2017+
const proc = Bun.spawn(["node", "preuninstall.mjs", "--dry-run"], {
2018+
cwd: process.cwd(),
2019+
stdout: "pipe",
2020+
stderr: "pipe",
2021+
})
2022+
2023+
const exitCode = await proc.exited
2024+
const stdout = await new Response(proc.stdout).text()
2025+
2026+
expect(exitCode).toBe(0)
2027+
expect(stdout).not.toContain("[VERBOSE]")
2028+
expect(stdout).not.toContain("Processing:")
2029+
})
2030+
})
2031+
17412032
describe("full install/uninstall cycle", () => {
17422033
it("should install and then cleanly uninstall", async () => {
17432034
// Create scripts

0 commit comments

Comments
 (0)