summaryrefslogtreecommitdiff
path: root/platform-paper/src/test
diff options
context:
space:
mode:
authorSho Sakuma <me@m1sk9.dev>2026-08-03 00:42:36 +0900
committerSho Sakuma <me@m1sk9.dev>2026-08-05 00:42:23 +0900
commit8ef90fc0a3fad0e71af6c786c4d5739ac81fea71 (patch)
treea9381abad208987c1e05566ef551bc4dfe667588 /platform-paper/src/test
parent2d8b613a3ad48acafd683f5286e29c3f1c167275 (diff)
downloadLunaticChat-8ef90fc0a3fad0e71af6c786c4d5739ac81fea71.tar.gz
LunaticChat-8ef90fc0a3fad0e71af6c786c4d5739ac81fea71.tar.bz2
LunaticChat-8ef90fc0a3fad0e71af6c786c4d5739ac81fea71.zip
perf: convert the words of a message concurrently
RomanjiConverter awaited the Google IME call for one word before starting the next, though the words are independent. Callers convert under a single one-second timeout covering the whole message, so an N-word message needed N round trips inside a budget sized for roughly one: past the first word or two the remaining calls were cancelled, and because cache.put is only reached after a call returns, the discarded work was not even remembered. The next identical message repeated it. The words now run under one coroutineScope, so the message costs one round trip rather than N. The new test pins the concurrency itself rather than the timing: the fake API client records how many calls are in flight at once, which fails against the sequential version. Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'platform-paper/src/test')
-rw-r--r--platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverterTest.kt21
1 files changed, 21 insertions, 0 deletions
diff --git a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverterTest.kt b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverterTest.kt
index 1e6d3c0..a7e0a52 100644
--- a/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverterTest.kt
+++ b/platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverterTest.kt
@@ -7,7 +7,9 @@ import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
+import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
+import java.util.concurrent.atomic.AtomicInteger
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
@@ -298,4 +300,23 @@ class RomanjiConverterTest {
assertEquals("おはよう", result)
verify(exactly = 1) { cache.put("ohayou", "おはよう") }
}
+
+ @Test
+ fun `words in one message are converted concurrently`() =
+ runBlocking {
+ val (converter, _, apiClient) = createConverter()
+ val inFlight = AtomicInteger(0)
+ val peakInFlight = AtomicInteger(0)
+
+ coEvery { apiClient.convert(any()) } coAnswers {
+ peakInFlight.updateAndGet { maxOf(it, inFlight.incrementAndGet()) }
+ delay(50)
+ inFlight.decrementAndGet()
+ "変換"
+ }
+
+ converter.convert("konnichiwa ohayou arigatou")
+
+ assertEquals(3, peakInFlight.get(), "each word should be in flight at the same time")
+ }
}