Skip to content

Commit

Permalink
feat: no-split-examples (#120)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Jan 3, 2023
1 parent 01152fd commit a7ddff0
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { idFlagSuggestions } from './rules/id-flag-suggestions';
import { noIdFlags } from './rules/migration/no-id-flags';
import { noFilepathFlags } from './rules/migration/no-filepath-flags';
import { noNumberFlags } from './rules/migration/no-number-flags';
import { noSplitExamples } from './rules/no-split-examples';
import { noUsernameProperties } from './rules/migration/no-username-properties';
import { noUnnecessaryProperties } from './rules/no-unnecessary-properties';

Expand All @@ -57,6 +58,7 @@ const recommended = {
'sf-plugin/no-oclif-flags-command-import': 'error',
'sf-plugin/read-only-properties': 'warn',
'sf-plugin/id-flag-suggestions': 'warn',
'sf-plugin/no-split-examples': 'error',
'sf-plugin/no-unnecessary-properties': 'warn',
},
};
Expand Down Expand Up @@ -113,6 +115,7 @@ export = {
'no-id-flags': noIdFlags,
'no-filepath-flags': noFilepathFlags,
'no-number-flags': noNumberFlags,
'no-split-examples': noSplitExamples,
'no-username-properties': noUsernameProperties,
'no-unnecessary-properties': noUnnecessaryProperties,
},
Expand Down
1 change: 0 additions & 1 deletion src/rules/dash-o.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export const dashO = ESLintUtils.RuleCreator.withoutDocs({
ancestorsContainsSfCommand(context.getAncestors()) &&
node.value?.type === AST_NODE_TYPES.CallExpression &&
node.value.callee?.type === AST_NODE_TYPES.MemberExpression &&
node.value.callee?.type === AST_NODE_TYPES.MemberExpression &&
node.value.callee.property.type === AST_NODE_TYPES.Identifier &&
!node.value.callee.property.name.toLowerCase().includes('org') &&
!node.value.callee.property.name.toLowerCase().includes('hub') &&
Expand Down
60 changes: 60 additions & 0 deletions src/rules/no-split-examples.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
import { extendsSfCommand, isInCommandDirectory } from '../shared/commands';

export const noSplitExamples = ESLintUtils.RuleCreator.withoutDocs({
meta: {
docs: {
description: 'Arrays of messags should use getMessages instead of getMessage followed by EOL splitting',
recommended: 'error',
},
messages: {
message: 'use getMessages',
},
type: 'problem',
fixable: 'code',
schema: [],
},
defaultOptions: [],
create(context) {
return isInCommandDirectory(context)
? {
PropertyDefinition(node): void {
if (
node.static &&
node.key.type === AST_NODE_TYPES.Identifier &&
node.key.name === 'examples' &&
node.parent.type === AST_NODE_TYPES.ClassBody &&
node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration &&
node.value.type === AST_NODE_TYPES.CallExpression &&
node.value.callee.type === AST_NODE_TYPES.MemberExpression &&
node.value.callee.object.type === AST_NODE_TYPES.CallExpression &&
node.value.callee.object.callee.type === AST_NODE_TYPES.MemberExpression &&
node.value.callee.object.callee.property.type === AST_NODE_TYPES.Identifier &&
node.value.callee.object.callee.property.name === 'getMessage' &&
node.value.callee.property.type === AST_NODE_TYPES.Identifier &&
node.value.callee.property.name === 'split' &&
extendsSfCommand(node.parent.parent)
) {
const target = node.value;
const fixedText = context
.getSourceCode()
.getText(node.value)
.replace('getMessage', 'getMessages')
.replace(/\.split\(.*\)/, '');
context.report({
node: node.value.callee.property,
messageId: 'message',
fix: (fixer) => fixer.replaceText(target, fixedText),
});
}
},
}
: {};
},
});
64 changes: 64 additions & 0 deletions test/rules/no-split-examples.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import path from 'path';
import { ESLintUtils } from '@typescript-eslint/utils';
import { noSplitExamples } from '../../src/rules/no-split-examples';

const ruleTester = new ESLintUtils.RuleTester({
parser: '@typescript-eslint/parser',
});

ruleTester.run('noSplitExamples', noSplitExamples, {
valid: [
{
name: 'correct examples with getMessages',
code: `
export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
public static readonly examples = messages.getMessages('examples')
}
`,
},
{
name: 'not an sf command',
code: `
export default class EnvCreateScratch extends somethingElse<ScratchCreateResponse> {
public static readonly examples = message.getMessage('examples').split(EOL)
}
`,
},
{
name: 'not in the commands folder',
filename: path.normalize('foo.ts'),
code: `
export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
public static readonly examples = message.getMessage('examples').split(EOL)
}
`,
},
],
invalid: [
{
name: 'getMessages with split',
filename: path.normalize('src/commands/foo.ts'),
errors: [
{
messageId: 'message',
},
],
code: `
export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
public static readonly examples = message.getMessage('examples').split(EOL);
}
`,
output: `
export default class EnvCreateScratch extends SfCommand<ScratchCreateResponse> {
public static readonly examples = message.getMessages('examples');
}
`,
},
],
});

0 comments on commit a7ddff0

Please sign in to comment.