Hook up ESLint, fix warnings (including conversion to async I/O).

This commit is contained in:
David Anson 2015-02-24 18:40:37 -08:00
parent d16e1cafc1
commit 160146ac3a
5 changed files with 230 additions and 41 deletions

161
.eslintrc Normal file
View file

@ -0,0 +1,161 @@
{
"ecmaFeatures": {},
"parser": "espree",
"env": {
"browser": false,
"node": true,
"amd": false,
"mocha": false,
"jasmine": false
},
"rules": {
"no-alert": 2,
"no-array-constructor": 2,
"no-bitwise": 2,
"no-caller": 2,
"no-catch-shadow": 2,
"no-comma-dangle": 2,
"no-cond-assign": 2,
"no-console": 2,
"no-constant-condition": 2,
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-div-regex": 2,
"no-dupe-keys": 2,
"no-else-return": 2,
"no-empty": 2,
"no-empty-class": 2,
"no-empty-label": 2,
"no-eq-null": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": 0,
"no-extra-semi": 2,
"no-extra-strict": 2,
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-implied-eval": 2,
"no-inline-comments": 0,
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-lonely-if": 2,
"no-loop-func": 2,
"no-mixed-requires": [2, true],
"no-mixed-spaces-and-tabs": [2, false],
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [2, { "max": 2 }],
"no-native-reassign": 2,
"no-negated-in-lhs": 2,
"no-nested-ternary": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-path-concat": 2,
"no-plusplus": 0,
"no-process-env": 2,
"no-process-exit": 2,
"no-proto": 2,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-reserved-keys": 2,
"no-restricted-modules": 0,
"no-return-assign": 2,
"no-script-url": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow": 2,
"no-shadow-restricted-names": 2,
"no-space-before-semi": 2,
"no-spaced-func": 2,
"no-sparse-arrays": 2,
"no-sync": 2,
"no-ternary": 0,
"no-trailing-spaces": 2,
"no-throw-literal": 2,
"no-undef": 2,
"no-undef-init": 2,
"no-undefined": 2,
"no-underscore-dangle": 2,
"no-unreachable": 2,
"no-unused-expressions": 2,
"no-unused-vars": [2, { "vars": "all", "args": "after-used" }],
"no-use-before-define": 2,
"no-void": 2,
"no-var": 0,
"no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],
"no-with": 2,
"no-wrap-func": 2,
"block-scoped-var": 2,
"brace-style": [2, "1tbs"],
"camelcase": 2,
"comma-spacing": 2,
"comma-style": 2,
"complexity": [2, 11],
"consistent-return": 2,
"consistent-this": [2, "self"],
"curly": [2, "all"],
"default-case": 2,
"dot-notation": [2, { "allowKeywords": true }],
"eol-last": 2,
"eqeqeq": 2,
"func-names": 2,
"func-style": [2, "declaration"],
"generator-star": 2,
"global-strict": [2, "always"],
"guard-for-in": 2,
"handle-callback-err": 2,
"indent": [2, 2],
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
"max-depth": [2, 4],
"max-len": [2, 80, 2],
"max-nested-callbacks": [2, 2],
"max-params": [2, 3],
"max-statements": [0, 10],
"new-cap": 2,
"new-parens": 2,
"one-var": 0,
"operator-assignment": [2, "always"],
"padded-blocks": [2, "never"],
"quote-props": 2,
"quotes": [2, "double"],
"radix": 2,
"semi": 2,
"sort-vars": 0,
"space-after-function-name": [2, "never"],
"space-after-keywords": [2, "always"],
"space-before-blocks": [2, "always"],
"space-before-function-parentheses": [2, "never"],
"space-in-brackets": [2, "always", { "propertyName": false }],
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-return-throw-case": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"spaced-line-comment": [2, "always"],
"strict": 2,
"use-isnan": 2,
"valid-jsdoc": 2,
"valid-typeof": 2,
"vars-on-top": 0,
"wrap-iife": 2,
"wrap-regex": 0,
"yoda": [2, "never"]
}
}

View file

