Add "severity"/"error" to rule in Configuration object, add corresponding documentation, resolve some new type-checking issues.

This commit is contained in:
David Anson 2025-09-18 21:21:12 -07:00
parent 1d2d3ed581
commit c6f248321e
13 changed files with 4030 additions and 688 deletions

View file

@ -375,12 +375,48 @@ for all rules. Using a tag name (e.g., `whitespace`) and a setting of `false`,
configuration object is passed or the optional `default` setting is not present, configuration object is passed or the optional `default` setting is not present,
all rules are enabled. all rules are enabled.
The following syntax disables the specified rule, tag, or `default`:
```javascript
{
"rule_name": false
}
```
The following syntax enables the specified rule, tag, or `default`:
```javascript
{
"rule_name": true
// OR
"rule_name": "error"
}
```
The following syntax enables and configures the specified rule:
```javascript
{
"rule_name": {
"parameter": "value"
}
// OR
"rule_name": {
"parameter": "value",
"severity": "error"
}
}
```
> Note that `error` and `severity` are not supported by library versions earlier
> than `0.39.0`. However, all examples above behave the same.
To evaluate a configuration object, the `default` setting is applied first, then To evaluate a configuration object, the `default` setting is applied first, then
keys are processed in order from top to bottom. If multiple values apply to a keys are processed in order from top to bottom. If multiple values apply to a
rule (because of tag names or duplication), later values override earlier ones. rule (because of tag names or duplication), later values override earlier ones.
Keys (including rule names, aliases, tags, or `default`) are not case-sensitive. Keys (including rule names, aliases, tags, or `default`) are not case-sensitive.
Example: Example using `default`, rule names, and tag names together:
```json ```json
{ {

View file

@ -61,8 +61,12 @@ for (const rule of rules) {
"" ""
); );
const ruleData = schema.properties[name]; const ruleData = schema.properties[name];
const ruleProperties = ruleData.oneOf.at(-1).properties; const ruleProperties = Object.fromEntries(
if (ruleProperties) { Object.entries(
ruleData.oneOf.at(-1).properties
).filter(([ key ]) => key !== "severity")
);
if (Object.keys(ruleProperties).length > 0) {
section.push( section.push(
"Parameters:", "Parameters:",
"" ""

File diff suppressed because it is too large Load diff

View file

@ -262,9 +262,9 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
for (const key of Object.keys(config)) { for (const key of Object.keys(config)) {
let value = config[key]; let value = config[key];
if (value) { if (value) {
if (!(value instanceof Object)) { value = (value instanceof Object) ?
value = {}; Object.fromEntries(Object.entries(value).filter(([ k ]) => k !== "severity")) :
} {};
} else { } else {
value = false; value = false;
} }

View file

@ -6,14 +6,20 @@ import yaml from "js-yaml";
import { __dirname, importWithTypeJson } from "../test/esm-helpers.mjs"; import { __dirname, importWithTypeJson } from "../test/esm-helpers.mjs";
const configSchema = await importWithTypeJson(import.meta, "../schema/markdownlint-config-schema.json"); const configSchema = await importWithTypeJson(import.meta, "../schema/markdownlint-config-schema.json");
/** @type {Object<string, any>} */
const configExample = {}; const configExample = {};
for (const rule in configSchema.properties) { for (const rule in configSchema.properties) {
if (/^(?:MD\d{3}|default|extends)$/.test(rule)) { if (/^(?:MD\d{3}|default|extends)$/.test(rule)) {
const properties = configSchema.properties[rule]; const properties = configSchema.properties[rule];
configExample[rule + "-description"] = properties.description; configExample[rule + "-description"] = properties.description;
configExample[rule] = properties.default; configExample[rule] = properties.default;
const subproperties = properties.oneOf?.at(-1).properties; const subproperties = Object.fromEntries(
if (subproperties) { Object.entries(
properties.oneOf?.at(-1).properties || []
).filter(([ key ]) => key !== "severity")
);
if (Object.keys(subproperties).length > 0) {
/** @type {Object<string, any>} */
const ruleExample = {}; const ruleExample = {};
// eslint-disable-next-line guard-for-in // eslint-disable-next-line guard-for-in
for (const property in subproperties) { for (const property in subproperties) {
@ -26,6 +32,13 @@ for (const rule in configSchema.properties) {
} }
} }
/**
* Transforms comments to use the specified prefix.
*
* @param {string} input Markdown input.
* @param {string} commentPrefix Comment prefix.
* @returns {string} Transformed input.
*/
const transformComments = (input, commentPrefix) => ( const transformComments = (input, commentPrefix) => (
commentPrefix + commentPrefix +
" Example markdownlint configuration with all properties set to their default value\n" + " Example markdownlint configuration with all properties set to their default value\n" +

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
# Configure File With Severity
Text * text* {MD037}
Text ` text` {MD038}
Text [ text](.) {MD039}
+ List item {MD004}
Text (text)[.] {MD011}
2. List item {MD029}
<!-- markdownlint-disable -->
Text * text*
Text ` text`
Text [ text](.)
+ List item
Text (text)[.]
2. List item
<!-- markdownlint-restore -->
Text * text* {MD037}
Text ` text` {MD038}
Text [ text](.) {MD039}
+ List item {MD004}
Text (text)[.] {MD011}
2. List item {MD029}
<!-- markdownlint-configure-file {
"default": false,
"MD037": "error",
"MD038": "error",
"MD039": "error",
"MD004": {
"severity": "error",
"style": "dash"
},
"MD011": {
"severity": "error"
},
"MD029": {
"severity": "error"
}
} -->

View file

@ -29,13 +29,14 @@ test("customRulesV0", (t) => new Promise((resolve) => {
}; };
lintAsync(options, function callback(err, actualResult) { lintAsync(options, function callback(err, actualResult) {
t.falsy(err); t.falsy(err);
const expectedResult = {}; const expectedResult = {
expectedResult[customRulesMd] = { [customRulesMd]: {
"any-blockquote-markdown-it": [ 12 ], "any-blockquote-markdown-it": [ 12 ],
"any-blockquote-micromark": [ 12 ], "any-blockquote-micromark": [ 12 ],
"every-n-lines": [ 2, 4, 6, 10, 12 ], "every-n-lines": [ 2, 4, 6, 10, 12 ],
"first-line": [ 1 ], "first-line": [ 1 ],
"letters-E-X": [ 3, 7 ] "letters-E-X": [ 3, 7 ]
}
}; };
t.deepEqual(actualResult, expectedResult, "Undetected issues."); t.deepEqual(actualResult, expectedResult, "Undetected issues.");
// @ts-ignore // @ts-ignore
@ -103,93 +104,94 @@ test("customRulesV1", (t) => new Promise((resolve) => {
}; };
lintAsync(options, function callback(err, actualResult) { lintAsync(options, function callback(err, actualResult) {
t.falsy(err); t.falsy(err);
const expectedResult = {}; const expectedResult = {
expectedResult[customRulesMd] = [ [customRulesMd]: [
{ "lineNumber": 12, { "lineNumber": 12,
"ruleName": "any-blockquote-markdown-it", "ruleName": "any-blockquote-markdown-it",
"ruleAlias": "any-blockquote-markdown-it", "ruleAlias": "any-blockquote-markdown-it",
"ruleDescription": "Rule that reports an error for any blockquote", "ruleDescription": "Rule that reports an error for any blockquote",
"ruleInformation": "ruleInformation":
`${homepage}/blob/main/test/rules/any-blockquote.js`, `${homepage}/blob/main/test/rules/any-blockquote.js`,
"errorDetail": "Blockquote spans 1 line(s).", "errorDetail": "Blockquote spans 1 line(s).",
"errorContext": "> Blockquote", "errorContext": "> Blockquote",
"errorRange": null }, "errorRange": null },
{ "lineNumber": 12, { "lineNumber": 12,
"ruleName": "any-blockquote-micromark", "ruleName": "any-blockquote-micromark",
"ruleAlias": "any-blockquote-micromark", "ruleAlias": "any-blockquote-micromark",
"ruleDescription": "Rule that reports an error for any blockquote", "ruleDescription": "Rule that reports an error for any blockquote",
"ruleInformation": "ruleInformation":
`${homepage}/blob/main/test/rules/any-blockquote.js`, `${homepage}/blob/main/test/rules/any-blockquote.js`,
"errorDetail": "Blockquote spans 1 line(s).", "errorDetail": "Blockquote spans 1 line(s).",
"errorContext": "> Blockquote", "errorContext": "> Blockquote",
"errorRange": null }, "errorRange": null },
{ "lineNumber": 2, { "lineNumber": 2,
"ruleName": "every-n-lines", "ruleName": "every-n-lines",
"ruleAlias": "every-n-lines", "ruleAlias": "every-n-lines",
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 2", "errorDetail": "Line number 2",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 4, { "lineNumber": 4,
"ruleName": "every-n-lines", "ruleName": "every-n-lines",
"ruleAlias": "every-n-lines", "ruleAlias": "every-n-lines",
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 4", "errorDetail": "Line number 4",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 6, { "lineNumber": 6,
"ruleName": "every-n-lines", "ruleName": "every-n-lines",
"ruleAlias": "every-n-lines", "ruleAlias": "every-n-lines",
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 6", "errorDetail": "Line number 6",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 10, { "lineNumber": 10,
"ruleName": "every-n-lines", "ruleName": "every-n-lines",
"ruleAlias": "every-n-lines", "ruleAlias": "every-n-lines",
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 10", "errorDetail": "Line number 10",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 12, { "lineNumber": 12,
"ruleName": "every-n-lines", "ruleName": "every-n-lines",
"ruleAlias": "every-n-lines", "ruleAlias": "every-n-lines",
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 12", "errorDetail": "Line number 12",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 1, { "lineNumber": 1,
"ruleName": "first-line", "ruleName": "first-line",
"ruleAlias": "first-line", "ruleAlias": "first-line",
"ruleDescription": "Rule that reports an error for the first line", "ruleDescription": "Rule that reports an error for the first line",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": null, "errorDetail": null,
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 3, { "lineNumber": 3,
"ruleName": "letters-E-X", "ruleName": "letters-E-X",
"ruleAlias": "letter-E-letter-X", "ruleAlias": "letter-E-letter-X",
"ruleDescription": "ruleDescription":
"Rule that reports an error for lines with the letters 'EX'", "Rule that reports an error for lines with the letters 'EX'",
"ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`, "ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`,
"errorDetail": null, "errorDetail": null,
"errorContext": "text", "errorContext": "text",
"errorRange": null }, "errorRange": null },
{ "lineNumber": 7, { "lineNumber": 7,
"ruleName": "letters-E-X", "ruleName": "letters-E-X",
"ruleAlias": "letter-E-letter-X", "ruleAlias": "letter-E-letter-X",
"ruleDescription": "ruleDescription":
"Rule that reports an error for lines with the letters 'EX'", "Rule that reports an error for lines with the letters 'EX'",
"ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`, "ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`,
"errorDetail": null, "errorDetail": null,
"errorContext": "text", "errorContext": "text",
"errorRange": null } "errorRange": null }
]; ]
};
t.deepEqual(actualResult, expectedResult, "Undetected issues."); t.deepEqual(actualResult, expectedResult, "Undetected issues.");
// @ts-ignore // @ts-ignore
const actualMessage = actualResult.toString(); const actualMessage = actualResult.toString();
@ -236,83 +238,84 @@ test("customRulesV2", (t) => new Promise((resolve) => {
}; };
lintAsync(options, function callback(err, actualResult) { lintAsync(options, function callback(err, actualResult) {
t.falsy(err); t.falsy(err);
const expectedResult = {}; const expectedResult = {
expectedResult[customRulesMd] = [ [customRulesMd]: [
{ "lineNumber": 12, { "lineNumber": 12,
"ruleNames": [ "any-blockquote-markdown-it" ], "ruleNames": [ "any-blockquote-markdown-it" ],
"ruleDescription": "Rule that reports an error for any blockquote", "ruleDescription": "Rule that reports an error for any blockquote",
"ruleInformation": "ruleInformation":
`${homepage}/blob/main/test/rules/any-blockquote.js`, `${homepage}/blob/main/test/rules/any-blockquote.js`,
"errorDetail": "Blockquote spans 1 line(s).", "errorDetail": "Blockquote spans 1 line(s).",
"errorContext": "> Blockquote", "errorContext": "> Blockquote",
"errorRange": null }, "errorRange": null },
{ "lineNumber": 12, { "lineNumber": 12,
"ruleNames": [ "any-blockquote-micromark" ], "ruleNames": [ "any-blockquote-micromark" ],
"ruleDescription": "Rule that reports an error for any blockquote", "ruleDescription": "Rule that reports an error for any blockquote",
"ruleInformation": "ruleInformation":
`${homepage}/blob/main/test/rules/any-blockquote.js`, `${homepage}/blob/main/test/rules/any-blockquote.js`,
"errorDetail": "Blockquote spans 1 line(s).", "errorDetail": "Blockquote spans 1 line(s).",
"errorContext": "> Blockquote", "errorContext": "> Blockquote",
"errorRange": null }, "errorRange": null },
{ "lineNumber": 2, { "lineNumber": 2,
"ruleNames": [ "every-n-lines" ], "ruleNames": [ "every-n-lines" ],
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 2", "errorDetail": "Line number 2",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 4, { "lineNumber": 4,
"ruleNames": [ "every-n-lines" ], "ruleNames": [ "every-n-lines" ],
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 4", "errorDetail": "Line number 4",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 6, { "lineNumber": 6,
"ruleNames": [ "every-n-lines" ], "ruleNames": [ "every-n-lines" ],
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 6", "errorDetail": "Line number 6",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 10, { "lineNumber": 10,
"ruleNames": [ "every-n-lines" ], "ruleNames": [ "every-n-lines" ],
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 10", "errorDetail": "Line number 10",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 12, { "lineNumber": 12,
"ruleNames": [ "every-n-lines" ], "ruleNames": [ "every-n-lines" ],
"ruleDescription": "Rule that reports an error every N lines", "ruleDescription": "Rule that reports an error every N lines",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Line number 12", "errorDetail": "Line number 12",
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 1, { "lineNumber": 1,
"ruleNames": [ "first-line" ], "ruleNames": [ "first-line" ],
"ruleDescription": "Rule that reports an error for the first line", "ruleDescription": "Rule that reports an error for the first line",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": null, "errorDetail": null,
"errorContext": null, "errorContext": null,
"errorRange": null }, "errorRange": null },
{ "lineNumber": 3, { "lineNumber": 3,
"ruleNames": [ "letters-E-X", "letter-E-letter-X", "contains-ex" ], "ruleNames": [ "letters-E-X", "letter-E-letter-X", "contains-ex" ],
"ruleDescription": "ruleDescription":
"Rule that reports an error for lines with the letters 'EX'", "Rule that reports an error for lines with the letters 'EX'",
"ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`, "ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`,
"errorDetail": null, "errorDetail": null,
"errorContext": "text", "errorContext": "text",
"errorRange": null }, "errorRange": null },
{ "lineNumber": 7, { "lineNumber": 7,
"ruleNames": [ "letters-E-X", "letter-E-letter-X", "contains-ex" ], "ruleNames": [ "letters-E-X", "letter-E-letter-X", "contains-ex" ],
"ruleDescription": "ruleDescription":
"Rule that reports an error for lines with the letters 'EX'", "Rule that reports an error for lines with the letters 'EX'",
"ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`, "ruleInformation": `${homepage}/blob/main/test/rules/letters-E-X.js`,
"errorDetail": null, "errorDetail": null,
"errorContext": "text", "errorContext": "text",
"errorRange": null } "errorRange": null }
]; ]
};
t.deepEqual(actualResult, expectedResult, "Undetected issues."); t.deepEqual(actualResult, expectedResult, "Undetected issues.");
// @ts-ignore // @ts-ignore
const actualMessage = actualResult.toString(); const actualMessage = actualResult.toString();
@ -366,13 +369,14 @@ test("customRulesConfig", (t) => new Promise((resolve) => {
}; };
lintAsync(options, function callback(err, actualResult) { lintAsync(options, function callback(err, actualResult) {
t.falsy(err); t.falsy(err);
const expectedResult = {}; const expectedResult = {
expectedResult[customRulesMd] = { [customRulesMd]: {
"any-blockquote-markdown-it": [ 12 ], "any-blockquote-markdown-it": [ 12 ],
"any-blockquote-micromark": [ 12 ], "any-blockquote-micromark": [ 12 ],
"every-n-lines": [ 3, 6, 12 ], "every-n-lines": [ 3, 6, 12 ],
"first-line": [ 1 ], "first-line": [ 1 ],
"letters-E-X": [ 7 ] "letters-E-X": [ 7 ]
}
}; };
t.deepEqual(actualResult, expectedResult, "Undetected issues."); t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve(); resolve();
@ -445,6 +449,7 @@ test("customRulesBadProperty", (t) => {
const { propertyName, propertyValues } = testCase; const { propertyName, propertyValues } = testCase;
for (const propertyValue of propertyValues) { for (const propertyValue of propertyValues) {
const badRule = { ...customRules.firstLine }; const badRule = { ...customRules.firstLine };
// @ts-ignore
badRule[propertyName] = propertyValue; badRule[propertyName] = propertyValue;
/** @type {import("markdownlint").Options} */ /** @type {import("markdownlint").Options} */
const options = { const options = {
@ -1211,6 +1216,7 @@ test("customRulesOnErrorBad", (t) => {
]) { ]) {
const { propertyName, subPropertyName, propertyValues } = testCase; const { propertyName, subPropertyName, propertyValues } = testCase;
for (const propertyValue of propertyValues) { for (const propertyValue of propertyValues) {
/** @type {Object<string, any>} */
const badObject = { const badObject = {
"lineNumber": 1 "lineNumber": 1
}; };
@ -1232,6 +1238,7 @@ test("customRulesOnErrorBad", (t) => {
"tags": [ "tag" ], "tags": [ "tag" ],
"parser": "none", "parser": "none",
"function": function onErrorBad(params, onError) { "function": function onErrorBad(params, onError) {
// @ts-ignore
onError(badObject); onError(badObject);
} }
} }
@ -1283,6 +1290,7 @@ test("customRulesOnErrorInvalid", (t) => {
]) { ]) {
const { propertyName, subPropertyName, propertyValues } = testCase; const { propertyName, subPropertyName, propertyValues } = testCase;
for (const propertyValue of propertyValues) { for (const propertyValue of propertyValues) {
/** @type {Object<string, any>} */
const badObject = { const badObject = {
"lineNumber": 1 "lineNumber": 1
}; };
@ -1304,6 +1312,7 @@ test("customRulesOnErrorInvalid", (t) => {
"tags": [ "tag" ], "tags": [ "tag" ],
"parser": "none", "parser": "none",
"function": function onErrorInvalid(params, onError) { "function": function onErrorInvalid(params, onError) {
// @ts-ignore
onError(badObject); onError(badObject);
} }
} }
@ -1361,6 +1370,7 @@ test("customRulesOnErrorValid", (t) => {
]) { ]) {
const { propertyName, subPropertyName, propertyValues } = testCase; const { propertyName, subPropertyName, propertyValues } = testCase;
for (const propertyValue of propertyValues) { for (const propertyValue of propertyValues) {
/** @type {Object<string, any>} */
const goodObject = { const goodObject = {
"lineNumber": 1 "lineNumber": 1
}; };
@ -1379,6 +1389,7 @@ test("customRulesOnErrorValid", (t) => {
"tags": [ "tag" ], "tags": [ "tag" ],
"parser": "none", "parser": "none",
"function": function onErrorValid(params, onError) { "function": function onErrorValid(params, onError) {
// @ts-ignore
onError(goodObject); onError(goodObject);
} }
} }
@ -1973,13 +1984,62 @@ test("customRulesAsyncThrowsInSyncContext", (t) => {
); );
}); });
test("customRulesParamsConfigExcludesSeverity", (t) => {
t.plan(4);
/** @type {import("markdownlint").Rule} */
const ruleBase = {
"names": [ "tbd" ],
"description": "description",
"tags": [ "tag" ],
"parser": "none",
"asynchronous": true,
"function": ({ config }) => {
t.is(typeof config, "object");
t.is(typeof config.severity, "undefined");
}
};
/** @type {import("markdownlint").Options} */
const options = {
"config": {
"name1": {
"severity": "error"
},
"name2": {
"key": "value",
"severity": "error"
}
},
"customRules": [
{
...ruleBase,
"names": [ "name1" ]
},
{
...ruleBase,
"names": [ "name2" ]
}
],
"strings": {
"string": "Unused"
}
};
return lintPromise(options);
});
test("customRulesParamsAreFrozen", (t) => { test("customRulesParamsAreFrozen", (t) => {
/**
* Asserts that rule parameters are frozen.
*
* @param {import("markdownlint").RuleParams} params Rule parameters.
* @returns {void}
*/
const assertParamsFrozen = (params) => { const assertParamsFrozen = (params) => {
const pending = [ params ]; const pending = [ params ];
let current = null; let current = null;
while ((current = pending.shift())) { while ((current = pending.shift())) {
t.true(Object.isFrozen(current) || (current === params)); t.true(Object.isFrozen(current) || (current === params));
for (const name of Object.getOwnPropertyNames(current)) { for (const name of Object.getOwnPropertyNames(current)) {
// @ts-ignore
const value = current[name]; const value = current[name];
if ( if (
value && value &&

View file

@ -346,17 +346,104 @@ test("enableRulesString", getConfigTestImplementation(
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesEmptyObject", getConfigTestImplementation( test("enableRulesObjectEmpty", getConfigTestImplementation(
{ {
"MD041": {}, "MD041": {},
"default": false, "default": false,
// @ts-ignore
"no-multiple-space-atx": {}, "no-multiple-space-atx": {},
"extra": {} "extra": {}
}, },
configTestExpected3511 configTestExpected3511
)); ));
test("enableRulesObjectTruthy", getConfigTestImplementation(
{
"MD041": {
// @ts-ignore
"severity": 1
},
"default": false,
"no-multiple-space-atx": {
// @ts-ignore
"severity": 1
},
"extra": {
"severity": 1
}
},
configTestExpected3511
));
test("enableRulesObjectFalsy", getConfigTestImplementation(
{
"MD041": {
// @ts-ignore
"severity": 0
},
"default": false,
"no-multiple-space-atx": {
// @ts-ignore
"severity": 0
},
"extra": {
"severity": 0
}
},
configTestExpected3511
));
test("enableRulesObjectError", getConfigTestImplementation(
{
"MD041": {
"severity": "error"
},
"default": false,
"no-multiple-space-atx": {
"severity": "error"
},
"extra": {
"severity": "error"
}
},
configTestExpected3511
));
test("enableRulesObjectWarning", getConfigTestImplementation(
{
"MD041": {
// @ts-ignore
"severity": "warning"
},
"default": false,
"no-multiple-space-atx": {
// @ts-ignore
"severity": "warning"
},
"extra": {
"severity": "warning"
}
},
configTestExpected3511
));
test("enableRulesObjectOff", getConfigTestImplementation(
{
"MD041": {
// @ts-ignore
"severity": "off"
},
"default": false,
"no-multiple-space-atx": {
// @ts-ignore
"severity": "off"
},
"extra": {
"severity": "off"
}
},
configTestExpected3511
));
test("disableTag", getConfigTestImplementation( test("disableTag", getConfigTestImplementation(
{ {
"default": true, "default": true,
@ -921,7 +1008,7 @@ test("readme", async(t) => {
}); });
test("validateJsonUsingConfigSchemaStrict", async(t) => { test("validateJsonUsingConfigSchemaStrict", async(t) => {
t.plan(211); t.plan(212);
// @ts-ignore // @ts-ignore
const ajv = new Ajv(ajvOptions); const ajv = new Ajv(ajvOptions);
const validateSchemaStrict = ajv.compile(configSchemaStrict); const validateSchemaStrict = ajv.compile(configSchemaStrict);

View file

@ -11203,6 +11203,320 @@ Generated by [AVA](https://avajs.dev).
`, `,
} }
## configure-file-with-severity.md
> Snapshot 1
{
errors: [
{
errorContext: null,
errorDetail: 'Expected: dash; Actual: plus',
errorRange: [
1,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '-',
},
lineNumber: 9,
ruleDescription: 'Unordered list style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md004.md',
ruleNames: [
'MD004',
'ul-style',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: 'Expected: dash; Actual: plus',
errorRange: [
1,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '-',
},
lineNumber: 37,
ruleDescription: 'Unordered list style',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md004.md',
ruleNames: [
'MD004',
'ul-style',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 11,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: '(text)[.]',
errorRange: [
6,
9,
],
fixInfo: {
deleteCount: 9,
editColumn: 6,
insertText: '[text](.)',
},
lineNumber: 39,
ruleDescription: 'Reversed link syntax',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md011.md',
ruleNames: [
'MD011',
'no-reversed-links',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: 'Expected: 1; Actual: 2; Style: 1/1/1',
errorRange: [
1,
3,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '1',
},
lineNumber: 13,
ruleDescription: 'Ordered list item prefix',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md029.md',
ruleNames: [
'MD029',
'ol-prefix',
],
severity: 'error',
},
{
errorContext: null,
errorDetail: 'Expected: 1; Actual: 2; Style: 1/1/1',
errorRange: [
1,
3,
],
fixInfo: {
deleteCount: 1,
editColumn: 1,
insertText: '1',
},
lineNumber: 41,
ruleDescription: 'Ordered list item prefix',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md029.md',
ruleNames: [
'MD029',
'ol-prefix',
],
severity: 'error',
},
{
errorContext: '* t',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 3,
ruleDescription: 'Spaces inside emphasis markers',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md037.md',
ruleNames: [
'MD037',
'no-space-in-emphasis',
],
severity: 'error',
},
{
errorContext: '* t',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 31,
ruleDescription: 'Spaces inside emphasis markers',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md037.md',
ruleNames: [
'MD037',
'no-space-in-emphasis',
],
severity: 'error',
},
{
errorContext: '` text`',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 5,
ruleDescription: 'Spaces inside code span elements',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md038.md',
ruleNames: [
'MD038',
'no-space-in-code',
],
severity: 'error',
},
{
errorContext: '` text`',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 33,
ruleDescription: 'Spaces inside code span elements',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md038.md',
ruleNames: [
'MD038',
'no-space-in-code',
],
severity: 'error',
},
{
errorContext: '[ text]',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 7,
ruleDescription: 'Spaces inside link text',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md039.md',
ruleNames: [
'MD039',
'no-space-in-links',
],
severity: 'error',
},
{
errorContext: '[ text]',
errorDetail: null,
errorRange: [
7,
1,
],
fixInfo: {
deleteCount: 1,
editColumn: 7,
},
lineNumber: 35,
ruleDescription: 'Spaces inside link text',
ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md039.md',
ruleNames: [
'MD039',
'no-space-in-links',
],
severity: 'error',
},
],
fixed: `# Configure File With Severity␊
Text *text* {MD037}␊
Text \`text\` {MD038}␊
Text [text](.) {MD039}␊
- List item {MD004}␊
Text [text](.) {MD011}␊
1. List item {MD029}␊
<!-- markdownlint-disable -->
Text * text*
Text \` text\`␊
Text [ text](.)␊
+ List item␊
Text (text)[.]␊
2. List item␊
<!-- markdownlint-restore -->
Text *text* {MD037}␊
Text \`text\` {MD038}␊
Text [text](.) {MD039}␊
- List item {MD004}␊
Text [text](.) {MD011}␊
1. List item {MD029}␊
<!-- markdownlint-configure-file {␊
"default": false,␊
"MD037": "error",␊
"MD038": "error",␊
"MD039": "error",␊
"MD004": {␊
"severity": "error",␊
"style": "dash"␊
},␊
"MD011": {␊
"severity": "error"␊
},␊
"MD029": {␊
"severity": "error"␊
}␊
} -->␊
`,
}
## consecutive_blank_lines.md ## consecutive_blank_lines.md
> Snapshot 1 > Snapshot 1