From 7b8d2b09982acda72709ea162e6789d13420d1e4 Mon Sep 17 00:00:00 2001 From: Igor Kamyshev Date: Thu, 14 Aug 2025 14:57:23 +0700 Subject: [PATCH 1/2] Add test-case for store after destruction --- ...-store-naming-convention-prefix.ts.test.js | 54 +++++++++---------- .../incorrect-store-after-destruction.ts | 9 ++++ 2 files changed, 34 insertions(+), 29 deletions(-) create mode 100644 rules/enforce-store-naming-convention/prefix/examples/incorrect-store-after-destruction.ts diff --git a/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js b/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js index ababaf4..07ce61d 100644 --- a/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js +++ b/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js @@ -18,33 +18,29 @@ const readExampleForTheRule = (name) => ({ filename: join(__dirname, "examples", name), }); -ruleTester.run( - "enforce-store-naming-convention-prefix.ts.test", - rule, - { - valid: ["correct-store-naming.ts", "correct-issue-139.ts"].map( - readExampleForTheRule - ), +ruleTester.run("enforce-store-naming-convention-prefix.ts.test", rule, { + valid: ["correct-store-naming.ts", "correct-issue-139.ts"].map( + readExampleForTheRule + ), - invalid: [ - // Errors - ...["incorrect-store-naming.ts"] - .map(readExampleForTheRule) - .map((result) => ({ - ...result, - errors: [ - { - messageId: "invalidName", - type: "VariableDeclarator", - suggestions: [ - { - messageId: "renameStore", - output: result.code.replace("justStore", "$justStore"), - }, - ], - }, - ], - })), - ], - } -); + invalid: [ + // Errors + ...["incorrect-store-naming.ts", "incorrect-store-after-destruction.ts"] + .map(readExampleForTheRule) + .map((result) => ({ + ...result, + errors: [ + { + messageId: "invalidName", + type: "VariableDeclarator", + suggestions: [ + { + messageId: "renameStore", + output: result.code.replace("justStore", "$justStore"), + }, + ], + }, + ], + })), + ], +}); diff --git a/rules/enforce-store-naming-convention/prefix/examples/incorrect-store-after-destruction.ts b/rules/enforce-store-naming-convention/prefix/examples/incorrect-store-after-destruction.ts new file mode 100644 index 0000000..cb25648 --- /dev/null +++ b/rules/enforce-store-naming-convention/prefix/examples/incorrect-store-after-destruction.ts @@ -0,0 +1,9 @@ +import { createStore } from "effector"; + +function createCustomStore() { + return [createStore(null)]; +} + +const [justStore] = createCustomStore(); + +export { justStore }; From 6ccf8aec7860ef3ac98124054f93847e2acb653d Mon Sep 17 00:00:00 2001 From: Igor Kamyshev Date: Thu, 14 Aug 2025 15:12:41 +0700 Subject: [PATCH 2/2] Make test passes --- .../enforce-store-naming-convention.js | 39 ++++++++++++------- ...-store-naming-convention-prefix.ts.test.js | 19 ++++++++- utils/node-name.js | 5 +++ utils/node-range.js | 5 +++ utils/traverse-real-declaration.js | 9 +++++ 5 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 utils/node-name.js create mode 100644 utils/node-range.js create mode 100644 utils/traverse-real-declaration.js diff --git a/rules/enforce-store-naming-convention/enforce-store-naming-convention.js b/rules/enforce-store-naming-convention/enforce-store-naming-convention.js index 8139939..b2d18b8 100644 --- a/rules/enforce-store-naming-convention/enforce-store-naming-convention.js +++ b/rules/enforce-store-naming-convention/enforce-store-naming-convention.js @@ -14,6 +14,11 @@ const { const { createLinkToRule } = require("../../utils/create-link-to-rule"); const { nodeTypeIs } = require("../../utils/node-type-is"); const { traverseParentByType } = require("../../utils/traverse-parent-by-type"); +const { + traverseRealDeclaration, +} = require("../../utils/traverse-real-declaration"); +const { nodeName } = require("../../utils/node-name"); +const { nodeRange } = require("../../utils/node-range"); module.exports = { meta: { @@ -47,23 +52,27 @@ module.exports = { if (parserServices?.program) { return { VariableDeclarator(node) { - const isEffectorStore = nodeTypeIs.store({ - node, - context, - }); - - if (!isEffectorStore) { - return; - } - - const storeName = node.id.name; + const realNodes = traverseRealDeclaration(node); - if (namingOf.store.isInvalid({ name: storeName, context })) { - reportStoreNameConventionViolation({ + for (const realNode of realNodes) { + const isEffectorStore = nodeTypeIs.store({ + node: realNode, context, - node, - storeName, }); + + if (!isEffectorStore) { + continue; + } + + const storeName = nodeName(realNode); + + if (namingOf.store.isInvalid({ name: storeName, context })) { + reportStoreNameConventionViolation({ + context, + node: realNode, + storeName, + }); + } } }, }; @@ -197,7 +206,7 @@ function reportStoreNameConventionViolation({ context, node, storeName }) { messageId: "renameStore", data: { storeName, correctedStoreName }, fix(fixer) { - return fixer.replaceTextRange(node.id.range, correctedStoreName); + return fixer.replaceTextRange(nodeRange(node), correctedStoreName); }, }, ], diff --git a/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js b/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js index 07ce61d..ee17b22 100644 --- a/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js +++ b/rules/enforce-store-naming-convention/prefix/enforce-store-naming-convention-prefix.ts.test.js @@ -25,7 +25,7 @@ ruleTester.run("enforce-store-naming-convention-prefix.ts.test", rule, { invalid: [ // Errors - ...["incorrect-store-naming.ts", "incorrect-store-after-destruction.ts"] + ...["incorrect-store-naming.ts"] .map(readExampleForTheRule) .map((result) => ({ ...result, @@ -42,5 +42,22 @@ ruleTester.run("enforce-store-naming-convention-prefix.ts.test", rule, { }, ], })), + ...["incorrect-store-after-destruction.ts"] + .map(readExampleForTheRule) + .map((result) => ({ + ...result, + errors: [ + { + messageId: "invalidName", + type: "Identifier", + suggestions: [ + { + messageId: "renameStore", + output: result.code.replace("justStore", "$justStore"), + }, + ], + }, + ], + })), ], }); diff --git a/utils/node-name.js b/utils/node-name.js new file mode 100644 index 0000000..1ffefcb --- /dev/null +++ b/utils/node-name.js @@ -0,0 +1,5 @@ +function nodeName(node) { + return node.id?.name ?? node.name; +} + +module.exports = { nodeName }; diff --git a/utils/node-range.js b/utils/node-range.js new file mode 100644 index 0000000..0b4754e --- /dev/null +++ b/utils/node-range.js @@ -0,0 +1,5 @@ +function nodeRange(node) { + return node.id?.range ?? node.range; +} + +module.exports = { nodeRange }; diff --git a/utils/traverse-real-declaration.js b/utils/traverse-real-declaration.js new file mode 100644 index 0000000..7a7e4d1 --- /dev/null +++ b/utils/traverse-real-declaration.js @@ -0,0 +1,9 @@ +function traverseRealDeclaration(node) { + if (node?.id?.type === "ArrayPattern") { + return node.id.elements; + } + + return [node]; +} + +module.exports = { traverseRealDeclaration };