Skip to content

Commit

Permalink
Merge pull request #550 from fishbrain/make-jest-optional
Browse files Browse the repository at this point in the history
Make jest optional
  • Loading branch information
lhansford authored Sep 2, 2024
2 parents ee14ce4 + 77224d9 commit dc14331
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 186 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@fishbrain/eslint-config-monorepo",
"private": true,
"description": "ESLint configs for Fishbrain projects",
"version": "6.0.5",
"version": "6.0.6",
"workspaces": [
"packages/*"
],
Expand Down
135 changes: 2 additions & 133 deletions packages/base/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,134 +1,3 @@
// @ts-check
import { config } from './index.js';

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import jestPlugin from 'eslint-plugin-jest';
import prettierPlugin from 'eslint-plugin-prettier';

const HTTP_CODES = [200, 201, 204, 301, 302, 400, 401, 404, 422, 500];
const HTML_HEADER_LEVELS = [1, 2, 3, 4, 5, 6];
const COMMON_MATH_VALUES = [24, 60, 100];
const COMMON_INDEX_VALUES = [-1, 0, 1];
const ALLOWED_NUMBERS = Array.from(
new Set(
COMMON_INDEX_VALUES.concat(
HTTP_CODES,
HTML_HEADER_LEVELS,
COMMON_MATH_VALUES,
),
),
);

export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
jestPlugin.configs['flat/recommended'],
{
plugins: { prettier: prettierPlugin },
rules: {
'@typescript-eslint/no-empty-function': 'off', // Noop functions are a common pattern we use during testing, so we don't want to enable it.
'@typescript-eslint/no-explicit-any': ['error', { fixToUnknown: true }],
'@typescript-eslint/no-unused-vars': [
'error',
{
ignoreRestSiblings: true,
varsIgnorePattern: '^_',
argsIgnorePattern: '^_',
},
],
'@typescript-eslint/promise-function-async': 'error',
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: true,
allowNumber: true,
},
],
curly: ['error', 'all'],
'max-lines': ['error', { max: 300, skipComments: true }],
'no-magic-numbers': [
'error',
{ ignoreArrayIndexes: true, ignore: ALLOWED_NUMBERS },
],
'prettier/prettier': 'error',
'require-atomic-updates': 'error',

// 'fp/no-delete': 'error',
// 'fp/no-let': 'error',
// 'fp/no-loops': 'error',
// 'fp/no-mutating-assign': 'error',
// 'fp/no-mutation': [
// 'error',
// {
// allowThis: true,
// },
// ],
// TODO:
// 'import/named': 'off', // Redundant when used with Typescript.
// 'import/no-extraneous-dependencies': [
// 'error',
// {
// devDependencies: [
// '**/*.test.tsx',
// '**/*.test.ts',
// '**/testing.tsx',
// '**/*.stories.tsx',
// '**/*.stories.ts',
// '**/setupTests.ts',
// '**/webpack.config.{js,ts}', // webpack config
// '**/webpack.config.*.{js,ts}', // webpack config
// ],
// },
// ],
// 'import/order': [
// 'error',
// {
// 'newlines-between': 'always-and-inside-groups',
// groups: [
// ['builtin', 'external'],
// ['internal', 'sibling', 'parent', 'index'],
// ],
// },
// ],
// 'import/prefer-default-export': 'off',
// // Allow typescript imports, airbnb has disallowed it
// 'import/extensions': [
// 'error',
// 'ignorePackages',
// {
// js: 'never',
// jsx: 'never',
// ts: 'never',
// tsx: 'never',
// },
// ],

// no export from test file
// https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/no-export.md
// 'jest/no-export': 'error',

// TODO: Below is the "recommended" rules from eslint-plugin-import
// analysis/correctness
// 'import/no-unresolved': 'error', // TODO: dupe
// 'import/named': 'error', // TODO: dupe
// 'import/namespace': 'error',
// 'import/default': 'error',
// 'import/export': 'error',

// // red flags (thus, warnings)
// 'import/no-named-as-default': 'off', // TODO: Should error, but it doesn't work with eslint9 just yet.
// 'import/no-named-as-default-member': 'off', // TODO: Should error, but it doesn't work with eslint9 just yet.
// 'import/no-duplicates': 'warn',
},
},
);
export default config;
140 changes: 138 additions & 2 deletions packages/base/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,139 @@
import _config from './eslint.config.js';
import jestPlugin from 'eslint-plugin-jest';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettierPlugin from 'eslint-plugin-prettier';

export const config = _config;
const HTTP_CODES = [200, 201, 204, 301, 302, 400, 401, 404, 422, 500];
const HTML_HEADER_LEVELS = [1, 2, 3, 4, 5, 6];
const COMMON_MATH_VALUES = [24, 60, 100];
const COMMON_INDEX_VALUES = [-1, 0, 1];
const ALLOWED_NUMBERS = Array.from(
new Set(
COMMON_INDEX_VALUES.concat(
HTTP_CODES,
HTML_HEADER_LEVELS,
COMMON_MATH_VALUES,
),
),
);

