diff --git a/src/rules/no-homogenous-tags.js b/src/rules/no-homogenous-tags.js index 0e4e82f5..5e047c62 100644 --- a/src/rules/no-homogenous-tags.js +++ b/src/rules/no-homogenous-tags.js @@ -1,10 +1,12 @@ const rule = 'no-homogenous-tags'; const { + applyOver, compose, intoArray, } = require('../utils/generic'); const {filter, map} = require('../utils/transducers'); -const {getScenarios} = require('../utils/selectors'); +const {getExamples, getScenarios} = require('../utils/selectors'); +const {flatMapScenarios} = require('../utils/gherkin'); const groupTagsByName = (tags) => { return tags.reduce((set, {name}) => set.add(name), new Set()); @@ -17,19 +19,19 @@ const collectScenarioTagInfo = (info, {tags}) => { }, info); }; -const createErrorByFeature = (feature) => ([name, tagsInfo]) => { +const createErrorByFeature = (feature, [parent, children]) => ([name, tagsInfo]) => { return { type: 'rule', - message: `${name} tag is declared in each scenario.` + - ' It could be defined at feature level.', + message: `${name} tag is declared in each ${children}.` + + ` It could be defined at ${parent} level.`, rule: rule, location: feature.location, }; }; -const noHomogenousTags = (feature) => { - const createError = createErrorByFeature(feature); - const scenarios = getScenarios(feature); +const noHomogenousTags = (getNodes, labels) => (feature) => { + const createError = createErrorByFeature(feature, labels); + const scenarios = getNodes(feature); const tagsInfo = scenarios.reduce(collectScenarioTagInfo, new Map()); const {length} = scenarios; return intoArray(compose( @@ -38,8 +40,13 @@ const noHomogenousTags = (feature) => { ))([...tagsInfo]); }; +const run = applyOver([ + noHomogenousTags(getScenarios, ['feature', 'scenario']), + flatMapScenarios(noHomogenousTags(getExamples, ['scenario', 'example'])), +]); + module.exports = { name: rule, - run: noHomogenousTags, + run, isValidConfig: () => [], }; diff --git a/test/rules/no-homogenous-tags/HomogenousExampleTags.feature b/test/rules/no-homogenous-tags/HomogenousExampleTags.feature new file mode 100644 index 00000000..6295781d --- /dev/null +++ b/test/rules/no-homogenous-tags/HomogenousExampleTags.feature @@ -0,0 +1,20 @@ +Feature: Feature with example homogenous tags + +Background: + Given I have a Background + +@tag1 +Scenario: This is a Scenario + Then this is a then step + +@tag3 +Scenario Outline: This is a Scenario Outline with the same tags + Then this is a then step +@tag2 +Examples: + | foo | + | bar | +@tag2 +Examples: + | foo | + | rab | diff --git a/test/rules/no-homogenous-tags/Violations.feature b/test/rules/no-homogenous-tags/HomogenousScenarioTags.feature similarity index 85% rename from test/rules/no-homogenous-tags/Violations.feature rename to test/rules/no-homogenous-tags/HomogenousScenarioTags.feature index c1e4d1e2..562076e3 100644 --- a/test/rules/no-homogenous-tags/Violations.feature +++ b/test/rules/no-homogenous-tags/HomogenousScenarioTags.feature @@ -1,4 +1,4 @@ -Feature: Feature with homogenous tags +Feature: Feature with scenario homogenous tags Background: Given I have a Background diff --git a/test/rules/no-homogenous-tags/no-homogenous-tags.js b/test/rules/no-homogenous-tags/no-homogenous-tags.js index e40e2dee..fa0cf4c1 100644 --- a/test/rules/no-homogenous-tags/no-homogenous-tags.js +++ b/test/rules/no-homogenous-tags/no-homogenous-tags.js @@ -1,8 +1,8 @@ const ruleName = 'no-homogenous-tags'; const ruleTestBase = require('../rule-test-base'); const rule = require('../../../src/rules/no-homogenous-tags.js'); -const runTest = ruleTestBase.createRuleTest(rule, ({tag}) => - `${tag} tag is declared in each scenario. It could be defined at feature level.`); +const runTest = ruleTestBase.createRuleTest(rule, ({tag, parent, children}) => + `${tag} tag is declared in each ${children}. It could be defined at ${parent} level.`); describe('No Homogenous Tags Rule', function() { it('doesn\'t raise errors when there are no violations', function() { @@ -10,20 +10,31 @@ describe('No Homogenous Tags Rule', function() { }); it('detects errors for scenarios, and scenario outlines', function() { - runTest('no-homogenous-tags/Violations.feature', {}, [{ + runTest('no-homogenous-tags/HomogenousScenarioTags.feature', {}, [{ location: { line: 1, column: 1, }, rule: ruleName, - messageElements: {tag: '@tag1'}, + messageElements: {tag: '@tag1', children: 'scenario', parent: 'feature'}, }, { location: { line: 1, column: 1, }, rule: ruleName, - messageElements: {tag: '@tag2'}, + messageElements: {tag: '@tag2', children: 'scenario', parent: 'feature'}, + }]); + }); + + it('detects errors for examples', function() { + runTest('no-homogenous-tags/HomogenousExampleTags.feature', {}, [{ + location: { + line: 11, + column: 1, + }, + rule: ruleName, + messageElements: {tag: '@tag2', children: 'example', parent: 'scenario'}, }]); }); });