test: remove all test files for a clean restart (task 0003)
Temporary: clear the entire test suite (unit, subprocess, the shared helper, and the parser-integration placeholder) so the tests can be rebuilt from scratch. Fixtures and the test tooling (bunfig, report script) are kept. Note: `bun test` now errors on an empty suite, so the flake's tests check is red until tests return.
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { runCli } from "./test-support.ts";
|
||||
|
||||
const CLI = `${import.meta.dir}/index.ts`;
|
||||
|
||||
describe("cli", () => {
|
||||
test("exits with non-zero code when no file argument is given", async () => {
|
||||
const { exitCode, stderr } = await runCli(["view"], CLI);
|
||||
|
||||
expect(exitCode).not.toBe(0);
|
||||
expect(stderr).toMatch(/missing required argument|usage/i);
|
||||
});
|
||||
test("exits with non-zero code when file does not exist", async () => {
|
||||
const { exitCode, stderr } = await runCli(
|
||||
["view", "/no/such/kitchen-recipe-does-not-exist.md"],
|
||||
CLI,
|
||||
);
|
||||
|
||||
expect(exitCode).toBe(1);
|
||||
expect(stderr.trim().length).toBeGreaterThan(0);
|
||||
expect(stderr).toMatch(/cannot read|no such file|ENOENT/i);
|
||||
expect(stderr).toContain("/no/such/kitchen-recipe-does-not-exist.md");
|
||||
});
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { runCli, stripAnsi } from "./test-support.ts";
|
||||
|
||||
const CLI = `${import.meta.dir}/index.ts`;
|
||||
const FIXTURE = join(import.meta.dir, "..", "..", "..", "fixtures", "prose.md");
|
||||
|
||||
describe("cli — integration", () => {
|
||||
test("renders a real recipe fixture end-to-end", async () => {
|
||||
const { exitCode, stdout } = await runCli(["view", FIXTURE], CLI);
|
||||
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(output).toContain("title: Buttered Toast");
|
||||
expect(output).toContain("servings: 2");
|
||||
expect(output).toContain("tags:");
|
||||
expect(output).toContain("breakfast");
|
||||
expect(output).toContain("simple");
|
||||
|
||||
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,87 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import type { DocumentAST } from "@kitchen-md/core";
|
||||
import chalk from "chalk";
|
||||
|
||||
import { render } from "./render.ts";
|
||||
import { stripAnsi } from "./test-support.ts";
|
||||
|
||||
describe("render", () => {
|
||||
test("renders a paragraph as prose followed by a blank line", () => {
|
||||
const ast: DocumentAST = {
|
||||
frontmatter: {},
|
||||
blocks: [{ type: "paragraph", children: [{ type: "text", value: "Hello world" }] }],
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
expect(stripAnsi(render(ast))).toBe("Hello world\n\n");
|
||||
});
|
||||
|
||||
test("renders a heading followed by a single newline (not a blank line)", () => {
|
||||
const ast: DocumentAST = {
|
||||
frontmatter: {},
|
||||
blocks: [{ type: "heading", level: 2, children: [{ type: "text", value: "Batter" }] }],
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
expect(stripAnsi(render(ast))).toBe("Batter\n");
|
||||
});
|
||||
|
||||
test("renders frontmatter as raw YAML before the body", () => {
|
||||
const ast: DocumentAST = {
|
||||
frontmatter: { title: "Classic Pancakes", servings: 4 },
|
||||
blocks: [{ type: "paragraph", children: [{ type: "text", value: "A simple breakfast." }] }],
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const output = stripAnsi(render(ast));
|
||||
|
||||
expect(output.startsWith("title: Classic Pancakes\nservings: 4\n")).toBe(true);
|
||||
expect(output).toContain("A simple breakfast.");
|
||||
expect(output.indexOf("title: Classic Pancakes")).toBeLessThan(
|
||||
output.indexOf("A simple breakfast."),
|
||||
);
|
||||
});
|
||||
|
||||
test("renders a visual separator between the frontmatter and the body", () => {
|
||||
const ast: DocumentAST = {
|
||||
frontmatter: { title: "Classic Pancakes", servings: 4 },
|
||||
blocks: [{ type: "paragraph", children: [{ type: "text", value: "A simple breakfast." }] }],
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const lines = stripAnsi(render(ast)).split("\n");
|
||||
const separatorIndex = lines.findIndex((line) => /^─+$/.test(line));
|
||||
const frontmatterIndex = lines.findIndex((line) => line.includes("servings: 4"));
|
||||
const bodyIndex = lines.findIndex((line) => line.includes("A simple breakfast."));
|
||||
|
||||
expect(separatorIndex).toBeGreaterThan(-1);
|
||||
expect(separatorIndex).toBeGreaterThan(frontmatterIndex);
|
||||
expect(separatorIndex).toBeLessThan(bodyIndex);
|
||||
});
|
||||
|
||||
test("styles headings distinctly by level and suppresses ANSI when colour is disabled", () => {
|
||||
const h1: DocumentAST = {
|
||||
frontmatter: {},
|
||||
blocks: [{ type: "heading", level: 1, children: [{ type: "text", value: "Title" }] }],
|
||||
diagnostics: [],
|
||||
};
|
||||
const h2: DocumentAST = {
|
||||
frontmatter: {},
|
||||
blocks: [{ type: "heading", level: 2, children: [{ type: "text", value: "Title" }] }],
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
const original = chalk.level;
|
||||
try {
|
||||
chalk.level = 1;
|
||||
expect(render(h1)).toContain("\x1b[");
|
||||
expect(render(h1)).not.toBe(render(h2));
|
||||
|
||||
chalk.level = 0;
|
||||
expect(render(h1)).not.toContain("\x1b[");
|
||||
} finally {
|
||||
chalk.level = original;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { runCli } from "./test-support.ts";
|
||||
|
||||
describe("smoke", () => {
|
||||
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");
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
export const stripAnsi = (s: string): string => s.replace(/\[[0-9;]*m/g, "");
|
||||
|
||||
export async function runCli(args: string[], cli: string) {
|
||||
const proc = Bun.spawn(["bun", cli, ...args], { stdout: "pipe", stderr: "pipe" });
|
||||
const exitCode = await proc.exited;
|
||||
const stdout = await new Response(proc.stdout).text();
|
||||
const stderr = await new Response(proc.stderr).text();
|
||||
return { exitCode, stdout, stderr };
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { stripAnsi } from "./test-support.ts";
|
||||
import { formatViewError, viewFile } from "./view.ts";
|
||||
|
||||
const FIXTURE = join(import.meta.dir, "..", "..", "..", "fixtures", "prose.md");
|
||||
|
||||
describe("view", () => {
|
||||
test("returns Ok with rendered output for a real recipe", () => {
|
||||
const result = viewFile(FIXTURE);
|
||||
|
||||
expect(result.isOk()).toBe(true);
|
||||
|
||||
const output = stripAnsi(result._unsafeUnwrap());
|
||||
expect(output).toContain("title: Buttered Toast");
|
||||
expect(output).toContain("servings: 2");
|
||||
expect(output).toMatch(/─+/);
|
||||
expect(output).toContain("Buttered Toast");
|
||||
expect(output).toContain("Method");
|
||||
expect(output).toContain("Toast the bread until golden on both sides.");
|
||||
expect(output).toContain("Cut into triangles and serve at once.");
|
||||
});
|
||||
|
||||
test("returns Err with a read-failed error for a missing file", () => {
|
||||
const result = viewFile("/no/such/kitchen-view-missing.md");
|
||||
|
||||
expect(result.isErr()).toBe(true);
|
||||
|
||||
const error = result._unsafeUnwrapErr();
|
||||
expect(error.tag).toBe("read-failed");
|
||||
expect(error.path).toBe("/no/such/kitchen-view-missing.md");
|
||||
expect(error.cause).toMatch(/ENOENT|no such file/i);
|
||||
});
|
||||
|
||||
test("formats a read-failed error as a human-readable message", () => {
|
||||
expect(formatViewError({ tag: "read-failed", path: "/tmp/x.md", cause: "boom" })).toBe(
|
||||
"cannot read '/tmp/x.md': boom",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import { describe, test } from "bun:test";
|
||||
|
||||
describe("parser — integration", () => {
|
||||
test.todo("parses the primary fixture into the complete Document AST");
|
||||
test.todo("extracts every annotation type from the primary fixture");
|
||||
test.todo("extracts an annotation from inside the fixture's blockquote");
|
||||
test.todo("normalises the fixture's non-canonical unit (tablespoons -> tbsp)");
|
||||
});
|
||||
@@ -1,89 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { parse } from "./parse.ts";
|
||||
|
||||
describe("parser", () => {
|
||||
describe("frontmatter", () => {
|
||||
test("parses frontmatter fields as-is", () => {
|
||||
const source =
|
||||
"---\ntitle: Classic Pancakes\nservings: 4\ntags: [breakfast, quick]\n---\n\n# Classic Pancakes";
|
||||
|
||||
const result = parse(source);
|
||||
|
||||
expect(result.frontmatter).toEqual({
|
||||
title: "Classic Pancakes",
|
||||
servings: 4,
|
||||
tags: ["breakfast", "quick"],
|
||||
});
|
||||
});
|
||||
test("returns an empty object for empty frontmatter", () => {
|
||||
const source = "---\n---\n\n# Title";
|
||||
|
||||
const result = parse(source);
|
||||
|
||||
expect(result.frontmatter).toEqual({});
|
||||
expect(result.blocks).toContainEqual({
|
||||
type: "heading",
|
||||
level: 1,
|
||||
children: [{ type: "text", value: "Title" }],
|
||||
});
|
||||
expect(result.diagnostics).toEqual([]);
|
||||
});
|
||||
test("returns an empty object when there is no frontmatter", () => {
|
||||
const result = parse("# Title");
|
||||
|
||||
expect(result.frontmatter).toEqual({});
|
||||
expect(result.diagnostics).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("blocks", () => {
|
||||
test("parses headings at every level (1-6)", () => {
|
||||
const source = "# H1\n\n## H2\n\n### H3\n\n#### H4\n\n##### H5\n\n###### H6";
|
||||
|
||||
const result = parse(source);
|
||||
|
||||
expect(result).toEqual({
|
||||
frontmatter: {},
|
||||
blocks: [
|
||||
{ type: "heading", level: 1, children: [{ type: "text", value: "H1" }] },
|
||||
{ type: "heading", level: 2, children: [{ type: "text", value: "H2" }] },
|
||||
{ type: "heading", level: 3, children: [{ type: "text", value: "H3" }] },
|
||||
{ type: "heading", level: 4, children: [{ type: "text", value: "H4" }] },
|
||||
{ type: "heading", level: 5, children: [{ type: "text", value: "H5" }] },
|
||||
{ type: "heading", level: 6, children: [{ type: "text", value: "H6" }] },
|
||||
],
|
||||
diagnostics: [],
|
||||
});
|
||||
});
|
||||
test("keeps blocks flat and in document order (a heading is a sibling of the following paragraph)", () => {
|
||||
const result = parse("# Batter\n\nSift the flour into a bowl.");
|
||||
|
||||
expect(result).toEqual({
|
||||
frontmatter: {},
|
||||
blocks: [
|
||||
{ type: "heading", level: 1, children: [{ type: "text", value: "Batter" }] },
|
||||
{
|
||||
type: "paragraph",
|
||||
children: [{ type: "text", value: "Sift the flour into a bowl." }],
|
||||
},
|
||||
],
|
||||
diagnostics: [],
|
||||
});
|
||||
});
|
||||
test("parses paragraphs with typed inline nodes", () => {
|
||||
const result = parse("Hello world");
|
||||
|
||||
expect(result).toEqual({
|
||||
frontmatter: {},
|
||||
blocks: [
|
||||
{
|
||||
type: "paragraph",
|
||||
children: [{ type: "text", value: "Hello world" }],
|
||||
},
|
||||
],
|
||||
diagnostics: [],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user