2020-09-12 12:11:14 -07:00
|
|
|
// @ts-check
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
import os from "node:os";
|
|
|
|
import path from "node:path";
|
|
|
|
import test from "ava";
|
|
|
|
import { characterEntities } from "character-entities";
|
|
|
|
import { gemoji } from "gemoji";
|
2025-09-08 21:09:35 -07:00
|
|
|
import helpers, { formatLintResults } from "../helpers/helpers.cjs";
|
2024-12-03 19:58:28 -08:00
|
|
|
import { lint } from "markdownlint/promise";
|
2024-11-28 20:36:44 -08:00
|
|
|
import { forEachInlineCodeSpan } from "../lib/markdownit.cjs";
|
|
|
|
import { getReferenceLinkImageData } from "../lib/cache.mjs";
|
2020-09-12 12:11:14 -07:00
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("clearHtmlCommentTextValid", (t) => {
|
|
|
|
t.plan(1);
|
2020-09-12 12:11:14 -07:00
|
|
|
const validComments = [
|
2021-01-30 13:08:57 -08:00
|
|
|
"<!-->",
|
|
|
|
"<!--->",
|
|
|
|
"<!---->",
|
|
|
|
"<!-- comment -->",
|
|
|
|
" <!-- comment -->",
|
|
|
|
" <!-- comment -->",
|
2020-09-12 12:11:14 -07:00
|
|
|
"<!-- text -->",
|
|
|
|
"<!--text-->",
|
|
|
|
"<!-- -->",
|
2021-01-28 21:45:53 -08:00
|
|
|
"<!-- -- -->",
|
2020-09-12 12:11:14 -07:00
|
|
|
"<!---->",
|
|
|
|
"<!---text-->",
|
|
|
|
"<!--text-text-->",
|
|
|
|
"<!--- -->",
|
|
|
|
"<!--",
|
|
|
|
"-->",
|
|
|
|
"<!--",
|
|
|
|
"",
|
|
|
|
"-->",
|
|
|
|
"<!--",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"-->",
|
|
|
|
"<!--",
|
|
|
|
"",
|
|
|
|
" text ",
|
|
|
|
"",
|
|
|
|
"-->",
|
|
|
|
"<!--text",
|
|
|
|
"",
|
|
|
|
"text-->",
|
|
|
|
"text<!--text-->text",
|
|
|
|
"text<!--",
|
|
|
|
"-->text",
|
|
|
|
"text<!--",
|
|
|
|
"text",
|
|
|
|
"-->text",
|
|
|
|
"<!--text--><!--text-->",
|
|
|
|
"text<!--text-->text<!--text-->text",
|
|
|
|
"text<!--text > text <!-->text",
|
|
|
|
"<!--",
|
|
|
|
"text"
|
|
|
|
];
|
|
|
|
const validResult = [
|
2021-01-30 13:08:57 -08:00
|
|
|
"<!-->",
|
|
|
|
"<!--->",
|
|
|
|
"<!---->",
|
2022-10-14 20:59:42 -07:00
|
|
|
"<!-- ....... -->",
|
|
|
|
" <!-- ....... -->",
|
|
|
|
" <!-- ....... -->",
|
|
|
|
"<!-- .... -->",
|
2021-01-30 14:36:11 -08:00
|
|
|
"<!--....-->",
|
2022-10-14 20:59:42 -07:00
|
|
|
"<!-- -->",
|
|
|
|
"<!-- .. -->",
|
2020-09-12 12:11:14 -07:00
|
|
|
"<!---->",
|
2021-01-30 14:36:11 -08:00
|
|
|
"<!--.....-->",
|
|
|
|
"<!--.........-->",
|
2022-10-14 20:59:42 -07:00
|
|
|
"<!--. -->",
|
2020-09-12 12:11:14 -07:00
|
|
|
"<!--",
|
|
|
|
"-->",
|
|
|
|
"<!--",
|
|
|
|
"",
|
|
|
|
"-->",
|
|
|
|
"<!--",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"-->",
|
|
|
|
"<!--",
|
|
|
|
"",
|
2022-10-14 20:59:42 -07:00
|
|
|
" .....",
|
2020-09-12 12:11:14 -07:00
|
|
|
"",
|
|
|
|
"-->",
|
2021-01-30 14:36:11 -08:00
|
|
|
"<!--....",
|
2020-09-12 12:11:14 -07:00
|
|
|
"",
|
2021-01-30 14:36:11 -08:00
|
|
|
"....-->",
|
|
|
|
"text<!--....-->text",
|
2020-09-12 12:11:14 -07:00
|
|
|
"text<!--",
|
|
|
|
"-->text",
|
|
|
|
"text<!--",
|
2021-01-30 14:36:11 -08:00
|
|
|
"....",
|
2020-09-12 12:11:14 -07:00
|
|
|
"-->text",
|
2021-01-30 14:36:11 -08:00
|
|
|
"<!--....--><!--....-->",
|
|
|
|
"text<!--....-->text<!--....-->text",
|
2022-10-14 20:59:42 -07:00
|
|
|
"text<!--.... . .... ..-->text",
|
2020-09-12 12:11:14 -07:00
|
|
|
"<!--",
|
|
|
|
"text"
|
|
|
|
];
|
|
|
|
const actual = helpers.clearHtmlCommentText(validComments.join("\n"));
|
|
|
|
const expected = validResult.join("\n");
|
2021-01-10 20:46:00 -08:00
|
|
|
t.is(actual, expected);
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("clearHtmlCommentTextInvalid", (t) => {
|
|
|
|
t.plan(1);
|
2020-09-12 12:11:14 -07:00
|
|
|
const invalidComments = [
|
|
|
|
"<!>",
|
|
|
|
"<!->",
|
|
|
|
"<!-->",
|
|
|
|
"<!--->",
|
|
|
|
"<!--> -->",
|
|
|
|
"<!-->text-->",
|
|
|
|
"<!--->text-->",
|
2021-01-28 21:45:53 -08:00
|
|
|
"<!---->",
|
|
|
|
"<!-->-->",
|
|
|
|
"<!-->t-->",
|
|
|
|
"<!--->-->",
|
|
|
|
"<!--->t-->",
|
2021-01-30 13:08:57 -08:00
|
|
|
"<!---->t-->",
|
2022-10-14 20:59:42 -07:00
|
|
|
" <!-- ........ .... ..... -->"
|
2020-09-12 12:11:14 -07:00
|
|
|
];
|
|
|
|
const actual = helpers.clearHtmlCommentText(invalidComments.join("\n"));
|
|
|
|
const expected = invalidComments.join("\n");
|
2021-01-10 20:46:00 -08:00
|
|
|
t.is(actual, expected);
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("clearHtmlCommentTextNonGreedy", (t) => {
|
|
|
|
t.plan(1);
|
2020-09-12 12:11:14 -07:00
|
|
|
const nonGreedyComments = [
|
|
|
|
"<!-- text --> -->",
|
|
|
|
"<!---text --> -->",
|
|
|
|
"<!--t--> -->",
|
|
|
|
"<!----> -->"
|
|
|
|
];
|
|
|
|
const nonGreedyResult = [
|
2022-10-14 20:59:42 -07:00
|
|
|
"<!-- .... --> -->",
|
|
|
|
"<!--..... --> -->",
|
2021-01-30 14:36:11 -08:00
|
|
|
"<!--.--> -->",
|
2020-09-12 12:11:14 -07:00
|
|
|
"<!----> -->"
|
|
|
|
];
|
|
|
|
const actual = helpers.clearHtmlCommentText(nonGreedyComments.join("\n"));
|
|
|
|
const expected = nonGreedyResult.join("\n");
|
2021-01-10 20:46:00 -08:00
|
|
|
t.is(actual, expected);
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("clearHtmlCommentTextEmbedded", (t) => {
|
|
|
|
t.plan(1);
|
2020-09-12 12:11:14 -07:00
|
|
|
const embeddedComments = [
|
|
|
|
"text<!--text-->text",
|
|
|
|
"<!-- markdownlint-disable MD010 -->",
|
|
|
|
"text<!--text-->text",
|
|
|
|
"text<!-- markdownlint-disable MD010 -->text",
|
|
|
|
"text<!--text-->text"
|
|
|
|
];
|
|
|
|
const embeddedResult = [
|
2021-01-30 14:36:11 -08:00
|
|
|
"text<!--....-->text",
|
2022-10-14 20:59:42 -07:00
|
|
|
"<!-- .................... ..... -->",
|
2021-01-30 14:36:11 -08:00
|
|
|
"text<!--....-->text",
|
2022-10-14 20:59:42 -07:00
|
|
|
"text<!-- .................... ..... -->text",
|
2021-01-30 14:36:11 -08:00
|
|
|
"text<!--....-->text"
|
2020-09-12 12:11:14 -07:00
|
|
|
];
|
|
|
|
const actual = helpers.clearHtmlCommentText(embeddedComments.join("\n"));
|
|
|
|
const expected = embeddedResult.join("\n");
|
2021-01-10 20:46:00 -08:00
|
|
|
t.is(actual, expected);
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("isBlankLine", (t) => {
|
2022-02-11 21:54:43 -08:00
|
|
|
t.plan(33);
|
2022-12-15 13:54:54 -08:00
|
|
|
// @ts-ignore
|
|
|
|
t.true(helpers.isBlankLine(null), "[null]");
|
2020-09-12 12:11:14 -07:00
|
|
|
const blankLines = [
|
|
|
|
"",
|
|
|
|
" ",
|
|
|
|
" ",
|
|
|
|
"\t\t\t",
|
|
|
|
"\r",
|
|
|
|
"\n",
|
|
|
|
"\t\r\n",
|
|
|
|
" <!-- text --> ",
|
|
|
|
"<!--text-->",
|
|
|
|
"<!---->",
|
|
|
|
"<!-- text -->\t<!-- text -->",
|
|
|
|
">",
|
|
|
|
"> ",
|
|
|
|
"> > > \t",
|
|
|
|
"> <!--text-->",
|
2021-12-20 04:18:45 +00:00
|
|
|
">><!--text-->",
|
|
|
|
"<!--",
|
|
|
|
" <!-- text",
|
|
|
|
"text --> ",
|
2022-02-11 21:54:43 -08:00
|
|
|
"-->",
|
|
|
|
"text --> <!--text--> <!--text--> <!-- text",
|
|
|
|
"text --> --> <!--text--> <!--text--> <!-- <!-- text"
|
2020-09-12 12:11:14 -07:00
|
|
|
];
|
2022-06-08 22:10:27 -07:00
|
|
|
for (const line of blankLines) {
|
2022-12-15 13:54:54 -08:00
|
|
|
t.true(helpers.isBlankLine(line), line);
|
2022-06-08 22:10:27 -07:00
|
|
|
}
|
2020-09-12 12:11:14 -07:00
|
|
|
const nonBlankLines = [
|
|
|
|
"text",
|
|
|
|
" text ",
|
|
|
|
".",
|
|
|
|
"> .",
|
|
|
|
"<!--text--> text",
|
2021-12-20 04:18:45 +00:00
|
|
|
"text <!--text-->",
|
|
|
|
"text <!--",
|
2022-02-11 21:54:43 -08:00
|
|
|
"--> text",
|
|
|
|
"text --> <!--text--> text <!--text--> <!-- text",
|
|
|
|
"text --> --> <!--text--> text <!--text--> <!-- <!-- text"
|
2020-09-12 12:11:14 -07:00
|
|
|
];
|
2022-06-08 22:10:27 -07:00
|
|
|
for (const line of nonBlankLines) {
|
|
|
|
t.true(!helpers.isBlankLine(line), line);
|
|
|
|
}
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("forEachInlineCodeSpan", (t) => {
|
|
|
|
t.plan(99);
|
2020-09-12 12:11:14 -07:00
|
|
|
const testCases =
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"input": "`code`",
|
|
|
|
"expecteds": [ [ "code", 0, 1, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text `code` text",
|
|
|
|
"expecteds": [ [ "code", 0, 6, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text `code` text `edoc`",
|
|
|
|
"expecteds": [
|
|
|
|
[ "code", 0, 6, 1 ],
|
|
|
|
[ "edoc", 0, 18, 1 ]
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text `code` text `edoc` text",
|
|
|
|
"expecteds": [
|
|
|
|
[ "code", 0, 6, 1 ],
|
|
|
|
[ "edoc", 0, 18, 1 ]
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text ``code`code`` text",
|
|
|
|
"expecteds": [ [ "code`code", 0, 7, 2 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "`code `` code`",
|
|
|
|
"expecteds": [ [ "code `` code", 0, 1, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "`code\\`text`",
|
|
|
|
"expecteds": [ [ "code\\", 0, 1, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "``\ncode\n``",
|
|
|
|
"expecteds": [ [ "\ncode\n", 0, 2, 2 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text\n`code`\ntext",
|
|
|
|
"expecteds": [ [ "code", 1, 1, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text\ntext\n`code`\ntext\n`edoc`\ntext",
|
|
|
|
"expecteds": [
|
|
|
|
[ "code", 2, 1, 1 ],
|
|
|
|
[ "edoc", 4, 1, 1 ]
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text `code\nedoc` text",
|
|
|
|
"expecteds": [ [ "code\nedoc", 0, 6, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "> text `code` text",
|
|
|
|
"expecteds": [ [ "code", 0, 8, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "> text\n> `code`\n> text",
|
|
|
|
"expecteds": [ [ "code", 1, 3, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "> text\n> `code\n> edoc`\n> text",
|
|
|
|
"expecteds": [ [ "code\n> edoc", 1, 3, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "```text``",
|
|
|
|
"expecteds": []
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text `text text",
|
|
|
|
"expecteds": []
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "`text``code``",
|
|
|
|
"expecteds": [ [ "code", 0, 7, 2 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text \\` text `code`",
|
|
|
|
"expecteds": [ [ "code", 0, 14, 1 ] ]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"input": "text\\\n`code`",
|
|
|
|
"expecteds": [ [ "code", 1, 1, 1 ] ]
|
|
|
|
}
|
|
|
|
];
|
2022-06-08 22:10:27 -07:00
|
|
|
for (const testCase of testCases) {
|
2020-09-12 12:11:14 -07:00
|
|
|
const { input, expecteds } = testCase;
|
2024-09-14 17:33:46 -07:00
|
|
|
forEachInlineCodeSpan(input, (code, line, column, ticks) => {
|
2022-12-15 13:54:54 -08:00
|
|
|
// @ts-ignore
|
2020-09-12 12:11:14 -07:00
|
|
|
const [ expectedCode, expectedLine, expectedColumn, expectedTicks ] =
|
|
|
|
expecteds.shift();
|
2021-01-10 20:46:00 -08:00
|
|
|
t.is(code, expectedCode, input);
|
|
|
|
t.is(line, expectedLine, input);
|
|
|
|
t.is(column, expectedColumn, input);
|
|
|
|
t.is(ticks, expectedTicks, input);
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
2022-06-19 02:14:03 +00:00
|
|
|
t.is(expecteds.shift(), undefined, input);
|
2022-06-08 22:10:27 -07:00
|
|
|
}
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2021-01-10 20:46:00 -08:00
|
|
|
test("getPreferredLineEnding", (t) => {
|
2022-05-05 23:14:18 -07:00
|
|
|
t.plan(21);
|
2020-09-12 12:11:14 -07:00
|
|
|
const testCases = [
|
2022-05-05 23:14:18 -07:00
|
|
|
[ "", "\n" ],
|
2020-09-12 12:11:14 -07:00
|
|
|
[ "\r", "\r" ],
|
|
|
|
[ "\n", "\n" ],
|
|
|
|
[ "\r\n", "\r\n" ],
|
|
|
|
[ "t\rt\nt", "\n" ],
|
|
|
|
[ "t\nt\rt", "\n" ],
|
|
|
|
[ "t\r\nt\nt", "\n" ],
|
|
|
|
[ "t\nt\r\nt", "\n" ],
|
|
|
|
[ "t\r\nt\rt", "\r\n" ],
|
|
|
|
[ "t\rt\r\nt", "\r\n" ],
|
|
|
|
[ "t\r\nt\rt\nt", "\n" ],
|
|
|
|
[ "t\r\nt\r\nt\r\nt", "\r\n" ],
|
|
|
|
[ "t\nt\nt\nt", "\n" ],
|
|
|
|
[ "t\rt\rt\rt", "\r" ],
|
|
|
|
[ "t\r\nt\nt\r\nt", "\r\n" ],
|
|
|
|
[ "t\nt\r\nt\nt", "\n" ],
|
|
|
|
[ "t\rt\t\rt", "\r" ]
|
|
|
|
];
|
2022-06-08 22:10:27 -07:00
|
|
|
for (const testCase of testCases) {
|
2020-09-12 12:11:14 -07:00
|
|
|
const [ input, expected ] = testCase;
|
|
|
|
const actual = helpers.getPreferredLineEnding(input);
|
2021-01-10 20:46:00 -08:00
|
|
|
t.is(actual, expected, "Incorrect line ending returned.");
|
2022-06-08 22:10:27 -07:00
|
|
|
}
|
2022-05-06 21:04:34 -07:00
|
|
|
t.is(helpers.getPreferredLineEnding("", null), "\n");
|
|
|
|
t.is(helpers.getPreferredLineEnding("", { "EOL": "\n" }), "\n");
|
|
|
|
t.is(helpers.getPreferredLineEnding("", { "EOL": "\r\n" }), "\r\n");
|
|
|
|
t.is(helpers.getPreferredLineEnding("", { "EOL": "custom" }), "custom");
|
2020-09-12 12:11:14 -07:00
|
|
|
});
|
|
|
|
|
2022-05-16 22:57:11 -07:00
|
|
|
test("expandTildePath", (t) => {
|
2022-07-24 12:22:32 -07:00
|
|
|
t.plan(17);
|
2022-05-16 22:57:11 -07:00
|
|
|
const homedir = os.homedir();
|
|
|
|
t.is(helpers.expandTildePath("", os), "");
|
2022-07-24 12:22:32 -07:00
|
|
|
t.is(helpers.expandTildePath("", {}), "");
|
2022-05-16 22:57:11 -07:00
|
|
|
t.is(helpers.expandTildePath("", null), "");
|
|
|
|
t.is(
|
|
|
|
path.resolve(helpers.expandTildePath("~", os)),
|
|
|
|
homedir
|
|
|
|
);
|
|
|
|
t.is(helpers.expandTildePath("~", null), "~");
|
|
|
|
t.is(helpers.expandTildePath("file", os), "file");
|
|
|
|
t.is(helpers.expandTildePath("file", null), "file");
|
|
|
|
t.is(helpers.expandTildePath("/file", os), "/file");
|
|
|
|
t.is(helpers.expandTildePath("/file", null), "/file");
|
|
|
|
t.is(
|
|
|
|
path.resolve(helpers.expandTildePath("~/file", os)),
|
|
|
|
path.join(homedir, "/file")
|
|
|
|
);
|
|
|
|
t.is(helpers.expandTildePath("~/file", null), "~/file");
|
|
|
|
t.is(helpers.expandTildePath("dir/file", os), "dir/file");
|
|
|
|
t.is(helpers.expandTildePath("dir/file", null), "dir/file");
|
|
|
|
t.is(helpers.expandTildePath("/dir/file", os), "/dir/file");
|
|
|
|
t.is(helpers.expandTildePath("/dir/file", null), "/dir/file");
|
|
|
|
t.is(
|
|
|
|
path.resolve(helpers.expandTildePath("~/dir/file", os)),
|
|
|
|
path.join(homedir, "/dir/file")
|
|
|
|
);
|
|
|
|
t.is(helpers.expandTildePath("~/dir/file", null), "~/dir/file");
|
|
|
|
});
|
2022-12-15 13:54:54 -08:00
|
|
|
|
2022-12-22 23:28:04 +00:00
|
|
|
test("getReferenceLinkImageData().shortcuts", (t) => {
|
|
|
|
t.plan(1);
|
2024-12-03 19:58:28 -08:00
|
|
|
/** @type {import("markdownlint").Options} */
|
2022-12-22 23:28:04 +00:00
|
|
|
const options = {
|
|
|
|
"customRules": [
|
|
|
|
{
|
|
|
|
"names": [ "no-shortcut-links" ],
|
|
|
|
"description": "-",
|
|
|
|
"tags": [ "-" ],
|
2024-03-09 16:17:50 -08:00
|
|
|
"parser": "none",
|
2022-12-22 23:28:04 +00:00
|
|
|
"function":
|
2024-03-09 16:17:50 -08:00
|
|
|
() => {
|
2024-08-24 22:05:16 -07:00
|
|
|
const { shortcuts } = getReferenceLinkImageData();
|
2022-12-22 23:28:04 +00:00
|
|
|
t.is(shortcuts.size, 0, [ ...shortcuts.keys() ].join(", "));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"strings": {
|
|
|
|
"no-shortcut-links": `
|
|
|
|
Full reference link: [text0][label]
|
|
|
|
Collapsed reference link: [label][]
|
|
|
|
Nested empty brackets: [text1[]](https://example.com/)
|
|
|
|
Missing close bracket, empty text: [text2[](https://example.com/)
|
|
|
|
Empty bracket pairs: [text3[]][]
|
2024-10-21 20:56:22 -07:00
|
|
|
Empty bracket pair: [text4[]]
|
2022-12-22 23:28:04 +00:00
|
|
|
|
|
|
|
[label]: https://example.com/label
|
|
|
|
`
|
|
|
|
}
|
|
|
|
};
|
2024-12-03 19:58:28 -08:00
|
|
|
return lint(options).then(() => null);
|
2022-12-22 23:28:04 +00:00
|
|
|
});
|
2023-06-24 15:45:51 -07:00
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
test("endOfLineHtmlEntityRe", (t) => {
|
2023-06-24 15:45:51 -07:00
|
|
|
const entities = Object.keys(characterEntities);
|
|
|
|
t.plan(entities.length);
|
|
|
|
for (const entity of entities) {
|
|
|
|
t.true(helpers.endOfLineHtmlEntityRe.test(`-&${entity};`), entity);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2024-11-28 20:36:44 -08:00
|
|
|
test("endOfLineGemojiCodeRe", (t) => {
|
2023-06-24 15:45:51 -07:00
|
|
|
const emojis = gemoji.flatMap((i) => i.names);
|
|
|
|
t.plan(emojis.length);
|
|
|
|
for (const emoji of emojis) {
|
|
|
|
t.true(helpers.endOfLineGemojiCodeRe.test(`-:${emoji}:`), emoji);
|
|
|
|
}
|
|
|
|
});
|
2024-06-15 15:45:04 -07:00
|
|
|
|
|
|
|
test("ellipsify", (t) => {
|
|
|
|
t.is(helpers.ellipsify("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), "abcdefghijklmnopqrstuvwxyzABCD...");
|
|
|
|
t.is(helpers.ellipsify("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", false, false), "abcdefghijklmnopqrstuvwxyzABCD...");
|
|
|
|
t.is(helpers.ellipsify("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", true, false), "abcdefghijklmnopqrstuvwxyzABCD...");
|
|
|
|
t.is(helpers.ellipsify("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", false, true), "...wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
|
|
t.is(helpers.ellipsify("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", true, true), "abcdefghijklmno...LMNOPQRSTUVWXYZ");
|
|
|
|
});
|
2024-09-27 23:58:40 -07:00
|
|
|
|
|
|
|
test("hasOverlap", (t) => {
|
|
|
|
t.plan(32);
|
2024-11-28 20:36:44 -08:00
|
|
|
/** @type {import("../helpers/helpers.cjs").FileRange[][]} */
|
2024-09-27 23:58:40 -07:00
|
|
|
const trueTestCases = [
|
|
|
|
// Same line
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 1 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 1 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 2, "endColumn": 2 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 3 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 2, "endColumn": 2 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 2, "endColumn": 3 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 3 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 2, "endColumn": 3 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 4 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 2, "endColumn": 3 }
|
|
|
|
],
|
|
|
|
// Common line
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 2, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 2, "endLine": 2, "startColumn": 2, "endColumn": 4 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 2, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 2, "endLine": 2, "startColumn": 1, "endColumn": 1 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 1, "endLine": 2, "startColumn": 2, "endColumn": 4 }
|
|
|
|
],
|
|
|
|
// Common lines
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 3, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 2, "endLine": 4, "startColumn": 3, "endColumn": 4 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 4, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 2, "endLine": 3, "startColumn": 3, "endColumn": 4 }
|
|
|
|
]
|
|
|
|
];
|
|
|
|
for (const trueTestCase of trueTestCases) {
|
|
|
|
const [ rangeA, rangeB ] = trueTestCase;
|
|
|
|
t.true(helpers.hasOverlap(rangeA, rangeB), JSON.stringify({ rangeA, rangeB }));
|
|
|
|
t.true(helpers.hasOverlap(rangeB, rangeA), JSON.stringify({ rangeB, rangeA }));
|
|
|
|
}
|
|
|
|
const falseTestCases = [
|
|
|
|
// Same line
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 1 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 2, "endColumn": 2 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 1, "endLine": 1, "startColumn": 3, "endColumn": 4 }
|
|
|
|
],
|
|
|
|
// Common line
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 2, "startColumn": 1, "endColumn": 2 },
|
|
|
|
{ "startLine": 2, "endLine": 3, "startColumn": 3, "endColumn": 4 }
|
|
|
|
],
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 2, "startColumn": 4, "endColumn": 2 },
|
|
|
|
{ "startLine": 2, "endLine": 3, "startColumn": 4, "endColumn": 2 }
|
|
|
|
],
|
|
|
|
// No common lines
|
|
|
|
[
|
|
|
|
{ "startLine": 1, "endLine": 2, "startColumn": 1, "endColumn": 4 },
|
|
|
|
{ "startLine": 3, "endLine": 4, "startColumn": 2, "endColumn": 3 }
|
|
|
|
]
|
|
|
|
];
|
|
|
|
for (const falseTestCase of falseTestCases) {
|
|
|
|
const [ rangeA, rangeB ] = falseTestCase;
|
|
|
|
t.false(helpers.hasOverlap(rangeA, rangeB), JSON.stringify({ rangeA, rangeB }));
|
|
|
|
t.false(helpers.hasOverlap(rangeB, rangeA), JSON.stringify({ rangeB, rangeA }));
|
|
|
|
}
|
|
|
|
});
|
2025-09-08 21:09:35 -07:00
|
|
|
|
|
|
|
test("formatLintResults", async(t) => {
|
|
|
|
t.plan(2);
|
|
|
|
t.deepEqual(formatLintResults(undefined), []);
|
|
|
|
const lintResults = await lint({ "strings": { "content": "# Heading <br/>" } });
|
|
|
|
t.deepEqual(
|
|
|
|
formatLintResults(lintResults),
|
|
|
|
[
|
|
|
|
"content: 1: MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: \"# Heading <br/>\"]",
|
|
|
|
"content: 1: MD033/no-inline-html Inline HTML [Element: br]",
|
|
|
|
"content: 1: MD047/single-trailing-newline Files should end with a single newline character"
|
|
|
|
]
|
|
|
|
);
|
|
|
|
});
|