Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .castiron.stats.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
schema_version: 1
generation_id: b935ba17-9980-45bd-b8c7-1939d1b03aba
generation_id: 0cdeb809-627b-4caa-9340-887e46d7979f
openapi_spec_hash: e81fa0fd2133715dabef9f00a42557a9
openapi_transformed_spec_hash: bea7a30d23deed3fc8f1c6413a38d354
config_hash: dda57991526f80e9f99d8f9621460eaa
codegen_sha: 9306aff2af8ad922f591ebbc1d29362cf9271bc8
codegen_sha: ca58cce22b36f9f5586a16379bc977d20f193a4a
codegen_hash: bda6b5fe61d5a094103b7cbc38597c82109f4c14bb23d4501d6c3e1569f75878
public_codegen_sha: 43d374297ff620990fa45fdd39a32079c3905e30
public_codegen_sha: 3a713a4b40be032d22b5aa19b393ee32178ea142
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,13 @@ class LiveTranscriptGrouper private constructor(builder: Builder) : AutoCloseabl
)

private fun normalize(value: String): String =
whitespace
.replace(value.lowercase(Locale.ROOT).replace('ς', 'σ').replace('-', ' '), " ")
.trim { it == ' ' || it in punctuation }
whitespace.replace(foldCase(value).replace('-', ' '), " ").trim {
it == ' ' || it in punctuation
}

// Sigma forms are equivalent here; fold before ROOT casing to avoid contextual scans.
private fun foldCase(value: String): String =
value.replace('\u03A3', '\u03C3').lowercase(Locale.ROOT).replace('ς', 'σ')
}

private class AckNode {
Expand Down Expand Up @@ -221,7 +225,7 @@ class LiveTranscriptGrouper private constructor(builder: Builder) : AutoCloseabl
highSurrogate = text.last().takeIf(Char::isHighSurrogate)
val end = text.length - if (highSurrogate == null) 0 else 1
// Folding final sigma keeps ROOT lowercase independent of fragment boundaries.
val lower = text.substring(0, end).lowercase(Locale.ROOT).replace('ς', 'σ')
val lower = foldCase(text.substring(0, end))
for (raw in lower) {
val char = if (raw == '-' || whitespace.matches(raw.toString())) ' ' else raw
val trim = char == ' ' || char in punctuation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import java.util.concurrent.TimeoutException
import java.util.function.Consumer
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.jupiter.api.Assertions.assertTimeout
import org.junit.jupiter.api.Test

internal class LiveTranscriptGrouperTest {
Expand Down Expand Up @@ -336,6 +337,22 @@ internal class LiveTranscriptGrouperTest {
assertThat(finalized(events).map { it.segment().text() }).containsExactly("hello")
}

@Test
fun longSigmaTranscriptPreservesTextWithoutContextualCasingDelay() {
val text = "\u03A3".repeat(32_000)
val events = updates()
assertTimeout(Duration.ofSeconds(5)) {
LiveTranscriptGrouper.create { events.add(it) }
.use { grouper ->
grouper.push(input("u1", "hello", 0, 100))
grouper.push(output("a1", text, 0, 100))
grouper.push(input("u2", " again", 100, 200))
}
}
assertThat(finalized(events).map { it.segment().text() })
.containsExactly("hello again", text)
}

@Test
fun acknowledgmentCaseMatchingDoesNotDependOnDeltaBoundaries() {
// U+0130 expands on ROOT lowercasing; Greek sigma has a final and an ordinary form.
Expand Down
Loading