summaryrefslogtreecommitdiff
path: root/platform-paper
diff options
context:
space:
mode:
Diffstat (limited to 'platform-paper')
-rw-r--r--platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverter.kt7
-rw-r--r--platform-paper/src/test/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverterTest.kt25
2 files changed, 30 insertions, 2 deletions
diff --git a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverter.kt b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverter.kt
index b502d63..e1a11f8 100644
--- a/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverter.kt
+++ b/platform-paper/src/main/kotlin/dev/m1sk9/lunaticChat/paper/converter/RomanjiConverter.kt
@@ -93,6 +93,13 @@ class RomanjiConverter(
// pin every word of the message to its unconverted form for good, because the words
// are converted concurrently and the timeout cancels all of them at once.
throw e
+ } catch (e: ConversionTimeoutException) {
+ // Returned without caching: a timeout says the request was slow, not that the word
+ // has no conversion, so recording the hiragana would pin it for the life of the
+ // cache over one slow reply. A hard API failure is different - the fallback is
+ // cached there deliberately.
+ logger.warning("Timed out converting $hiragana, leaving it uncached: ${e.message}")
+ return hiragana
} catch (e: Exception) {
logger.warning("Failed to convert $hiragana: ${e.message}")
hiragana // Use hiragana if API fails
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 69baa32..c8314d7 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
@@ -302,7 +302,7 @@ class RomanjiConverterTest {
}
@Test
- fun `an API timeout degrades to hiragana like any other failure`() =
+ fun `an API timeout degrades to hiragana without caching it`() =
runBlocking {
val (converter, cache, apiClient) = createConverter()
coEvery { apiClient.convert("おはよう") } throws ConversionTimeoutException(1.seconds)
@@ -310,7 +310,28 @@ class RomanjiConverterTest {
val result = converter.convert("ohayou")
assertEquals("おはよう", result)
- verify(exactly = 1) { cache.put("ohayou", "おはよう") }
+ // A slow reply says nothing about the word, so caching the hiragana would pin it to its
+ // unconverted form for the life of the cache.
+ verify(exactly = 0) { cache.put(any(), any()) }
+ }
+
+ @Test
+ fun `a word that timed out is converted on the next attempt`() =
+ runBlocking {
+ // A cache that actually remembers, unlike the shared fixture whose get() always returns
+ // null - which would let this pass even if the timeout had been cached.
+ val entries = mutableMapOf<String, String>()
+ val cache = mockk<ConversionCache>(relaxed = true)
+ every { cache.get(any()) } answers { entries[firstArg()] }
+ every { cache.put(any(), any()) } answers { entries[firstArg()] = secondArg() }
+ val apiClient = mockk<GoogleIMEClient>(relaxed = true)
+ val converter = RomanjiConverter(cache, apiClient, TestUtils.TestLogger())
+
+ coEvery { apiClient.convert("おはよう") } throws ConversionTimeoutException(1.seconds)
+ converter.convert("ohayou")
+ coEvery { apiClient.convert("おはよう") } returns "おはよう御座います"
+
+ assertEquals("おはよう御座います", converter.convert("ohayou"))
}
@Test