diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..08c10310 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,60 @@ +module.exports = { + root: true, + extends: [ + 'kentcdodds', + 'plugin:jest/recommended', + 'plugin:jest-formatting/recommended', + 'prettier', + ], + rules: { + // Base + 'max-lines-per-function': 'off', + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@typescript-eslint/utils/dist/*'], + message: 'Import from `@typescript-eslint/utils` instead.', + }, + ], + }, + ], + + // Import + 'import/order': [ + 'warn', + { + groups: ['builtin', 'external', 'parent', 'sibling', 'index'], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: false, + }, + }, + ], + }, + overrides: [ + { + // TypeScript + files: ['**/*.ts?(x)'], + parser: '@typescript-eslint/parser', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig.eslint.json'], + }, + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + ], + rules: { + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { argsIgnorePattern: '^_' }, + ], + '@typescript-eslint/no-use-before-define': 'off', + }, + }, + ], +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 6b6c57a8..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "env": { - "commonjs": true, - "es6": true, - "node": true, - "jest/globals": true - }, - "extends": [ - "kentcdodds", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "prettier", - "plugin:jest/recommended", - "plugin:jest-formatting/recommended" - ], - "plugins": ["@typescript-eslint", "jest", "jest-formatting"], - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": "./tsconfig.eslint.json" - }, - "rules": { - // TS - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/no-unused-vars": [ - "warn", - { "argsIgnorePattern": "^_" } - ], - "@typescript-eslint/no-use-before-define": "off", - - // ESLint - "max-lines-per-function": "off", - "no-restricted-imports": [ - "error", - { - "patterns": ["@typescript-eslint/utils/dist/*"] - } - ], - - // Import - "import/no-import-module-exports": "off", - "import/order": [ - "warn", - { - "groups": ["builtin", "external", "parent", "sibling", "index"], - "newlines-between": "always", - "alphabetize": { - "order": "asc", - "caseInsensitive": false - } - } - ] - } -} diff --git a/lib/rules/no-await-sync-events.ts b/lib/rules/no-await-sync-events.ts index ebb0b5bc..954cd30a 100644 --- a/lib/rules/no-await-sync-events.ts +++ b/lib/rules/no-await-sync-events.ts @@ -151,13 +151,16 @@ export default createTestingLibraryRule({ return; } + const eventModuleName = getPropertyIdentifierNode(node)?.name; + const eventFullName = eventModuleName + ? `${eventModuleName}.${simulateEventFunctionName}` + : simulateEventFunctionName; + context.report({ node, messageId: 'noAwaitSyncEvents', data: { - name: `${ - getPropertyIdentifierNode(node)?.name - }.${simulateEventFunctionName}`, + name: eventFullName, }, }); }, diff --git a/lib/rules/no-dom-import.ts b/lib/rules/no-dom-import.ts index 4b34e21b..a095e013 100644 --- a/lib/rules/no-dom-import.ts +++ b/lib/rules/no-dom-import.ts @@ -12,13 +12,22 @@ const DOM_TESTING_LIBRARY_MODULES = [ '@testing-library/dom', ]; -const correctModuleNameByFramework = { +const CORRECT_MODULE_NAME_BY_FRAMEWORK: Record< + 'angular' | 'marko' | string, + string | undefined +> = { angular: '@testing-library/angular', // ATL is *always* called `@testing-library/angular` marko: '@marko/testing-library', // Marko TL is called `@marko/testing-library` }; -const getCorrectModuleName = (moduleName: string, framework: string): string => - correctModuleNameByFramework[framework] || - moduleName.replace('dom', framework); +const getCorrectModuleName = ( + moduleName: string, + framework: string +): string => { + return ( + CORRECT_MODULE_NAME_BY_FRAMEWORK[framework] ?? + moduleName.replace('dom', framework) + ); +}; export default createTestingLibraryRule({ name: RULE_NAME, diff --git a/lib/rules/no-wait-for-snapshot.ts b/lib/rules/no-wait-for-snapshot.ts index 3f0cc462..4e2b84ef 100644 --- a/lib/rules/no-wait-for-snapshot.ts +++ b/lib/rules/no-wait-for-snapshot.ts @@ -68,7 +68,9 @@ export default createTestingLibraryRule({ } return { - [`Identifier[name=${SNAPSHOT_REGEXP}]`](node: TSESTree.Identifier) { + [`Identifier[name=${String(SNAPSHOT_REGEXP)}]`]( + node: TSESTree.Identifier + ) { const closestAsyncUtil = getClosestAsyncUtil(node); if (closestAsyncUtil === null) { return; diff --git a/lib/utils/file-import.ts b/lib/utils/file-import.ts index 8b8e5b24..6bfeae0f 100644 --- a/lib/utils/file-import.ts +++ b/lib/utils/file-import.ts @@ -1,7 +1,7 @@ // Copied from https://github.com/babel/babel/blob/b35c78f08dd854b08575fc66ebca323fdbc59dab/packages/babel-helpers/src/helpers.js#L615-L619 // eslint-disable-next-line @typescript-eslint/no-explicit-any const interopRequireDefault = (obj: any): { default: T } => - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return obj?.__esModule ? obj : { default: obj }; export const importDefault = (moduleName: string): T => diff --git a/tests/index.test.ts b/tests/index.test.ts index 2b738922..6788a479 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -67,6 +67,7 @@ it('should export configs that refer to actual rules', () => { expect(rule.startsWith(ruleNamePrefix)).toBe(true); expect(ruleNames).toContain(ruleName); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return expect(() => require(`../lib/rules/${ruleName}`)).not.toThrow(); }); });