feat: add inline icons for edit

This commit is contained in:
2026-07-16 02:49:55 +05:00
parent bda6c6b2e0
commit 7c0584707a
35 changed files with 1280 additions and 94 deletions
@@ -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);
});
});