git.iko.soy/opencode-android
on 8948962 help sign in
opencode-android/app/src/test/java/soy/iko/opencode/ui/chat/ConversationExportTest.kt
56 lines 1.9 kB history raw
1package soy.iko.opencode.ui.chat
3import org.junit.Assert.assertEquals
4import org.junit.Assert.assertTrue
5import org.junit.Test
6import soy.iko.opencode.data.model.AssistantMessage
7import soy.iko.opencode.data.model.MessageWithParts
8import soy.iko.opencode.data.model.ReasoningPart
9import soy.iko.opencode.data.model.TextPart
10import soy.iko.opencode.data.model.UserMessage
12class ConversationExportTest {
14 private val sid = "s1"
16 private fun user(id: String, text: String) =
17 MessageWithParts(UserMessage(id, sid), listOf(TextPart(id = "p$id", text = text)))
19 private fun assistant(id: String, text: String) =
20 MessageWithParts(AssistantMessage(id, sid), listOf(TextPart(id = "p$id", text = text)))
22 @Test
23 fun rendersRoleHeadersAndBodies() {
24 val md = buildConversationMarkdown(
25 listOf(user("u1", "Hello"), assistant("a1", "Hi there!")),
26 title = "My chat",
27 )
28 assertTrue(md.startsWith("# My chat"))
29 assertTrue(md.contains("## You\n\nHello"))
30 assertTrue(md.contains("## opencode\n\nHi there!"))
31 }
33 @Test
34 fun omitsTitleWhenBlank() {
35 val md = buildConversationMarkdown(listOf(user("u1", "hi")), title = null)
36 assertTrue(md.startsWith("## You"))
37 }
39 @Test
40 fun skipsMessagesWithoutText() {
41 val onlyReasoning = MessageWithParts(
42 AssistantMessage("a1", sid),
43 listOf(ReasoningPart(id = "r1", text = "hmm")),
44 )
45 val md = buildConversationMarkdown(listOf(onlyReasoning), title = null)
46 // Reasoning is exported in italics, so it still appears.
47 assertTrue(md.contains("## opencode"))
48 assertTrue(md.contains("_hmm_"))
49 }
51 @Test
52 fun emptyConversationProducesJustTheTitle() {
53 // No message bodies to export, but the title header is still emitted.
54 assertEquals("# x", buildConversationMarkdown(emptyList(), title = "x"))
55 }