Skip to content

Commit

Permalink
fix: ensure config emoji used in rule doc notice
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish committed Nov 1, 2022
1 parent 5981e42 commit 74668fa
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 62 deletions.
135 changes: 74 additions & 61 deletions lib/rule-notices.ts
Expand Up @@ -38,6 +38,47 @@ export const NOTICE_TYPE_DEFAULT_PRESENCE_AND_ORDERING: {
[NOTICE_TYPE.TYPE]: false,
};

function severityToTerminology(severity: SEVERITY_TYPE) {
switch (severity) {
case SEVERITY_TYPE.error:
return 'is enabled';
case SEVERITY_TYPE.warn:
return '_warns_';
case SEVERITY_TYPE.off:
return 'is _disabled_';
default:
throw new Error(`Unknown severity: ${severity}`);
}
}

function configsToNoticeSentence(
configs: string[],
severity: SEVERITY_TYPE,
configsLinkOrWord: string,
configLinkOrWord: string,
configEmojis: ConfigEmojis,
useGenericConfigEmoji: boolean
): string | undefined {
const csv = configs
.map((config) => {
const emoji = findConfigEmoji(configEmojis, config);
return `${emoji ? `${emoji} ` : ''}\`${config}\``;
})
.join(', ');

const term = severityToTerminology(severity);
const sentence =
configs.length > 1
? `This rule ${term} in the following ${configsLinkOrWord}: ${csv}.`
: configs.length === 1
? `This rule ${term} in the ${
useGenericConfigEmoji ? csv : `\`${configs?.[0]}\``
} ${configLinkOrWord}.`
: undefined;

return sentence;
}

/**
* An object containing the text for each notice type (as a string or function to generate the string).
*/
Expand Down Expand Up @@ -82,10 +123,9 @@ const RULE_NOTICES: {

// If one applicable config with an emoji, use the emoji for that config, otherwise use the general config emoji.
let emoji = '';
if (
configsEnabled.length + configsWarn.length + configsDisabled.length >
1
) {
const useGenericConfigEmoji =
configsEnabled.length + configsWarn.length + configsDisabled.length > 1;
if (useGenericConfigEmoji) {
emoji = EMOJI_CONFIG;
} else if (configsEnabled.length > 0) {
// @ts-expect-error -- will always be a string thanks to fallback
Expand All @@ -107,63 +147,36 @@ const RULE_NOTICES: {
});
}

// List of configs that enable the rule.
const configsEnabledCSV = configsEnabled
.map((configEnabled) => {
const emoji = configEmojis.find(
(configEmoji) => configEmoji.config === configEnabled
)?.emoji;
return `${emoji ? `${emoji} ` : ''}\`${configEnabled}\``;
})
.join(', ');

// List of configs that warn for the rule.
const configsWarnCSV = configsWarn
.map((configWarn) => {
const emoji = configEmojis.find(
(configEmoji) => configEmoji.config === configWarn
)?.emoji;
return `${emoji ? `${emoji} ` : ''}\`${configWarn}\``;
})
.join(', ');

// List of configs that disable the rule.
const configsDisabledCSV = configsDisabled
.map((configDisabled) => {
const emoji = configEmojis.find(
(configEmoji) => configEmoji.config === configDisabled
)?.emoji;
return `${emoji ? `${emoji} ` : ''}\`${configDisabled}\``;
})
.join(', ');

// Complete sentence for configs that enable the rule.
const SENTENCE_ENABLED =
configsEnabled.length > 1
? `This rule is enabled in the following ${configsLinkOrWord}: ${configsEnabledCSV}.`
: configsEnabled.length === 1
? `This rule is enabled in the \`${configsEnabled?.[0]}\` ${configLinkOrWord}.`
: undefined;

// Complete sentence for configs that warn for the rule.
const SENTENCE_WARN =
configsWarn.length > 1
? `This rule _warns_ in the following ${configsLinkOrWord}: ${configsWarnCSV}.`
: configsWarn.length === 1
? `This rule _warns_ in the \`${configsWarn?.[0]}\` ${configLinkOrWord}.`
: undefined;

