Add MD034 with tests, improve validation of README and Rules.

This commit is contained in:
David Anson 2015-04-14 00:01:57 -07:00
parent 495fbac6fd
commit 0e24df7cf7
7 changed files with 104 additions and 34 deletions

View file

@ -64,6 +64,7 @@ cases come directly from that project.
* **MD031** - Fenced code blocks should be surrounded by blank lines
* **MD032** - Lists should be surrounded by blank lines
* **MD033** - Inline HTML
* **MD034** - Bare URL used
See [Rules.md](doc/Rules.md) for more details.
@ -78,12 +79,14 @@ See [Rules.md](doc/Rules.md) for more details.
* **hard_tab** - MD010
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
MD024, MD025, MD026
* **html** - MD033
* **indentation** - MD005, MD006, MD007, MD027
* **line_length** - MD013
* **links** - MD011
* **links** - MD011, MD034
* **ol** - MD029, MD030, MD032
* **spaces** - MD018, MD019, MD020, MD021, MD023
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
* **url** - MD034
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030
## API

View file

@ -698,3 +698,25 @@ To fix this, use 'pure' markdown instead of including raw HTML:
Rationale: Raw HTML is allowed in markdown, but this rule is included for
those who want their documents to only include "pure" markdown, or for those
who are rendering markdown documents in something other than HTML.
## MD034 - Bare URL used
Tags: links, url
This rule is triggered whenever a URL is given that isn't surrounded by angle
brackets:
For more information, see http://www.example.com/.
To fix this, add angle brackets around the URL:
For more information, see <http://www.example.com/>.
Rationale: Without angle brackets, the URL isn't converted into a link in many
markdown parsers.
Note: if you do want a bare URL without it being converted into a link,
enclose it in a code block, otherwise in some markdown parsers it _will_ be
converted:
`http://www.example.com`

View file

@ -619,5 +619,32 @@ module.exports = [
errors.push(token.lineNumber);
});
}
},
{
"name": "MD034",
"desc": "Bare URL used",
"tags": [ "links", "url" ],
"func": function MD034(params, errors) {
filterTokens(params.tokens, "inline")
.forEach(function forToken(token) {
var lineNumber = token.lineNumber;
var inLink = false;
token.children.forEach(function forChild(child) {
if (child.type === "link_open") {
inLink = true;
} else if (child.type === "link_close") {
inLink = false;
} else if ((child.type === "text") &&
!inLink &&
/https?:\/\//.test(child.content)) {
errors.push(lineNumber);
} else if ((child.type === "softbreak") ||
(child.type === "hardbreak")) {
lineNumber++;
}
});
});
}
}
];

View file

@ -6,5 +6,6 @@
"line_length": false,
"MD006": false,
"MD007": false,
"MD033": false
"MD033": false,
"MD034": false
}

9
test/links.md Normal file
View file

@ -0,0 +1,9 @@
# Link test
For more information, please see the
following page: http://www.example.com/ {MD034}
which will tell you all you want to know.
http://www.google.com/ {MD034}
This link should be fine: <http://www.google.com/>

View file

@ -498,7 +498,15 @@ module.exports.badFileSync = function badFileSync(test) {
};
module.exports.readme = function readme(test) {
test.expect(144);
test.expect(80);
var tagToRules = {};
rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) {
var tagRules = tagToRules[tag] || [];
tagRules.push(rule.name);
tagToRules[tag] = tagRules;
});
});
fs.readFile("README.md", shared.utf8Encoding,
function readFile(err, contents) {
test.ifError(err);
@ -507,8 +515,6 @@ module.exports.readme = function readme(test) {
var inRules = false;
var seenTags = false;
var inTags = false;
var docTags = [];
var usedTags = [];
md.parse(contents, {}).forEach(function forToken(token) {
if (token.type === "bullet_list_open") {
if (!seenRules) {
@ -524,38 +530,32 @@ module.exports.readme = function readme(test) {
} else if (token.type === "inline") {
if (inRules) {
var rule = rulesLeft.shift();
var expected = "**" + rule.name + "** - " + rule.desc;
test.equal(token.content, expected, "Rule mismatch.");
test.ok(rule,
"Missing rule implementation for " + token.content + ".");
if (rule) {
var expected = "**" + rule.name + "** - " + rule.desc;
test.equal(token.content, expected, "Rule mismatch.");
}
} else if (inTags) {
var parts = token.content.replace(/\*\*/g, "").split(/ - |, |,\n/);
var tag = parts.shift();
docTags.push(tag);
parts.forEach(function forPart(part) {
var found = rules.some(function forRule(r) {
if (r.name === part) {
test.ok(r.tags.indexOf(tag) !== -1, "Missing tag.");
r.tags.forEach(function forTag(t) {
if (usedTags.indexOf(t) === -1) {
usedTags.push(t);
}
});
return true;
}
return false;
});
test.ok(found, "Unknown rule." + part);
});
test.deepEqual(parts, tagToRules[tag] || [],
"Rule mismatch for tag " + tag + ".");
delete tagToRules[tag];
}
}
});
test.ok(!rulesLeft.length, "Missing rule.");
test.deepEqual(docTags, usedTags.sort(), "Tag mismatch.");
var ruleLeft = rulesLeft.shift();
test.ok(!ruleLeft,
"Missing rule documentation for " + (ruleLeft || {}).name + ".");
var tagLeft = Object.keys(tagToRules).shift();
test.ok(!tagLeft, "Undocumented tag " + tagLeft + ".");
test.done();
});
};
module.exports.doc = function doc(test) {
test.expect(90);
test.expect(123);
fs.readFile("doc/Rules.md", shared.utf8Encoding,
function readFile(err, contents) {
test.ifError(err);
@ -569,19 +569,27 @@ module.exports.doc = function doc(test) {
inHeading = false;
} else if (token.type === "inline") {
if (inHeading) {
test.ok(!rule, "Missing tags.");
test.ok(!rule,
"Missing tags for rule " + (rule || {}).name + ".");
rule = rulesLeft.shift();
var expected = rule.name + " - " + rule.desc;
test.equal(token.content, expected, "Rule mismatch.");
} else if (/^Tags: /.test(token.content)) {
test.ok(rule,
"Missing rule implementation for " + token.content + ".");
if (rule) {
var expected = rule.name + " - " + rule.desc;
test.equal(token.content, expected, "Rule mismatch.");
}
} else if (/^Tags: /.test(token.content) && rule) {
var tags = token.content.split(/, |: | /).slice(1);
test.deepEqual(tags, rule.tags, "Tag mismatch.");
test.deepEqual(tags, rule.tags,
"Tag mismatch for rule " + rule.name + ".");
rule = null;
}
}
});
test.ok(!rulesLeft.length, "Missing rule.");
test.ok(!rule, "Missing tags.");
var ruleLeft = rulesLeft.shift();
test.ok(!ruleLeft,
"Missing rule documentation for " + (ruleLeft || {}).name + ".");
test.ok(!rule, "Missing tags for rule " + (rule || {}).name + ".");
test.done();
});
};

View file

@ -1,4 +1,4 @@
Go to (this website)[http://www.example.com] {MD011}
Go to (this website)[http://www.example.com] {MD011} {MD034}
However, this shouldn't trigger inside code blocks: