Add lint rules from eslint-plugin-unicorn.

This commit is contained in:
David Anson 2020-09-06 20:34:10 -07:00
parent 0f4745efe3
commit 5ab938a6ab
11 changed files with 96 additions and 31 deletions

View file

@ -8,7 +8,8 @@
},
"plugins": [
"jsdoc",
"node"
"node",
"unicorn"
],
"extends": [
"eslint:all",
@ -113,6 +114,62 @@
"node/prefer-global/url-search-params": "error",
"node/prefer-global/url": "error",
"node/prefer-promises/dns": "error",
"node/prefer-promises/fs": "off"
"node/prefer-promises/fs": "off",
"unicorn/better-regex": "off",
"unicorn/catch-error-name": "error",
"unicorn/consistent-function-scoping": "off",
"unicorn/custom-error-definition": "error",
"unicorn/error-message": "error",
"unicorn/escape-case": "error",
"unicorn/expiring-todo-comments": "error",
"unicorn/explicit-length-check": "error",
"unicorn/filename-case": "off",
"unicorn/import-index": "error",
"unicorn/new-for-builtins": "error",
"unicorn/no-abusive-eslint-disable": "error",
"unicorn/no-array-instanceof": "error",
"unicorn/no-console-spaces": "error",
"unicorn/no-fn-reference-in-iterator": "off",
"unicorn/no-for-loop": "error",
"unicorn/no-hex-escape": "error",
"unicorn/no-keyword-prefix": "off",
"unicorn/no-nested-ternary": "error",
"unicorn/no-new-buffer": "error",
"unicorn/no-null": "off",
"unicorn/no-object-as-default-parameter": "error",
"unicorn/no-process-exit": "error",
"unicorn/no-reduce": "error",
"unicorn/no-unreadable-array-destructuring": "error",
"unicorn/no-unsafe-regex": "off",
"unicorn/no-unused-properties": "error",
"unicorn/no-useless-undefined": "error",
"unicorn/no-zero-fractions": "error",
"unicorn/number-literal-case": "error",
"unicorn/prefer-add-event-listener": "error",
"unicorn/prefer-array-find": "error",
"unicorn/prefer-dataset": "error",
"unicorn/prefer-event-key": "error",
"unicorn/prefer-flat-map": "error",
"unicorn/prefer-includes": "error",
"unicorn/prefer-modern-dom-apis": "error",
"unicorn/prefer-negative-index": "error",
"unicorn/prefer-node-append": "error",
"unicorn/prefer-node-remove": "error",
"unicorn/prefer-number-properties": "error",
"unicorn/prefer-optional-catch-binding": "error",
"unicorn/prefer-query-selector": "error",
"unicorn/prefer-reflect-apply": "error",
"unicorn/prefer-replace-all": "off",
"unicorn/prefer-set-has": "error",
"unicorn/prefer-spread": "error",
"unicorn/prefer-starts-ends-with": "error",
"unicorn/prefer-string-slice": "off",
"unicorn/prefer-text-content": "error",
"unicorn/prefer-trim-start-end": "off",
"unicorn/prefer-type-error": "error",
"unicorn/prevent-abbreviations": "off",
"unicorn/string-content": "error",
"unicorn/throw-new-error": "error"
}
}

View file

