mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo.git
synced 2026-09-21 16:52:01 -07:00
100 lines
2.9 KiB
JavaScript
100 lines
2.9 KiB
JavaScript
/*
|
|
Normal acceptance runner for psf-memo-client.
|
|
|
|
Orchestrates the acceptance pipeline:
|
|
feature file -> bb gherkin-parser -> JSON IR -> acceptance entrypoint
|
|
generator -> generated test entry points -> node test runner
|
|
|
|
It procures the latest Babashka APS tools from the Acceptance-Pipeline-
|
|
Specification repository on first use, then parses, generates, and runs every
|
|
Gherkin feature under specs/.
|
|
|
|
Exit code 0 when all acceptance tests pass; non-zero otherwise.
|
|
*/
|
|
|
|
'use strict'
|
|
|
|
const { execFileSync } = require('node:child_process')
|
|
const fs = require('node:fs')
|
|
const path = require('node:path')
|
|
|
|
const root = path.resolve(__dirname, '..')
|
|
const specsDir = path.join(root, 'specs')
|
|
const buildDir = path.join(root, 'build', 'acceptance')
|
|
const irDir = path.join(buildDir, 'ir')
|
|
const genDir = path.join(buildDir, 'generated')
|
|
const apsDir = path.join(root, 'tmp', 'aps-spec')
|
|
|
|
function sh (cmd, args, opts = {}) {
|
|
return execFileSync(cmd, args, {
|
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
...opts
|
|
}).toString()
|
|
}
|
|
|
|
// Procure the latest APS tools if not already present in the worktree.
|
|
function ensureAps () {
|
|
if (fs.existsSync(apsDir)) return
|
|
fs.mkdirSync(path.dirname(apsDir), { recursive: true })
|
|
sh('git', ['clone', '--depth', '1',
|
|
'https://github.com/unclebob/Acceptance-Pipeline-Specification.git', apsDir])
|
|
}
|
|
|
|
function main () {
|
|
ensureAps()
|
|
|
|
const features = fs
|
|
.readdirSync(specsDir)
|
|
.filter((f) => f.endsWith('.feature'))
|
|
.sort()
|
|
|
|
if (features.length === 0) {
|
|
console.log('No feature files found under specs/.')
|
|
return
|
|
}
|
|
|
|
fs.mkdirSync(irDir, { recursive: true })
|
|
fs.mkdirSync(genDir, { recursive: true })
|
|
|
|
for (const featureFile of features) {
|
|
const base = featureFile.replace(/\.feature$/i, '')
|
|
const featurePath = path.join(specsDir, featureFile)
|
|
const irPath = path.join(irDir, `${base}.json`)
|
|
|
|
// 1) Parse the feature to JSON IR using the Babashka APS gherkin-parser.
|
|
sh('bb', ['gherkin-parser', featurePath, irPath], { cwd: apsDir })
|
|
|
|
// 2) Generate executable acceptance entry points from the IR.
|
|
sh('node', [path.join(root, 'acceptance', 'lib', 'generate.js'), irPath, genDir])
|
|
}
|
|
|
|
// 3) Run every generated acceptance test.
|
|
const tests = fs
|
|
.readdirSync(genDir)
|
|
.filter((f) => f.endsWith('.acceptance.test.js'))
|
|
.sort()
|
|
|
|
let failures = 0
|
|
for (const testFile of tests) {
|
|
try {
|
|
const out = sh('node', [path.join(genDir, testFile)])
|
|
process.stdout.write(out)
|
|
console.log(`ACCEPTANCE PASS: ${testFile}`)
|
|
} catch (err) {
|
|
failures++
|
|
process.stdout.write(err.stdout || '')
|
|
process.stderr.write(err.stderr || '')
|
|
console.error(`ACCEPTANCE FAIL: ${testFile}`)
|
|
}
|
|
}
|
|
|
|
if (failures > 0) {
|
|
console.error(`ACCEPTANCE: ${failures} failing test file(s)`)
|
|
process.exit(1)
|
|
} else {
|
|
console.log(`ACCEPTANCE: all ${tests.length} generated test file(s) passed`)
|
|
}
|
|
}
|
|
|
|
main()
|