Declare prettier, eslint, and husky in package.json so the lint and prepare scripts work without relying on globally-installed tools. Add a .prettierrc.json matching the project's tabs/no-bracket-spacing style and apply prettier --write across the tree.
109 lines
3.3 KiB
TypeScript
109 lines
3.3 KiB
TypeScript
import {describe, expect, it} from "bun:test";
|
||
import {classifyLines} from "../src/markdownStructure";
|
||
|
||
describe("classifyLines – plain content", () => {
|
||
it("classifies all lines as content when there is no frontmatter or code", () => {
|
||
const input = "# Title\n\n- [ ] open\n- text\n";
|
||
expect(classifyLines(input)).toEqual([
|
||
"content",
|
||
"content",
|
||
"content",
|
||
"content",
|
||
"content",
|
||
]);
|
||
});
|
||
});
|
||
|
||
describe("classifyLines – fenced code blocks", () => {
|
||
it("classifies backtick-fenced lines as code", () => {
|
||
const input = ["before", "```", "- [ ] not a task", "```", "after"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["content", "code", "code", "code", "content"]);
|
||
});
|
||
|
||
it("classifies tilde-fenced lines as code", () => {
|
||
const input = ["before", "~~~", "- [ ] not a task", "~~~", "after"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["content", "code", "code", "code", "content"]);
|
||
});
|
||
|
||
it("supports info strings on the opening fence", () => {
|
||
const input = ["```markdown", "- [ ] not a task", "```"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["code", "code", "code"]);
|
||
});
|
||
|
||
it("does not close on a shorter fence", () => {
|
||
const input = ["````", "```", "still in code", "````"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["code", "code", "code", "code"]);
|
||
});
|
||
|
||
it("does not treat tilde and backtick fences as matching", () => {
|
||
const input = ["```", "~~~", "still code"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["code", "code", "code"]);
|
||
});
|
||
|
||
it("treats a closing fence with trailing whitespace as a closer", () => {
|
||
const input = ["```", "x", "``` ", "after"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["code", "code", "code", "content"]);
|
||
});
|
||
|
||
it("does not treat a fence with info string as a closer", () => {
|
||
const input = ["```", "x", "``` not-a-closer", "still", "```"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["code", "code", "code", "code", "code"]);
|
||
});
|
||
|
||
it("permits up to 3 spaces of indentation on the fence", () => {
|
||
const input = [" ```", "- [ ] not a task", " ```", "after"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["code", "code", "code", "content"]);
|
||
});
|
||
});
|
||
|
||
describe("classifyLines – frontmatter", () => {
|
||
it("treats opening --- only at the very first line", () => {
|
||
const input = ["---", "Pending tasks: true", "---", "- [ ] open"].join("\n");
|
||
expect(classifyLines(input)).toEqual([
|
||
"frontmatter",
|
||
"frontmatter",
|
||
"frontmatter",
|
||
"content",
|
||
]);
|
||
});
|
||
|
||
it("does not treat a --- elsewhere as frontmatter", () => {
|
||
const input = ["# Title", "---", "- [ ] open"].join("\n");
|
||
expect(classifyLines(input)).toEqual(["content", "content", "content"]);
|
||
});
|
||
|
||
it("supports the YAML ... terminator", () => {
|
||
const input = ["---", "key: value", "...", "- [ ] open"].join("\n");
|
||
expect(classifyLines(input)).toEqual([
|
||
"frontmatter",
|
||
"frontmatter",
|
||
"frontmatter",
|
||
"content",
|
||
]);
|
||
});
|
||
});
|
||
|
||
describe("classifyLines – combined", () => {
|
||
it("handles frontmatter followed by content with a code block", () => {
|
||
const input = [
|
||
"---",
|
||
"foo: bar",
|
||
"---",
|
||
"- [ ] real task",
|
||
"```",
|
||
"- [ ] not a task",
|
||
"```",
|
||
"- [ ] another real task",
|
||
].join("\n");
|
||
expect(classifyLines(input)).toEqual([
|
||
"frontmatter",
|
||
"frontmatter",
|
||
"frontmatter",
|
||
"content",
|
||
"code",
|
||
"code",
|
||
"code",
|
||
"content",
|
||
]);
|
||
});
|
||
});
|