const baseConfig = [
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{ plugins: { prettier: prettierPlugin } },
];

const customRules = {
rules: {
'@typescript-eslint/no-empty-function': 'off', // Noop functions are a common pattern we use during testing, so we don't want to enable it.
'@typescript-eslint/no-explicit-any': ['error', { fixToUnknown: true }],
'@typescript-eslint/no-unused-vars': [
'error',
{
ignoreRestSiblings: true,
varsIgnorePattern: '^_',
argsIgnorePattern: '^_',
},
],
'@typescript-eslint/promise-function-async': 'error',
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: true,
allowNumber: true,
},
],
curly: ['error', 'all'],
'max-lines': ['error', { max: 300, skipComments: true }],
'no-magic-numbers': [
'error',
{ ignoreArrayIndexes: true, ignore: ALLOWED_NUMBERS },
],
'prettier/prettier': 'error',
'require-atomic-updates': 'error',

// 'fp/no-delete': 'error',
// 'fp/no-let': 'error',
// 'fp/no-loops': 'error',
// 'fp/no-mutating-assign': 'error',
// 'fp/no-mutation': [
// 'error',
// {
// allowThis: true,
// },
// ],
// TODO:
// 'import/named': 'off', // Redundant when used with Typescript.
// 'import/no-extraneous-dependencies': [
// 'error',
// {
// devDependencies: [
// '**/*.test.tsx',
// '**/*.test.ts',
// '**/testing.tsx',
// '**/*.stories.tsx',
// '**/*.stories.ts',
// '**/setupTests.ts',
// '**/webpack.config.{js,ts}', // webpack config
// '**/webpack.config.*.{js,ts}', // webpack config
// ],
// },
// ],
// 'import/order': [
// 'error',
// {
// 'newlines-between': 'always-and-inside-groups',
// groups: [
// ['builtin', 'external'],
// ['internal', 'sibling', 'parent', 'index'],
// ],
// },
// ],
// 'import/prefer-default-export': 'off',
// // Allow typescript imports, airbnb has disallowed it
// 'import/extensions': [
// 'error',
// 'ignorePackages',
// {
// js: 'never',
// jsx: 'never',
// ts: 'never',
// tsx: 'never',
// },
// ],

// no export from test file
// https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/no-export.md
// 'jest/no-export': 'error',

// TODO: Below is the "recommended" rules from eslint-plugin-import
// analysis/correctness
// 'import/no-unresolved': 'error', // TODO: dupe
// 'import/named': 'error', // TODO: dupe
// 'import/namespace': 'error',
// 'import/default': 'error',
// 'import/export': 'error',

// // red flags (thus, warnings)
// 'import/no-named-as-default': 'off', // TODO: Should error, but it doesn't work with eslint9 just yet.
// 'import/no-named-as-default-member': 'off', // TODO: Should error, but it doesn't work with eslint9 just yet.
// 'import/no-duplicates': 'warn',
},
};

export const configWithoutJest = tseslint.config(...baseConfig, customRules);
export const config = tseslint.config(
...baseConfig,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
jestPlugin.configs['flat/recommended'],
customRules,
);
2 changes: 1 addition & 1 deletion packages/base/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@fishbrain/eslint-config-base",
"packageManager": "yarn@4.4.1",
"version": "6.0.5",
"version": "6.0.6",
"type": "module",
"exports": "./index.js",
"scripts": {
Expand Down
48 changes: 2 additions & 46 deletions packages/react/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument */
// @ts-check
import { config } from './index.js';

import tseslint from 'typescript-eslint';
import reactPlugin from 'eslint-plugin-react';
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
import compatPlugin from 'eslint-plugin-compat';
import globals from 'globals';

import { config } from '@fishbrain/eslint-config-base';

export default tseslint.config(
...config,
{
...reactPlugin.configs.flat.recommended,
settings: { react: { version: 'detect' } },
languageOptions: {
...reactPlugin.configs.flat.recommended.languageOptions,
globals: {
...globals.browser,
},
},
},
jsxA11yPlugin.flatConfigs.recommended,
compatPlugin.configs['flat/recommended'],
{
rules: {
// 'jsx-a11y/label-has-for': 'off', // This is deprecated but in the recommended extension for some reason // TODO: Check if needed
'jsx-a11y/media-has-caption': 'off',
'jsx-a11y/no-onchange': 'off',
'no-alert': 'error',
'no-console': 'warn',
'react/jsx-filename-extension': [
'warn',
{ extensions: ['.tsx', '.jsx'] },
],
'react/jsx-max-props-per-line': ['warn', { when: 'multiline' }],
'react/no-render-return-value': 'off',
'react/prop-types': 'off', // No need for prop types with Typescript
'react/react-in-jsx-scope': 'off',

// TODO: Disabled until https://github.com/facebook/react/issues/28313 is resolved.
// 'react-hooks/exhaustive-deps': 'error',
// 'react-hooks/rules-of-hooks': 'error',
},
},
);
export default config;
Loading

0 comments on commit dc14331

Please sign in to comment.