1package soy.iko.opencode.ui.usage
3import org.junit.Assert.assertEquals
4import org.junit.Assert.assertTrue
6import soy.iko.opencode.data.model.AssistantMessage
7import soy.iko.opencode.data.model.MessageWithParts
8import soy.iko.opencode.data.model.TimeInfo
9import soy.iko.opencode.data.model.Tokens
10import soy.iko.opencode.data.model.UserMessage
12class UsageAggregationTest {
14 private fun assistant(model: String, cost: Double, input: Long, output: Long) =
16 info = AssistantMessage(
21 tokens = Tokens(input = input, output = output),
22 time = TimeInfo(completed = 1L),
27 fun aggregatesTotalsAndByModel() {
28 val sessions = listOf(
29 Triple("s1", "One", listOf(assistant("gpt", 0.10, 100, 50), assistant("gpt", 0.20, 200, 100))),
30 Triple("s2", "Two", listOf(assistant("claude", 0.05, 10, 5), MessageWithParts(UserMessage("u", "s2")))),
32 val report = aggregateUsage(sessions)
33 assertEquals(0.35, report.totalCost, 1e-9)
34 assertEquals(3, report.messageCount)
35 assertEquals(2, report.sessionCount)
36 assertEquals(2, report.byModel.size)
37 // Highest-cost model floats to the top.
38 assertEquals("gpt", report.byModel.first().model)
39 assertEquals(0.30, report.byModel.first().cost, 1e-9)
40 assertEquals(450L, report.byModel.first().tokens.total)
44 fun ignoresZeroUsageMessages() {
45 val sessions = listOf(Triple("s", "t", listOf(assistant("m", 0.0, 0, 0))))
46 assertTrue(aggregateUsage(sessions).isEmpty)
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