test: move test files, add ts configs
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import { Task } from "@/model/task";
|
||||
import { ITaskRepository } from "@/ports";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { InMemoryFileSystem } from "../../tests/helpers/InMemoryFileSystem";
|
||||
import { FsTaskRepository } from "./FsTaskRepository";
|
||||
|
||||
describe("FsTaskRepository", () => {
|
||||
let fs: InMemoryFileSystem;
|
||||
let repo: ITaskRepository;
|
||||
|
||||
const folder = "/tasks";
|
||||
|
||||
const sampleTask = {
|
||||
title: "Fix login bug",
|
||||
description: "Token validation error",
|
||||
status: "todo" as const,
|
||||
priority: "high" as const,
|
||||
tags: ["bug", "frontend"],
|
||||
assignee: "ivanov",
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
fs = new InMemoryFileSystem();
|
||||
repo = new FsTaskRepository(fs, ".task.md");
|
||||
});
|
||||
|
||||
it("creates a task and writes it as a .task.md file", async () => {
|
||||
const task = await repo.create(folder, sampleTask);
|
||||
|
||||
expect(task.id).toBeTruthy();
|
||||
expect(task.title).toBe("Fix login bug");
|
||||
expect(task.created).toBeTruthy();
|
||||
expect(task.updated).toBe(task.created);
|
||||
|
||||
const files = await fs.readdir(folder);
|
||||
expect(files).toHaveLength(1);
|
||||
expect(files[0]).toMatch(/\.task\.md$/);
|
||||
|
||||
const content = await fs.readFile(`${folder}/${files[0]}`);
|
||||
expect(content).toContain("Fix login bug");
|
||||
expect(content).toContain("status: todo");
|
||||
});
|
||||
|
||||
it("list returns created tasks sorted by updated desc", async () => {
|
||||
const a = await repo.create(folder, { ...sampleTask, title: "A" });
|
||||
await delay(10);
|
||||
const b = await repo.create(folder, { ...sampleTask, title: "B" });
|
||||
|
||||
const tasks = await repo.list(folder);
|
||||
expect(tasks).toHaveLength(2);
|
||||
expect(tasks[0].title).toBe("B");
|
||||
expect(tasks[1].title).toBe("A");
|
||||
});
|
||||
|
||||
it("getById returns the correct task", async () => {
|
||||
const created = await repo.create(folder, sampleTask);
|
||||
const found = await repo.getById(folder, created.id);
|
||||
expect(found).toEqual(created);
|
||||
});
|
||||
|
||||
it("getById returns undefined for unknown id", async () => {
|
||||
const found = await repo.getById(folder, "nonexistent");
|
||||
expect(found).toBeUndefined();
|
||||
});
|
||||
|
||||
it("update modifies the file and updates timestamp", async () => {
|
||||
const task = await repo.create(folder, sampleTask);
|
||||
await delay(5);
|
||||
const updated: Task = { ...task, title: "Fixed!", status: "done" };
|
||||
|
||||
await repo.update(folder, updated);
|
||||
const found = await repo.getById(folder, task.id);
|
||||
|
||||
expect(found!.title).toBe("Fixed!");
|
||||
expect(found!.status).toBe("done");
|
||||
expect(new Date(found!.updated).getTime()).toBeGreaterThan(
|
||||
new Date(task.updated).getTime(),
|
||||
);
|
||||
});
|
||||
|
||||
it("delete removes the task file", async () => {
|
||||
const task = await repo.create(folder, sampleTask);
|
||||
await repo.delete(folder, task.id);
|
||||
|
||||
const tasks = await repo.list(folder);
|
||||
expect(tasks).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("delete is a no-op for unknown id", async () => {
|
||||
await expect(repo.delete(folder, "nope")).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("list returns empty array for non-existent folder", async () => {
|
||||
const tasks = await repo.list("/nonexistent");
|
||||
expect(tasks).toEqual([]);
|
||||
});
|
||||
|
||||
it("filters files by extension", async () => {
|
||||
fs.writeFile(`${folder}/notes.txt`, "hello");
|
||||
fs.writeFile(`${folder}/chore.md`, "---\nid: x\n---\n");
|
||||
|
||||
await repo.create(folder, sampleTask);
|
||||
|
||||
const tasks = await repo.list(folder);
|
||||
expect(tasks).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("skips unparseable .task.md files silently", async () => {
|
||||
fs.writeFile(`${folder}/corrupt.task.md`, "not valid frontmatter");
|
||||
|
||||
await repo.create(folder, sampleTask);
|
||||
const tasks = await repo.list(folder);
|
||||
expect(tasks).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
function delay(ms: number): Promise<void> {
|
||||
return new Promise((r) => setTimeout(r, ms));
|
||||
}
|
||||
Reference in New Issue
Block a user