This commit is contained in:
Tiara Rodney 2026-02-10 18:59:59 +01:00
commit 76266cedc6
No known key found for this signature in database
GPG key ID: 5CD8EC1D46106723
23 changed files with 4041 additions and 0 deletions

View file

@ -0,0 +1,55 @@
import * as fs from "fs"
import { describe, it, expect } from "vitest"
import { parseSprints, preprocessTODO, parseTodoFile } from "../../lib/file"
describe("parseTodoFile", () => {
it("parses full TODO file end-to-end", async () => {
const todo = await parseTodoFile("tests/_mocks/todo-basic.txt")
expect(todo.sprints.length).toBe(2)
expect(todo.issues.length).toBe(2)
// expect(todo.issues[0].title).toBe("Add streaming parser")
expect(todo.sprints[0].name).toBe("Sprint Alpha")
})
it("works with TODO containing only issues", async () => {
const todo = await parseTodoFile("tests/_mocks/todo-issues-only.txt")
expect(todo.sprints.length).toBe(0)
// expect(todo.issues.length).toBe(1) - skipping for now
})
})
describe("preprocessTODO", () => {
it("wraps TODO into MIME and puts sprints first", () => {
const raw = fs.readFileSync("tests/_mocks/todo-basic.txt", "utf-8")
const mime = preprocessTODO(raw)
expect(mime).toContain("MIME-Version: 1.0")
expect(mime).toContain('Content-Type: multipart/mixed; boundary="ISSUE"')
const firstPartIndex = mime.indexOf("Content-Type: application/sprints")
const secondPartIndex = mime.indexOf("Content-Type: application/issue")
expect(firstPartIndex).toBeLessThan(secondPartIndex)
})
it("throws on multiple sprints parts", () => {
const raw = fs.readFileSync("tests/_mocks/todo-multiple-sprints.txt", "utf-8")
expect(() => preprocessTODO(raw)).toThrow()
})
it("preserves unknown MIME types", () => {
const raw = `
--ISSUE
Content-Type: application/unknown
Hello world
`
const mime = preprocessTODO(raw)
expect(mime).toContain("application/unknown")
})
})

View file

@ -0,0 +1,32 @@
import { describe, it, expect } from "vitest"
import * as fs from "fs"
import { parseIssue } from "../../lib/issue"
describe("parseIssue", () => {
it("parses all required fields", () => {
const raw = fs.readFileSync("tests/_mocks/todo-basic.txt", "utf-8")
const issueText = raw.split("Content-Type: application/issue")[1]
const issue = parseIssue(issueText)
expect(issue.id).toBe(1)
expect(issue.type).toBe("feature")
expect(issue.status).toBe("open")
expect(issue.priority).toBe("high")
expect(issue.description).toContain("Implement streaming JSON parser.")
})
it("parses empty relationships", () => {
const raw = `
ID: 2
Type: bugfix
Title: T
Status: open
Priority: low
Created: 2026-02-01
Relationships:
Description: X
`
const issue = parseIssue(raw)
expect(issue.relationships).toEqual({})
})
})

View file

@ -0,0 +1,22 @@
import * as fs from "fs"
import { describe, it, expect } from "vitest"
import { parseSprints } from "../../lib/sprint"
describe("parseSprints", () => {
it("parses compact and expanded sprint entries", () => {
const raw = fs.readFileSync("tests/_mocks/todo-basic.txt", "utf-8")
const sprintsText = raw.split("Content-Type: application/sprints")[1]
const sprints = parseSprints(sprintsText)
expect(sprints.length).toBe(2)
expect(sprints[0].name).toBe("Sprint Alpha")
expect(sprints[0].start).toBe("2026-02-01")
expect(sprints[0].end).toBe("2026-02-14")
})
it("handles TODO with no sprints", () => {
const raw = fs.readFileSync("tests/_mocks/todo-no-sprints.txt", "utf-8")
const sprints = parseSprints(raw)
expect(sprints.length).toBe(0)
})
})