Repository: import-js/eslint-plugin-import
Pull request #2425 (2022-04-05 16:46:55)

Release 2.26.0


Patch:
diff --git a/.eslintrc b/.eslintrc
index 12fb8b7a..2cbfd59c 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -102,6 +102,16 @@
                 "es6": false,
             },
         },
+        {
+            "files": "resolvers/webpack/**",
+            "rules": {
+                "import/no-extraneous-dependencies": 1,
+                "no-console": 1,
+            },
+            "env": {
+                "es6": true,
+            },
+        },
         {
             "files": [
                 "resolvers/*/test/**/*",
@@ -127,5 +137,15 @@
                 "no-console": 1,
             },
         },
+        {
+            "files": "tests/**",
+            "env": {
+                "mocha": true,
+            },
+            "rules": {
+                "max-len": 0,
+                "import/default": 0,
+            },
+        },
     ],
 }
diff --git a/.github/workflows/node-4+.yml b/.github/workflows/node-4+.yml
index 3af06b3b..6762bf0b 100644
--- a/.github/workflows/node-4+.yml
+++ b/.github/workflows/node-4+.yml
@@ -34,6 +34,11 @@ jobs:
           - 3
           - 2
         include:
+          - node-version: 'lts/*'
+            eslint: 7
+            ts-parser: 4
+            env:
+              TS_PARSER: 4
           - node-version: 'lts/*'
             eslint: 7
             ts-parser: 3
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3894d312..18572d61 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,28 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 
 ## [Unreleased]
 