@ -3,25 +3,42 @@
var fs = require("fs");
var rules = require("./rules");
function lintFile(file, options) {
var results = {};
var contents = fs.readFileSync(file, { encoding: "utf8" });
var lines = contents.split(/\r\n|\n/g);
Object.keys(rules).forEach(function(name) {
var rule = rules[name];
var errors = rule(lines);
if (errors.length) {
results[name] = errors;
function lintFile(file, options, callback) {
fs.readFile(file, { "encoding": "utf8" }, function readFile(err, contents) {
if (err) {
callback(err);
} else {
var lines = contents.split(/\r\n|\n/g);
var result = {};
Object.keys(rules).forEach(function forRule(name) {
var rule = rules[name];
var errors = rule(lines);
if (errors.length) {
result[name] = errors;
}
});
callback(null, result);
}
});
return results;
}
module.exports = function(options) {
module.exports = function markdownlint(options, callback) {
var results = {};
var files = options.files || [];
files.forEach(function(file) {
results[file] = lintFile(file, options);
});
return results;
function lintFiles() {
var file = files.shift();
if (file) {
lintFile(file, options, function lintFileCallback(err, result) {
if (err) {
callback(err);
} else {
results[file] = result;
lintFiles();
}
});
} else {
callback(null, results);
}
}
lintFiles();
};

View file

@ -3,20 +3,20 @@
function padAndTrim(lines) {
return [].concat(
"",
lines.map(function(line) {
lines.map(function mapLine(line) {
return line.trim();
}),
"");
}
module.exports = {
MD031: function(lines) {
"MD031": function MD031(lines) {
// Some parsers have trouble detecting fenced code blocks without
// surrounding whitespace, so examine the lines directly.
lines = padAndTrim(lines);
var errors = [];
var inCode = false;
lines.forEach(function(line, lineNum) {
lines.forEach(function forLine(line, lineNum) {
if (line.match(/^(```|~~~)/)) {
inCode = !inCode;
if ((inCode && lines[lineNum - 1].length) ||

View file

@ -14,9 +14,11 @@
"url": "https://github.com/DavidAnson/markdownlint/issues"
},
"scripts": {
"test": "nodeunit"
"test": "nodeunit",
"lint": "eslint lib test"
},
"devDependencies": {
"eslint": "^0.15.0",
"nodeunit": "^0.9.0"
},
"keywords": [

View file

@ -5,31 +5,40 @@ var path = require("path");
var markdownlint = require("../lib/markdownlint");
function createTestForFile(file) {
return function(test) {
test.expect(1);
var contents = fs.readFileSync(file, { encoding: "utf8" });
var lines = contents.split(/\r\n|\n/g);
var results = {};
lines.forEach(function(line, lineNum) {
var match = line.match(/\{(MD\d+)(?::(\d+))?\}/);
if (match) {
var rule = match[1];
var lines = results[rule] || [];
lines.push(lineNum + 1);
results[rule] = lines;
}
});
var actual = markdownlint({
files: [ file ]
});
var expected = {};
expected[file] = results;
test.deepEqual(actual, expected, "Line numbers are not correct.");
test.done();
return function testForFile(test) {
test.expect(3);
fs.readFile(
file,
{ "encoding": "utf8" },
function readFileCallback(err, contents) {
test.ifError(err);
var lines = contents.split(/\r\n|\n/g);
var results = {};
lines.forEach(function forLine(line, lineNum) {
var match = line.match(/\{(MD\d+)(?::(\d+))?\}/);
if (match) {
var rule = match[1];
var errors = results[rule] || [];
errors.push(lineNum + 1);
results[rule] = errors;
}
});
markdownlint({
"files": [ file ]
}, function markdownlintCallback(errr, actual) {
test.ifError(errr);
var expected = {};
expected[file] = results;
test.deepEqual(actual, expected, "Line numbers are not correct.");
test.done();
});
});
};
}
fs.readdirSync(__dirname).forEach(function(file) {
/* eslint-disable no-sync, for synchronous test method creation */
fs.readdirSync(__dirname).forEach(function forFile(file) {
/* eslint-enable no-sync */
if (file.match(/\.md$/)) {
module.exports[file] = createTestForFile(path.join(__dirname, file));
}