diff --git a/lib/configs.ts b/lib/configs.ts index 9258a81a..e86c3d17 100644 --- a/lib/configs.ts +++ b/lib/configs.ts @@ -7,6 +7,8 @@ export function hasCustomConfigs(plugin: Plugin) { ); } +const SEVERITY_ENABLED = new Set([2, 'error']); + /** * Get config names that a given rule belongs to. */ @@ -20,7 +22,13 @@ export function getConfigsForRule( for (const configName in configsToRules) { const rules = configsToRules[configName]; const value = rules[`${pluginPrefix}/${ruleName}`]; - const isEnabled = [2, 'error'].includes(value); + const isEnabled = + ((typeof value === 'string' || typeof value === 'number') && + SEVERITY_ENABLED.has(value)) || + (typeof value === 'object' && + Array.isArray(value) && + value.length > 0 && + SEVERITY_ENABLED.has(value[0])); if (isEnabled) { configNames.push(configName); diff --git a/lib/types.ts b/lib/types.ts index 46bb56a4..a6e854be 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -4,7 +4,9 @@ export type RuleModule = TSESLint.RuleModule & { meta: Required, 'docs'>>; }; -export type Rules = Record; +type RuleSeverity = 'off' | 'error' | 'warn' | 0 | 1 | 2; + +export type Rules = Record; export type Config = { extends?: string[]; diff --git a/test/lib/__snapshots__/generator-test.ts.snap b/test/lib/__snapshots__/generator-test.ts.snap index 59c524f8..c5485eaa 100644 --- a/test/lib/__snapshots__/generator-test.ts.snap +++ b/test/lib/__snapshots__/generator-test.ts.snap @@ -316,6 +316,27 @@ exports[`generator #generate only a \`recommended\` config updates the documenta " `; +exports[`generator #generate rule config with options generates the documentation 1`] = ` +"## Rules + + +| Rule | Description | ✅ | 🔧 | 💡 | +| ------------------------------ | ---------------------- | --- | --- | --- | +| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | ✅ | | | + + +" +`; + +exports[`generator #generate rule config with options generates the documentation 2`] = ` +"# Description of no-foo (\`test/no-foo\`) + +✅ This rule is enabled in the \`recommended\` config. + + +" +`; + exports[`generator #generate rule doc without header marker but pre-existing header updates the documentation 1`] = ` "# Description (\`test/no-foo\`) @@ -327,6 +348,33 @@ Pre-existing notice about the rule being recommended. Details." `; +exports[`generator #generate rules that are disabled generates the documentation 1`] = ` +"## Rules + + +| Rule | Description | ✅ | 🔧 | 💡 | +| ------------------------------ | ---------------------- | --- | --- | --- | +| [no-bar](docs/rules/no-bar.md) | Description of no-bar. | | | | +| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | | | | + + +" +`; + +exports[`generator #generate rules that are disabled generates the documentation 2`] = ` +"# Description of no-foo (\`test/no-foo\`) + + +" +`; + +exports[`generator #generate rules that are disabled generates the documentation 3`] = ` +"# Description of no-bar (\`test/no-bar\`) + + +" +`; + exports[`generator #generate successful updates the documentation 1`] = ` "# eslint-plugin-test Description. diff --git a/test/lib/generator-test.ts b/test/lib/generator-test.ts index dc977d62..7b9993de 100644 --- a/test/lib/generator-test.ts +++ b/test/lib/generator-test.ts @@ -1481,5 +1481,111 @@ describe('generator', function () { expect(readFileSync('docs/rules/no-foo.md', 'utf8')).toMatchSnapshot(); }); }); + + describe('rule config with options', function () { + beforeEach(function () { + mockFs({ + 'package.json': JSON.stringify({ + name: 'eslint-plugin-test', + main: 'index.js', + type: 'module', + }), + + 'index.js': ` + export default { + rules: { + 'no-foo': { + meta: { docs: { description: 'Description of no-foo.' }, }, + create(context) {}, + schema: [{ /* some options */ }] + }, + }, + configs: { + recommended: { + rules: { + 'test/no-foo': ['error', { /* some options */ }], + } + }, + } + };`, + + 'README.md': '## Rules\n', + + 'docs/rules/no-foo.md': '', + + // Needed for some of the test infrastructure to work. + node_modules: mockFs.load( + resolve(__dirname, '..', '..', 'node_modules') + ), + }); + }); + + afterEach(function () { + mockFs.restore(); + jest.resetModules(); + }); + + it('generates the documentation', async function () { + await generate('.'); + expect(readFileSync('README.md', 'utf8')).toMatchSnapshot(); + expect(readFileSync('docs/rules/no-foo.md', 'utf8')).toMatchSnapshot(); + }); + }); + + describe('rules that are disabled', function () { + beforeEach(function () { + mockFs({ + 'package.json': JSON.stringify({ + name: 'eslint-plugin-test', + main: 'index.js', + type: 'module', + }), + + 'index.js': ` + export default { + rules: { + 'no-foo': { + meta: { docs: { description: 'Description of no-foo.' }, }, + create(context) {}, + }, + 'no-bar': { + meta: { docs: { description: 'Description of no-bar.' }, }, + create(context) {}, + }, + }, + configs: { + recommended: { + rules: { + 'test/no-foo': 'off', + 'test/no-bar': 0, + } + }, + } + };`, + + 'README.md': '## Rules\n', + + 'docs/rules/no-foo.md': '', + 'docs/rules/no-bar.md': '', + + // Needed for some of the test infrastructure to work. + node_modules: mockFs.load( + resolve(__dirname, '..', '..', 'node_modules') + ), + }); + }); + + afterEach(function () { + mockFs.restore(); + jest.resetModules(); + }); + + it('generates the documentation', async function () { + await generate('.'); + expect(readFileSync('README.md', 'utf8')).toMatchSnapshot(); + expect(readFileSync('docs/rules/no-foo.md', 'utf8')).toMatchSnapshot(); + expect(readFileSync('docs/rules/no-bar.md', 'utf8')).toMatchSnapshot(); + }); + }); }); });