From e639c66726b83606b96e2fab8893f2613543224e Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 21 May 2020 10:29:21 +0200 Subject: [PATCH 1/3] fix: deep copy standardRules config This fixes #303 invalid configuration for dot-notation --- src/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index a6254b5f..808234e9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,6 +19,10 @@ const equivalents = [ 'space-before-function-paren' ] as const +function clone (value: T): T { + return JSON.parse(JSON.stringify(value)) +} + function fromEntries (iterable: Array<[string, T]>): { [key: string]: T } { return [...iterable].reduce<{ [key: string]: T }>((obj, [key, val]) => { obj[key] = val @@ -44,7 +48,7 @@ export = { 'no-use-before-define': 'off', // @typescript-eslint versions of Standard.js rules: - ...fromEntries(equivalents.map((name) => [`@typescript-eslint/${name}`, standardRules[name]])), + ...fromEntries(equivalents.map((name) => [`@typescript-eslint/${name}`, clone(standardRules[name])])), '@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: false, From 4a5877795a1042c3d6b9b1d9757f572775e2a6a1 Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Thu, 21 May 2020 11:48:45 +0200 Subject: [PATCH 2/3] test: add test for referenceless config --- src/index.test.ts | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/index.test.ts b/src/index.test.ts index 77015166..2632297f 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,5 +1,6 @@ -import test from 'ava' +import test, { ExecutionContext } from 'ava' import exported from '.' +import { rules as standardRules } from 'eslint-config-standard/eslintrc.json' import standardPkg from 'eslint-config-standard/package.json' import readPkgUp, { NormalizedPackageJson } from 'read-pkg-up' @@ -192,3 +193,32 @@ test('Deps parser and plugin are same version', async (t) => { const pluginRange = ourPeerDeps['@typescript-eslint/eslint-plugin'] t.is(parserRange.split('^')[1], pluginRange.split('>=')[1]) }) + +interface RulesConfig { + [name: string]: object | string | number | boolean | null +} + +/** + * Test that objects' values do not hold same memory references + */ +function testNotHaveObjectReferences (t: ExecutionContext, rules: RulesConfig, comparisonRules: RulesConfig, skipSameKey: boolean = false): void { + for (const ruleName in rules) { + const ruleConfig = rules[ruleName] + if (typeof ruleConfig !== 'object') continue // Non-objects use copy-by-value + + for (const comparisonRuleName in comparisonRules) { + if (skipSameKey && ruleName === comparisonRuleName) continue + t.not(ruleConfig, comparisonRules[comparisonRuleName]) + } + } +} + +test('No references in rules config', (t) => { + for (const override of exported.overrides) { + const rules: RulesConfig = override.rules + // Rules must not have object references inside theirselves + testNotHaveObjectReferences(t, rules, rules, true) + // Rules must not have object references to standard rules + testNotHaveObjectReferences(t, rules, standardRules) + } +}) From 74b73a161da492da65ba49337e4d6427c997909a Mon Sep 17 00:00:00 2001 From: Patrick Remy Date: Sun, 24 May 2020 15:49:19 +0200 Subject: [PATCH 3/3] test: only check references of same key rules --- src/index.test.ts | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/index.test.ts b/src/index.test.ts index 2632297f..13659857 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,4 +1,4 @@ -import test, { ExecutionContext } from 'ava' +import test from 'ava' import exported from '.' import { rules as standardRules } from 'eslint-config-standard/eslintrc.json' import standardPkg from 'eslint-config-standard/package.json' @@ -198,27 +198,15 @@ interface RulesConfig { [name: string]: object | string | number | boolean | null } -/** - * Test that objects' values do not hold same memory references - */ -function testNotHaveObjectReferences (t: ExecutionContext, rules: RulesConfig, comparisonRules: RulesConfig, skipSameKey: boolean = false): void { - for (const ruleName in rules) { - const ruleConfig = rules[ruleName] - if (typeof ruleConfig !== 'object') continue // Non-objects use copy-by-value +test('No references to standard rules config', (t) => { + for (const override of exported.overrides) { + const standardRulesConfig: RulesConfig = standardRules + const overrideRulesConfig: RulesConfig = override.rules - for (const comparisonRuleName in comparisonRules) { - if (skipSameKey && ruleName === comparisonRuleName) continue - t.not(ruleConfig, comparisonRules[comparisonRuleName]) - } - } -} + for (const ruleName in standardRulesConfig) { + if (typeof standardRulesConfig[ruleName] !== 'object') continue // Non-objects use copy-by-value -test('No references in rules config', (t) => { - for (const override of exported.overrides) { - const rules: RulesConfig = override.rules - // Rules must not have object references inside theirselves - testNotHaveObjectReferences(t, rules, rules, true) - // Rules must not have object references to standard rules - testNotHaveObjectReferences(t, rules, standardRules) + t.not(overrideRulesConfig[`@typescript-eslint/${ruleName}`], standardRulesConfig[ruleName]) + } } })