BlockGrouperTest.kt
96 lignes · 4016 octets
package fr.ebii.card2vcf.ocr import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue class BlockGrouperTest { private fun ligne( text: String, top: Int, height: Int = 30, left: Int = 0, right: Int = 300, confidence: Float = 90f, ) = OcrLine(text, OcrBox(left, top, right, top + height), confidence) @Test fun listeVideAucunBloc() { assertEquals(emptyList(), BlockGrouper.group(emptyList())) } @Test fun troisPavesSeparesDonnentTroisBlocs() { val lines = listOf( ligne("Sonia MARTIN", top = 100, height = 40), ligne("Directrice commerciale", top = 150), ligne("561 allée des Noisetiers", top = 400), ligne("69760 Limonest", top = 440), ligne("Tél. 04 75 35 12 34", top = 700), ) val blocs = BlockGrouper.group(lines) assertEquals(3, blocs.size) assertEquals(listOf("Sonia MARTIN", "Directrice commerciale"), blocs[0].lines.map { it.text }) assertEquals(listOf("561 allée des Noisetiers", "69760 Limonest"), blocs[1].lines.map { it.text }) assertEquals(listOf("Tél. 04 75 35 12 34"), blocs[2].lines.map { it.text }) } @Test fun lignesAdresseContiguesGroupees() { val blocs = BlockGrouper.group( listOf( ligne("561 allée des Noisetiers", top = 100), ligne("69760 Limonest - France", top = 140), ), ) assertEquals(1, blocs.size) assertEquals("561 allée des Noisetiers\n69760 Limonest - France", blocs[0].text()) } @Test fun deuxColonnesNonFusionneesMemeSiEntrelaceesVerticalement() { val gauche1 = ligne("561 allée des Noisetiers", top = 100, left = 0, right = 300) val droite1 = ligne("Tél. 04 75 35 12 34", top = 110, left = 600, right = 900) val gauche2 = ligne("69760 Limonest", top = 140, left = 0, right = 300) val droite2 = ligne("contact@voltea.fr", top = 150, left = 600, right = 900) val blocs = BlockGrouper.group(listOf(gauche1, droite1, gauche2, droite2)) assertEquals(2, blocs.size) val textes = blocs.map { b -> b.lines.map { it.text } } assertTrue(textes.contains(listOf("561 allée des Noisetiers", "69760 Limonest")), "colonne gauche intacte: $textes") assertTrue(textes.contains(listOf("Tél. 04 75 35 12 34", "contact@voltea.fr")), "colonne droite intacte: $textes") } @Test fun hauteurMedianeRobusteAUneLigneGeante() { // Logo géant (h=200) : la médiane reste ~30, donc l'écart de 60 px sous le logo coupe. val blocs = BlockGrouper.group( listOf( ligne("VOLTEA", top = 0, height = 200), ligne("Sonia Martin", top = 260), ligne("Directrice", top = 300), ), ) assertEquals(2, blocs.size) assertEquals(listOf("VOLTEA"), blocs[0].lines.map { it.text }) assertEquals(listOf("Sonia Martin", "Directrice"), blocs[1].lines.map { it.text }) } @Test fun blocsOrdonnesDeHautEnBasPuisDeGaucheADroite() { val basGauche = ligne("bas gauche", top = 500, left = 0, right = 200) val hautDroite = ligne("haut droite", top = 100, left = 600, right = 800) val hautGauche = ligne("haut gauche", top = 100, left = 0, right = 200) val blocs = BlockGrouper.group(listOf(basGauche, hautDroite, hautGauche)) assertEquals( listOf("haut gauche", "haut droite", "bas gauche"), blocs.map { it.text() }, ) } @Test fun proprietesDeBloc() { val bloc = OcrBlock( listOf( OcrLine("a", OcrBox(10, 100, 200, 130), 80f), OcrLine("b", OcrBox(20, 140, 300, 170), 60f), ), ) assertEquals(OcrBox(10, 100, 300, 170), bloc.box()) assertEquals(70f, bloc.avgConfidence()) assertEquals("a\nb", bloc.text()) } }
GitRust