2024-12-03 19:58:28 -08:00
|
|
|
// Attempt to validate important type declarations
|
2019-11-10 19:26:55 -08:00
|
|
|
|
2024-12-03 19:58:28 -08:00
|
|
|
import { Configuration, ConfigurationStrict, LintResults, Options, Rule, RuleParams, RuleOnError, RuleOnErrorInfo } from "../../lib/exports.mjs";
|
|
|
|
import { applyFix, applyFixes, getVersion } from "../../lib/exports.mjs";
|
|
|
|
import { lint as lintAsync, readConfig as readConfigAsync } from "../../lib/exports-async.mjs";
|
|
|
|
import { lint as lintPromise, readConfig as readConfigPromise } from "../../lib/exports-promise.mjs";
|
|
|
|
import { lint as lintSync, readConfig as readConfigSync } from "../../lib/exports-sync.mjs";
|
2019-11-10 19:26:55 -08:00
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
import assert from "assert";
|
2024-12-25 20:42:32 -08:00
|
|
|
import markdownIt from "markdown-it";
|
2019-11-10 19:26:55 -08:00
|
|
|
const markdownlintJsonPath = "../../.markdownlint.json";
|
|
|
|
|
2024-12-03 19:58:28 -08:00
|
|
|
const version: string = getVersion();
|
2020-10-17 14:17:35 -07:00
|
|
|
assert(/^\d+\.\d+\.\d+$/.test(version));
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
function assertConfiguration(config: Configuration) {
|
2019-11-10 19:26:55 -08:00
|
|
|
assert(!!config);
|
2022-12-23 23:12:50 +00:00
|
|
|
assert.deepEqual(config["line-length"], { "strict": true, "code_blocks": false });
|
2019-11-10 19:26:55 -08:00
|
|
|
// config assignment is covered by markdownlint.Options
|
|
|
|
}
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
function assertConfigurationCallback(err: Error | null, config?: Configuration) {
|
2019-11-10 19:26:55 -08:00
|
|
|
assert(!err);
|
|
|
|
config && assertConfiguration(config);
|
|
|
|
}
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
function assertLintResults(results: LintResults) {
|
2019-11-10 19:26:55 -08:00
|
|
|
assert(!!results);
|
|
|
|
assert.equal(results["string"].length, 1);
|
|
|
|
assert.equal(results["string"][0].lineNumber, 1);
|
|
|
|
assert.deepEqual(results["string"][0].ruleNames, [ "MD047", "single-trailing-newline" ]);
|
|
|
|
assert.equal(results["string"][0].ruleDescription, "Files should end with a single newline character");
|
2022-10-30 14:58:45 -07:00
|
|
|
assert.equal(results["string"][0].ruleInformation.replace(/v\d+\.\d+\.\d+/, "v0.0.0"), "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md047.md");
|
2019-11-10 19:26:55 -08:00
|
|
|
assert.equal(results["string"][0].errorDetail, null);
|
|
|
|
assert.equal(results["string"][0].errorContext, null);
|
|
|
|
assert.deepEqual(results["string"][0].errorRange, [ 9, 1 ]);
|
2021-06-14 22:30:35 -07:00
|
|
|
const fixInfo = results["string"][0].fixInfo;
|
|
|
|
assert(!!fixInfo);
|
|
|
|
if (fixInfo) {
|
|
|
|
assert.equal(fixInfo.lineNumber, null);
|
|
|
|
assert.equal(fixInfo.editColumn, 10);
|
|
|
|
assert(!fixInfo.deleteCount);
|
|
|
|
assert.equal(fixInfo.insertText, "\n");
|
|
|
|
}
|
2019-11-10 19:26:55 -08:00
|
|
|
assert.equal(results["../bad.md"].length, 2);
|
2020-10-02 13:33:05 -07:00
|
|
|
// Deliberate assignment to unused variable validates types
|
|
|
|
// False-positive for js/useless-assignment-to-local
|
2019-11-10 19:26:55 -08:00
|
|
|
results = {
|
|
|
|
"key": [
|
|
|
|
{
|
|
|
|
"lineNumber": 1,
|
|
|
|
"ruleNames": [ "rule", "names" ],
|
|
|
|
"ruleDescription": "description",
|
|
|
|
"ruleInformation": "https://example.com/ruleInformation",
|
|
|
|
"errorDetail": "detail",
|
|
|
|
"errorContext": "context",
|
|
|
|
"errorRange": [ 1, 2 ],
|
|
|
|
"fixInfo": {
|
|
|
|
"editColumn": 1,
|
|
|
|
"deleteCount": 1,
|
|
|
|
"insertText": "text"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
function assertLintResultsCallback(err: Error | null, results?: LintResults) {
|
2019-11-10 19:26:55 -08:00
|
|
|
assert(!err);
|
|
|
|
results && assertLintResults(results);
|
|
|
|
}
|
|
|
|
|
2024-12-03 19:58:28 -08:00
|
|
|
assertConfiguration(readConfigSync(markdownlintJsonPath));
|
|
|
|
assertConfiguration(readConfigSync(markdownlintJsonPath, [ JSON.parse ]));
|
2019-11-10 19:26:55 -08:00
|
|
|
|
2024-12-03 19:58:28 -08:00
|
|
|
readConfigAsync(markdownlintJsonPath, assertConfigurationCallback);
|
|
|
|
readConfigAsync(markdownlintJsonPath, [ JSON.parse ], assertConfigurationCallback);
|
2019-11-10 19:26:55 -08:00
|
|
|
|
2020-09-13 12:58:09 -07:00
|
|
|
(async () => {
|
2024-12-03 19:58:28 -08:00
|
|
|
assertConfigurationCallback(null, await readConfigPromise(markdownlintJsonPath));
|
|
|
|
assertConfigurationCallback(null, await readConfigPromise(markdownlintJsonPath, [ JSON.parse ]))
|
2020-09-13 12:58:09 -07:00
|
|
|
})();
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
let options: Options;
|
2019-11-10 19:26:55 -08:00
|
|
|
options = {
|
|
|
|
"files": [ "../bad.md" ],
|
|
|
|
"strings": {
|
|
|
|
"string": "# Heading"
|
|
|
|
},
|
|
|
|
"config": {
|
|
|
|
"no-missing-space-atx": false,
|
|
|
|
"no-hard-tabs": {
|
|
|
|
"code_blocks": true
|
|
|
|
}
|
|
|
|
},
|
2022-06-05 22:32:22 -07:00
|
|
|
"configParsers": [ JSON.parse ],
|
2019-11-10 19:26:55 -08:00
|
|
|
"customRules": undefined,
|
|
|
|
"frontMatter": /---/,
|
|
|
|
"handleRuleFailures": false,
|
|
|
|
"noInlineConfig": false,
|
2024-12-27 21:22:14 -08:00
|
|
|
"markdownItFactory": () => markdownIt()
|
2019-11-10 19:26:55 -08:00
|
|
|
};
|
|
|
|
|
2024-12-03 19:58:28 -08:00
|
|
|
assertLintResults(lintSync(options));
|
|
|
|
lintAsync(options, assertLintResultsCallback);
|
2020-09-13 12:58:09 -07:00
|
|
|
(async () => {
|
2024-12-03 19:58:28 -08:00
|
|
|
assertLintResultsCallback(null, await lintPromise(options));
|
2020-09-13 12:58:09 -07:00
|
|
|
})();
|
2019-11-10 19:26:55 -08:00
|
|
|
|
|
|
|
options.files = "../bad.md";
|
2024-12-03 19:58:28 -08:00
|
|
|
assertLintResults(lintSync(options));
|
|
|
|
lintAsync(options, assertLintResultsCallback);
|
2020-09-13 12:58:09 -07:00
|
|
|
(async () => {
|
2024-12-03 19:58:28 -08:00
|
|
|
assertLintResultsCallback(null, await lintPromise(options));
|
2020-09-13 12:58:09 -07:00
|
|
|
})();
|
2019-11-10 19:26:55 -08:00
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
const testRule: Rule = {
|
2019-11-10 19:26:55 -08:00
|
|
|
"names": [ "test-rule" ],
|
|
|
|
"description": "Test rule",
|
2023-07-11 21:44:45 -07:00
|
|
|
"information": new URL("https://example.com/rule-information"),
|
2019-11-10 19:26:55 -08:00
|
|
|
"tags": [ "test-tag" ],
|
2024-03-09 16:17:50 -08:00
|
|
|
"parser": "none",
|
2024-11-28 20:36:44 -08:00
|
|
|
"function": function rule(params: RuleParams, onError: RuleOnError) {
|
2019-11-10 19:26:55 -08:00
|
|
|
assert(!!params);
|
|
|
|
assert(!!onError);
|
2024-11-28 20:36:44 -08:00
|
|
|
let ruleParams: RuleParams;
|
2019-11-10 19:26:55 -08:00
|
|
|
ruleParams = {
|
|
|
|
"name": "name",
|
2024-02-27 20:42:09 -08:00
|
|
|
"parsers": {
|
|
|
|
"markdownit": {
|
2024-03-07 21:14:08 -08:00
|
|
|
"tokens": []
|
2024-03-09 16:17:50 -08:00
|
|
|
},
|
|
|
|
"micromark": {
|
|
|
|
"tokens": []
|
2024-02-27 20:42:09 -08:00
|
|
|
}
|
|
|
|
},
|
2019-11-10 19:26:55 -08:00
|
|
|
"lines": [
|
|
|
|
"one",
|
|
|
|
"two"
|
|
|
|
],
|
|
|
|
"frontMatterLines": [
|
|
|
|
"three"
|
|
|
|
],
|
2024-09-29 18:11:41 -07:00
|
|
|
"config": options.config,
|
|
|
|
"version": "1.2.3"
|
2019-11-10 19:26:55 -08:00
|
|
|
};
|
|
|
|
assert(ruleParams);
|
2024-11-28 20:36:44 -08:00
|
|
|
let ruleOnErrorInfo: RuleOnErrorInfo;
|
2019-11-10 19:26:55 -08:00
|
|
|
ruleOnErrorInfo = {
|
|
|
|
"lineNumber": 1,
|
2021-09-25 16:23:37 -07:00
|
|
|
"detail": "detail",
|
2019-11-10 19:26:55 -08:00
|
|
|
"context": "context",
|
2023-07-11 21:44:45 -07:00
|
|
|
"information": new URL("https://example.com/error-information"),
|
2019-11-10 19:26:55 -08:00
|
|
|
"range": [ 1, 2 ],
|
|
|
|
"fixInfo": {
|
|
|
|
"lineNumber": 1,
|
|
|
|
"editColumn": 1,
|
|
|
|
"deleteCount": 1,
|
|
|
|
"insertText": "text"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
assert(ruleOnErrorInfo);
|
|
|
|
false && onError(ruleOnErrorInfo);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
options.customRules = [ testRule ];
|
2024-12-03 19:58:28 -08:00
|
|
|
assertLintResults(lintSync(options));
|
|
|
|
lintAsync(options, assertLintResultsCallback);
|
2020-09-13 12:58:09 -07:00
|
|
|
(async () => {
|
2024-12-03 19:58:28 -08:00
|
|
|
assertLintResultsCallback(null, await lintPromise(options));
|
2020-09-13 12:58:09 -07:00
|
|
|
})();
|
2024-08-27 20:47:33 -07:00
|
|
|
|
2024-10-06 17:24:44 -07:00
|
|
|
assert.equal(
|
2024-12-03 19:58:28 -08:00
|
|
|
applyFix(
|
2024-10-06 17:24:44 -07:00
|
|
|
"# Fixing\n",
|
|
|
|
{
|
|
|
|
"insertText": "Head",
|
|
|
|
"editColumn": 3,
|
|
|
|
"deleteCount": 3
|
|
|
|
},
|
|
|
|
"\n"
|
|
|
|
),
|
|
|
|
"# Heading\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.equal(
|
2024-12-03 19:58:28 -08:00
|
|
|
applyFixes(
|
2024-10-06 17:24:44 -07:00
|
|
|
"# Fixing\n",
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"lineNumber": 1,
|
|
|
|
"fixInfo": {
|
|
|
|
"insertText": "Head",
|
|
|
|
"editColumn": 3,
|
|
|
|
"deleteCount": 3
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
),
|
|
|
|
"# Heading\n"
|
|
|
|
);
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
const configuration: Configuration = {
|
2024-08-27 20:47:33 -07:00
|
|
|
"custom-rule": true,
|
|
|
|
"no-hard-tabs": false,
|
|
|
|
"heading-style": {
|
|
|
|
"style": "consistent"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
assert(configuration);
|
2024-11-28 20:36:44 -08:00
|
|
|
const configurationStrict: ConfigurationStrict = {
|
2024-08-27 20:47:33 -07:00
|
|
|
// "custom-rule": true,
|
|
|
|
"no-hard-tabs": false,
|
|
|
|
"heading-style": {
|
|
|
|
"style": "consistent"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
assert(configurationStrict);
|