diff --git a/.gherkin-lintrc b/.gherkin-lintrc new file mode 100644 index 0000000..c84eba4 --- /dev/null +++ b/.gherkin-lintrc @@ -0,0 +1,38 @@ +{ + "docstring-indent": [ + "on", + { + "indent": 6 + } + ], + "file-name": [ + "on", + { + "style": "kebab-case" + } + ], + "indentation": [ + "on", + { + "Feature": 0, + "Background": 2, + "Scenario": 2, + "Examples": 4, + "Step": 4, + "given": 4, + "example": 6, + "and": 4 + } + ], + "no-dupe-feature-names": "on", + "no-dupe-scenario-names": "off", + "no-empty-file": "on", + "no-files-without-scenarios": "on", + "no-multiple-empty-lines": "off", + "no-partially-commented-tag-lines": "on", + "no-trailing-spaces": "off", + "no-unnamed-features": "on", + "no-unnamed-scenarios": "on", + "no-scenario-outlines-without-examples": "on", + "use-and": "on" +} diff --git a/custom-rules/docstring-indent.js b/custom-rules/docstring-indent.js new file mode 100644 index 0000000..6678f34 --- /dev/null +++ b/custom-rules/docstring-indent.js @@ -0,0 +1,55 @@ +const rule = 'docstring-indent' + +const availableConfigs = { + indent: { + type: 'number', + defaultValue: 6, + description: 'Number of spaces required for docstring indentation' + } +} + +function run (feature, file, config = {}) { + const errors = [] + const requiredSpaces = ' '.repeat(config.indent || 6) + + feature.children.forEach(child => { + if (child.scenario) { + child.scenario.steps.forEach(step => { + if (step.docString) { + const { location } = step.docString + const stepIndent = step.text.match(/^\s*/)[0] + const expectedIndent = stepIndent + requiredSpaces + + // Check opening docstring. + const openingLine = file.lines[location.line - 1] + if (!openingLine.startsWith(expectedIndent + '"""')) { + errors.push({ + message: `Docstring opening """ must be indented ${config.indent} spaces`, + rule, + line: location.line + }) + } + + // Check closing docstring. + const closingLineNum = location.line + step.docString.content.split('\n').length + 1 + const closingLine = file.lines[closingLineNum - 1] + if (!closingLine.startsWith(expectedIndent + '"""')) { + errors.push({ + message: `Docstring closing """ must match opening indent (${expectedIndent.length} spaces total)`, + rule, + line: closingLineNum + }) + } + } + }) + } + }) + + return errors +} + +module.exports = { + name: rule, + run, + availableConfigs +}