From 243cb4f970e40aa195a3bffa0528dbdbfef7c4f5 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 3 Apr 2021 09:05:48 +1300 Subject: [PATCH] fix(no-duplicate-hooks): support `describe.each` (#797) Fixes #642 --- .../__tests__/no-duplicate-hooks.test.ts | 167 ++++++++++++++++++ src/rules/no-duplicate-hooks.ts | 4 +- 2 files changed, 169 insertions(+), 2 deletions(-) diff --git a/src/rules/__tests__/no-duplicate-hooks.test.ts b/src/rules/__tests__/no-duplicate-hooks.test.ts index f3ee07bd1..8a14c00a3 100644 --- a/src/rules/__tests__/no-duplicate-hooks.test.ts +++ b/src/rules/__tests__/no-duplicate-hooks.test.ts @@ -288,3 +288,170 @@ ruleTester.run('nested describe blocks', rule, { }, ], }); + +ruleTester.run('describe.each blocks', rule, { + valid: [ + dedent` + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + `, + dedent` + describe('something', () => { + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + + describe.each(['world'])('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + }); + `, + dedent` + describe.each\`\`('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + `, + dedent` + describe('something', () => { + describe.each\`\`('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + + describe.each\`\`('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + }); + `, + ], + invalid: [ + { + code: dedent` + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is not fine', () => {}); + }); + `, + errors: [ + { + messageId: 'noDuplicateHook', + data: { hook: 'beforeEach' }, + column: 3, + line: 3, + }, + ], + }, + { + code: dedent` + describe('something', () => { + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + + describe.each(['world'])('%s', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is not fine', () => {}); + }); + }); + `, + errors: [ + { + messageId: 'noDuplicateHook', + data: { hook: 'beforeEach' }, + column: 5, + line: 10, + }, + ], + }, + { + code: dedent` + describe('something', () => { + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + + describe.each(['world'])('%s', () => { + describe('some more', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is not fine', () => {}); + }); + }); + }); + `, + errors: [ + { + messageId: 'noDuplicateHook', + data: { hook: 'beforeEach' }, + column: 7, + line: 11, + }, + ], + }, + { + code: dedent` + describe.each\`\`('%s', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is fine', () => {}); + }); + `, + errors: [ + { + messageId: 'noDuplicateHook', + data: { hook: 'beforeEach' }, + column: 3, + line: 3, + }, + ], + }, + { + code: dedent` + describe('something', () => { + describe.each\`\`('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + + describe.each\`\`('%s', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is not fine', () => {}); + }); + }); + `, + errors: [ + { + messageId: 'noDuplicateHook', + data: { hook: 'beforeEach' }, + column: 5, + line: 10, + }, + ], + }, + ], +}); diff --git a/src/rules/no-duplicate-hooks.ts b/src/rules/no-duplicate-hooks.ts index d06da84b6..3a699d010 100644 --- a/src/rules/no-duplicate-hooks.ts +++ b/src/rules/no-duplicate-hooks.ts @@ -1,4 +1,4 @@ -import { createRule, isDescribe, isHook } from './utils'; +import { createRule, isDescribe, isEachCall, isHook } from './utils'; const newHookContext = () => ({ beforeAll: 0, @@ -45,7 +45,7 @@ export default createRule({ } }, 'CallExpression:exit'(node) { - if (isDescribe(node)) { + if (isDescribe(node) && !isEachCall(node)) { hookContexts.pop(); } },