yx_generate_api_js/test/cli.integration.test.js

245 lines
6.4 KiB
JavaScript

import assert from 'node:assert/strict'
import { execFile as execFileCallback } from 'node:child_process'
import fs from 'node:fs/promises'
import os from 'node:os'
import path from 'node:path'
import { promisify } from 'node:util'
import test from 'node:test'
const execFile = promisify(execFileCallback)
const createTempDir = async () => {
return fs.mkdtemp(path.join(os.tmpdir(), 'yx-generate-api-cli-'))
}
test('cli gen supports spaced flags and syncs the external index file', async () => {
const tempDir = await createTempDir()
try {
const swaggerPath = path.join(tempDir, 'swagger.json')
const configPath = path.join(tempDir, 'yx-generate-api.config.mjs')
const outputDir = path.join(tempDir, 'generated')
const externalIndexFile = path.join(tempDir, 'api-index.js')
const cliPath = path.resolve('bin/yx-generate-api.js')
await fs.writeFile(
swaggerPath,
JSON.stringify(
{
openapi: '3.0.0',
paths: {
'/api/v1/Alpha/GetThing': {
get: {
tags: ['Alpha'],
summary: 'Get alpha thing',
responses: {
200: { description: 'OK' },
},
},
},
},
},
null,
2,
),
'utf8',
)
await fs.writeFile(
configPath,
`export default {
swaggerUrl: './swagger.json',
swaggerTimeoutMs: 1000,
outputDir: './generated',
externalIndexFile: './api-index.js',
requestImport: '../request',
cleanOutput: true,
sync: {
enabled: true,
},
}
`,
'utf8',
)
await execFile(process.execPath, [cliPath, 'gen', '--config', configPath, '--timeout', '1000'], {
cwd: tempDir,
})
const generatedIndexContent = await fs.readFile(path.join(outputDir, 'index.js'), 'utf8')
const externalIndexContent = await fs.readFile(externalIndexFile, 'utf8')
assert.match(generatedIndexContent, /export \* as alphaApi from ["']\.\/alpha["']/)
assert.match(generatedIndexContent, /export \* from ["']\.\/alpha["']/)
assert.match(externalIndexContent, /AUTO-GENERATED API EXPORTS START/)
assert.match(externalIndexContent, /export \* from ["']\.\/generated["']/)
} finally {
await fs.rm(tempDir, { recursive: true, force: true })
}
})
test('cli gen reports duplicate export conflicts with module and url details in non-interactive mode', async () => {
const tempDir = await createTempDir()
try {
const swaggerPath = path.join(tempDir, 'swagger.json')
const configPath = path.join(tempDir, 'yx-generate-api.config.mjs')
const cliPath = path.resolve('bin/yx-generate-api.js')
await fs.writeFile(
swaggerPath,
JSON.stringify(
{
openapi: '3.0.0',
paths: {
'/api/v1/Alpha/GetList': {
get: {
tags: ['Alpha'],
responses: {
200: { description: 'OK' },
},
},
},
'/api/v1/Beta/GetList': {
get: {
tags: ['Beta'],
responses: {
200: { description: 'OK' },
},
},
},
},
},
null,
2,
),
'utf8',
)
await fs.writeFile(
configPath,
`export default {
swaggerUrl: './swagger.json',
swaggerTimeoutMs: 1000,
outputDir: './generated',
externalIndexFile: './api-index.js',
requestImport: '../request',
cleanOutput: true,
sync: {
enabled: true,
},
}
`,
'utf8',
)
await assert.rejects(
execFile(process.execPath, [cliPath, 'gen', '--config', configPath], {
cwd: tempDir,
}),
(error) => {
assert.match(error.stderr, /Duplicate API export names detected/)
assert.match(error.stderr, /module=Alpha, file=alpha, url=\/api\/v1\/Alpha\/GetList/)
assert.match(error.stderr, /module=Beta, file=beta, url=\/api\/v1\/Beta\/GetList/)
return true
},
)
} finally {
await fs.rm(tempDir, { recursive: true, force: true })
}
})
test('cli gen skips sync by default when generateIndexFile is false', async () => {
const tempDir = await createTempDir()
try {
const swaggerPath = path.join(tempDir, 'swagger.json')
const configPath = path.join(tempDir, 'yx-generate-api.config.mjs')
const outputDir = path.join(tempDir, 'generated')
const externalIndexFile = path.join(tempDir, 'api-index.js')
const cliPath = path.resolve('bin/yx-generate-api.js')
await fs.writeFile(
swaggerPath,
JSON.stringify(
{
openapi: '3.0.0',
paths: {
'/api/v1/Alpha/GetThing': {
get: {
tags: ['Alpha'],
responses: {
200: { description: 'OK' },
},
},
},
},
},
null,
2,
),
'utf8',
)
await fs.writeFile(
configPath,
`export default {
swaggerUrl: './swagger.json',
swaggerTimeoutMs: 1000,
outputDir: './generated',
generateIndexFile: false,
externalIndexFile: './api-index.js',
requestImport: '../request',
cleanOutput: true,
}
`,
'utf8',
)
await execFile(process.execPath, [cliPath, 'gen', '--config', configPath], {
cwd: tempDir,
})
await assert.doesNotReject(fs.access(path.join(outputDir, 'alpha.js')))
await assert.rejects(fs.access(path.join(outputDir, 'index.js')))
await assert.rejects(fs.access(externalIndexFile))
} finally {
await fs.rm(tempDir, { recursive: true, force: true })
}
})
test('cli sync fails clearly when sync.enabled=true but generateIndexFile is false', async () => {
const tempDir = await createTempDir()
try {
const configPath = path.join(tempDir, 'yx-generate-api.config.mjs')
const cliPath = path.resolve('bin/yx-generate-api.js')
await fs.writeFile(
configPath,
`export default {
outputDir: './generated',
generateIndexFile: false,
externalIndexFile: './api-index.js',
sync: {
enabled: true,
},
}
`,
'utf8',
)
await assert.rejects(
execFile(process.execPath, [cliPath, 'sync', '--config', configPath], {
cwd: tempDir,
}),
(error) => {
assert.match(error.stderr, /generateIndexFile=false/)
return true
},
)
} finally {
await fs.rm(tempDir, { recursive: true, force: true })
}
})