1package soy.iko.opencode.data.model
3import kotlinx.serialization.json.Json
4import org.junit.Assert.assertEquals
5import org.junit.Assert.assertTrue
9 private val json = Json { ignoreUnknownKeys = true; isLenient = true }
10 private fun element(s: String) = json.parseToJsonElement(s)
13 fun parsesTodosFromObject() {
14 val todos = parseTodos(
15 element("""{"todos":[{"id":"1","content":"A","status":"completed"},{"id":"2","content":"B","status":"in_progress"}]}"""),
17 assertEquals(2, todos.size)
18 assertEquals("A", todos[0].content)
19 assertEquals(TodoStatus.COMPLETED, todos[0].statusEnum())
20 assertEquals(TodoStatus.IN_PROGRESS, todos[1].statusEnum())
24 fun parsesTodosFromBareArray() {
25 val todos = parseTodos(element("""[{"content":"only","status":"pending"}]"""))
26 assertEquals(1, todos.size)
27 assertEquals(TodoStatus.PENDING, todos[0].statusEnum())
31 fun ignoresUnknownKeysAndUnknownStatus() {
32 val todos = parseTodos(element("""{"todos":[{"content":"x","status":"weird","extra":123}]}"""))
33 assertEquals(1, todos.size)
34 assertEquals("x", todos[0].content)
35 assertEquals(TodoStatus.UNKNOWN, todos[0].statusEnum())
39 fun returnsEmptyForNullAndGarbage() {
40 assertTrue(parseTodos(null).isEmpty())
41 assertTrue(parseTodos(element(""""just a string"""")).isEmpty())
42 assertTrue(parseTodos(element("""{"nope":true}""")).isEmpty())
46 fun statusEnumNormalizesAliases() {
47 assertEquals(TodoStatus.IN_PROGRESS, TodoItem(status = "in-progress").statusEnum())
48 assertEquals(TodoStatus.COMPLETED, TodoItem(status = "DONE").statusEnum())
49 assertEquals(TodoStatus.CANCELLED, TodoItem(status = "canceled").statusEnum())
50 assertEquals(TodoStatus.PENDING, TodoItem(status = "").statusEnum())
54 fun currentPlanPicksLatestNonEmptyTodowrite() {
55 val messages = listOf(
56 message("m1", todoPart("p1", """{"todos":[{"content":"old","status":"pending"}]}""")),
57 message("m2", todoPart("p2", """{"todos":[{"content":"new1","status":"completed"},{"content":"new2","status":"pending"}]}""")),
58 message("m3", TextPart(id = "t", text = "just talking")),
60 val plan = currentTodoPlan(messages)
61 assertEquals(2, plan.size)
62 assertEquals("new1", plan[0].content)
66 fun currentPlanSkipsEmptyLatestForPriorNonEmpty() {
67 val messages = listOf(
68 message("m1", todoPart("p1", """{"todos":[{"content":"keep","status":"pending"}]}""")),
69 message("m2", todoPart("p2", """{"todos":[]}""")),
71 val plan = currentTodoPlan(messages)
72 assertEquals(1, plan.size)
73 assertEquals("keep", plan[0].content)
77 fun currentPlanEmptyWhenNoTodowrite() {
78 val messages = listOf(
79 message("m1", TextPart(id = "t", text = "hi")),
80 message("m2", ToolPart(id = "b", tool = "bash", state = ToolCompleted(output = "done"))),
82 assertTrue(currentTodoPlan(messages).isEmpty())
85 private fun message(id: String, vararg parts: Part) =
86 MessageWithParts(AssistantMessage(id = id, sessionID = "s"), parts.toList())
88 private fun todoPart(id: String, inputJson: String): ToolPart =
89 ToolPart(id = id, tool = "todowrite", state = ToolCompleted(input = element(inputJson)))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list