feat: add inline icons for edit
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { MAX_TASK_TITLE_LENGTH } from "@/model/taskFile";
|
||||
import { validateFrontmatter } from "./validateFrontmatter";
|
||||
|
||||
const valid = `---
|
||||
id: "550e8400-e29b-41d4-a716-446655440000"
|
||||
title: Fix login
|
||||
status: todo
|
||||
priority: high
|
||||
tags: [bug]
|
||||
assignee: ""
|
||||
created: 2026-07-12T10:00:00.000Z
|
||||
updated: 2026-07-12T10:00:00.000Z
|
||||
---
|
||||
|
||||
Body
|
||||
`;
|
||||
|
||||
describe("validateFrontmatter", () => {
|
||||
it("accepts a valid task file", () => {
|
||||
expect(validateFrontmatter(valid)).toEqual([]);
|
||||
});
|
||||
|
||||
it("errors when frontmatter is missing", () => {
|
||||
const issues = validateFrontmatter("no frontmatter\n");
|
||||
expect(issues).toHaveLength(1);
|
||||
expect(issues[0].severity).toBe("error");
|
||||
expect(issues[0].message).toMatch(/frontmatter/i);
|
||||
});
|
||||
|
||||
it("errors when frontmatter is unclosed", () => {
|
||||
const issues = validateFrontmatter("---\ntitle: x\n");
|
||||
expect(issues.some((i) => /not closed/i.test(i.message))).toBe(true);
|
||||
});
|
||||
|
||||
it("errors on invalid status", () => {
|
||||
const content = valid.replace("status: todo", "status: nope");
|
||||
const issues = validateFrontmatter(content);
|
||||
const statusIssue = issues.find((i) => i.field === "status");
|
||||
expect(statusIssue).toBeDefined();
|
||||
expect(statusIssue!.severity).toBe("error");
|
||||
expect(statusIssue!.range.startLine).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("errors on invalid priority", () => {
|
||||
const content = valid.replace("priority: high", "priority: urgent");
|
||||
const issues = validateFrontmatter(content);
|
||||
expect(issues.some((i) => i.field === "priority")).toBe(true);
|
||||
});
|
||||
|
||||
it("errors when id is missing", () => {
|
||||
const content = valid.replace(
|
||||
'id: "550e8400-e29b-41d4-a716-446655440000"\n',
|
||||
"",
|
||||
);
|
||||
const issues = validateFrontmatter(content);
|
||||
expect(
|
||||
issues.some((i) => i.field === "id" && /missing/i.test(i.message)),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("errors when title exceeds max length", () => {
|
||||
const long = "x".repeat(MAX_TASK_TITLE_LENGTH + 1);
|
||||
const content = valid.replace("title: Fix login", `title: ${long}`);
|
||||
const issues = validateFrontmatter(content);
|
||||
const titleIssue = issues.find((i) => i.field === "title");
|
||||
expect(titleIssue).toBeDefined();
|
||||
expect(titleIssue!.message).toMatch(String(MAX_TASK_TITLE_LENGTH));
|
||||
});
|
||||
|
||||
it("errors when tags is not an array", () => {
|
||||
const content = valid.replace("tags: [bug]", "tags: bug");
|
||||
const issues = validateFrontmatter(content);
|
||||
expect(issues.some((i) => i.field === "tags")).toBe(true);
|
||||
});
|
||||
|
||||
it("warns on unknown fields", () => {
|
||||
const content = valid.replace(
|
||||
"updated: 2026-07-12T10:00:00.000Z",
|
||||
"updated: 2026-07-12T10:00:00.000Z\nfoo: bar",
|
||||
);
|
||||
const issues = validateFrontmatter(content);
|
||||
const unknown = issues.find((i) => i.field === "foo");
|
||||
expect(unknown).toBeDefined();
|
||||
expect(unknown!.severity).toBe("warning");
|
||||
});
|
||||
|
||||
it("errors on broken YAML", () => {
|
||||
const content = `---
|
||||
title: [unterminated
|
||||
---
|
||||
`;
|
||||
const issues = validateFrontmatter(content);
|
||||
expect(issues.some((i) => /yaml/i.test(i.message))).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user