-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(capture-sdk): Add tests for
CropToCameraFrameTextRecognizer
PIA-4617
- Loading branch information
1 parent
de12a85
commit c40b3aa
Showing
2 changed files
with
276 additions
and
0 deletions.
There are no files selected for viewing
176 changes: 176 additions & 0 deletions
176
.../net/gini/android/capture/internal/textrecognition/CropToCameraFrameTextRecognizerTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
package net.gini.android.capture.internal.textrecognition | ||
|
||
import android.graphics.Rect | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import com.google.common.truth.Truth.assertWithMessage | ||
import com.nhaarman.mockitokotlin2.mock | ||
import net.gini.android.capture.internal.textrecognition.test.RecognizedTextFixtures | ||
import net.gini.android.capture.internal.textrecognition.test.TextRecognizerStub | ||
import net.gini.android.capture.internal.util.Size | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
/** | ||
* Cannot use `@RunWith(JUnitParamsRunner::class)` because android.graphics.Rect needs the implementation provided by Robolectric. | ||
* Without Robolectric "method not mocked" exceptions are thrown: | ||
* > `java.lang.RuntimeException: Method contains in android.graphics.Rect not mocked. See https://developer.android.com/r/studio-ui/build/not-mocked for details.` | ||
*/ | ||
@RunWith(AndroidJUnit4::class) | ||
internal class CropToCameraFrameTextRecognizerTest { | ||
|
||
/** | ||
* Cannot use `@Parameters(method = "textCroppingTestParameterValues")`. See class comment above. | ||
*/ | ||
@Test | ||
fun `processImage() crops text to the camera frame and maintains text layout`() { | ||
val testParameters = textCroppingTestParameterValues() | ||
for (testParameter in testParameters) { | ||
val testDescription = testParameter[0] as String | ||
val recognizedText = testParameter[1] as RecognizedText | ||
val expectedText = testParameter[2] as RecognizedText | ||
val cameraPreviewSize = testParameter[3] as Size? | ||
val imageSize = testParameter[4] as Size? | ||
val imageRotation = testParameter[5] as Int | ||
val cameraFrame = testParameter[6] as Rect? | ||
|
||
// Given | ||
val textRecognizer = CropToCameraFrameTextRecognizer(TextRecognizerStub(recognizedText)) | ||
cameraPreviewSize?.let { textRecognizer.cameraPreviewSize = it } | ||
imageSize?.let { textRecognizer.setImageSizeAndRotation(imageSize, imageRotation) } | ||
cameraFrame?.let { textRecognizer.cameraFrameRect = it } | ||
|
||
// When | ||
textRecognizer.processImage(mock(), 100, 200, 0, doneCallback = { text -> | ||
// Then | ||
assertWithMessage(""" | ||
Test: $testDescription | ||
Camera preview size: $cameraPreviewSize | ||
Image size: $imageSize | ||
Image rotation: $imageRotation | ||
Camera frame: $cameraFrame | ||
""".trimIndent()) | ||
.that(text).isEqualTo(expectedText) | ||
}, cancelledCallback = { | ||
}) | ||
} | ||
} | ||
|
||
/** | ||
* Cannot use `@Parameters(method = "textCroppingTestParameterValues")`. See class comment above. | ||
*/ | ||
@Test | ||
fun `processByteArray() crops text to the camera frame and maintains text layout`() { | ||
val testParameters = textCroppingTestParameterValues() | ||
for (testParameter in testParameters) { | ||
val testDescription = testParameter[0] as String | ||
val recognizedText = testParameter[1] as RecognizedText | ||
val expectedText = testParameter[2] as RecognizedText | ||
val cameraPreviewSize = testParameter[3] as Size? | ||
val imageSize = testParameter[4] as Size? | ||
val imageRotation = testParameter[5] as Int | ||
val cameraFrame = testParameter[6] as Rect? | ||
|
||
// Given | ||
val textRecognizer = CropToCameraFrameTextRecognizer(TextRecognizerStub(recognizedText)) | ||
cameraPreviewSize?.let { textRecognizer.cameraPreviewSize = it } | ||
imageSize?.let { textRecognizer.setImageSizeAndRotation(imageSize, imageRotation) } | ||
cameraFrame?.let { textRecognizer.cameraFrameRect = it } | ||
|
||
// When | ||
textRecognizer.processByteArray(ByteArray(0), 100, 200, 0, doneCallback = { text -> | ||
// Then | ||
assertWithMessage(""" | ||
Test: $testDescription | ||
Camera preview size: $cameraPreviewSize | ||
Image size: $imageSize | ||
Image rotation: $imageRotation | ||
Camera frame: $cameraFrame | ||
""".trimIndent()) | ||
.that(text).isEqualTo(expectedText) | ||
}, cancelledCallback = { | ||
}) | ||
} | ||
} | ||
|
||
private fun textCroppingTestParameterValues(): List<List<Any?>> = listOf( | ||
// testDescription, recognizedText, expectedText, cameraPreviewSize, imageSize, imageRotation, cameraFrame | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, null, null, 0, null), | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, null, null, 0, Rect(0, 0, 1000, 1000)), | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, null, Size(1000, 1000), 0, null), | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, null, Size(1000, 1000), 0, Rect(0, 0, 1000, 1000)), | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, Size(1000, 1000), null, 0, null), | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, Size(1000, 1000), null, 0, Rect(0, 0, 1000, 1000)), | ||
listOf("Don't crop if some sizes are null", RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, Size(1000, 1000), Size(1000, 1000), 0, null), | ||
listOf("Don't crop if the camera frame contains all the text", | ||
RecognizedTextFixtures.fixture1, RecognizedTextFixtures.fixture1, Size(1000, 1000), Size(1000, 1000), 0, Rect(0, 0, 1000, 1000)), | ||
listOf("Don't crop if the camera frame contains all the text and the image size is different from the camera preview size", | ||
RecognizedTextFixtures.fixture2, RecognizedTextFixtures.fixture2, Size(1000, 1000), Size(100, 100), 0, Rect(0, 0, 1000, 1000)), | ||
listOf("Crop elements which exceed the left edge of the camera frame", | ||
RecognizedTextFixtures.fixture1, fixture1CroppedLeft, Size(1000, 1000), Size(1000, 1000), 0, Rect(200, 0, 1000, 1000)), | ||
listOf("Crop elements which exceed the left edge of the camera frame and the image size is different from the camera preview size", | ||
RecognizedTextFixtures.fixture2, fixture2CroppedLeft, Size(1000, 1000), Size(100, 100), 0, Rect(80, 0, 1000, 1000)), | ||
listOf("Crop elements which exceed the top edge of the camera frame", | ||
RecognizedTextFixtures.fixture1, fixture1CroppedTop, Size(1000, 1000), Size(1000, 1000), 0, Rect(0, 140, 1000, 1000)), | ||
// TODO: | ||
// Crop elements which exceed the top edge of the camera frame and the image size is different from the camera preview size | ||
// Crop elements which exceed the right edge of the camera frame | ||
// Crop elements which exceed the right edge of the camera frame and the image size is different from the camera preview size | ||
// Crop elements which exceed the bottom edge of the camera frame | ||
// Crop elements which exceed the bottom edge of the camera frame and the image size is different from the camera preview size | ||
) | ||
|
||
private val fixture1CroppedLeft = RecognizedText( | ||
""" | ||
SE | ||
Bank | ||
""".trimIndent(), | ||
blocks = listOf( | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("SE", Rect(240, 90, 260, 100)), | ||
) | ||
), | ||
) | ||
), | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Bank", Rect(200, 130, 240, 140)), | ||
) | ||
), | ||
) | ||
), | ||
) | ||
) | ||
|
||
private val fixture2CroppedLeft = RecognizedText("DE86210700200123010101", | ||
blocks = listOf( | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("DE86210700200123010101", Rect(11, 7, 33, 8)), | ||
) | ||
), | ||
) | ||
), | ||
) | ||
) | ||
|
||
private val fixture1CroppedTop = RecognizedText("Verwendungszweck:", | ||
blocks = listOf( | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Verwendungszweck:", Rect(50, 150, 170, 160)), | ||
) | ||
), | ||
) | ||
), | ||
) | ||
) | ||
} |
100 changes: 100 additions & 0 deletions
100
...est/java/net/gini/android/capture/internal/textrecognition/test/RecognizedTextFixtures.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package net.gini.android.capture.internal.textrecognition.test | ||
|
||
import android.graphics.Rect | ||
import net.gini.android.capture.internal.textrecognition.RecognizedText | ||
import net.gini.android.capture.internal.textrecognition.RecognizedTextBlock | ||
import net.gini.android.capture.internal.textrecognition.RecognizedTextElement | ||
import net.gini.android.capture.internal.textrecognition.RecognizedTextLine | ||
|
||
internal object RecognizedTextFixtures { | ||
|
||
// For image size: 1000 x 1000 | ||
val fixture1 = RecognizedText(""" | ||
Bankverbindung | ||
IBAN: DE86210700200123010101 | ||
Empfänger: Zalando SE | ||
BIC: DEUTEDEHH210 | ||
Bank: Deutsche Bank | ||
Verwendungszweck: | ||
""".trimIndent(), | ||
blocks = listOf( | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Bankverbindung", Rect(50, 50, 190, 60)), | ||
) | ||
), | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("IBAN:", Rect(50, 70, 100, 80)), | ||
RecognizedTextElement("DE86210700200123010101", Rect(110, 70, 330, 80)), | ||
) | ||
), | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Empfänger:", Rect(50, 90, 150, 100)), | ||
RecognizedTextElement("Zalando", Rect(160, 90, 230, 100)), | ||
RecognizedTextElement("SE", Rect(240, 90, 260, 100)), | ||
) | ||
), | ||
) | ||
), | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("BIC:", Rect(50, 110, 90, 120)), | ||
RecognizedTextElement("DEUTEDEHH210", Rect(50, 110, 170, 120)), | ||
) | ||
), | ||
) | ||
), | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Bank:", Rect(50, 130, 100, 140)), | ||
RecognizedTextElement("Deutsche", Rect(110, 130, 190, 140)), | ||
RecognizedTextElement("Bank", Rect(200, 130, 240, 140)), | ||
) | ||
), | ||
) | ||
), | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Verwendungszweck:", Rect(50, 150, 170, 160)), | ||
) | ||
), | ||
) | ||
), | ||
) | ||
) | ||
|
||
// For image size: 100 x 100 | ||
val fixture2 = RecognizedText(""" | ||
Bankverbindung | ||
IBAN: DE86210700200123010101 | ||
""".trimIndent(), | ||
blocks = listOf( | ||
RecognizedTextBlock( | ||
listOf( | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("Bankverbindung", Rect(5, 5, 19, 6)), | ||
) | ||
), | ||
RecognizedTextLine( | ||
listOf( | ||
RecognizedTextElement("IBAN:", Rect(5, 7, 10, 8)), | ||
RecognizedTextElement("DE86210700200123010101", Rect(11, 7, 33, 8)), | ||
) | ||
), | ||
) | ||
), | ||
) | ||
) | ||
|
||
} |