Skip to content

Commit

Permalink
Breaking: Support ESM rules
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish committed Sep 21, 2021
1 parent 30bb8e2 commit a73fb83
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
17 changes: 16 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,20 @@ module.exports = {
let exportsVarOverridden = false;
let exportsIsFunction = false;

const exportNodes = ast.body
// ESM
const exportDefaultDeclaration = ast.body.find(statement => statement.type === 'ExportDefaultDeclaration');
const exportNodesESM = exportDefaultDeclaration && exportDefaultDeclaration.declaration.type === 'ObjectExpression' ?
exportDefaultDeclaration.declaration.properties.reduce((parsedProps, prop) => {
const keyValue = module.exports.getKeyName(prop);
if (INTERESTING_KEYS.has(keyValue)) {
parsedProps[keyValue] = prop.value;
}
return parsedProps;
}, {}) :
undefined;

// CJS
const exportNodesCJS = ast.body
.filter(statement => statement.type === 'ExpressionStatement')
.map(statement => statement.expression)
.filter(expression => expression.type === 'AssignmentExpression')
Expand Down Expand Up @@ -150,6 +163,8 @@ module.exports = {
return currentExports;
}, {});

const exportNodes = exportNodesESM || exportNodesCJS;

const createExists = Object.prototype.hasOwnProperty.call(exportNodes, 'create');
if (!createExists) {
return null;
Expand Down
23 changes: 23 additions & 0 deletions tests/lib/rules/prefer-message-ids.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ ruleTester.run('prefer-message-ids', rule, {
}
};
`,
{
// ESM
code: `
export default {
create(context) {
context.report({ node, messageId: 'foo' });
}
};
`,
parserOptions: { sourceType: 'module' },
},
`
module.exports = {
create(context) {
Expand Down Expand Up @@ -91,6 +102,18 @@ ruleTester.run('prefer-message-ids', rule, {
`,
errors: [{ messageId: 'foundMessage', type: 'Property' }],
},
{
// ESM
code: `
export default {
create(context) {
context.report({ node, message: 'foo' });
}
};
`,
parserOptions: { sourceType: 'module' },
errors: [{ messageId: 'foundMessage', type: 'Property' }],
},
{
// With message in variable.
code: `
Expand Down
22 changes: 22 additions & 0 deletions tests/lib/rules/require-meta-docs-description.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ ruleTester.run('require-meta-docs-description', rule, {
create(context) {}
};
`,
{
// ESM
code: `
export default {
meta: { docs: { description: 'disallow unused variables' } },
create(context) {}
};
`,
parserOptions: { sourceType: 'module' },
},
`
module.exports = {
meta: { docs: { description: 'enforce a maximum line length' } },
Expand Down Expand Up @@ -104,6 +114,18 @@ ruleTester.run('require-meta-docs-description', rule, {
output: null,
errors: [{ messageId: 'missing', type: 'ObjectExpression' }],
},
{
// ESM
code: `
export default {
meta: {},
create(context) {}
};
`,
output: null,
parserOptions: { sourceType: 'module' },
errors: [{ messageId: 'missing', type: 'ObjectExpression' }],
},
{
code: `
module.exports = {
Expand Down
29 changes: 28 additions & 1 deletion tests/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,23 @@ describe('utils', () => {
});
});

describe('the file does not have a valid rule (ESM)', () => {
[
'',
'export const foo = { create() {} }',
'export default { foo: {} }',
'const foo = {}; export default foo',
].forEach(noRuleCase => {
it(`returns null for ${noRuleCase}`, () => {
const ast = espree.parse(noRuleCase, { ecmaVersion: 8, range: true, sourceType: 'module' });
assert.isNull(utils.getRuleInfo({ ast }), 'Expected no rule to be found');
});
});
});

describe('the file has a valid rule', () => {
const CASES = {
// CJS
'module.exports = { create: function foo() {} };': {
create: { type: 'FunctionExpression', id: { name: 'foo' } }, // (This property will actually contain the AST node.)
meta: null,
Expand Down Expand Up @@ -110,11 +125,23 @@ describe('utils', () => {
meta: null,
isNewStyle: false,
},

// ESM
'export default { create() {} }': {
create: { type: 'FunctionExpression' },
meta: null,
isNewStyle: true,
},
'export default { create() {}, meta: {} }': {
create: { type: 'FunctionExpression' },
meta: { type: 'ObjectExpression' },
isNewStyle: true,
},
};

Object.keys(CASES).forEach(ruleSource => {
it(ruleSource, () => {
const ast = espree.parse(ruleSource, { ecmaVersion: 6, range: true });
const ast = espree.parse(ruleSource, { ecmaVersion: 6, range: true, sourceType: ruleSource.includes('export default') ? 'module' : 'script' });
const ruleInfo = utils.getRuleInfo({ ast });
assert(
lodash.isMatch(ruleInfo, CASES[ruleSource]),
Expand Down

0 comments on commit a73fb83

Please sign in to comment.