diff --git a/package.json b/package.json index 689c3bfa27..6b6f9da063 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "mocha": "^3.5.3", "npm-which": "^3.0.1", "nyc": "^11.9.0", + "object.fromentries": "^2.0.5", "redux": "^3.7.2", "rimraf": "^2.7.1", "safe-publish-latest": "^2.0.0", diff --git a/tests/src/parsers.js b/tests/src/parsers.js index 5dc0ae0a32..d581d80296 100644 --- a/tests/src/parsers.js +++ b/tests/src/parsers.js @@ -132,7 +132,9 @@ const parsers = { || features.has('flow') || features.has('ts') || features.has('types') - || (features.has('fragment') && semver.satisfies(version, '< 5')); + //if it has fragments use version 5 and higher // create features for export from + || (features.has('fragment') && semver.satisfies(version, '< 5')) + || features.has(''); const skipBabel = features.has('no-babel'); const skipOldBabel = skipBabel || features.has('no-babel-old') || semver.satisfies(version, '>= 8'); diff --git a/tests/src/rules/default.js b/tests/src/rules/default.js index e00218d795..1634674987 100644 --- a/tests/src/rules/default.js +++ b/tests/src/rules/default.js @@ -1,28 +1,48 @@ +// eslint-disable-next-line no-unused-vars import path from 'path'; -import { test, testVersion, SYNTAX_CASES, getTSParsers, parsers } from '../utils'; +// eslint-disable-next-line no-unused-vars +import { test, testVersion, SYNTAX_CASES, parsers as utilsParsers, getTSParsers } from '../utils'; +import parsers from '../parsers'; import { RuleTester } from 'eslint'; import semver from 'semver'; import { version as tsEslintVersion } from 'typescript-eslint-parser/package.json'; +import fromEntries from 'object.fromentries'; + + import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve'; -const ruleTester = new RuleTester(); + const rule = require('rules/default'); + + +const parserOptions = { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + + settings: { + 'import/parsers': fromEntries(getTSParsers().map((parser)=>[parser, ['.ts']] )), + + }, +}; + +const ruleTester = new RuleTester({ parserOptions }); + ruleTester.run('default', rule, { - valid: [].concat( + valid: parsers.all([].concat( test({ code: 'import "./malformed.js"' }), test({ code: 'import foo from "./empty-folder";' }), test({ code: 'import { foo } from "./default-export";' }), test({ code: 'import foo from "./default-export";' }), test({ code: 'import foo from "./mixed-exports";' }), - test({ - code: 'import bar from "./default-export";' }), - test({ - code: 'import CoolClass from "./default-class";' }), - test({ - code: 'import bar, { baz } from "./default-export";' }), + test({ code: 'import bar from "./default-export";' }), + test({ code: 'import CoolClass from "./default-class";' }), + test({ code: 'import bar, { baz } from "./default-export";' }), // core modules always have a default test({ code: 'import crypto from "crypto";' }), @@ -30,20 +50,34 @@ ruleTester.run('default', rule, { test({ code: 'import common from "./common";' }), // es7 export syntax - test({ code: 'export bar from "./bar"', - parser: parsers.BABEL_ESLINT }), + test({ + code: 'export bar from "./bar"', + parserOptions: { + ecmaVersion: 2018, + ecmaFeatures: { + modules: true, + }, + }, + }), test({ code: 'export { default as bar } from "./bar"' }), - test({ code: 'export bar, { foo } from "./bar"', - parser: parsers.BABEL_ESLINT }), + test({ code: 'export bar, { foo } from "./bar"' }), test({ code: 'export { default as bar, foo } from "./bar"' }), test({ code: 'export bar, * as names from "./bar"', - parser: parsers.BABEL_ESLINT }), + parserOptions: { + ecmaVersion: 2018, + ecmaFeatures: { + modules: true, + }, + } }), // sanity check test({ code: 'export {a} from "./named-exports"' }), - test({ + test({ code: 'import twofer from "./trampoline"', - parser: parsers.BABEL_ESLINT, + parserOptions: { + sourceType: 'module', + ecmaVersion: 2015, + }, }), // jsx @@ -69,29 +103,98 @@ ruleTester.run('default', rule, { }), // from no-errors + test({ code: "import Foo from './jsx/FooES7.js';" }), + + // #545: more ES7 cases + test({ code: "import bar from './default-export-from.js';" }), + test({ code: "import bar from './default-export-from-named.js';" }), test({ - code: "import Foo from './jsx/FooES7.js';", - parser: parsers.BABEL_ESLINT, + code: "import bar from './default-export-from-ignored.js';", + settings: { 'import/ignore': ['common'] }, + }), + test({ + code: "export bar from './default-export-from-ignored.js';", + settings: { 'import/ignore': ['common'] }, }), - // #545: more ES7 cases + //typescript context test({ - code: "import bar from './default-export-from.js';", - parser: parsers.BABEL_ESLINT, + code: `import foobar from "./typescript-default"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + //feature + //features: ['ts'], }), test({ - code: "import bar from './default-export-from-named.js';", - parser: parsers.BABEL_ESLINT, + code: `import foobar from "./typescript-export-assign-default"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, }), test({ - code: "import bar from './default-export-from-ignored.js';", - settings: { 'import/ignore': ['common'] }, - parser: parsers.BABEL_ESLINT, + code: `import foobar from "./typescript-export-assign-function"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, }), + semver.satisfies(tsEslintVersion, '>= 22') ? test({ + code: `import foobar from "./typescript-export-assign-mixed"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }) : [], test({ - code: "export bar from './default-export-from-ignored.js';", - settings: { 'import/ignore': ['common'] }, - parser: parsers.BABEL_ESLINT, + code: `import foobar from "./typescript-export-assign-default-reexport"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + + test({ + code: `import React from "./typescript-export-assign-default-namespace"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + parserOptions: { + tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-export-assign-default-namespace/'), + }, + }), + + test({ + code: `import Foo from "./typescript-export-as-default-namespace"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + parserOptions: { + tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-export-assign-default-namespace/'), + }, + }), + + test({ + code: `import Foo from "./typescript-export-react-test-renderer"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + parserOptions: { + tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-export-react-test-renderer/'), + }, + }), + test({ + code: `import Foo from "./typescript-extended-config"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + parserOptions: { + tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-extended-config/'), + }, + }), + test({ + + code: `import foobar from "./typescript-export-assign-property"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, }), // es2022: Arbitrary module namespace identifier names @@ -102,10 +205,16 @@ ruleTester.run('default', rule, { }, })), - ...SYNTAX_CASES, - ), - invalid: [ + // #311: import of mismatched case + CASE_SENSITIVE_FS ? [] : test({ + code: 'import foo from "./jsx/MyUncoolComponent.jsx"', + }), + + SYNTAX_CASES, + )), + + invalid: parsers.all([].concat( test({ code: "import Foo from './jsx/FooES7.js';", errors: ["Parse errors in imported module './jsx/FooES7.js': Unexpected token = (6:16)"], @@ -119,23 +228,19 @@ ruleTester.run('default', rule, { // es7 export syntax test({ code: 'export baz from "./named-exports"', - parser: parsers.BABEL_ESLINT, errors: ['No default export found in imported module "./named-exports".'], }), test({ code: 'export baz, { bar } from "./named-exports"', - parser: parsers.BABEL_ESLINT, errors: ['No default export found in imported module "./named-exports".'], }), test({ code: 'export baz, * as names from "./named-exports"', - parser: parsers.BABEL_ESLINT, 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: parsers.BABEL_ESLINT, errors: ['No default export found in imported module "./broken-trampoline".'], }), @@ -144,173 +249,59 @@ ruleTester.run('default', rule, { code: 'import barDefault from "./re-export"', errors: ['No default export found in imported module "./re-export".'], }), - ], -}); -// #311: import of mismatched case -if (!CASE_SENSITIVE_FS) { - ruleTester.run('default (path case-insensitivity)', rule, { - valid: [ - test({ - code: 'import foo from "./jsx/MyUncoolComponent.jsx"', - }), - ], - invalid: [ - test({ - code: 'import bar from "./Named-Exports"', - errors: ['No default export found in imported module "./Named-Exports".'], - }), - ], - }); -} - -context('TypeScript', function () { - getTSParsers().forEach((parser) => { - ruleTester.run(`default`, rule, { - valid: [].concat( - test({ - code: `import foobar from "./typescript-default"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: `import foobar from "./typescript-export-assign-default"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: `import foobar from "./typescript-export-assign-function"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - 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, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: `import React from "./typescript-export-assign-default-namespace"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - parserOptions: { - tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-export-assign-default-namespace/'), - }, - }), - test({ - code: `import Foo from "./typescript-export-as-default-namespace"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - parserOptions: { - tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-export-as-default-namespace/'), - }, - }), - test({ - code: `import Foo from "./typescript-export-react-test-renderer"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - parserOptions: { - tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-export-react-test-renderer/'), - }, - }), - test({ - code: `import Foo from "./typescript-extended-config"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - parserOptions: { - tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-extended-config/'), - }, - }), - test({ - code: `import foobar from "./typescript-export-assign-property"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - ), - - invalid: [ - test({ - code: `import foobar from "./typescript"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - errors: ['No default export found in imported module "./typescript".'], - }), - test({ - code: `import React from "./typescript-export-assign-default-namespace"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - errors: ['No default export found in imported module "./typescript-export-assign-default-namespace".'], - }), - test({ - code: `import FooBar from "./typescript-export-as-default-namespace"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - errors: ['No default export found in imported module "./typescript-export-as-default-namespace".'], - }), - test({ - code: `import Foo from "./typescript-export-as-default-namespace"`, - parser, - settings: { - 'import/parsers': { [parser]: ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - parserOptions: { - tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-no-compiler-options/'), - }, - errors: [ - { - message: 'No default export found in imported module "./typescript-export-as-default-namespace".', - line: 1, - column: 8, - endLine: 1, - endColumn: 11, - }, - ], - }), + + //typescript context + //context('TypeScript', function () + test({ + code: `import foobar from "./typescript"`, + + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + errors: ['No default export found in imported module "./typescript".'], + }), + test({ + code: `import React from "./typescript-export-assign-default-namespace"`, + + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + errors: ['No default export found in imported module "./typescript-export-assign-default-namespace".'], + }), + test({ + code: `import FooBar from "./typescript-export-as-default-namespace"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + errors: ['No default export found in imported module "./typescript-export-as-default-namespace".'], + }), + test({ + code: `import Foo from "./typescript-export-as-default-namespace"`, + settings: { + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + parserOptions: { + tsconfigRootDir: path.resolve(__dirname, '../../files/typescript-no-compiler-options/'), + }, + errors: [ + { + message: 'No default export found in imported module "./typescript-export-as-default-namespace".', + line: 1, + column: 8, + endLine: 1, + endColumn: 11, + }, ], - }); - }); + }), + + // #311: import of mismatched case + CASE_SENSITIVE_FS ? [] : test({ + code: 'import bar from "./Named-Exports"', + errors: ['No default export found in imported module "./Named-Exports".'], + }), + )), + + + });