From b32797c25dbdd970123c109a68bf3ddad9e30fc0 Mon Sep 17 00:00:00 2001 From: Carl Markham Date: Sun, 29 Sep 2024 19:29:15 +0100 Subject: [PATCH] add scenario-action and scenario-verification rules --- src/rules/README.md | 54 +++++++++++++++++++ src/rules/scenario-action.ts | 30 +++++++++++ src/rules/scenario-verification.ts | 34 ++++++++++++ .../features/scenario-action.feature | 30 +++++++++++ .../features/scenario-verification.feature | 29 ++++++++++ 5 files changed, 177 insertions(+) create mode 100644 src/rules/scenario-action.ts create mode 100644 src/rules/scenario-verification.ts create mode 100644 tests/acceptance/features/scenario-action.feature create mode 100644 tests/acceptance/features/scenario-verification.feature diff --git a/src/rules/README.md b/src/rules/README.md index 70dd047..6960dd0 100644 --- a/src/rules/README.md +++ b/src/rules/README.md @@ -39,6 +39,8 @@ option. | [Filename Kebab Case](#filename-kebab-case) | `filename-kebab-case` | ❌ | | [Unique Examples](#unique-examples) | `unique-examples` | ❌ | | [Feature Description](#feature-description) | `feature-description` | ❌ | +| [Scenario Action](#scenario-action) | `scenario-action` | ❌ | +| [Scenario Verification](#scenario-verification) | `scenario-verification` | ❌ | ### Allowed Tags @@ -736,3 +738,55 @@ export default { } } ``` + +### Scenario Action + +Scenarios should have a "When" to denote an action + +**Examples** + +Enable the rule + +```typescript +export default { + rules: { + 'scenario-action': 'on', + } +} +``` + +Enable the rule and set severity + +```typescript +export default { + rules: { + 'scenario-action': 'error', + } +} +``` + +### Scenario Verification + +Scenarios should have a "Then" to denote verification of an action + +**Examples** + +Enable the rule + +```typescript +export default { + rules: { + 'scenario-verification': 'on', + } +} +``` + +Enable the rule and set severity + +```typescript +export default { + rules: { + 'scenario-verification': 'error', + } +} +``` diff --git a/src/rules/scenario-action.ts b/src/rules/scenario-action.ts new file mode 100644 index 0000000..274be04 --- /dev/null +++ b/src/rules/scenario-action.ts @@ -0,0 +1,30 @@ +import { switchOrSeveritySchema } from '../schemas' +import Schema from '../schema' +import Rule from '../rule' +import { RawSchema, AcceptedSchema } from '../types' +import Document from '../document' + +export default class ScenarioAction implements Rule { + public readonly name: string = 'scenario-action' + + public readonly acceptedSchema: AcceptedSchema = switchOrSeveritySchema + + public readonly schema: Schema + + public constructor(rawSchema: RawSchema) { + this.schema = new Schema(rawSchema) + } + + public async run(document: Document): Promise { + document.feature.children.forEach((child) => { + if (!child.scenario) { + return + } + + const whens = child.scenario.steps.filter((s) => s.keyword.trim() === 'When') + if (whens.length === 0) { + document.addError(this.name, 'Scenario should contain a "When" to denote an action.', child.scenario.location) + } + }) + } +} diff --git a/src/rules/scenario-verification.ts b/src/rules/scenario-verification.ts new file mode 100644 index 0000000..d7291c4 --- /dev/null +++ b/src/rules/scenario-verification.ts @@ -0,0 +1,34 @@ +import { switchOrSeveritySchema } from '../schemas' +import Schema from '../schema' +import Rule from '../rule' +import { RawSchema, AcceptedSchema } from '../types' +import Document from '../document' + +export default class ScenarioVerification implements Rule { + public readonly name: string = 'scenario-verification' + + public readonly acceptedSchema: AcceptedSchema = switchOrSeveritySchema + + public readonly schema: Schema + + public constructor(rawSchema: RawSchema) { + this.schema = new Schema(rawSchema) + } + + public async run(document: Document): Promise { + document.feature.children.forEach((child) => { + if (!child.scenario) { + return + } + + const whens = child.scenario.steps.filter((s) => s.keyword.trim() === 'Then') + if (whens.length === 0) { + document.addError( + this.name, + 'Scenario should contain a "Then" to denote verification of an action.', + child.scenario.location, + ) + } + }) + } +} diff --git a/tests/acceptance/features/scenario-action.feature b/tests/acceptance/features/scenario-action.feature new file mode 100644 index 0000000..ca126d1 --- /dev/null +++ b/tests/acceptance/features/scenario-action.feature @@ -0,0 +1,30 @@ +Feature: Feature Description + + Scenario: Invalid + Given the following feature file + """ + Feature: Invalid + Scenario: Doing something + Given I do something + Then I should have done something + """ + When Gherklin is ran with the following configuration + | rules | + | {"scenario-action": "error"} | + Then there is 1 file with errors + And the errors are + | location | severity | rule | message | + | {"line": 2, "column": 3} | error | scenario-action | Scenario should contain a "When" to denote an action. | + + Scenario: Valid + Given the following feature file + """ + Feature: Valid + Scenario: Doing something + When I do something + Then I should have done something + """ + When Gherklin is ran with the following configuration + | rules | + | {"scenario-action": "error"} | + Then there are 0 files with errors diff --git a/tests/acceptance/features/scenario-verification.feature b/tests/acceptance/features/scenario-verification.feature new file mode 100644 index 0000000..41d3069 --- /dev/null +++ b/tests/acceptance/features/scenario-verification.feature @@ -0,0 +1,29 @@ +Feature: Feature Description + + Scenario: Invalid + Given the following feature file + """ + Feature: Invalid + Scenario: Doing something + When I do something + """ + When Gherklin is ran with the following configuration + | rules | + | {"scenario-verification": "error"} | + Then there is 1 file with errors + And the errors are + | location | severity | rule | message | + | {"line": 2, "column": 3} | error | scenario-verification | Scenario should contain a "Then" to denote verification of an action. | + + Scenario: Valid + Given the following feature file + """ + Feature: Valid + Scenario: Doing something + When I do something + Then I should have done something + """ + When Gherklin is ran with the following configuration + | rules | + | {"scenario-verification": "error"} | + Then there are 0 files with errors