This commit is contained in:
David Anson 2025-09-15 22:24:06 -07:00
parent e857672728
commit 56cde85f72
5 changed files with 737 additions and 286 deletions

View file

@ -1281,97 +1281,97 @@ export interface ConfigurationStrict {
/**
* headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043
*/
headings?: boolean;
headings?: boolean | "error";
/**
* bullet : MD004, MD005, MD007, MD032
*/
bullet?: boolean;
bullet?: boolean | "error";
/**
* ul : MD004, MD005, MD007, MD030, MD032
*/
ul?: boolean;
ul?: boolean | "error";
/**
* indentation : MD005, MD007, MD027
*/
indentation?: boolean;
indentation?: boolean | "error";
/**
* whitespace : MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039
*/
whitespace?: boolean;
whitespace?: boolean | "error";
/**
* hard_tab : MD010
*/
hard_tab?: boolean;
hard_tab?: boolean | "error";
/**
* links : MD011, MD034, MD039, MD042, MD051, MD052, MD053, MD054, MD059
*/
links?: boolean;
links?: boolean | "error";
/**
* blank_lines : MD012, MD022, MD031, MD032, MD047
*/
blank_lines?: boolean;
blank_lines?: boolean | "error";
/**
* line_length : MD013
*/
line_length?: boolean;
line_length?: boolean | "error";
/**
* code : MD014, MD031, MD038, MD040, MD046, MD048
*/
code?: boolean;
code?: boolean | "error";
/**
* atx : MD018, MD019
*/
atx?: boolean;
atx?: boolean | "error";
/**
* spaces : MD018, MD019, MD020, MD021, MD023
*/
spaces?: boolean;
spaces?: boolean | "error";
/**
* atx_closed : MD020, MD021
*/
atx_closed?: boolean;
atx_closed?: boolean | "error";
/**
* blockquote : MD027, MD028
*/
blockquote?: boolean;
blockquote?: boolean | "error";
/**
* ol : MD029, MD030, MD032
*/
ol?: boolean;
ol?: boolean | "error";
/**
* html : MD033
*/
html?: boolean;
html?: boolean | "error";
/**
* url : MD034
*/
url?: boolean;
url?: boolean | "error";
/**
* hr : MD035
*/
hr?: boolean;
hr?: boolean | "error";
/**
* emphasis : MD036, MD037, MD049, MD050
*/
emphasis?: boolean;
emphasis?: boolean | "error";
/**
* language : MD040
*/
language?: boolean;
language?: boolean | "error";
/**
* spelling : MD044
*/
spelling?: boolean;
spelling?: boolean | "error";
/**
* accessibility : MD045, MD059
*/
accessibility?: boolean;
accessibility?: boolean | "error";
/**
* images : MD045, MD052, MD053, MD054
*/
images?: boolean;
images?: boolean | "error";
/**
* table : MD055, MD056, MD058, MD060
*/
table?: boolean;
table?: boolean | "error";
}

View file

