init
This commit is contained in:
commit
76266cedc6
23 changed files with 4041 additions and 0 deletions
31
scripts/ts-mime-todo/tests/_mocks/todo-basic.txt
Normal file
31
scripts/ts-mime-todo/tests/_mocks/todo-basic.txt
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
--ISSUE
|
||||
Content-Type: application/sprints
|
||||
Sprints:
|
||||
- Name: Sprint Alpha
|
||||
Range: 2026-02-01..2026-02-14
|
||||
-
|
||||
Name: Sprint Beta
|
||||
Range: 2026-02-15..2026-02-28
|
||||
|
||||
--ISSUE
|
||||
Content-Type: application/issue
|
||||
ID: 1
|
||||
Type: feature
|
||||
Title: Add streaming parser
|
||||
Status: open
|
||||
Priority: high
|
||||
Created: 2026-02-05
|
||||
Relationships: dependsOn:3
|
||||
Description: Implement streaming JSON parser.
|
||||
Must support SAX-like events.
|
||||
|
||||
--ISSUE
|
||||
Content-Type: application/issue
|
||||
ID: 2
|
||||
Type: bugfix
|
||||
Title: Fix wraparound
|
||||
Status: in-progress
|
||||
Priority: medium
|
||||
Created: 2026-02-06
|
||||
Relationships:
|
||||
Description: Fix off-by-one in circular buffer.
|
||||
10
scripts/ts-mime-todo/tests/_mocks/todo-issues-only.txt
Normal file
10
scripts/ts-mime-todo/tests/_mocks/todo-issues-only.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
--ISSUE
|
||||
Content-Type: application/issue
|
||||
ID: 10
|
||||
Type: hotfix
|
||||
Title: Patch crash
|
||||
Status: done
|
||||
Priority: high
|
||||
Created: 2026-02-03
|
||||
Relationships:
|
||||
Description: Fix crash in allocator.
|
||||
26
scripts/ts-mime-todo/tests/_mocks/todo-multiple-sprints.txt
Normal file
26
scripts/ts-mime-todo/tests/_mocks/todo-multiple-sprints.txt
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
--ISSUE
|
||||
Content-Type: application/sprints
|
||||
Sprints:
|
||||
- Name: Sprint Alpha
|
||||
Range: 2026-02-01..2026-02-14
|
||||
-
|
||||
Name: Sprint Beta
|
||||
Range: 2026-02-15..2026-02-28
|
||||
|
||||
--ISSUE
|
||||
Content-Type: application/sprints
|
||||
Sprints:
|
||||
- Name: Sprint Gamma
|
||||
Range: 2026-02-28..2026-03-15
|
||||
|
||||
--ISSUE
|
||||
Content-Type: application/issue
|
||||
ID: 1
|
||||
Type: feature
|
||||
Title: Add streaming parser
|
||||
Status: open
|
||||
Priority: high
|
||||
Created: 2026-02-05
|
||||
Relationships: dependsOn:3
|
||||
Description: Implement streaming JSON parser.
|
||||
Must support SAX-like events.
|
||||
1
scripts/ts-mime-todo/tests/_mocks/todo-no-sprints.txt
Normal file
1
scripts/ts-mime-todo/tests/_mocks/todo-no-sprints.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
Sprints:
|
||||
55
scripts/ts-mime-todo/tests/lib/file.test.ts
Normal file
55
scripts/ts-mime-todo/tests/lib/file.test.ts
Normal 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")
|
||||
})
|
||||
})
|
||||
32
scripts/ts-mime-todo/tests/lib/issue.test.ts
Normal file
32
scripts/ts-mime-todo/tests/lib/issue.test.ts
Normal 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({})
|
||||
})
|
||||
})
|
||||
22
scripts/ts-mime-todo/tests/lib/sprint.test.ts
Normal file
22
scripts/ts-mime-todo/tests/lib/sprint.test.ts
Normal 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)
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue