Skip to content

Commit ec99192

Browse files
committed
chore: wip
1 parent 59ea5fc commit ec99192

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

test/cli.test.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { describe, expect, it } from 'bun:test'
2+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3+
import { tmpdir } from 'node:os'
4+
import { join } from 'node:path'
5+
import pkg from '../package.json'
6+
7+
function runCli(args: string[]) {
8+
const proc = Bun.spawnSync({
9+
cmd: ['bun', 'bin/cli.ts', ...args],
10+
stdout: 'pipe',
11+
stderr: 'pipe',
12+
cwd: process.cwd(),
13+
env: { ...process.env },
14+
})
15+
const dec = new TextDecoder()
16+
return {
17+
code: proc.exitCode,
18+
stdout: dec.decode(proc.stdout).trim(),
19+
stderr: dec.decode(proc.stderr).trim(),
20+
}
21+
}
22+
23+
function makeTempModelsDir(): string {
24+
const dir = mkdtempSync(join(tmpdir(), 'qb-cli-'))
25+
const modelJs = `module.exports = {
26+
name: 'User',
27+
table: 'users',
28+
primaryKey: 'id',
29+
attributes: { id: { validation: { rule: {} } }, email: { validation: { rule: {} } } },
30+
}`
31+
writeFileSync(join(dir, 'user.js'), modelJs)
32+
return dir
33+
}
34+
35+
describe('CLI', () => {
36+
it('version prints package version', () => {
37+
const out = runCli(['version'])
38+
expect(out.stdout).toBe(pkg.version)
39+
expect(out.code).toBe(0)
40+
})
41+
42+
it('introspect prints JSON schema from models dir', () => {
43+
const dir = makeTempModelsDir()
44+
const out = runCli(['introspect', dir])
45+
expect(out.code).toBe(0)
46+
const json = JSON.parse(out.stdout)
47+
expect(Object.keys(json)).toContain('users')
48+
expect(json.users).toHaveProperty('primaryKey')
49+
expect(typeof json.users.columns).toBe('object')
50+
rmSync(dir, { recursive: true, force: true })
51+
})
52+
53+
it('sql prints a textual query (or placeholder) for a table', () => {
54+
const dir = makeTempModelsDir()
55+
const out = runCli(['sql', dir, 'users', '--limit', '3'])
56+
expect(typeof out.stdout).toBe('string')
57+
expect(out.stdout.length).toBeGreaterThan(0)
58+
expect(out.code).toBe(0)
59+
rmSync(dir, { recursive: true, force: true })
60+
})
61+
62+
it('file and unsafe commands run without throwing (no DB expected)', () => {
63+
const tmp = join(mkdtempSync(join(tmpdir(), 'qb-sql-')), 'q.sql')
64+
writeFileSync(tmp, 'SELECT 1')
65+
const f = runCli(['file', tmp])
66+
// may succeed or fail depending on env; just assert process did not crash
67+
expect([0, 1]).toContain(f.code)
68+
const u = runCli(['unsafe', 'SELECT 1'])
69+
expect([0, 1]).toContain(u.code)
70+
})
71+
72+
it('explain prints JSON or exits non-zero gracefully without a DB', () => {
73+
const out = runCli(['explain', 'SELECT 1'])
74+
if (out.code === 0) {
75+
const parsed = JSON.parse(out.stdout)
76+
expect(Array.isArray(parsed)).toBeTrue()
77+
}
78+
else {
79+
// still should not crash the test suite; stdout or stderr may contain info
80+
expect(typeof out.stdout).toBe('string')
81+
}
82+
})
83+
84+
it('ping prints an availability message', () => {
85+
const out = runCli(['ping'])
86+
expect(['OK', 'NOT READY']).toContain(out.stdout)
87+
})
88+
89+
it('help prints usage information', () => {
90+
const out = runCli(['--help'])
91+
expect(out.stdout.toLowerCase()).toContain('query-builder')
92+
})
93+
})

0 commit comments

Comments
 (0)