This is an automated email from the ASF dual-hosted git repository.

apupier pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 18e97b132479 Improve integration tests assertions for docling
18e97b132479 is described below

commit 18e97b1324794ba269c266611314d12c5aac7b16
Author: AurĂ©lien Pupier <[email protected]>
AuthorDate: Tue Jan 27 15:11:43 2026 +0100

    Improve integration tests assertions for docling
    
    Several tests were checking only that the result was not null and empty.
    Now checking some subparts of expected result and the file type.
    
    Signed-off-by: AurĂ©lien Pupier <[email protected]>
---
 .../integration/DoclingServeProducerIT.java        | 106 ++++++++++-----------
 .../docling/integration/MetadataExtractionIT.java  |  32 ++++---
 .../docling/integration/OcrExtractionIT.java       |  34 +++----
 3 files changed, 84 insertions(+), 88 deletions(-)

diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
index 859eb0b02f6f..466f07207852 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/DoclingServeProducerIT.java
@@ -22,12 +22,15 @@ import java.nio.file.Path;
 
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.docling.ConversionStatus;
+import org.apache.camel.component.docling.ConversionStatus.Status;
 import org.apache.camel.component.docling.DoclingHeaders;
 import org.apache.camel.component.docling.DoclingOperations;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
 import org.junit.jupiter.api.io.TempDir;
 
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
@@ -45,64 +48,60 @@ class DoclingServeProducerIT extends DoclingITestSupport {
     Path outputDir;
 
     @Test
-    public void testMarkdownConversionWithDoclingServe() throws Exception {
+    void testMarkdownConversionWithDoclingServe() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-markdown-serve",
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(result);
-        assertTrue(result.length() > 0);
+        assertThat(result).containsIgnoringCase("Test Document");
 
         LOG.info("Successfully converted document to Markdown");
     }
 
     @Test
-    public void testHtmlConversionWithDoclingServe() throws Exception {
+    void testHtmlConversionWithDoclingServe() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-html-serve",
                 testFile.toString(),
                 DoclingHeaders.OPERATION, DoclingOperations.CONVERT_TO_HTML, 
String.class);
 
-        assertNotNull(result);
-        assertTrue(result.length() > 0);
+        assertThat(result).containsIgnoringCase("<h1>Test Document</h1>");
 
         LOG.info("Successfully converted document to HTML");
     }
 
     @Test
