Skip to content

Commit

Permalink
New: endLine and endColumn of the lint result. (refs #3307)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Jul 9, 2016
1 parent baeb313 commit 0a44361
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/developer-guide/nodejs-api.md
Expand Up @@ -119,6 +119,8 @@ The information available for each linting message is:
* `ruleId` - the ID of the rule that triggered the messages (or null if `fatal` is true).
* `severity` - either 1 or 2, depending on your configuration.
* `source` - the line of code where the problem is (or empty string if it can't be found).
* `endColumn` - the end column of the range on which the error occurred (this property is omitted if it's not range).
* `endLine` - the end line of the range on which the error occurred (this property is omitted if it's not range).
* `fix` - an object describing the fix for the problem (this property is omitted if no fix is available).

You can also get an instance of the `SourceCode` object used inside of `linter` by using the `getSourceCode()` method:
Expand Down
8 changes: 6 additions & 2 deletions docs/developer-guide/working-with-rules.md
Expand Up @@ -127,8 +127,12 @@ The main method you'll use is `context.report()`, which publishes a warning or e
* `message` - the problem message.
* `node` - (optional) the AST node related to the problem. If present and `loc` is not specified, then the starting location of the node is used as the location of the problem.
* `loc` - (optional) an object specifying the location of the problem. If both `loc` and `node` are specified, then the location is used from `loc` instead of `node`.
* `line` - the 1-based line number at which the problem occurred.
* `column` - the 0-based column number at which the problem occurred.
* `start` - An object of the start location.
* `line` - the 1-based line number at which the problem occurred.
* `column` - the 0-based column number at which the problem occurred.
* `end` - An object of the end location.
* `line` - the 1-based line number at which the problem occurred.
* `column` - the 0-based column number at which the problem occurred.
* `data` - (optional) placeholder data for `message`.
* `fix` - (optional) a function that applies a fix to resolve the problem.

Expand Down
11 changes: 10 additions & 1 deletion lib/eslint.js
Expand Up @@ -954,7 +954,10 @@ module.exports = (function() {
location = node.loc.start;
}

// else, assume location was provided, so node may be omitted
// Store end location.
var endLocation = location.end;

location = location.start || location;

if (isDisabledByReportingConfig(reportingConfig, ruleId, location)) {
return;
Expand All @@ -981,6 +984,12 @@ module.exports = (function() {
source: sourceCode.lines[location.line - 1] || ""
};

// Define endLine and endColumn if exists.
if (endLocation) {
problem.endLine = endLocation.line;
problem.endColumn = endLocation.column + 1; // switch to 1-base instead of 0-base
}

// ensure there's range and text properties, otherwise it's not a valid fix
if (fix && Array.isArray(fix.range) && (typeof fix.text === "string")) {

Expand Down
8 changes: 8 additions & 0 deletions lib/testers/rule-tester.js
Expand Up @@ -418,6 +418,14 @@ RuleTester.prototype = {
if (item.errors[i].hasOwnProperty("column")) {
assert.equal(messages[i].column, item.errors[i].column, "Error column should be " + item.errors[i].column);
}

if (item.errors[i].hasOwnProperty("endLine")) {
assert.equal(messages[i].endLine, item.errors[i].endLine, "Error endLine should be " + item.errors[i].endLine);
}

if (item.errors[i].hasOwnProperty("endColumn")) {
assert.equal(messages[i].endColumn, item.errors[i].endColumn, "Error endColumn should be " + item.errors[i].endColumn);
}
} else {

// Only string or object errors are valid.
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/testers/rule-tester/no-var.js
Expand Up @@ -20,6 +20,7 @@ module.exports = function(context) {
if (node.kind === "var") {
context.report({
node: node,
loc: sourceCode.getFirstToken(node).loc,
message: "Bad var.",
fix: function(fixer) {
return fixer.remove(sourceCode.getFirstToken(node));
Expand Down
50 changes: 50 additions & 0 deletions tests/lib/eslint.js
Expand Up @@ -1071,6 +1071,56 @@ describe("eslint", function() {
});
});

it("should not have 'endLine' and 'endColumn' when there is not 'loc' property.", function() {
eslint.on("Program", function(node) {
eslint.report(
"test-rule",
2,
node,
"test"
);
});

var messages = eslint.verify("0", config, "", true);

assert.strictEqual(messages[0].endLine, void 0);
assert.strictEqual(messages[0].endColumn, void 0);
});

it("should have 'endLine' and 'endColumn' when 'loc' property has 'end' property.", function() {
eslint.on("Program", function(node) {
eslint.report(
"test-rule",
2,
node,
node.loc,
"test"
);
});

var messages = eslint.verify("0", config, "", true);

assert.strictEqual(messages[0].endLine, 1);
assert.strictEqual(messages[0].endColumn, 2);
});

it("should not have 'endLine' and 'endColumn' when 'loc' property doe not have 'end' property.", function() {
eslint.on("Program", function(node) {
eslint.report(
"test-rule",
2,
node,
node.loc.start,
"test"
);
});

var messages = eslint.verify("0", config, "", true);

assert.strictEqual(messages[0].endLine, void 0);
assert.strictEqual(messages[0].endColumn, void 0);
});

});

describe("when evaluating code", function() {
Expand Down
26 changes: 26 additions & 0 deletions tests/lib/testers/rule-tester.js
Expand Up @@ -253,6 +253,32 @@ describe("RuleTester", function() {
}, /Error column should be 0/);
});

it("should throw an error if invalid code specifies wrong endLine", function() {
assert.throws(function() {
ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
valid: [
"bar = baz;"
],
invalid: [
{ code: "var foo = bar;", output: "foo = bar", errors: [{ message: "Bad var.", type: "VariableDeclaration", endLine: 10}] }
]
});
}, "Error endLine should be 10");
});

it("should throw an error if invalid code specifies wrong endColumn", function() {
assert.throws(function() {
ruleTester.run("no-var", require("../../fixtures/testers/rule-tester/no-var"), {
valid: [
"bar = baz;"
],
invalid: [
{ code: "var foo = bar;", output: "foo = bar", errors: [{ message: "Bad var.", type: "VariableDeclaration", endColumn: 10}] }
]
});
}, "Error endColumn should be 10");
});

it("should throw an error if invalid code has the wrong number of errors", function() {

assert.throws(function() {
Expand Down

0 comments on commit 0a44361

Please sign in to comment.