// Complete sentence for configs that disable the rule.
const SENTENCE_DISABLED =
configsDisabled.length > 1
? `This rule is _disabled_ in the following ${configsLinkOrWord}: ${configsDisabledCSV}.`
: configsDisabled.length === 1
? `This rule is _disabled_ in the \`${configsDisabled?.[0]}\` ${configLinkOrWord}.`
: undefined;

return `${emoji} ${[SENTENCE_ENABLED, SENTENCE_WARN, SENTENCE_DISABLED]
.filter((sentence) => sentence !== undefined)
.join(' ')}`;
const sentences = [
configsToNoticeSentence(
configsEnabled,
SEVERITY_TYPE.error,
configsLinkOrWord,
configLinkOrWord,
configEmojis,
useGenericConfigEmoji
),
configsToNoticeSentence(
configsWarn,
SEVERITY_TYPE.warn,
configsLinkOrWord,
configLinkOrWord,
configEmojis,
useGenericConfigEmoji
),
configsToNoticeSentence(
configsDisabled,
SEVERITY_TYPE.off,
configsLinkOrWord,
configLinkOrWord,
configEmojis,
useGenericConfigEmoji
),
]
.filter(Boolean)
.join(' ');

return `${emoji} ${sentences}`;
},

// Deprecated notice has optional "replaced by" rules list.
Expand Down
27 changes: 26 additions & 1 deletion test/lib/__snapshots__/generator-test.ts.snap
Expand Up @@ -650,7 +650,7 @@ exports[`generator #generate rules that are disabled or set to warn generates th
exports[`generator #generate rules that are disabled or set to warn generates the documentation 4`] = `
"# Description of no-baz (\`test/no-baz\`)
💼 This rule is enabled in the \`recommended\` config. This rule is _disabled_ in the \`other\` config.
💼 This rule is enabled in the \`recommended\` config. This rule is _disabled_ in the \`other\` config.
<!-- end auto-generated rule header -->
"
Expand Down Expand Up @@ -726,6 +726,31 @@ exports[`generator #generate rules that are disabled or set to warn, only one co
"
`;

exports[`generator #generate rules that are disabled or set to warn, two configs present generates the documentation 1`] = `
"## Rules
<!-- begin auto-generated rules list -->
💼 Configurations enabled in.\\
✅<sup>⚠️</sup> Warns in the \`recommended\` configuration.\\
⌨️<sup>🚫</sup> Disabled in the \`typescript\` configuration.
| Name | Description | 💼 |
| :----------------------------- | :--------------------- | :------------------------------------------------------------------------------------------------------------- |
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | <span style="white-space:nowrap">✅<sup>⚠️</sup></span> <span style="white-space:nowrap">⌨️<sup>🚫</sup></span> |
<!-- end auto-generated rules list -->
"
`;

exports[`generator #generate rules that are disabled or set to warn, two configs present generates the documentation 2`] = `
"# Description of no-foo (\`test/no-foo\`)
💼 This rule _warns_ in the ✅ \`recommended\` config. This rule is _disabled_ in the ⌨️ \`typescript\` config.
<!-- end auto-generated rule header -->
"
`;

exports[`generator #generate shows column and notice for requiresTypeChecking updates the documentation 1`] = `
"<!-- begin auto-generated rules list -->
Expand Down
54 changes: 54 additions & 0 deletions test/lib/generator-test.ts
Expand Up @@ -2015,6 +2015,60 @@ describe('generator', function () {
});
});

describe('rules that are disabled or set to warn, two configs present', 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) {},
},
},
configs: {
recommended: {
rules: {
'test/no-foo': 1,
}
},
typescript: {
rules: {
'test/no-foo': 0,
}
},
}
};`,

'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('config emoji matches off/warn emoji superscript', function () {
beforeEach(function () {
mockFs({
Expand Down

0 comments on commit 74668fa

Please sign in to comment.