Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for flat config #923

Merged
merged 6 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .eslint-doc-generatorrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ const prettierConfig = require('./.prettierrc.js');

/** @type {import('eslint-doc-generator').GenerateOptions} */
const config = {
ignoreConfig: [
'flat/angular',
'flat/dom',
'flat/marko',
'flat/react',
'flat/vue',
],
postprocess: (content) =>
prettier.format(content, { ...prettierConfig, parser: 'markdown' }),
};
Expand Down
90 changes: 90 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ Another approach for customizing ESLint config by paths is through [ESLint Casca

## Shareable configurations

> [!NOTE]
>
> `eslint.config.js` compatible versions of configs are available prefixed with
> `flat/`, though most of the plugin documentation still currently uses
> `.eslintrc` syntax.
>
> Refer to the
> [ESLint documentation on the new configuration file format](https://eslint.org/docs/latest/use/configure/configuration-files-new)
> for more.

This plugin exports several recommended configurations that enforce good practices for specific Testing Library packages.
You can find more info about enabled rules in the [Supported Rules section](#supported-rules), under the `Configurations` column.

Expand Down Expand Up @@ -140,6 +150,22 @@ module.exports = {
};
```

To enable this configuration with `eslint.config.js`, use
`testingLibrary.configs['flat/dom']`:

```js
const testingLibrary = require('eslint-plugin-testing-library');

module.exports = [
{
files: [
/* glob matching your test files */
],
...testingLibrary.configs['flat/dom'],
},
];
```

### Angular

Enforces recommended rules for Angular Testing Library.
Expand All @@ -153,6 +179,22 @@ module.exports = {
};
```

To enable this configuration with `eslint.config.js`, use
`testingLibrary.configs['flat/angular']`:

```js
const testingLibrary = require('eslint-plugin-testing-library');

module.exports = [
{
files: [
/* glob matching your test files */
],
...testingLibrary.configs['flat/angular'],
},
];
```

### React

Enforces recommended rules for React Testing Library.
Expand All @@ -166,6 +208,22 @@ module.exports = {
};
```

To enable this configuration with `eslint.config.js`, use
`testingLibrary.configs['flat/react']`:

```js
const testingLibrary = require('eslint-plugin-testing-library');

module.exports = [
{
files: [
/* glob matching your test files */
],
...testingLibrary.configs['flat/react'],
},
];
```

### Vue

Enforces recommended rules for Vue Testing Library.
Expand All @@ -179,6 +237,22 @@ module.exports = {
};
```

To enable this configuration with `eslint.config.js`, use
`testingLibrary.configs['flat/vue']`:

```js
const testingLibrary = require('eslint-plugin-testing-library');

module.exports = [
{
files: [
/* glob matching your test files */
],
...testingLibrary.configs['flat/vue'],
},
];
```

### Marko

Enforces recommended rules for Marko Testing Library.
Expand All @@ -192,6 +266,22 @@ module.exports = {
};
```

To enable this configuration with `eslint.config.js`, use
`testingLibrary.configs['flat/marko']`:

```js
const testingLibrary = require('eslint-plugin-testing-library');

module.exports = [
{
files: [
/* glob matching your test files */
],
...testingLibrary.configs['flat/marko'],
},
];
```

## Supported Rules

> Remember that all rules from this plugin are prefixed by `"testing-library/"`
Expand Down
2 changes: 1 addition & 1 deletion lib/configs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
SupportedTestingFramework,
} from '../utils';

export type LinterConfigRules = Record<string, TSESLint.Linter.RuleEntry>;
export type LinterConfigRules = Pick<Required<TSESLint.Linter.Config>, 'rules'>;

const configsDir = __dirname;

Expand Down
41 changes: 39 additions & 2 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
import type { TSESLint } from '@typescript-eslint/utils';

import configs from './configs';
import rules from './rules';
import { SupportedTestingFramework } from './utils';

// we can't natively import package.json as tsc will copy it into dist/
const {
name: packageName,
version: packageVersion,
// eslint-disable-next-line @typescript-eslint/no-var-requires
} = require('../package.json') as { name: string; version: string };

export = {
configs,
const plugin = {
meta: {
name: packageName,
version: packageVersion,
},
// ugly cast for now to keep TypeScript happy since
// we don't have types for flat config yet
configs: {} as Record<
SupportedTestingFramework | `flat/${SupportedTestingFramework}`,
Pick<Required<TSESLint.Linter.Config>, 'rules'>
>,
rules,
};

plugin.configs = {
...configs,
...(Object.fromEntries(
Object.entries(configs).map(([framework, config]) => [
`flat/${framework}`,
{
plugins: { 'testing-library': plugin },
rules: config.rules,
},
])
) as Record<
`flat/${SupportedTestingFramework}`,
Pick<Required<TSESLint.Linter.Config>, 'rules'> & { plugins: unknown }
>),
};

export = plugin;
5 changes: 5 additions & 0 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ it('should export configs that refer to actual rules', () => {
'react',
'vue',
'marko',
'flat/dom',
'flat/angular',
'flat/react',
'flat/vue',
'flat/marko',
]);
const allConfigRules = Object.values(allConfigs)
.map((config) => Object.keys(config.rules))
Expand Down
5 changes: 3 additions & 2 deletions tools/generate-configs/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type LinterConfigRules } from '../../lib/configs';
import { type TSESLint } from '@typescript-eslint/utils';

import rules from '../../lib/rules';
import {
SUPPORTED_TESTING_FRAMEWORKS,
Expand All @@ -11,7 +12,7 @@ const RULE_NAME_PREFIX = 'testing-library/';

const getRecommendedRulesForTestingFramework = (
framework: SupportedTestingFramework
): LinterConfigRules =>
): Record<string, TSESLint.Linter.RuleEntry> =>
Object.entries(rules)
.filter(
([
Expand Down