@ -196,7 +196,8 @@
if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) {
markdown.value = decodedHash.substring(hashPrefix.length);
}
} catch (ex) {
/* eslint-disable-next-line unicorn/prefer-optional-catch-binding */
} catch (error) {
// Invalid
}
}
@ -205,7 +206,8 @@
try {
/* eslint-disable-next-line no-new */
new URL(rulesMd);
} catch (ex) {
/* eslint-disable-next-line unicorn/prefer-optional-catch-binding */
} catch (error) {
markdown.value = [
"# Sorry",
"",

View file

@ -2782,10 +2782,10 @@ module.exports = {
// Close current run
var content = line.substring(emphasisIndex, matchIndex);
if (!emphasisLength) {
content = content.trimStart();
content = content.trimLeft();
}
if (!match) {
content = content.trimEnd();
content = content.trimRight();
}
var leftSpace = leftSpaceRe.test(content);
var rightSpace = rightSpaceRe.test(content);

View file

@ -154,7 +154,7 @@ function removeFrontMatter(content, frontMatter) {
const contentMatched = frontMatterMatch[0];
content = content.slice(contentMatched.length);
frontMatterLines = contentMatched.split(helpers.newLineRe);
if (frontMatterLines.length &&
if ((frontMatterLines.length > 0) &&
(frontMatterLines[frontMatterLines.length - 1] === "")) {
frontMatterLines.length--;
}
@ -343,7 +343,8 @@ function getEnabledRulesPerLineNumber(
...config,
...json
};
} catch (ex) {
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
} catch (error) {
// Ignore parse errors for inline configuration
}
}
@ -459,7 +460,7 @@ function lintContent(
resultVersion,
callback) {
// Remove UTF-8 byte order marker (if present)
content = content.replace(/^\ufeff/, "");
content = content.replace(/^\uFEFF/, "");
// Remove front matter
const removeFrontMatterResult = removeFrontMatter(content, frontMatter);
const frontMatterLines = removeFrontMatterResult.frontMatterLines;
@ -582,17 +583,17 @@ function lintContent(
if (handleRuleFailures) {
try {
rule.function(params, onError);
} catch (ex) {
} catch (error) {
onError({
"lineNumber": 1,
"detail": `This rule threw an exception: ${ex.message}`
"detail": `This rule threw an exception: ${error.message}`
});
}
} else {
rule.function(params, onError);
}
// Record any errors (significant performance benefit from length check)
if (errors.length) {
if (errors.length > 0) {
errors.sort(lineNumberComparison);
const filteredErrors = errors
.filter((resultVersion === 3) ?
@ -624,7 +625,7 @@ function lintContent(
}
return errorObject;
});
if (filteredErrors.length) {
if (filteredErrors.length > 0) {
if (resultVersion === 0) {
result[ruleNameFriendly] = filteredErrors;
} else {
@ -636,9 +637,9 @@ function lintContent(
// Run all rules
try {
ruleList.forEach(forRule);
} catch (ex) {
} catch (error) {
cache.clear();
return callback(ex);
return callback(error);
}
cache.clear();
return callback(null, result);
@ -819,8 +820,8 @@ function parseConfiguration(name, content, parsers) {
(parsers || [ JSON.parse ]).every((parser) => {
try {
config = parser(content);
} catch (ex) {
errors.push(ex.message);
} catch (error) {
errors.push(error.message);
}
return !config;
});

View file

@ -11,7 +11,7 @@ module.exports = {
"function": function MD001(params, onError) {
let prevLevel = 0;
filterTokens(params, "heading_open", function forToken(token) {
const level = parseInt(token.tag.slice(1), 10);
const level = Number.parseInt(token.tag.slice(1), 10);
if (prevLevel && (level > prevLevel)) {
addErrorDetailIf(onError, token.lineNumber,
"h" + (prevLevel + 1), "h" + level);

View file

@ -13,7 +13,7 @@ module.exports = {
const maximum = Number(params.config.maximum || 1);
let count = 0;
forEachLine(lineMetadata(), (line, lineIndex, inCode) => {
count = (inCode || line.trim().length) ? 0 : count + 1;
count = (inCode || (line.trim().length > 0)) ? 0 : count + 1;
if (maximum < count) {
addErrorDetailIf(
onError,

View file

@ -32,10 +32,10 @@ module.exports = {
// Close current run
let content = line.substring(emphasisIndex, matchIndex);
if (!emphasisLength) {
content = content.trimStart();
content = content.trimLeft();
}
if (!match) {
content = content.trimEnd();
content = content.trimRight();
}
const leftSpace = leftSpaceRe.test(content);
const rightSpace = rightSpaceRe.test(content);

View file

@ -17,7 +17,7 @@
"test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 node test/markdownlint-test.js",
"test-declaration": "cd example/typescript && tsc && node type-check.js",
"test-extra": "node test/markdownlint-test-extra.js",
"lint": "eslint --max-warnings 0 lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0, node/no-missing-require: 0, node/no-extraneous-require: 0\" example",
"lint": "eslint --max-warnings 0 lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0, unicorn/prefer-add-event-listener: 0, unicorn/prefer-query-selector: 0, unicorn/prefer-replace-all: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0, node/no-missing-require: 0, node/no-extraneous-require: 0\" example",
"ci": "npm run test-cover && npm run lint && npm run test-declaration",
"build-config-schema": "node schema/build-config-schema.js",
"build-declaration": "tsc --allowJs --declaration --outDir declaration --resolveJsonModule lib/markdownlint.js && cpy declaration/lib/markdownlint.d.ts lib && rimraf declaration",
@ -43,6 +43,7 @@
"eslint": "~7.8.1",
"eslint-plugin-jsdoc": "~30.3.1",
"eslint-plugin-node": "~11.1.0",
"eslint-plugin-unicorn": "~21.0.0",
"globby": "~11.0.1",
"js-yaml": "~3.14.0",
"make-dir-cli": "~2.0.0",

View file

@ -55,7 +55,7 @@ function lintTestRepo(test, globPatterns, configPath) {
};
return markdownlintPromise(options).then((results) => {
const resultsString = results.toString();
if (resultsString.length) {
if (resultsString.length > 0) {
// eslint-disable-next-line no-console
console.log(resultsString);
}

View file

@ -24,7 +24,7 @@ const configSchema = require("../schema/markdownlint-config-schema.json");
const homepage = packageJson.homepage;
const version = packageJson.version;
const deprecatedRuleNames = [ "MD002", "MD006" ];
const deprecatedRuleNames = new Set([ "MD002", "MD006" ]);
/**
* Create a test function for the specified test file.
@ -128,7 +128,11 @@ function createTestForFile(file) {
while ((match = regex.exec(line))) {
const rule = match[1];
const errors = results[rule] || [];
errors.push(match[2] ? parseInt(match[2], 10) : lineNum + 1);
errors.push(
match[2] ?
Number.parseInt(match[2], 10) :
lineNum + 1
);
results[rule] = errors;
}
});
@ -1504,7 +1508,7 @@ tape("readme", (test) => {
let expected = "**[" + ruleName + "](doc/Rules.md#" +
ruleName.toLowerCase() + ")** *" +
ruleAliases.join("/") + "* - " + rule.description;
if (deprecatedRuleNames.includes(ruleName)) {
if (deprecatedRuleNames.has(ruleName)) {
expected = "~~" + expected + "~~";
}
test.equal(token.content, expected, "Rule mismatch.");
@ -1566,7 +1570,7 @@ tape("rules", (test) => {
"Missing rule implementation for " + token.content + ".");
const ruleName = rule.names[0];
let headingContent = ruleName + " - " + rule.description;
if (deprecatedRuleNames.includes(ruleName)) {
if (deprecatedRuleNames.has(ruleName)) {
headingContent = "~~" + headingContent + "~~";
}
test.equal(token.content,
@ -1580,16 +1584,16 @@ tape("rules", (test) => {
});
ruleUsesParams.sort();
}
} else if (/^Tags: /.test(token.content) && rule) {
} else if (token.content.startsWith("Tags: ") && rule) {
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
rule.tags, "Tag mismatch for rule " + rule.names + ".");
ruleHasTags = true;
} else if (/^Aliases: /.test(token.content) && rule) {
} else if (token.content.startsWith("Aliases: ") && rule) {
test.deepEqual(token.content.split(tagAliasParameterRe).slice(1),
rule.names.slice(1),
"Alias mismatch for rule " + rule.names + ".");
ruleHasAliases = true;
} else if (/^Parameters: /.test(token.content) && rule) {
} else if (token.content.startsWith("Parameters: ") && rule) {
let inDetails = false;
const parameters = token.content.split(tagAliasParameterRe)
.slice(1)

View file

@ -17,7 +17,7 @@ const languageJavaScript = /js|javascript/i;
function cleanJsdocRulesFromEslintConfig(config) {
const cleanedConfig = { ...config };
for (const rule in config.rules) {
if (/^(jsdoc|node)\//.test(rule)) {
if (/^(jsdoc|node|unicorn)\//.test(rule)) {
delete cleanedConfig.rules[rule];
}
}