From 932aba2d2dc02ce59111ee3a6e3b297b464b6c4c Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Wed, 27 Mar 2024 02:28:45 +0900 Subject: [PATCH 01/11] feat: support flat config --- .github/workflows/main.yml | 3 +- .gitignore | 2 +- __tests__/integrations/flat-config.spec.ts | 40 ++++++++ __tests__/integrations/flat-config/.npmrc | 1 + __tests__/integrations/flat-config/a.vue | 11 +++ .../integrations/flat-config/eslint.config.js | 10 ++ .../integrations/flat-config/package.json | 11 +++ __tests__/integrations/helper.ts | 8 ++ __tests__/integrations/legacy-config.spec.ts | 40 ++++++++ .../integrations/legacy-config/.eslintrc.json | 13 +++ __tests__/integrations/legacy-config/.npmrc | 1 + __tests__/integrations/legacy-config/a.vue | 11 +++ .../integrations/legacy-config/package.json | 11 +++ package.json | 10 +- src/configs/flat/recommended.ts | 52 +++++++++++ src/index.ts | 61 ++++++------ src/rules/interactive-supports-focus.ts | 2 +- tsconfig.build.json | 2 +- tsconfig.json | 1 + yarn.lock | 92 ++++++++++--------- 20 files changed, 307 insertions(+), 75 deletions(-) create mode 100644 __tests__/integrations/flat-config.spec.ts create mode 100644 __tests__/integrations/flat-config/.npmrc create mode 100644 __tests__/integrations/flat-config/a.vue create mode 100644 __tests__/integrations/flat-config/eslint.config.js create mode 100644 __tests__/integrations/flat-config/package.json create mode 100644 __tests__/integrations/helper.ts create mode 100644 __tests__/integrations/legacy-config.spec.ts create mode 100644 __tests__/integrations/legacy-config/.eslintrc.json create mode 100644 __tests__/integrations/legacy-config/.npmrc create mode 100644 __tests__/integrations/legacy-config/a.vue create mode 100644 __tests__/integrations/legacy-config/package.json create mode 100644 src/configs/flat/recommended.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a09ea6ea..896807e1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,7 +19,8 @@ jobs: - name: Lint and test run: | yarn install --frozen-lockfile - yarn prepublishOnly + yarn build yarn lint yarn prettier --check '**/*' yarn test + yarn test:integration diff --git a/.gitignore b/.gitignore index aab752e0..9a0c8974 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ /.husky/ /.idea/ /dist/ -/node_modules/ +node_modules /docs/.vitepress/dist /docs/.vitepress/cache yarn-error.log diff --git a/__tests__/integrations/flat-config.spec.ts b/__tests__/integrations/flat-config.spec.ts new file mode 100644 index 00000000..97b5d95d --- /dev/null +++ b/__tests__/integrations/flat-config.spec.ts @@ -0,0 +1,40 @@ +import cp from "child_process"; +import path from "path"; +import semver from "semver"; +import { readPackageJson } from "./helper"; + +const ESLINT = `.${path.sep}node_modules${path.sep}.bin${path.sep}eslint`; + +describe("Integration with flat config", () => { + let originalCwd: null | string = null; + + beforeEach(() => { + originalCwd = process.cwd(); + process.chdir(path.join(__dirname, "flat-config")); + cp.execSync("npm i -f", { stdio: "inherit" }); + }); + afterEach(() => { + originalCwd && process.chdir(originalCwd); + }); + + it("should lint without errors", () => { + if ( + !semver.satisfies( + process.version, + readPackageJson( + path.resolve(__dirname, "flat-config/node_modules/eslint") + ).engines.node + ) + ) { + return; + } + + const result = JSON.parse( + cp.execSync(`${ESLINT} a.vue --max-warnings 1 --format=json`, { + encoding: "utf-8" + }) + ); + expect(result.length).toBe(1); + expect(result[0].messages[0].messageId).toBe("imgMissingAlt"); + }); +}); diff --git a/__tests__/integrations/flat-config/.npmrc b/__tests__/integrations/flat-config/.npmrc new file mode 100644 index 00000000..43c97e71 --- /dev/null +++ b/__tests__/integrations/flat-config/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/__tests__/integrations/flat-config/a.vue b/__tests__/integrations/flat-config/a.vue new file mode 100644 index 00000000..6f0b8f75 --- /dev/null +++ b/__tests__/integrations/flat-config/a.vue @@ -0,0 +1,11 @@ + + + diff --git a/__tests__/integrations/flat-config/eslint.config.js b/__tests__/integrations/flat-config/eslint.config.js new file mode 100644 index 00000000..5ae8ab92 --- /dev/null +++ b/__tests__/integrations/flat-config/eslint.config.js @@ -0,0 +1,10 @@ +import plugin from "eslint-plugin-vuejs-accessibility"; + +export default [ + ...plugin.configs["flat/recommended"], + { + rules: { + "vuejs-accessibility/alt-text": "warn" + } + } +]; diff --git a/__tests__/integrations/flat-config/package.json b/__tests__/integrations/flat-config/package.json new file mode 100644 index 00000000..e89f1403 --- /dev/null +++ b/__tests__/integrations/flat-config/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "name": "integration-test-for-flat-config", + "type": "module", + "version": "1.0.0", + "description": "Integration test for flat config", + "dependencies": { + "eslint": "^8.57.0-0", + "eslint-plugin-vuejs-accessibility": "file:../../.." + } +} diff --git a/__tests__/integrations/helper.ts b/__tests__/integrations/helper.ts new file mode 100644 index 00000000..d69995d1 --- /dev/null +++ b/__tests__/integrations/helper.ts @@ -0,0 +1,8 @@ +import fs from "fs"; +import path from "path"; + +export function readPackageJson(base: string) { + return JSON.parse( + fs.readFileSync(path.resolve(base, "package.json"), "utf-8") + ); +} diff --git a/__tests__/integrations/legacy-config.spec.ts b/__tests__/integrations/legacy-config.spec.ts new file mode 100644 index 00000000..8a4e65cb --- /dev/null +++ b/__tests__/integrations/legacy-config.spec.ts @@ -0,0 +1,40 @@ +import cp from "child_process"; +import path from "path"; +import semver from "semver"; +import { readPackageJson } from "./helper"; + +const ESLINT = `.${path.sep}node_modules${path.sep}.bin${path.sep}eslint`; + +describe("Integration with legacy config", () => { + let originalCwd: null | string = null; + + beforeEach(() => { + originalCwd = process.cwd(); + process.chdir(path.join(__dirname, "legacy-config")); + cp.execSync("npm i -f", { stdio: "inherit" }); + }); + afterEach(() => { + originalCwd && process.chdir(originalCwd); + }); + + it("should lint without errors", () => { + if ( + !semver.satisfies( + process.version, + readPackageJson( + path.resolve(__dirname, "legacy-config/node_modules/eslint") + ).engines.node + ) + ) { + return; + } + + const result = JSON.parse( + cp.execSync(`${ESLINT} a.vue --max-warnings 1 --format=json`, { + encoding: "utf-8" + }) + ); + expect(result.length).toBe(1); + expect(result[0].messages[0].messageId).toBe("imgMissingAlt"); + }); +}); diff --git a/__tests__/integrations/legacy-config/.eslintrc.json b/__tests__/integrations/legacy-config/.eslintrc.json new file mode 100644 index 00000000..b8124b09 --- /dev/null +++ b/__tests__/integrations/legacy-config/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "root": true, + "extends": ["plugin:vuejs-accessibility/recommended"], + "plugins": ["vuejs-accessibility"], + "parser": "vue-eslint-parser", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2019 + }, + "rules": { + "vuejs-accessibility/alt-text": "warn" + } +} diff --git a/__tests__/integrations/legacy-config/.npmrc b/__tests__/integrations/legacy-config/.npmrc new file mode 100644 index 00000000..43c97e71 --- /dev/null +++ b/__tests__/integrations/legacy-config/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/__tests__/integrations/legacy-config/a.vue b/__tests__/integrations/legacy-config/a.vue new file mode 100644 index 00000000..6f0b8f75 --- /dev/null +++ b/__tests__/integrations/legacy-config/a.vue @@ -0,0 +1,11 @@ + + + diff --git a/__tests__/integrations/legacy-config/package.json b/__tests__/integrations/legacy-config/package.json new file mode 100644 index 00000000..902617e7 --- /dev/null +++ b/__tests__/integrations/legacy-config/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "name": "integration-test-for-legacy-config", + "type": "module", + "version": "1.0.0", + "description": "Integration test for legacy config", + "dependencies": { + "eslint": "^8.57.0-0", + "eslint-plugin-vuejs-accessibility": "file:../../.." + } +} diff --git a/package.json b/package.json index 27081770..758ed9cf 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,15 @@ "version": "2.2.1", "description": "An eslint plugin for checking Vue.js files for accessibility", "main": "dist/index.js", + "files": [ + "dist" + ], "scripts": { "lint": "eslint --cache .", + "build": "tsc -p tsconfig.build.json", "prepublishOnly": "tsc -p tsconfig.build.json", "test": "jest", + "test:integration": "jest --testTimeout 60000 --testRegex \".*\\.spec\\.ts$\"", "release": "np", "docs:dev": "vitepress dev docs", "docs:build": "vitepress build docs" @@ -42,15 +47,18 @@ "@types/eslint-scope": "^3.7.2", "@types/jest": "^29.2.5", "@types/node": "^20.1.0", + "@types/semver": "^7.5.7", "@typescript-eslint/eslint-plugin": "^7.0.0", - "@typescript-eslint/parser": "^6.9.1", + "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.8.0", "eslint-plugin-eslint-plugin": "^5.0.0", + "globals": "^14.0.0", "husky": "^9.0.5", "jest": "^29.2.2", "np": "^10.0.0", "prettier": "^3.0.0", "pretty-quick": "^4.0.0", + "semver": "^7.6.0", "ts-jest": "^29.0.3", "ts-node": "^10.3.0", "typescript": "^5.0.2", diff --git a/src/configs/flat/recommended.ts b/src/configs/flat/recommended.ts new file mode 100644 index 00000000..582b5789 --- /dev/null +++ b/src/configs/flat/recommended.ts @@ -0,0 +1,52 @@ +import globals from "globals"; + +const recommended = [ + { + plugins: { + get "vuejs-accessibility"() { + return require("../../index"); + } + }, + languageOptions: { + sourceType: "module", + globals: globals.browser + } + }, + { + files: ["*.vue", "**/*.vue"], + plugins: { + get "vuejs-accessibility"() { + return require("../../index"); + } + }, + languageOptions: { + parser: require("vue-eslint-parser"), + sourceType: "module", + globals: globals.browser + }, + rules: { + "vuejs-accessibility/alt-text": "error", + "vuejs-accessibility/anchor-has-content": "error", + "vuejs-accessibility/aria-props": "error", + "vuejs-accessibility/aria-role": "error", + "vuejs-accessibility/aria-unsupported-elements": "error", + "vuejs-accessibility/click-events-have-key-events": "error", + "vuejs-accessibility/form-control-has-label": "error", + "vuejs-accessibility/heading-has-content": "error", + "vuejs-accessibility/iframe-has-title": "error", + "vuejs-accessibility/interactive-supports-focus": "error", + "vuejs-accessibility/label-has-for": "error", + "vuejs-accessibility/media-has-caption": "error", + "vuejs-accessibility/mouse-events-have-key-events": "error", + "vuejs-accessibility/no-access-key": "error", + "vuejs-accessibility/no-autofocus": "error", + "vuejs-accessibility/no-distracting-elements": "error", + "vuejs-accessibility/no-redundant-roles": "error", + "vuejs-accessibility/no-static-element-interactions": "error", + "vuejs-accessibility/role-has-required-aria-props": "error", + "vuejs-accessibility/tabindex-no-positive": "error" + } + } +]; + +export = recommended; diff --git a/src/index.ts b/src/index.ts index 32c75c79..c9876182 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ -import recommended from "./configs/recommended"; +import { default as recommended } from "./configs/recommended"; +import flatRecommended from "./configs/flat/recommended"; import altText from "./rules/alt-text"; import anchorHasContent from "./rules/anchor-has-content"; @@ -22,33 +23,35 @@ import noStaticElementInteractions from "./rules/no-static-element-interactions" import roleHasRequiredAriaProps from "./rules/role-has-required-aria-props"; import tabindexNoPositive from "./rules/tabindex-no-positive"; -const plugin = { - configs: { - recommended - }, - rules: { - "alt-text": altText, - "anchor-has-content": anchorHasContent, - "aria-props": ariaProps, - "aria-role": ariaRole, - "aria-unsupported-elements": ariaUnsupportedElements, - "click-events-have-key-events": clickEventsHaveKeyEvents, - "form-control-has-label": formControlHasLabel, - "heading-has-content": headingHasContent, - "iframe-has-title": iframeHasTitle, - "interactive-supports-focus": interactiveSupportsFocus, - "label-has-for": labelHasFor, - "media-has-caption": mediaHasCaption, - "mouse-events-have-key-events": mouseEventsHaveKeyEvents, - "no-access-key": noAccessKey, - "no-autofocus": noAutofocus, - "no-distracting-elements": noDistractingElements, - "no-onchange": noOnchange, - "no-redundant-roles": noRedundantRoles, - "no-static-element-interactions": noStaticElementInteractions, - "role-has-required-aria-props": roleHasRequiredAriaProps, - "tabindex-no-positive": tabindexNoPositive - } +const configs = { + recommended, + "flat/recommended": flatRecommended +}; +const rules = { + "alt-text": altText, + "anchor-has-content": anchorHasContent, + "aria-props": ariaProps, + "aria-role": ariaRole, + "aria-unsupported-elements": ariaUnsupportedElements, + "click-events-have-key-events": clickEventsHaveKeyEvents, + "form-control-has-label": formControlHasLabel, + "heading-has-content": headingHasContent, + "iframe-has-title": iframeHasTitle, + "interactive-supports-focus": interactiveSupportsFocus, + "label-has-for": labelHasFor, + "media-has-caption": mediaHasCaption, + "mouse-events-have-key-events": mouseEventsHaveKeyEvents, + "no-access-key": noAccessKey, + "no-autofocus": noAutofocus, + "no-distracting-elements": noDistractingElements, + "no-onchange": noOnchange, + "no-redundant-roles": noRedundantRoles, + "no-static-element-interactions": noStaticElementInteractions, + "role-has-required-aria-props": roleHasRequiredAriaProps, + "tabindex-no-positive": tabindexNoPositive }; -export = plugin; +export = { + configs, + rules +}; diff --git a/src/rules/interactive-supports-focus.ts b/src/rules/interactive-supports-focus.ts index 7fa5d9d3..d3871ff6 100644 --- a/src/rules/interactive-supports-focus.ts +++ b/src/rules/interactive-supports-focus.ts @@ -71,7 +71,7 @@ function hasTabIndex(node: AST.VElement) { return value === null; } -interface InteractiveSupportsFocus extends Rule.RuleModule { +export interface InteractiveSupportsFocus extends Rule.RuleModule { interactiveHandlers: string[]; interactiveRoles: ARIARoleDefinitionKey[]; } diff --git a/tsconfig.build.json b/tsconfig.build.json index fd6c5ac3..6b9bf3be 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,4 +1,4 @@ { "extends": "./tsconfig.json", - "exclude": ["bin", "src/**/__tests__", "docs/**", "jest.setup.ts"] + "exclude": ["bin", "src/**/__tests__", "docs/**", "jest.setup.ts", "dist"] } diff --git a/tsconfig.json b/tsconfig.json index c4df42ce..dd54c5ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "strict": true, "esModuleInterop": true, "resolveJsonModule": true, + "declaration": true, "outDir": "./dist" } } diff --git a/yarn.lock b/yarn.lock index af19cfe0..a78a9fd4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1321,6 +1321,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== +"@types/semver@^7.5.7": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== + "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1360,25 +1365,17 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^6.9.1": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== +"@typescript-eslint/parser@^7.0.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.4.0.tgz#540f4321de1e52b886c0fa68628af1459954c1f1" + integrity sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ== dependencies: - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/scope-manager" "7.4.0" + "@typescript-eslint/types" "7.4.0" + "@typescript-eslint/typescript-estree" "7.4.0" + "@typescript-eslint/visitor-keys" "7.4.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== - dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - "@typescript-eslint/scope-manager@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.0.0.tgz#15ea9abad2b56fc8f5c0b516775f41c86c5c8685" @@ -1387,6 +1384,14 @@ "@typescript-eslint/types" "7.0.0" "@typescript-eslint/visitor-keys" "7.0.0" +"@typescript-eslint/scope-manager@7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz#acfc69261f10ece7bf7ece1734f1713392c3655f" + integrity sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw== + dependencies: + "@typescript-eslint/types" "7.4.0" + "@typescript-eslint/visitor-keys" "7.4.0" + "@typescript-eslint/type-utils@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.0.0.tgz#a4c7ae114414e09dbbd3c823b5924793f7483252" @@ -1397,23 +1402,23 @@ debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== - "@typescript-eslint/types@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.0.0.tgz#2e5889c7fe3c873fc6dc6420aa77775f17cd5dc6" integrity sha512-9ZIJDqagK1TTs4W9IyeB2sH/s1fFhN9958ycW8NRTg1vXGzzH5PQNzq6KbsbVGMT+oyyfa17DfchHDidcmf5cg== -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== +"@typescript-eslint/types@7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.4.0.tgz#ee9dafa75c99eaee49de6dcc9348b45d354419b6" + integrity sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw== + +"@typescript-eslint/typescript-estree@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.0.tgz#7ce66f2ce068517f034f73fba9029300302fdae9" + integrity sha512-JzsOzhJJm74aQ3c9um/aDryHgSHfaX8SHFIu9x4Gpik/+qxLvxUylhTsO9abcNu39JIdhY2LgYrFxTii3IajLA== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "7.0.0" + "@typescript-eslint/visitor-keys" "7.0.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -1421,13 +1426,13 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.0.tgz#7ce66f2ce068517f034f73fba9029300302fdae9" - integrity sha512-JzsOzhJJm74aQ3c9um/aDryHgSHfaX8SHFIu9x4Gpik/+qxLvxUylhTsO9abcNu39JIdhY2LgYrFxTii3IajLA== +"@typescript-eslint/typescript-estree@7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz#12dbcb4624d952f72c10a9f4431284fca24624f4" + integrity sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg== dependencies: - "@typescript-eslint/types" "7.0.0" - "@typescript-eslint/visitor-keys" "7.0.0" + "@typescript-eslint/types" "7.4.0" + "@typescript-eslint/visitor-keys" "7.4.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -1448,14 +1453,6 @@ "@typescript-eslint/typescript-estree" "7.0.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== - dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" - "@typescript-eslint/visitor-keys@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.0.tgz#83cdadd193ee735fe9ea541f6a2b4d76dfe62081" @@ -1464,6 +1461,14 @@ "@typescript-eslint/types" "7.0.0" eslint-visitor-keys "^3.4.1" +"@typescript-eslint/visitor-keys@7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz#0c8ff2c1f8a6fe8d7d1a57ebbd4a638e86a60a94" + integrity sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA== + dependencies: + "@typescript-eslint/types" "7.4.0" + eslint-visitor-keys "^3.4.1" + "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -2935,6 +2940,11 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" From 07b9b56101983686c2aec2746d0799d3e6b04442 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Wed, 27 Mar 2024 09:48:32 +0900 Subject: [PATCH 02/11] refactor: tweak test context --- __tests__/integrations/flat-config.spec.ts | 2 +- __tests__/integrations/legacy-config.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/__tests__/integrations/flat-config.spec.ts b/__tests__/integrations/flat-config.spec.ts index 97b5d95d..2f7c48de 100644 --- a/__tests__/integrations/flat-config.spec.ts +++ b/__tests__/integrations/flat-config.spec.ts @@ -17,7 +17,7 @@ describe("Integration with flat config", () => { originalCwd && process.chdir(originalCwd); }); - it("should lint without errors", () => { + it("should work with config", () => { if ( !semver.satisfies( process.version, diff --git a/__tests__/integrations/legacy-config.spec.ts b/__tests__/integrations/legacy-config.spec.ts index 8a4e65cb..aefa8adf 100644 --- a/__tests__/integrations/legacy-config.spec.ts +++ b/__tests__/integrations/legacy-config.spec.ts @@ -17,7 +17,7 @@ describe("Integration with legacy config", () => { originalCwd && process.chdir(originalCwd); }); - it("should lint without errors", () => { + it("should work with config", () => { if ( !semver.satisfies( process.version, From 205370ac18e95f7fc5817f646ab622dff89d260b Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Wed, 27 Mar 2024 14:20:37 +0900 Subject: [PATCH 03/11] fix: update docs & tweak vitepress --- docs/.vitepress/{config.ts => config.mts} | 0 docs/index.md | 28 ++++++++++++++++++- docs/rule-overview/RuleTable.vue | 1 + ...verview.data.ts => rule-overview.data.mts} | 8 +++--- src/configs/base.ts | 26 +++++++++++++++++ src/configs/flat/recommended.ts | 24 ++-------------- src/configs/recommended.ts | 24 ++-------------- tsconfig.build.json | 9 +++++- 8 files changed, 70 insertions(+), 50 deletions(-) rename docs/.vitepress/{config.ts => config.mts} (100%) rename docs/rule-overview/{rule-overview.data.ts => rule-overview.data.mts} (73%) create mode 100644 src/configs/base.ts diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.mts similarity index 100% rename from docs/.vitepress/config.ts rename to docs/.vitepress/config.mts diff --git a/docs/index.md b/docs/index.md index 74073a93..7b0f8711 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,33 @@ pnpm add -D eslint-plugin-vuejs-accessibility ## 📖 Usage -Add `vuejs-accessibility` to the plugins section of your `eslint` configuration. You can omit the `eslint-plugin-` prefix: +### Configuration (`eslint.config.js`) + +Use `eslint.config.js` file to configure rules. This is the default in ESLint v9, but can be used starting from ESLint v8.57.0. See also: https://eslint.org/docs/latest/use/configure/configuration-files-new. + +Example eslint.config.js: + +```js +import pluginVueA11y from "eslint-plugin-vuejs-accessibility"; + +export default [ + // add more generic rulesets here, such as: + // js.configs.recommended, + ...pluginVueA11y.configs["flat/recommended"], + { + rules: { + // override/add rules settings here, such as: + // "vuejs-accessibility/alt-text": "error" + } + } +]; +``` + +### Configuration (`.eslintrc`) + +Use `.eslintrc.*` file to configure rules in ESLint < v9. See also: https://eslint.org/docs/latest/use/configure/. + +Add `vuejs-accessibility` to the plugins section of your configuration. You can omit the `eslint-plugin-` prefix: ```json { diff --git a/docs/rule-overview/RuleTable.vue b/docs/rule-overview/RuleTable.vue index 69e20029..54b1dce7 100644 --- a/docs/rule-overview/RuleTable.vue +++ b/docs/rule-overview/RuleTable.vue @@ -38,3 +38,4 @@ td:last-of-type { width: 50px; } +./rule-overview.data.mjs diff --git a/docs/rule-overview/rule-overview.data.ts b/docs/rule-overview/rule-overview.data.mts similarity index 73% rename from docs/rule-overview/rule-overview.data.ts rename to docs/rule-overview/rule-overview.data.mts index ca67c9ed..3747058c 100644 --- a/docs/rule-overview/rule-overview.data.ts +++ b/docs/rule-overview/rule-overview.data.mts @@ -1,6 +1,6 @@ import { defineLoader } from "vitepress"; -import recommended from "../../src/configs/recommended"; -import { rules } from "../.vitepress/rulesForSidebar"; +import { rules as baseRules } from "../../src/configs/base.js"; +import { rules } from "../.vitepress/rulesForSidebar.js"; export type Data = Array<{ name: string; @@ -23,8 +23,8 @@ export default defineLoader({ }); function getRecommendedRules() { - if (recommended.rules) { - return Object.keys(recommended.rules).map(removeRulePrefix); + if (baseRules) { + return Object.keys(baseRules).map(removeRulePrefix); } return []; } diff --git a/src/configs/base.ts b/src/configs/base.ts new file mode 100644 index 00000000..133c96a1 --- /dev/null +++ b/src/configs/base.ts @@ -0,0 +1,26 @@ +import type { Linter } from "eslint"; + +const rules = { + "vuejs-accessibility/alt-text": "error", + "vuejs-accessibility/anchor-has-content": "error", + "vuejs-accessibility/aria-props": "error", + "vuejs-accessibility/aria-role": "error", + "vuejs-accessibility/aria-unsupported-elements": "error", + "vuejs-accessibility/click-events-have-key-events": "error", + "vuejs-accessibility/form-control-has-label": "error", + "vuejs-accessibility/heading-has-content": "error", + "vuejs-accessibility/iframe-has-title": "error", + "vuejs-accessibility/interactive-supports-focus": "error", + "vuejs-accessibility/label-has-for": "error", + "vuejs-accessibility/media-has-caption": "error", + "vuejs-accessibility/mouse-events-have-key-events": "error", + "vuejs-accessibility/no-access-key": "error", + "vuejs-accessibility/no-autofocus": "error", + "vuejs-accessibility/no-distracting-elements": "error", + "vuejs-accessibility/no-redundant-roles": "error", + "vuejs-accessibility/no-static-element-interactions": "error", + "vuejs-accessibility/role-has-required-aria-props": "error", + "vuejs-accessibility/tabindex-no-positive": "error" +} satisfies Linter.RulesRecord; + +export { rules }; diff --git a/src/configs/flat/recommended.ts b/src/configs/flat/recommended.ts index 582b5789..3ba48fc7 100644 --- a/src/configs/flat/recommended.ts +++ b/src/configs/flat/recommended.ts @@ -1,4 +1,5 @@ import globals from "globals"; +import { rules } from "../base"; const recommended = [ { @@ -24,28 +25,7 @@ const recommended = [ sourceType: "module", globals: globals.browser }, - rules: { - "vuejs-accessibility/alt-text": "error", - "vuejs-accessibility/anchor-has-content": "error", - "vuejs-accessibility/aria-props": "error", - "vuejs-accessibility/aria-role": "error", - "vuejs-accessibility/aria-unsupported-elements": "error", - "vuejs-accessibility/click-events-have-key-events": "error", - "vuejs-accessibility/form-control-has-label": "error", - "vuejs-accessibility/heading-has-content": "error", - "vuejs-accessibility/iframe-has-title": "error", - "vuejs-accessibility/interactive-supports-focus": "error", - "vuejs-accessibility/label-has-for": "error", - "vuejs-accessibility/media-has-caption": "error", - "vuejs-accessibility/mouse-events-have-key-events": "error", - "vuejs-accessibility/no-access-key": "error", - "vuejs-accessibility/no-autofocus": "error", - "vuejs-accessibility/no-distracting-elements": "error", - "vuejs-accessibility/no-redundant-roles": "error", - "vuejs-accessibility/no-static-element-interactions": "error", - "vuejs-accessibility/role-has-required-aria-props": "error", - "vuejs-accessibility/tabindex-no-positive": "error" - } + rules } ]; diff --git a/src/configs/recommended.ts b/src/configs/recommended.ts index 47ec21e1..180cd64f 100644 --- a/src/configs/recommended.ts +++ b/src/configs/recommended.ts @@ -1,4 +1,5 @@ import type { Linter } from "eslint"; +import { rules } from "./base"; const recommended: Linter.BaseConfig = { parser: require.resolve("vue-eslint-parser"), @@ -11,28 +12,7 @@ const recommended: Linter.BaseConfig = { es6: true }, plugins: ["vuejs-accessibility"], - rules: { - "vuejs-accessibility/alt-text": "error", - "vuejs-accessibility/anchor-has-content": "error", - "vuejs-accessibility/aria-props": "error", - "vuejs-accessibility/aria-role": "error", - "vuejs-accessibility/aria-unsupported-elements": "error", - "vuejs-accessibility/click-events-have-key-events": "error", - "vuejs-accessibility/form-control-has-label": "error", - "vuejs-accessibility/heading-has-content": "error", - "vuejs-accessibility/iframe-has-title": "error", - "vuejs-accessibility/interactive-supports-focus": "error", - "vuejs-accessibility/label-has-for": "error", - "vuejs-accessibility/media-has-caption": "error", - "vuejs-accessibility/mouse-events-have-key-events": "error", - "vuejs-accessibility/no-access-key": "error", - "vuejs-accessibility/no-autofocus": "error", - "vuejs-accessibility/no-distracting-elements": "error", - "vuejs-accessibility/no-redundant-roles": "error", - "vuejs-accessibility/no-static-element-interactions": "error", - "vuejs-accessibility/role-has-required-aria-props": "error", - "vuejs-accessibility/tabindex-no-positive": "error" - } + rules }; export default recommended; diff --git a/tsconfig.build.json b/tsconfig.build.json index 6b9bf3be..35e615fa 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,4 +1,11 @@ { "extends": "./tsconfig.json", - "exclude": ["bin", "src/**/__tests__", "docs/**", "jest.setup.ts", "dist"] + "exclude": [ + "bin", + "src/**/__tests__", + "docs/**", + "jest.setup.ts", + "dist", + "__tests__" + ] } From 3125a9dd1752bc406daef720bd39005a49351ae3 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Wed, 27 Mar 2024 14:26:33 +0900 Subject: [PATCH 04/11] fix: remove --- docs/rule-overview/RuleTable.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/rule-overview/RuleTable.vue b/docs/rule-overview/RuleTable.vue index 54b1dce7..69e20029 100644 --- a/docs/rule-overview/RuleTable.vue +++ b/docs/rule-overview/RuleTable.vue @@ -38,4 +38,3 @@ td:last-of-type { width: 50px; } -./rule-overview.data.mjs From 1acacc899eba3820606dc0f5c83ff3db93956652 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Thu, 11 Apr 2024 10:59:55 +0900 Subject: [PATCH 05/11] fix: add name for eslint inspector debugging --- docs/rule-overview/rule-overview.data.mts | 2 +- src/configs/flat/recommended.ts | 4 +++- src/configs/recommended.ts | 2 +- src/configs/{base.ts => rules.ts} | 0 4 files changed, 5 insertions(+), 3 deletions(-) rename src/configs/{base.ts => rules.ts} (100%) diff --git a/docs/rule-overview/rule-overview.data.mts b/docs/rule-overview/rule-overview.data.mts index 3747058c..857bcad9 100644 --- a/docs/rule-overview/rule-overview.data.mts +++ b/docs/rule-overview/rule-overview.data.mts @@ -1,5 +1,5 @@ import { defineLoader } from "vitepress"; -import { rules as baseRules } from "../../src/configs/base.js"; +import { rules as baseRules } from "../../src/configs/rules.js"; import { rules } from "../.vitepress/rulesForSidebar.js"; export type Data = Array<{ diff --git a/src/configs/flat/recommended.ts b/src/configs/flat/recommended.ts index 3ba48fc7..e2c316b9 100644 --- a/src/configs/flat/recommended.ts +++ b/src/configs/flat/recommended.ts @@ -1,8 +1,9 @@ import globals from "globals"; -import { rules } from "../base"; +import { rules } from "../rules"; const recommended = [ { + name: 'vuejs-accessibility:setup:base', plugins: { get "vuejs-accessibility"() { return require("../../index"); @@ -14,6 +15,7 @@ const recommended = [ } }, { + name: 'vuejs-accessibility:setup:with-files-rules-and-parser', files: ["*.vue", "**/*.vue"], plugins: { get "vuejs-accessibility"() { diff --git a/src/configs/recommended.ts b/src/configs/recommended.ts index 180cd64f..731c9294 100644 --- a/src/configs/recommended.ts +++ b/src/configs/recommended.ts @@ -1,5 +1,5 @@ import type { Linter } from "eslint"; -import { rules } from "./base"; +import { rules } from "./rules"; const recommended: Linter.BaseConfig = { parser: require.resolve("vue-eslint-parser"), diff --git a/src/configs/base.ts b/src/configs/rules.ts similarity index 100% rename from src/configs/base.ts rename to src/configs/rules.ts From b85b0381b9909cf378d2ec4e1d41589c254ffff5 Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Thu, 11 Apr 2024 11:01:16 +0900 Subject: [PATCH 06/11] test: eslint v9 testing --- __tests__/integrations/flat-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/integrations/flat-config/package.json b/__tests__/integrations/flat-config/package.json index e89f1403..aa907ba0 100644 --- a/__tests__/integrations/flat-config/package.json +++ b/__tests__/integrations/flat-config/package.json @@ -5,7 +5,7 @@ "version": "1.0.0", "description": "Integration test for flat config", "dependencies": { - "eslint": "^8.57.0-0", + "eslint": "^9.0.0", "eslint-plugin-vuejs-accessibility": "file:../../.." } } From dacc876e4c4bcc709cde08280e24c93c9a7fe2da Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Thu, 11 Apr 2024 11:16:11 +0900 Subject: [PATCH 07/11] fix: support eslint v8.x and v9 compatibility --- src/utils/defineTemplateBodyVisitor.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/utils/defineTemplateBodyVisitor.ts b/src/utils/defineTemplateBodyVisitor.ts index 41776062..cb46973f 100644 --- a/src/utils/defineTemplateBodyVisitor.ts +++ b/src/utils/defineTemplateBodyVisitor.ts @@ -14,7 +14,8 @@ function defineTemplateBodyVisitor( templateVisitor: TemplateListener, scriptVisitor?: Rule.RuleListener ) { - if (!context.parserServices.defineTemplateBodyVisitor) { + const parserServices = getParserServices(context); + if (!parserServices.defineTemplateBodyVisitor) { if (path.extname(context.getFilename()) === ".vue") { context.report({ loc: { line: 1, column: 0 }, @@ -26,10 +27,19 @@ function defineTemplateBodyVisitor( return {}; } - return context.parserServices.defineTemplateBodyVisitor( + return parserServices.defineTemplateBodyVisitor( templateVisitor, scriptVisitor ); } +/** + * This function is API compatible with eslint v8.x and eslint v9 or later. + * @see https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#from-context-to-sourcecode + */ +function getParserServices(context: Rule.RuleContext) { + // @ts-expect-error TODO: remove this when eslint v8 support is dropped + return context.sourceCode ? context.sourceCode.parserServices : context.parserServices +} + export default defineTemplateBodyVisitor; From 57eddcc3108af7d3b7daa25599f20ab6f016b8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Hoyer?= Date: Thu, 18 Apr 2024 11:43:52 -0300 Subject: [PATCH 08/11] :see_no_evil: Add .eslintignore file to skip test fixtures --- .eslintignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..bef33474 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +__tests__/integrations/flat-config/ +__tests__/integrations/legacy-config/ +dist/ From 05e1c4729dc570f3f1fd632d0aa23af34125d9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Hoyer?= Date: Thu, 18 Apr 2024 12:08:04 -0300 Subject: [PATCH 09/11] :truck: Move fixtures to a separate __fixtures__ folder --- .eslintignore | 3 +-- .prettierignore | 2 ++ __tests__/integrations/{ => __fixtures__}/flat-config/.npmrc | 0 __tests__/integrations/{ => __fixtures__}/flat-config/a.vue | 0 .../{ => __fixtures__}/flat-config/eslint.config.js | 0 .../integrations/{ => __fixtures__}/flat-config/package.json | 2 +- .../{ => __fixtures__}/legacy-config/.eslintrc.json | 0 .../integrations/{ => __fixtures__}/legacy-config/.npmrc | 0 .../integrations/{ => __fixtures__}/legacy-config/a.vue | 0 .../{ => __fixtures__}/legacy-config/package.json | 2 +- __tests__/integrations/flat-config.spec.ts | 5 +++-- __tests__/integrations/legacy-config.spec.ts | 5 +++-- 12 files changed, 11 insertions(+), 8 deletions(-) rename __tests__/integrations/{ => __fixtures__}/flat-config/.npmrc (100%) rename __tests__/integrations/{ => __fixtures__}/flat-config/a.vue (100%) rename __tests__/integrations/{ => __fixtures__}/flat-config/eslint.config.js (100%) rename __tests__/integrations/{ => __fixtures__}/flat-config/package.json (77%) rename __tests__/integrations/{ => __fixtures__}/legacy-config/.eslintrc.json (100%) rename __tests__/integrations/{ => __fixtures__}/legacy-config/.npmrc (100%) rename __tests__/integrations/{ => __fixtures__}/legacy-config/a.vue (100%) rename __tests__/integrations/{ => __fixtures__}/legacy-config/package.json (78%) diff --git a/.eslintignore b/.eslintignore index bef33474..abe810c5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,2 @@ -__tests__/integrations/flat-config/ -__tests__/integrations/legacy-config/ +__fixtures__/ dist/ diff --git a/.prettierignore b/.prettierignore index 1559e0d8..3f7e7daa 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ .eslintcache +.eslintignore .gitignore .husky .npmignore @@ -6,3 +7,4 @@ LICENSE yarn.lock dist +__fixtures__ diff --git a/__tests__/integrations/flat-config/.npmrc b/__tests__/integrations/__fixtures__/flat-config/.npmrc similarity index 100% rename from __tests__/integrations/flat-config/.npmrc rename to __tests__/integrations/__fixtures__/flat-config/.npmrc diff --git a/__tests__/integrations/flat-config/a.vue b/__tests__/integrations/__fixtures__/flat-config/a.vue similarity index 100% rename from __tests__/integrations/flat-config/a.vue rename to __tests__/integrations/__fixtures__/flat-config/a.vue diff --git a/__tests__/integrations/flat-config/eslint.config.js b/__tests__/integrations/__fixtures__/flat-config/eslint.config.js similarity index 100% rename from __tests__/integrations/flat-config/eslint.config.js rename to __tests__/integrations/__fixtures__/flat-config/eslint.config.js diff --git a/__tests__/integrations/flat-config/package.json b/__tests__/integrations/__fixtures__/flat-config/package.json similarity index 77% rename from __tests__/integrations/flat-config/package.json rename to __tests__/integrations/__fixtures__/flat-config/package.json index aa907ba0..ce85990d 100644 --- a/__tests__/integrations/flat-config/package.json +++ b/__tests__/integrations/__fixtures__/flat-config/package.json @@ -6,6 +6,6 @@ "description": "Integration test for flat config", "dependencies": { "eslint": "^9.0.0", - "eslint-plugin-vuejs-accessibility": "file:../../.." + "eslint-plugin-vuejs-accessibility": "file:../../../.." } } diff --git a/__tests__/integrations/legacy-config/.eslintrc.json b/__tests__/integrations/__fixtures__/legacy-config/.eslintrc.json similarity index 100% rename from __tests__/integrations/legacy-config/.eslintrc.json rename to __tests__/integrations/__fixtures__/legacy-config/.eslintrc.json diff --git a/__tests__/integrations/legacy-config/.npmrc b/__tests__/integrations/__fixtures__/legacy-config/.npmrc similarity index 100% rename from __tests__/integrations/legacy-config/.npmrc rename to __tests__/integrations/__fixtures__/legacy-config/.npmrc diff --git a/__tests__/integrations/legacy-config/a.vue b/__tests__/integrations/__fixtures__/legacy-config/a.vue similarity index 100% rename from __tests__/integrations/legacy-config/a.vue rename to __tests__/integrations/__fixtures__/legacy-config/a.vue diff --git a/__tests__/integrations/legacy-config/package.json b/__tests__/integrations/__fixtures__/legacy-config/package.json similarity index 78% rename from __tests__/integrations/legacy-config/package.json rename to __tests__/integrations/__fixtures__/legacy-config/package.json index 902617e7..34d02ee5 100644 --- a/__tests__/integrations/legacy-config/package.json +++ b/__tests__/integrations/__fixtures__/legacy-config/package.json @@ -6,6 +6,6 @@ "description": "Integration test for legacy config", "dependencies": { "eslint": "^8.57.0-0", - "eslint-plugin-vuejs-accessibility": "file:../../.." + "eslint-plugin-vuejs-accessibility": "file:../../../.." } } diff --git a/__tests__/integrations/flat-config.spec.ts b/__tests__/integrations/flat-config.spec.ts index 2f7c48de..1ef00cb9 100644 --- a/__tests__/integrations/flat-config.spec.ts +++ b/__tests__/integrations/flat-config.spec.ts @@ -7,10 +7,11 @@ const ESLINT = `.${path.sep}node_modules${path.sep}.bin${path.sep}eslint`; describe("Integration with flat config", () => { let originalCwd: null | string = null; + const dirFixture = path.join(__dirname, "__fixtures__/flat-config"); beforeEach(() => { originalCwd = process.cwd(); - process.chdir(path.join(__dirname, "flat-config")); + process.chdir(dirFixture); cp.execSync("npm i -f", { stdio: "inherit" }); }); afterEach(() => { @@ -22,7 +23,7 @@ describe("Integration with flat config", () => { !semver.satisfies( process.version, readPackageJson( - path.resolve(__dirname, "flat-config/node_modules/eslint") + path.resolve(dirFixture, "node_modules/eslint") ).engines.node ) ) { diff --git a/__tests__/integrations/legacy-config.spec.ts b/__tests__/integrations/legacy-config.spec.ts index aefa8adf..af88cbfc 100644 --- a/__tests__/integrations/legacy-config.spec.ts +++ b/__tests__/integrations/legacy-config.spec.ts @@ -7,10 +7,11 @@ const ESLINT = `.${path.sep}node_modules${path.sep}.bin${path.sep}eslint`; describe("Integration with legacy config", () => { let originalCwd: null | string = null; + const dirFixture = path.join(__dirname, "__fixtures__/legacy-config"); beforeEach(() => { originalCwd = process.cwd(); - process.chdir(path.join(__dirname, "legacy-config")); + process.chdir(dirFixture); cp.execSync("npm i -f", { stdio: "inherit" }); }); afterEach(() => { @@ -22,7 +23,7 @@ describe("Integration with legacy config", () => { !semver.satisfies( process.version, readPackageJson( - path.resolve(__dirname, "legacy-config/node_modules/eslint") + path.resolve(dirFixture, "node_modules/eslint") ).engines.node ) ) { From 643fe21aee10348bba6392857cf3f2681ea7e019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Hoyer?= Date: Thu, 18 Apr 2024 12:15:29 -0300 Subject: [PATCH 10/11] :rotating_light: Fix prettier warnings --- __tests__/integrations/flat-config.spec.ts | 15 +++++++-------- __tests__/integrations/legacy-config.spec.ts | 15 +++++++-------- src/configs/flat/recommended.ts | 4 ++-- src/utils/defineTemplateBodyVisitor.ts | 4 +++- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/__tests__/integrations/flat-config.spec.ts b/__tests__/integrations/flat-config.spec.ts index 1ef00cb9..e4998163 100644 --- a/__tests__/integrations/flat-config.spec.ts +++ b/__tests__/integrations/flat-config.spec.ts @@ -19,14 +19,13 @@ describe("Integration with flat config", () => { }); it("should work with config", () => { - if ( - !semver.satisfies( - process.version, - readPackageJson( - path.resolve(dirFixture, "node_modules/eslint") - ).engines.node - ) - ) { + expect.assertions(2); + + const eslintPackageJson = readPackageJson( + path.resolve(dirFixture, "node_modules/eslint") + ); + + if (!semver.satisfies(process.version, eslintPackageJson.engines.node)) { return; } diff --git a/__tests__/integrations/legacy-config.spec.ts b/__tests__/integrations/legacy-config.spec.ts index af88cbfc..a7570d0d 100644 --- a/__tests__/integrations/legacy-config.spec.ts +++ b/__tests__/integrations/legacy-config.spec.ts @@ -19,14 +19,13 @@ describe("Integration with legacy config", () => { }); it("should work with config", () => { - if ( - !semver.satisfies( - process.version, - readPackageJson( - path.resolve(dirFixture, "node_modules/eslint") - ).engines.node - ) - ) { + expect.assertions(2); + + const eslintPackageJson = readPackageJson( + path.resolve(dirFixture, "node_modules/eslint") + ); + + if (!semver.satisfies(process.version, eslintPackageJson.engines.node)) { return; } diff --git a/src/configs/flat/recommended.ts b/src/configs/flat/recommended.ts index e2c316b9..a483fbec 100644 --- a/src/configs/flat/recommended.ts +++ b/src/configs/flat/recommended.ts @@ -3,7 +3,7 @@ import { rules } from "../rules"; const recommended = [ { - name: 'vuejs-accessibility:setup:base', + name: "vuejs-accessibility:setup:base", plugins: { get "vuejs-accessibility"() { return require("../../index"); @@ -15,7 +15,7 @@ const recommended = [ } }, { - name: 'vuejs-accessibility:setup:with-files-rules-and-parser', + name: "vuejs-accessibility:setup:with-files-rules-and-parser", files: ["*.vue", "**/*.vue"], plugins: { get "vuejs-accessibility"() { diff --git a/src/utils/defineTemplateBodyVisitor.ts b/src/utils/defineTemplateBodyVisitor.ts index cb46973f..cfe38d1b 100644 --- a/src/utils/defineTemplateBodyVisitor.ts +++ b/src/utils/defineTemplateBodyVisitor.ts @@ -39,7 +39,9 @@ function defineTemplateBodyVisitor( */ function getParserServices(context: Rule.RuleContext) { // @ts-expect-error TODO: remove this when eslint v8 support is dropped - return context.sourceCode ? context.sourceCode.parserServices : context.parserServices + return context.sourceCode + ? context.sourceCode.parserServices + : context.parserServices; } export default defineTemplateBodyVisitor; From 138b36b7262e99fa1735f8943672144d6e47a902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Hoyer?= Date: Thu, 18 Apr 2024 12:46:57 -0300 Subject: [PATCH 11/11] :bug: Prettier broke @ts-expect-error --- src/utils/defineTemplateBodyVisitor.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/defineTemplateBodyVisitor.ts b/src/utils/defineTemplateBodyVisitor.ts index cfe38d1b..8e4b9502 100644 --- a/src/utils/defineTemplateBodyVisitor.ts +++ b/src/utils/defineTemplateBodyVisitor.ts @@ -39,9 +39,9 @@ function defineTemplateBodyVisitor( */ function getParserServices(context: Rule.RuleContext) { // @ts-expect-error TODO: remove this when eslint v8 support is dropped - return context.sourceCode - ? context.sourceCode.parserServices - : context.parserServices; + const legacy = context.sourceCode; + + return legacy ? legacy.parserServices : context.parserServices; } export default defineTemplateBodyVisitor;