2020-09-12 12:11:14 -07:00
|
|
|
// @ts-check
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2022-08-16 04:01:53 +00:00
|
|
|
const fs = require("node:fs").promises;
|
|
|
|
const path = require("node:path");
|
2021-01-10 20:46:00 -08:00
|
|
|
const test = require("ava").default;
|
2022-05-10 06:11:46 +00:00
|
|
|
const { markdownlint } = require("../lib/markdownlint").promises;
|
2020-09-12 12:11:14 -07:00
|
|
|
const helpers = require("../helpers");
|
2022-10-29 23:21:45 -07:00
|
|
|
const constants = require("../lib/constants");
|
2020-09-12 12:11:14 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a test function for the specified test file.
|
|
|
|
*
|
|
|
|
* @param {string} file Test file relative path.
|
|
|
|
* @returns {Function} Test function.
|
|
|
|
*/
|
|
|
|
function createTestForFile(file) {
|
2023-03-15 21:26:22 -07:00
|
|
|
return (t) => (
|
|
|
|
// Read and lint Markdown test file
|
|
|
|
Promise.all([
|
|
|
|
fs.readFile(file, "utf8"),
|
|
|
|
markdownlint({
|
|
|
|
"files": [ file ]
|
|
|
|
})
|
|
|
|
])
|
2022-05-10 06:11:46 +00:00
|
|
|
// Compare expected results and snapshot
|
|
|
|
.then((params) => {
|
2023-03-15 21:26:22 -07:00
|
|
|
const [ content, results ] = params;
|
2022-05-10 06:11:46 +00:00
|
|
|
// Canonicalize version number
|
2022-06-08 22:10:27 -07:00
|
|
|
const errors = results[file]
|
|
|
|
.filter((error) => !!error.ruleInformation);
|
|
|
|
for (const error of errors) {
|
|
|
|
error.ruleInformation =
|
2022-05-10 06:11:46 +00:00
|
|
|
error.ruleInformation.replace(/v\d+\.\d+\.\d+/, "v0.0.0");
|
2022-06-08 22:10:27 -07:00
|
|
|
}
|
2022-05-10 06:11:46 +00:00
|
|
|
// Match identified issues by MD### markers
|
|
|
|
const marker = /\{(MD\d+)(?::(\d+))?\}/g;
|
|
|
|
const lines = content.split(helpers.newLineRe);
|
|
|
|
const expected = {};
|
2022-06-08 22:10:27 -07:00
|
|
|
// @ts-ignore
|
|
|
|
for (const [ index, line ] of lines.entries()) {
|
2022-05-10 06:11:46 +00:00
|
|
|
let match = null;
|
|
|
|
while ((match = marker.exec(line))) {
|
|
|
|
const rule = match[1];
|
|
|
|
// eslint-disable-next-line no-multi-assign
|
|
|
|
const indices = expected[rule] = expected[rule] || [];
|
2023-03-15 21:26:22 -07:00
|
|
|
const lineNumber =
|
|
|
|
match[2] ? Number.parseInt(match[2], 10) : index + 1;
|
|
|
|
if (!indices.includes(lineNumber)) {
|
|
|
|
indices.push(lineNumber);
|
|
|
|
}
|
2022-05-10 06:11:46 +00:00
|
|
|
}
|
2022-06-08 22:10:27 -07:00
|
|
|
}
|
2022-10-15 16:06:20 -07:00
|
|
|
const actual = {};
|
|
|
|
for (const error of errors) {
|
|
|
|
const rule = error.ruleNames[0];
|
|
|
|
// eslint-disable-next-line no-multi-assign
|
|
|
|
const indices = actual[rule] = actual[rule] || [];
|
|
|
|
if (indices[indices.length - 1] !== error.lineNumber) {
|
|
|
|
indices.push(error.lineNumber);
|
2022-06-08 22:10:27 -07:00
|
|
|
}
|
2022-10-29 23:21:45 -07:00
|
|
|
t.true(
|
|
|
|
!error.fixInfo || constants.fixableRuleNames.includes(rule),
|
|
|
|
`Fixable rule ${rule} is not tagged as such.`
|
|
|
|
);
|
2020-09-12 12:11:14 -07:00
|
|
|
}
|
2022-10-15 16:06:20 -07:00
|
|
|
t.deepEqual(actual, expected, "Too few or too many issues found.");
|
2022-05-10 06:11:46 +00:00
|
|
|
// Create snapshot
|
|
|
|
const fixed = helpers.applyFixes(content, errors)
|
|
|
|
.replace(/\r\n/g, "\n");
|
|
|
|
t.snapshot({
|
|
|
|
errors,
|
|
|
|
fixed
|
|
|
|
});
|
2022-05-11 06:07:43 +00:00
|
|
|
// Identify missing fixes
|
2022-05-10 06:11:46 +00:00
|
|
|
return markdownlint({
|
|
|
|
"strings": {
|
|
|
|
"input": fixed
|
2023-03-15 21:26:22 -07:00
|
|
|
}
|
2022-05-11 06:07:43 +00:00
|
|
|
}).then((fixedResults) => {
|
|
|
|
const unfixed = fixedResults.input.filter((error) => !!error.fixInfo);
|
2022-05-10 06:11:46 +00:00
|
|
|
t.deepEqual(unfixed, [], "Fixable error(s) not fixed.");
|
|
|
|
});
|
|
|
|
})
|
2020-09-12 12:11:14 -07:00
|
|
|
.catch()
|
2023-03-15 21:26:22 -07:00
|
|
|
.then(t.done)
|
|
|
|
);
|
2020-09-12 12:11:14 -07:00
|
|
|
}
|
|
|
|
|
2022-08-16 04:01:53 +00:00
|
|
|
const files = require("node:fs")
|
2022-06-08 22:10:27 -07:00
|
|
|
.readdirSync("./test")
|
|
|
|
.filter((file) => /\.md$/.test(file));
|
|
|
|
for (const file of files) {
|
2020-09-12 12:11:14 -07:00
|
|
|
// @ts-ignore
|
2022-06-08 22:10:27 -07:00
|
|
|
test(
|
2022-05-10 06:11:46 +00:00
|
|
|
file,
|
|
|
|
createTestForFile(path.join("./test", file))
|
2022-06-08 22:10:27 -07:00
|
|
|
);
|
|
|
|
}
|