diff --git a/.changeset/serious-mayflies-yell.md b/.changeset/serious-mayflies-yell.md new file mode 100644 index 000000000..a03e61934 --- /dev/null +++ b/.changeset/serious-mayflies-yell.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +feat: Add `svelte/valid-context-access` rule diff --git a/README.md b/README.md index a5661af1c..17599fee5 100644 --- a/README.md +++ b/README.md @@ -320,6 +320,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/require-store-callbacks-use-set-param](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-store-callbacks-use-set-param/) | store callbacks must use `set` param | | | [svelte/require-store-reactive-access](https://sveltejs.github.io/eslint-plugin-svelte/rules/require-store-reactive-access/) | disallow to use of the store itself as an operand. Need to use $ prefix or get function. | :wrench: | | [svelte/valid-compile](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | :star: | +| [svelte/valid-context-access](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-context-access/) | context functions must be called during component initialization. | | | [svelte/valid-prop-names-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/) | disallow props other than data or errors in SvelteKit page components. | | ## Security Vulnerability diff --git a/docs/rules.md b/docs/rules.md index ef85cb467..968875980 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -33,6 +33,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/require-store-callbacks-use-set-param](./rules/require-store-callbacks-use-set-param.md) | store callbacks must use `set` param | | | [svelte/require-store-reactive-access](./rules/require-store-reactive-access.md) | disallow to use of the store itself as an operand. Need to use $ prefix or get function. | :wrench: | | [svelte/valid-compile](./rules/valid-compile.md) | disallow warnings when compiling. | :star: | +| [svelte/valid-context-access](./rules/valid-context-access.md) | context functions must be called during component initialization. | | | [svelte/valid-prop-names-in-kit-pages](./rules/valid-prop-names-in-kit-pages.md) | disallow props other than data or errors in SvelteKit page components. | | ## Security Vulnerability diff --git a/docs/rules/valid-context-access.md b/docs/rules/valid-context-access.md new file mode 100644 index 000000000..365b4b23e --- /dev/null +++ b/docs/rules/valid-context-access.md @@ -0,0 +1,79 @@ +--- +pageClass: "rule-details" +sidebarDepth: 0 +title: "svelte/valid-context-access" +description: "context functions must be called during component initialization." +--- + +# svelte/valid-context-access + +> context functions must be called during component initialization. + +- :exclamation: **_This rule has not been released yet._** + +## :book: Rule Details + +This rule reports where context API is called except during component initialization. + + + + + +```svelte + +``` + + + +- :warning: This rule only inspects Svelte files, not JS / TS files. + +## :wrench: Options + +Nothing. + +## :books: Further Reading + +- [Svelte - Docs > RUN TIME > svelte > setContext](https://svelte.dev/docs#run-time-svelte-setcontext) +- [Svelte - Docs > RUN TIME > svelte > getContext](https://svelte.dev/docs#run-time-svelte-getContext) +- [Svelte - Docs > RUN TIME > svelte > hasContext](https://svelte.dev/docs#run-time-svelte-hasContext) +- [Svelte - Docs > RUN TIME > svelte > getAllContexts](https://svelte.dev/docs#run-time-svelte-getAllContexts) + +## :mag: Implementation + +- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/src/rules/valid-context-access.ts) +- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/tests/src/rules/valid-context-access.ts) diff --git a/src/rules/infinite-reactive-loop.ts b/src/rules/infinite-reactive-loop.ts index 13ea8741a..fe0075e16 100644 --- a/src/rules/infinite-reactive-loop.ts +++ b/src/rules/infinite-reactive-loop.ts @@ -1,57 +1,11 @@ import type { TSESTree } from "@typescript-eslint/types" import type { AST } from "svelte-eslint-parser" -import { ReferenceTracker } from "@eslint-community/eslint-utils" import { createRule } from "../utils" import type { RuleContext } from "../types" import { findVariable } from "../utils/ast-utils" import { traverseNodes } from "svelte-eslint-parser" - -/** - * Get usage of `tick` - */ -function extractTickReferences( - context: RuleContext, -): { node: TSESTree.CallExpression; name: string }[] { - const referenceTracker = new ReferenceTracker( - context.getSourceCode().scopeManager.globalScope!, - ) - const a = referenceTracker.iterateEsmReferences({ - svelte: { - [ReferenceTracker.ESM]: true, - tick: { - [ReferenceTracker.CALL]: true, - }, - }, - }) - return Array.from(a).map(({ node, path }) => { - return { - node: node as TSESTree.CallExpression, - name: path[path.length - 1], - } - }) -} - -/** - * Get usage of `setTimeout`, `setInterval`, `queueMicrotask` - */ -function extractTaskReferences( - context: RuleContext, -): { node: TSESTree.CallExpression; name: string }[] { - const referenceTracker = new ReferenceTracker( - context.getSourceCode().scopeManager.globalScope!, - ) - const a = referenceTracker.iterateGlobalReferences({ - setTimeout: { [ReferenceTracker.CALL]: true }, - setInterval: { [ReferenceTracker.CALL]: true }, - queueMicrotask: { [ReferenceTracker.CALL]: true }, - }) - return Array.from(a).map(({ node, path }) => { - return { - node: node as TSESTree.CallExpression, - name: path[path.length - 1], - } - }) -} +import { extractSvelteLifeCycleReferences } from "./reference-helpers/svelte-lifecycle" +import { extractTaskReferences } from "./reference-helpers/microtask" /** * If `node` is inside of `maybeAncestorNode`, return true. @@ -400,12 +354,14 @@ export default createRule("infinite-reactive-loop", { type: "suggestion", }, create(context) { + const tickCallExpressions = Array.from( + extractSvelteLifeCycleReferences(context, ["tick"]), + ) + const taskReferences = Array.from(extractTaskReferences(context)) + const reactiveVariableReferences = getReactiveVariableReferences(context) + return { ["SvelteReactiveStatement"]: (ast: AST.SvelteReactiveStatement) => { - const tickCallExpressions = extractTickReferences(context) - const taskReferences = extractTaskReferences(context) - const reactiveVariableReferences = - getReactiveVariableReferences(context) const trackedVariableNodes = getTrackedVariableNodes( reactiveVariableReferences, ast, diff --git a/src/rules/reference-helpers/microtask.ts b/src/rules/reference-helpers/microtask.ts new file mode 100644 index 000000000..073b968a2 --- /dev/null +++ b/src/rules/reference-helpers/microtask.ts @@ -0,0 +1,37 @@ +import type { TSESTree } from "@typescript-eslint/types" +import { ReferenceTracker } from "@eslint-community/eslint-utils" +import type { RuleContext } from "../../types" + +type FunctionName = "setTimeout" | "setInterval" | "queueMicrotask" + +/** + * Get usage of `setTimeout`, `setInterval`, `queueMicrotask` + */ +export function* extractTaskReferences( + context: RuleContext, + functionNames: FunctionName[] = [ + "setTimeout", + "setInterval", + "queueMicrotask", + ], +): Generator<{ node: TSESTree.CallExpression; name: string }, void> { + const referenceTracker = new ReferenceTracker( + context.getSourceCode().scopeManager.globalScope!, + ) + for (const { node, path } of referenceTracker.iterateGlobalReferences({ + setTimeout: { + [ReferenceTracker.CALL]: functionNames.includes("setTimeout"), + }, + setInterval: { + [ReferenceTracker.CALL]: functionNames.includes("setInterval"), + }, + queueMicrotask: { + [ReferenceTracker.CALL]: functionNames.includes("queueMicrotask"), + }, + })) { + yield { + node: node as TSESTree.CallExpression, + name: path[path.length - 1], + } + } +} diff --git a/src/rules/reference-helpers/svelte-context.ts b/src/rules/reference-helpers/svelte-context.ts new file mode 100644 index 000000000..ebeb8f57a --- /dev/null +++ b/src/rules/reference-helpers/svelte-context.ts @@ -0,0 +1,42 @@ +import type { TSESTree } from "@typescript-eslint/types" +import { ReferenceTracker } from "@eslint-community/eslint-utils" +import type { RuleContext } from "../../types" + +type ContextName = "setContext" | "getContext" | "hasContext" | "getAllContexts" + +/** Extract svelte's context API references */ +export function* extractContextReferences( + context: RuleContext, + contextNames: ContextName[] = [ + "setContext", + "getContext", + "hasContext", + "getAllContexts", + ], +): Generator<{ node: TSESTree.CallExpression; name: string }, void> { + const referenceTracker = new ReferenceTracker( + context.getSourceCode().scopeManager.globalScope!, + ) + for (const { node, path } of referenceTracker.iterateEsmReferences({ + svelte: { + [ReferenceTracker.ESM]: true, + setContext: { + [ReferenceTracker.CALL]: contextNames.includes("setContext"), + }, + getContext: { + [ReferenceTracker.CALL]: contextNames.includes("getContext"), + }, + hasContext: { + [ReferenceTracker.CALL]: contextNames.includes("hasContext"), + }, + getAllContexts: { + [ReferenceTracker.CALL]: contextNames.includes("getAllContexts"), + }, + }, + })) { + yield { + node: node as TSESTree.CallExpression, + name: path[path.length - 1], + } + } +} diff --git a/src/rules/reference-helpers/svelte-lifecycle.ts b/src/rules/reference-helpers/svelte-lifecycle.ts new file mode 100644 index 000000000..2b05069b7 --- /dev/null +++ b/src/rules/reference-helpers/svelte-lifecycle.ts @@ -0,0 +1,53 @@ +import type { TSESTree } from "@typescript-eslint/types" +import { ReferenceTracker } from "@eslint-community/eslint-utils" +import type { RuleContext } from "../../types" + +type LifeCycleName = + | "onMount" + | "beforeUpdate" + | "afterUpdate" + | "onDestroy" + | "tick" + +/** + * Get usage of Svelte life cycle functions. + */ +export function* extractSvelteLifeCycleReferences( + context: RuleContext, + fuctionName: LifeCycleName[] = [ + "onMount", + "beforeUpdate", + "afterUpdate", + "onDestroy", + "tick", + ], +): Generator<{ node: TSESTree.CallExpression; name: string }, void> { + const referenceTracker = new ReferenceTracker( + context.getSourceCode().scopeManager.globalScope!, + ) + for (const { node, path } of referenceTracker.iterateEsmReferences({ + svelte: { + [ReferenceTracker.ESM]: true, + onMount: { + [ReferenceTracker.CALL]: fuctionName.includes("onMount"), + }, + beforeUpdate: { + [ReferenceTracker.CALL]: fuctionName.includes("beforeUpdate"), + }, + afterUpdate: { + [ReferenceTracker.CALL]: fuctionName.includes("afterUpdate"), + }, + onDestroy: { + [ReferenceTracker.CALL]: fuctionName.includes("onDestroy"), + }, + tick: { + [ReferenceTracker.CALL]: fuctionName.includes("tick"), + }, + }, + })) { + yield { + node: node as TSESTree.CallExpression, + name: path[path.length - 1], + } + } +} diff --git a/src/rules/valid-context-access.ts b/src/rules/valid-context-access.ts new file mode 100644 index 000000000..cd8490f1e --- /dev/null +++ b/src/rules/valid-context-access.ts @@ -0,0 +1,223 @@ +import { createRule } from "../utils" +import { extractContextReferences } from "./reference-helpers/svelte-context" +import { extractSvelteLifeCycleReferences } from "./reference-helpers/svelte-lifecycle" +import { extractTaskReferences } from "./reference-helpers/microtask" +import { isInsideOfPromiseThenOrCatch } from "../utils/promise" +import type { AST } from "svelte-eslint-parser" +import type { TSESTree } from "@typescript-eslint/types" + +export default createRule("valid-context-access", { + meta: { + docs: { + description: + "context functions must be called during component initialization.", + category: "Possible Errors", + recommended: false, + }, + schema: [], + messages: { + unexpected: + "Do not call {{function}} except during component initialization.", + }, + type: "problem", + }, + create(context) { + // // This rule doesn't check other than Svelte files. + if (!context.parserServices.isSvelte) { + return {} + } + + const sourceCode = context.getSourceCode() + const lifeCycleReferences = Array.from( + extractSvelteLifeCycleReferences(context), + ).map((r) => r.node) + const taskReferences = Array.from(extractTaskReferences(context)) + + // Extract diff --git a/tests/fixtures/rules/valid-context-access/invalid/case02-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case02-errors.yaml new file mode 100644 index 000000000..f33732b66 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case02-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 5 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case02-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case02-input.svelte new file mode 100644 index 000000000..b0af74395 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case02-input.svelte @@ -0,0 +1,7 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case03-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case03-errors.yaml new file mode 100644 index 000000000..96c6f1b93 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case03-errors.yaml @@ -0,0 +1,4 @@ +- message: Do not call setContext except during component initialization. + line: 4 + column: 5 + suggestions: null diff --git a/tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte new file mode 100644 index 000000000..2df88bc18 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case03-input.svelte @@ -0,0 +1,8 @@ + + + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case04-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case04-errors.yaml new file mode 100644 index 000000000..96c6f1b93 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case04-errors.yaml @@ -0,0 +1,4 @@ +- message: Do not call setContext except during component initialization. + line: 4 + column: 5 + suggestions: null diff --git a/tests/fixtures/rules/valid-context-access/invalid/case04-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case04-input.svelte new file mode 100644 index 000000000..4b62a8d4e --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case04-input.svelte @@ -0,0 +1,13 @@ + + +{#if true} + {@const foo = something()} + +{/if} diff --git a/tests/fixtures/rules/valid-context-access/invalid/case05-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case05-errors.yaml new file mode 100644 index 000000000..96c6f1b93 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case05-errors.yaml @@ -0,0 +1,4 @@ +- message: Do not call setContext except during component initialization. + line: 4 + column: 5 + suggestions: null diff --git a/tests/fixtures/rules/valid-context-access/invalid/case05-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case05-input.svelte new file mode 100644 index 000000000..b21f3b9b8 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case05-input.svelte @@ -0,0 +1,12 @@ + + +{#if something()} + +{/if} diff --git a/tests/fixtures/rules/valid-context-access/invalid/case06-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case06-errors.yaml new file mode 100644 index 000000000..9d0ec949e --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case06-errors.yaml @@ -0,0 +1,4 @@ +- message: Do not call setContext except during component initialization. + line: 5 + column: 7 + suggestions: null diff --git a/tests/fixtures/rules/valid-context-access/invalid/case06-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case06-input.svelte new file mode 100644 index 000000000..310840bb8 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case06-input.svelte @@ -0,0 +1,15 @@ + + +{#if something()} + +{/if} diff --git a/tests/fixtures/rules/valid-context-access/invalid/case07-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case07-errors.yaml new file mode 100644 index 000000000..5702a7bed --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case07-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call hasContext except during component initialization. + line: 5 + column: 9 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case07-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case07-input.svelte new file mode 100644 index 000000000..5484f2dc9 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case07-input.svelte @@ -0,0 +1,9 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case08-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case08-errors.yaml new file mode 100644 index 000000000..6e01eaa01 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case08-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 6 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case08-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case08-input.svelte new file mode 100644 index 000000000..574c3b3ab --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case08-input.svelte @@ -0,0 +1,9 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case09-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case09-errors.yaml new file mode 100644 index 000000000..8a807194f --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case09-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 3 + column: 3 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case09-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case09-input.svelte new file mode 100644 index 000000000..0017cf865 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case09-input.svelte @@ -0,0 +1,4 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case10-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case10-errors.yaml new file mode 100644 index 000000000..f33732b66 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case10-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 5 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case10-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case10-input.svelte new file mode 100644 index 000000000..0d504f5ff --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case10-input.svelte @@ -0,0 +1,7 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case11-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case11-errors.yaml new file mode 100644 index 000000000..0897a75a9 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case11-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 6 + column: 7 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case11-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case11-input.svelte new file mode 100644 index 000000000..dc9f3571b --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case11-input.svelte @@ -0,0 +1,11 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case12-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case12-errors.yaml new file mode 100644 index 000000000..28b8f23b8 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case12-errors.yaml @@ -0,0 +1,12 @@ +- message: Do not call setContext except during component initialization. + line: 5 + column: 5 +- message: Do not call setContext except during component initialization. + line: 9 + column: 5 +- message: Do not call setContext except during component initialization. + line: 13 + column: 5 +- message: Do not call setContext except during component initialization. + line: 17 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case12-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case12-input.svelte new file mode 100644 index 000000000..c170ecc49 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case12-input.svelte @@ -0,0 +1,19 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case13-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case13-errors.yaml new file mode 100644 index 000000000..f33732b66 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case13-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 5 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case13-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case13-input.svelte new file mode 100644 index 000000000..80ddb16c4 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case13-input.svelte @@ -0,0 +1,7 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case14-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case14-errors.yaml new file mode 100644 index 000000000..4055b4a9a --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case14-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 4 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case14-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case14-input.svelte new file mode 100644 index 000000000..e8a9b151e --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case14-input.svelte @@ -0,0 +1,10 @@ + diff --git a/tests/fixtures/rules/valid-context-access/invalid/case15-errors.yaml b/tests/fixtures/rules/valid-context-access/invalid/case15-errors.yaml new file mode 100644 index 000000000..4055b4a9a --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case15-errors.yaml @@ -0,0 +1,3 @@ +- message: Do not call setContext except during component initialization. + line: 4 + column: 5 diff --git a/tests/fixtures/rules/valid-context-access/invalid/case15-input.svelte b/tests/fixtures/rules/valid-context-access/invalid/case15-input.svelte new file mode 100644 index 000000000..f0df9c344 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/invalid/case15-input.svelte @@ -0,0 +1,11 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case01-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case01-input.svelte new file mode 100644 index 000000000..3ec7fa441 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case01-input.svelte @@ -0,0 +1,8 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case02-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case02-input.svelte new file mode 100644 index 000000000..bab6b283a --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case02-input.svelte @@ -0,0 +1,6 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case03-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case03-input.svelte new file mode 100644 index 000000000..461a5f1f3 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case03-input.svelte @@ -0,0 +1,8 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case04-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case04-input.svelte new file mode 100644 index 000000000..852518424 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case04-input.svelte @@ -0,0 +1,15 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case05-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case05-input.svelte new file mode 100644 index 000000000..49cce3bc7 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case05-input.svelte @@ -0,0 +1,6 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case06-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case06-input.svelte new file mode 100644 index 000000000..17e2ae7e2 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case06-input.svelte @@ -0,0 +1,15 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case07-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case07-input.svelte new file mode 100644 index 000000000..24c5ae0a4 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case07-input.svelte @@ -0,0 +1,12 @@ + + +{#if something} + +{/if} diff --git a/tests/fixtures/rules/valid-context-access/valid/case08-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case08-input.svelte new file mode 100644 index 000000000..c0b2b1d8b --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case08-input.svelte @@ -0,0 +1,22 @@ + diff --git a/tests/fixtures/rules/valid-context-access/valid/case09-input.js b/tests/fixtures/rules/valid-context-access/valid/case09-input.js new file mode 100644 index 000000000..4d3f8fe4c --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case09-input.js @@ -0,0 +1,17 @@ +import { setContext } from "svelte" + +const something = () => { + setContext("answer", 42) +} + +const something2 = async () => { + await Promise.resolve() + setContext("answer", 42) +} + +const aaa = (fn) => { + fn() +} + +aaa(() => something()) +something2() diff --git a/tests/fixtures/rules/valid-context-access/valid/case10-input.svelte b/tests/fixtures/rules/valid-context-access/valid/case10-input.svelte new file mode 100644 index 000000000..fac4aafc3 --- /dev/null +++ b/tests/fixtures/rules/valid-context-access/valid/case10-input.svelte @@ -0,0 +1,6 @@ + diff --git a/tests/src/rules/valid-context-access.ts b/tests/src/rules/valid-context-access.ts new file mode 100644 index 000000000..f40dafd6d --- /dev/null +++ b/tests/src/rules/valid-context-access.ts @@ -0,0 +1,20 @@ +import { RuleTester } from "eslint" +import rule from "../../../src/rules/valid-context-access" +import { loadTestCases } from "../../utils/utils" + +const tester = new RuleTester({ + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + }, + env: { + browser: true, + es2017: true, + }, +}) + +tester.run( + "valid-context-access", + rule as any, + loadTestCases("valid-context-access"), +)