Permalink
Browse files

Breaking: require rules to provide report messages (fixes #10011) (#1…

…0057)

This updates ESLint core to throw an error when a rule reports a problem without providing a report message. It is unlikely that many users were relying on the previous behavior, because a reported problem without a message would crash several formatters, including the default formatter. However, it is possible that someone was relying on this with the `json` formatter.
  • Loading branch information...
not-an-aardvark committed Mar 22, 2018
1 parent 837edc7 commit a9ee9ae879f4f8226f07b159700bb5bd4e9028ff
Showing with 31 additions and 11 deletions.
  1. +8 −11 lib/report-translator.js
  2. +14 −0 tests/lib/linter.js
  3. +9 −0 tests/lib/report-translator.js
View
@@ -113,15 +113,6 @@ function normalizeReportLoc(descriptor) {
return descriptor.node.loc;
}
/**
* Interpolates data placeholders in report messages
* @param {MessageDescriptor} descriptor The report message descriptor.
* @returns {string} The interpolated message for the descriptor
*/
function normalizeMessagePlaceholders(descriptor) {
return interpolate(descriptor.message, descriptor.data);
}
/**
* Compares items in a fixes array by range.
* @param {Fix} a The first message.
@@ -254,6 +245,8 @@ module.exports = function createReportTranslator(metadata) {
assertValidNodeInfo(descriptor);
let computedMessage;
if (descriptor.messageId) {
if (!metadata.messageIds) {
throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata.");
@@ -267,15 +260,19 @@ module.exports = function createReportTranslator(metadata) {
if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) {
throw new TypeError(`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`);
}
descriptor.message = messages[id];
computedMessage = messages[id];
} else if (descriptor.message) {
computedMessage = descriptor.message;
} else {
throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem.");
}
return createProblem({
ruleId: metadata.ruleId,
severity: metadata.severity,
node: descriptor.node,
message: normalizeMessagePlaceholders(descriptor),
message: interpolate(computedMessage, descriptor.data),
messageId: descriptor.messageId,
loc: normalizeReportLoc(descriptor),
fix: normalizeFixes(descriptor, metadata.sourceCode)
View
@@ -851,6 +851,20 @@ describe("Linter", () => {
sinon.assert.calledTwice(spyLiteral);
sinon.assert.calledOnce(spyBinaryExpression);
});
it("should throw an error if a rule reports a problem without a message", () => {
linter.defineRule("invalid-report", context => ({
Program(node) {
context.report({ node });
}
}));
assert.throws(
() => linter.verify("foo", { rules: { "invalid-report": "error" } }),
TypeError,
"Missing `message` property in report() call; add a message that describes the linting problem."
);
});
});
describe("when config has shared settings for rules", () => {
@@ -164,6 +164,15 @@ describe("createReportTranslator", () => {
/^context\.report\(\) called with a messageId of '[^']+' which is not present in the 'messages' config:/
);
});
it("should throw when no message is provided", () => {
const reportDescriptor = { node };
assert.throws(
() => translateReport(reportDescriptor),
TypeError,
"Missing `message` property in report() call; add a message that describes the linting problem."
);
});
});
describe("combining autofixes", () => {
it("should merge fixes to one if 'fix' function returns an array of fixes.", () => {

0 comments on commit a9ee9ae

Please sign in to comment.