Skip to content

Commit

Permalink
Sort error output by file/line number/rule name/description (fixes #26).
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidAnson committed Jan 30, 2018
1 parent 8008d42 commit 6722a92
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
23 changes: 21 additions & 2 deletions markdownlint.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,34 @@ function prepareFileList(files) {

function lint(lintFiles, config) {
var lintOptions = {
resultVersion: 2,
files: lintFiles,
config: config
};
return markdownlint.sync(lintOptions);
}

function printResult(lintResult) {
var lintResultString = lintResult.toString();
if (lintResultString) {
var results = flatten(Object.keys(lintResult).map(function (file) {
return lintResult[file].map(function (result) {
return {
file: file,
lineNumber: result.lineNumber,
names: result.ruleNames.join('/'),
description: result.ruleDescription +
(result.errorDetail ? ' [' + result.errorDetail + ']' : '') +
(result.errorContext ? ' [Context: "' + result.errorContext + '"]' : '')
};
});
}));
if (results.length > 0) {
results.sort(function (a, b) {
return a.file.localeCompare(b.file) || a.lineNumber - b.lineNumber ||
a.names.localeCompare(b.names) || a.description.localeCompare(b.description);
});
var lintResultString = results.map(function (result) {
return result.file + ': ' + result.lineNumber + ': ' + result.names + ' ' + result.description;
}).join('\n');
console.error(lintResultString);
// Note: process.exit(1) will end abruptly, interrupting asynchronous IO
// streams (e.g., when the output is being piped). Just set the exit code
Expand Down
28 changes: 28 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ test('linting of incorrect Markdown file fails', async t => {
try {
await execa('../markdownlint.js',
['--config', 'test-config.json', 'incorrect.md']);
t.fail();
} catch (err) {
t.true(err.stdout === '');
t.true(err.stderr.match(errorPattern).length === 8);
Expand All @@ -39,6 +40,7 @@ test('linting of incorrect Markdown file fails', async t => {
test('linting of incorrect Markdown via npm run file fails with eol', async t => {
try {
await execa('npm', ['run', 'invalid']);
t.fail();
} catch (err) {
t.true(/\nnpm ERR! code ELIFECYCLE/.test(err.stderr));
}
Expand All @@ -55,6 +57,7 @@ test('glob linting works with failing files', async t => {
try {
await execa('../markdownlint.js',
['--config', 'test-config.json', '**/*.md']);
t.fail();
} catch (err) {
t.true(err.stdout === '');
t.true(err.stderr.match(errorPattern).length === 16);
Expand All @@ -72,6 +75,7 @@ test('dir linting works with failing .markdown files', async t => {
try {
await execa('../markdownlint.js',
['--config', 'test-config.json', 'subdir-incorrect']);
t.fail();
} catch (err) {
t.true(err.stdout === '');
t.true(err.stderr.match(errorPattern).length === 10);
Expand All @@ -96,6 +100,7 @@ test('glob linting with failing files has fewer errors when ignored by dir', asy
try {
await execa('../markdownlint.js',
['--config', 'test-config.json', '**/*.md', '--ignore', 'subdir-incorrect']);
t.fail();
} catch (err) {
t.true(err.stdout === '');
t.true(err.stderr.match(errorPattern).length === 8);
Expand All @@ -106,6 +111,7 @@ test('dir linting with failing files has fewer errors when ignored by file', asy
try {
await execa('../markdownlint.js',
['--config', 'test-config.json', 'subdir-incorrect', '--ignore', 'subdir-incorrect/incorrect.md']);
t.fail();
} catch (err) {
t.true(err.stdout === '');
t.true(err.stderr.match(errorPattern).length === 2);
Expand All @@ -118,3 +124,25 @@ test('glob linting with failing files passes when ignored by multiple globs', as
t.true(result.stdout === '');
t.true(result.stderr === '');
});

test('linting results are sorted by file/line/names/description', async t => {
try {
await execa('../markdownlint.js',
['--config', 'test-config.json', 'incorrect.md']);
t.fail();
} catch (err) {
const expected = [
'incorrect.md: 1: MD002/first-header-h1 First header should be a top level header [Expected: h1; Actual: h2]',
'incorrect.md: 1: MD022/blanks-around-headers Headers should be surrounded by blank lines [Context: "## header 2"]',
'incorrect.md: 1: MD041/first-line-h1 First line in file should be a top level header [Context: "## header 2"]',
'incorrect.md: 2: MD022/blanks-around-headers Headers should be surrounded by blank lines [Context: "# header"]',
'incorrect.md: 4: MD014/commands-show-output Dollar signs used before commands without showing output [Context: "$ code"]',
'incorrect.md: 10: MD014/commands-show-output Dollar signs used before commands without showing output [Context: "$ code"]',
'incorrect.md: 16: MD014/commands-show-output Dollar signs used before commands without showing output [Context: "$ code"]',
'incorrect.md: 23: MD014/commands-show-output Dollar signs used before commands without showing output [Context: "$ code"]',
''
].join('\n');
t.true(err.stdout === '');
t.true(err.stderr === expected);
}
});

0 comments on commit 6722a92

Please sign in to comment.