Merge rule name/alias in rule definitions and results (for resultVersion 2).

This commit is contained in:
David Anson 2018-01-12 23:21:06 -08:00
parent b565c1ff32
commit 54c28f47c3
13 changed files with 322 additions and 291 deletions

View file

@ -351,7 +351,11 @@ each error is identified by rule name and line number. This is deprecated.
Passing a `resultVersion` of `1` corresponds to a detailed format where each error
includes information about the line number, rule name, alias, description, as well
as any additional detail or context that is available. This is the default.
as any additional detail or context that is available. This is deprecated.
Passing a `resultVersion` of `2` corresponds to a detailed format where each error
includes information about the line number, rule names, description, as well as any
additional detail or context that is available. This is the default.
#### callback
@ -481,29 +485,25 @@ Output:
"good.md": [],
"bad.md": [
{ "lineNumber": 3,
"ruleName": "MD010",
"ruleAlias": "no-hard-tabs",
"ruleNames": [ "MD010", "no-hard-tabs" ],
"ruleDescription": "Hard tabs",
"errorDetail": "Column: 17",
"errorContext": null,
"errorRange": [ 17, 1 ] },
{ "lineNumber": 1,
"ruleName": "MD018",
"ruleAlias": "no-missing-space-atx",
"ruleNames": [ "MD018", "no-missing-space-atx" ],
"ruleDescription": "No space after hash on atx style header",
"errorDetail": null,
"errorContext": "#bad.md",
"errorRange": [ 1, 2 ] },
{ "lineNumber": 3,
"ruleName": "MD018",
"ruleAlias": "no-missing-space-atx",
"ruleNames": [ "MD018", "no-missing-space-atx" ],
"ruleDescription": "No space after hash on atx style header",
"errorDetail": null,
"errorContext": "#This file fails\tsome rules.",
"errorRange": [ 1, 2 ] },
{ "lineNumber": 1,
"ruleName": "MD041",
"ruleAlias": "first-line-h1",
"ruleNames": [ "MD041", "first-line-h1" ],
"ruleDescription": "First line in file should be a top level header",
"errorDetail": null,
"errorContext": "#bad.md",

View file

@ -51,10 +51,11 @@
};
var results = window.markdownlint.sync(options);
violations.innerHTML = results.content.map(function mapResult(result) {
var ruleRef = rulesMd + "#" + result.ruleName.toLowerCase() + "---" +
var ruleName = result.ruleNames[0];
var ruleRef = rulesMd + "#" + ruleName.toLowerCase() + "---" +
result.ruleDescription.toLowerCase().replace(/ /g, "-");
return "<a href='#" + result.lineNumber + "'><em>" + result.lineNumber +
"</em></a> - <a href='" + ruleRef + "'>" + result.ruleName + "</a> " +
"</em></a> - <a href='" + ruleRef + "'>" + ruleName + "</a> " +
result.ruleDescription +
(result.errorDetail ?
" [<span class='detail'>" +

View file

@ -8,31 +8,36 @@ var md = require("markdown-it")({ "html": true });
var rules = require("./rules");
var shared = require("./shared");
// Mappings from rule to description and tag to rules
// Mappings from rule to description and name/tag to rules
var allRuleNames = [];
var ruleNameToRule = {};
var idUpperToRuleNames = {};
// var tagToRuleNames = {};
rules.forEach(function forRule(rule) {
allRuleNames.push(rule.name);
ruleNameToRule[rule.name] = rule;
var ruleName = rule.names[0];
var ruleAliases = rule.names.slice(1);
allRuleNames.push(ruleName);
ruleNameToRule[ruleName] = rule;
// The following is useful for updating README.md
// console.log(
// "* **[" + rule.name + "](doc/Rules.md#" + rule.name.toLowerCase() +
// ")** *" + rule.aliases.join(", ") + "* - " + rule.desc);
// "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
// ")** *" + ruleAliases.join(", ") + "* - " + rule.desc);
rule.tags.forEach(function forTag(tag) {
var tagUpper = tag.toUpperCase();
var ruleNames = idUpperToRuleNames[tagUpper] || [];
ruleNames.push(rule.name);
ruleNames.push(ruleName);
idUpperToRuleNames[tagUpper] = ruleNames;
// tagToRuleNames[tag] = ruleName;
});
rule.aliases.forEach(function forAlias(alias) {
ruleAliases.forEach(function forAlias(alias) {
var aliasUpper = alias.toUpperCase();
idUpperToRuleNames[aliasUpper] = [ rule.name ];
idUpperToRuleNames[aliasUpper] = [ ruleName ];
});
});
// The following is useful for updating README.md
// Object.keys(idUpperToRuleNames).sort().forEach(function forTag(tag) {
// console.log("* **" + tag + "** - " + idUpperToRuleNames[tag].join(", "));
// Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {
// console.log("* **" + tag + "** - " +
// idUpperToRuleNames[tag.toUpperCase()].join(", "));
// });
// Class for results with toString for pretty display
@ -44,11 +49,13 @@ Results.prototype.toString = function resultsToString(useAlias) {
var fileResults = that[file];
if (Array.isArray(fileResults)) {
fileResults.forEach(function forResult(result) {
var ruleMoniker = result.ruleNames ?
result.ruleNames.join("/") :
(result.ruleName + "/" + result.ruleAlias);
results.push(
file + ": " +
result.lineNumber + ": " +
result.ruleName + "/" +
result.ruleAlias + " " +
ruleMoniker + " " +
result.ruleDescription +
(result.errorDetail ?
" [" + result.errorDetail + "]" :
@ -65,7 +72,7 @@ Results.prototype.toString = function resultsToString(useAlias) {
var result =
file + ": " +
lineNumber + ": " +
(useAlias ? rule.aliases[0] : rule.name) + " " +
rule.names[useAlias ? 1 : 0] + " " +
rule.desc;
results.push(result);
});
@ -155,7 +162,8 @@ function lintContent(
var ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]];
var mergedRules = {};
rules.forEach(function forRule(rule) {
mergedRules[rule.name] = ruleDefault;
var ruleName = rule.names[0];
mergedRules[ruleName] = ruleDefault;
});
Object.keys(config).forEach(function forKey(key) {
var value = config[key];
@ -178,7 +186,8 @@ function lintContent(
// Create mapping of enabled rules per line
var enabledRules = {};
rules.forEach(function forRule(rule) {
enabledRules[rule.name] = !!mergedRules[rule.name];
var ruleName = rule.names[0];
enabledRules[ruleName] = !!mergedRules[ruleName];
});
function forMatch(match) {
var enabled = match[1].toUpperCase() === "EN";
@ -220,7 +229,8 @@ function lintContent(
var result = (resultVersion === 0) ? {} : [];
rules.forEach(function forRule(rule) {
// Configure rule
params.options = mergedRules[rule.name];
var ruleName = rule.names[0];
params.options = mergedRules[ruleName];
var errors = [];
function addError(lineNumber, detail, context, range) {
errors.push({
@ -272,7 +282,7 @@ function lintContent(
var filteredErrors = errors
.filter(uniqueFilterForSortedErrors)
.filter(function removeDisabledRules(error) {
return enabledRulesPerLineNumber[error.lineNumber][rule.name];
return enabledRulesPerLineNumber[error.lineNumber][ruleName];
})
.map(function formatResults(error) {
if (resultVersion === 0) {
@ -296,19 +306,23 @@ function lintContent(
range = [ column, length ];
}
}
return {
"lineNumber": error.lineNumber,
"ruleName": rule.name,
"ruleAlias": rule.aliases[0],
"ruleDescription": rule.desc,
"errorDetail": error.detail,
"errorContext": error.context,
"errorRange": range
};
var errorObject = {};
errorObject.lineNumber = error.lineNumber;
if (resultVersion === 1) {
errorObject.ruleName = rule.names[0];
errorObject.ruleAlias = rule.names[1];
} else {
errorObject.ruleNames = rule.names;
}
errorObject.ruleDescription = rule.desc;
errorObject.errorDetail = error.detail;
errorObject.errorContext = error.context;
errorObject.errorRange = range;
return errorObject;
});
if (filteredErrors.length) {
if (resultVersion === 0) {
result[rule.name] = filteredErrors;
result[ruleName] = filteredErrors;
} else {
result.push.apply(result, filteredErrors);
}
@ -359,7 +373,7 @@ function lintInput(options, synchronous, callback) {
shared.frontMatterRe : options.frontMatter;
var noInlineConfig = !!options.noInlineConfig;
var resultVersion = (options.resultVersion === undefined) ?
1 : options.resultVersion;
2 : options.resultVersion;
var results = new Results();
// Helper to lint the next file in the array
function lintFilesArray() {

View file

@ -183,10 +183,9 @@ function flattenLists(params) {
module.exports = [
{
"name": "MD001",
"names": [ "MD001", "header-increment" ],
"desc": "Header levels should only increment by one level at a time",
"tags": [ "headers" ],
"aliases": [ "header-increment" ],
"regexp": null,
"func": function MD001(params, errors) {
var prevLevel = 0;
@ -202,10 +201,9 @@ module.exports = [
},
{
"name": "MD002",
"names": [ "MD002", "first-header-h1" ],
"desc": "First header should be a top level header",
"tags": [ "headers" ],
"aliases": [ "first-header-h1" ],
"regexp": null,
"func": function MD002(params, errors) {
var level = params.options.level || 1;
@ -221,10 +219,9 @@ module.exports = [
},
{
"name": "MD003",
"names": [ "MD003", "header-style" ],
"desc": "Header style",
"tags": [ "headers" ],
"aliases": [ "header-style" ],
"regexp": null,
"func": function MD003(params, errors) {
var style = params.options.style || "consistent";
@ -258,10 +255,9 @@ module.exports = [
},
{
"name": "MD004",
"names": [ "MD004", "ul-style" ],
"desc": "Unordered list style",
"tags": [ "bullet", "ul" ],
"aliases": [ "ul-style" ],
"regexp": listItemMarkerRe,
"func": function MD004(params, errors) {
var style = params.options.style || "consistent";
@ -293,10 +289,9 @@ module.exports = [
},
{
"name": "MD005",
"names": [ "MD005", "list-indent" ],
"desc": "Inconsistent indentation for list items at the same level",
"tags": [ "bullet", "ul", "indentation" ],
"aliases": [ "list-indent" ],
"regexp": listItemMarkerRe,
"func": function MD005(params, errors) {
flattenLists(params).forEach(function forList(list) {
@ -309,10 +304,9 @@ module.exports = [
},
{
"name": "MD006",
"names": [ "MD006", "ul-start-left" ],
"desc": "Consider starting bulleted lists at the beginning of the line",
"tags": [ "bullet", "ul", "indentation" ],
"aliases": [ "ul-start-left" ],
"regexp": listItemMarkerRe,
"func": function MD006(params, errors) {
flattenLists(params).forEach(function forList(list) {
@ -324,10 +318,9 @@ module.exports = [
},
{
"name": "MD007",
"names": [ "MD007", "ul-indent" ],
"desc": "Unordered list indentation",
"tags": [ "bullet", "ul", "indentation" ],
"aliases": [ "ul-indent" ],
"regexp": listItemMarkerRe,
"func": function MD007(params, errors) {
var optionsIndent = params.options.indent || 2;
@ -346,10 +339,9 @@ module.exports = [
},
{
"name": "MD009",
"names": [ "MD009", "no-trailing-spaces" ],
"desc": "Trailing spaces",
"tags": [ "whitespace" ],
"aliases": [ "no-trailing-spaces" ],
"regexp": trailingSpaceRe,
"func": function MD009(params, errors) {
var brSpaces = params.options.br_spaces || 0;
@ -377,10 +369,9 @@ module.exports = [
},
{
"name": "MD010",
"names": [ "MD010", "no-hard-tabs" ],
"desc": "Hard tabs",
"tags": [ "whitespace", "hard_tab" ],
"aliases": [ "no-hard-tabs" ],
"regexp": tabRe,
"func": function MD010(params, errors) {
var codeBlocks = params.options.code_blocks;
@ -395,10 +386,9 @@ module.exports = [
},
{
"name": "MD011",
"names": [ "MD011", "no-reversed-links" ],
"desc": "Reversed link syntax",
"tags": [ "links" ],
"aliases": [ "no-reversed-links" ],
"regexp": reversedLinkRe,
"func": function MD011(params, errors) {
forEachInlineChild(params, "text", function forToken(token) {
@ -411,10 +401,9 @@ module.exports = [
},
{
"name": "MD012",
"names": [ "MD012", "no-multiple-blanks" ],
"desc": "Multiple consecutive blank lines",
"tags": [ "whitespace", "blank_lines" ],
"aliases": [ "no-multiple-blanks" ],
"regexp": null,
"func": function MD012(params, errors) {
var maximum = params.options.maximum || 1;
@ -429,10 +418,9 @@ module.exports = [
},
{
"name": "MD013",
"names": [ "MD013", "line-length" ],
"desc": "Line length",
"tags": [ "line_length" ],
"aliases": [ "line-length" ],
"regexp": longLineReFunc,
"func": function MD013(params, errors) {
var lineLength = params.options.line_length || defaultLineLength;
@ -487,10 +475,9 @@ module.exports = [
},
{
"name": "MD014",
"names": [ "MD014", "commands-show-output" ],
"desc": "Dollar signs used before commands without showing output",
"tags": [ "code" ],
"aliases": [ "commands-show-output" ],
"regexp": dollarCommandRe,
"func": function MD014(params, errors) {
[ "code_block", "fence" ].forEach(function forType(type) {
@ -509,10 +496,9 @@ module.exports = [
},
{
"name": "MD018",
"names": [ "MD018", "no-missing-space-atx" ],
"desc": "No space after hash on atx style header",
"tags": [ "headers", "atx", "spaces" ],
"aliases": [ "no-missing-space-atx" ],
"regexp": atxHeaderSpaceRe,
"func": function MD018(params, errors) {
forEachLine(params, function forLine(line, lineIndex, inCode) {
@ -524,10 +510,9 @@ module.exports = [
},
{
"name": "MD019",
"names": [ "MD019", "no-multiple-space-atx" ],
"desc": "Multiple spaces after hash on atx style header",
"tags": [ "headers", "atx", "spaces" ],
"aliases": [ "no-multiple-space-atx" ],
"regexp": atxHeaderSpaceRe,
"func": function MD019(params, errors) {
filterTokens(params, "heading_open", function forToken(token) {
@ -540,10 +525,9 @@ module.exports = [
},
{
"name": "MD020",
"names": [ "MD020", "no-missing-space-closed-atx" ],
"desc": "No space inside hashes on closed atx style header",
"tags": [ "headers", "atx_closed", "spaces" ],
"aliases": [ "no-missing-space-closed-atx" ],
"regexp": atxClosedHeaderNoSpaceRe,
"func": function MD020(params, errors) {
forEachLine(params, function forLine(line, lineIndex, inCode) {
@ -559,10 +543,9 @@ module.exports = [
},
{
"name": "MD021",
"names": [ "MD021", "no-multiple-space-closed-atx" ],
"desc": "Multiple spaces inside hashes on closed atx style header",
"tags": [ "headers", "atx_closed", "spaces" ],
"aliases": [ "no-multiple-space-closed-atx" ],
"regexp": atxClosedHeaderSpaceRe,
"func": function MD021(params, errors) {
filterTokens(params, "heading_open", function forToken(token) {
@ -578,10 +561,9 @@ module.exports = [
},
{
"name": "MD022",
"names": [ "MD022", "blanks-around-headers" ],
"desc": "Headers should be surrounded by blank lines",
"tags": [ "headers", "blank_lines" ],
"aliases": [ "blanks-around-headers" ],
"regexp": null,
"func": function MD022(params, errors) {
var prevHeadingLineNumber = 0;
@ -613,10 +595,9 @@ module.exports = [
},
{
"name": "MD023",
"names": [ "MD023", "header-start-left" ],
"desc": "Headers must start at the beginning of the line",
"tags": [ "headers", "spaces" ],
"aliases": [ "header-start-left" ],
"regexp": spaceBeforeHeaderRe,
"func": function MD023(params, errors) {
filterTokens(params, "heading_open", function forToken(token) {
@ -628,10 +609,9 @@ module.exports = [
},
{
"name": "MD024",
"names": [ "MD024", "no-duplicate-header" ],
"desc": "Multiple headers with the same content",
"tags": [ "headers" ],
"aliases": [ "no-duplicate-header" ],
"regexp": null,
"func": function MD024(params, errors) {
var knownContent = [];
@ -646,10 +626,9 @@ module.exports = [
},
{
"name": "MD025",
"names": [ "MD025", "single-h1" ],
"desc": "Multiple top level headers in the same document",
"tags": [ "headers" ],
"aliases": [ "single-h1" ],
"regexp": null,
"func": function MD025(params, errors) {
var level = params.options.level || 1;
@ -668,10 +647,9 @@ module.exports = [
},
{
"name": "MD026",
"names": [ "MD026", "no-trailing-punctuation" ],
"desc": "Trailing punctuation in header",
"tags": [ "headers" ],
"aliases": [ "no-trailing-punctuation" ],
"regexp": trailingPunctuationRe,
"func": function MD026(params, errors) {
var punctuation = params.options.punctuation || ".,;:!?";
@ -687,10 +665,9 @@ module.exports = [
},
{
"name": "MD027",
"names": [ "MD027", "no-multiple-space-blockquote" ],
"desc": "Multiple spaces after blockquote symbol",
"tags": [ "blockquote", "whitespace", "indentation" ],
"aliases": [ "no-multiple-space-blockquote" ],
"regexp": spaceAfterBlockQuote,
"func": function MD027(params, errors) {
var blockquoteNesting = 0;
@ -723,10 +700,9 @@ module.exports = [
},
{
"name": "MD028",
"names": [ "MD028", "no-blanks-blockquote" ],
"desc": "Blank line inside blockquote",
"tags": [ "blockquote", "whitespace" ],
"aliases": [ "no-blanks-blockquote" ],
"regexp": null,
"func": function MD028(params, errors) {
var prevToken = {};
@ -741,10 +717,9 @@ module.exports = [
},
{
"name": "MD029",
"names": [ "MD029", "ol-prefix" ],
"desc": "Ordered list item prefix",
"tags": [ "ol" ],
"aliases": [ "ol-prefix" ],
"regexp": listItemMarkerRe,
"func": function MD029(params, errors) {
var style = params.options.style || "one_or_ordered";
@ -773,10 +748,9 @@ module.exports = [
},
{
"name": "MD030",
"names": [ "MD030", "list-marker-space" ],
"desc": "Spaces after list markers",
"tags": [ "ol", "ul", "whitespace" ],
"aliases": [ "list-marker-space" ],
"regexp": listItemMarkerRe,
"func": function MD030(params, errors) {
var ulSingle = params.options.ul_single || 1;
@ -799,10 +773,9 @@ module.exports = [
},
{
"name": "MD031",
"names": [ "MD031", "blanks-around-fences" ],
"desc": "Fenced code blocks should be surrounded by blank lines",
"tags": [ "code", "blank_lines" ],
"aliases": [ "blanks-around-fences" ],
"regexp": null,
"func": function MD031(params, errors) {
var lines = params.lines;
@ -816,10 +789,9 @@ module.exports = [
},
{
"name": "MD032",
"names": [ "MD032", "blanks-around-lists" ],
"desc": "Lists should be surrounded by blank lines",
"tags": [ "bullet", "ul", "ol", "blank_lines" ],
"aliases": [ "blanks-around-lists" ],
"regexp": null,
"func": function MD032(params, errors) {
var blankOrListRe = /^[\s>]*($|\s)/;
@ -847,10 +819,9 @@ module.exports = [
},
{
"name": "MD033",
"names": [ "MD033", "no-inline-html" ],
"desc": "Inline HTML",
"tags": [ "html" ],
"aliases": [ "no-inline-html" ],
"regexp": htmlRe,
"func": function MD033(params, errors) {
var allowedElements = (params.options.allowed_elements || [])
@ -882,10 +853,9 @@ module.exports = [
},
{
"name": "MD034",
"names": [ "MD034", "no-bare-urls" ],
"desc": "Bare URL used",
"tags": [ "links", "url" ],
"aliases": [ "no-bare-urls" ],
"regexp": bareUrlRe,
"func": function MD034(params, errors) {
filterTokens(params, "inline", function forToken(token) {
@ -907,10 +877,9 @@ module.exports = [
},
{
"name": "MD035",
"names": [ "MD035", "hr-style" ],
"desc": "Horizontal rule style",
"tags": [ "hr" ],
"aliases": [ "hr-style" ],
"regexp": null,
"func": function MD035(params, errors) {
var style = params.options.style || "consistent";
@ -925,10 +894,9 @@ module.exports = [
},
{
"name": "MD036",
"names": [ "MD036", "no-emphasis-as-header" ],
"desc": "Emphasis used instead of a header",
"tags": [ "headers", "emphasis" ],
"aliases": [ "no-emphasis-as-header" ],
"regexp": null,
"func": function MD036(params, errors) {
var punctuation = params.options.punctuation || ".,;:!?";
@ -975,10 +943,9 @@ module.exports = [
},
{
"name": "MD037",
"names": [ "MD037", "no-space-in-emphasis" ],
"desc": "Spaces inside emphasis markers",
"tags": [ "whitespace", "emphasis" ],
"aliases": [ "no-space-in-emphasis" ],
"regexp": null,
"func": function MD037(params, errors) {
forEachInlineChild(params, "text", function forToken(token) {
@ -1001,10 +968,9 @@ module.exports = [
},
{
"name": "MD038",
"names": [ "MD038", "no-space-in-code" ],
"desc": "Spaces inside code span elements",
"tags": [ "whitespace", "code" ],
"aliases": [ "no-space-in-code" ],
"regexp": null,
"func": function MD038(params, errors) {
var inlineCodeSpansRe = /(?:^|[^\\])((`+)((?:.*?[^`])|)\2(?!`))/g;
@ -1031,10 +997,9 @@ module.exports = [
},
{
"name": "MD039",
"names": [ "MD039", "no-space-in-links" ],
"desc": "Spaces inside link text",
"tags": [ "whitespace", "links" ],
"aliases": [ "no-space-in-links" ],
"regexp": spaceInsideLinkRe,
"func": function MD039(params, errors) {
filterTokens(params, "inline", function forToken(token) {
@ -1061,10 +1026,9 @@ module.exports = [
},
{
"name": "MD040",
"names": [ "MD040", "fenced-code-language" ],
"desc": "Fenced code blocks should have a language specified",
"tags": [ "code", "language" ],
"aliases": [ "fenced-code-language" ],
"regexp": null,
"func": function MD040(params, errors) {
filterTokens(params, "fence", function forToken(token) {
@ -1076,10 +1040,9 @@ module.exports = [
},
{
"name": "MD041",
"names": [ "MD041", "first-line-h1" ],
"desc": "First line in file should be a top level header",
"tags": [ "headers" ],
"aliases": [ "first-line-h1" ],
"regexp": null,
"func": function MD041(params, errors) {
var level = params.options.level || 1;
@ -1109,10 +1072,9 @@ module.exports = [
},
{
"name": "MD042",
"names": [ "MD042", "no-empty-links" ],
"desc": "No empty links",
"tags": [ "links" ],
"aliases": [ "no-empty-links" ],
"regexp": emptyLinkRe,
"func": function MD042(params, errors) {
filterTokens(params, "inline", function forToken(token) {
@ -1142,10 +1104,9 @@ module.exports = [
},
{
"name": "MD043",
"names": [ "MD043", "required-headers" ],
"desc": "Required header structure",
"tags": [ "headers" ],
"aliases": [ "required-headers" ],
"regexp": null,
"func": function MD043(params, errors) {
var requiredHeaders = params.options.headers;
@ -1179,10 +1140,9 @@ module.exports = [
},
{
"name": "MD044",
"names": [ "MD044", "proper-names" ],
"desc": "Proper names should have the correct capitalization",
"tags": [ "spelling" ],
"aliases": [ "proper-names" ],
"regexp": null,
"func": function MD044(params, errors) {
var names = params.options.names || [];
@ -1221,10 +1181,9 @@ module.exports = [
}
},
{
"name": "MD045",
"names": [ "MD045", "no-alt-text" ],
"desc": "Images should have alternate text (alt text)",
"tags": [ "accessibility", "images" ],
"aliases": [ "no-alt-text" ],
"regexp": null,
"func": function MD045(params, errors) {
forEachInlineChild(params, "image", function forToken(token) {

View file

@ -28,16 +28,16 @@ var tags = {};
rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) {
var tagRules = tags[tag] || [];
tagRules.push(rule.name);
tagRules.push(rule.names[0]);
tags[tag] = tagRules;
});
var scheme = {
"description": rule.name + "/" + rule.aliases.join("/") + " - " + rule.desc,
"description": rule.names.join("/") + " - " + rule.desc,
"type": "boolean",
"default": true
};
var custom = true;
switch (rule.name) {
switch (rule.names[0]) {
case "MD002":
case "MD025":
scheme.properties = {
@ -266,9 +266,8 @@ rules.forEach(function forRule(rule) {
scheme.type = [ "boolean", "object" ];
scheme.additionalProperties = false;
}
schema.properties[rule.name] = scheme;
rule.aliases.forEach(function forAlias(alias) {
schema.properties[alias] = scheme;
rule.names.forEach(function forName(name) {
schema.properties[name] = scheme;
});
});

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 3,
"ruleName": "MD001",
"ruleAlias": "header-increment",
"ruleNames": [ "MD001", "header-increment" ],
"ruleDescription": "Header levels should only increment by one level at a time",
"errorDetail": "Expected: h3; Actual: h4",
"errorContext": null,
@ -10,8 +9,7 @@
},
{
"lineNumber": 1,
"ruleName": "MD002",
"ruleAlias": "first-header-h1",
"ruleNames": [ "MD002", "first-header-h1" ],
"ruleDescription": "First header should be a top level header",
"errorDetail": "Expected: h1; Actual: h2",
"errorContext": null,
@ -19,8 +17,7 @@
},
{
"lineNumber": 5,
"ruleName": "MD003",
"ruleAlias": "header-style",
"ruleNames": [ "MD003", "header-style" ],
"ruleDescription": "Header style",
"errorDetail": "Expected: atx; Actual: atx_closed",
"errorContext": null,
@ -28,8 +25,7 @@
},
{
"lineNumber": 10,
"ruleName": "MD004",
"ruleAlias": "ul-style",
"ruleNames": [ "MD004", "ul-style" ],
"ruleDescription": "Unordered list style",
"errorDetail": "Expected: asterisk; Actual: dash",
"errorContext": null,
@ -37,8 +33,7 @@
},
{
"lineNumber": 8,
"ruleName": "MD005",
"ruleAlias": "list-indent",
"ruleNames": [ "MD005", "list-indent" ],
"ruleDescription": "Inconsistent indentation for list items at the same level",
"errorDetail": "Expected: 0; Actual: 1",
"errorContext": null,
@ -46,8 +41,7 @@
},
{
"lineNumber": 12,
"ruleName": "MD006",
"ruleAlias": "ul-start-left",
"ruleNames": [ "MD006", "ul-start-left" ],
"ruleDescription": "Consider starting bulleted lists at the beginning of the line",
"errorDetail": "Expected: 0; Actual: 1",
"errorContext": null,
@ -55,8 +49,7 @@
},
{
"lineNumber": 12,
"ruleName": "MD007",
"ruleAlias": "ul-indent",
"ruleNames": [ "MD007", "ul-indent" ],
"ruleDescription": "Unordered list indentation",
"errorDetail": "Expected: 2; Actual: 1",
"errorContext": null,
@ -64,8 +57,7 @@
},
{
"lineNumber": 15,
"ruleName": "MD009",
"ruleAlias": "no-trailing-spaces",
"ruleNames": [ "MD009", "no-trailing-spaces" ],
"ruleDescription": "Trailing spaces",
"errorDetail": "Expected: 0; Actual: 1",
"errorContext": null,
@ -73,8 +65,7 @@
},
{
"lineNumber": 17,
"ruleName": "MD010",
"ruleAlias": "no-hard-tabs",
"ruleNames": [ "MD010", "no-hard-tabs" ],
"ruleDescription": "Hard tabs",
"errorDetail": "Column: 5",
"errorContext": null,

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 5,
"ruleName": "MD011",
"ruleAlias": "no-reversed-links",
"ruleNames": [ "MD011", "no-reversed-links" ],
"ruleDescription": "Reversed link syntax",
"errorDetail": "(reversed)[link]",
"errorContext": null,
@ -10,8 +9,7 @@
},
{
"lineNumber": 7,
"ruleName": "MD012",
"ruleAlias": "no-multiple-blanks",
"ruleNames": [ "MD012", "no-multiple-blanks" ],
"ruleDescription": "Multiple consecutive blank lines",
"errorDetail": "Expected: 1; Actual: 2",
"errorContext": null,
@ -19,8 +17,7 @@
},
{
"lineNumber": 8,
"ruleName": "MD013",
"ruleAlias": "line-length",
"ruleNames": [ "MD013", "line-length" ],
"ruleDescription": "Line length",
"errorDetail": "Expected: 80; Actual: 99",
"errorContext": null,
@ -28,8 +25,7 @@
},
{
"lineNumber": 10,
"ruleName": "MD014",
"ruleAlias": "commands-show-output",
"ruleNames": [ "MD014", "commands-show-output" ],
"ruleDescription": "Dollar signs used before commands without showing output",
"errorDetail": null,
"errorContext": "$ command with no output",
@ -37,8 +33,7 @@
},
{
"lineNumber": 12,
"ruleName": "MD018",
"ruleAlias": "no-missing-space-atx",
"ruleNames": [ "MD018", "no-missing-space-atx" ],
"ruleDescription": "No space after hash on atx style header",
"errorDetail": null,
"errorContext": "##No space A",
@ -46,8 +41,7 @@
},
{
"lineNumber": 14,
"ruleName": "MD019",
"ruleAlias": "no-multiple-space-atx",
"ruleNames": [ "MD019", "no-multiple-space-atx" ],
"ruleDescription": "Multiple spaces after hash on atx style header",
"errorDetail": null,
"errorContext": "## Multiple spaces B",
@ -55,8 +49,7 @@
},
{
"lineNumber": 16,
"ruleName": "MD020",
"ruleAlias": "no-missing-space-closed-atx",
"ruleNames": [ "MD020", "no-missing-space-closed-atx" ],
"ruleDescription": "No space inside hashes on closed atx style header",
"errorDetail": null,
"errorContext": "##No space C ##",
@ -64,8 +57,7 @@
},
{
"lineNumber": 18,
"ruleName": "MD020",
"ruleAlias": "no-missing-space-closed-atx",
"ruleNames": [ "MD020", "no-missing-space-closed-atx" ],
"ruleDescription": "No space inside hashes on closed atx style header",
"errorDetail": null,
"errorContext": "## No space D##",
@ -73,8 +65,7 @@
},
{
"lineNumber": 20,
"ruleName": "MD021",
"ruleAlias": "no-multiple-space-closed-atx",
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
"ruleDescription": "Multiple spaces inside hashes on closed atx style header",
"errorDetail": null,
"errorContext": "## Multiple spaces E ##",
@ -82,8 +73,7 @@
},
{
"lineNumber": 22,
"ruleName": "MD021",
"ruleAlias": "no-multiple-space-closed-atx",
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
"ruleDescription": "Multiple spaces inside hashes on closed atx style header",
"errorDetail": null,
"errorContext": "## Multiple spaces F ##",

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 1,
"ruleName": "MD022",
"ruleAlias": "blanks-around-headers",
"ruleNames": [ "MD022", "blanks-around-headers" ],
"ruleDescription": "Headers should be surrounded by blank lines",
"errorDetail": null,
"errorContext": "# Heading",
@ -10,8 +9,7 @@
},
{
"lineNumber": 1,
"ruleName": "MD023",
"ruleAlias": "header-start-left",
"ruleNames": [ "MD023", "header-start-left" ],
"ruleDescription": "Headers must start at the beginning of the line",
"errorDetail": null,
"errorContext": " # Heading",
@ -19,8 +17,7 @@
},
{
"lineNumber": 4,
"ruleName": "MD024",
"ruleAlias": "no-duplicate-header",
"ruleNames": [ "MD024", "no-duplicate-header" ],
"ruleDescription": "Multiple headers with the same content",
"errorDetail": null,
"errorContext": "# Heading",
@ -28,8 +25,7 @@
},
{
"lineNumber": 4,
"ruleName": "MD025",
"ruleAlias": "single-h1",
"ruleNames": [ "MD025", "single-h1" ],
"ruleDescription": "Multiple top level headers in the same document",
"errorDetail": null,
"errorContext": "# Heading",
@ -37,8 +33,7 @@
},
{
"lineNumber": 6,
"ruleName": "MD026",
"ruleAlias": "no-trailing-punctuation",
"ruleNames": [ "MD026", "no-trailing-punctuation" ],
"ruleDescription": "Trailing punctuation in header",
"errorDetail": "Punctuation: '.'",
"errorContext": null,
@ -46,8 +41,7 @@
},
{
"lineNumber": 8,
"ruleName": "MD027",
"ruleAlias": "no-multiple-space-blockquote",
"ruleNames": [ "MD027", "no-multiple-space-blockquote" ],
"ruleDescription": "Multiple spaces after blockquote symbol",
"errorDetail": null,
"errorContext": "> Multiple spaces",
@ -55,8 +49,7 @@
},
{
"lineNumber": 15,
"ruleName": "MD027",
"ruleAlias": "no-multiple-space-blockquote",
"ruleNames": [ "MD027", "no-multiple-space-blockquote" ],
"ruleDescription": "Multiple spaces after blockquote symbol",
"errorDetail": null,
"errorContext": "> > Multiple spaces, multiple...",
@ -64,8 +57,7 @@
},
{
"lineNumber": 17,
"ruleName": "MD027",
"ruleAlias": "no-multiple-space-blockquote",
"ruleNames": [ "MD027", "no-multiple-space-blockquote" ],
"ruleDescription": "Multiple spaces after blockquote symbol",
"errorDetail": null,
"errorContext": "> > > Multiple spaces, multip...",
@ -73,8 +65,7 @@
},
{
"lineNumber": 19,
"ruleName": "MD027",
"ruleAlias": "no-multiple-space-blockquote",
"ruleNames": [ "MD027", "no-multiple-space-blockquote" ],
"ruleDescription": "Multiple spaces after blockquote symbol",
"errorDetail": null,
"errorContext": "> > > Multiple spaces, multip...",
@ -82,8 +73,7 @@
},
{
"lineNumber": 9,
"ruleName": "MD028",
"ruleAlias": "no-blanks-blockquote",
"ruleNames": [ "MD028", "no-blanks-blockquote" ],
"ruleDescription": "Blank line inside blockquote",
"errorDetail": null,
"errorContext": null,
@ -91,8 +81,7 @@
},
{
"lineNumber": 13,
"ruleName": "MD029",
"ruleAlias": "ol-prefix",
"ruleNames": [ "MD029", "ol-prefix" ],
"ruleDescription": "Ordered list item prefix",
"errorDetail": "Expected: 2; Actual: 3; Style: 1/2/3",
"errorContext": null,
@ -100,8 +89,7 @@
},
{
"lineNumber": 13,
"ruleName": "MD030",
"ruleAlias": "list-marker-space",
"ruleNames": [ "MD030", "list-marker-space" ],
"ruleDescription": "Spaces after list markers",
"errorDetail": "Expected: 1; Actual: 2",
"errorContext": null,

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 3,
"ruleName": "MD030",
"ruleAlias": "list-marker-space",
"ruleNames": [ "MD030", "list-marker-space" ],
"ruleDescription": "Spaces after list markers",
"errorDetail": "Expected: 1; Actual: 0",
"errorContext": null,
@ -10,8 +9,7 @@
},
{
"lineNumber": 5,
"ruleName": "MD030",
"ruleAlias": "list-marker-space",
"ruleNames": [ "MD030", "list-marker-space" ],
"ruleDescription": "Spaces after list markers",
"errorDetail": "Expected: 1; Actual: 0",
"errorContext": null,
@ -19,8 +17,7 @@
},
{
"lineNumber": 11,
"ruleName": "MD030",
"ruleAlias": "list-marker-space",
"ruleNames": [ "MD030", "list-marker-space" ],
"ruleDescription": "Spaces after list markers",
"errorDetail": "Expected: 1; Actual: 2",
"errorContext": null,
@ -28,8 +25,7 @@
},
{
"lineNumber": 13,
"ruleName": "MD030",
"ruleAlias": "list-marker-space",
"ruleNames": [ "MD030", "list-marker-space" ],
"ruleDescription": "Spaces after list markers",
"errorDetail": "Expected: 1; Actual: 2",
"errorContext": null,

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 3,
"ruleName": "MD031",
"ruleAlias": "blanks-around-fences",
"ruleNames": [ "MD031", "blanks-around-fences" ],
"ruleDescription": "Fenced code blocks should be surrounded by blank lines",
"errorDetail": null,
"errorContext": "```",
@ -10,8 +9,7 @@
},
{
"lineNumber": 4,
"ruleName": "MD032",
"ruleAlias": "blanks-around-lists",
"ruleNames": [ "MD032", "blanks-around-lists" ],
"ruleDescription": "Lists should be surrounded by blank lines",
"errorDetail": null,
"errorContext": "* List",
@ -19,8 +17,7 @@
},
{
"lineNumber": 6,
"ruleName": "MD033",
"ruleAlias": "no-inline-html",
"ruleNames": [ "MD033", "no-inline-html" ],
"ruleDescription": "Inline HTML",
"errorDetail": "Element: hr",
"errorContext": null,
@ -28,8 +25,7 @@
},
{
"lineNumber": 8,
"ruleName": "MD034",
"ruleAlias": "no-bare-urls",
"ruleNames": [ "MD034", "no-bare-urls" ],
"ruleDescription": "Bare URL used",
"errorDetail": null,
"errorContext": "http://example.com",
@ -37,8 +33,7 @@
},
{
"lineNumber": 11,
"ruleName": "MD035",
"ruleAlias": "hr-style",
"ruleNames": [ "MD035", "hr-style" ],
"ruleDescription": "Horizontal rule style",
"errorDetail": "Expected: ---; Actual: ***",
"errorContext": null,
@ -46,8 +41,7 @@
},
{
"lineNumber": 13,
"ruleName": "MD036",
"ruleAlias": "no-emphasis-as-header",
"ruleNames": [ "MD036", "no-emphasis-as-header" ],
"ruleDescription": "Emphasis used instead of a header",
"errorDetail": null,
"errorContext": "Emphasis",
@ -55,8 +49,7 @@
},
{
"lineNumber": 15,
"ruleName": "MD037",
"ruleAlias": "no-space-in-emphasis",
"ruleNames": [ "MD037", "no-space-in-emphasis" ],
"ruleDescription": "Spaces inside emphasis markers",
"errorDetail": null,
"errorContext": "* inside *",
@ -64,8 +57,7 @@
},
{
"lineNumber": 31,
"ruleName": "MD037",
"ruleAlias": "no-space-in-emphasis",
"ruleNames": [ "MD037", "no-space-in-emphasis" ],
"ruleDescription": "Spaces inside emphasis markers",
"errorDetail": null,
"errorContext": "* some*",
@ -73,8 +65,7 @@
},
{
"lineNumber": 32,
"ruleName": "MD037",
"ruleAlias": "no-space-in-emphasis",
"ruleNames": [ "MD037", "no-space-in-emphasis" ],
"ruleDescription": "Spaces inside emphasis markers",
"errorDetail": null,
"errorContext": "*some *",
@ -82,8 +73,7 @@
},
{
"lineNumber": 33,
"ruleName": "MD037",
"ruleAlias": "no-space-in-emphasis",
"ruleNames": [ "MD037", "no-space-in-emphasis" ],
"ruleDescription": "Spaces inside emphasis markers",
"errorDetail": null,
"errorContext": "**some **",
@ -91,8 +81,7 @@
},
{
"lineNumber": 34,
"ruleName": "MD037",
"ruleAlias": "no-space-in-emphasis",
"ruleNames": [ "MD037", "no-space-in-emphasis" ],
"ruleDescription": "Spaces inside emphasis markers",
"errorDetail": null,
"errorContext": "_ some_",
@ -100,8 +89,7 @@
},
{
"lineNumber": 35,
"ruleName": "MD037",
"ruleAlias": "no-space-in-emphasis",
"ruleNames": [ "MD037", "no-space-in-emphasis" ],
"ruleDescription": "Spaces inside emphasis markers",
"errorDetail": null,
"errorContext": "__ some __",
@ -109,8 +97,7 @@
},
{
"lineNumber": 17,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "` inside `",
@ -118,8 +105,7 @@
},
{
"lineNumber": 24,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "`` inside ``",
@ -127,8 +113,7 @@
},
{
"lineNumber": 25,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "` code`",
@ -136,8 +121,7 @@
},
{
"lineNumber": 26,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "` elements`",
@ -145,8 +129,7 @@
},
{
"lineNumber": 27,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "`` code``",
@ -154,8 +137,7 @@
},
{
"lineNumber": 28,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "`` ` embedded backtick``",
@ -163,8 +145,7 @@
},
{
"lineNumber": 29,
"ruleName": "MD038",
"ruleAlias": "no-space-in-code",
"ruleNames": [ "MD038", "no-space-in-code" ],
"ruleDescription": "Spaces inside code span elements",
"errorDetail": null,
"errorContext": "``embedded backtick` ``",
@ -172,8 +153,7 @@
},
{
"lineNumber": 19,
"ruleName": "MD039",
"ruleAlias": "no-space-in-links",
"ruleNames": [ "MD039", "no-space-in-links" ],
"ruleDescription": "Spaces inside link text",
"errorDetail": null,
"errorContext": "[ inside ]",
@ -181,8 +161,7 @@
},
{
"lineNumber": 21,
"ruleName": "MD040",
"ruleAlias": "fenced-code-language",
"ruleNames": [ "MD040", "fenced-code-language" ],
"ruleDescription": "Fenced code blocks should have a language specified",
"errorDetail": null,
"errorContext": "```",

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 1,
"ruleName": "MD041",
"ruleAlias": "first-line-h1",
"ruleNames": [ "MD041", "first-line-h1" ],
"ruleDescription": "First line in file should be a top level header",
"errorDetail": null,
"errorContext": "Not a header",
@ -10,8 +9,7 @@
},
{
"lineNumber": 3,
"ruleName": "MD042",
"ruleAlias": "no-empty-links",
"ruleNames": [ "MD042", "no-empty-links" ],
"ruleDescription": "No empty links",
"errorDetail": null,
"errorContext": "[empty]()",
@ -19,8 +17,7 @@
},
{
"lineNumber": 5,
"ruleName": "MD042",
"ruleAlias": "no-empty-links",
"ruleNames": [ "MD042", "no-empty-links" ],
"ruleDescription": "No empty links",
"errorDetail": null,
"errorContext": "[empty]()",
@ -28,8 +25,7 @@
},
{
"lineNumber": 7,
"ruleName": "MD042",
"ruleAlias": "no-empty-links",
"ruleNames": [ "MD042", "no-empty-links" ],
"ruleDescription": "No empty links",
"errorDetail": null,
"errorContext": "[empty]()",
@ -37,8 +33,7 @@
},
{
"lineNumber": 17,
"ruleName": "MD042",
"ruleAlias": "no-empty-links",
"ruleNames": [ "MD042", "no-empty-links" ],
"ruleDescription": "No empty links",
"errorDetail": null,
"errorContext": "[empty one]()",
@ -46,8 +41,7 @@
},
{
"lineNumber": 20,
"ruleName": "MD043",
"ruleAlias": "required-headers",
"ruleNames": [ "MD043", "required-headers" ],
"ruleDescription": "Required header structure",
"errorDetail": null,
"errorContext": "# Header",
@ -55,8 +49,7 @@
},
{
"lineNumber": 9,
"ruleName": "MD044",
"ruleAlias": "proper-names",
"ruleNames": [ "MD044", "proper-names" ],
"ruleDescription": "Proper names should have the correct capitalization",
"errorDetail": "Expected: markdownlint; Actual: MARKDOWNLINT",
"errorContext": null,
@ -64,8 +57,7 @@
},
{
"lineNumber": 12,
"ruleName": "MD044",
"ruleAlias": "proper-names",
"ruleNames": [ "MD044", "proper-names" ],
"ruleDescription": "Proper names should have the correct capitalization",
"errorDetail": "Expected: markdownlint; Actual: Markdownlint",
"errorContext": null,
@ -73,8 +65,7 @@
},
{
"lineNumber": 15,
"ruleName": "MD044",
"ruleAlias": "proper-names",
"ruleNames": [ "MD044", "proper-names" ],
"ruleDescription": "Proper names should have the correct capitalization",
"errorDetail": "Expected: markdownlint; Actual: MarkDownLint",
"errorContext": null,
@ -82,8 +73,7 @@
},
{
"lineNumber": 19,
"ruleName": "MD045",
"ruleAlias": "no-alt-text",
"ruleNames": [ "MD045", "no-alt-text" ],
"ruleDescription": "Images should have alternate text (alt text)",
"errorDetail": null,
"errorContext": null,

View file

@ -1,8 +1,7 @@
[
{
"lineNumber": 6,
"ruleName": "MD009",
"ruleAlias": "no-trailing-spaces",
"ruleNames": [ "MD009", "no-trailing-spaces" ],
"ruleDescription": "Trailing spaces",
"errorDetail": "Expected: 0; Actual: 1",
"errorContext": null,
@ -10,8 +9,7 @@
},
{
"lineNumber": 4,
"ruleName": "MD041",
"ruleAlias": "first-line-h1",
"ruleNames": [ "MD041", "first-line-h1" ],
"ruleDescription": "First line in file should be a top level header",
"errorDetail": null,
"errorContext": "Text",

View file

@ -32,7 +32,7 @@ function createTestForFile(file) {
return Q.nfcall(markdownlint, {
"files": [ file ],
"config": mergedConfig,
"resultVersion": detailedResults ? 1 : 0
"resultVersion": detailedResults ? 2 : 0
});
});
var expectedPromise = detailedResults ?
@ -211,7 +211,8 @@ module.exports.resultFormattingV1 = function resultFormattingV1(test) {
"./test/atx_header_spacing.md",
"./test/first_header_bad_atx.md"
],
"config": defaultConfig
"config": defaultConfig,
"resultVersion": 1
};
markdownlint(options, function callback(err, actualResult) {
test.ifError(err);
@ -292,10 +293,11 @@ module.exports.resultFormattingV1 = function resultFormattingV1(test) {
});
};
module.exports.resultFormattingV1BadRegExp = function resultFormattingV1(test) {
module.exports.resultFormattingV1BadRegExp =
function resultFormattingV1BadRegExp(test) {
test.expect(3);
var md010 = rules[8];
test.equal(md010.name, "MD010", "Wrong rule.");
test.equal(md010.names[0], "MD010", "Wrong rule.");
var md010RegExp = md010.regexp;
md010.regexp = /X/;
var options = {
@ -324,6 +326,123 @@ module.exports.resultFormattingV1BadRegExp = function resultFormattingV1(test) {
});
};
module.exports.resultFormattingV2 = function resultFormattingV2(test) {
test.expect(3);
var options = {
"strings": {
"truncate":
"# Multiple spaces inside hashes on closed atx style header #"
},
"files": [
"./test/atx_header_spacing.md",
"./test/first_header_bad_atx.md"
],
"config": defaultConfig
};
markdownlint(options, function callback(err, actualResult) {
test.ifError(err);
var expectedResult = {
"truncate": [
{ "lineNumber": 1,
"ruleNames": [ "MD021", "no-multiple-space-closed-atx" ],
"ruleDescription":
"Multiple spaces inside hashes on closed atx style header",
"errorDetail": null,
"errorContext": "# Multiple spa...style header #",
"errorRange": [ 1, 4 ] }
],
"./test/atx_header_spacing.md": [
{ "lineNumber": 3,
"ruleNames": [ "MD002", "first-header-h1" ],
"ruleDescription": "First header should be a top level header",
"errorDetail": "Expected: h1; Actual: h2",
"errorContext": null,
"errorRange": null },
{ "lineNumber": 1,
"ruleNames": [ "MD018", "no-missing-space-atx" ],
"ruleDescription": "No space after hash on atx style header",
"errorDetail": null,
"errorContext": "#Header 1 {MD018}",
"errorRange": [ 1, 2 ] },
{ "lineNumber": 3,
"ruleNames": [ "MD019", "no-multiple-space-atx" ],
"ruleDescription": "Multiple spaces after hash on atx style header",
"errorDetail": null,
"errorContext": "## Header 2 {MD019}",
"errorRange": [ 1, 5 ] },
{ "lineNumber": 5,
"ruleNames": [ "MD019", "no-multiple-space-atx" ],
"ruleDescription": "Multiple spaces after hash on atx style header",
"errorDetail": null,
"errorContext": "## Header 3 {MD019}",
"errorRange": [ 1, 6 ] }
],
"./test/first_header_bad_atx.md": [
{ "lineNumber": 1,
"ruleNames": [ "MD002", "first-header-h1" ],
"ruleDescription": "First header should be a top level header",
"errorDetail": "Expected: h1; Actual: h2",
"errorContext": null,
"errorRange": null }
]
};
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
var actualMessage = actualResult.toString();
var expectedMessage =
"truncate: 1: MD021/no-multiple-space-closed-atx" +
" Multiple spaces inside hashes on closed atx style header" +
" [Context: \"# Multiple spa...style header #\"]\n" +
"./test/atx_header_spacing.md: 3: MD002/first-header-h1" +
" First header should be a top level header" +
" [Expected: h1; Actual: h2]\n" +
"./test/atx_header_spacing.md: 1: MD018/no-missing-space-atx" +
" No space after hash on atx style header" +
" [Context: \"#Header 1 {MD018}\"]\n" +
"./test/atx_header_spacing.md: 3: MD019/no-multiple-space-atx" +
" Multiple spaces after hash on atx style header" +
" [Context: \"## Header 2 {MD019}\"]\n" +
"./test/atx_header_spacing.md: 5: MD019/no-multiple-space-atx" +
" Multiple spaces after hash on atx style header" +
" [Context: \"## Header 3 {MD019}\"]\n" +
"./test/first_header_bad_atx.md: 1: MD002/first-header-h1" +
" First header should be a top level header" +
" [Expected: h1; Actual: h2]";
test.equal(actualMessage, expectedMessage, "Incorrect message.");
test.done();
});
};
module.exports.resultFormattingV2BadRegExp =
function resultFormattingV2BadRegExp(test) {
test.expect(3);
var md010 = rules[8];
test.equal(md010.names[0], "MD010", "Wrong rule.");
var md010RegExp = md010.regexp;
md010.regexp = /X/;
var options = {
"strings": {
"tab": "\t."
},
"config": defaultConfig
};
markdownlint(options, function callback(err, actualResult) {
test.ifError(err);
var expectedResult = {
"tab": [
{ "lineNumber": 1,
"ruleNames": [ "MD010", "no-hard-tabs" ],
"ruleDescription": "Hard tabs",
"errorDetail": "Column: 1",
"errorContext": null,
"errorRange": null }
]
};
test.deepEqual(actualResult, expectedResult, "Undetected issues.");
md010.regexp = md010RegExp;
test.done();
});
};
module.exports.stringInputLineEndings = function stringInputLineEndings(test) {
test.expect(2);
var options = {
@ -969,23 +1088,24 @@ module.exports.missingStringValue = function missingStringValue(test) {
module.exports.ruleNamesUpperCase = function ruleNamesUpperCase(test) {
test.expect(41);
rules.forEach(function forRule(rule) {
test.equal(rule.name, rule.name.toUpperCase(), "Rule name not upper-case.");
var ruleName = rule.names[0];
test.equal(ruleName, ruleName.toUpperCase(), "Rule name not upper-case.");
});
test.done();
};
module.exports.uniqueAliases = function uniqueAliases(test) {
test.expect(82);
module.exports.uniqueNames = function uniqueNames(test) {
test.expect(164);
var tags = [];
rules.forEach(function forRule(rule) {
Array.prototype.push.apply(tags, rule.tags);
});
var aliases = [];
var names = [];
rules.forEach(function forRule(rule) {
rule.aliases.forEach(function forAlias(alias) {
test.ok(tags.indexOf(alias) === -1, "Alias not unique in tags.");
test.ok(aliases.indexOf(alias) === -1, "Alias not unique in aliases.");
aliases.push(alias);
rule.names.forEach(function forAlias(name) {
test.ok(tags.indexOf(name) === -1, "Name not unique in tags.");
test.ok(names.indexOf(name) === -1, "Name not unique in names.");
names.push(name);
});
});
test.done();
@ -997,7 +1117,7 @@ module.exports.readme = function readme(test) {
rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) {
var tagRules = tagToRules[tag] || [];
tagRules.push(rule.name);
tagRules.push(rule.names[0]);
tagToRules[tag] = tagRules;
});
});
@ -1030,9 +1150,11 @@ module.exports.readme = function readme(test) {
test.ok(rule,
"Missing rule implementation for " + token.content + ".");
if (rule) {
var expected = "**[" + rule.name + "](doc/Rules.md#" +
rule.name.toLowerCase() + ")** *" +
rule.aliases.join(", ") + "* - " + rule.desc;
var ruleName = rule.names[0];
var ruleAliases = rule.names.slice(1);
var expected = "**[" + ruleName + "](doc/Rules.md#" +
ruleName.toLowerCase() + ")** *" +
ruleAliases.join(", ") + "* - " + rule.desc;
test.equal(token.content, expected, "Rule mismatch.");
}
} else if (inTags) {
@ -1046,7 +1168,8 @@ module.exports.readme = function readme(test) {
});
var ruleLeft = rulesLeft.shift();
test.ok(!ruleLeft,
"Missing rule documentation for " + (ruleLeft || {}).name + ".");
"Missing rule documentation for " +
(ruleLeft || "[NO RULE]").toString() + ".");
var tagLeft = Object.keys(tagToRules).shift();
test.ok(!tagLeft, "Undocumented tag " + tagLeft + ".");
test.done();
@ -1065,13 +1188,14 @@ module.exports.doc = function doc(test) {
var ruleHasAliases = true;
var ruleUsesParams = null;
var tagAliasParameterRe = /, |: | /;
function testTagsAliasesParams() {
function testTagsAliasesParams(r) {
r = r || "[NO RULE]";
test.ok(ruleHasTags,
"Missing tags for rule " + (rule || {}).name + ".");
"Missing tags for rule " + r.toString() + ".");
test.ok(ruleHasAliases,
"Missing aliases for rule " + (rule || {}).name + ".");
"Missing aliases for rule " + r.toString() + ".");
test.ok(!ruleUsesParams,
"Missing parameters for rule " + (rule || {}).name + ".");
"Missing parameters for rule " + r.toString() + ".");
}
md.parse(contents, {}).forEach(function forToken(token) {
if ((token.type === "heading_open") && (token.tag === "h2")) {
@ -1080,13 +1204,13 @@ module.exports.doc = function doc(test) {
inHeading = false;
} else if (token.type === "inline") {
if (inHeading) {
testTagsAliasesParams();
testTagsAliasesParams(rule);
rule = rulesLeft.shift();
ruleHasTags = ruleHasAliases = false;
test.ok(rule,
"Missing rule implementation for " + token.content + ".");
if (rule) {
test.equal(token.content, rule.name + " - " + rule.desc,
test.equal(token.content, rule.names[0] + " - " + rule.desc,
"Rule mismatch.");
ruleUsesParams = rule.func.toString()
.match(/params\.options\.[_a-z]*/gi);
@ -1098,11 +1222,12 @@ module.exports.doc = function doc(test) {
}
} else if (/^Tags: /.test(token.content) && rule) {
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
rule.tags, "Tag mismatch for rule " + rule.name + ".");
rule.tags, "Tag mismatch for rule " + rule.toString() + ".");
ruleHasTags = true;
} else if (/^Aliases: /.test(token.content) && rule) {
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
rule.aliases, "Alias mismatch for rule " + rule.name + ".");
rule.names.slice(1),
"Alias mismatch for rule " + rule.toString() + ".");
ruleHasAliases = true;
} else if (/^Parameters: /.test(token.content) && rule) {
var inDetails = false;
@ -1113,16 +1238,17 @@ module.exports.doc = function doc(test) {
return !inDetails;
});
test.deepEqual(parameters, ruleUsesParams,
"Missing parameter for rule " + rule.name);
"Missing parameter for rule " + rule.toString());
ruleUsesParams = null;
}
}
});
var ruleLeft = rulesLeft.shift();
test.ok(!ruleLeft,
"Missing rule documentation for " + (ruleLeft || {}).name + ".");
"Missing rule documentation for " +
(ruleLeft || "[NO RULE]").toString() + ".");
if (rule) {
testTagsAliasesParams();
testTagsAliasesParams(rule);
}
test.done();
});