Scénarios en Gherkin standard validés par l'analyseur officiel ; ADR amendables
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
42ace839d2
commit
2ab30a4abe
@@ -0,0 +1,8 @@
|
||||
# Analyseur Gherkin officiel de Cucumber, pour valider docs/scenarios/ (ADR 0008).
|
||||
FROM node:22.11.0-alpine3.20
|
||||
|
||||
WORKDIR /opt/gherkin
|
||||
RUN npm install --no-audit --no-fund @cucumber/gherkin@29.0.0 @cucumber/messages@26.0.1
|
||||
COPY validate.mjs .
|
||||
|
||||
ENTRYPOINT ["node", "/opt/gherkin/validate.mjs"]
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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)
|
||||
Reference in New Issue
Block a user