test: rebuild the view-skeleton suite on ADR 0009 tiers (task 0003)

Guard the CLI entry's program.parse() behind import.meta.main so the
command module can be imported without running the CLI, then rebuild the
deleted suite across the three tiers ADR 0009 defines:

- unit: parse (core) and render (bin), asserted on return values
- integration: the view command function, asserted on its Result
- e2e: the kitchen binary as a subprocess (exit codes, streams, ANSI
  suppression, errors, --help)

Drop the stale test-support.ts coverage ignore and refresh the task's
implementation notes to describe the tiered suite.
This commit is contained in:
2026-07-28 22:41:59 -04:00
parent e16f3f957d
commit 02020309eb
7 changed files with 365 additions and 15 deletions

View File

@@ -0,0 +1,102 @@
import { describe, expect, test } from "bun:test";
import { parse } from "@kitchen-md/core";
describe("parse", () => {
test("frontmatter passthrough — arbitrary fields become a plain object", () => {
const input = `---
title: Buttered Toast
servings: 2
tags: [breakfast, simple]
---
# Buttered Toast
`;
const result = parse(input);
expect(result.frontmatter).toEqual({
title: "Buttered Toast",
servings: 2,
tags: ["breakfast", "simple"],
});
});
test("frontmatter is an empty object when absent", () => {
const result = parse("# Just a heading");
expect(result.frontmatter).toEqual({});
});
test("frontmatter is an empty object when the block is empty", () => {
const input = `---
---
# Heading
`;
const result = parse(input);
expect(result.frontmatter).toEqual({});
});
test("headings are modelled at every level 16 with TextNode children", () => {
const cases: [string, 1 | 2 | 3 | 4 | 5 | 6, string][] = [
["# Level One", 1, "Level One"],
["## Level Two", 2, "Level Two"],
["### Level Three", 3, "Level Three"],
["#### Level Four", 4, "Level Four"],
["##### Level Five", 5, "Level Five"],
["###### Level Six", 6, "Level Six"],
];
for (const [markdown, level, text] of cases) {
const result = parse(markdown);
expect(result.blocks).toEqual([
{
type: "heading",
level,
children: [{ type: "text", value: text }],
},
]);
}
});
test("a paragraph is a ParagraphBlock with TextNode content", () => {
const result = parse("Just some plain prose.");
expect(result.blocks).toEqual([
{
type: "paragraph",
children: [{ type: "text", value: "Just some plain prose." }],
},
]);
});
test("blocks are flat and in document order — a heading is a sibling of the following paragraph", () => {
const input = `# Title
A paragraph under it.
`;
const result = parse(input);
expect(result.blocks).toEqual([
{
type: "heading",
level: 1,
children: [{ type: "text", value: "Title" }],
},
{
type: "paragraph",
children: [{ type: "text", value: "A paragraph under it." }],
},
]);
});
test("diagnostics are empty in the normal case", () => {
const result = parse("# Ok");
expect(result.diagnostics).toEqual([]);
});
});