diff --git a/lib/rules/no-identical-tests.js b/lib/rules/no-identical-tests.js index f05e8540..fd1673e5 100644 --- a/lib/rules/no-identical-tests.js +++ b/lib/rules/no-identical-tests.js @@ -29,15 +29,53 @@ module.exports = { const message = 'This test case is identical to another case.'; const sourceCode = context.getSourceCode(); + // ---------------------------------------------------------------------- + // Helpers + // ---------------------------------------------------------------------- + /** + *compare two test cases despite of properties order. + *@returns {boolean} if eq, return true, else return false. + */ + function eq (testA, testB) { + if (testA.type !== testB.type) { + return false; + } + + if (testA.type !== 'ObjectExpression') { + return sourceCode.getText(testA) === sourceCode.getText(testB); + } + + const propertiesA = testA.properties || []; + const propertiesB = testB.properties || []; + + // if properties length not eq; return false; + if (propertiesA.length !== propertiesB.length) { + return false; + } + + const propertiesSetA = new Set(); + propertiesA.forEach(item => { + const code = sourceCode.getText(item); + propertiesSetA.add(code); + }); + + for (let i = 0; i < propertiesB.length; i++) { + const code = sourceCode.getText(propertiesB[i]); + if (!propertiesSetA.has(code)) { + return false; + } + } + return true; + } + return { Program (ast) { utils.getTestInfo(context, ast).forEach(testRun => { [testRun.valid, testRun.invalid].forEach(tests => { - const cache = Object.create(null); + const cache = []; // to avoid tests being null (tests || []).forEach(test => { - const testCode = sourceCode.getText(test); - if (cache[testCode]) { + if (cache.some(item => eq(item, test))) { context.report({ node: test, message, @@ -50,7 +88,7 @@ module.exports = { }, }); } else { - cache[testCode] = true; + cache.push(test); } }); }); diff --git a/tests/lib/rules/no-identical-tests.js b/tests/lib/rules/no-identical-tests.js index 55f8ddfd..343c5cfd 100644 --- a/tests/lib/rules/no-identical-tests.js +++ b/tests/lib/rules/no-identical-tests.js @@ -38,6 +38,14 @@ ruleTester.run('no-identical-tests', rule, { invalid: [] }); `, + ` + new RuleTester().run('foo', bar, { + valid: [ + 'foo', + ], + invalid: [] + }); + `, ], invalid: [ @@ -106,5 +114,45 @@ ruleTester.run('no-identical-tests', rule, { `, errors: [ERROR, ERROR], }, + { + code: ` + new RuleTester().run('foo', bar, { + valid: [ + { code: 'foo', options: ['bar'] }, + { options: ['bar'], code: 'foo' }, + ], + invalid: [] + }); + `, + output: ` + new RuleTester().run('foo', bar, { + valid: [ + { code: 'foo', options: ['bar'] }, + ], + invalid: [] + }); + `, + errors: [ERROR], + }, + { + code: ` + new RuleTester().run('foo', bar, { + valid: [ + 'foo', + 'foo', + ], + invalid: [] + }); + `, + output: ` + new RuleTester().run('foo', bar, { + valid: [ + 'foo', + ], + invalid: [] + }); + `, + errors: [ERROR], + }, ], });