Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ const errorSignature = err =>

const getErrorCode = _.pipe(_.get('ruleId'), _.split('/'), _.last);

const preprocessorPlaceholder = '___';
const preprocessorTemplate = `JSON.stringify(${preprocessorPlaceholder})`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is JSON.stringify even necessary? Just wrapping the JSON is parentheses would make for valid JS: ({"foo":1})

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but as soon as additional eslint rules kick in (for example no-unused-expressions) or prettier tries to parse the file with babel, things start to fall apart. One could work around those issues by fine-tuning the eslintrc file, but just adding JSON.stringify simplifies things in practice a lot.


const processors = {
'.json': {
preprocess: function(text, fileName) {
Expand All @@ -112,7 +115,14 @@ const processors = {
const parsed = jsonServiceHandle.parseJSONDocument(textDocument);
fileLintResults[fileName] = getDiagnostics(parsed);
fileComments[fileName] = parsed.comments;
return ['']; // sorry nothing ;)

const [, eol = ''] = text.match(/([\n\r]*)$/);
return [
preprocessorTemplate.replace(
preprocessorPlaceholder,
text.slice(0, text.length - eol.length)
) + eol
];
},
postprocess: function(messages, fileName) {
const textDocument = fileDocuments[fileName];
Expand Down Expand Up @@ -144,6 +154,20 @@ const processors = {
endColumn: error.endColumn + 1
});
}),
_.mapValues(error => {
if (_.startsWith('json/', error.ruleId)) return error;
const prefixLength = preprocessorTemplate.indexOf(preprocessorPlaceholder);

return _.assign(error, {
column: error.column - (error.line === 1 ? prefixLength : 0),
endColumn: error.endColumn - (error.endLine === 1 ? prefixLength : 0),
fix:
error.fix &&
_.assign(error.fix, {
range: error.fix.range.map(location => location - prefixLength)
})
});
}),
_.values
)(messages);
}
Expand Down
7 changes: 3 additions & 4 deletions test/integration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ function validateInfringementExpectation(expected, actualSituation) {
else expect(actualSituation).to.have.property(scoped(rule));
}
const allExpectedErrors = expected.map(_.pipe(_.split(':'), _.head, scoped));
expect(_.xor(_.keys(actualSituation), allExpectedErrors)).to.have.length(
0,
'Extra errors found'
);
// only check for errors generated by this plugin
const actualErrors = _.keys(actualSituation).filter(error => error.startsWith(scoped('')));
expect(_.xor(actualErrors, allExpectedErrors)).to.have.length(0, 'Extra errors found');
}

function validateFile(filename, config = {}) {
Expand Down
15 changes: 10 additions & 5 deletions test/unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ describe('plugin', function() {
});
describe('preprocess', function() {
const preprocess = plugin.processors['.json'].preprocess;
it('should return the same text', function() {
it('should contain the text', function() {
const fileName = 'whatever-the-name.js';

const newText = preprocess('whatever', fileName);
const text = 'whatever';
const newText = preprocess(text, fileName);
assert.isArray(newText, 'preprocess should return array');
assert.strictEqual(newText[0], '');
assert.include(newText[0], text);
});
});
describe('postprocess', function() {
Expand Down Expand Up @@ -91,8 +92,12 @@ describe('plugin', function() {

const rules = ['undefined', 'trailing-comma'];
const lintFile = fakeApplyRule(rules.map(rule => plugin.rules[rule]));
const samples = [singleQuotes, trailingCommas, multipleErrors, trailingText, good];
samples.forEach(sample => preprocess(sample.text, sample.fileName));
let samples = [singleQuotes, trailingCommas, multipleErrors, trailingText, good].map(
sample => {
// !FIXME: check
return _.set('text', preprocess(sample.text, sample.fileName)[0], sample);
}
);

const errorsByFile = _.fromPairs(
samples.map(sample => [sample.fileName, lintFile(sample.fileName)])
Expand Down