-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathcli.spec.ts
113 lines (99 loc) · 3.03 KB
/
cli.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import * as childProcess from 'child_process'
import * as path from 'path'
import * as fs from 'fs'
import * as os from 'os'
const projectRoot = path.join(__dirname, '..')
const testDir = path.join(__dirname, 'cli')
const testNodeModules = path.join(testDir, 'node_modules')
const setupSqlPath = path.join(testDir, 'setup.sql')
const teardownSqlPath = path.join(testDir, 'teardown.sql')
const sqlsDir = path.join(testDir, 'sqls')
const invalidSqlsDir = path.join(testDir, 'invalid-sqls')
const checkTemplate = path.join(testDir, 'check.ts.template')
const checkTs = path.join(testDir, 'check.ts')
const typePlaceholder = '__CONNECTION_TYPE__'
const cliPath = path.join(__dirname, '../dist/src/cli.js')
// postgres.js defaults
const user = process.env.PGUSER || os.userInfo().username
const db = process.env.PGDATABASE || 'postgres'
function recursiveDeleteTsFiles(dir: string) {
fs.readdirSync(dir, { withFileTypes: true }).forEach((dirent) => {
const { name } = dirent
if (dirent.isDirectory()) {
recursiveDeleteTsFiles(path.join(dir, name))
} else if (path.extname(dirent.name) === '.ts') {
fs.unlinkSync(path.join(dir, name))
}
})
}
function removeGeneratedFiles() {
// eslint-disable-next-line no-extra-semi
;[sqlsDir, invalidSqlsDir].forEach(recursiveDeleteTsFiles)
if (fs.existsSync(checkTs)) fs.unlinkSync(checkTs)
}
function runSqlScript(path: string) {
childProcess.execSync(`psql -f ${path}`, {
env: { ...process.env, PGUSER: user, PGDATABASE: db },
})
}
function runCli(paths: string, options = '') {
childProcess.execSync(`node ${cliPath} ${options} ${paths}`, {
cwd: testDir,
stdio: 'pipe',
timeout: 5000,
})
}
function generateCheckTs(connectionType: string) {
const template = fs.readFileSync(checkTemplate, 'utf-8')
fs.writeFileSync(checkTs, template.replace(typePlaceholder, connectionType))
}
function build(cwd = testDir) {
try {
childProcess.execSync('yarn build', {
cwd,
stdio: 'pipe',
encoding: 'utf-8',
})
} catch (err) {
console.log(err)
throw err
}
}
describe('cli', () => {
beforeAll(() => {
if (!fs.existsSync(cliPath)) {
build(projectRoot)
}
if (!fs.existsSync(testNodeModules)) {
childProcess.execSync('yarn', { cwd: testDir })
}
runSqlScript(setupSqlPath)
})
afterAll(() => {
runSqlScript(teardownSqlPath)
})
afterEach(() => {
removeGeneratedFiles()
})
it('generates valid node-postgres code', () => {
runCli(sqlsDir, '--target pg')
generateCheckTs('Pool')
build()
})
it('generates valid postgres.js code', () => {
runCli(sqlsDir, '--target postgres')
generateCheckTs('Sql<{}>')
build()
})
it('exit status 1 on failure', () => {
type ErrorType = (Error & childProcess.SpawnSyncReturns<Buffer>) | undefined
let error: ErrorType = undefined
try {
runCli(invalidSqlsDir)
} catch (err) {
error = err as ErrorType
}
expect(error?.status).toEqual(1)
expect(error?.message).toContain('ERROR: syntax error at or near "foo"')
})
})