mime-todo-cli/tests/lib/serializer.test.ts
2026-03-15 05:11:59 +01:00

129 lines
4.2 KiB
TypeScript

import * as fs from "fs"
import { describe, it, expect } from "vitest"
import { parseTodoFile } from "../../src/file.js"
import {
serializeTodoFile,
serializeIssue,
serializeSprints,
serializeRelationships,
} from "../../src/serializer.js"
describe("serializeRelationships", () => {
it("serializes empty relationships", () => {
expect(serializeRelationships({})).toBe("")
})
it("serializes single relationship", () => {
expect(serializeRelationships({ dependsOn: [3] })).toBe("dependsOn:3")
})
it("serializes multiple relationships", () => {
const result = serializeRelationships({ dependsOn: [3, 4], blocks: [7] })
expect(result).toContain("dependsOn:3 4")
expect(result).toContain("blocks:7")
})
})
describe("serializeSprints", () => {
it("serializes empty sprints", () => {
expect(serializeSprints([])).toBe("Sprints:")
})
it("serializes sprint list", () => {
const result = serializeSprints([
{ name: "Alpha", start: "2026-02-01", end: "2026-02-14" },
])
expect(result).toContain("Sprints:")
expect(result).toContain("- Name: Alpha")
expect(result).toContain("Range: 2026-02-01..2026-02-14")
})
})
describe("serializeIssue", () => {
it("serializes an issue with all fields", () => {
const result = serializeIssue({
id: 1,
type: "feature",
title: "Test",
status: "open",
priority: "high",
created: "2026-02-05",
relationships: { dependsOn: [3] },
description: "A test issue",
body: "",
})
expect(result).toContain("ID: 1")
expect(result).toContain("Type: feature")
expect(result).toContain("Title: Test")
expect(result).toContain("Status: open")
expect(result).toContain("Priority: high")
expect(result).toContain("Created: 2026-02-05")
expect(result).toContain("Relationships: dependsOn:3")
expect(result).toContain("Description: A test issue")
})
it("serializes multi-line description", () => {
const result = serializeIssue({
id: 1,
type: "feature",
title: "Test",
status: "open",
priority: "high",
created: "2026-02-05",
relationships: {},
description: "Line one\nLine two",
body: "",
})
expect(result).toContain("Description: Line one")
expect(result).toContain(" Line two")
})
})
describe("round-trip", () => {
it("parse → serialize → parse produces equivalent data", async () => {
const todo1 = await parseTodoFile("tests/_mocks/todo-basic.txt")
const serialized = serializeTodoFile(todo1)
// Write to temp location for re-parsing
const tmpPath = "tests/_mocks/_roundtrip.txt"
fs.writeFileSync(tmpPath, serialized)
try {
const todo2 = await parseTodoFile(tmpPath)
expect(todo2.sprints.length).toBe(todo1.sprints.length)
expect(todo2.issues.length).toBe(todo1.issues.length)
for (let i = 0; i < todo1.sprints.length; i++) {
expect(todo2.sprints[i].name).toBe(todo1.sprints[i].name)
expect(todo2.sprints[i].start).toBe(todo1.sprints[i].start)
expect(todo2.sprints[i].end).toBe(todo1.sprints[i].end)
}
for (let i = 0; i < todo1.issues.length; i++) {
expect(todo2.issues[i].id).toBe(todo1.issues[i].id)
expect(todo2.issues[i].type).toBe(todo1.issues[i].type)
expect(todo2.issues[i].title).toBe(todo1.issues[i].title)
expect(todo2.issues[i].status).toBe(todo1.issues[i].status)
expect(todo2.issues[i].priority).toBe(todo1.issues[i].priority)
expect(todo2.issues[i].created).toBe(todo1.issues[i].created)
expect(todo2.issues[i].description).toBe(todo1.issues[i].description)
}
} finally {
fs.unlinkSync(tmpPath)
}
})
it("round-trips issues-only file", async () => {
const todo1 = await parseTodoFile("tests/_mocks/todo-issues-only.txt")
const serialized = serializeTodoFile(todo1)
const tmpPath = "tests/_mocks/_roundtrip2.txt"
fs.writeFileSync(tmpPath, serialized)
try {
const todo2 = await parseTodoFile(tmpPath)
expect(todo2.issues.length).toBe(todo1.issues.length)
expect(todo2.sprints.length).toBe(0)
} finally {
fs.unlinkSync(tmpPath)
}
})
})