Skip to content

Commit

Permalink
New: Add context.report({ messageId }) (fixes eslint#6740)
Browse files Browse the repository at this point in the history
  • Loading branch information
j-f1 committed Sep 14, 2017
1 parent 2731f94 commit cd4bde8
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 4 deletions.
3 changes: 2 additions & 1 deletion lib/linter.js
Expand Up @@ -869,6 +869,7 @@ module.exports = class Linter {
}

const rule = this.rules.get(ruleId);
const messageIds = rule && rule.meta && rule.meta.messages;
let reportTranslator = null;
const ruleContext = Object.freeze(
Object.assign(
Expand All @@ -889,7 +890,7 @@ module.exports = class Linter {
* with Node 8.4.0.
*/
if (reportTranslator === null) {
reportTranslator = createReportTranslator({ ruleId, severity, sourceCode });
reportTranslator = createReportTranslator({ ruleId, severity, sourceCode, messageIds });
}
const problem = reportTranslator.apply(null, arguments);

Expand Down
26 changes: 24 additions & 2 deletions lib/report-translator.js
Expand Up @@ -216,6 +216,12 @@ function createProblem(options) {
source: options.sourceLines[options.loc.start.line - 1] || ""
};

// If this isn’t in the conditional, some of the tests fail
// because `messageId` is present in the problem object
if (options.messageId) {
problem.messageId = options.messageId;
}

if (options.loc.end) {
problem.endLine = options.loc.end.line;
problem.endColumn = options.loc.end.column + 1;
Expand All @@ -231,12 +237,13 @@ function createProblem(options) {
/**
* Returns a function that converts the arguments of a `context.report` call from a rule into a reported
* problem for the Node.js API.
* @param {{ruleId: string, severity: number, sourceCode: SourceCode}} metadata Metadata for the reported problem
* @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object}} metadata Metadata for the reported problem
* @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted
* @returns {function(...args): {
* ruleId: string,
* severity: (0|1|2),
* message: string,
* message: (string|undefined),
* messageId: (string|undefined),
* line: number,
* column: number,
* endLine: (number|undefined),
Expand All @@ -261,11 +268,26 @@ module.exports = function createReportTranslator(metadata) {

assertValidNodeInfo(descriptor);

if (descriptor.messageId) {
const id = descriptor.messageId;
const messages = metadata.messageIds;

if (descriptor.message) {
throw new TypeError("context.report() called with a message and a messageId. Please only pass one.");
}
if (!messages || !Object.keys(messages).includes(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];
}


return createProblem({
ruleId: metadata.ruleId,
severity: metadata.severity,
node: descriptor.node,
message: normalizeMessagePlaceholders(descriptor),
messageId: descriptor.messageId,
loc: normalizeReportLoc(descriptor),
fix: normalizeFixes(descriptor, metadata.sourceCode),
sourceLines: metadata.sourceCode.lines
Expand Down
57 changes: 56 additions & 1 deletion tests/lib/report-translator.js
Expand Up @@ -48,7 +48,7 @@ describe("createReportTranslator", () => {
node = sourceCode.ast.body[0];
location = sourceCode.ast.body[1].loc.start;
message = "foo";
translateReport = createReportTranslator({ ruleId: "foo-rule", severity: 2, sourceCode });
translateReport = createReportTranslator({ ruleId: "foo-rule", severity: 2, sourceCode, messageIds: { testMessage: message } });
});

describe("old-style call with location", () => {
Expand Down Expand Up @@ -113,6 +113,61 @@ describe("createReportTranslator", () => {
}
);
});
it("should translate the messageId into a message", () => {
const reportDescriptor = {
node,
loc: location,
messageId: "testMessage",
fix: () => ({ range: [1, 2], text: "foo" })
};

assert.deepEqual(
translateReport(reportDescriptor),
{
ruleId: "foo-rule",
severity: 2,
message: "foo",
messageId: "testMessage",
line: 2,
column: 1,
nodeType: "ExpressionStatement",
source: "bar",
fix: {
range: [1, 2],
text: "foo"
}
}
);
});
it("should throw when both messageId and message are provided", () => {
const reportDescriptor = {
node,
loc: location,
messageId: "testMessage",
message: "bar",
fix: () => ({ range: [1, 2], text: "foo" })
};

assert.throws(
() => translateReport(reportDescriptor),
TypeError,
"context.report() called with a message and a messageId. Please only pass one."
);
});
it("should throw when an invalid messageId is provided", () => {
const reportDescriptor = {
node,
loc: location,
messageId: "thisIsNotASpecifiedMessageId",
fix: () => ({ range: [1, 2], text: "foo" })
};

assert.throws(
() => translateReport(reportDescriptor),
TypeError,
/^context\.report\(\) called with a messageId of '[^']+' which is not present in the 'messages' config:/
);
});
});
describe("combining autofixes", () => {
it("should merge fixes to one if 'fix' function returns an array of fixes.", () => {
Expand Down

0 comments on commit cd4bde8

Please sign in to comment.