Refactor to run rule analysis when called, simplify functions.

This commit is contained in:
David Anson 2018-02-05 21:26:07 -08:00
parent fda309df2f
commit 4619a8c824
3 changed files with 99 additions and 72 deletions

View file

@ -64,7 +64,7 @@
"max-lines": "off", "max-lines": "off",
"max-nested-callbacks": "error", "max-nested-callbacks": "error",
"max-params": ["error", 7], "max-params": ["error", 7],
"max-statements": ["error", 32], "max-statements": ["error", 20],
"max-statements-per-line": "error", "max-statements-per-line": "error",
"multiline-comment-style": ["error", "separate-lines"], "multiline-comment-style": ["error", "separate-lines"],
"multiline-ternary": "off", "multiline-ternary": "off",

View file

@ -8,33 +8,6 @@ var md = require("markdown-it")({ "html": true });
var rules = require("./rules"); var rules = require("./rules");
var shared = require("./shared"); var shared = require("./shared");
// Mapping from rule names/tags to canonical rule name
var aliasToRuleNames = {};
// var tagToRuleNames = {};
rules.forEach(function forRule(rule) {
var ruleName = rule.names[0].toUpperCase();
// The following is useful for updating README.md
// console.log(
// "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
// ")** *" + rule.names.slice(1).join(", ") + "* - " + rule.description);
rule.names.forEach(function forName(name) {
var nameUpper = name.toUpperCase();
aliasToRuleNames[nameUpper] = [ ruleName ];
});
rule.tags.forEach(function forTag(tag) {
var tagUpper = tag.toUpperCase();
var ruleNames = aliasToRuleNames[tagUpper] || [];
ruleNames.push(ruleName);
aliasToRuleNames[tagUpper] = ruleNames;
// tagToRuleNames[tag] = ruleName;
});
});
// The following is useful for updating README.md
// Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {
// console.log("* **" + tag + "** - " +
// aliasToRuleNames[tag.toUpperCase()].join(", "));
// });
// Class for results with toString for pretty display // Class for results with toString for pretty display
function Results() {} function Results() {}
Results.prototype.toString = function resultsToString(useAlias) { Results.prototype.toString = function resultsToString(useAlias) {
@ -85,24 +58,8 @@ Results.prototype.toString = function resultsToString(useAlias) {
return results.join("\n"); return results.join("\n");
}; };
// Array.sort comparison for objects in errors array // Remove front matter (if present at beginning of content)
function lineNumberComparison(a, b) { function removeFrontMatter(content, frontMatter) {
return a.lineNumber - b.lineNumber;
}
// Function to return unique values from a sorted errors array
function uniqueFilterForSortedErrors(value, index, array) {
return (index === 0) || (value.lineNumber > array[index - 1].lineNumber);
}
// Lints a single string
function lintContent(
content, config, frontMatter, noInlineConfig, resultVersion) {
// Remove UTF-8 byte order marker (if present)
if (content.charCodeAt(0) === 0xfeff) {
content = content.slice(1);
}
// Remove front matter (if present at beginning of content)
var frontMatterLines = []; var frontMatterLines = [];
if (frontMatter) { if (frontMatter) {
var frontMatterMatch = content.match(frontMatter); var frontMatterMatch = content.match(frontMatter);
@ -116,14 +73,16 @@ function lintContent(
} }
} }
} }
// Ignore the content of HTML comments return {
content = shared.clearHtmlCommentText(content); "content": content,
// Parse content into tokens and lines "frontMatterLines": frontMatterLines
var tokens = md.parse(content, {}); };
var lines = content.split(shared.newLineRe); }
var tokenLists = {};
// Annotate tokens with line/lineNumber
function annotateTokens(tokens, lines) {
var tbodyMap = null; var tbodyMap = null;
// Annotate tokens with line/lineNumber var tokenLists = {};
tokens.forEach(function forToken(token) { tokens.forEach(function forToken(token) {
// Handle missing maps for table body // Handle missing maps for table body
if (token.type === "tbody_open") { if (token.type === "tbody_open") {
@ -159,7 +118,41 @@ function lintContent(
} }
tokenLists[token.type].push(token); tokenLists[token.type].push(token);
}); });
// Merge rules/tags and sanitize config return tokenLists;
}
// Map rule names/tags to canonical rule name
function mapAliasToRuleNames(ruleList) {
var aliasToRuleNames = {};
// var tagToRuleNames = {};
ruleList.forEach(function forRule(rule) {
var ruleName = rule.names[0].toUpperCase();
// The following is useful for updating README.md:
// console.log(
// "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
// ")** *" + rule.names.slice(1).join(", ") + "* - " + rule.description);
rule.names.forEach(function forName(name) {
var nameUpper = name.toUpperCase();
aliasToRuleNames[nameUpper] = [ ruleName ];
});
rule.tags.forEach(function forTag(tag) {
var tagUpper = tag.toUpperCase();
var ruleNames = aliasToRuleNames[tagUpper] || [];
ruleNames.push(ruleName);
aliasToRuleNames[tagUpper] = ruleNames;
// tagToRuleNames[tag] = ruleName;
});
});
// The following is useful for updating README.md:
// Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {
// console.log("* **" + tag + "** - " +
// aliasToRuleNames[tag.toUpperCase()].join(", "));
// });
return aliasToRuleNames;
}
// Merge rules/tags and sanitize config
function mergeRulesAndSanitize(config, aliasToRuleNames) {
var defaultKey = Object.keys(config).filter(function forKey(key) { var defaultKey = Object.keys(config).filter(function forKey(key) {
return key.toUpperCase() === "DEFAULT"; return key.toUpperCase() === "DEFAULT";
}); });
@ -183,7 +176,12 @@ function lintContent(
mergedRules[ruleName] = value; mergedRules[ruleName] = value;
}); });
}); });
// Create mapping of enabled rules per line return mergedRules;
}
// Create mapping of enabled rules per line
function getEnabledRulesPerLineNumber(
lines, frontMatterLines, noInlineConfig, mergedRules, aliasToRuleNames) {
var enabledRules = {}; var enabledRules = {};
var allRuleNames = []; var allRuleNames = [];
rules.forEach(function forRule(rule) { rules.forEach(function forRule(rule) {
@ -216,6 +214,40 @@ function lintContent(
} }
enabledRulesPerLineNumber.push(enabledRules); enabledRulesPerLineNumber.push(enabledRules);
}); });
return enabledRulesPerLineNumber;
}
// Array.sort comparison for objects in errors array
function lineNumberComparison(a, b) {
return a.lineNumber - b.lineNumber;
}
// Function to return unique values from a sorted errors array
function uniqueFilterForSortedErrors(value, index, array) {
return (index === 0) || (value.lineNumber > array[index - 1].lineNumber);
}
// Lints a single string
function lintContent(
content, config, frontMatter, noInlineConfig, resultVersion) {
// Remove UTF-8 byte order marker (if present)
if (content.charCodeAt(0) === 0xfeff) {
content = content.slice(1);
}
// Remove front matter
var removeFrontMatterResult = removeFrontMatter(content, frontMatter);
content = removeFrontMatterResult.content;
var frontMatterLines = removeFrontMatterResult.frontMatterLines;
// Ignore the content of HTML comments
content = shared.clearHtmlCommentText(content);
// Parse content into tokens and lines
var tokens = md.parse(content, {});
var lines = content.split(shared.newLineRe);
var tokenLists = annotateTokens(tokens, lines);
var aliasToRuleNames = mapAliasToRuleNames(rules);
var mergedRules = mergeRulesAndSanitize(config, aliasToRuleNames);
var enabledRulesPerLineNumber = getEnabledRulesPerLineNumber(
lines, frontMatterLines, noInlineConfig, mergedRules, aliasToRuleNames);
// Create parameters for rules // Create parameters for rules
var params = { var params = {
"tokens": tokens, "tokens": tokens,

View file

@ -1071,15 +1071,12 @@ module.exports.readme = function readme(test) {
if (!seenRelated) { if (!seenRelated) {
seenRelated = true; seenRelated = true;
} else if (seenRelated && !seenRules) { } else if (seenRelated && !seenRules) {
seenRules = true; seenRules = inRules = true;
inRules = true;
} else if (seenRelated && seenRules && !seenTags) { } else if (seenRelated && seenRules && !seenTags) {
seenTags = true; seenTags = inTags = true;
inTags = true;
} }
} else if (token.type === "bullet_list_close") { } else if (token.type === "bullet_list_close") {
inRules = false; inRules = inTags = false;
inTags = false;
} else if (token.type === "inline") { } else if (token.type === "inline") {
if (inRules) { if (inRules) {
var rule = rulesLeft.shift(); var rule = rulesLeft.shift();
@ -1145,7 +1142,6 @@ module.exports.doc = function doc(test) {
ruleHasTags = ruleHasAliases = false; ruleHasTags = ruleHasAliases = false;
test.ok(rule, test.ok(rule,
"Missing rule implementation for " + token.content + "."); "Missing rule implementation for " + token.content + ".");
if (rule) {
test.equal(token.content, test.equal(token.content,
rule.names[0] + " - " + rule.description, rule.names[0] + " - " + rule.description,
"Rule mismatch."); "Rule mismatch.");
@ -1156,7 +1152,6 @@ module.exports.doc = function doc(test) {
return use.split(".").pop(); return use.split(".").pop();
}); });
} }
}
} else if (/^Tags: /.test(token.content) && rule) { } else if (/^Tags: /.test(token.content) && rule) {
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1), test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
rule.tags, "Tag mismatch for rule " + rule.toString() + "."); rule.tags, "Tag mismatch for rule " + rule.toString() + ".");