@ -652,7 +652,10 @@ for (const rule of rules) {
for (const [ tag, tagTags ] of Object.entries(tags)) {
const scheme = {
"description": `${tag} : ${tagTags.join(", ")}`,
"type": "boolean",
"oneOf": [
{ "type": "boolean" },
{ "enum": [ "error" ] }
],
"default": true
};
schema.properties[tag] = scheme;

View file

@ -2896,122 +2896,338 @@
},
"headings": {
"description": "headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"bullet": {
"description": "bullet : MD004, MD005, MD007, MD032",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"ul": {
"description": "ul : MD004, MD005, MD007, MD030, MD032",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"indentation": {
"description": "indentation : MD005, MD007, MD027",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"whitespace": {
"description": "whitespace : MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"hard_tab": {
"description": "hard_tab : MD010",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"links": {
"description": "links : MD011, MD034, MD039, MD042, MD051, MD052, MD053, MD054, MD059",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"blank_lines": {
"description": "blank_lines : MD012, MD022, MD031, MD032, MD047",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"line_length": {
"description": "line_length : MD013",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"code": {
"description": "code : MD014, MD031, MD038, MD040, MD046, MD048",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"atx": {
"description": "atx : MD018, MD019",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"spaces": {
"description": "spaces : MD018, MD019, MD020, MD021, MD023",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"atx_closed": {
"description": "atx_closed : MD020, MD021",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"blockquote": {
"description": "blockquote : MD027, MD028",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"ol": {
"description": "ol : MD029, MD030, MD032",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"html": {
"description": "html : MD033",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"url": {
"description": "url : MD034",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"hr": {
"description": "hr : MD035",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"emphasis": {
"description": "emphasis : MD036, MD037, MD049, MD050",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"language": {
"description": "language : MD040",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"spelling": {
"description": "spelling : MD044",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"accessibility": {
"description": "accessibility : MD045, MD059",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"images": {
"description": "images : MD045, MD052, MD053, MD054",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"table": {
"description": "table : MD055, MD056, MD058, MD060",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
}
},

View file

@ -2896,122 +2896,338 @@
},
"headings": {
"description": "headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"bullet": {
"description": "bullet : MD004, MD005, MD007, MD032",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"ul": {
"description": "ul : MD004, MD005, MD007, MD030, MD032",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"indentation": {
"description": "indentation : MD005, MD007, MD027",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"whitespace": {
"description": "whitespace : MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"hard_tab": {
"description": "hard_tab : MD010",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"links": {
"description": "links : MD011, MD034, MD039, MD042, MD051, MD052, MD053, MD054, MD059",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"blank_lines": {
"description": "blank_lines : MD012, MD022, MD031, MD032, MD047",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"line_length": {
"description": "line_length : MD013",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"code": {
"description": "code : MD014, MD031, MD038, MD040, MD046, MD048",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"atx": {
"description": "atx : MD018, MD019",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"spaces": {
"description": "spaces : MD018, MD019, MD020, MD021, MD023",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"atx_closed": {
"description": "atx_closed : MD020, MD021",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"blockquote": {
"description": "blockquote : MD027, MD028",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"ol": {
"description": "ol : MD029, MD030, MD032",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"html": {
"description": "html : MD033",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"url": {
"description": "url : MD034",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"hr": {
"description": "hr : MD035",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"emphasis": {
"description": "emphasis : MD036, MD037, MD049, MD050",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"language": {
"description": "language : MD040",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"spelling": {
"description": "spelling : MD044",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"accessibility": {
"description": "accessibility : MD045, MD059",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"images": {
"description": "images : MD045, MD052, MD053, MD054",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
},
"table": {
"description": "table : MD055, MD056, MD058, MD060",
"type": "boolean",
"oneOf": [
{
"type": "boolean"
},
{
"enum": [
"error"
]
}
],
"default": true
}
},

View file

@ -159,7 +159,7 @@ function normalizeLintResults(results) {
Object.entries(results).map(
([ source, errors ]) => [
source, errors.map(
({ lineNumber, ruleNames }) => `${ruleNames[0]} ${lineNumber}`
({ lineNumber, ruleNames, severity }) => `${ruleNames[0]} ${lineNumber} ${severity}`
)
]
)
@ -167,257 +167,273 @@ function normalizeLintResults(results) {
}
/**
* Gets a Configuration default value test implementation.
* Gets a Configuration value test implementation.
*
* @param {(config: Configuration) => void} setDefault Sets the value of the Configuration default value.
* @param {Configuration} config Configuration object.
* @param {string[]} files List of files.
* @param {NormalizedLintResults} expected Expected result.
* @returns {ImplementationFn} Test implementation.
*/
function getConfigDefaultTestImplementation(setDefault, expected) {
function getConfigTestImplementation(config, files, expected) {
return async(t) => {
t.plan(1);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
],
"config": {},
config,
files,
"noInlineConfig": true
};
setDefault(options.config);
const actual = await lintPromise(options);
t.deepEqual(normalizeLintResults(actual), expected);
};
}
const configDefaultTestExpectedEnabled = {
"./test/atx_heading_spacing.md": [
"MD018 1",
"MD019 3",
"MD019 5",
"MD041 1"
],
"./test/first_heading_bad_atx.md": [
"MD041 1"
]
};
const configDefaultTestExpectedDisabled = {
const configTestFiles = [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
];
const configTestExpected = {
"./test/atx_heading_spacing.md": [],
"./test/first_heading_bad_atx.md": []
};
test("defaultTrue", getConfigDefaultTestImplementation(
(config) => (config.default = true),
configDefaultTestExpectedEnabled
));
test("defaultFalse", getConfigDefaultTestImplementation(
(config) => (config.default = false),
configDefaultTestExpectedDisabled
));
test("defaultError", getConfigDefaultTestImplementation(
(config) => (config.default = "error"),
configDefaultTestExpectedEnabled
));
test("defaultWarning", getConfigDefaultTestImplementation(
// @ts-ignore
(config) => (config.default = "warning"),
configDefaultTestExpectedEnabled
));
test("defaultOff", getConfigDefaultTestImplementation(
// @ts-ignore
(config) => (config.default = "off"),
configDefaultTestExpectedEnabled
));
test("defaultUnset", getConfigDefaultTestImplementation(
() => {},
configDefaultTestExpectedEnabled
));
test("disableRules", (t) => new Promise((resolve) => {
t.plan(2);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/no_first_line_heading.md"
const configTestExpected1 = {
"./test/atx_heading_spacing.md": [
"MD018 1 error"
],
"config": {
"./test/first_heading_bad_atx.md": []
};
const configTestExpected11 = {
"./test/atx_heading_spacing.md": [
"MD041 1 error"
],
"./test/first_heading_bad_atx.md": [
"MD041 1 error"
]
};
const configTestExpected135 = {
"./test/atx_heading_spacing.md": [
"MD018 1 error",
"MD019 3 error",
"MD019 5 error"
],
"./test/first_heading_bad_atx.md": []
};
const configTestExpected3511 = {
"./test/atx_heading_spacing.md": [
"MD019 3 error",
"MD019 5 error",
"MD041 1 error"
],
"./test/first_heading_bad_atx.md": [
"MD041 1 error"
]
};
const configTestExpected13511 = {
"./test/atx_heading_spacing.md": [
"MD018 1 error",
"MD019 3 error",
"MD019 5 error",
"MD041 1 error"
],
"./test/first_heading_bad_atx.md": [
"MD041 1 error"
]
};
test("defaultUnset", getConfigTestImplementation(
{},
configTestFiles,
configTestExpected13511
));
test("defaultTrue", getConfigTestImplementation(
{ "default": true },
configTestFiles,
configTestExpected13511
));
test("defaultFalse", getConfigTestImplementation(
{ "default": false },
configTestFiles,
configTestExpected
));
test("defaultTruthy", getConfigTestImplementation(
// @ts-ignore
{ "default": 1 },
configTestFiles,
configTestExpected13511
));
test("defaultFalsy", getConfigTestImplementation(
// @ts-ignore
{ "default": 0 },
configTestFiles,
configTestExpected
));
test("defaultError", getConfigTestImplementation(
{ "default": "error" },
configTestFiles,
configTestExpected13511
));
test("defaultWarning", getConfigTestImplementation(
// @ts-ignore
{ "default": "warning" },
configTestFiles,
configTestExpected13511
));
test("defaultOff", getConfigTestImplementation(
// @ts-ignore
{ "default": "off" },
configTestFiles,
configTestExpected13511
));
test("disableRules", getConfigTestImplementation(
{
"default": true,
"MD019": false,
"first-line-h1": false
"first-line-h1": false,
"extra": false
},
"resultVersion": 0
};
lintAsync(options, function callback(err, actualResult) {
t.falsy(err);
const expectedResult = {
"./test/atx_heading_spacing.md": {
"MD018": [ 1 ]
},
"./test/no_first_line_heading.md": {}
};
// @ts-ignore
t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve();
});
}));
configTestFiles,
configTestExpected1
));
test("enableRules", (t) => new Promise((resolve) => {
t.plan(2);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
],
"config": {
test("disableRulesFalsy", getConfigTestImplementation(
{
"default": true,
// @ts-ignore
"MD019": 0,
// @ts-ignore
"first-line-h1": 0,
"extra": 0
},
configTestFiles,
configTestExpected1
));
test("enableRules", getConfigTestImplementation(
{
"MD041": true,
"default": false,
"no-multiple-space-atx": true
"no-multiple-space-atx": true,
"extra": true
},
"noInlineConfig": true,
"resultVersion": 0
};
lintAsync(options, function callback(err, actualResult) {
t.falsy(err);
const expectedResult = {
"./test/atx_heading_spacing.md": {
"MD019": [ 3, 5 ],
"MD041": [ 1 ]
},
"./test/first_heading_bad_atx.md": {
"MD041": [ 1 ]
}
};
// @ts-ignore
t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve();
});
}));
configTestFiles,
configTestExpected3511
));
test("enableRulesMixedCase", (t) => new Promise((resolve) => {
t.plan(2);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
],
"config": {
test("enableRulesMixedCase", getConfigTestImplementation(
{
"Md041": true,
"DeFaUlT": false,
"nO-mUlTiPlE-sPaCe-AtX": true
"nO-mUlTiPlE-sPaCe-AtX": true,
"ExTrA": true
},
"noInlineConfig": true,
"resultVersion": 0
};
lintAsync(options, function callback(err, actualResult) {
t.falsy(err);
const expectedResult = {
"./test/atx_heading_spacing.md": {
"MD019": [ 3, 5 ],
"MD041": [ 1 ]
},
"./test/first_heading_bad_atx.md": {
"MD041": [ 1 ]
}
};
// @ts-ignore
t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve();
});
}));
configTestFiles,
configTestExpected3511
));
test("disableTag", (t) => new Promise((resolve) => {
t.plan(2);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
],
"config": {
test("enableRulesTruthy", getConfigTestImplementation(
{
// @ts-ignore
"MD041": 1,
"default": false,
// @ts-ignore
"no-multiple-space-atx": 1,
"extra": 1
},
configTestFiles,
configTestExpected3511
));
test("enableRulesString", getConfigTestImplementation(
{
"MD041": "error",
"default": false,
"no-multiple-space-atx": "error",
"extra": "error"
},
configTestFiles,
configTestExpected3511
));
test("enableRulesEmptyObject", getConfigTestImplementation(
{
"MD041": {},
"default": false,
// @ts-ignore
"no-multiple-space-atx": {},
"extra": {}
},
configTestFiles,
configTestExpected3511
));
test("disableTag", getConfigTestImplementation(
{
"default": true,
"spaces": false
"spaces": false,
"extra": false
},
"noInlineConfig": true,
"resultVersion": 0
};
lintAsync(options, function callback(err, actualResult) {
t.falsy(err);
const expectedResult = {
"./test/atx_heading_spacing.md": {
"MD041": [ 1 ]
},
"./test/first_heading_bad_atx.md": {
"MD041": [ 1 ]
}
};
// @ts-ignore
t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve();
});
}));
configTestFiles,
configTestExpected11
));
test("enableTag", (t) => new Promise((resolve) => {
t.plan(2);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
],
"config": {
test("disableTagFalsy", getConfigTestImplementation(
{
"default": true,
// @ts-ignore
"spaces": 0,
"extra": 0
},
configTestFiles,
configTestExpected11
));
test("enableTag", getConfigTestImplementation(
{
"default": false,
"spaces": true,
"notatag": true
"extra": true
},
"resultVersion": 0
};
lintAsync(options, function callback(err, actualResult) {
t.falsy(err);
const expectedResult = {
"./test/atx_heading_spacing.md": {
"MD018": [ 1 ],
"MD019": [ 3, 5 ]
},
"./test/first_heading_bad_atx.md": {}
};
// @ts-ignore
t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve();
});
}));
configTestFiles,
configTestExpected135
));
test("enableTagMixedCase", (t) => new Promise((resolve) => {
t.plan(2);
const options = {
"files": [
"./test/atx_heading_spacing.md",
"./test/first_heading_bad_atx.md"
],
"config": {
test("enableTagMixedCase", getConfigTestImplementation(
{
"DeFaUlT": false,
"SpAcEs": true,
"NoTaTaG": true
"ExTrA": true
},
"resultVersion": 0
};
lintAsync(options, function callback(err, actualResult) {
t.falsy(err);
const expectedResult = {
"./test/atx_heading_spacing.md": {
"MD018": [ 1 ],
"MD019": [ 3, 5 ]
},
"./test/first_heading_bad_atx.md": {}
};
configTestFiles,
configTestExpected135
));
test("enableTagTruthy", getConfigTestImplementation(
{
"default": false,
// @ts-ignore
t.deepEqual(actualResult, expectedResult, "Undetected issues.");
resolve();
});
}));
"spaces": 1,
"extra": 1
},
configTestFiles,
configTestExpected135
));
test("enableTagString", getConfigTestImplementation(
{
"default": false,
"spaces": "error",
"extra": "error"
},
configTestFiles,
configTestExpected135
));
test("styleFiles", async(t) => {
t.plan(8);