+## [2.26.0] - 2022-04-05
+
+### Added
+- [`no-named-default`, `no-default-export`, `prefer-default-export`, `no-named-export`, `export`, `named`, `namespace`, `no-unused-modules`]: support arbitrary module namespace names ([#2358], thanks [@sosukesuzuki])
+- [`no-dynamic-require`]: support dynamic import with espree ([#2371], thanks [@sosukesuzuki])
+- [`no-relative-packages`]: add fixer ([#2381], thanks [@forivall])
+
+### Fixed
+- [`default`]: `typescript-eslint-parser`: avoid a crash on exporting as namespace (thanks [@ljharb])
+- [`export`]/TypeScript: false positive for typescript namespace merging ([#1964], thanks [@magarcia])
+- [`no-duplicates`]: ignore duplicate modules in different TypeScript module declarations ([#2378], thanks [@remcohaszing])
+- [`no-unused-modules`]: avoid a crash when processing re-exports ([#2388], thanks [@ljharb])
+
+### Changed
+- [Tests] `no-nodejs-modules`: add tests for node protocol URL ([#2367], thanks [@sosukesuzuki])
+- [Tests] `default`, `no-anonymous-default-export`, `no-mutable-exports`, `no-named-as-default-member`, `no-named-as-default`: add tests for arbitrary module namespace names ([#2358], thanks [@sosukesuzuki])
+- [Docs] [`no-unresolved`]: Fix RegExp escaping in readme ([#2332], thanks [@stephtr])
+- [Refactor] `namespace`: try to improve performance ([#2340], thanks [@ljharb])
+- [Docs] make rule doc titles consistent ([#2393], thanks [@TheJaredWilcurt])
+- [Docs] `order`: TS code examples should use TS code blocks ([#2411], thanks [@MM25Zamanian])
+- [Docs] `no-unresolved`: fix link ([#2417], thanks [@kylemh])
+
 ## [2.25.4] - 2022-01-02
 
 ### Fixed
@@ -955,6 +977,16 @@ for info on changes for earlier releases.
 
 [`memo-parser`]: ./memo-parser/README.md
 
+[#2417]: https://github.com/import-js/eslint-plugin-import/pull/2417
+[#2411]: https://github.com/import-js/eslint-plugin-import/pull/2411
+[#2393]: https://github.com/import-js/eslint-plugin-import/pull/2393
+[#2388]: https://github.com/import-js/eslint-plugin-import/pull/2388
+[#2381]: https://github.com/import-js/eslint-plugin-import/pull/2381
+[#2378]: https://github.com/import-js/eslint-plugin-import/pull/2378
+[#2371]: https://github.com/import-js/eslint-plugin-import/pull/2371
+[#2367]: https://github.com/import-js/eslint-plugin-import/pull/2367
+[#2332]: https://github.com/import-js/eslint-plugin-import/pull/2332
+[#2358]: https://github.com/import-js/eslint-plugin-import/pull/2358
 [#2341]: https://github.com/import-js/eslint-plugin-import/pull/2341
 [#2334]: https://github.com/import-js/eslint-plugin-import/pull/2334
 [#2305]: https://github.com/import-js/eslint-plugin-import/pull/2305
@@ -1234,6 +1266,7 @@ for info on changes for earlier releases.
 [#211]: https://github.com/import-js/eslint-plugin-import/pull/211
 [#164]: https://github.com/import-js/eslint-plugin-import/pull/164
 [#157]: https://github.com/import-js/eslint-plugin-import/pull/157
+[#2340]: https://github.com/import-js/eslint-plugin-import/issues/2340
 [#2255]: https://github.com/import-js/eslint-plugin-import/issues/2255
 [#2210]: https://github.com/import-js/eslint-plugin-import/issues/2210
 [#2201]: https://github.com/import-js/eslint-plugin-import/issues/2201
@@ -1347,7 +1380,8 @@ for info on changes for earlier releases.
 [#119]: https://github.com/import-js/eslint-plugin-import/issues/119
 [#89]: https://github.com/import-js/eslint-plugin-import/issues/89
 
-[Unreleased]: https://github.com/import-js/eslint-plugin-import/compare/v2.25.4...HEAD
+[Unreleased]: https://github.com/import-js/eslint-plugin-import/compare/v2.26.0...HEAD
+[2.26.0]: https://github.com/import-js/eslint-plugin-import/compare/v2.25.4...v2.26.0
 [2.25.4]: https://github.com/import-js/eslint-plugin-import/compare/v2.25.3...v2.25.4
 [2.25.3]: https://github.com/import-js/eslint-plugin-import/compare/v2.25.2...v2.25.3
 [2.25.2]: https://github.com/import-js/eslint-plugin-import/compare/v2.25.1...v2.25.2
@@ -1542,6 +1576,7 @@ for info on changes for earlier releases.
 [@kmui2]: https://github.com/kmui2
 [@knpwrs]: https://github.com/knpwrs
 [@KostyaZgara]: https://github.com/KostyaZgara
+[@kylemh]: https://github.com/kylemh
 [@laysent]: https://github.com/laysent
 [@le0nik]: https://github.com/le0nik
 [@lemonmade]: https://github.com/lemonmade
@@ -1558,6 +1593,7 @@ for info on changes for earlier releases.
 [@ludofischer]: https://github.com/ludofischer
 [@lukeapage]: https://github.com/lukeapage
 [@lydell]: https://github.com/lydell
+[@magarcia]: https://github.com/magarcia
 [@Mairu]: https://github.com/Mairu
 [@malykhinvi]: https://github.com/malykhinvi
 [@manovotny]: https://github.com/manovotny
@@ -1618,9 +1654,11 @@ for info on changes for earlier releases.
 [@skyrpex]: https://github.com/skyrpex
 [@sompylasar]: https://github.com/sompylasar
 [@soryy708]: https://github.com/soryy708
+[@sosukesuzuki]: https://github.com/sosukesuzuki
 [@spalger]: https://github.com/spalger
 [@st-sloth]: https://github.com/st-sloth
 [@stekycz]: https://github.com/stekycz
+[@stephtr]: https://github.com/stephtr
 [@straub]: https://github.com/straub
 [@strawbrary]: https://github.com/strawbrary
 [@stropho]: https://github.com/stropho
@@ -1633,6 +1671,7 @@ for info on changes for earlier releases.
 [@Taranys]: https://github.com/Taranys
 [@taye]: https://github.com/taye
 [@TheCrueltySage]: https://github.com/TheCrueltySage
+[@TheJaredWilcurt]: https://github.com/TheJaredWilcurt
 [@tihonove]: https://github.com/tihonove
 [@timkraut]: https://github.com/timkraut
 [@tizmagik]: https://github.com/tizmagik
diff --git a/docs/rules/dynamic-import-chunkname.md b/docs/rules/dynamic-import-chunkname.md
index d29c06bb..6b43074f 100644
--- a/docs/rules/dynamic-import-chunkname.md
+++ b/docs/rules/dynamic-import-chunkname.md
@@ -1,4 +1,4 @@
-# dynamic imports require a leading comment with a webpackChunkName (dynamic-import-chunkname)
+# import/dynamic-import-chunkname
 
 This rule reports any dynamic imports without a webpackChunkName specified in a leading block comment in the proper format.
 
diff --git a/docs/rules/imports-first.md b/docs/rules/imports-first.md
index 7dadffa6..4b90f04e 100644
--- a/docs/rules/imports-first.md
+++ b/docs/rules/imports-first.md
@@ -1,3 +1,3 @@
-# imports-first
+# import/imports-first
 
 This rule was **deprecated** in eslint-plugin-import v2.0.0. Please use the corresponding rule [`first`](https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/first.md).
diff --git a/docs/rules/no-import-module-exports.md b/docs/rules/no-import-module-exports.md
index 8131fd5f..d658deb5 100644
--- a/docs/rules/no-import-module-exports.md
+++ b/docs/rules/no-import-module-exports.md
@@ -1,4 +1,4 @@
-# no-import-module-exports
+# import/no-import-module-exports
 
 Reports the use of import declarations with CommonJS exports in any module
 except for the [main module](https://docs.npmjs.com/files/package.json#main).
diff --git a/docs/rules/no-relative-packages.md b/docs/rules/no-relative-packages.md
index d5a06849..a989c12a 100644
--- a/docs/rules/no-relative-packages.md
+++ b/docs/rules/no-relative-packages.md
@@ -5,6 +5,7 @@ Use this rule to prevent importing packages through relative paths.
 It's useful in Yarn/Lerna workspaces, were it's possible to import a sibling
 package using `../package` relative path, while direct `package` is the correct one.
 
++(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule.
 
 ### Examples
 
diff --git a/docs/rules/no-unresolved.md b/docs/rules/no-unresolved.md
index 89d00b93..08522deb 100644
--- a/docs/rules/no-unresolved.md
+++ b/docs/rules/no-unresolved.md
@@ -60,7 +60,7 @@ This rule has its own ignore list, separate from [`import/ignore`]. This is beca
 To suppress errors from files that may not be properly resolved by your [resolver settings](../../README.md#resolver-plugins), you may add an `ignore` key with an array of `RegExp` pattern strings:
 
 ```js
-/*eslint import/no-unresolved: [2, { ignore: ['\.img$'] }]*/
+/*eslint import/no-unresolved: [2, { ignore: ['\\.img$'] }]*/
 
 import { x } from './mod' // may be reported, if not resolved to a module
 
@@ -98,7 +98,7 @@ If you're using a module bundler other than Node or Webpack, you may end up with
 
 ## Further Reading
 
-- [Resolver plugins](../../README.md#resolver-plugins)
+- [Resolver plugins](../../README.md#resolvers)
 - [Node resolver](https://npmjs.com/package/eslint-import-resolver-node) (default)
 - [Webpack resolver](https://npmjs.com/package/eslint-import-resolver-webpack)
 - [`import/ignore`] global setting
diff --git a/docs/rules/order.md b/docs/rules/order.md
index 437467e2..f6e1ddbe 100644
--- a/docs/rules/order.md
+++ b/docs/rules/order.md
@@ -5,7 +5,7 @@ Enforce a convention in the order of `require()` / `import` statements.
 
 With the [`groups`](#groups-array) option set to `["builtin", "external", "internal", "parent", "sibling", "index", "object", "type"]` the order is as shown in the following example:
 
-```js
+```ts
 // 1. node "builtin" modules
 import fs from 'fs';
 import path from 'path';
@@ -36,7 +36,7 @@ Statements using the ES6 `import` syntax must appear before any `require()` stat
 
 ## Fail
 
-```js
+```ts
 import _ from 'lodash';
 import path from 'path'; // `path` import should occur before import of `lodash`
 
@@ -54,7 +54,7 @@ import foo from './foo'; // `import` statements must be before `require` stateme
 
 ## Pass
 
-```js
+```ts
 import path from 'path';
 import _ from 'lodash';
 
@@ -85,7 +85,7 @@ This rule supports the following options:
 How groups are defined, and the order to respect. `groups` must be an array of `string` or [`string`]. The only allowed `string`s are:
 `"builtin"`, `"external"`, `"internal"`, `"unknown"`, `"parent"`, `"sibling"`, `"index"`, `"object"`, `"type"`.
 The enforced order is the same as the order of each element in a group. Omitted types are implicitly grouped together as the last element. Example:
-```js
+```ts
 [
   'builtin', // Built-in types are first
   ['sibling', 'parent'], // Then sibling and parent types. They can be mingled together
@@ -98,7 +98,7 @@ The default value is `["builtin", "external", "parent", "sibling", "index"]`.
 
 You can set the options like this:
 
-```js
+```ts
 "import/order": ["error", {"groups": ["index", "sibling", "parent", "internal", "external", "builtin", "object", "type"]}]
 ```
 
@@ -184,7 +184,7 @@ The default value is `"ignore"`.
 
 With the default group setting, the following will be invalid:
 
-```js
+```ts
 /* eslint import/order: ["error", {"newlines-between": "always"}] */
 import fs from 'fs';
 import path from 'path';
@@ -192,7 +192,7 @@ import index from './';
 import sibling from './foo';
 ```
 
-```js
+```ts
 /* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
 import fs from 'fs';
 
@@ -201,7 +201,7 @@ import index from './';
 import sibling from './foo';
 ```
 
-```js
+```ts
 /* eslint import/order: ["error", {"newlines-between": "never"}] */
 import fs from 'fs';
 import path from 'path';
@@ -213,7 +213,7 @@ import sibling from './foo';
 
 while those will be valid:
 
-```js
+```ts
 /* eslint import/order: ["error", {"newlines-between": "always"}] */
 import fs from 'fs';
 import path from 'path';
@@ -223,7 +223,7 @@ import index from './';
 import sibling from './foo';
 ```
 
-```js
+```ts
 /* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
 import fs from 'fs';
 
@@ -234,7 +234,7 @@ import index from './';
 import sibling from './foo';
 ```
 
-```js
+```ts
 /* eslint import/order: ["error", {"newlines-between": "never"}] */
 import fs from 'fs';
 import path from 'path';
@@ -250,7 +250,7 @@ Sort the order within each group in alphabetical manner based on **import path**
 - `caseInsensitive`: use `true` to ignore case, and `false` to consider case (default: `false`).
 
 Example setting:
-```js
+```ts
 alphabetize: {
   order: 'asc', /* sort in ascending order. Options: ['ignore', 'asc', 'desc'] */
   caseInsensitive: true /* ignore case. Options: [true, false] */
@@ -259,7 +259,7 @@ alphabetize: {
 
 This will fail the rule check:
 
-```js
+```ts
 /* eslint import/order: ["error", {"alphabetize": {"order": "asc", "caseInsensitive": true}}] */
 import React, { PureComponent } from 'react';
 import aTypes from 'prop-types';
@@ -270,7 +270,7 @@ import blist from 'BList';
 
 While this will pass:
 
-```js
+```ts
 /* eslint import/order: ["error", {"alphabetize": {"order": "asc", "caseInsensitive": true}}] */
 import blist from 'BList';
 import * as classnames from 'classnames';
@@ -290,7 +290,7 @@ way that is safe.
 
 This will fail the rule check:
 
-```js
+```ts
 /* eslint import/order: ["error", {"warnOnUnassignedImports": true}] */
 import fs from 'fs';
 import './styles.css';
@@ -299,7 +299,7 @@ import path from 'path';
 
 While this will pass:
 
-```js
+```ts
 /* eslint import/order: ["error", {"warnOnUnassignedImports": true}] */
 import fs from 'fs';
 import path from 'path';
diff --git a/memo-parser/.eslintrc.yml b/memo-parser/.eslintrc.yml
deleted file mode 100644
index e7e6b3d3..00000000
--- a/memo-parser/.eslintrc.yml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-rules:
-  import/no-extraneous-dependencies: 1
diff --git a/package.json b/package.json
index 07068866..fcfa9b1e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-plugin-import",
-  "version": "2.25.4",
+  "version": "2.26.0",
   "description": "Import with sanity.",
   "engines": {
     "node": ">=4"
@@ -53,10 +53,10 @@
   },
   "homepage": "https://github.com/import-js/eslint-plugin-import",
   "devDependencies": {
-    "@angular-eslint/template-parser": "^13.0.1",
+    "@angular-eslint/template-parser": "^13.1.0",
     "@eslint/import-test-order-redirect-scoped": "file:./tests/files/order-redirect-scoped",
     "@test-scope/some-module": "file:./tests/files/symlinked-module",
-    "@typescript-eslint/parser": "^2.23.0 || ^3.3.0 || ^4.29.3",
+    "@typescript-eslint/parser": "^2.23.0 || ^3.3.0 || ^4.29.3 || ^5.10.0",
     "array.prototype.flatmap": "^1.2.5",
     "babel-cli": "^6.26.0",
     "babel-core": "^6.26.3",
@@ -67,7 +67,7 @@
     "babel-preset-flow": "^6.23.0",
     "babel-register": "^6.26.0",
     "babylon": "^6.18.0",
-    "chai": "^4.3.4",
+    "chai": "^4.3.6",
     "cross-env": "^4.0.0",
     "escope": "^3.6.0",
     "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8",
@@ -93,7 +93,7 @@
     "semver": "^6.3.0",
     "sinon": "^2.4.1",
     "typescript": "^2.8.1 || ~3.9.5",
-    "typescript-eslint-parser": "^15 || ^22.0.0"
+    "typescript-eslint-parser": "^15 || ^20 || ^22"
   },
   "peerDependencies": {
     "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
@@ -104,13 +104,13 @@
     "debug": "^2.6.9",
     "doctrine": "^2.1.0",
     "eslint-import-resolver-node": "^0.3.6",
-    "eslint-module-utils": "^2.7.2",
+    "eslint-module-utils": "^2.7.3",
     "has": "^1.0.3",
-    "is-core-module": "^2.8.0",
+    "is-core-module": "^2.8.1",
     "is-glob": "^4.0.3",
-    "minimatch": "^3.0.4",
+    "minimatch": "^3.1.2",
     "object.values": "^1.1.5",
-    "resolve": "^1.20.0",
-    "tsconfig-paths": "^3.12.0"
+    "resolve": "^1.22.0",
+    "tsconfig-paths": "^3.14.1"
   }
 }
diff --git a/resolvers/webpack/.eslintrc b/resolvers/webpack/.eslintrc
deleted file mode 100644
index 544167c4..00000000
--- a/resolvers/webpack/.eslintrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "rules": {
-    "import/no-extraneous-dependencies": 1,
-    "no-console": 1,
-  },
-  "env": {
-    "es6": true,
-  },
-}
diff --git a/src/ExportMap.js b/src/ExportMap.js
index 564b5d63..d75c7ecd 100644
--- a/src/ExportMap.js
+++ b/src/ExportMap.js
@@ -479,11 +479,11 @@ ExportMap.parse = function (path, content, context) {
       }));
       return;
     case 'ExportAllDeclaration':
-      m.namespace.set(s.exported.name, addNamespace(exportMeta, s.source.value));
+      m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.source.value));
       return;
     case 'ExportSpecifier':
       if (!n.source) {
-        m.namespace.set(s.exported.name, addNamespace(exportMeta, s.local));
+        m.namespace.set(s.exported.name || s.exported.value, addNamespace(exportMeta, s.local));
         return;
       }
       // else falls through
@@ -593,7 +593,7 @@ ExportMap.parse = function (path, content, context) {
           importedSpecifiers.add(specifier.type);
         }
         if (specifier.type === 'ImportSpecifier') {
-          importedSpecifiers.add(specifier.imported.name);
+          importedSpecifiers.add(specifier.imported.name || specifier.imported.value);
         }
 
         // import { type Foo } (Flow)
@@ -645,7 +645,7 @@ ExportMap.parse = function (path, content, context) {
     // This doesn't declare anything, but changes what's being exported.
     if (includes(exports, n.type)) {
       const exportedName = n.type === 'TSNamespaceExportDeclaration'
-        ? n.id.name
+        ? (n.id || n.name).name
         : (n.expression && n.expression.name || (n.expression.id && n.expression.id.name) || null);
       const declTypes = [
         'VariableDeclaration',
diff --git a/src/rules/export.js b/src/rules/export.js
index e0b2c578..4cae1074 100644
--- a/src/rules/export.js
+++ b/src/rules/export.js
@@ -36,13 +36,59 @@ const tsTypePrefix = 'type:';
  */
 function isTypescriptFunctionOverloads(nodes) {
   const types = new Set(Array.from(nodes, node => node.parent.type));
-  return (
-    types.has('TSDeclareFunction') &&
-    (
-      types.size === 1 ||
-      (types.size === 2 && types.has('FunctionDeclaration'))
-    )
-  );
+  return types.has('TSDeclareFunction')
+    && (
+      types.size === 1
+      || (types.size === 2 && types.has('FunctionDeclaration'))
+    );
+}
+
+/**
+ * Detect merging Namespaces with Classes, Functions, or Enums like:
+ * ```ts
+ * export class Foo { }
+ * export namespace Foo { }
+ * ```
+ * @param {Set<Object>} nodes
+ * @returns {boolean}
+ */
+function isTypescriptNamespaceMerging(nodes) {
+  const types = new Set(Array.from(nodes, node => node.parent.type));
+  const noNamespaceNodes = Array.from(nodes).filter((node) => node.parent.type !== 'TSModuleDeclaration');
+
+  return types.has('TSModuleDeclaration')
+    && (
+      types.size === 1
+      // Merging with functions
+      || (types.size === 2 && (types.has('FunctionDeclaration') || types.has('TSDeclareFunction')))
+      || (types.size === 3 && types.has('FunctionDeclaration') && types.has('TSDeclareFunction'))
+      // Merging with classes or enums
+      || (types.size === 2 && (types.has('ClassDeclaration') || types.has('TSEnumDeclaration')) && noNamespaceNodes.length === 1)
+    );
+}
+
+/**
+ * Detect if a typescript namespace node should be reported as multiple export:
+ * ```ts
+ * export class Foo { }
+ * export function Foo();
+ * export namespace Foo { }
+ * ```
+ * @param {Object} node
+ * @param {Set<Object>} nodes
+ * @returns {boolean}
+ */
+function shouldSkipTypescriptNamespace(node, nodes) {
+  const types = new Set(Array.from(nodes, node => node.parent.type));
+
+  return !isTypescriptNamespaceMerging(nodes)
+    && node.parent.type === 'TSModuleDeclaration'
+    && (
+      types.has('TSEnumDeclaration')
+      || types.has('ClassDeclaration')
+      || types.has('FunctionDeclaration')
+      || types.has('TSDeclareFunction')
+    );
 }
 
 module.exports = {
@@ -85,15 +131,19 @@ module.exports = {
     }
 
     return {
-      'ExportDefaultDeclaration': (node) => addNamed('default', node, getParent(node)),
+      ExportDefaultDeclaration(node) {
+        addNamed('default', node, getParent(node));
+      },
 
-      'ExportSpecifier': (node) => addNamed(
-        node.exported.name,
-        node.exported,
-        getParent(node.parent),
-      ),
+      ExportSpecifier(node) {
+        addNamed(
+          node.exported.name || node.exported.value,
+          node.exported,
+          getParent(node.parent),
+        );
+      },
 
-      'ExportNamedDeclaration': function (node) {
+      ExportNamedDeclaration(node) {
         if (node.declaration == null) return;
 
         const parent = getParent(node);
@@ -119,7 +169,7 @@ module.exports = {
         }
       },
 
-      'ExportAllDeclaration': function (node) {
+      ExportAllDeclaration(node) {
         if (node.source == null) return; // not sure if this is ever true
 
         // `export * as X from 'path'` does not conflict
@@ -156,9 +206,11 @@ module.exports = {
           for (const [name, nodes] of named) {
             if (nodes.size <= 1) continue;
 
-            if (isTypescriptFunctionOverloads(nodes)) continue;
+            if (isTypescriptFunctionOverloads(nodes) || isTypescriptNamespaceMerging(nodes)) continue;
 
             for (const node of nodes) {
+              if (shouldSkipTypescriptNamespace(node, nodes)) continue;
+
               if (name === 'default') {
                 context.report(node, 'Multiple default exports.');
               } else {
diff --git a/src/rules/named.js b/src/rules/named.js
index a529c295..ad1b5e17 100644
--- a/src/rules/named.js
+++ b/src/rules/named.js
@@ -58,7 +58,9 @@ module.exports = {
           return;
         }
 
-        const deepLookup = imports.hasDeep(im[key].name);
+        const name = im[key].name || im[key].value;
+
+        const deepLookup = imports.hasDeep(name);
 
         if (!deepLookup.found) {
           if (deepLookup.path.length > 1) {
@@ -66,9 +68,9 @@ module.exports = {
               .map(i => path.relative(path.dirname(context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename()), i.path))
               .join(' -> ');
 
-            context.report(im[key], `${im[key].name} not found via ${deepPath}`);
+            context.report(im[key], `${name} not found via ${deepPath}`);
           } else {
-            context.report(im[key], im[key].name + ' not found in \'' + node.source.value + '\'');
+            context.report(im[key], name + ' not found in \'' + node.source.value + '\'');
           }
         }
       });
diff --git a/src/rules/namespace.js b/src/rules/namespace.js
index 6325b88b..405c415c 100644
--- a/src/rules/namespace.js
+++ b/src/rules/namespace.js
@@ -3,6 +3,44 @@ import Exports from '../ExportMap';
 import importDeclaration from '../importDeclaration';
 import docsUrl from '../docsUrl';
 
+function processBodyStatement(context, namespaces, declaration) {
+  if (declaration.type !== 'ImportDeclaration') return;
+
+  if (declaration.specifiers.length === 0) return;
+
+  const imports = Exports.get(declaration.source.value, context);
+  if (imports == null) return null;
+
+  if (imports.errors.length > 0) {
+    imports.reportErrors(context, declaration);
+    return;
+  }
+
+  declaration.specifiers.forEach((specifier) => {
+    switch (specifier.type) {
+    case 'ImportNamespaceSpecifier':
+      if (!imports.size) {
+        context.report(
+          specifier,
+          `No exported names found in module '${declaration.source.value}'.`,
+        );
+      }
+      namespaces.set(specifier.local.name, imports);
+      break;
+    case 'ImportDefaultSpecifier':
+    case 'ImportSpecifier': {
+      const meta = imports.get(
+        // default to 'default' for default https://i.imgur.com/nj6qAWy.jpg
+        specifier.imported ? (specifier.imported.name || specifier.imported.value) : 'default',
+      );
+      if (!meta || !meta.namespace) { break; }
+      namespaces.set(specifier.local.name, meta.namespace);
+      break;
+    }
+    }
+  });
+}
+
 module.exports = {
   meta: {
     type: 'problem',
@@ -41,44 +79,7 @@ module.exports = {
     return {
       // pick up all imports at body entry time, to properly respect hoisting
       Program({ body }) {
-        function processBodyStatement(declaration) {
-          if (declaration.type !== 'ImportDeclaration') return;
-
-          if (declaration.specifiers.length === 0) return;
-
-          const imports = Exports.get(declaration.source.value, context);
-          if (imports == null) return null;
-
-          if (imports.errors.length) {
-            imports.reportErrors(context, declaration);
-            return;
-          }
-
-          for (const specifier of declaration.specifiers) {
-            switch (specifier.type) {
-            case 'ImportNamespaceSpecifier':
-              if (!imports.size) {
-                context.report(
-                  specifier,
-                  `No exported names found in module '${declaration.source.value}'.`,
-                );
-              }
-              namespaces.set(specifier.local.name, imports);
-              break;
-            case 'ImportDefaultSpecifier':
-            case 'ImportSpecifier': {
-              const meta = imports.get(
-                // default to 'default' for default https://i.imgur.com/nj6qAWy.jpg
-                specifier.imported ? specifier.imported.name : 'default',
-              );
-              if (!meta || !meta.namespace) { break; }
-              namespaces.set(specifier.local.name, meta.namespace);
-              break;
-            }
-            }
-          }
-        }
-        body.forEach(processBodyStatement);
+        body.forEach(x => processBodyStatement(context, namespaces, x));
       },
 
       // same as above, but does not add names to local map
@@ -120,7 +121,6 @@ module.exports = {
         const namepath = [dereference.object.name];
         // while property is namespace and parent is member expression, keep validating
         while (namespace instanceof Exports && dereference.type === 'MemberExpression') {
-
           if (dereference.computed) {
             if (!allowComputed) {
               context.report(
@@ -147,7 +147,6 @@ module.exports = {
           namespace = exported.namespace;
           dereference = dereference.parent;
         }
-
       },
 
       VariableDeclarator({ id, init }) {
diff --git a/src/rules/no-default-export.js b/src/rules/no-default-export.js
index a17428c5..ed1aaf8d 100644
--- a/src/rules/no-default-export.js
+++ b/src/rules/no-default-export.js
@@ -25,7 +25,7 @@ module.exports = {
       },
 
       ExportNamedDeclaration(node) {
-        node.specifiers.filter(specifier => specifier.exported.name === 'default').forEach(specifier => {
+        node.specifiers.filter(specifier => (specifier.exported.name || specifier.exported.value) === 'default').forEach(specifier => {
           const { loc } = context.getSourceCode().getFirstTokens(node)[1] || {};
           if (specifier.type === 'ExportDefaultSpecifier') {
             context.report({ node, message: preferNamed, loc });
diff --git a/src/rules/no-duplicates.js b/src/rules/no-duplicates.js
index 43c2c5b2..efd9583f 100644
--- a/src/rules/no-duplicates.js
+++ b/src/rules/no-duplicates.js
@@ -274,17 +274,23 @@ module.exports = {
       return defaultResolver(parts[1]) + '?' + parts[2];
     }) : defaultResolver;
 
-    const imported = new Map();
-    const nsImported = new Map();
-    const defaultTypesImported = new Map();
-    const namedTypesImported = new Map();
+    const moduleMaps = new Map();
 
     function getImportMap(n) {
+      if (!moduleMaps.has(n.parent)) {
+        moduleMaps.set(n.parent, {
+          imported: new Map(),
+          nsImported: new Map(),
+          defaultTypesImported: new Map(),
+          namedTypesImported: new Map(),
+        });
+      }
+      const map = moduleMaps.get(n.parent);
       if (n.importKind === 'type') {
-        return n.specifiers.length > 0 && n.specifiers[0].type === 'ImportDefaultSpecifier' ? defaultTypesImported : namedTypesImported;
+        return n.specifiers.length > 0 && n.specifiers[0].type === 'ImportDefaultSpecifier' ? map.defaultTypesImported : map.namedTypesImported;
       }
 
-      return hasNamespace(n) ? nsImported : imported;
+      return hasNamespace(n) ? map.nsImported : map.imported;
     }
 
     return {
@@ -301,10 +307,12 @@ module.exports = {
       },
 
       'Program:exit': function () {
-        checkImports(imported, context);
-        checkImports(nsImported, context);
-        checkImports(defaultTypesImported, context);
-        checkImports(namedTypesImported, context);
+        for (const map of moduleMaps.values()) {
+          checkImports(map.imported, context);
+          checkImports(map.nsImported, context);
+          checkImports(map.defaultTypesImported, context);
+          checkImports(map.namedTypesImported, context);
+        }
       },
     };
   },
diff --git a/src/rules/no-dynamic-require.js b/src/rules/no-dynamic-require.js
index 8267fd26..27e9a957 100644
--- a/src/rules/no-dynamic-require.js
+++ b/src/rules/no-dynamic-require.js
@@ -19,6 +19,8 @@ function isStaticValue(arg) {
     (arg.type === 'TemplateLiteral' && arg.expressions.length === 0);
 }
 
+const dynamicImportErrorMessage = 'Calls to import() should use string literals';
+
 module.exports = {
   meta: {
     type: 'suggestion',
@@ -55,10 +57,19 @@ module.exports = {
         if (options.esmodule && isDynamicImport(node)) {
           return context.report({
             node,
-            message: 'Calls to import() should use string literals',
+            message: dynamicImportErrorMessage,
           });
         }
       },
+      ImportExpression(node) {
+        if (!options.esmodule || isStaticValue(node.source)) {
+          return;
+        }
+        return context.report({
+          node,
+          message: dynamicImportErrorMessage,
+        });
+      },
     };
   },
 };
diff --git a/src/rules/no-named-default.js b/src/rules/no-named-default.js
index 116c89cf..6a5c1db7 100644
--- a/src/rules/no-named-default.js
+++ b/src/rules/no-named-default.js
@@ -17,7 +17,7 @@ module.exports = {
             return;
           }
 
-          if (im.type === 'ImportSpecifier' && im.imported.name === 'default') {
+          if (im.type === 'ImportSpecifier' && (im.imported.name || im.imported.value) === 'default') {
             context.report({
               node: im.local,
               message: `Use default import syntax to import '${im.local.name}'.` });
diff --git a/src/rules/no-named-export.js b/src/rules/no-named-export.js
index bb586ead..6c92ad9c 100644
--- a/src/rules/no-named-export.js
+++ b/src/rules/no-named-export.js
@@ -25,7 +25,7 @@ module.exports = {
           return context.report({ node, message });
         }
 
-        const someNamed = node.specifiers.some(specifier => specifier.exported.name !== 'default');
+        const someNamed = node.specifiers.some(specifier => (specifier.exported.name || specifier.exported.value) !== 'default');
         if (someNamed) {
           context.report({ node, message });
         }
diff --git a/src/rules/no-relative-packages.js b/src/rules/no-relative-packages.js
index 17406e80..7bf1ce5c 100644
--- a/src/rules/no-relative-packages.js
+++ b/src/rules/no-relative-packages.js
@@ -6,6 +6,11 @@ import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisi
 import importType from '../core/importType';
 import docsUrl from '../docsUrl';
 
+/** @param {string} filePath */
+function toPosixPath(filePath) {
+  return filePath.replace(/\\/g, '/');
+}
+
 function findNamedPackage(filePath) {
   const found = readPkgUp({ cwd: filePath });
   if (found.pkg && !found.pkg.name) {
@@ -42,6 +47,8 @@ function checkImportForRelativePackage(context, importPath, node) {
     context.report({
       node,
       message: `Relative import from another package is not allowed. Use \`${properImport}\` instead of \`${importPath}\``,
+      fix: fixer => fixer.replaceText(node, JSON.stringify(toPosixPath(properImport)))
+      ,
     });
   }
 }
@@ -52,6 +59,7 @@ module.exports = {
     docs: {
       url: docsUrl('no-relative-packages'),
     },
+    fixable: 'code',
     schema: [makeOptionsSchema()],
   },
 
diff --git a/src/rules/no-unused-modules.js b/src/rules/no-unused-modules.js
index 9891d409..5feb3190 100644
--- a/src/rules/no-unused-modules.js
+++ b/src/rules/no-unused-modules.js
@@ -273,8 +273,10 @@ const prepareImportsAndExports = (srcFiles, context) => {
   exportAll.forEach((value, key) => {
     value.forEach(val => {
       const currentExports = exportList.get(val);
-      const currentExport = currentExports.get(EXPORT_ALL_DECLARATION);
-      currentExport.whereUsed.add(key);
+      if (currentExports) {
+        const currentExport = currentExports.get(EXPORT_ALL_DECLARATION);
+        currentExport.whereUsed.add(key);
+      }
     });
   });
 };
@@ -604,7 +606,7 @@ module.exports = {
           if (specifiers.length > 0) {
             specifiers.forEach(specifier => {
               if (specifier.exported) {
-                newExportIdentifiers.add(specifier.exported.name);
+                newExportIdentifiers.add(specifier.exported.name || specifier.exported.value);
               }
             });
           }
@@ -715,8 +717,8 @@ module.exports = {
           if (astNode.source) {
             resolvedPath = resolve(astNode.source.raw.replace(/('|")/g, ''), context);
             astNode.specifiers.forEach(specifier => {
-              const name = specifier.local.name;
-              if (specifier.local.name === DEFAULT) {
+              const name = specifier.local.name || specifier.local.value;
+              if (name === DEFAULT) {
                 newDefaultImports.add(resolvedPath);
               } else {
                 newImports.set(name, resolvedPath);
@@ -753,7 +755,7 @@ module.exports = {
                 specifier.type === IMPORT_NAMESPACE_SPECIFIER) {
               return;
             }
-            newImports.set(specifier.imported.name, resolvedPath);
+            newImports.set(specifier.imported.name || specifier.imported.value, resolvedPath);
           });
         }
       });
@@ -942,7 +944,7 @@ module.exports = {
       },
       'ExportNamedDeclaration': node => {
         node.specifiers.forEach(specifier => {
-          checkUsage(node, specifier.exported.name);
+          checkUsage(node, specifier.exported.name || specifier.exported.value);
         });
         forEachDeclarationIdentifier(node.declaration, (name) => {
           checkUsage(node, name);
diff --git a/src/rules/prefer-default-export.js b/src/rules/prefer-default-export.js
index a8c52bb1..230efad1 100644
--- a/src/rules/prefer-default-export.js
+++ b/src/rules/prefer-default-export.js
@@ -40,7 +40,7 @@ module.exports = {
       },
 
       'ExportSpecifier': function (node) {
-        if (node.exported.name === 'default') {
+        if ((node.exported.name || node.exported.value) === 'default') {
           hasDefaultExport = true;
         } else {
           specifierExportCount++;
diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md
index 487a0644..193fc141 100644
--- a/utils/CHANGELOG.md
+++ b/utils/CHANGELOG.md
@@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 
 ## Unreleased
 
+## v2.7.3 - 2022-01-26
+
+### Fixed
+- [Fix] `parse`: restore compatibility by making the return value `ast` again ([#2350], thanks [@ljharb])
+
 ## v2.7.2 - 2022-01-01
 
 ### Fixed
@@ -110,6 +115,7 @@ Yanked due to critical issue with cache key resulting from #839.
 ### Fixed
 - `unambiguous.test()` regex is now properly in multiline mode
 
+[#2350]: https://github.com/import-js/eslint-plugin-import/issues/2350
 [#2343]: https://github.com/import-js/eslint-plugin-import/pull/2343
 [#2261]: https://github.com/import-js/eslint-plugin-import/pull/2261
 [#2212]: https://github.com/import-js/eslint-plugin-import/pull/2212
diff --git a/utils/package.json b/utils/package.json
index 97f95162..2e348d07 100644
--- a/utils/package.json
+++ b/utils/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-module-utils",
-  "version": "2.7.2",
+  "version": "2.7.3",
   "description": "Core utilities to support eslint-plugin-import and other module-related plugins.",
   "engines": {
     "node": ">=4"
diff --git a/utils/parse.js b/utils/parse.js
index 810533ed..98e82159 100644
--- a/utils/parse.js
+++ b/utils/parse.js
@@ -32,6 +32,16 @@ function keysFromParser(parserPath, parserInstance, parsedResult) {
   return null;
 }
 
+// this exists to smooth over the unintentional breaking change in v2.7.
+// TODO, semver-major: avoid mutating `ast` and return a plain object instead.
+function makeParseReturn(ast, visitorKeys) {
+  if (ast) {
+    ast.visitorKeys = visitorKeys;
+    ast.ast = ast;
+  }
+  return ast;
+}
+
 exports.default = function parse(path, content, context) {
 
   if (context == null) throw new Error('need context to parse properly');
@@ -73,10 +83,7 @@ exports.default = function parse(path, content, context) {
     try {
       const parserRaw = parser.parseForESLint(content, parserOptions);
       ast = parserRaw.ast;
-      return {
-        ast,
-        visitorKeys: keysFromParser(parserPath, parser, parserRaw),
-      };
+      return makeParseReturn(ast, keysFromParser(parserPath, parser, parserRaw));
     } catch (e) {
       console.warn();
       console.warn('Error while parsing ' + parserOptions.filePath);
@@ -89,18 +96,12 @@ exports.default = function parse(path, content, context) {
           '` is invalid and will just be ignored'
       );
     } else {
-      return {
-        ast,
-        visitorKeys: keysFromParser(parserPath, parser, undefined),
-      };
+      return makeParseReturn(ast, keysFromParser(parserPath, parser, undefined));
     }
   }
 
-  const keys = keysFromParser(parserPath, parser, undefined);
-  return {
-    ast: parser.parse(content, parserOptions),
-    visitorKeys: keys,
-  };
+  const ast = parser.parse(content, parserOptions);
+  return makeParseReturn(ast, keysFromParser(parserPath, parser, undefined));
 };
 
 function getParserPath(path, context) {


Test patch:
diff --git a/tests/.eslintrc b/tests/.eslintrc
deleted file mode 100644
index 5720f3fc..00000000
--- a/tests/.eslintrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "env": {
-    "mocha": true,
-  },
-  "rules": {
-    "max-len": 0,
-    "import/default": 0,
-  },
-}
diff --git a/tests/dep-time-travel.sh b/tests/dep-time-travel.sh
index 82681b38..665ca1cc 100755
--- a/tests/dep-time-travel.sh
+++ b/tests/dep-time-travel.sh
@@ -21,6 +21,8 @@ elif [[ "$ESLINT_VERSION" -lt "5" ]]; then # completely remove the new TypeScrip
   npm uninstall --no-save @typescript-eslint/parser
 elif [[ "$TRAVIS_NODE_VERSION" -lt "10" ]]; then # TS parser 3 requires node 10+
   npm i --no-save "@typescript-eslint/parser@3"
+elif [[ "$TRAVIS_NODE_VERSION" -lt "12" ]]; then # TS parser 4 requires node 12+
+  npm i --no-save "@typescript-eslint/parser@4"
 fi
 
 # use these alternate TypeScript dependencies for ESLint < v4
@@ -30,6 +32,9 @@ if [[ "$ESLINT_VERSION" -lt "4" ]]; then
 
   echo "Downgrading TypeScript dependencies..."
   npm i --no-save typescript-eslint-parser@15 typescript@2.8.1
+elif [[ "$ESLINT_VERSION" -lt "7" ]]; then
+  echo "Downgrading TypeScript dependencies..."
+  npm i --no-save typescript-eslint-parser@20
 fi
 
 # typescript-eslint-parser 1.1.1+ is not compatible with node 6
diff --git a/tests/files/.eslintrc b/tests/files/.eslintrc.js
similarity index 85%
rename from tests/files/.eslintrc
rename to tests/files/.eslintrc.js
index 6d36c133..6f252980 100644
--- a/tests/files/.eslintrc
+++ b/tests/files/.eslintrc.js
@@ -1,4 +1,9 @@
-{
+const eslintPkg = require('eslint/package.json');
+const semver = require('semver');
+
+const supportsArbitraryModuleNamespaceIdentifierNames = semver.satisfies(eslintPkg.version, '>= 8.7');
+
+const config = {
   "parser": "babel-eslint",
   "parserOptions": {
     "sourceType": "module",
@@ -281,5 +286,36 @@
     "import/no-duplicates": 0,
     "import/no-extraneous-dependencies": 0,
     "import/unambiguous": 0
-  }
+  },
+  ignorePatterns: [
+    "default-export-namespace-string.js",
+    "default-export-string.js",
+    "export-default-string-and-named.js",
+    "no-unused-modules/arbitrary-module-namespace-identifier-name-a.js",
+    "no-unused-modules/arbitrary-module-namespace-identifier-name-b.js",
+    "no-unused-modules/arbitrary-module-namespace-identifier-name-c.js"
+  ],
+}
+
+if (supportsArbitraryModuleNamespaceIdentifierNames) {
+  config.ignorePatterns = [];
+  config.overrides = [
+    // For parsing arbitrary module namespace names
+    {
+      "files": [
+        "default-export-namespace-string.js",
+        "default-export-string.js",
+        "export-default-string-and-named.js",
+        "no-unused-modules/arbitrary-module-namespace-identifier-name-a.js",
+        "no-unused-modules/arbitrary-module-namespace-identifier-name-b.js",
+        "no-unused-modules/arbitrary-module-namespace-identifier-name-c.js"
+      ],
+      "parser": "espree",
+      "parserOptions": {
+        "ecmaVersion": 2022
+      }
+    }
+  ];
 }
+
+module.exports = config;
diff --git a/tests/files/default-export-namespace-string.js b/tests/files/default-export-namespace-string.js
new file mode 100644
index 00000000..5b4a01ab
--- /dev/null
+++ b/tests/files/default-export-namespace-string.js
@@ -0,0 +1,1 @@
+export * as "default" from "./named-exports";
diff --git a/tests/files/default-export-string.js b/tests/files/default-export-string.js
new file mode 100644
index 00000000..4f68b517
--- /dev/null
+++ b/tests/files/default-export-string.js
@@ -0,0 +1,3 @@
+function foo() { return 'bar' }
+
+export { foo as "default" }
diff --git a/tests/files/export-default-string-and-named.js b/tests/files/export-default-string-and-named.js
new file mode 100644
index 00000000..62c7d13c
--- /dev/null
+++ b/tests/files/export-default-string-and-named.js
@@ -0,0 +1,4 @@
+const bar = "bar";
+export function foo() {}
+
+export { bar as "default" }
diff --git a/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-a.js b/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-a.js
new file mode 100644
index 00000000..7ad810de
--- /dev/null
+++ b/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-a.js
@@ -0,0 +1,2 @@
+const foo = 333
+export { foo as "foo" }
diff --git a/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-b.js b/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-b.js
new file mode 100644
index 00000000..fa765272
--- /dev/null
+++ b/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-b.js
@@ -0,0 +1,1 @@
+import { "foo" as foo } from "./arbitrary-module-namespace-identifier-name-a.js"
diff --git a/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-c.js b/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-c.js
new file mode 100644
index 00000000..7ad810de
--- /dev/null
+++ b/tests/files/no-unused-modules/arbitrary-module-namespace-identifier-name-c.js
@@ -0,0 +1,2 @@
+const foo = 333
+export { foo as "foo" }
diff --git a/tests/files/unused-modules-reexport-crash/src/App.tsx b/tests/files/unused-modules-reexport-crash/src/App.tsx
new file mode 100644
index 00000000..c797a976
--- /dev/null
+++ b/tests/files/unused-modules-reexport-crash/src/App.tsx
@@ -0,0 +1,5 @@
+import { hello } from './magic/test'
+
+hello();
+
+export default function App() {};
diff --git a/tests/files/unused-modules-reexport-crash/src/index.tsx b/tests/files/unused-modules-reexport-crash/src/index.tsx
new file mode 100644
index 00000000..124b1745
--- /dev/null
+++ b/tests/files/unused-modules-reexport-crash/src/index.tsx
@@ -0,0 +1,3 @@
+import App from './App';
+
+export const x = App
\ No newline at end of file
diff --git a/tests/files/unused-modules-reexport-crash/src/magic/index.js b/tests/files/unused-modules-reexport-crash/src/magic/index.js
new file mode 100644
index 00000000..ac3f46bb
--- /dev/null
+++ b/tests/files/unused-modules-reexport-crash/src/magic/index.js
@@ -0,0 +1,1 @@
+export * from './test'
diff --git a/tests/files/unused-modules-reexport-crash/src/magic/test.js b/tests/files/unused-modules-reexport-crash/src/magic/test.js
new file mode 100644
index 00000000..a6d74afd
--- /dev/null
+++ b/tests/files/unused-modules-reexport-crash/src/magic/test.js
@@ -0,0 +1,7 @@
+export function hello() {
+	console.log('hello!!');
+}
+
+export function unused() {
+	console.log('im unused!!');
+}
\ No newline at end of file
diff --git a/tests/src/cli.js b/tests/src/cli.js
index 5b7e705b..e6afd8e4 100644
--- a/tests/src/cli.js
+++ b/tests/src/cli.js
@@ -104,6 +104,9 @@ describe('CLI regression tests', function () {
                 fixableErrorCount: 0,
                 fixableWarningCount: 0,
                 source: results[0].source, // NewLine-characters might differ depending on git-settings
+                ...(semver.satisfies(eslintPkg.version, '>= 8.8') && {
+                  suppressedMessages: [],
+                }),
                 usedDeprecatedRules: results[0].usedDeprecatedRules, // we don't care about this one
               },
             ],
diff --git a/tests/src/core/getExports.js b/tests/src/core/getExports.js
index 604ae5cf..867644bc 100644
--- a/tests/src/core/getExports.js
+++ b/tests/src/core/getExports.js
@@ -343,7 +343,6 @@ describe('ExportMap', function () {
   });
 
   context('alternate parsers', function () {
-
     const configs = [
       // ['string form', { 'typescript-eslint-parser': '.ts' }],
     ];
diff --git a/tests/src/rules/default.js b/tests/src/rules/default.js
index 0274e437..eb2028c7 100644
--- a/tests/src/rules/default.js
+++ b/tests/src/rules/default.js
@@ -1,6 +1,8 @@
 import path from 'path';
-import { test, SYNTAX_CASES, getTSParsers } from '../utils';
+import { test, testVersion, SYNTAX_CASES, getTSParsers, parsers } from '../utils';
 import { RuleTester } from 'eslint';
+import semver from 'semver';
+import { version as tsEslintVersion } from 'typescript-eslint-parser/package.json';
 
 import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve';
 
@@ -8,7 +10,7 @@ const ruleTester = new RuleTester();
 const rule = require('rules/default');
 
 ruleTester.run('default', rule, {
-  valid: [
+  valid: [].concat(
     test({ code: 'import "./malformed.js"' }),
 
     test({ code: 'import foo from "./empty-folder";' }),
@@ -29,19 +31,19 @@ ruleTester.run('default', rule, {
 
     // es7 export syntax
     test({ code: 'export bar from "./bar"',
-      parser: require.resolve('babel-eslint') }),
+      parser: parsers.BABEL_OLD }),
     test({ code: 'export { default as bar } from "./bar"' }),
     test({ code: 'export bar, { foo } from "./bar"',
-      parser: require.resolve('babel-eslint') }),
+      parser: parsers.BABEL_OLD }),
     test({ code: 'export { default as bar, foo } from "./bar"' }),
     test({ code: 'export bar, * as names from "./bar"',
-      parser: require.resolve('babel-eslint') }),
+      parser: parsers.BABEL_OLD }),
 
     // sanity check
     test({ code: 'export {a} from "./named-exports"' }),
     test({
       code: 'import twofer from "./trampoline"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // jsx
@@ -69,31 +71,39 @@ ruleTester.run('default', rule, {
     // from no-errors
     test({
       code: "import Foo from './jsx/FooES7.js';",
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // #545: more ES7 cases
     test({
       code: "import bar from './default-export-from.js';",
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: "import bar from './default-export-from-named.js';",
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: "import bar from './default-export-from-ignored.js';",
       settings: { 'import/ignore': ['common'] },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: "export bar from './default-export-from-ignored.js';",
       settings: { 'import/ignore': ['common'] },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'export { "default" as bar } from "./bar"',
+      parserOptions: {
+        ecmaVersion: 2022,
+      },
+    })),
+
     ...SYNTAX_CASES,
-  ],
+  ),
 
   invalid: [
     test({
@@ -109,23 +119,23 @@ ruleTester.run('default', rule, {
     // es7 export syntax
     test({
       code: 'export baz from "./named-exports"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ['No default export found in imported module "./named-exports".'],
     }),
     test({
       code: 'export baz, { bar } from "./named-exports"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ['No default export found in imported module "./named-exports".'],
     }),
     test({
       code: 'export baz, * as names from "./named-exports"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ['No default export found in imported module "./named-exports".'],
     }),
     // exports default from a module with no default
     test({
       code: 'import twofer from "./broken-trampoline"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ['No default export found in imported module "./broken-trampoline".'],
     }),
 
@@ -157,7 +167,7 @@ if (!CASE_SENSITIVE_FS) {
 context('TypeScript', function () {
   getTSParsers().forEach((parser) => {
     ruleTester.run(`default`, rule, {
-      valid: [
+      valid: [].concat(
         test({
           code: `import foobar from "./typescript-default"`,
           parser,
@@ -182,14 +192,14 @@ context('TypeScript', function () {
             'import/resolver': { 'eslint-import-resolver-typescript': true },
           },
         }),
-        test({
+        semver.satisfies(tsEslintVersion, '>= 22') ? test({
           code: `import foobar from "./typescript-export-assign-mixed"`,
           parser,
           settings: {
             'import/parsers': { [parser]: ['.ts'] },
             'import/resolver': { 'eslint-import-resolver-typescript': true },
           },
-        }),
+        }) : [],
         test({
           code: `import foobar from "./typescript-export-assign-default-reexport"`,
           parser,
@@ -250,7 +260,7 @@ context('TypeScript', function () {
             'import/resolver': { 'eslint-import-resolver-typescript': true },
           },
         }),
-      ],
+      ),
 
       invalid: [
         test({
diff --git a/tests/src/rules/dynamic-import-chunkname.js b/tests/src/rules/dynamic-import-chunkname.js
index a2ee55f1..7e482cf0 100644
--- a/tests/src/rules/dynamic-import-chunkname.js
+++ b/tests/src/rules/dynamic-import-chunkname.js
@@ -1,4 +1,4 @@
-import { SYNTAX_CASES, getTSParsers } from '../utils';
+import { SYNTAX_CASES, getTSParsers, parsers } from '../utils';
 import { RuleTester } from 'eslint';
 import semver from 'semver';
 
@@ -15,7 +15,7 @@ const pickyCommentOptions = [{
 const multipleImportFunctionOptions = [{
   importFunctions: ['dynamicImport', 'definitelyNotStaticImport'],
 }];
-const parser = require.resolve('babel-eslint');
+const parser = parsers.BABEL_OLD;
 
 const noLeadingCommentError = 'dynamic imports require a leading comment with the webpack chunkname';
 const nonBlockCommentError = 'dynamic imports require a /* foo */ style comment, not a // foo comment';
@@ -495,7 +495,7 @@ ruleTester.run('dynamic-import-chunkname', rule, {
 
 context('TypeScript', () => {
   getTSParsers().forEach((typescriptParser) => {
-    const nodeType = typescriptParser.includes('typescript-eslint-parser') || (typescriptParser.includes('@typescript-eslint/parser') && semver.satisfies(require('@typescript-eslint/parser/package.json').version, '^2'))
+    const nodeType = typescriptParser === parsers.TS_OLD || (typescriptParser === parsers.TS_NEW && semver.satisfies(require('@typescript-eslint/parser/package.json').version, '^2'))
       ? 'CallExpression'
       : 'ImportExpression';
 
diff --git a/tests/src/rules/export.js b/tests/src/rules/export.js
index 29fae410..5996e9fa 100644
--- a/tests/src/rules/export.js
+++ b/tests/src/rules/export.js
@@ -3,6 +3,7 @@ import { test, testFilePath, SYNTAX_CASES, getTSParsers, testVersion } from '../
 import { RuleTester } from 'eslint';
 import eslintPkg from 'eslint/package.json';
 import semver from 'semver';
+import { version as tsEslintVersion } from 'typescript-eslint-parser/package.json';
 
 const ruleTester = new RuleTester();
 const rule = require('rules/export');
@@ -25,7 +26,7 @@ ruleTester.run('export', rule, {
     // #328: "export * from" does not export a default
     test({ code: 'export default foo; export * from "./bar"' }),
 
-    ...SYNTAX_CASES,
+    SYNTAX_CASES,
 
     test({
       code: `
@@ -46,7 +47,7 @@ ruleTester.run('export', rule, {
     })) || [],
   ),
 
-  invalid: [
+  invalid: [].concat(
     // multiple defaults
     // test({
     //   code: 'export default foo; export default bar',
@@ -81,22 +82,31 @@ ruleTester.run('export', rule, {
     // }),
     test({
       code: 'let foo; export { foo }; export * from "./export-all"',
-      errors: ['Multiple exports of name \'foo\'.',
-        'Multiple exports of name \'foo\'.'],
+      errors: [
+        'Multiple exports of name \'foo\'.',
+        'Multiple exports of name \'foo\'.',
+      ],
     }),
-    // test({ code: 'export * from "./default-export"'
-    //      , errors: [{ message: 'No named exports found in module ' +
-    //                            '\'./default-export\'.'
-    //                 , type: 'Literal' }] }),
+    // test({
+    //   code: 'export * from "./default-export"',
+    //   errors: [
+    //     {
+    //       message: 'No named exports found in module \'./default-export\'.',
+    //       type: 'Literal',
+    //     },
+    //   ],
+    // }),
 
     // note: Espree bump to Acorn 4+ changed this test's error message.
     //       `npm up` first if it's failing.
     test({
       code: 'export * from "./malformed.js"',
-      errors: [{
-        message: "Parse errors in imported module './malformed.js': 'return' outside of function (1:1)",
-        type: 'Literal',
-      }],
+      errors: [
+        {
+          message: "Parse errors in imported module './malformed.js': 'return' outside of function (1:1)",
+          type: 'Literal',
+        },
+      ],
     }),
 
     // test({
@@ -122,7 +132,19 @@ ruleTester.run('export', rule, {
       code: 'export * from "./default-export"',
       errors: [`No named exports found in module './default-export'.`],
     }),
-  ],
+
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'let foo; export { foo as "foo" }; export * from "./export-all"',
+      errors: [
+        'Multiple exports of name \'foo\'.',
+        'Multiple exports of name \'foo\'.',
+      ],
+      parserOptions: {
+        ecmaVersion: 2022,
+      },
+    })),
+  ),
 });
 
 
@@ -137,54 +159,60 @@ context('TypeScript', function () {
     };
 
     ruleTester.run('export', rule, {
-      valid: [
+      valid: [].concat(
         // type/value name clash
-        test(Object.assign({
+        test({
           code: `
             export const Foo = 1;
             export type Foo = number;
           `,
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             export const Foo = 1;
             export interface Foo {}
           `,
-        }, parserConfig)),
+          ...parserConfig,
+        }),
 
-        test(Object.assign({
+        semver.satisfies(tsEslintVersion, '>= 22') ? test({
           code: `
             export function fff(a: string);
             export function fff(a: number);
           `,
-        }, parserConfig)),
+          ...parserConfig,
+        }) : [],
 
-        test(Object.assign({
+        semver.satisfies(tsEslintVersion, '>= 22') ? test({
           code: `
             export function fff(a: string);
             export function fff(a: number);
             export function fff(a: string|number) {};
           `,
-        }, parserConfig)),
+          ...parserConfig,
+        }) : [],
 
         // namespace
-        test(Object.assign({
+        test({
           code: `
             export const Bar = 1;
             export namespace Foo {
               export const Bar = 1;
             }
           `,
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             export type Bar = string;
             export namespace Foo {
               export type Bar = string;
             }
           `,
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             export const Bar = 1;
             export type Bar = string;
@@ -193,8 +221,9 @@ context('TypeScript', function () {
               export type Bar = string;
             }
           `,
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             export namespace Foo {
               export const Foo = 1;
@@ -206,13 +235,56 @@ context('TypeScript', function () {
               }
             }
           `,
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        semver.satisfies(eslintPkg.version, '>= 6') ? [
+          test({
+            code: `
+              export class Foo { }
+              export namespace Foo { }
+              export namespace Foo {
+                export class Bar {}
+              }
+            `,
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export function Foo();
+              export namespace Foo { }
+            `,
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export function Foo(a: string);
+              export namespace Foo { }
+            `,
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export function Foo(a: string);
+              export function Foo(a: number);
+              export namespace Foo { }
+            `,
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export enum Foo { }
+              export namespace Foo { }
+            `,
+            ...parserConfig,
+          }),
+        ] : [],
+        test({
           code: 'export * from "./file1.ts"',
           filename: testFilePath('typescript-d-ts/file-2.ts'),
-        }, parserConfig)),
+          ...parserConfig,
+        }),
 
-        ...(semver.satisfies(eslintPkg.version, '< 6') ? [] : [
+        semver.satisfies(eslintPkg.version, '>= 6') ? [
           test({
             code: `
               export * as A from './named-export-collision/a';
@@ -220,10 +292,10 @@ context('TypeScript', function () {
             `,
             parser,
           }),
-        ]),
+        ] : [],
 
         // Exports in ambient modules
-        test(Object.assign({
+        test({
           code: `
             declare module "a" {
               const Foo = 1;
@@ -234,8 +306,9 @@ context('TypeScript', function () {
               export {Bar as default};
             }
           `,
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             declare module "a" {
               const Foo = 1;
@@ -244,9 +317,10 @@ context('TypeScript', function () {
             const Bar = 2;
             export {Bar as default};
           `,
-        }, parserConfig)),
+          ...parserConfig,
+        }),
 
-        ...(semver.satisfies(process.version, '< 8') && semver.satisfies(eslintPkg.version, '< 6') ? [] : test({
+        semver.satisfies(process.version, '< 8') && semver.satisfies(eslintPkg.version, '< 6') ? [] : test({
           ...parserConfig,
           code: `
             export * from './module';
@@ -256,11 +330,11 @@ context('TypeScript', function () {
             ...parserConfig.settings,
             'import/extensions': ['.js', '.ts', '.jsx'],
           },
-        })),
-      ],
-      invalid: [
+        }),
+      ),
+      invalid: [].concat(
         // type/value name clash
-        test(Object.assign({
+        test({
           code: `
             export type Foo = string;
             export type Foo = number;
@@ -275,10 +349,11 @@ context('TypeScript', function () {
               line: 3,
             },
           ],
-        }, parserConfig)),
+          ...parserConfig,
+        }),
 
         // namespace
-        test(Object.assign({
+        test({
           code: `
             export const a = 1
             export namespace Foo {
@@ -296,8 +371,9 @@ context('TypeScript', function () {
               line: 5,
             },
           ],
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             declare module 'foo' {
               const Foo = 1;
@@ -315,8 +391,9 @@ context('TypeScript', function () {
               line: 5,
             },
           ],
-        }, parserConfig)),
-        test(Object.assign({
+          ...parserConfig,
+        }),
+        test({
           code: `
             export namespace Foo {
               export namespace Bar {
@@ -347,10 +424,138 @@ context('TypeScript', function () {
               line: 9,
             },
           ],
-        }, parserConfig)),
+          ...parserConfig,
+        }),
+        semver.satisfies(eslintPkg.version, '< 6') ? [] : [
+          test({
+            code: `
+              export class Foo { }
+              export class Foo { }
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export enum Foo { }
+              export enum Foo { }
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export enum Foo { }
+              export class Foo { }
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export const Foo = 'bar';
+              export class Foo { }
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export function Foo();
+              export class Foo { }
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export const Foo = 'bar';
+              export function Foo();
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+          test({
+            code: `
+              export const Foo = 'bar';
+              export namespace Foo { }
+            `,
+            errors: [
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 2,
+              },
+              {
+                message: `Multiple exports of name 'Foo'.`,
+                line: 3,
+              },
+            ],
+            ...parserConfig,
+          }),
+        ],
 
         // Exports in ambient modules
-        test(Object.assign({
+        test({
           code: `
             declare module "a" {
               const Foo = 1;
@@ -371,8 +576,9 @@ context('TypeScript', function () {
               line: 9,
             },
           ],
-        }, parserConfig)),
-      ],
+          ...parserConfig,
+        }),
+      ),
     });
   });
 });
diff --git a/tests/src/rules/extensions.js b/tests/src/rules/extensions.js
index 93ebc28f..cf93fac9 100644
--- a/tests/src/rules/extensions.js
+++ b/tests/src/rules/extensions.js
@@ -1,6 +1,6 @@
 import { RuleTester } from 'eslint';
 import rule from 'rules/extensions';
-import { getTSParsers, test, testFilePath } from '../utils';
+import { getTSParsers, test, testFilePath, parsers } from '../utils';
 
 const ruleTester = new RuleTester();
 
@@ -601,7 +601,7 @@ ruleTester.run('extensions', rule, {
 describe('TypeScript', () => {
   getTSParsers()
     // Type-only imports were added in TypeScript ESTree 2.23.0
-    .filter((parser) => parser !== require.resolve('typescript-eslint-parser'))
+    .filter((parser) => parser !== parsers.TS_OLD)
     .forEach((parser) => {
       ruleTester.run(`${parser}: extensions ignore type-only`, rule, {
         valid: [
diff --git a/tests/src/rules/max-dependencies.js b/tests/src/rules/max-dependencies.js
index 6d80bbf0..982a4b42 100644
--- a/tests/src/rules/max-dependencies.js
+++ b/tests/src/rules/max-dependencies.js
@@ -1,4 +1,4 @@
-import { test, getTSParsers } from '../utils';
+import { test, getTSParsers, parsers } from '../utils';
 
 import { RuleTester } from 'eslint';
 
@@ -66,7 +66,7 @@ ruleTester.run('max-dependencies', rule, {
 
     test({
       code: 'import type { x } from \'./foo\'; import type { y } from \'./bar\'',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       options: [{
         max: 1,
       }],
@@ -77,7 +77,7 @@ ruleTester.run('max-dependencies', rule, {
 
     test({
       code: 'import type { x } from \'./foo\'; import type { y } from \'./bar\'; import type { z } from \'./baz\'',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       options: [{
         max: 2,
         ignoreTypeImports: false,
@@ -92,7 +92,7 @@ ruleTester.run('max-dependencies', rule, {
 describe('TypeScript', () => {
   getTSParsers()
     // Type-only imports were added in TypeScript ESTree 2.23.0
-    .filter((parser) => parser !== require.resolve('typescript-eslint-parser'))
+    .filter((parser) => parser !== parsers.TS_OLD)
     .forEach((parser) => {
       ruleTester.run(`max-dependencies (${parser.replace(process.cwd(), '.')})`, rule, {
         valid: [
diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js
index 10ba76b7..b5500a6d 100644
--- a/tests/src/rules/named.js
+++ b/tests/src/rules/named.js
@@ -1,4 +1,4 @@
-import { test, SYNTAX_CASES, getTSParsers, testFilePath, testVersion } from '../utils';
+import { test, SYNTAX_CASES, getTSParsers, testFilePath, testVersion, parsers } from '../utils';
 import { RuleTester } from 'eslint';
 
 import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve';
@@ -7,9 +7,8 @@ import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve';
 const ruleTester = new RuleTester();
 const rule = require('rules/named');
 
-function error(name, module) {
-  return { message: name + ' not found in \'' + module + '\'',
-    type: 'Identifier' };
+function error(name, module, type = 'Identifier') {
+  return { message: name + ' not found in \'' + module + '\'', type };
 }
 
 ruleTester.run('named', rule, {
@@ -55,11 +54,11 @@ ruleTester.run('named', rule, {
     // es7
     test({
       code: 'export bar, { foo } from "./bar"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import { foo, bar } from "./named-trampoline"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // regression tests
@@ -74,43 +73,43 @@ ruleTester.run('named', rule, {
     // should ignore imported/exported flow types, even if they don’t exist
     test({
       code: 'import type { MissingType } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import typeof { MissingType } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import type { MyOpaqueType } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import typeof { MyOpaqueType } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import { type MyOpaqueType, MyClass } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import { typeof MyOpaqueType, MyClass } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import typeof MissingType from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import typeof * as MissingType from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'export type { MissingType } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'export type { MyOpaqueType } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // jsnext
@@ -199,10 +198,16 @@ ruleTester.run('named', rule, {
 
     testVersion('>=7.8.0', () => ({ code: 'import { something } from "./dynamic-import-in-commonjs"',
       parserOptions: { ecmaVersion: 2021 } })),
+
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import { "foo" as foo } from "./bar"', parserOptions: { ecmaVersion: 2022 } })),
+    testVersion('>= 8.7', () => ({
+      code: 'import { "foo" as foo } from "./empty-module"', parserOptions: { ecmaVersion: 2022 } })),
     ),
   ],
 
-  invalid: [
+  invalid: [].concat(
     test({ code: 'import { somethingElse } from "./test-module"',
       errors: [ error('somethingElse', './test-module') ] }),
 
@@ -239,17 +244,17 @@ ruleTester.run('named', rule, {
     // es7
     test({
       code: 'export bar2, { bar } from "./bar"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ["bar not found in './bar'"],
     }),
     test({
       code: 'import { foo, bar, baz } from "./named-trampoline"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ["baz not found in './named-trampoline'"],
     }),
     test({
       code: 'import { baz } from "./broken-trampoline"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ['baz not found via broken-trampoline.js -> named-exports.js'],
     }),
 
@@ -289,7 +294,7 @@ ruleTester.run('named', rule, {
 
     test({
       code: 'import  { type MyOpaqueType, MyMissingClass } from "./flowtypes"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ["MyMissingClass not found in './flowtypes'"],
     }),
 
@@ -323,7 +328,24 @@ ruleTester.run('named', rule, {
       code: 'import { default as barDefault } from "./re-export"',
       errors: [`default not found in './re-export'`],
     }),
-  ],
+
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import { "somethingElse" as somethingElse } from "./test-module"',
+      errors: [ error('somethingElse', './test-module', 'Literal') ],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+    testVersion('>= 8.7', () => ({
+      code: 'import { "baz" as baz, "bop" as bop } from "./bar"',
+      errors: [error('baz', './bar', 'Literal'), error('bop', './bar', 'Literal')],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+    testVersion('>= 8.7', () => ({
+      code: 'import { "default" as barDefault } from "./re-export"',
+      errors: [`default not found in './re-export'`],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+  ),
 });
 
 // #311: import of mismatched case
diff --git a/tests/src/rules/namespace.js b/tests/src/rules/namespace.js
index 826637b9..1465d213 100644
--- a/tests/src/rules/namespace.js
+++ b/tests/src/rules/namespace.js
@@ -1,4 +1,4 @@
-import { test, SYNTAX_CASES, getTSParsers, testVersion, testFilePath } from '../utils';
+import { test, SYNTAX_CASES, getTSParsers, testVersion, testFilePath, parsers } from '../utils';
 import { RuleTester } from 'eslint';
 import flatMap from 'array.prototype.flatmap';
 
@@ -57,16 +57,16 @@ const valid = [
   // es7 //
   /////////
   test({ code: 'export * as names from "./named-exports"',
-    parser: require.resolve('babel-eslint') }),
+    parser: parsers.BABEL_OLD }),
   test({ code: 'export defport, * as names from "./named-exports"',
-    parser: require.resolve('babel-eslint') }),
+    parser: parsers.BABEL_OLD }),
   // non-existent is handled by no-unresolved
   test({ code: 'export * as names from "./does-not-exist"',
-    parser: require.resolve('babel-eslint') }),
+    parser: parsers.BABEL_OLD }),
 
   test({
     code: 'import * as Endpoints from "./issue-195/Endpoints"; console.log(Endpoints.Users)',
-    parser: require.resolve('babel-eslint'),
+    parser: parsers.BABEL_OLD,
   }),
 
   // respect hoisting
@@ -81,11 +81,11 @@ const valid = [
   test({ code: "import * as names from './default-export'; console.log(names.default)" }),
   test({
     code: 'export * as names from "./default-export"',
-    parser: require.resolve('babel-eslint'),
+    parser: parsers.BABEL_OLD,
   }),
   test({
     code: 'export defport, * as names from "./default-export"',
-    parser: require.resolve('babel-eslint'),
+    parser: parsers.BABEL_OLD,
   }),
 
   // #456: optionally ignore computed references
@@ -103,7 +103,7 @@ const valid = [
   }),
   test({
     code: `import * as names from './named-exports'; const {a, b, ...rest} = names;`,
-    parser: require.resolve('babel-eslint'),
+    parser: parsers.BABEL_OLD,
   }),
 
   // #1144: should handle re-export CommonJS as namespace
@@ -183,10 +183,35 @@ const valid = [
     parserOptions: {
       ecmaVersion: 2020,
     },
-  })) || []),
+  })),
+  // es2022: Arbitrary module namespace identifier names
+  testVersion('>= 8.7', () => ({
+    code: "import * as names from './default-export-string';",
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+  testVersion('>= 8.7', () => ({
+    code: "import * as names from './default-export-string'; console.log(names.default)",
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+  testVersion('>= 8.7', () => ({
+    code: "import * as names from './default-export-namespace-string';",
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+  testVersion('>= 8.7', () => ({
+    code: "import * as names from './default-export-namespace-string'; console.log(names.default)",
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+  testVersion('>= 8.7', () => ({
+    code: `import { "b" as b } from "./deep/a"; console.log(b.c.d.e)`,
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+  testVersion('>= 8.7', () => ({
+    code: `import { "b" as b } from "./deep/a"; var {c:{d:{e}}} = b`,
+    parserOptions: { ecmaVersion: 2022 },
+  }))),
 ];
 
-const invalid = [
+const invalid = [].concat(
   test({ code: "import * as names from './named-exports'; " +
                ' console.log(names.c);',
   errors: [error('c', 'names')] }),
@@ -226,7 +251,7 @@ const invalid = [
 
   test({
     code: 'import * as Endpoints from "./issue-195/Endpoints"; console.log(Endpoints.Foo)',
-    parser: require.resolve('babel-eslint'),
+    parser: parsers.BABEL_OLD,
     errors: ["'Foo' not found in imported namespace 'Endpoints'."],
   }),
 
@@ -275,12 +300,23 @@ const invalid = [
     },
   }),
 
-]
+  // es2022: Arbitrary module namespace identifier names
+  testVersion('>= 8.7', () => ({
+    code: `import { "b" as b } from "./deep/a"; console.log(b.e)`,
+    errors: [ "'e' not found in imported namespace 'b'." ],
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+  testVersion('>= 8.7', () => ({
+    code: `import { "b" as b } from "./deep/a"; console.log(b.c.e)`,
+    errors: [ "'e' not found in deeply imported namespace 'b.c'." ],
+    parserOptions: { ecmaVersion: 2022 },
+  })),
+)
 
 ///////////////////////
 // deep dereferences //
 //////////////////////
-;[['deep', require.resolve('espree')], ['deep-es7', require.resolve('babel-eslint')]].forEach(function ([folder, parser]) { // close over params
+;[['deep', require.resolve('espree')], ['deep-es7', parsers.BABEL_OLD]].forEach(function ([folder, parser]) { // close over params
   valid.push(
     test({ parser, code: `import * as a from "./${folder}/a"; console.log(a.b.c.d.e)` }),
     test({ parser, code: `import { b } from "./${folder}/a"; console.log(b.c.d.e)` }),
diff --git a/tests/src/rules/newline-after-import.js b/tests/src/rules/newline-after-import.js
index a00e8690..80cc076c 100644
--- a/tests/src/rules/newline-after-import.js
+++ b/tests/src/rules/newline-after-import.js
@@ -1,7 +1,9 @@
 import { RuleTester } from 'eslint';
 import flatMap from 'array.prototype.flatmap';
+import semver from 'semver';
+import { version as tsEslintVersion } from 'typescript-eslint-parser/package.json';
 
-import { getTSParsers, testVersion } from '../utils';
+import { getTSParsers, parsers, testVersion } from '../utils';
 
 const IMPORT_ERROR_MESSAGE = 'Expected 1 empty line after import statement not followed by another import.';
 const IMPORT_ERROR_MESSAGE_MULTIPLE = (count) => {
@@ -12,7 +14,7 @@ const REQUIRE_ERROR_MESSAGE = 'Expected 1 empty line after require statement not
 const ruleTester = new RuleTester();
 
 ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
-  valid: [
+  valid: [].concat(
     `var path = require('path');\nvar foo = require('foo');\n`,
     `require('foo');`,
     `switch ('foo') { case 'bar': require('baz'); }`,
@@ -161,24 +163,24 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         class App {}
       `,
       parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     {
       code: `var foo = require('foo');\n\n@SomeDecorator(foo)\nclass Foo {}`,
       parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     {
       code : `// issue 1004\nimport foo from 'foo';\n\n@SomeDecorator(foo)\nexport default class Test {}`,
       parserOptions: { sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     {
       code : `// issue 1004\nconst foo = require('foo');\n\n@SomeDecorator(foo)\nexport default class Test {}`,
       parserOptions: { sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
-    ...flatMap(getTSParsers(), (parser) => [
+    flatMap(getTSParsers(), (parser) => [].concat(
       {
         code: `
           import { ExecaReturnValue } from 'execa';
@@ -213,14 +215,14 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         parser,
         parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
       },
-      {
+      parser !== parsers.TS_OLD || semver.satisfies(tsEslintVersion, '>= 22') ? {
         code: `
           export import a = obj;\nf(a);
         `,
         parser,
         parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
-      },
-      {
+      } : [],
+      parser !== parsers.TS_OLD || semver.satisfies(tsEslintVersion, '>= 22') ? {
         code: `
           import { a } from "./a";
 
@@ -230,7 +232,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
           }`,
         parser,
         parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
-      },
+      } : [],
       {
         code: `
           import stub from './stub';
@@ -242,7 +244,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         parser,
         parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
       },
-    ]),
+    )),
     {
       code: `
         import stub from './stub';
@@ -253,7 +255,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
       `,
       parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
     },
-  ],
+  ),
 
   invalid: [].concat(
     {
@@ -415,7 +417,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         message: IMPORT_ERROR_MESSAGE,
       } ],
       parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     {
       code: `var foo = require('foo');\n@SomeDecorator(foo)\nclass Foo {}`,
@@ -426,7 +428,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         message: REQUIRE_ERROR_MESSAGE,
       } ],
       parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     {
       code: `// issue 10042\nimport foo from 'foo';\n@SomeDecorator(foo)\nexport default class Test {}`,
@@ -437,7 +439,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         message: IMPORT_ERROR_MESSAGE,
       } ],
       parserOptions: { sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     {
       code: `// issue 1004\nconst foo = require('foo');\n@SomeDecorator(foo)\nexport default class Test {}`,
@@ -448,7 +450,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         message: REQUIRE_ERROR_MESSAGE,
       } ],
       parserOptions: { sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     },
     testVersion('>= 6', () => ({
       code: `
@@ -472,7 +474,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), {
         },
       ],
       parserOptions: { sourceType: 'module' },
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     })) || [],
   ),
 });
diff --git a/tests/src/rules/no-anonymous-default-export.js b/tests/src/rules/no-anonymous-default-export.js
index 231f1b66..0428ee1b 100644
--- a/tests/src/rules/no-anonymous-default-export.js
+++ b/tests/src/rules/no-anonymous-default-export.js
@@ -1,4 +1,4 @@
-import { test, SYNTAX_CASES } from '../utils';
+import { test, testVersion, SYNTAX_CASES } from '../utils';
 
 import { RuleTester } from 'eslint';
 
@@ -6,7 +6,7 @@ const ruleTester = new RuleTester();
 const rule = require('rules/no-anonymous-default-export');
 
 ruleTester.run('no-anonymous-default-export', rule, {
-  valid: [
+  valid: [].concat(
     // Exports with identifiers are valid
     test({ code: 'const foo = 123\nexport default foo' }),
     test({ code: 'export default function foo() {}' }),
@@ -31,12 +31,17 @@ ruleTester.run('no-anonymous-default-export', rule, {
     test({ code: 'export * from \'foo\'' }),
     test({ code: 'const foo = 123\nexport { foo }' }),
     test({ code: 'const foo = 123\nexport { foo as default }' }),
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'const foo = 123\nexport { foo as "default" }',
+      parserOptions: { ecmaVersion: 2022 },
+    })),
 
     // Allow call expressions by default for backwards compatibility
     test({ code: 'export default foo(bar)' }),
 
     ...SYNTAX_CASES,
-  ],
+  ),
 
   invalid: [
     test({ code: 'export default []', errors: [{ message: 'Assign array to a variable before exporting as module default' }] }),
diff --git a/tests/src/rules/no-cycle.js b/tests/src/rules/no-cycle.js
index c4e3235e..22e097dd 100644
--- a/tests/src/rules/no-cycle.js
+++ b/tests/src/rules/no-cycle.js
@@ -1,4 +1,4 @@
-import { test as _test, testFilePath } from '../utils';
+import { parsers, test as _test, testFilePath } from '../utils';
 
 import { RuleTester } from 'eslint';
 import flatMap from 'array.prototype.flatmap';
@@ -63,36 +63,36 @@ ruleTester.run('no-cycle', rule, {
       test({
         code: `import("./${testDialect}/depth-two").then(function({ foo }) {})`,
         options: [{ maxDepth: 1 }],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: `import type { FooType } from "./${testDialect}/depth-one"`,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: `import type { FooType, BarType } from "./${testDialect}/depth-one"`,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
     ]),
 
     test({
       code: 'import { bar } from "./flow-types"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import { bar } from "./flow-types-only-importing-type"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import { bar } from "./flow-types-only-importing-multiple-types"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
   ),
 
   invalid: [].concat(
     test({
       code: 'import { bar } from "./flow-types-some-type-imports"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [error(`Dependency cycle detected.`)],
     }),
     test({
@@ -166,17 +166,17 @@ ruleTester.run('no-cycle', rule, {
       test({
         code: `import { bar } from "./${testDialect}/depth-three-indirect"`,
         errors: [error(`Dependency cycle via ./depth-two:1=>./depth-one:1`)],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: `import("./${testDialect}/depth-three-star")`,
         errors: [error(`Dependency cycle via ./depth-two:1=>./depth-one:1`)],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: `import("./${testDialect}/depth-three-indirect")`,
         errors: [error(`Dependency cycle via ./depth-two:1=>./depth-one:1`)],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: `import { foo } from "./${testDialect}/depth-two"`,
@@ -192,7 +192,7 @@ ruleTester.run('no-cycle', rule, {
 
     test({
       code: 'import { bar } from "./flow-types-depth-one"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [error(`Dependency cycle via ./flow-types-depth-two:4=>./es6/depth-one:1`)],
     }),
   ),
diff --git a/tests/src/rules/no-default-export.js b/tests/src/rules/no-default-export.js
index 61e55d95..6c1a85a1 100644
--- a/tests/src/rules/no-default-export.js
+++ b/tests/src/rules/no-default-export.js
@@ -1,4 +1,4 @@
-import { test, testVersion } from '../utils';
+import { parsers, test, testVersion } from '../utils';
 
 import { RuleTester } from 'eslint';
 
@@ -58,7 +58,7 @@ ruleTester.run('no-default-export', rule, {
     }),
     test({
       code: 'export { a, b } from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // no exports at all
@@ -74,15 +74,15 @@ ruleTester.run('no-default-export', rule, {
 
     test({
       code: `export type UserId = number;`,
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'export foo from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: `export Memory, { MemoryValue } from './Memory'`,
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
   ],
   invalid: [].concat(
@@ -154,7 +154,7 @@ ruleTester.run('no-default-export', rule, {
     }),
     test({
       code: 'export default from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [
         {
           type: 'ExportNamedDeclaration',
@@ -162,5 +162,16 @@ ruleTester.run('no-default-export', rule, {
         },
       ],
     }),
+    // es2022: Arbitrary module namespae identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'let foo; export { foo as "default" }',
+      errors: [
+        {
+          type: 'ExportNamedDeclaration',
+          message: 'Do not alias `foo` as `default`. Just export `foo` itself instead.',
+        },
+      ],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
   ),
 });
diff --git a/tests/src/rules/no-duplicates.js b/tests/src/rules/no-duplicates.js
index ad39543f..cde41b3a 100644
--- a/tests/src/rules/no-duplicates.js
+++ b/tests/src/rules/no-duplicates.js
@@ -1,5 +1,5 @@
 import * as path from 'path';
-import { test as testUtil, getNonDefaultParsers } from '../utils';
+import { test as testUtil, getNonDefaultParsers, parsers } from '../utils';
 
 import { RuleTester } from 'eslint';
 import eslintPkg from 'eslint/package.json';
@@ -26,7 +26,7 @@ ruleTester.run('no-duplicates', rule, {
     // #225: ignore duplicate if is a flow type import
     test({
       code: "import { x } from './foo'; import type { y } from './foo'",
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // #1107: Using different query strings that trigger different webpack loaders.
@@ -107,7 +107,7 @@ ruleTester.run('no-duplicates', rule, {
     test({
       code: "import type { x } from './foo'; import type { y } from './foo'",
       output: "import type { x , y } from './foo'; ",
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: ['\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.'],
     }),
 
@@ -418,7 +418,7 @@ import {x,y} from './foo'
 context('TypeScript', function () {
   getNonDefaultParsers()
     // Type-only imports were added in TypeScript ESTree 2.23.0
-    .filter((parser) => parser !== require.resolve('typescript-eslint-parser'))
+    .filter((parser) => parser !== parsers.TS_OLD)
     .forEach((parser) => {
       const parserConfig = {
         parser,
@@ -454,6 +454,20 @@ context('TypeScript', function () {
             `,
             ...parserConfig,
           }),
+          test({
+            code: `
+              import type { Identifier } from 'module';
+
+              declare module 'module2' {
+                import type { Identifier } from 'module';
+              }
+
+              declare module 'module3' {
+                import type { Identifier } from 'module';
+              }
+            `,
+            ...parserConfig,
+          }),
         ],
         invalid: [
           test({
diff --git a/tests/src/rules/no-dynamic-require.js b/tests/src/rules/no-dynamic-require.js
index 4a70e7bc..0b141ccd 100644
--- a/tests/src/rules/no-dynamic-require.js
+++ b/tests/src/rules/no-dynamic-require.js
@@ -1,6 +1,7 @@
-import { test } from '../utils';
+import { parsers, test, testVersion } from '../utils';
 
 import { RuleTester } from 'eslint';
+import flatMap from 'array.prototype.flatmap';
 
 const ruleTester = new RuleTester();
 const rule = require('rules/no-dynamic-require');
@@ -28,56 +29,93 @@ ruleTester.run('no-dynamic-require', rule, {
     test({ code: 'var foo = require("@scope/foo")' }),
 
     //dynamic import
-    test({
-      code: 'import("foo")',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import(`foo`)',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import("./foo")',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import("@scope/foo")',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'var foo = import("foo")',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'var foo = import(`foo`)',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'var foo = import("./foo")',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'var foo = import("@scope/foo")',
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import("../" + name)',
-      errors: [dynamicImportError],
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: false }],
-    }),
-    test({
-      code: 'import(`../${name}`)',
-      errors: [dynamicImportError],
-      parser: require.resolve('babel-eslint'),
+    ...flatMap([parsers.ESPREE, parsers.BABEL_OLD], (parser) => {
+      const _test =
+        parser === parsers.ESPREE
+          ? (testObj) => testVersion('>= 6.2.0', () => testObj)
+          : (testObj) => test(testObj);
+      return [].concat(
+        _test({
+          code: 'import("foo")',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import(`foo`)',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import("./foo")',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import("@scope/foo")',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'var foo = import("foo")',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'var foo = import(`foo`)',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'var foo = import("./foo")',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'var foo = import("@scope/foo")',
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import("../" + name)',
+          errors: [dynamicImportError],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import(`../${name}`)',
+          errors: [dynamicImportError],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+      );
     }),
   ],
   invalid: [
@@ -104,29 +142,49 @@ ruleTester.run('no-dynamic-require', rule, {
     }),
 
     // dynamic import
-    test({
-      code: 'import("../" + name)',
-      errors: [dynamicImportError],
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import(`../${name}`)',
-      errors: [dynamicImportError],
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import(name)',
-      errors: [dynamicImportError],
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
-    }),
-    test({
-      code: 'import(name())',
-      errors: [dynamicImportError],
-      parser: require.resolve('babel-eslint'),
-      options: [{ esmodule: true }],
+    ...flatMap([parsers.ESPREE, parsers.BABEL_OLD], (parser) => {
+      const _test =
+        parser === parsers.ESPREE
+          ? (testObj) => testVersion('>= 6.2.0', () => testObj)
+          : (testObj) => test(testObj);
+      return [].concat(
+        _test({
+          code: 'import("../" + name)',
+          errors: [dynamicImportError],
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import(`../${name}`)',
+          errors: [dynamicImportError],
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import(name)',
+          errors: [dynamicImportError],
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+        _test({
+          code: 'import(name())',
+          errors: [dynamicImportError],
+          options: [{ esmodule: true }],
+          parser,
+          parserOptions: {
+            ecmaVersion: 2020,
+          },
+        }),
+      );
     }),
     test({
       code: 'require(`foo${x}`)',
diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js
index d4c9f6d7..d4e3886b 100644
--- a/tests/src/rules/no-extraneous-dependencies.js
+++ b/tests/src/rules/no-extraneous-dependencies.js
@@ -1,4 +1,4 @@
-import { getTSParsers, test, testFilePath } from '../utils';
+import { getTSParsers, parsers, test, testFilePath } from '../utils';
 import typescriptConfig from '../../../config/typescript';
 import path from 'path';
 import fs from 'fs';
@@ -82,7 +82,7 @@ ruleTester.run('no-extraneous-dependencies', rule, {
     test({
       code: 'import type MyType from "myflowtyped";',
       options: [{ packageDir: packageDirWithFlowTyped }],
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: `
@@ -90,7 +90,7 @@ ruleTester.run('no-extraneous-dependencies', rule, {
         import typeof TypeScriptModule from 'typescript';
       `,
       options: [{ packageDir: packageDirWithFlowTyped }],
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import react from "react";',
@@ -398,7 +398,7 @@ ruleTester.run('no-extraneous-dependencies', rule, {
 describe('TypeScript', () => {
   getTSParsers()
     // Type-only imports were added in TypeScript ESTree 2.23.0
-    .filter((parser) => parser !== require.resolve('typescript-eslint-parser'))
+    .filter((parser) => parser !== parsers.TS_OLD)
     .forEach((parser) => {
       const parserConfig = {
         parser,
@@ -433,12 +433,12 @@ typescriptRuleTester.run('no-extraneous-dependencies typescript type imports', r
     test({
       code: 'import type MyType from "not-a-dependency";',
       filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import type { MyType } from "not-a-dependency";',
       filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
   ],
   invalid: [
diff --git a/tests/src/rules/no-mutable-exports.js b/tests/src/rules/no-mutable-exports.js
index 2ecae48c..1171443c 100644
--- a/tests/src/rules/no-mutable-exports.js
+++ b/tests/src/rules/no-mutable-exports.js
@@ -1,11 +1,11 @@
-import { test } from '../utils';
+import { parsers, test, testVersion } from '../utils';
 import { RuleTester } from 'eslint';
 import rule from 'rules/no-mutable-exports';
 
 const ruleTester = new RuleTester();
 
 ruleTester.run('no-mutable-exports', rule, {
-  valid: [
+  valid: [].concat(
     test({ code: 'export const count = 1' }),
     test({ code: 'export function getCount() {}' }),
     test({ code: 'export class Counter {}' }),
@@ -25,15 +25,19 @@ ruleTester.run('no-mutable-exports', rule, {
     test({ code: 'class Counter {}\nexport default Counter' }),
     test({ code: 'class Counter {}\nexport { Counter as default }' }),
     test({
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       code: 'export Something from "./something";',
     }),
     test({
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       code: 'type Foo = {}\nexport type {Foo}',
     }),
-  ],
-  invalid: [
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'const count = 1\nexport { count as "counter" }', parserOptions: { ecmaVersion: 2022 },
+    })),
+  ),
+  invalid: [].concat(
     test({
       code: 'export let count = 1',
       errors: ['Exporting mutable \'let\' binding, use \'const\' instead.'],
@@ -66,6 +70,12 @@ ruleTester.run('no-mutable-exports', rule, {
       code: 'var count = 1\nexport default count',
       errors: ['Exporting mutable \'var\' binding, use \'const\' instead.'],
     }),
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'let count = 1\nexport { count as "counter" }',
+      errors: ['Exporting mutable \'let\' binding, use \'const\' instead.'],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
 
     // todo: undeclared globals
     // test({
@@ -76,5 +86,5 @@ ruleTester.run('no-mutable-exports', rule, {
     //   code: 'count = 1\nexport default count',
     //   errors: ['Exporting mutable global binding, use \'const\' instead.'],
     // }),
-  ],
+  ),
 });
diff --git a/tests/src/rules/no-named-as-default-member.js b/tests/src/rules/no-named-as-default-member.js
index b4f3cf58..53cba230 100644
--- a/tests/src/rules/no-named-as-default-member.js
+++ b/tests/src/rules/no-named-as-default-member.js
@@ -1,21 +1,27 @@
-import { test, SYNTAX_CASES } from '../utils';
+import { test, testVersion, SYNTAX_CASES } from '../utils';
 import { RuleTester } from 'eslint';
 import rule from 'rules/no-named-as-default-member';
 
 const ruleTester = new RuleTester();
 
 ruleTester.run('no-named-as-default-member', rule, {
-  valid: [
+  valid: [].concat(
     test({ code: 'import bar, {foo} from "./bar";' }),
     test({ code: 'import bar from "./bar"; const baz = bar.baz' }),
     test({ code: 'import {foo} from "./bar"; const baz = foo.baz;' }),
     test({ code: 'import * as named from "./named-exports"; const a = named.a' }),
     test({ code: 'import foo from "./default-export-default-property"; const a = foo.default' }),
 
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import bar, { foo } from "./export-default-string-and-named"',
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+
     ...SYNTAX_CASES,
-  ],
+  ),
 
-  invalid: [
+  invalid: [].concat(
     test({
       code: 'import bar from "./bar"; const foo = bar.foo;',
       errors: [{
@@ -56,5 +62,17 @@ ruleTester.run('no-named-as-default-member', rule, {
         type: 'Identifier',
       }],
     }),
-  ],
+    // es2022: Arbitrary module namespace identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import bar from "./export-default-string-and-named"; const foo = bar.foo;',
+      errors: [{
+        message: (
+          'Caution: `bar` also has a named export `foo`. ' +
+          'Check if you meant to write `import {foo} from \'./export-default-string-and-named\'` instead.'
+        ),
+        type: 'MemberExpression',
+      }],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+  ),
 });
diff --git a/tests/src/rules/no-named-as-default.js b/tests/src/rules/no-named-as-default.js
index 57b2f53b..04ec28e6 100644
--- a/tests/src/rules/no-named-as-default.js
+++ b/tests/src/rules/no-named-as-default.js
@@ -1,11 +1,11 @@
-import { test, SYNTAX_CASES } from '../utils';
+import { test, testVersion, SYNTAX_CASES, parsers } from '../utils';
 import { RuleTester } from 'eslint';
 
 const ruleTester = new RuleTester();
 const rule = require('rules/no-named-as-default');
 
 ruleTester.run('no-named-as-default', rule, {
-  valid: [
+  valid: [].concat(
     test({ code: 'import "./malformed.js"' }),
 
     test({ code: 'import bar, { foo } from "./bar";' }),
@@ -13,18 +13,24 @@ ruleTester.run('no-named-as-default', rule, {
 
     // es7
     test({ code: 'export bar, { foo } from "./bar";',
-      parser: require.resolve('babel-eslint') }),
+      parser: parsers.BABEL_OLD }),
     test({ code: 'export bar from "./bar";',
-      parser: require.resolve('babel-eslint') }),
+      parser: parsers.BABEL_OLD }),
 
     // #566: don't false-positive on `default` itself
     test({ code: 'export default from "./bar";',
-      parser: require.resolve('babel-eslint') }),
+      parser: parsers.BABEL_OLD }),
+
+    // es2022: Arbitrary module namespae identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import bar, { foo } from "./export-default-string-and-named"',
+      parserOptions: { ecmaVersion: 2022 },
+    })),
 
     ...SYNTAX_CASES,
-  ],
+  ),
 
-  invalid: [
+  invalid: [].concat(
     test({
       code: 'import foo from "./bar";',
       errors: [ {
@@ -39,13 +45,13 @@ ruleTester.run('no-named-as-default', rule, {
     // es7
     test({
       code: 'export foo from "./bar";',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [ {
         message: 'Using exported name \'foo\' as identifier for default export.',
         type: 'ExportDefaultSpecifier' } ] }),
     test({
       code: 'export foo, { foo as bar } from "./bar";',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [ {
         message: 'Using exported name \'foo\' as identifier for default export.',
         type: 'ExportDefaultSpecifier' } ] }),
@@ -57,5 +63,23 @@ ruleTester.run('no-named-as-default', rule, {
         type: 'Literal',
       }],
     }),
-  ],
+
+    // es2022: Arbitrary module namespae identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import foo from "./export-default-string-and-named"',
+      errors: [{
+        message: 'Using exported name \'foo\' as identifier for default export.',
+        type: 'ImportDefaultSpecifier',
+      }],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+    testVersion('>= 8.7', () => ({
+      code: 'import foo, { foo as bar } from "./export-default-string-and-named"',
+      errors: [{
+        message: 'Using exported name \'foo\' as identifier for default export.',
+        type: 'ImportDefaultSpecifier',
+      }],
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+  ),
 });
diff --git a/tests/src/rules/no-named-default.js b/tests/src/rules/no-named-default.js
index 56470f2b..191c9c6c 100644
--- a/tests/src/rules/no-named-default.js
+++ b/tests/src/rules/no-named-default.js
@@ -1,4 +1,4 @@
-import { test, SYNTAX_CASES } from '../utils';
+import { test, testVersion, SYNTAX_CASES, parsers } from '../utils';
 import { RuleTester } from 'eslint';
 
 const ruleTester = new RuleTester();
@@ -12,24 +12,24 @@ ruleTester.run('no-named-default', rule, {
     // Should ignore imported flow types
     test({
       code: 'import { type default as Foo } from "./bar";',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'import { typeof default as Foo } from "./bar";',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     ...SYNTAX_CASES,
   ],
 
-  invalid: [
+  invalid: [].concat(
     /*test({
       code: 'import { default } from "./bar";',
       errors: [{
         message: 'Use default import syntax to import \'default\'.',
         type: 'Identifier',
       }],
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),*/
     test({
       code: 'import { default as bar } from "./bar";',
@@ -45,5 +45,17 @@ ruleTester.run('no-named-default', rule, {
         type: 'Identifier',
       }],
     }),
-  ],
+
+    // es2022: Arbitrary module namespae identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'import { "default" as bar } from "./bar";',
+      errors: [{
+        message: 'Use default import syntax to import \'bar\'.',
+        type: 'Identifier',
+      }],
+      parserOptions: {
+        ecmaVersion: 2022,
+      },
+    })) || [],
+  ),
 });
diff --git a/tests/src/rules/no-named-export.js b/tests/src/rules/no-named-export.js
index 41d0fcd7..58b5da2f 100644
--- a/tests/src/rules/no-named-export.js
+++ b/tests/src/rules/no-named-export.js
@@ -1,11 +1,11 @@
 import { RuleTester } from 'eslint';
-import { test } from '../utils';
+import { parsers, test, testVersion } from '../utils';
 
 const ruleTester = new RuleTester();
 const rule = require('rules/no-named-export');
 
 ruleTester.run('no-named-export', rule, {
-  valid: [
+  valid: [].concat(
     test({
       code: 'export default function bar() {};',
     }),
@@ -14,7 +14,7 @@ ruleTester.run('no-named-export', rule, {
     }),
     test({
       code: 'export default from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // no exports at all
@@ -27,7 +27,13 @@ ruleTester.run('no-named-export', rule, {
     test({
       code: `import {default as foo} from './foo';`,
     }),
-  ],
+
+    // es2022: Arbitrary module namespae identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'let foo; export { foo as "default" }',
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+  ),
   invalid: [
     test({
       code: `
@@ -146,7 +152,7 @@ ruleTester.run('no-named-export', rule, {
     }),
     test({
       code: 'export { a, b } from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [{
         type: 'ExportNamedDeclaration',
         message: 'Named exports are not allowed.',
@@ -154,7 +160,7 @@ ruleTester.run('no-named-export', rule, {
     }),
     test({
       code: `export type UserId = number;`,
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [{
         type: 'ExportNamedDeclaration',
         message: 'Named exports are not allowed.',
@@ -162,7 +168,7 @@ ruleTester.run('no-named-export', rule, {
     }),
     test({
       code: 'export foo from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [{
         type: 'ExportNamedDeclaration',
         message: 'Named exports are not allowed.',
@@ -170,7 +176,7 @@ ruleTester.run('no-named-export', rule, {
     }),
     test({
       code: `export Memory, { MemoryValue } from './Memory'`,
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       errors: [{
         type: 'ExportNamedDeclaration',
         message: 'Named exports are not allowed.',
diff --git a/tests/src/rules/no-nodejs-modules.js b/tests/src/rules/no-nodejs-modules.js
index 3587a71d..9be60570 100644
--- a/tests/src/rules/no-nodejs-modules.js
+++ b/tests/src/rules/no-nodejs-modules.js
@@ -1,6 +1,7 @@
 import { test } from '../utils';
 
 import { RuleTester } from 'eslint';
+const isCore = require('is-core-module');
 
 const ruleTester = new RuleTester();
 const rule = require('rules/no-nodejs-modules');
@@ -10,7 +11,7 @@ const error = message => ({
 });
 
 ruleTester.run('no-nodejs-modules', rule, {
-  valid: [
+  valid: [].concat(
     test({ code: 'import _ from "lodash"' }),
     test({ code: 'import find from "lodash.find"' }),
     test({ code: 'import foo from "./foo"' }),
@@ -55,8 +56,42 @@ ruleTester.run('no-nodejs-modules', rule, {
         allow: ['path', 'events'],
       }],
     }),
-  ],
-  invalid: [
+    isCore('node:events') ? [
+      test({
+        code: 'import events from "node:events"',
+        options: [{
+          allow: ['node:events'],
+        }],
+      }),
+      test({
+        code: 'var events = require("node:events")',
+        options: [{
+          allow: ['node:events'],
+        }],
+      }),
+    ]: [],
+    isCore('node:path') ? [
+      test({
+        code: 'import path from "node:path"',
+        options: [{
+          allow: ['node:path'],
+        }],
+      }),
+      test({
+        code: 'var path = require("node:path")',
+        options: [{
+          allow: ['node:path'],
+        }],
+      }),
+    ] : [],
+    isCore('node:path') && isCore('node:events') ? test({
+      code: 'import path from "node:path";import events from "node:events"',
+      options: [{
+        allow: ['node:path', 'node:events'],
+      }],
+    }) : [],
+  ),
+  invalid: [].concat(
     test({
       code: 'import path from "path"',
       errors: [error('Do not import Node.js builtin module "path"')],
@@ -80,5 +115,32 @@ ruleTester.run('no-nodejs-modules', rule, {
       }],
       errors: [error('Do not import Node.js builtin module "fs"')],
     }),
-  ],
+    isCore('node:path') ? [
+      test({
+        code: 'import path from "node:path"',
+        errors: [error('Do not import Node.js builtin module "node:path"')],
+      }),
+      test({
+        code: 'var path = require("node:path")',
+        errors: [error('Do not import Node.js builtin module "node:path"')],
+      }),
+    ] : [],
+    isCore('node:fs') ? [
+      test({
+        code: 'import fs from "node:fs"',
+        errors: [error('Do not import Node.js builtin module "node:fs"')],
+      }),
+      test({
+        code: 'var fs = require("node:fs")',
+        errors: [error('Do not import Node.js builtin module "node:fs"')],
+      }),
+      test({
+        code: 'import fs from "node:fs"',
+        options: [{
+          allow: ['node:path'],
+        }],
+        errors: [error('Do not import Node.js builtin module "node:fs"')],
+      }),
+    ] : [],
+  ),
 });
diff --git a/tests/src/rules/no-relative-packages.js b/tests/src/rules/no-relative-packages.js
index 1a706387..2d27bcc9 100644
--- a/tests/src/rules/no-relative-packages.js
+++ b/tests/src/rules/no-relative-packages.js
@@ -47,6 +47,7 @@ ruleTester.run('no-relative-packages', rule, {
         line: 1,
         column: 17,
       } ],
+      output: 'import foo from "package-named"',
     }),
     test({
       code: 'import foo from "../package-named"',
@@ -56,6 +57,7 @@ ruleTester.run('no-relative-packages', rule, {
         line: 1,
         column: 17,
       } ],
+      output: 'import foo from "package-named"',
     }),
     test({
       code: 'import foo from "../package-scoped"',
@@ -65,6 +67,7 @@ ruleTester.run('no-relative-packages', rule, {
         line: 1,
         column: 17,
       } ],
+      output: `import foo from "@scope/package-named"`,
     }),
     test({
       code: 'import bar from "../bar"',
@@ -74,6 +77,7 @@ ruleTester.run('no-relative-packages', rule, {
         line: 1,
         column: 17,
       } ],
+      output: `import bar from "eslint-plugin-import/tests/files/bar"`,
     }),
   ],
 });
diff --git a/tests/src/rules/no-relative-parent-imports.js b/tests/src/rules/no-relative-parent-imports.js
index d6a47ae3..30504980 100644
--- a/tests/src/rules/no-relative-parent-imports.js
+++ b/tests/src/rules/no-relative-parent-imports.js
@@ -1,10 +1,10 @@
 import { RuleTester } from 'eslint';
 import rule from 'rules/no-relative-parent-imports';
-import { test as _test, testFilePath } from '../utils';
+import { parsers, test as _test, testFilePath } from '../utils';
 
 const test = def => _test(Object.assign(def, {
   filename: testFilePath('./internal-modules/plugins/plugin2/index.js'),
-  parser: require.resolve('babel-eslint'),
+  parser: parsers.BABEL_OLD,
 }));
 
 const ruleTester = new RuleTester();
diff --git a/tests/src/rules/no-unresolved.js b/tests/src/rules/no-unresolved.js
index 71efc128..c0252ad1 100644
--- a/tests/src/rules/no-unresolved.js
+++ b/tests/src/rules/no-unresolved.js
@@ -1,6 +1,6 @@
-import * as path from 'path';
+import path from 'path';
 
-import { getTSParsers, test, SYNTAX_CASES, testVersion } from '../utils';
+import { getTSParsers, test, SYNTAX_CASES, testVersion, parsers } from '../utils';
 
 import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve';
 
@@ -30,7 +30,7 @@ function runResolverTests(resolver) {
       rest({ code: "import {someThing} from './test-module';" }),
       rest({ code: "import fs from 'fs';" }),
       rest({ code: "import('fs');",
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
 
       // check with eslint parser
       testVersion('>= 7', () => rest({
@@ -46,9 +46,9 @@ function runResolverTests(resolver) {
 
       // stage 1 proposal for export symmetry,
       rest({ code: 'export * as bar from "./bar"',
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
       rest({ code: 'export bar from "./bar"',
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
       rest({ code: 'import foo from "./jsx/MyUnCoolComponent.jsx"' }),
 
       // commonjs setting
@@ -127,7 +127,7 @@ function runResolverTests(resolver) {
           message: 'Unable to resolve path to module \'in-alternate-root\'.',
           type: 'Literal',
         }],
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
 
       rest({ code: 'export { foo } from "./does-not-exist"',
         errors: ["Unable to resolve path to module './does-not-exist'."] }),
@@ -148,11 +148,11 @@ function runResolverTests(resolver) {
 
       // export symmetry proposal
       rest({ code: 'export * as bar from "./does-not-exist"',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         errors: ["Unable to resolve path to module './does-not-exist'."],
       }),
       rest({ code: 'export bar from "./does-not-exist"',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         errors: ["Unable to resolve path to module './does-not-exist'."],
       }),
 
@@ -444,7 +444,7 @@ ruleTester.run('import() with built-in parser', rule, {
 
 context('TypeScript', () => {
   // Type-only imports were added in TypeScript ESTree 2.23.0
-  getTSParsers().filter(x => x !== require.resolve('typescript-eslint-parser')).forEach((parser) => {
+  getTSParsers().filter(x => x !== parsers.TS_OLD).forEach((parser) => {
     ruleTester.run(`${parser}: no-unresolved ignore type-only`, rule, {
       valid: [
         test({
diff --git a/tests/src/rules/no-unused-modules.js b/tests/src/rules/no-unused-modules.js
index 6f87058c..38db2ef4 100644
--- a/tests/src/rules/no-unused-modules.js
+++ b/tests/src/rules/no-unused-modules.js
@@ -1,4 +1,4 @@
-import { test, testFilePath, getTSParsers } from '../utils';
+import { test, testVersion, testFilePath, getTSParsers, parsers } from '../utils';
 import jsxConfig from '../../../config/react';
 import typescriptConfig from '../../../config/typescript';
 
@@ -105,56 +105,56 @@ ruleTester.run('no-unused-modules', rule, {
 });
 
 
-// tests for  exports
+// tests for exports
 ruleTester.run('no-unused-modules', rule, {
   valid: [
     test({
       options: unusedExportsOptions,
       code: 'import { o2 } from "./file-o";export default () => 12',
       filename: testFilePath('./no-unused-modules/file-a.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'export const b = 2',
       filename: testFilePath('./no-unused-modules/file-b.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'const c1 = 3; function c2() { return 3 }; export { c1, c2 }',
       filename: testFilePath('./no-unused-modules/file-c.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'export function d() { return 4 }',
       filename: testFilePath('./no-unused-modules/file-d.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'export class q { q0() {} }',
       filename: testFilePath('./no-unused-modules/file-q.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'const e0 = 5; export { e0 as e }',
       filename: testFilePath('./no-unused-modules/file-e.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'const l0 = 5; const l = 10; export { l0 as l1, l }; export default () => {}',
       filename: testFilePath('./no-unused-modules/file-l.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       options: unusedExportsOptions,
       code: 'const o0 = 0; const o1 = 1; export { o0, o1 as o2 }; export default () => {}',
       filename: testFilePath('./no-unused-modules/file-o.js'),
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
   ],
   invalid: [
@@ -263,7 +263,7 @@ describe('dynamic imports', () => {
             const d = 40
             export default d
             `,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/exports-for-dynamic-js.js'),
       }),
     ],
@@ -277,7 +277,7 @@ describe('dynamic imports', () => {
         const d = 40
         export default d
         `,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/exports-for-dynamic-js-2.js'),
         errors: [
           error(`exported declaration 'a' not used within other modules`),
@@ -298,9 +298,20 @@ describe('dynamic imports', () => {
             const ts_d = 40
             export default ts_d
             `,
-        parser: require.resolve('@typescript-eslint/parser'),
+        parser: parsers.TS_NEW,
         filename: testFilePath('./no-unused-modules/typescript/exports-for-dynamic-ts.ts'),
       }),
+      test({
+        code: `
+        import App from './App';
+      `,
+        filename: testFilePath('./unused-modules-reexport-crash/src/index.tsx'),
+        parser: parsers.TS_NEW,
+        options: [{        
+          unusedExports: true,
+          ignoreExports: ['**/magic/**'],
+        }],
+      }),
     ],
     invalid: [
     ],
@@ -1177,7 +1188,7 @@ describe('correctly work with JSX only files', () => {
       test({
         options: unusedExportsJsxOptions,
         code: 'import a from "file-jsx-a";',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/jsx/file-jsx-a.jsx'),
       }),
     ],
@@ -1185,7 +1196,7 @@ describe('correctly work with JSX only files', () => {
       test({
         options: unusedExportsJsxOptions,
         code: `export const b = 2;`,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/jsx/file-jsx-b.jsx'),
         errors: [
           error(`exported declaration 'b' not used within other modules`),
@@ -1201,7 +1212,7 @@ describe('ignore flow types', () => {
       test({
         options: unusedExportsOptions,
         code: 'import { type FooType, type FooInterface } from "./flow-2";',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/flow/flow-0.js'),
       }),
       test({
@@ -1210,13 +1221,13 @@ describe('ignore flow types', () => {
                export type FooType = string;
                export interface FooInterface {};
                `,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/flow/flow-2.js'),
       }),
       test({
         options: unusedExportsOptions,
         code: 'import type { FooType, FooInterface } from "./flow-4";',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/flow/flow-3.js'),
       }),
       test({
@@ -1225,7 +1236,7 @@ describe('ignore flow types', () => {
                export type FooType = string;
                export interface FooInterface {};
                `,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/flow/flow-4.js'),
       }),
       test({
@@ -1234,7 +1245,7 @@ describe('ignore flow types', () => {
                export type Bar = number;
                export interface BarInterface {};
                `,
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/flow/flow-1.js'),
       }),
     ],
@@ -1248,16 +1259,46 @@ describe('support (nested) destructuring assignment', () => {
       test({
         options: unusedExportsOptions,
         code: 'import {a, b} from "./destructuring-b";',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/destructuring-a.js'),
       }),
       test({
         options: unusedExportsOptions,
         code: 'const obj = {a: 1, dummy: {b: 2}}; export const {a, dummy: {b}} = obj;',
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
         filename: testFilePath('./no-unused-modules/destructuring-b.js'),
       }),
     ],
     invalid: [],
   });
 });
+
+describe('support ES2022 Arbitrary module namespace identifier names', () => {
+  ruleTester.run('no-unused-module', rule, {
+    valid: [].concat(
+      testVersion('>= 8.7', () => ({
+        options: unusedExportsOptions,
+        code: `import { "foo" as foo } from "./arbitrary-module-namespace-identifier-name-a"`,
+        parserOptions: { ecmaVersion: 2022 },
+        filename: testFilePath('./no-unused-modules/arbitrary-module-namespace-identifier-name-b.js'),
+      })),
+      testVersion('>= 8.7', () => ({
+        options: unusedExportsOptions,
+        code: 'const foo = 333;\nexport { foo as "foo" }',
+        parserOptions: { ecmaVersion: 2022 },
+        filename: testFilePath('./no-unused-modules/arbitrary-module-namespace-identifier-name-a.js'),
+      })),
+    ),
+    invalid: [].concat(
+      testVersion('>= 8.7', () => ({
+        options: unusedExportsOptions,
+        code: 'const foo = 333\nexport { foo as "foo" }',
+        parserOptions: { ecmaVersion: 2022 },
+        filename: testFilePath('./no-unused-modules/arbitrary-module-namespace-identifier-name-c.js'),
+        errors: [
+          error(`exported declaration 'foo' not used within other modules`),
+        ],
+      })),
+    ),
+  });
+});
diff --git a/tests/src/rules/no-useless-path-segments.js b/tests/src/rules/no-useless-path-segments.js
index 21d9a5f7..f9609535 100644
--- a/tests/src/rules/no-useless-path-segments.js
+++ b/tests/src/rules/no-useless-path-segments.js
@@ -1,4 +1,4 @@
-import { test } from '../utils';
+import { parsers, test } from '../utils';
 import { RuleTester } from 'eslint';
 
 const ruleTester = new RuleTester();
@@ -29,11 +29,11 @@ function runResolverTests(resolver) {
       test({ code: 'import "./importType"', options: [{ noUselessIndex: true }] }), // ./importType.js does not exist
 
       test({ code: 'import(".")',
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
       test({ code: 'import("..")',
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
       test({ code: 'import("fs").then(function(fs) {})',
-        parser: require.resolve('babel-eslint') }),
+        parser: parsers.BABEL_OLD }),
     ],
 
     invalid: [
@@ -232,19 +232,19 @@ function runResolverTests(resolver) {
         code: 'import("./")',
         output: 'import(".")',
         errors: [ 'Useless path segments for "./", should be "."'],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: 'import("../")',
         output: 'import("..")',
         errors: [ 'Useless path segments for "../", should be ".."'],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
       test({
         code: 'import("./deep//a")',
         output: 'import("./deep/a")',
         errors: [ 'Useless path segments for "./deep//a", should be "./deep/a"'],
-        parser: require.resolve('babel-eslint'),
+        parser: parsers.BABEL_OLD,
       }),
     ],
   });
diff --git a/tests/src/rules/no-webpack-loader-syntax.js b/tests/src/rules/no-webpack-loader-syntax.js
index a8aa0dd2..2b841e18 100644
--- a/tests/src/rules/no-webpack-loader-syntax.js
+++ b/tests/src/rules/no-webpack-loader-syntax.js
@@ -1,6 +1,7 @@
-import { test, getTSParsers } from '../utils';
+import { test, getTSParsers, parsers } from '../utils';
 
 import { RuleTester } from 'eslint';
+import semver from 'semver';
 
 const ruleTester = new RuleTester();
 const rule = require('rules/no-webpack-loader-syntax');
@@ -82,16 +83,20 @@ context('TypeScript', function () {
         'import/resolver': { 'eslint-import-resolver-typescript': true },
       },
     };
-    ruleTester.run('no-webpack-loader-syntax', rule, {
-      valid: [
-        test(Object.assign({
-          code: 'import { foo } from\nalert()',
-        }, parserConfig)),
-        test(Object.assign({
-          code: 'import foo from\nalert()',
-        }, parserConfig)),
-      ],
-      invalid: [],
-    });
+    // @typescript-eslint/parser@5+ throw error for invalid module specifiers at parsing time.
+    // https://github.com/typescript-eslint/typescript-eslint/releases/tag/v5.0.0
+    if (!(parser === parsers.TS_NEW && semver.satisfies(require('@typescript-eslint/parser/package.json').version, '>= 5'))) {
+      ruleTester.run('no-webpack-loader-syntax', rule, {
+        valid: [
+          test(Object.assign({
+            code: 'import { foo } from\nalert()',
+          }, parserConfig)),
+          test(Object.assign({
+            code: 'import foo from\nalert()',
+          }, parserConfig)),
+        ],
+        invalid: [],
+      });
+    }
   });
 });
diff --git a/tests/src/rules/order.js b/tests/src/rules/order.js
index 79426c4c..e552c9a8 100644
--- a/tests/src/rules/order.js
+++ b/tests/src/rules/order.js
@@ -1,4 +1,4 @@
-import { test, getTSParsers, getNonDefaultParsers, testFilePath } from '../utils';
+import { test, getTSParsers, getNonDefaultParsers, testFilePath, parsers } from '../utils';
 
 import { RuleTester } from 'eslint';
 import eslintPkg from 'eslint/package.json';
@@ -2321,7 +2321,7 @@ ruleTester.run('order', rule, {
 context('TypeScript', function () {
   getNonDefaultParsers()
     // Type-only imports were added in TypeScript ESTree 2.23.0
-    .filter((parser) => parser !== require.resolve('typescript-eslint-parser'))
+    .filter((parser) => parser !== parsers.TS_OLD)
     .forEach((parser) => {
       const parserConfig = {
         parser,
diff --git a/tests/src/rules/prefer-default-export.js b/tests/src/rules/prefer-default-export.js
index 36205b19..6a36f08b 100644
--- a/tests/src/rules/prefer-default-export.js
+++ b/tests/src/rules/prefer-default-export.js
@@ -1,12 +1,14 @@
-import { test, getNonDefaultParsers } from '../utils';
+import { test, testVersion, getNonDefaultParsers, parsers } from '../utils';
 
 import { RuleTester } from 'eslint';
+import semver from 'semver';
+import { version as tsEslintVersion } from 'typescript-eslint-parser/package.json';
 
 const ruleTester = new RuleTester();
 const rule = require('../../../src/rules/prefer-default-export');
 
 ruleTester.run('prefer-default-export', rule, {
-  valid: [
+  valid: [].concat(
     test({
       code: `
         export const foo = 'foo';
@@ -64,7 +66,7 @@ ruleTester.run('prefer-default-export', rule, {
     }),
     test({
       code: `export Memory, { MemoryValue } from './Memory'`,
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // no exports at all
@@ -75,26 +77,31 @@ ruleTester.run('prefer-default-export', rule, {
 
     test({
       code: `export type UserId = number;`,
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
 
     // issue #653
     test({
       code: 'export default from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     test({
       code: 'export { a, b } from "foo.js"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
     }),
     // ...SYNTAX_CASES,
     test({
       code: `
         export const [CounterProvider,, withCounter] = func();;
       `,
-      parser: require.resolve('babel-eslint'),
-    }),
-  ],
+      parser: parsers.BABEL_OLD,
+    }),
+    // es2022: Arbitrary module namespae identifier names
+    testVersion('>= 8.7', () => ({
+      code: 'let foo; export { foo as "default" };',
+      parserOptions: { ecmaVersion: 2022 },
+    })),
+  ),
   invalid: [
     test({
       code: `
@@ -159,28 +166,24 @@ context('TypeScript', function () {
     };
 
     ruleTester.run('prefer-default-export', rule, {
-      valid: [
+      valid: [].concat(
         // Exporting types
-        test({
+        semver.satisfies(tsEslintVersion, '>= 22') ? test({
           code: `
           export type foo = string;
           export type bar = number;`,
           ...parserConfig,
-        }),
+        }) : [],
         test({
           code: `
           export type foo = string;
           export type bar = number;`,
           ...parserConfig,
         }),
-        test({
-          code: 'export type foo = string',
-          ...parserConfig,
-        }),
-        test({
+        semver.satisfies(tsEslintVersion, '>= 22') ? test({
           code: 'export type foo = string',
           ...parserConfig,
-        }),
+        }) : [],
         test({
           code: 'export interface foo { bar: string; }',
           ...parserConfig,
@@ -189,7 +192,7 @@ context('TypeScript', function () {
           code: 'export interface foo { bar: string; }; export function goo() {}',
           ...parserConfig,
         }),
-      ],
+      ),
       invalid: [],
     });
   });
diff --git a/tests/src/rules/unambiguous.js b/tests/src/rules/unambiguous.js
index 72e6b108..8cef6962 100644
--- a/tests/src/rules/unambiguous.js
+++ b/tests/src/rules/unambiguous.js
@@ -1,4 +1,5 @@
 import { RuleTester } from 'eslint';
+import { parsers } from '../utils';
 
 const ruleTester = new RuleTester();
 const rule = require('rules/unambiguous');
@@ -38,7 +39,7 @@ ruleTester.run('unambiguous', rule, {
     },
     {
       code: 'function x() {}; export * as y from "z"',
-      parser: require.resolve('babel-eslint'),
+      parser: parsers.BABEL_OLD,
       parserOptions: { ecmaVersion: 2015, sourceType: 'module' },
     },
     {
diff --git a/tests/src/utils.js b/tests/src/utils.js
index 012c3a7c..b66ecf9c 100644
--- a/tests/src/utils.js
+++ b/tests/src/utils.js
@@ -5,24 +5,26 @@ import semver from 'semver';
 // warms up the module cache. this import takes a while (>500ms)
 import 'babel-eslint';
 
+export const parsers = {
+  ESPREE: require.resolve('espree'),
+  TS_OLD: semver.satisfies(eslintPkg.version, '>=4.0.0 <6.0.0') && require.resolve('typescript-eslint-parser'),
+  TS_NEW: semver.satisfies(eslintPkg.version, '>5.0.0') && require.resolve('@typescript-eslint/parser'),
+  BABEL_OLD: require.resolve('babel-eslint'),
+};
+
 export function testFilePath(relativePath) {
   return path.join(process.cwd(), './tests/files', relativePath);
 }
 
 export function getTSParsers() {
-  const parsers = [];
-  if (semver.satisfies(eslintPkg.version, '>=4.0.0 <6.0.0')) {
-    parsers.push(require.resolve('typescript-eslint-parser'));
-  }
-
-  if (semver.satisfies(eslintPkg.version, '>5.0.0')) {
-    parsers.push(require.resolve('@typescript-eslint/parser'));
-  }
-  return parsers;
+  return [
+    parsers.TS_OLD,
+    parsers.TS_NEW,
+  ].filter(Boolean);
 }
 
 export function getNonDefaultParsers() {
-  return getTSParsers().concat(require.resolve('babel-eslint'));
+  return getTSParsers().concat(parsers.BABEL_OLD).filter(Boolean);
 }
 
 export const FILENAME = testFilePath('foo.js');
@@ -65,7 +67,7 @@ export const SYNTAX_CASES = [
   test({ code: 'for (let [ foo, bar ] of baz) {}' }),
 
   test({ code: 'const { x, y } = bar' }),
-  test({ code: 'const { x, y, ...z } = bar', parser: require.resolve('babel-eslint') }),
+  test({ code: 'const { x, y, ...z } = bar', parser: parsers.BABEL_OLD }),
 
   // all the exports
   test({ code: 'let x; export { x }' }),
@@ -73,7 +75,7 @@ export const SYNTAX_CASES = [
 
   // not sure about these since they reference a file
   // test({ code: 'export { x } from "./y.js"'}),
-  // test({ code: 'export * as y from "./y.js"', parser: require.resolve('babel-eslint')}),
+  // test({ code: 'export * as y from "./y.js"', parser: parsers.BABEL_OLD}),
 
   test({ code: 'export const x = null' }),
   test({ code: 'export var x = null' }),