test: add prose-fixture end-to-end smoke for kitchen view (task 0003)
Pull a reduced end-to-end smoke forward into the slice so the view flow is exercised over a real on-disk recipe, not just a temp file. Add fixtures/prose.md — a recipe using only this slice's modelled constructs (frontmatter, headings, plain paragraphs) so it renders losslessly. integration_test now runs `kitchen view fixtures/prose.md` as a subprocess and asserts the frontmatter, separator, headings, paragraphs, and flat document order end-to-end. smoke_test covers `kitchen --help` exiting 0 with the view command listed. The full fixtures/basic.md smoke remains task 0007, which needs 0004's richer nodes before that fixture renders losslessly.
This commit is contained in:
@@ -68,4 +68,12 @@ They assert real observable behaviour against independent literals rather than r
|
|||||||
### Review follow-up applied
|
### Review follow-up applied
|
||||||
|
|
||||||
The `runCli` and `stripAnsi` test helpers were extracted into `packages/bin/src/test-support.ts` to remove duplication the review flagged across the bin test files.
|
The `runCli` and `stripAnsi` test helpers were extracted into `packages/bin/src/test-support.ts` to remove duplication the review flagged across the bin test files.
|
||||||
The scaffold's remaining `test.todo` placeholders (future block/inline types, annotations, the smoke test) are left intact for their owning tasks.
|
The scaffold's remaining `test.todo` placeholders (future block/inline types, annotations) are left intact for their owning tasks.
|
||||||
|
|
||||||
|
### End-to-end coverage pulled forward
|
||||||
|
|
||||||
|
A reduced end-to-end smoke was pulled forward so the vertical slice is validated the way a user runs it.
|
||||||
|
`fixtures/prose.md` is a committed recipe using only the constructs this slice models — frontmatter, headings at levels 1–3, and plain-text paragraphs — so it renders losslessly today.
|
||||||
|
`integration_test.ts` runs `kitchen view fixtures/prose.md` as a subprocess and asserts the ANSI-stripped output: exit 0, frontmatter YAML before the body, the separator, every heading and paragraph, and flat document order.
|
||||||
|
`smoke_test.ts` covers `kitchen --help` exiting 0 with the `view` command listed.
|
||||||
|
This is a subset of task 0007's smoke, which still owns the full `fixtures/basic.md` end-to-end once 0004's richer nodes make that fixture render losslessly.
|
||||||
|
|||||||
22
fixtures/prose.md
Normal file
22
fixtures/prose.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
title: Buttered Toast
|
||||||
|
servings: 2
|
||||||
|
tags: [breakfast, simple]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Buttered Toast
|
||||||
|
|
||||||
|
The simplest breakfast, and a good way to smoke-test the renderer.
|
||||||
|
Everything here is plain prose — no lists, code, or annotations yet.
|
||||||
|
|
||||||
|
## Method
|
||||||
|
|
||||||
|
Toast the bread until golden on both sides.
|
||||||
|
|
||||||
|
### Timing
|
||||||
|
|
||||||
|
Spread the butter while the toast is still warm so it soaks in.
|
||||||
|
|
||||||
|
## Serving
|
||||||
|
|
||||||
|
Cut into triangles and serve at once.
|
||||||
@@ -1,33 +1,43 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test } from "bun:test";
|
||||||
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
||||||
import { tmpdir } from "node:os";
|
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
|
||||||
import { runCli, stripAnsi } from "./test-support.ts";
|
import { runCli, stripAnsi } from "./test-support.ts";
|
||||||
|
|
||||||
const CLI = `${import.meta.dir}/index.ts`;
|
const CLI = `${import.meta.dir}/index.ts`;
|
||||||
|
const FIXTURE = join(import.meta.dir, "..", "..", "..", "fixtures", "prose.md");
|
||||||
|
|
||||||
describe("cli — integration", () => {
|
describe("cli — integration", () => {
|
||||||
test("invokes core parser and produces output for a real fixture file", async () => {
|
test("renders a real recipe fixture end-to-end", async () => {
|
||||||
const dir = mkdtempSync(join(tmpdir(), "kitchen-md-"));
|
const { exitCode, stdout } = await runCli(["view", FIXTURE], CLI);
|
||||||
const file = join(dir, "recipe.md");
|
|
||||||
writeFileSync(
|
|
||||||
file,
|
|
||||||
"---\ntitle: Test Recipe\nservings: 2\n---\n\n# Heading One\n\nA plain paragraph of prose.\n",
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { exitCode, stdout } = await runCli(["view", file], CLI);
|
|
||||||
const output = stripAnsi(stdout);
|
const output = stripAnsi(stdout);
|
||||||
|
const lines = output.split("\n");
|
||||||
|
const lineOf = (needle: string): number => lines.findIndex((line) => line.includes(needle));
|
||||||
|
|
||||||
expect(exitCode).toBe(0);
|
expect(exitCode).toBe(0);
|
||||||
expect(output).toContain("title: Test Recipe");
|
|
||||||
|
expect(output).toContain("title: Buttered Toast");
|
||||||
expect(output).toContain("servings: 2");
|
expect(output).toContain("servings: 2");
|
||||||
expect(output).toMatch(/─+/);
|
expect(output).toContain("tags:");
|
||||||
expect(output).toContain("Heading One");
|
expect(output).toContain("breakfast");
|
||||||
expect(output).toContain("A plain paragraph of prose.");
|
expect(output).toContain("simple");
|
||||||
} finally {
|
|
||||||
rmSync(dir, { recursive: true, force: true });
|
expect(lines.some((line) => /^─+$/.test(line))).toBe(true);
|
||||||
}
|
|
||||||
|
expect(output).toContain("Buttered Toast");
|
||||||
|
expect(output).toContain("Method");
|
||||||
|
expect(output).toContain("Timing");
|
||||||
|
expect(output).toContain("Serving");
|
||||||
|
|
||||||
|
expect(output).toContain("The simplest breakfast");
|
||||||
|
expect(output).toContain("Toast the bread until golden on both sides.");
|
||||||
|
expect(output).toContain("Spread the butter while the toast is still warm");
|
||||||
|
expect(output).toContain("Cut into triangles and serve at once.");
|
||||||
|
|
||||||
|
const separatorLine = lines.findIndex((line) => /^─+$/.test(line));
|
||||||
|
expect(lineOf("servings: 2")).toBeLessThan(separatorLine);
|
||||||
|
expect(separatorLine).toBeLessThan(lineOf("Method"));
|
||||||
|
expect(lineOf("Method")).toBeLessThan(lineOf("Timing"));
|
||||||
|
expect(lineOf("Timing")).toBeLessThan(lineOf("Serving"));
|
||||||
|
expect(lineOf("Method")).toBeLessThan(lineOf("Toast the bread until golden on both sides."));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import { describe, test } from "bun:test";
|
import { describe, expect, test } from "bun:test";
|
||||||
|
|
||||||
|
import { runCli } from "./test-support.ts";
|
||||||
|
|
||||||
describe("smoke", () => {
|
describe("smoke", () => {
|
||||||
test.todo("kitchen --help exits with code 0");
|
test("kitchen --help exits with code 0", async () => {
|
||||||
|
const { exitCode, stdout } = await runCli(["--help"], `${import.meta.dir}/index.ts`);
|
||||||
|
|
||||||
|
expect(exitCode).toBe(0);
|
||||||
|
expect(stdout).toMatch(/view/);
|
||||||
|
});
|
||||||
test.todo("kitchen parse <fixture> outputs structured JSON covering all annotation types");
|
test.todo("kitchen parse <fixture> outputs structured JSON covering all annotation types");
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user