-    public void testUrlConversionWithDoclingServe() throws Exception {
+    void testUrlConversionWithDoclingServe() throws Exception {
         // Test converting a document from a URL
         String url = "https://arxiv.org/pdf/2501.17887";;
 
         String result = template.requestBody("direct:convert-url-serve", url, 
String.class);
 
-        assertNotNull(result);
-        assertTrue(result.length() > 0);
+        assertThat(result).containsIgnoringCase("An Efficient Open-Source 
Toolkit");
 
         LOG.info("Successfully converted document from URL");
     }
 
     @Test
-    public void testJsonConversionWithDoclingServe() throws Exception {
+    void testJsonConversionWithDoclingServe() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-json-serve",
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(result);
-        assertTrue(result.length() > 0);
-        // JSON response should contain some structure
-        assertTrue(result.contains("{") || result.contains("["));
+        
assertThatJson(result).node("schema_name").asString().isEqualTo("DoclingDocument");
+        
assertThatJson(result).inPath("texts[*].text").isArray().contains("Test 
Document",
+                "This is a test document for Docling-Serve processing.");
 
         LOG.info("Successfully converted document to JSON");
     }
 
     @Test
-    public void testConvertAndWriteToFile() throws Exception {
+    void testConvertAndWriteToFile() throws Exception {
         Path testFile = createTestFile();
 
         // Send the file path to the route that converts and writes to file
@@ -110,91 +109,82 @@ class DoclingServeProducerIT extends DoclingITestSupport {
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString());
 
-        // Verify the output file was created
         File outputFile = new File(outputDir.toFile(), "converted-output.md");
-        assertTrue(outputFile.exists(), "Output file should exist");
-        assertTrue(outputFile.length() > 0, "Output file should not be empty");
-
-        // Read and verify content
-        String content = Files.readString(outputFile.toPath());
-        assertNotNull(content);
-        assertTrue(content.length() > 0);
+        assertThat(outputFile.toPath())
+                .exists()
+                .content().containsIgnoringCase("Test Document");
 
         LOG.info("Successfully converted document and wrote to file: {}", 
outputFile.getAbsolutePath());
         LOG.info("Output file size: {} bytes", outputFile.length());
     }
 
     @Test
-    public void testAsyncMarkdownConversion() throws Exception {
+    void testAsyncMarkdownConversion() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-async-markdown",
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(result, "Async conversion result should not be null");
-        assertTrue(result.length() > 0, "Async conversion result should not be 
empty");
+        assertThat(result).containsIgnoringCase("Test Document");
 
         LOG.info("Successfully converted document to Markdown using async 
mode");
     }
 
     @Test
-    public void testAsyncHtmlConversion() throws Exception {
+    void testAsyncHtmlConversion() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-async-html",
                 testFile.toString(),
                 DoclingHeaders.OPERATION, DoclingOperations.CONVERT_TO_HTML, 
String.class);
 
-        assertNotNull(result, "Async HTML conversion result should not be 
null");
-        assertTrue(result.length() > 0, "Async HTML conversion result should 
not be empty");
+        assertThat(result).containsIgnoringCase("<h1>Test Document</h1>");
 
         LOG.info("Successfully converted document to HTML using async mode");
     }
 
     @Test
-    public void testAsyncJsonConversion() throws Exception {
+    void testAsyncJsonConversion() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-async-json",
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(result, "Async JSON conversion result should not be 
null");
-        assertTrue(result.length() > 0, "Async JSON conversion result should 
not be empty");
-        assertTrue(result.contains("{") || result.contains("["), "JSON result 
should contain JSON structure");
+        
assertThatJson(result).node("schema_name").asString().isEqualTo("DoclingDocument");
+        
assertThatJson(result).inPath("texts[*].text").isArray().contains("Test 
Document",
+                "This is a test document for Docling-Serve processing.");
 
         LOG.info("Successfully converted document to JSON using async mode");
     }
 
     @Test
-    public void testAsyncUrlConversion() throws Exception {
+    void testAsyncUrlConversion() throws Exception {
         String url = "https://arxiv.org/pdf/2501.17887";;
 
         String result = template.requestBody("direct:convert-async-url", url, 
String.class);
 
-        assertNotNull(result, "Async URL conversion result should not be 
null");
-        assertTrue(result.length() > 0, "Async URL conversion result should 
not be empty");
+        assertThat(result).containsIgnoringCase("An Efficient Open-Source 
Toolkit");
 
         LOG.info("Successfully converted document from URL using async mode");
     }
 
     @Test
-    public void testAsyncConversionWithCustomTimeout() throws Exception {
+    void testAsyncConversionWithCustomTimeout() throws Exception {
         Path testFile = createTestFile();
 
         String result = 
template.requestBodyAndHeader("direct:convert-async-custom-timeout",
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(result, "Async conversion with custom timeout should not 
be null");
-        assertTrue(result.length() > 0, "Async conversion with custom timeout 
should not be empty");
+        assertThat(result).contains("This is a test document for Docling-Serve 
processing.");
 
         LOG.info("Successfully converted document using async mode with custom 
timeout");
     }
 
     @Test
-    public void testAsyncConversionWithHeaderOverride() throws Exception {
+    void testAsyncConversionWithHeaderOverride() throws Exception {
         Path testFile = createTestFile();
 
         // Use sync endpoint but override with async header
@@ -209,14 +199,13 @@ class DoclingServeProducerIT extends DoclingITestSupport {
                     }
                 }, String.class);
 
-        assertNotNull(result, "Async conversion via header override should not 
be null");
-        assertTrue(result.length() > 0, "Async conversion via header override 
should not be empty");
+        assertThat(result).contains("This is a test document for Docling-Serve 
processing.");
 
         LOG.info("Successfully converted document using async mode via header 
override");
     }
 
     @Test
-    public void testSubmitAsyncConversion() throws Exception {
+    void testSubmitAsyncConversion() throws Exception {
         Path testFile = createTestFile();
 
         // Submit async conversion and get task ID
@@ -224,14 +213,13 @@ class DoclingServeProducerIT extends DoclingITestSupport {
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(taskId, "Task ID should not be null");
-        assertTrue(taskId.length() > 0, "Task ID should not be empty");
+        assertThat(taskId).startsWith("task-");
 
         LOG.info("Successfully submitted async conversion with task ID: {}", 
taskId);
     }
 
     @Test
-    public void testCheckConversionStatus() throws Exception {
+    void testCheckConversionStatus() throws Exception {
         Path testFile = createTestFile();
 
         // First, submit async conversion
@@ -249,13 +237,13 @@ class DoclingServeProducerIT extends DoclingITestSupport {
 
         assertNotNull(status, "Status should not be null");
         assertNotNull(status.getTaskId(), "Status task ID should not be null");
-        assertNotNull(status.getStatus(), "Status state should not be null");
+        assertThat(status.getStatus()).isEqualTo(Status.COMPLETED);
 
         LOG.info("Successfully checked status for task {}: {}", taskId, 
status.getStatus());
     }
 
     @Test
-    public void testCustomAsyncWorkflow() throws Exception {
+    void testCustomAsyncWorkflow() throws Exception {
         Path testFile = createTestFile();
 
         // Custom workflow: submit, poll until complete, get result
@@ -293,13 +281,14 @@ class DoclingServeProducerIT extends DoclingITestSupport {
         }
 
         if (status.getResult() != null) {
+            // TODO: this check can never happen as there is an if condition 
before. The status.getResult() is actually null, is it expected or a bug?
             assertTrue(status.getResult().length() > 0, "Result should not be 
empty");
             LOG.info("Successfully retrieved result: {} characters", 
status.getResult().length());
         }
     }
 
     @Test
-    public void testCustomPollingWorkflowWithRoute() throws Exception {
+    void testCustomPollingWorkflowWithRoute() throws Exception {
         Path testFile = createTestFile();
 
         // This test demonstrates using the built-in async mode with a route
@@ -308,8 +297,7 @@ class DoclingServeProducerIT extends DoclingITestSupport {
                 testFile.toString(),
                 DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), 
String.class);
 
-        assertNotNull(result, "Result should not be null");
-        assertTrue(result.length() > 0, "Result should not be empty");
+        assertThat(result).contains("This is a test document for Docling-Serve 
processing.");
 
         LOG.info("Custom polling workflow (using built-in async mode) 
completed successfully with {} characters",
                 result.length());
@@ -317,9 +305,19 @@ class DoclingServeProducerIT extends DoclingITestSupport {
 
     private Path createTestFile() throws Exception {
         Path tempFile = Files.createTempFile("docling-serve-test", ".md");
-        Files.write(tempFile,
-                "# Test Document\n\nThis is a test document for Docling-Serve 
processing.\n\n## Section 1\n\nSome content here.\n\n- List item 1\n- List item 
2\n"
-                        .getBytes());
+        Files.writeString(tempFile,
+                """
+                        # Test Document
+
+                        This is a test document for Docling-Serve processing.
+
+                        ## Section 1
+
+                        Some content here.
+
+                        - List item 1
+                        - List item 2
+                        """);
         return tempFile;
     }
 
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
index 074f27b841bf..e6ad1415815a 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/MetadataExtractionIT.java
@@ -37,10 +37,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
  * Integration test for metadata extraction operations using test-infra for 
container management.
  */
 @DisabledIfSystemProperty(named = "ci.env.name", matches = ".*", 
disabledReason = "Too much resources on GitHub Actions")
-public class MetadataExtractionIT extends DoclingITestSupport {
+class MetadataExtractionIT extends DoclingITestSupport {
 
     @Test
-    public void testBasicMetadataExtraction() throws Exception {
+    void testBasicMetadataExtraction() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         DocumentMetadata metadata = 
template.requestBody("direct:extract-metadata",
@@ -86,7 +86,7 @@ public class MetadataExtractionIT extends DoclingITestSupport 
{
     }
 
     @Test
-    public void testMetadataExtractionWithHeaders() throws Exception {
+    void testMetadataExtractionWithHeaders() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         // Extract metadata with headers enabled (default behavior)
@@ -96,11 +96,13 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
         assertNotNull(metadata, "Metadata should not be null");
         assertNotNull(metadata.getFileName(), "File name should be extracted");
 
+        // TODO: verify headers are populated
+
         LOG.info("Successfully extracted metadata with headers: {}", metadata);
     }
 
     @Test
-    public void testMetadataExtractionWithoutHeaders() throws Exception {
+    void testMetadataExtractionWithoutHeaders() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         DocumentMetadata metadata = 
template.requestBody("direct:extract-metadata-no-headers",
@@ -113,7 +115,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
     }
 
     @Test
-    public void testMetadataExtractionWithAllFields() throws Exception {
+    void testMetadataExtractionWithAllFields() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         DocumentMetadata metadata = 
template.requestBody("direct:extract-metadata-all-fields",
@@ -131,7 +133,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
     }
 
     @Test
-    public void testMetadataExtractionWithRawMetadata() throws Exception {
+    void testMetadataExtractionWithRawMetadata() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         DocumentMetadata metadata = 
template.requestBody("direct:extract-metadata-with-raw",
@@ -150,7 +152,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
     }
 
     @Test
-    public void testMetadataExtractionFromUrl() throws Exception {
+    void testMetadataExtractionFromUrl() throws Exception {
         // Test extracting metadata from a URL (if docling-serve supports it)
         String url = "https://arxiv.org/pdf/2501.17887";;
 
@@ -164,7 +166,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
     }
 
     @Test
-    public void testMetadataHelperMethods() throws Exception {
+    void testMetadataHelperMethods() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         DocumentMetadata metadata = 
template.requestBody("direct:extract-metadata",
@@ -173,13 +175,13 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
         assertNotNull(metadata, "Metadata should not be null");
 
         // Test helper methods
-        assertTrue(metadata.getFileName() != null, "Should have file name");
+        assertNotNull(metadata.getFileName(), "Should have file name");
 
         LOG.info("Metadata helper methods tested successfully");
     }
 
     @Test
-    public void testMetadataToString() throws Exception {
+    void testMetadataToString() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         DocumentMetadata metadata = 
template.requestBody("direct:extract-metadata",
@@ -206,11 +208,13 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
         assertNotNull(metadata, "Metadata should not be null");
         assertNotNull(metadata.getFileName(), "File name should be extracted");
 
+        // TODO: the headers are not verified if they are really used or not
+
         LOG.info("Successfully verified metadata headers are populated");
     }
 
     @Test
-    public void testMetadataExtractionEmptyCustomFields() throws Exception {
+    void testMetadataExtractionEmptyCustomFields() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         // Extract metadata without extractAllMetadata flag
@@ -228,7 +232,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
     }
 
     @Test
-    public void testMetadataExtractionNoRawMetadata() throws Exception {
+    void testMetadataExtractionNoRawMetadata() throws Exception {
         Path testFile = createTestMarkdownFile();
 
         // Extract metadata without includeRawMetadata flag
@@ -247,7 +251,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
 
     private Path createTestMarkdownFile() throws Exception {
         Path tempFile = Files.createTempFile("docling-metadata-test", ".md");
-        Files.write(tempFile,
+        Files.writeString(tempFile,
                 """
                         # Test Document for Metadata Extraction
 
@@ -263,7 +267,7 @@ public class MetadataExtractionIT extends 
DoclingITestSupport {
                         ## Section 2
 
                         More content with some **bold** text and *italic* text.
-                        """.getBytes());
+                        """);
         return tempFile;
     }
 
diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
index 3f354e989a05..59613b16b3c3 100644
--- 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
@@ -39,7 +39,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
@@ -83,8 +84,7 @@ class OcrExtractionIT extends CamelTestSupport {
 
         String result = template.requestBody("direct:ocr-extract-text", 
testImage.toString(), String.class);
 
-        assertNotNull(result, "OCR result should not be null");
-        assertTrue(result.length() > 0, "OCR result should not be empty");
+        assertThat(result).isNotBlank();
 
         LOG.info("OCR extraction result:\n{}", result);
 
@@ -106,13 +106,12 @@ class OcrExtractionIT extends CamelTestSupport {
     }
 
     @Test
-    public void testOcrMarkdownConversionFromImage() throws Exception {
+    void testOcrMarkdownConversionFromImage() throws Exception {
         Path testImage = createTestImageWithText();
 
         String result = template.requestBody("direct:ocr-convert-markdown", 
testImage.toString(), String.class);
 
-        assertNotNull(result, "Markdown result should not be null");
-        assertTrue(result.length() > 0, "Markdown result should not be empty");
+        assertThat(result).isNotBlank();
 
         checkExtractedText(result);
 
@@ -121,14 +120,13 @@ class OcrExtractionIT extends CamelTestSupport {
     }
 
     @Test
-    public void testOcrJsonConversionFromImage() throws Exception {
+    void testOcrJsonConversionFromImage() throws Exception {
         Path testImage = createTestImageWithText();
 
         String result = template.requestBody("direct:ocr-convert-json", 
testImage.toString(), String.class);
 
-        assertNotNull(result, "JSON result should not be null");
-        assertTrue(result.length() > 0, "JSON result should not be empty");
-        assertTrue(result.contains("{") || result.contains("["), "Result 
should be valid JSON");
+        
assertThatJson(result).node("schema_name").asString().isEqualTo("DoclingDocument");
+        assertThatJson(result).inPath("texts[*].text").isArray().contains("OCR 
Test Document");
 
         checkExtractedText(result);
 
@@ -137,13 +135,12 @@ class OcrExtractionIT extends CamelTestSupport {
     }
 
     @Test
-    public void testOcrWithAsyncMode() throws Exception {
+    void testOcrWithAsyncMode() throws Exception {
         Path testImage = createTestImageWithText();
 
         String result = template.requestBody("direct:ocr-async-extract", 
testImage.toString(), String.class);
 
-        assertNotNull(result, "Async OCR result should not be null");
-        assertTrue(result.length() > 0, "Async OCR result should not be 
empty");
+        assertThat(result).isNotBlank();
 
         checkExtractedText(result);
 
@@ -152,14 +149,12 @@ class OcrExtractionIT extends CamelTestSupport {
     }
 
     @Test
-    public void testOcrFromPngImage() throws Exception {
+    void testOcrFromPngImage() throws Exception {
         Path testImage = createTestPngImage();
 
         String result = template.requestBody("direct:ocr-extract-text", 
testImage.toString(), String.class);
 
-        assertNotNull(result, "OCR result from PNG should not be null");
-        assertTrue(result.length() > 0, "OCR result from PNG should not be 
empty");
-
+        assertThat(result).isNotBlank();
         checkExtractedText(result);
 
         LOG.info("OCR extraction from PNG result:\n{}", result);
@@ -167,13 +162,12 @@ class OcrExtractionIT extends CamelTestSupport {
     }
 
     @Test
-    public void testOcrWithMultipleTextBlocks() throws Exception {
+    void testOcrWithMultipleTextBlocks() throws Exception {
         Path testImage = createImageWithMultipleTextBlocks();
 
         String result = template.requestBody("direct:ocr-extract-text", 
testImage.toString(), String.class);
 
-        assertNotNull(result, "OCR result should not be null");
-        assertTrue(result.length() > 0, "OCR result should not be empty");
+        assertThat(result).isNotBlank();
 
         // Verify that at least some of the expected text was extracted
         // Note: OCR may not be 100% accurate, so we check for partial matches

Reply via email to