diff --git a/.eslintrc.js b/.eslintrc.js index 99f3f5d3e41d..23e43d374c41 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,6 +26,7 @@ module.exports = { './tsconfig.eslint.json', './packages/*/tsconfig.json', './tests/integration/tsconfig.json', + './tools/tsconfig.json', /** * We are currently in the process of transitioning to nx's out of the box structure and * so need to manually specify converted packages' tsconfig.build.json and tsconfig.spec.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 143b0bdd3048..ef5d9f5ad3ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,9 @@ on: merge_group: env: + PRIMARY_ESLINT_VERSION: '^8.0.0' PRIMARY_NODE_VERSION: 18 + PRIMARY_TYPESCRIPT_VERSION: '~4.8.0' # Only set the read-write token if we are on the main branch NX_CLOUD_ACCESS_TOKEN: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && secrets.NX_CLOUD_ACCESS_TOKEN }} @@ -61,6 +63,7 @@ jobs: needs: [install] runs-on: ubuntu-latest strategy: + fail-fast: false matrix: lint-task: ['check-spelling', 'check-format', 'lint-markdown'] steps: @@ -80,6 +83,7 @@ jobs: needs: [build] runs-on: ubuntu-latest strategy: + fail-fast: false matrix: lint-task: ['lint', 'typecheck'] steps: @@ -119,8 +123,10 @@ jobs: needs: [build] runs-on: ubuntu-latest strategy: + fail-fast: false matrix: # just run on the oldest and latest supported versions and assume the intermediate versions are good + # unfortunately you can't reference environment variables in an array :( node-version: [14, 18] package: [ @@ -176,6 +182,104 @@ jobs: # Sadly 1 day is the minimum retention-days: 1 + unit_tests_ts_regression: + name: Run Unit Tests (TypeScript Version Regression Checks) + needs: [build] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + package: + # note that we don't regression test all packages here on purpose because most don't depend on TS directly. + ['eslint-plugin', 'scope-manager', 'type-utils', 'typescript-estree'] + + ts-version: + # unfortunately you can't reference environment variables in an array :( + [ + # lowest possible version + '4.2.4', + # somewhere in the middle for sanity check + '~4.5.5', + # highest possible version + '~4.8.2', + ] + env: + # Added the - at the end to function as a separator to improve readability in the PR comment from the Nx cloud app + NX_CLOUD_ENV_NAME: 'Node ${{ matrix.node-version }} -' + COLLECT_COVERAGE: false + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Install + uses: ./.github/actions/prepare-install + with: + node-version: ${{ env.PRIMARY_NODE_VERSION }} + - name: Build + uses: ./.github/actions/prepare-build + + - name: Install Specific TS Version + run: | + yarn ts-node ./tools/change-ts-version.ts ${{ matrix.ts-version }} + yarn --ignore-engines --ignore-scripts + + - name: Patch Packages + if: matrix.ts-version == env.PRIMARY_TYPESCRIPT_VERSION + run: | + yarn patch-package + + # we don't collect coverage for these tests on purpose + - name: Run unit tests for ${{ matrix.package }} + run: npx nx test ${{ matrix.package }} --coverage=false + env: + CI: true + + unit_tests_eslint_regression: + name: Run Unit Tests (ESLint Version Regression Checks) + needs: [build] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + package: + # note that we don't regression test all packages here on purpose because most don't depend on ESLint directly. + ['eslint-plugin', 'utils'] + eslint-version: + # unfortunately you can't reference environment variables in an array :( + [ + # lowest possible version + '6.0.0', + # somewhere in the middle for sanity check + '7.32.0', + # highest possible version + '^8.0.0', + ] + env: + # Added the - at the end to function as a separator to improve readability in the PR comment from the Nx cloud app + NX_CLOUD_ENV_NAME: 'Node ${{ matrix.node-version }} -' + COLLECT_COVERAGE: false + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Install + uses: ./.github/actions/prepare-install + with: + node-version: ${{ env.PRIMARY_NODE_VERSION }} + - name: Build + uses: ./.github/actions/prepare-build + + - name: Install Specific ESLint Version + run: yarn add -DW --ignore-engines --ignore-scripts eslint@${{ matrix.eslint-version }} + + # we don't collect coverage for these tests on purpose + - name: Run unit tests for ${{ matrix.package }} + run: npx nx test ${{ matrix.package }} --coverage=false + env: + CI: true + website_tests: permissions: contents: read # to fetch code (actions/checkout) diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index cd858c970d8e..902ac489e213 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -48,12 +48,14 @@ "@babel/parser": "*", "@microsoft/api-extractor": "^7.23.2", "@types/babel__core": "*", + "eslint": "*", "glob": "*", "jest-diff": "*", "jest-snapshot": "*", "jest-specific-snapshot": "*", "make-dir": "*", "pretty-format": "*", + "semver": "*", "typescript": "*" } } diff --git a/packages/ast-spec/src/declaration/ExportAllDeclaration/fixtures/assertion/config.json b/packages/ast-spec/src/declaration/ExportAllDeclaration/fixtures/assertion/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/ExportAllDeclaration/fixtures/assertion/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/ExportNamedDeclaration/fixtures/_error_/assertion/config.json b/packages/ast-spec/src/declaration/ExportNamedDeclaration/fixtures/_error_/assertion/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/ExportNamedDeclaration/fixtures/_error_/assertion/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/ImportDeclaration/fixtures/assertion/config.json b/packages/ast-spec/src/declaration/ImportDeclaration/fixtures/assertion/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/ImportDeclaration/fixtures/assertion/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/TSInterfaceDeclaration/fixtures/_error_/missing-id/config.json b/packages/ast-spec/src/declaration/TSInterfaceDeclaration/fixtures/_error_/missing-id/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/TSInterfaceDeclaration/fixtures/_error_/missing-id/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/TSInterfaceDeclaration/fixtures/_error_/non-identifier-name/config.json b/packages/ast-spec/src/declaration/TSInterfaceDeclaration/fixtures/_error_/non-identifier-name/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/TSInterfaceDeclaration/fixtures/_error_/non-identifier-name/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/_error_/module-invalid-id/config.json b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/_error_/module-invalid-id/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/_error_/module-invalid-id/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/_error_/namespace-invalid-id/config.json b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/_error_/namespace-invalid-id/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/_error_/namespace-invalid-id/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/declaration/TSTypeAliasDeclaration/fixtures/_error_/non-identifier-name/config.json b/packages/ast-spec/src/declaration/TSTypeAliasDeclaration/fixtures/_error_/non-identifier-name/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/declaration/TSTypeAliasDeclaration/fixtures/_error_/non-identifier-name/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-override-with-no-extends/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-override-with-no-extends/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-override-with-no-extends/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-complex/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-complex/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-complex/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-number/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-number/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-number/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-string/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-string/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-computed-string/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/key-private/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-private/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-private/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/key-string/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-string/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/key-string/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-override/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-override/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-override/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-private/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-private/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-private/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-protected/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-protected/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-protected/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-public/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-public/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-public/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-readonly/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-readonly/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-readonly/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-static/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-static/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-static/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/no-annotation-no-value/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/no-annotation-no-value/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/no-annotation-no-value/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/no-annotation-with-value/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/no-annotation-with-value/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/no-annotation-with-value/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/config.json b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/array-array/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/array-array/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/array-array/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/arrow-func-no-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/arrow-func-no-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/arrow-func-no-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/arrow-func-with-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/arrow-func-with-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/arrow-func-with-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/chained-satisfies/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/chained-satisfies/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/chained-satisfies/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/conditional-no-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/conditional-no-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/conditional-no-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/conditional-with-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/conditional-with-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/conditional-with-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-keyword/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-keyword/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-keyword/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-object-type/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-object-type/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-object-type/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-tuple-type/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-tuple-type/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/identifier-tuple-type/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/logical-no-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/logical-no-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/logical-no-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/logical-with-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/logical-with-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/logical-with-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/object-object-inner-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/object-object-inner-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/object-object-inner-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/object-object-outer-parentheses/config.json b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/object-object-outer-parentheses/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/expression/TSSatisfiesExpression/fixtures/object-object-outer-parentheses/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/abstract-class-with-override-property/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/abstract-class-with-override-property/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/abstract-class-with-override-property/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-with-import-assertions/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-with-import-assertions/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/_error_/export-with-import-assertions/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/abstract-class-with-override-method/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/abstract-class-with-override-method/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/abstract-class-with-override-method/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-static-blocks/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-static-blocks/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-static-blocks/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-constructor-and-parameter-property-with-modifiers/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-constructor-and-parameter-property-with-modifiers/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-constructor-and-parameter-property-with-modifiers/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-constructor-and-parameter-proptery-with-override-modifier/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-constructor-and-parameter-proptery-with-override-modifier/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-constructor-and-parameter-proptery-with-override-modifier/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-override-method/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-override-method/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-override-method/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-override-property/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-override-property/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/class-with-override-property/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-all-with-import-assertions/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-all-with-import-assertions/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/export-all-with-import-assertions/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/import-with-import-assertions/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/import-with-import-assertions/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/import-with-import-assertions/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/private-fields-in-in/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/private-fields-in-in/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/private-fields-in-in/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-only-export-specifiers/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-only-export-specifiers/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-only-export-specifiers/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-only-import-specifiers/config.json b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-only-import-specifiers/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/basics/fixtures/type-only-import-specifiers/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/expressions/fixtures/_error_/instantiation-expression/config.json b/packages/ast-spec/src/legacy-fixtures/expressions/fixtures/_error_/instantiation-expression/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/expressions/fixtures/_error_/instantiation-expression/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/conditional-infer-with-constraint/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/conditional-infer-with-constraint/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/conditional-infer-with-constraint/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/interface-with-accessors/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/interface-with-accessors/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/interface-with-accessors/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/object-literal-type-with-accessors/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/object-literal-type-with-accessors/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/object-literal-type-with-accessors/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in-and-out/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in-and-out/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in-and-out/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in-out/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in-out/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in-out/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-in/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-out/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-out/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/optional-variance-out/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/src/legacy-fixtures/types/fixtures/typeof-with-type-parameters/config.json b/packages/ast-spec/src/legacy-fixtures/types/fixtures/typeof-with-type-parameters/config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/ast-spec/src/legacy-fixtures/types/fixtures/typeof-with-type-parameters/config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/ast-spec/tests/fixtures.test.ts b/packages/ast-spec/tests/fixtures.test.ts index df70fe613eb6..ed7fcc03a77d 100644 --- a/packages/ast-spec/tests/fixtures.test.ts +++ b/packages/ast-spec/tests/fixtures.test.ts @@ -1,7 +1,10 @@ +import { ESLint } from 'eslint'; import fs from 'fs'; import glob from 'glob'; import makeDir from 'make-dir'; import path from 'path'; +import * as semver from 'semver'; +import * as ts from 'typescript'; import { parseBabel } from './util/parsers/babel'; import type { @@ -44,8 +47,37 @@ const ERROR_FIXTURES: readonly string[] = glob.sync( `${SRC_DIR}/**/fixtures/_error_/*/fixture.{ts,tsx}`, ); -const FIXTURES: readonly Fixture[] = [...VALID_FIXTURES, ...ERROR_FIXTURES].map( - absolute => { +function loadConfig(configPath: string): ASTFixtureConfig { + try { + return require(configPath).default; + } catch { + return {}; + } +} + +function versionsSemverExcluded( + versions: ASTFixtureVersionsConfig | undefined, +): boolean { + if (!versions) { + return false; + } + + if (versions.eslint && !semver.satisfies(ESLint.version, versions.eslint)) { + return true; + } + + if ( + versions.typescript && + !semver.satisfies(ts.version, versions.typescript) + ) { + return true; + } + + return false; +} + +const FIXTURES: readonly Fixture[] = [...VALID_FIXTURES, ...ERROR_FIXTURES] + .map(absolute => { const relativeToSrc = path.relative(SRC_DIR, absolute); const { dir, ext } = path.parse(relativeToSrc); const segments = dir.split(path.sep).filter(s => s !== 'fixtures'); @@ -53,15 +85,15 @@ const FIXTURES: readonly Fixture[] = [...VALID_FIXTURES, ...ERROR_FIXTURES].map( const fixtureDir = path.join(SRC_DIR, dir); const configPath = path.join(fixtureDir, 'config' /* .ts */); const snapshotPath = path.join(fixtureDir, 'snapshots'); + const config = loadConfig(configPath); + + if (versionsSemverExcluded(config.versions)) { + return undefined; + } + return { absolute, - config: ((): ASTFixtureConfig => { - try { - return require(configPath).default; - } catch { - return {}; - } - })(), + config, ext, isError: absolute.includes('/_error_/'), isJSX: ext.endsWith('x'), @@ -99,8 +131,8 @@ const FIXTURES: readonly Fixture[] = [...VALID_FIXTURES, ...ERROR_FIXTURES].map( }, snapshotPath, }; - }, -); + }) + .filter((f): f is NonNullable => !!f); function hasErrorCode(e: unknown): e is { code: unknown } { return typeof e === 'object' && e != null && 'code' in e; diff --git a/packages/ast-spec/typings/global.d.ts b/packages/ast-spec/typings/global.d.ts index 4464c06fbcf7..ef475a6032c6 100644 --- a/packages/ast-spec/typings/global.d.ts +++ b/packages/ast-spec/typings/global.d.ts @@ -11,4 +11,17 @@ interface ASTFixtureConfig { * The value should be a description of why there isn't support - for example a github issue URL. */ readonly expectBabelToNotSupport?: string; + + /** + * Dependency version semver ranges to filter to in regression testing. + */ + readonly versions?: ASTFixtureVersionsConfig; +} + +/** + * Dependency version semver ranges to filter to in regression testing. + */ +interface ASTFixtureVersionsConfig { + readonly eslint?: string; + readonly typescript?: string; } diff --git a/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts index 2d41b0c3f981..47cf13cc4d49 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts @@ -7,9 +7,9 @@ const ruleTester = new RuleTester({ ecmaVersion: 2020, sourceType: 'module', }, - // type-only imports were first added in TS3.8 + // type-only imports were first added in TS3.8; TS4.5 added inline types dependencyConstraints: { - typescript: '3.8', + typescript: '4.5', }, }); diff --git a/packages/eslint-plugin/tests/rules/member-ordering.test.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts index 3305bebfa8cd..902c7aa0f614 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -5,6 +5,9 @@ import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', + dependencyConstraints: { + typescript: '4.9', + }, }); const grouped: RunTests = { diff --git a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts index 93b01ce6f333..f42d4a31139a 100644 --- a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts +++ b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts @@ -2801,6 +2801,9 @@ var a = 1 }, { code: 'export function foo(arg1: string): number;\nexport function foo(arg2: number) {\n return arg2;\n}', + dependencyConstraints: { + typescript: '4.5', + }, options: [ { blankLine: 'always', prev: '*', next: 'block-like' }, { blankLine: 'never', prev: '*', next: 'export' }, @@ -2808,6 +2811,9 @@ var a = 1 }, { code: 'function foo(arg1: string): number;\nfunction foo(arg2: number) {\n return arg2;\n}', + dependencyConstraints: { + typescript: '4.5', + }, options: [ { blankLine: 'always', prev: '*', next: 'block-like' }, { blankLine: 'never', prev: '*', next: 'function' }, diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index ceec8b2d5345..ef2b31f2af4f 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -44,12 +44,14 @@ "devDependencies": { "@types/glob": "*", "@typescript-eslint/typescript-estree": "5.53.0", + "eslint": "*", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", "prettier": "*", "pretty-format": "*", "rimraf": "*", + "semver": "*", "typescript": "*" }, "funding": { diff --git a/packages/scope-manager/tests/eslint-scope/references.test.ts b/packages/scope-manager/tests/eslint-scope/references.test.ts index 15ed88c9a1ef..05593ffe25b1 100644 --- a/packages/scope-manager/tests/eslint-scope/references.test.ts +++ b/packages/scope-manager/tests/eslint-scope/references.test.ts @@ -1,3 +1,6 @@ +import * as semver from 'semver'; +import * as ts from 'typescript'; + import { getRealVariables, parseAndAnalyze } from '../util'; describe('References:', () => { @@ -541,10 +544,11 @@ describe('References:', () => { ); }); - describe('When emitDecoratorMetadata is true', () => { - it('check type referenced by decorator metadata', () => { - const { scopeManager } = parseAndAnalyze( - ` + if (semver.satisfies(ts.version, '>=4.9')) { + describe('When emitDecoratorMetadata is true', () => { + it('check type referenced by decorator metadata', () => { + const { scopeManager } = parseAndAnalyze( + ` @deco class A { property: Type1; @@ -585,75 +589,78 @@ describe('References:', () => { foo(): TypeC; } `, - { - emitDecoratorMetadata: true, - }, - ); - - const classAScope = scopeManager.globalScope!.childScopes[0]; - const propertyTypeRef = classAScope.references[2]; - expect(propertyTypeRef.identifier.name).toBe('a'); - expect(propertyTypeRef.isTypeReference).toBe(true); - expect(propertyTypeRef.isValueReference).toBe(true); - - const setterParamTypeRef = classAScope.childScopes[0].references[0]; - expect(setterParamTypeRef.identifier.name).toBe('SetterType'); - expect(setterParamTypeRef.isTypeReference).toBe(true); - expect(setterParamTypeRef.isValueReference).toBe(false); - - const constructorParamTypeRef = classAScope.childScopes[1].references[0]; - expect(constructorParamTypeRef.identifier.name).toBe('b'); - expect(constructorParamTypeRef.isTypeReference).toBe(true); - expect(constructorParamTypeRef.isValueReference).toBe(true); - - const methodParamTypeRef = classAScope.childScopes[2].references[0]; - expect(methodParamTypeRef.identifier.name).toBe('Type2'); - expect(methodParamTypeRef.isTypeReference).toBe(true); - expect(methodParamTypeRef.isValueReference).toBe(true); - const methodParamTypeRef0 = classAScope.childScopes[2].references[2]; - expect(methodParamTypeRef0.identifier.name).toBe('Type0'); - expect(methodParamTypeRef0.isTypeReference).toBe(true); - expect(methodParamTypeRef0.isValueReference).toBe(true); - - const methodParamTypeRef1 = classAScope.childScopes[3].references[0]; - expect(methodParamTypeRef1.identifier.name).toBe('Type3'); - expect(methodParamTypeRef1.isTypeReference).toBe(true); - expect(methodParamTypeRef1.isValueReference).toBe(true); - - const methodReturnTypeRef = classAScope.childScopes[4].references[0]; - expect(methodReturnTypeRef.identifier.name).toBe('Type4'); - expect(methodReturnTypeRef.isTypeReference).toBe(true); - expect(methodReturnTypeRef.isValueReference).toBe(true); - - const setterParamTypeRef1 = classAScope.childScopes[5].references[0]; - expect(setterParamTypeRef1.identifier.name).toBe('Type5'); - expect(setterParamTypeRef1.isTypeReference).toBe(true); - expect(setterParamTypeRef1.isValueReference).toBe(true); - - const setterParamTypeRef2 = classAScope.childScopes[6].references[0]; - expect(setterParamTypeRef2.identifier.name).toBe('Type6'); - expect(setterParamTypeRef2.isTypeReference).toBe(true); - expect(setterParamTypeRef2.isValueReference).toBe(true); - - const classBScope = scopeManager.globalScope!.childScopes[1]; - - const constructorParamTypeRef1 = classBScope.childScopes[0].references[0]; - expect(constructorParamTypeRef1.identifier.name).toBe('c'); - expect(constructorParamTypeRef1.isTypeReference).toBe(true); - expect(constructorParamTypeRef1.isValueReference).toBe(true); - - const setterParamTypeRef3 = classBScope.childScopes[1].references[0]; - // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum - expect(setterParamTypeRef3.identifier.name).toBe('Type'); - expect(setterParamTypeRef3.isTypeReference).toBe(true); - expect(setterParamTypeRef3.isValueReference).toBe(false); - - const classCScope = scopeManager.globalScope!.childScopes[2]; - - const methodReturnTypeRef1 = classCScope.childScopes[0].references[0]; - expect(methodReturnTypeRef1.identifier.name).toBe('TypeC'); - expect(methodReturnTypeRef1.isTypeReference).toBe(true); - expect(methodReturnTypeRef1.isValueReference).toBe(false); + { + emitDecoratorMetadata: true, + }, + ); + + const classAScope = scopeManager.globalScope!.childScopes[0]; + const propertyTypeRef = classAScope.references[2]; + expect(propertyTypeRef.identifier.name).toBe('a'); + expect(propertyTypeRef.isTypeReference).toBe(true); + expect(propertyTypeRef.isValueReference).toBe(true); + + const setterParamTypeRef = classAScope.childScopes[0].references[0]; + expect(setterParamTypeRef.identifier.name).toBe('SetterType'); + expect(setterParamTypeRef.isTypeReference).toBe(true); + expect(setterParamTypeRef.isValueReference).toBe(false); + + const constructorParamTypeRef = + classAScope.childScopes[1].references[0]; + expect(constructorParamTypeRef.identifier.name).toBe('b'); + expect(constructorParamTypeRef.isTypeReference).toBe(true); + expect(constructorParamTypeRef.isValueReference).toBe(true); + + const methodParamTypeRef = classAScope.childScopes[2].references[0]; + expect(methodParamTypeRef.identifier.name).toBe('Type2'); + expect(methodParamTypeRef.isTypeReference).toBe(true); + expect(methodParamTypeRef.isValueReference).toBe(true); + const methodParamTypeRef0 = classAScope.childScopes[2].references[2]; + expect(methodParamTypeRef0.identifier.name).toBe('Type0'); + expect(methodParamTypeRef0.isTypeReference).toBe(true); + expect(methodParamTypeRef0.isValueReference).toBe(true); + + const methodParamTypeRef1 = classAScope.childScopes[3].references[0]; + expect(methodParamTypeRef1.identifier.name).toBe('Type3'); + expect(methodParamTypeRef1.isTypeReference).toBe(true); + expect(methodParamTypeRef1.isValueReference).toBe(true); + + const methodReturnTypeRef = classAScope.childScopes[4].references[0]; + expect(methodReturnTypeRef.identifier.name).toBe('Type4'); + expect(methodReturnTypeRef.isTypeReference).toBe(true); + expect(methodReturnTypeRef.isValueReference).toBe(true); + + const setterParamTypeRef1 = classAScope.childScopes[5].references[0]; + expect(setterParamTypeRef1.identifier.name).toBe('Type5'); + expect(setterParamTypeRef1.isTypeReference).toBe(true); + expect(setterParamTypeRef1.isValueReference).toBe(true); + + const setterParamTypeRef2 = classAScope.childScopes[6].references[0]; + expect(setterParamTypeRef2.identifier.name).toBe('Type6'); + expect(setterParamTypeRef2.isTypeReference).toBe(true); + expect(setterParamTypeRef2.isValueReference).toBe(true); + + const classBScope = scopeManager.globalScope!.childScopes[1]; + + const constructorParamTypeRef1 = + classBScope.childScopes[0].references[0]; + expect(constructorParamTypeRef1.identifier.name).toBe('c'); + expect(constructorParamTypeRef1.isTypeReference).toBe(true); + expect(constructorParamTypeRef1.isValueReference).toBe(true); + + const setterParamTypeRef3 = classBScope.childScopes[1].references[0]; + // eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum + expect(setterParamTypeRef3.identifier.name).toBe('Type'); + expect(setterParamTypeRef3.isTypeReference).toBe(true); + expect(setterParamTypeRef3.isValueReference).toBe(false); + + const classCScope = scopeManager.globalScope!.childScopes[2]; + + const methodReturnTypeRef1 = classCScope.childScopes[0].references[0]; + expect(methodReturnTypeRef1.identifier.name).toBe('TypeC'); + expect(methodReturnTypeRef1.isTypeReference).toBe(true); + expect(methodReturnTypeRef1.isValueReference).toBe(false); + }); }); - }); + } }); diff --git a/packages/scope-manager/tests/fixtures.test.ts b/packages/scope-manager/tests/fixtures.test.ts index fa86c1544c7b..9a963e872d3e 100644 --- a/packages/scope-manager/tests/fixtures.test.ts +++ b/packages/scope-manager/tests/fixtures.test.ts @@ -1,7 +1,10 @@ +import { ESLint } from 'eslint'; import fs from 'fs'; import glob from 'glob'; import makeDir from 'make-dir'; import path from 'path'; +import * as semver from 'semver'; +import * as ts from 'typescript'; import type { AnalyzeOptions } from './util'; import { parseAndAnalyze } from './util'; @@ -25,8 +28,10 @@ const fixtures = glob const { name, dir, ext } = path.parse(relative); const segments = dir.split(path.sep); const snapshotPath = path.join(FIXTURES_DIR, dir); + const configPath = path.join(snapshotPath, `${name}.config.json`); return { absolute, + configPath: fs.existsSync(configPath) ? configPath : undefined, name, ext, segments, @@ -51,6 +56,27 @@ const ALLOWED_OPTIONS: Map = new Map< ['emitDecoratorMetadata', ['boolean']], ]); +interface FixtureConfig { + eslint?: string; + typescript?: string; +} + +function shouldSkipFixture(configPath: string): boolean { + const config = JSON.parse( + fs.readFileSync(configPath, 'utf8').toString(), + ) as FixtureConfig; + + if (config.eslint && !semver.satisfies(ESLint.version, config.eslint)) { + return true; + } + + if (config.typescript && !semver.satisfies(ts.version, config.typescript)) { + return true; + } + + return false; +} + function nestDescribe( fixture: typeof fixtures[number], segments = fixture.segments, @@ -164,7 +190,10 @@ function nestDescribe( } }; - if ([...fixture.segments, fixture.name].join(path.sep) === ONLY) { + if (fixture.configPath && shouldSkipFixture(fixture.configPath)) { + // eslint-disable-next-line jest/no-disabled-tests + it.skip(fixture.name, test); + } else if ([...fixture.segments, fixture.name].join(path.sep) === ONLY) { // eslint-disable-next-line jest/no-focused-tests it.only(fixture.name, test); } else { diff --git a/packages/scope-manager/tests/fixtures/call-expression/call-expression.config.json b/packages/scope-manager/tests/fixtures/call-expression/call-expression.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/call-expression/call-expression.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/abstract-accessor-property.config.json b/packages/scope-manager/tests/fixtures/class/declaration/abstract-accessor-property.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/abstract-accessor-property.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/accessor-property-type-annotation.config.json b/packages/scope-manager/tests/fixtures/class/declaration/accessor-property-type-annotation.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/accessor-property-type-annotation.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/accessor-property.config.json b/packages/scope-manager/tests/fixtures/class/declaration/accessor-property.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/accessor-property.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/private-identifier.config.json b/packages/scope-manager/tests/fixtures/class/declaration/private-identifier.config.json new file mode 100644 index 000000000000..4e3aee9f144f --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/private-identifier.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.3" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/static-block.config.json b/packages/scope-manager/tests/fixtures/class/declaration/static-block.config.json new file mode 100644 index 000000000000..3bc2566a3010 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/static-block.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.4" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/static-external-ref.config.json b/packages/scope-manager/tests/fixtures/class/declaration/static-external-ref.config.json new file mode 100644 index 000000000000..3bc2566a3010 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/static-external-ref.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.4" +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/static-with-constructor.config.json b/packages/scope-manager/tests/fixtures/class/declaration/static-with-constructor.config.json new file mode 100644 index 000000000000..3bc2566a3010 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/static-with-constructor.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.4" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/accessor-deco.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/accessor-deco.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/accessor-deco.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/method-deco.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/method-deco.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/method-deco.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/method-return-generic.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/method-return-generic.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/method-return-generic.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-both.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-both.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-both.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-inner.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-inner.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-inner.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-outer.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-outer.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/nested-class-outer.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/parameters-deco.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/parameters-deco.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/parameters-deco.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/emit-metadata/property-deco.config.json b/packages/scope-manager/tests/fixtures/class/emit-metadata/property-deco.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/emit-metadata/property-deco.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/class/expression/private-identifier.config.json b/packages/scope-manager/tests/fixtures/class/expression/private-identifier.config.json new file mode 100644 index 000000000000..4e3aee9f144f --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/expression/private-identifier.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.3" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/accessor.config.json b/packages/scope-manager/tests/fixtures/decorators/accessor.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/accessor.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/class-deco-with-object-param.config.json b/packages/scope-manager/tests/fixtures/decorators/class-deco-with-object-param.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/class-deco-with-object-param.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/class-property.config.json b/packages/scope-manager/tests/fixtures/decorators/class-property.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/class-property.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/class.config.json b/packages/scope-manager/tests/fixtures/decorators/class.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/class.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/method.config.json b/packages/scope-manager/tests/fixtures/decorators/method.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/method.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/parameter-property.config.json b/packages/scope-manager/tests/fixtures/decorators/parameter-property.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/parameter-property.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/parameter.config.json b/packages/scope-manager/tests/fixtures/decorators/parameter.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/parameter.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/decorators/typeof-this.config.json b/packages/scope-manager/tests/fixtures/decorators/typeof-this.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/decorators/typeof-this.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/export/type-inline.config.json b/packages/scope-manager/tests/fixtures/export/type-inline.config.json new file mode 100644 index 000000000000..4e3daea2fc6d --- /dev/null +++ b/packages/scope-manager/tests/fixtures/export/type-inline.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.5" +} diff --git a/packages/scope-manager/tests/fixtures/import/type-inline-value.config.json b/packages/scope-manager/tests/fixtures/import/type-inline-value.config.json new file mode 100644 index 000000000000..4e3daea2fc6d --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-inline-value.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.5" +} diff --git a/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.config.json b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.config.json b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/type-assertion/satisfies.config.json b/packages/scope-manager/tests/fixtures/type-assertion/satisfies.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-assertion/satisfies.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/type-declaration/infer-type-constraint.config.json b/packages/scope-manager/tests/fixtures/type-declaration/infer-type-constraint.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-declaration/infer-type-constraint.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/scope-manager/tests/fixtures/type-declaration/type-query-with-parameters.config.json b/packages/scope-manager/tests/fixtures/type-declaration/type-query-with-parameters.config.json new file mode 100644 index 000000000000..e475530972bd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/type-declaration/type-query-with-parameters.config.json @@ -0,0 +1,3 @@ +{ + "typescript": ">=4.9" +} diff --git a/packages/typescript-estree/tests/lib/convert.test.ts b/packages/typescript-estree/tests/lib/convert.test.ts index fb3ac3f63139..55b44dad2eee 100644 --- a/packages/typescript-estree/tests/lib/convert.test.ts +++ b/packages/typescript-estree/tests/lib/convert.test.ts @@ -1,4 +1,5 @@ import { AST_NODE_TYPES } from '@typescript-eslint/types'; +import * as semver from 'semver'; import * as ts from 'typescript'; import type { TSNode } from '../../src'; @@ -76,6 +77,9 @@ describe('convert', () => { }); it('deeplyCopy should convert array of nodes', () => { + if (!semver.satisfies(ts.version, '>=4.7')) { + return; + } const ast = convertCode('new foo()'); const instance = new Converter(ast, { diff --git a/packages/typescript-estree/tests/lib/semantic-diagnostics-enabled.test.ts b/packages/typescript-estree/tests/lib/semantic-diagnostics-enabled.test.ts index b87abc896cbe..5f675ba7fafa 100644 --- a/packages/typescript-estree/tests/lib/semantic-diagnostics-enabled.test.ts +++ b/packages/typescript-estree/tests/lib/semantic-diagnostics-enabled.test.ts @@ -1,6 +1,8 @@ -import { readFileSync } from 'fs'; +import * as fs from 'fs'; import glob from 'glob'; import path from 'path'; +import * as semver from 'semver'; +import * as ts from 'typescript'; import * as parser from '../../src'; import { formatSnapshotName, isJSXFileType } from '../../tools/test-utils'; @@ -12,15 +14,34 @@ import { serializer } from '../../tools/tserror-serializer'; */ const FIXTURES_DIR = path.join(__dirname, '../../../ast-spec/src'); -const testFiles = glob.sync('**/fixture.ts', { +const FILE_NAME_START = 'fixture.ts'; + +const testFiles = glob.sync(`**/${FILE_NAME_START}`, { cwd: FIXTURES_DIR, }); expect.addSnapshotSerializer(serializer); +interface FixtureVersionConfig { + readonly typescript: string; +} + describe('Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled', () => { testFiles.forEach(filename => { - const code = readFileSync(path.join(FIXTURES_DIR, filename), 'utf8'); + const configPath = path.join( + FIXTURES_DIR, + filename.replace(FILE_NAME_START, 'config.json'), + ); + if (fs.existsSync(configPath)) { + const config = JSON.parse( + fs.readFileSync(configPath).toString(), + ) as FixtureVersionConfig; + if (!semver.satisfies(ts.version, config.typescript)) { + return; + } + } + + const code = fs.readFileSync(path.join(FIXTURES_DIR, filename), 'utf8'); const fileExtension = path.extname(filename); const config: parser.TSESTreeOptions = { loc: true, diff --git a/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts b/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts index 57ac48b38c18..5c8e672d9e21 100644 --- a/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts +++ b/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts @@ -1,5 +1,7 @@ import * as parser from '@typescript-eslint/parser'; +import { ESLint } from 'eslint'; import eslintPackageJson from 'eslint/package.json'; +import semver from 'semver'; import * as dependencyConstraintsModule from '../../../src/eslint-utils/rule-tester/dependencyConstraints'; import { RuleTester } from '../../../src/eslint-utils/rule-tester/RuleTester'; @@ -100,50 +102,54 @@ const NOOP_RULE: RuleModule<'error', []> = { }; describe('RuleTester', () => { - it('automatically sets the filename for tests', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: '/some/path/that/totally/exists/', - }, - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'invalid tests should work as well', - errors: [], - }, - ], - valid: [ - 'string based valid test', - { - code: 'object based valid test', - }, - { - code: "explicit filename shouldn't be overwritten", - filename: '/set/in/the/test.ts', + if ( + 'version' in (ESLint as {}) && + semver.satisfies((ESLint as { version: string }).version, '>=8') + ) { + it('automatically sets the filename for tests', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: '/some/path/that/totally/exists/', }, - { - code: 'jsx should have the correct filename', - parserOptions: { - ecmaFeatures: { - jsx: true, + }); + + ruleTester.run('my-rule', NOOP_RULE, { + invalid: [ + { + code: 'invalid tests should work as well', + errors: [], + }, + ], + valid: [ + 'string based valid test', + { + code: 'object based valid test', + }, + { + code: "explicit filename shouldn't be overwritten", + filename: '/set/in/the/test.ts', + }, + { + code: 'jsx should have the correct filename', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, }, }, - }, - { - code: 'type-aware parser options should override the constructor config', - parserOptions: { - project: 'tsconfig.test-specific.json', - tsconfigRootDir: '/set/in/the/test/', + { + code: 'type-aware parser options should override the constructor config', + parserOptions: { + project: 'tsconfig.test-specific.json', + tsconfigRootDir: '/set/in/the/test/', + }, }, - }, - ], - }); + ], + }); - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` + expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` { "invalid": [ { @@ -185,74 +191,55 @@ describe('RuleTester', () => { ], } `); - }); - - it('schedules the parser caches to be cleared afterAll', () => { - // it should schedule the afterAll - expect(mockedAfterAll).toHaveBeenCalledTimes(0); - const _ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: '/some/path/that/totally/exists/', - }, - }); - expect(mockedAfterAll).toHaveBeenCalledTimes(1); - - // the provided callback should clear the caches - const callback = mockedAfterAll.mock.calls[0][0]; - expect(typeof callback).toBe('function'); - expect(mockedParserClearCaches).not.toHaveBeenCalled(); - callback(); - expect(mockedParserClearCaches).toHaveBeenCalledTimes(1); - }); - - it('throws an error if you attempt to set the parser to ts-eslint at the test level', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: '/some/path/that/totally/exists/', - }, }); - expect(() => - ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - { - code: 'object based valid test', - parser: '@typescript-eslint/parser', - }, - ], - - invalid: [], - }), - ).toThrowErrorMatchingInlineSnapshot( - `"Do not set the parser at the test level unless you want to use a parser other than @typescript-eslint/parser"`, - ); - }); + it('schedules the parser caches to be cleared afterAll', () => { + // it should schedule the afterAll + expect(mockedAfterAll).toHaveBeenCalledTimes(0); + const _ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: '/some/path/that/totally/exists/', + }, + }); + expect(mockedAfterAll).toHaveBeenCalledTimes(1); + + // the provided callback should clear the caches + const callback = mockedAfterAll.mock.calls[0][0]; + expect(typeof callback).toBe('function'); + expect(mockedParserClearCaches).not.toHaveBeenCalled(); + callback(); + expect(mockedParserClearCaches).toHaveBeenCalledTimes(1); + }); - describe('checks dependencies as specified', () => { - it('does not check dependencies if there are no dependency constraints', () => { + it('throws an error if you attempt to set the parser to ts-eslint at the test level', () => { const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: '/some/path/that/totally/exists/', + }, }); - ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - 'const x = 1;', - { code: 'const x = 2;' }, - // empty object is ignored - { code: 'const x = 3;', dependencyConstraints: {} }, - ], - invalid: [], - }); + expect(() => + ruleTester.run('my-rule', NOOP_RULE, { + valid: [ + { + code: 'object based valid test', + parser: '@typescript-eslint/parser', + }, + ], - expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); + invalid: [], + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Do not set the parser at the test level unless you want to use a parser other than @typescript-eslint/parser"`, + ); }); - describe('does not check dependencies if is an "only" manually set', () => { - it('in the valid section', () => { + describe('checks dependencies as specified', () => { + it('does not check dependencies if there are no dependency constraints', () => { const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); @@ -261,17 +248,8 @@ describe('RuleTester', () => { valid: [ 'const x = 1;', { code: 'const x = 2;' }, - { - code: 'const x = 3;', - // eslint-disable-next-line eslint-plugin/no-only-tests -- intentional only for test purposes - only: true, - }, - { - code: 'const x = 4;', - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, + // empty object is ignored + { code: 'const x = 3;', dependencyConstraints: {} }, ], invalid: [], }); @@ -279,88 +257,116 @@ describe('RuleTester', () => { expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); }); - it('in the invalid section', () => { + describe('does not check dependencies if is an "only" manually set', () => { + it('in the valid section', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + }); + + ruleTester.run('my-rule', NOOP_RULE, { + valid: [ + 'const x = 1;', + { code: 'const x = 2;' }, + { + code: 'const x = 3;', + // eslint-disable-next-line eslint-plugin/no-only-tests -- intentional only for test purposes + only: true, + }, + { + code: 'const x = 4;', + dependencyConstraints: { + 'totally-real-dependency': '999', + }, + }, + ], + invalid: [], + }); + + expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); + }); + + it('in the invalid section', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + }); + + ruleTester.run('my-rule', NOOP_RULE, { + valid: [ + 'const x = 1;', + { code: 'const x = 2;' }, + { + code: 'const x = 4;', + dependencyConstraints: { + 'totally-real-dependency': '999', + }, + }, + ], + invalid: [ + { + code: 'const x = 3;', + errors: [], + // eslint-disable-next-line eslint-plugin/no-only-tests -- intentional only for test purposes + only: true, + }, + ], + }); + + expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); + }); + }); + + it('correctly handles string-based at-least', () => { const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - 'const x = 1;', - { code: 'const x = 2;' }, + invalid: [ { - code: 'const x = 4;', + code: 'failing - major', + errors: [], dependencyConstraints: { 'totally-real-dependency': '999', }, }, - ], - invalid: [ { - code: 'const x = 3;', + code: 'failing - major.minor', errors: [], - // eslint-disable-next-line eslint-plugin/no-only-tests -- intentional only for test purposes - only: true, - }, - ], - }); - - expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); - }); - }); - - it('correctly handles string-based at-least', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing - major', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, - { - code: 'failing - major.minor', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999.0', + dependencyConstraints: { + 'totally-real-dependency': '999.0', + }, }, - }, - { - code: 'failing - major.minor.patch', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999.0.0', + { + code: 'failing - major.minor.patch', + errors: [], + dependencyConstraints: { + 'totally-real-dependency': '999.0.0', + }, }, - }, - ], - valid: [ - { - code: 'passing - major', - dependencyConstraints: { - 'totally-real-dependency': '10', + ], + valid: [ + { + code: 'passing - major', + dependencyConstraints: { + 'totally-real-dependency': '10', + }, }, - }, - { - code: 'passing - major.minor', - dependencyConstraints: { - 'totally-real-dependency': '10.0', + { + code: 'passing - major.minor', + dependencyConstraints: { + 'totally-real-dependency': '10.0', + }, }, - }, - { - code: 'passing - major.minor.patch', - dependencyConstraints: { - 'totally-real-dependency': '10.0.0', + { + code: 'passing - major.minor.patch', + dependencyConstraints: { + 'totally-real-dependency': '10.0.0', + }, }, - }, - ], - }); + ], + }); - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` + expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` { "invalid": [ { @@ -395,68 +401,68 @@ describe('RuleTester', () => { ], } `); - }); - - it('correctly handles object-based semver', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', }); - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing - major', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': { - range: '^999', + it('correctly handles object-based semver', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + }); + + ruleTester.run('my-rule', NOOP_RULE, { + invalid: [ + { + code: 'failing - major', + errors: [], + dependencyConstraints: { + 'totally-real-dependency': { + range: '^999', + }, }, }, - }, - { - code: 'failing - major.minor', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': { - range: '>=999.0', + { + code: 'failing - major.minor', + errors: [], + dependencyConstraints: { + 'totally-real-dependency': { + range: '>=999.0', + }, }, }, - }, - { - code: 'failing with options', - errors: [], - dependencyConstraints: { - 'totally-real-dependency-prerelease': { - range: '^10', - options: { - includePrerelease: false, + { + code: 'failing with options', + errors: [], + dependencyConstraints: { + 'totally-real-dependency-prerelease': { + range: '^10', + options: { + includePrerelease: false, + }, }, }, }, - }, - ], - valid: [ - { - code: 'passing - major', - dependencyConstraints: { - 'totally-real-dependency': { - range: '^10', + ], + valid: [ + { + code: 'passing - major', + dependencyConstraints: { + 'totally-real-dependency': { + range: '^10', + }, }, }, - }, - { - code: 'passing - major.minor', - dependencyConstraints: { - 'totally-real-dependency': { - range: '<999', + { + code: 'passing - major.minor', + dependencyConstraints: { + 'totally-real-dependency': { + range: '<999', + }, }, }, - }, - ], - }); + ], + }); - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` + expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` { "invalid": [ { @@ -487,51 +493,51 @@ describe('RuleTester', () => { ], } `); - }); - - it('tests without versions should always be run', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', }); - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'no constraints is always run', - errors: [], - }, - { - code: 'empty object is always run', - errors: [], - dependencyConstraints: {}, - }, - { - code: 'failing constraint', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '99999', + it('tests without versions should always be run', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + }); + + ruleTester.run('my-rule', NOOP_RULE, { + invalid: [ + { + code: 'no constraints is always run', + errors: [], }, - }, - ], - valid: [ - 'string based is always run', - { - code: 'no constraints is always run', - }, - { - code: 'empty object is always run', - dependencyConstraints: {}, - }, - { - code: 'passing constraint', - dependencyConstraints: { - 'totally-real-dependency': '10', + { + code: 'empty object is always run', + errors: [], + dependencyConstraints: {}, }, - }, - ], - }); + { + code: 'failing constraint', + errors: [], + dependencyConstraints: { + 'totally-real-dependency': '99999', + }, + }, + ], + valid: [ + 'string based is always run', + { + code: 'no constraints is always run', + }, + { + code: 'empty object is always run', + dependencyConstraints: {}, + }, + { + code: 'passing constraint', + dependencyConstraints: { + 'totally-real-dependency': '10', + }, + }, + ], + }); - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` + expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` { "invalid": [ { @@ -570,52 +576,52 @@ describe('RuleTester', () => { ], } `); - }); + }); - it('uses filter instead of "only" for old ESLint versions', () => { - // need it twice because ESLint internally fetches this value once :( - eslintVersionSpy.mockReturnValueOnce('1.0.0'); - eslintVersionSpy.mockReturnValueOnce('1.0.0'); + it('uses filter instead of "only" for old ESLint versions', () => { + // need it twice because ESLint internally fetches this value once :( + eslintVersionSpy.mockReturnValueOnce('1.0.0'); + eslintVersionSpy.mockReturnValueOnce('1.0.0'); - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + }); - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999', + ruleTester.run('my-rule', NOOP_RULE, { + invalid: [ + { + code: 'failing', + errors: [], + dependencyConstraints: { + 'totally-real-dependency': '999', + }, }, - }, - { - code: 'passing', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '10', + { + code: 'passing', + errors: [], + dependencyConstraints: { + 'totally-real-dependency': '10', + }, }, - }, - ], - valid: [ - 'always passing string test', - { - code: 'failing', - dependencyConstraints: { - 'totally-real-dependency': '999', + ], + valid: [ + 'always passing string test', + { + code: 'failing', + dependencyConstraints: { + 'totally-real-dependency': '999', + }, }, - }, - { - code: 'passing', - dependencyConstraints: { - 'totally-real-dependency': '10', + { + code: 'passing', + dependencyConstraints: { + 'totally-real-dependency': '10', + }, }, - }, - ], - }); + ], + }); - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` + expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` { "invalid": [ { @@ -645,35 +651,35 @@ describe('RuleTester', () => { ], } `); - }); - - describe('constructor constraints', () => { - it('skips all tests if a constructor constraint is not satisifed', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }); + }); - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing - major', - errors: [], - }, - ], - valid: [ - { - code: 'passing - major', + describe('constructor constraints', () => { + it('skips all tests if a constructor constraint is not satisifed', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + dependencyConstraints: { + 'totally-real-dependency': '999', }, - ], - }); + }); + + ruleTester.run('my-rule', NOOP_RULE, { + invalid: [ + { + code: 'failing - major', + errors: [], + }, + ], + valid: [ + { + code: 'passing - major', + }, + ], + }); - // trigger the describe block - expect(mockedDescribe.mock.calls.length).toBeGreaterThanOrEqual(1); - mockedDescribe.mock.lastCall?.[1](); - expect(mockedDescribe.mock.calls).toMatchInlineSnapshot(` + // trigger the describe block + expect(mockedDescribe.mock.calls.length).toBeGreaterThanOrEqual(1); + mockedDescribe.mock.lastCall?.[1](); + expect(mockedDescribe.mock.calls).toMatchInlineSnapshot(` [ [ "my-rule", @@ -681,40 +687,40 @@ describe('RuleTester', () => { ], ] `); - expect(mockedIt.mock.lastCall).toMatchInlineSnapshot(` + expect(mockedIt.mock.lastCall).toMatchInlineSnapshot(` [ "All tests skipped due to unsatisfied constructor dependency constraints", [Function], ] `); - }); - - it('does not skip all tests if a constructor constraint is satisifed', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - dependencyConstraints: { - 'totally-real-dependency': '10', - }, }); - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'valid', - errors: [], - }, - ], - valid: [ - { - code: 'valid', + it('does not skip all tests if a constructor constraint is satisifed', () => { + const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + dependencyConstraints: { + 'totally-real-dependency': '10', }, - ], - }); + }); - // trigger the describe block - expect(mockedDescribe.mock.calls.length).toBeGreaterThanOrEqual(1); - mockedDescribe.mock.lastCall?.[1](); - expect(mockedDescribe.mock.calls).toMatchInlineSnapshot(` + ruleTester.run('my-rule', NOOP_RULE, { + invalid: [ + { + code: 'valid', + errors: [], + }, + ], + valid: [ + { + code: 'valid', + }, + ], + }); + + // trigger the describe block + expect(mockedDescribe.mock.calls.length).toBeGreaterThanOrEqual(1); + mockedDescribe.mock.lastCall?.[1](); + expect(mockedDescribe.mock.calls).toMatchInlineSnapshot(` [ [ "my-rule", @@ -730,8 +736,13 @@ describe('RuleTester', () => { ], ] `); - // expect(mockedIt.mock.lastCall).toMatchInlineSnapshot(`undefined`); + // expect(mockedIt.mock.lastCall).toMatchInlineSnapshot(`undefined`); + }); }); }); - }); + } else { + it('exists', () => { + expect(RuleTester).toBeTruthy(); + }); + } }); diff --git a/packages/website-eslint/package.json b/packages/website-eslint/package.json index 1792b0c1b27b..6e9bb4d0db82 100644 --- a/packages/website-eslint/package.json +++ b/packages/website-eslint/package.json @@ -32,6 +32,6 @@ "eslint": "*", "rollup": "^2.75.4", "rollup-plugin-terser": "^7.0.2", - "semver": "^7.3.7" + "semver": "*" } } diff --git a/tools/change-ts-version.ts b/tools/change-ts-version.ts new file mode 100644 index 000000000000..feab7880214e --- /dev/null +++ b/tools/change-ts-version.ts @@ -0,0 +1,21 @@ +import fs from 'fs'; +import path from 'path'; +import semver from 'semver'; + +const packageJson = require('../package.json') as { + resolutions: Record; + devDependencies: Record; +}; + +const newVersion = semver.valid(semver.coerce(process.argv[2])); +if (newVersion == null) { + throw new Error('The first argument passed must be a valid semver'); +} + +packageJson.resolutions.typescript = newVersion; +packageJson.devDependencies.typescript = newVersion; + +fs.writeFileSync( + path.resolve(__dirname, '../package.json'), + JSON.stringify(packageJson, null, 2), +); diff --git a/tools/generate-contributors.ts b/tools/generate-contributors.ts index 103046721217..87b42a05dd42 100644 --- a/tools/generate-contributors.ts +++ b/tools/generate-contributors.ts @@ -21,7 +21,7 @@ interface Contributor { contributions: number; type: string; login?: string; - url?: string; + url: string; avatar_url?: string; html_url?: string; } diff --git a/tools/tsconfig.json b/tools/tsconfig.json new file mode 100644 index 000000000000..28a93cc86cbc --- /dev/null +++ b/tools/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "esModuleInterop": true, + "resolveJsonModule": true, + "rootDir": ".." + }, + "include": ["./*.ts"], + "references": [] +} diff --git a/yarn.lock b/yarn.lock index 33d570dc85b9..e38bbb329fb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12285,6 +12285,13 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" +semver@*, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@~7.3.0: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -12302,13 +12309,6 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@~7.3.0: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"