47 lines
1.7 KiB
JavaScript
47 lines
1.7 KiB
JavaScript
// Valide des fichiers .feature avec l'analyseur Gherkin officiel.
|
|
// Usage : node validate.mjs fichier.feature…
|
|
// Sort en erreur si un fichier n'est pas du Gherkin valide, n'est pas en
|
|
// français (# language: fr), ne contient aucun scénario, ou a une étape égarée
|
|
// dans une description (signe d'un mot-clé mal orthographié, que Gherkin
|
|
// accepte alors comme texte libre).
|
|
|
|
import { readFileSync } from 'node:fs'
|
|
import { AstBuilder, GherkinClassicTokenMatcher, Parser } from '@cucumber/gherkin'
|
|
import { IdGenerator } from '@cucumber/messages'
|
|
|
|
const STEP = /^\s*(Étant donné|Etant donné|Quand|Alors|Et|Mais)\b/
|
|
|
|
function strayStep(description) {
|
|
return description.split('\n').find((line) => STEP.test(line))
|
|
}
|
|
|
|
let errors = 0
|
|
|
|
for (const file of process.argv.slice(2)) {
|
|
const parser = new Parser(new AstBuilder(IdGenerator.uuid()), new GherkinClassicTokenMatcher())
|
|
try {
|
|
const { feature } = parser.parse(readFileSync(file, 'utf8'))
|
|
if (!feature) {
|
|
throw new Error('aucune fonctionnalité')
|
|
}
|
|
if (feature.language !== 'fr') {
|
|
throw new Error(`langue « ${feature.language} » au lieu de « fr »`)
|
|
}
|
|
const scenarios = feature.children.filter((child) => child.scenario).map((child) => child.scenario)
|
|
if (scenarios.length === 0) {
|
|
throw new Error('aucun scénario')
|
|
}
|
|
for (const description of [feature.description, ...scenarios.map((scenario) => scenario.description)]) {
|
|
const line = strayStep(description)
|
|
if (line) {
|
|
throw new Error(`étape hors d'un scénario (mot-clé mal orthographié ?) : ${line.trim()}`)
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.log(`${file} : ${error.message}`)
|
|
errors++
|
|
}
|
|
}
|
|
|
|
process.exit(errors === 0 ? 0 : 1)
|