From 87d114f7214ee123d2fe5fc5a6a55a95aa2a891a Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 14 Aug 2024 15:31:52 +0200 Subject: [PATCH 1/2] ci: add eslint check on some jobs --- .github/workflows/ci.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d798ca109..ae3af6315 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,7 @@ jobs: flag-for-pinia: '--pinia' flag-for-vitest: '--vitest' flag-for-e2e: '--cypress' + flag-for-eslint: '--eslint' flag-for-devtools: '--devtools' - node-version: 18 @@ -76,6 +77,7 @@ jobs: flag-for-pinia: '--pinia' flag-for-vitest: '--vitest' flag-for-e2e: '--cypress' + flag-for-eslint: '--eslint' flag-for-devtools: '--devtools' - node-version: 20 @@ -86,6 +88,7 @@ jobs: flag-for-pinia: '--pinia' flag-for-vitest: '--vitest' flag-for-e2e: '--cypress' + flag-for-eslint: '--eslint' flag-for-devtools: '--devtools' - node-version: 22 @@ -96,11 +99,12 @@ jobs: flag-for-pinia: '--pinia' flag-for-vitest: '--vitest' flag-for-e2e: '--cypress' + flag-for-eslint: '--eslint' flag-for-devtools: '--devtools' runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.os == 'windows-latest' }} env: - FEATURE_FLAGS: ${{ matrix.flag-for-ts }} ${{ matrix.flag-for-jsx }} ${{ matrix.flag-for-router }} ${{ matrix.flag-for-pinia }} ${{ matrix.flag-for-vitest }} ${{ matrix.flag-for-e2e }} ${{matrix.flag-for-devtools}} + FEATURE_FLAGS: ${{ matrix.flag-for-ts }} ${{ matrix.flag-for-jsx }} ${{ matrix.flag-for-router }} ${{ matrix.flag-for-pinia }} ${{ matrix.flag-for-vitest }} ${{ matrix.flag-for-e2e }} ${{matrix.flag-for-eslint}} ${{matrix.flag-for-devtools}} # Sometimes the Linux runner can't verify Cypress in 30s CYPRESS_VERIFY_TIMEOUT: 60000 steps: @@ -189,3 +193,8 @@ jobs: name: Run e2e test script working-directory: ../sample-project run: pnpm test:e2e + + - if: ${{ contains(matrix.flag-for-eslint, '--') }} + name: Run lint script + working-directory: ../sample-project + run: pnpm lint --no-fix --max-warnings=0 From 461263989b80f56c7dc026fc67ef6f462e1f2c75 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 14 Aug 2024 15:53:51 +0200 Subject: [PATCH 2/2] test: add unit test for eslint configs The commit adds a unit test for the eslint configurations and properly formats our tests. --- .prettierignore | 2 + __test__/locale.spec.ts | 12 +++--- __test__/renderEslint.spec.ts | 56 ++++++++++++++++++++++++++ scripts/snapshot.mjs | 7 +++- utils/renderEslint.ts | 74 +++++++++++++++++++++-------------- 5 files changed, 114 insertions(+), 37 deletions(-) create mode 100644 __test__/renderEslint.spec.ts diff --git a/.prettierignore b/.prettierignore index 688151cd9..be18eeb0a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,6 +4,8 @@ pnpm-lock.yaml # https://github.com/prettier/prettier/issues/7884 **/*.spec.js **/*.spec.ts +# but let's format our unit tests +!__test__/**/*.spec.ts **/dist # https://github.com/prettier/prettier/issues/5246 **/*.html diff --git a/__test__/locale.spec.ts b/__test__/locale.spec.ts index 1ea0a1127..6e36d3b9b 100644 --- a/__test__/locale.spec.ts +++ b/__test__/locale.spec.ts @@ -6,23 +6,23 @@ import en from '../locales/en-US.json' function getKeys(obj: any, path = '', result: string[] = []) { for (let key in obj) { if (typeof obj[key] === 'object') { - getKeys(obj[key], path ? `${path}.${key}` : key, result); + getKeys(obj[key], path ? `${path}.${key}` : key, result) } else { - result.push(path ? `${path}.${key}` : key); + result.push(path ? `${path}.${key}` : key) } } - return result; + return result } const localesOtherThanEnglish = readdirSync(resolve(__dirname, '../locales')).filter((file) => { return file.endsWith('.json') && !file.startsWith('en-US') }) -const defaultKeys = getKeys(en); +const defaultKeys = getKeys(en) -describe("locale files should include all keys", () => { +describe('locale files should include all keys', () => { localesOtherThanEnglish.forEach((locale) => { it(`for ${locale}`, () => { expect(getKeys(require(`../locales/${locale}`))).toEqual(defaultKeys) }) }) -}) \ No newline at end of file +}) diff --git a/__test__/renderEslint.spec.ts b/__test__/renderEslint.spec.ts new file mode 100644 index 000000000..5c54e4e2d --- /dev/null +++ b/__test__/renderEslint.spec.ts @@ -0,0 +1,56 @@ +import { it, describe, expect } from 'vitest' +import { getAdditionalConfigAndDependencies } from '../utils/renderEslint' + +describe('renderEslint', () => { + it('should get additional dependencies and config with no test flags', () => { + const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({ + needsCypress: false, + needsCypressCT: false, + needsPlaywright: false + }) + expect(additionalConfig).toStrictEqual({}) + expect(additionalDependencies).toStrictEqual({}) + }) + + it('should get additional dependencies and config with for cypress', () => { + const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({ + needsCypress: true, + needsCypressCT: false, + needsPlaywright: false + }) + expect(additionalConfig.overrides[0].files).toStrictEqual([ + 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/support/**/*.{js,ts,jsx,tsx}' + ]) + expect(additionalConfig.overrides[0].extends).toStrictEqual(['plugin:cypress/recommended']) + expect(additionalDependencies['eslint-plugin-cypress']).not.toBeUndefined() + }) + + it('should get additional dependencies and config with for cypress with component testing', () => { + const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({ + needsCypress: true, + needsCypressCT: true, + needsPlaywright: false + }) + expect(additionalConfig.overrides[0].files).toStrictEqual([ + '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/support/**/*.{js,ts,jsx,tsx}' + ]) + expect(additionalConfig.overrides[0].extends).toStrictEqual(['plugin:cypress/recommended']) + expect(additionalDependencies['eslint-plugin-cypress']).not.toBeUndefined() + }) + + it('should get additional dependencies and config with for playwright', () => { + const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({ + needsCypress: false, + needsCypressCT: false, + needsPlaywright: true + }) + expect(additionalConfig.overrides[0].files).toStrictEqual([ + 'e2e/**/*.{test,spec}.{js,ts,jsx,tsx}' + ]) + expect(additionalConfig.overrides[0].extends).toStrictEqual(['plugin:playwright/recommended']) + expect(additionalDependencies['eslint-plugin-playwright']).not.toBeUndefined() + }) +}) diff --git a/scripts/snapshot.mjs b/scripts/snapshot.mjs index ea4c4ad18..b80da8e1e 100644 --- a/scripts/snapshot.mjs +++ b/scripts/snapshot.mjs @@ -54,7 +54,12 @@ function fullCombination(arr) { } let flagCombinations = fullCombination(featureFlags) -flagCombinations.push(['default'], ['devtools', 'router', 'pinia'], ['eslint'], ['eslint-with-prettier']) +flagCombinations.push( + ['default'], + ['devtools', 'router', 'pinia'], + ['eslint'], + ['eslint-with-prettier'] +) // `--with-tests` are equivalent of `--vitest --cypress` // Previously it means `--cypress` without `--vitest`. diff --git a/utils/renderEslint.ts b/utils/renderEslint.ts index ecb74ae67..ca48646a1 100644 --- a/utils/renderEslint.ts +++ b/utils/renderEslint.ts @@ -15,36 +15,11 @@ export default function renderEslint( rootDir, { needsTypeScript, needsCypress, needsCypressCT, needsPrettier, needsPlaywright } ) { - const additionalConfig: Linter.Config = {} - const additionalDependencies = {} - - if (needsCypress) { - additionalConfig.overrides = [ - { - files: needsCypressCT - ? [ - '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}', - 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', - 'cypress/support/**/*.{js,ts,jsx,tsx}' - ] - : ['cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', 'cypress/support/**/*.{js,ts,jsx,tsx}'], - extends: ['plugin:cypress/recommended'] - } - ] - - additionalDependencies['eslint-plugin-cypress'] = eslintDeps['eslint-plugin-cypress'] - } - - if (needsPlaywright) { - additionalConfig.overrides = [ - { - files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'], - extends: ['plugin:playwright/recommended'] - } - ] - - additionalDependencies['eslint-plugin-playwright'] = eslintDeps['eslint-plugin-playwright'] - } + const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({ + needsCypress, + needsCypressCT, + needsPlaywright + }) const { pkg, files } = createESLintConfig({ vueVersion: '3.x', @@ -86,3 +61,42 @@ export default function renderEslint( fs.writeFileSync(fullPath, content as string, 'utf-8') } } + +// visible for testing +export function getAdditionalConfigAndDependencies({ + needsCypress, + needsCypressCT, + needsPlaywright +}) { + const additionalConfig: Linter.Config = {} + const additionalDependencies = {} + + if (needsCypress) { + additionalConfig.overrides = [ + { + files: needsCypressCT + ? [ + '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/support/**/*.{js,ts,jsx,tsx}' + ] + : ['cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', 'cypress/support/**/*.{js,ts,jsx,tsx}'], + extends: ['plugin:cypress/recommended'] + } + ] + + additionalDependencies['eslint-plugin-cypress'] = eslintDeps['eslint-plugin-cypress'] + } + + if (needsPlaywright) { + additionalConfig.overrides = [ + { + files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'], + extends: ['plugin:playwright/recommended'] + } + ] + + additionalDependencies['eslint-plugin-playwright'] = eslintDeps['eslint-plugin-playwright'] + } + return { additionalConfig, additionalDependencies } +}