Skip to content

Commit

Permalink
custom-error-definition: Cover exports name (#313)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHen authored and sindresorhus committed Jun 10, 2019
1 parent 6f10722 commit 3f2e9a6
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 16 deletions.
49 changes: 47 additions & 2 deletions rules/custom-error-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
const upperfirst = require('lodash.upperfirst');
const getDocsUrl = require('./utils/get-docs-url');

const MESSAGE_ID_INVALID_EXPORT = 'invalidExport';

const nameRegexp = /^(?:[A-Z][a-z\d]*)*Error$/;

const getClassName = name => upperfirst(name).replace(/(error|)$/i, 'Error');
Expand Down Expand Up @@ -124,10 +126,50 @@ const customErrorDefinition = (context, node) => {
}
};

const customErrorExport = (context, node) => {
if (!node.left.object || node.left.object.name !== 'exports') {
return;
}

if (!node.left.property) {
return;
}

const exportsName = node.left.property.name;

const maybeError = node.right;

if (maybeError.type !== 'ClassExpression') {
return;
}

if (!hasValidSuperClass(maybeError)) {
return;
}

if (!maybeError.id) {
return;
}

// Assume rule has already fixed the error name
const errorName = maybeError.id.name;

if (exportsName === errorName) {
return;
}

context.report({
node: node.left.property,
messageId: MESSAGE_ID_INVALID_EXPORT,
fix: fixer => fixer.replaceText(node.left.property, errorName)
});
};

const create = context => {
return {
ClassDeclaration: node => customErrorDefinition(context, node),
'AssignmentExpression[right.type="ClassExpression"]': node => customErrorDefinition(context, node.right)
'AssignmentExpression[right.type="ClassExpression"]': node => customErrorDefinition(context, node.right),
'AssignmentExpression[left.type="MemberExpression"]': node => customErrorExport(context, node)
};
};

Expand All @@ -138,6 +180,9 @@ module.exports = {
docs: {
url: getDocsUrl(__filename)
},
fixable: 'code'
fixable: 'code',
messages: {
[MESSAGE_ID_INVALID_EXPORT]: 'Exported error name should match error class'
}
}
};
49 changes: 35 additions & 14 deletions test/custom-error-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const noSuperCallError = {ruleId: 'custom-error-definition', message: 'Missing c
const invalidNameError = name => ({ruleId: 'custom-error-definition', message: `The \`name\` property should be set to \`${name}\`.`});
const passMessageToSuperError = {ruleId: 'custom-error-definition', message: 'Pass the error message to `super()`.'};
const invalidMessageAssignmentError = {ruleId: 'custom-error-definition', message: 'Pass the error message to `super()` instead of setting `this.message`.'};
const invalidExportError = {
ruleId: 'custom-error-definition',
messageId: 'invalidExport'
};

ruleTester.run('custom-error-definition', rule, {
valid: [
Expand Down Expand Up @@ -110,6 +114,18 @@ ruleTester.run('custom-error-definition', rule, {
this.name = 'fooError';
}
};
`,
`
exports.whatever = class Whatever {};
`,
`
class FooError extends Error {
constructor(error) {
super(error);
this.name = 'FooError';
}
};
exports.fooError = FooError;
`
],
invalid: [
Expand Down Expand Up @@ -356,20 +372,25 @@ ruleTester.run('custom-error-definition', rule, {
invalidNameError('FooError')
]
},
// TODO: Uncomment test as part of #190
// {
// code: `
// exports.fooError = class FooError extends Error {
// constructor(error) {
// super(error);
// this.name = 'FooError';
// }
// };
// `,
// errors: [
// invalidNameError('fooError')
// ]
// },
{
code: `
exports.fooError = class FooError extends Error {
constructor(error) {
super(error);
this.name = 'FooError';
}
};
`,
errors: [invalidExportError],
output: `
exports.FooError = class FooError extends Error {
constructor(error) {
super(error);
this.name = 'FooError';
}
};
`
},
{
code: `
exports.FooError = class FooError extends TypeError {
Expand Down

0 comments on commit 3f2e9a6

Please sign in to comment.