Meilenstein-Präfixe aus Klassennamen entfernt
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
/**
|
||||
* Sealed interface representing the complete outcome of document processing.
|
||||
* <p>
|
||||
* This interface models all possible document outcomes:
|
||||
* <ul>
|
||||
* <li>{@link PreCheckPassed}: Document passed all pre-checks</li>
|
||||
* <li>{@link PreCheckFailed}: Document failed a pre-check (deterministic content error: no usable text or page limit exceeded)</li>
|
||||
* <li>{@link TechnicalDocumentError}: Technical failure during candidate access or PDF extraction (I/O, access, parsing, etc.)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Design principles:
|
||||
* <ul>
|
||||
* <li>Exhaustive: All document processing outcomes are covered</li>
|
||||
* <li>Document-centric: Each outcome carries the source candidate for correlation and traceability</li>
|
||||
* <li>No exceptions: Results are encoded in the type system</li>
|
||||
* <li>Clear distinction: Deterministic content errors (PreCheckFailed) vs. technical failures (TechnicalDocumentError)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Error classification:
|
||||
* <ul>
|
||||
* <li>PreCheckPassed: Extraction succeeded and all pre-checks passed (ready for further processing)</li>
|
||||
* <li>PreCheckFailed: Extraction succeeded but deterministic content check failed (no usable text, page limit exceeded)</li>
|
||||
* <li>TechnicalDocumentError: Extraction failed due to technical issue (I/O, file access, PDF parsing, etc.)</li>
|
||||
* </ul>
|
||||
*/
|
||||
public sealed interface DocumentProcessingOutcome
|
||||
permits PreCheckPassed, PreCheckFailed, TechnicalDocumentError {
|
||||
// Marker interface; concrete implementations define structure
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
/**
|
||||
* Sealed interface representing the complete outcome of M3 document processing.
|
||||
* <p>
|
||||
* This interface models all four possible M3 document outcomes:
|
||||
* <ul>
|
||||
* <li>{@link M3PreCheckPassed}: Document passed all M3 pre-checks</li>
|
||||
* <li>{@link M3PreCheckFailed}: Document failed a pre-check (deterministic content error: no usable text or page limit exceeded)</li>
|
||||
* <li>{@link M3TechnicalDocumentError}: Technical failure during candidate access or PDF extraction (I/O, access, parsing, etc.)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Design principles:
|
||||
* <ul>
|
||||
* <li>Exhaustive: All M3 document processing outcomes are covered (exactly four cases)</li>
|
||||
* <li>Document-centric: Each outcome carries the source candidate for correlation and traceability</li>
|
||||
* <li>No exceptions: Results are encoded in the type system</li>
|
||||
* <li>Clear distinction: Deterministic content errors (M3PreCheckFailed) vs. technical failures (M3TechnicalDocumentError)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Error classification:
|
||||
* <ul>
|
||||
* <li>M3PreCheckPassed: Extraction succeeded and all pre-checks passed (ready for M4+)</li>
|
||||
* <li>M3PreCheckFailed: Extraction succeeded but deterministic content check failed (no usable text, page limit exceeded)</li>
|
||||
* <li>M3TechnicalDocumentError: Extraction failed due to technical issue (I/O, file access, PDF parsing, etc.)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since M3-AP-006
|
||||
*/
|
||||
public sealed interface M3DocumentProcessingOutcome
|
||||
permits M3PreCheckPassed, M3PreCheckFailed, M3TechnicalDocumentError {
|
||||
// Marker interface; concrete implementations define structure
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
/**
|
||||
* Sealed interface representing the outcome of M3 document pre-checks.
|
||||
* <p>
|
||||
* This interface introduced in AP-001 establishes the architectural
|
||||
* pattern for M3 pre-check results. The actual pre-check logic (fachlich validation
|
||||
* such as "brauchbarer Text" and "Seitenlimit") is implemented in AP-004 via
|
||||
* {@link de.gecheckt.pdf.umbenenner.application.service.M3PreCheckEvaluator}.
|
||||
* <p>
|
||||
* There are two allowed implementations:
|
||||
* <ul>
|
||||
* <li>{@link M3PreCheckPassed}: Document passed all M3 pre-checks and is ready for KI integration</li>
|
||||
* <li>{@link M3PreCheckFailed}: Document failed an M3 pre-check and will not proceed further in this run</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Design principles:
|
||||
* <ul>
|
||||
* <li>Sealed: enforces exhaustive handling of all cases</li>
|
||||
* <li>Carries both success path ({@link M3PreCheckPassed}) and failure reason ({@link M3PreCheckFailed})</li>
|
||||
* <li>Defined early (AP-001) to ensure architecture is established before logic arrives</li>
|
||||
* <li>Future-extensible for additional pre-check variants in later milestones</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since M3-AP-001
|
||||
*/
|
||||
public sealed interface M3ProcessingDecision
|
||||
permits M3PreCheckPassed, M3PreCheckFailed {
|
||||
// Marker interface; concrete implementations define structure
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a document that failed an M3 pre-check.
|
||||
* Represents a document that failed a pre-check.
|
||||
* <p>
|
||||
* This result encapsulates:
|
||||
* <ul>
|
||||
@@ -22,12 +22,11 @@ import java.util.Objects;
|
||||
*
|
||||
* @param candidate the source document metadata
|
||||
* @param failureReason a human-readable explanation of the pre-check failure
|
||||
* @since M3-AP-001
|
||||
*/
|
||||
public record M3PreCheckFailed(
|
||||
public record PreCheckFailed(
|
||||
SourceDocumentCandidate candidate,
|
||||
String failureReason
|
||||
) implements M3ProcessingDecision, M3DocumentProcessingOutcome {
|
||||
) implements ProcessingDecision, DocumentProcessingOutcome {
|
||||
/**
|
||||
* Constructor with validation.
|
||||
*
|
||||
@@ -36,11 +35,11 @@ public record M3PreCheckFailed(
|
||||
* @throws NullPointerException if either parameter is null
|
||||
* @throws IllegalArgumentException if failureReason is empty
|
||||
*/
|
||||
public M3PreCheckFailed {
|
||||
public PreCheckFailed {
|
||||
Objects.requireNonNull(candidate, "candidate must not be null");
|
||||
Objects.requireNonNull(failureReason, "failureReason must not be null");
|
||||
if (failureReason.isEmpty()) {
|
||||
throw new IllegalArgumentException("failureReason must not be empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
/**
|
||||
* Enumeration of M3 pre-check failure reasons.
|
||||
* Enumeration of pre-check failure reasons.
|
||||
* <p>
|
||||
* These are the deterministic content errors that can occur during M3 pre-check evaluation.
|
||||
* These are the deterministic content errors that can occur during pre-check evaluation.
|
||||
* They distinguish between failures in the document content versus technical extraction failures.
|
||||
* <p>
|
||||
* Deterministic content errors:
|
||||
@@ -12,19 +12,17 @@ package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
* <li>{@link #PAGE_LIMIT_EXCEEDED}: The document exceeds the configured page limit.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Note: Technical extraction failures (I/O errors, PDFBox failures) are not M3 pre-check reasons;
|
||||
* Note: Technical extraction failures (I/O errors, PDFBox failures) are not pre-check reasons;
|
||||
* they are represented as {@link PdfExtractionTechnicalError} in the extraction result.
|
||||
*
|
||||
* @since M3-AP-004
|
||||
*/
|
||||
public enum M3PreCheckFailureReason {
|
||||
public enum PreCheckFailureReason {
|
||||
/**
|
||||
* The extracted PDF text, after normalization, contains no letters or digits.
|
||||
* <p>
|
||||
* This is a deterministic content error: reprocessing the same file in a later run
|
||||
* will have the same outcome unless the source file is changed.
|
||||
* <p>
|
||||
* In M3, retry logic: exactly 1 retry in a later batch run.
|
||||
* Retry logic: exactly 1 retry in a later batch run.
|
||||
*/
|
||||
NO_USABLE_TEXT("No usable text in extracted PDF content"),
|
||||
|
||||
@@ -33,13 +31,13 @@ public enum M3PreCheckFailureReason {
|
||||
* <p>
|
||||
* This is a deterministic content error: the page count will not change unless the source file is modified.
|
||||
* <p>
|
||||
* In M3, retry logic: exactly 1 retry in a later batch run.
|
||||
* Retry logic: exactly 1 retry in a later batch run.
|
||||
*/
|
||||
PAGE_LIMIT_EXCEEDED("Document page count exceeds configured limit");
|
||||
|
||||
private final String description;
|
||||
|
||||
M3PreCheckFailureReason(String description) {
|
||||
PreCheckFailureReason(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@@ -51,4 +49,4 @@ public enum M3PreCheckFailureReason {
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a document that passed all M3 pre-checks.
|
||||
* Represents a document that passed all pre-checks.
|
||||
* <p>
|
||||
* This result encapsulates:
|
||||
* <ul>
|
||||
@@ -11,17 +11,16 @@ import java.util.Objects;
|
||||
* <li>The successful PDF text extraction result</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* A document with this decision is ready to proceed to M4 and later milestones
|
||||
* A document with this decision is ready to proceed to further processing steps
|
||||
* (fingerprinting, persistence, KI integration, filename generation, target copy).
|
||||
*
|
||||
* @param candidate the source document metadata
|
||||
* @param extraction the successful text extraction result
|
||||
* @since M3-AP-001
|
||||
*/
|
||||
public record M3PreCheckPassed(
|
||||
public record PreCheckPassed(
|
||||
SourceDocumentCandidate candidate,
|
||||
PdfExtractionSuccess extraction
|
||||
) implements M3ProcessingDecision, M3DocumentProcessingOutcome {
|
||||
) implements ProcessingDecision, DocumentProcessingOutcome {
|
||||
/**
|
||||
* Constructor with validation.
|
||||
*
|
||||
@@ -29,8 +28,8 @@ public record M3PreCheckPassed(
|
||||
* @param extraction must be non-null
|
||||
* @throws NullPointerException if either parameter is null
|
||||
*/
|
||||
public M3PreCheckPassed {
|
||||
public PreCheckPassed {
|
||||
Objects.requireNonNull(candidate, "candidate must not be null");
|
||||
Objects.requireNonNull(extraction, "extraction must not be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
/**
|
||||
* Sealed interface representing the outcome of document pre-checks.
|
||||
* <p>
|
||||
* This interface establishes the architectural pattern for pre-check results.
|
||||
* The actual pre-check logic (fachlich validation such as "brauchbarer Text" and "Seitenlimit")
|
||||
* is implemented via {@link de.gecheckt.pdf.umbenenner.application.service.PreCheckEvaluator}.
|
||||
* <p>
|
||||
* There are two allowed implementations:
|
||||
* <ul>
|
||||
* <li>{@link PreCheckPassed}: Document passed all pre-checks and is ready for further processing</li>
|
||||
* <li>{@link PreCheckFailed}: Document failed a pre-check and will not proceed further in this run</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Design principles:
|
||||
* <ul>
|
||||
* <li>Sealed: enforces exhaustive handling of all cases</li>
|
||||
* <li>Carries both success path ({@link PreCheckPassed}) and failure reason ({@link PreCheckFailed})</li>
|
||||
* <li>Defined early to ensure architecture is established before logic arrives</li>
|
||||
* <li>Future-extensible for additional pre-check variants in later milestones</li>
|
||||
* </ul>
|
||||
*/
|
||||
public sealed interface ProcessingDecision
|
||||
permits PreCheckPassed, PreCheckFailed {
|
||||
// Marker interface; concrete implementations define structure
|
||||
}
|
||||
@@ -20,19 +20,18 @@ import java.util.Objects;
|
||||
* <li>Out of memory during extraction</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* This is distinct from {@link M3ExtractedContentError}, which represents problems with the document
|
||||
* This is distinct from content errors, which represent problems with the document
|
||||
* content itself rather than infrastructure failures.
|
||||
*
|
||||
* @param candidate the source document metadata
|
||||
* @param errorMessage a description of the technical failure
|
||||
* @param cause the underlying exception, if any (may be null)
|
||||
* @since M3-AP-006
|
||||
*/
|
||||
public record M3TechnicalDocumentError(
|
||||
public record TechnicalDocumentError(
|
||||
SourceDocumentCandidate candidate,
|
||||
String errorMessage,
|
||||
Throwable cause
|
||||
) implements M3DocumentProcessingOutcome {
|
||||
) implements DocumentProcessingOutcome {
|
||||
/**
|
||||
* Constructor with validation.
|
||||
*
|
||||
@@ -42,11 +41,11 @@ public record M3TechnicalDocumentError(
|
||||
* @throws NullPointerException if candidate or errorMessage is null
|
||||
* @throws IllegalArgumentException if errorMessage is empty
|
||||
*/
|
||||
public M3TechnicalDocumentError {
|
||||
public TechnicalDocumentError {
|
||||
Objects.requireNonNull(candidate, "candidate must not be null");
|
||||
Objects.requireNonNull(errorMessage, "errorMessage must not be null");
|
||||
if (errorMessage.isEmpty()) {
|
||||
throw new IllegalArgumentException("errorMessage must not be empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,34 +3,34 @@
|
||||
* <p>
|
||||
* This package contains the fundamental domain entities and status models required for document processing:
|
||||
* <ul>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus} — enumeration of all valid document processing states (M2-AP-001)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.RunId} — unique identifier for a batch run (M2-AP-003)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.BatchRunContext} — technical context for a batch run (M2-AP-003)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentCandidate} — discovered PDF from source folder (M3-AP-001)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentLocator} — opaque locator passed from scan adapter to extraction adapter (M3-AP-001)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PdfPageCount} — typed page count validation (M3-AP-001)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PdfExtractionResult} — sealed result of PDF text extraction (M3-AP-001)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.M3ProcessingDecision} — sealed result of M3 pre-checks (M3-AP-001)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus} — enumeration of all valid document processing states</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.RunId} — unique identifier for a batch run</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.BatchRunContext} — technical context for a batch run</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentCandidate} — discovered PDF from source folder</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentLocator} — opaque locator passed from scan adapter to extraction adapter</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PdfPageCount} — typed page count validation</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PdfExtractionResult} — sealed result of PDF text extraction</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingDecision} — sealed result of pre-checks</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Additional classes introduced in M3:
|
||||
* Additional classes:
|
||||
* <ul>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.M3PreCheckFailureReason} — enumeration of M3 pre-check failure reasons (M3-AP-004)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.M3DocumentProcessingOutcome} — sealed interface for all M3 document processing outcomes (M3-AP-006)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.M3TechnicalDocumentError} — technical failure during extraction (M3-AP-006)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PreCheckFailureReason} — enumeration of pre-check failure reasons</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.DocumentProcessingOutcome} — sealed interface for all document processing outcomes</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.TechnicalDocumentError} — technical failure during extraction</li>
|
||||
* </ul>
|
||||
*
|
||||
* Implementation classes:
|
||||
* <ul>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.M3PreCheckPassed} — document passed M3 pre-checks (M3-AP-001, M3-AP-004, M3-AP-006)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.M3PreCheckFailed} — document failed M3 pre-check (M3-AP-001, M3-AP-004, M3-AP-006)</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PreCheckPassed} — document passed pre-checks</li>
|
||||
* <li>{@link de.gecheckt.pdf.umbenenner.domain.model.PreCheckFailed} — document failed pre-check</li>
|
||||
* </ul>
|
||||
*
|
||||
* M3 Document Processing Outcome Model (M3-AP-006):
|
||||
* The complete M3 document processing pipeline results in one of three outcomes, all implementing
|
||||
* {@link de.gecheckt.pdf.umbenenner.domain.model.M3DocumentProcessingOutcome}:
|
||||
* Document Processing Outcome Model:
|
||||
* The complete document processing pipeline results in one of three outcomes, all implementing
|
||||
* {@link de.gecheckt.pdf.umbenenner.domain.model.DocumentProcessingOutcome}:
|
||||
* <ul>
|
||||
* <li>Pre-check passed: Document text extracted and validated successfully (ready for M4+)</li>
|
||||
* <li>Pre-check passed: Document text extracted and validated successfully (ready for further processing)</li>
|
||||
* <li>Pre-check failed: Deterministic content error (no usable text, page limit exceeded)</li>
|
||||
* <li>Technical document error: Infrastructure or parsing failure (I/O, access, PDF parsing)</li>
|
||||
* </ul>
|
||||
@@ -41,7 +41,5 @@
|
||||
* <li>Immutable value objects or enumerations</li>
|
||||
* <li>Reusable across all layers via the Application and Adapter contracts</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since M2-AP-001
|
||||
*/
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests for document processing outcome types.
|
||||
* <p>
|
||||
* Verifies that all outcome types are properly created and validated.
|
||||
*/
|
||||
class DocumentProcessingOutcomeTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
private SourceDocumentCandidate candidate;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
Path pdfFile = tempDir.resolve("doc.pdf");
|
||||
Files.createFile(pdfFile);
|
||||
SourceDocumentLocator locator = new SourceDocumentLocator(pdfFile.toString());
|
||||
candidate = new SourceDocumentCandidate("doc.pdf", 1024L, locator);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testTechnicalDocumentError_ValidConstruction() {
|
||||
// Act
|
||||
var error = new TechnicalDocumentError(candidate, "I/O error", null);
|
||||
|
||||
// Assert
|
||||
assertEquals(candidate, error.candidate());
|
||||
assertEquals("I/O error", error.errorMessage());
|
||||
assertNull(error.cause());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTechnicalDocumentError_WithCause() {
|
||||
// Arrange
|
||||
var cause = new RuntimeException("File not found");
|
||||
|
||||
// Act
|
||||
var error = new TechnicalDocumentError(candidate, "I/O error", cause);
|
||||
|
||||
// Assert
|
||||
assertEquals(cause, error.cause());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTechnicalDocumentError_WithNullCandidate_ThrowsException() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new TechnicalDocumentError(null, "Error", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTechnicalDocumentError_WithNullErrorMessage_ThrowsException() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new TechnicalDocumentError(candidate, null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTechnicalDocumentError_WithEmptyErrorMessage_ThrowsException() {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new TechnicalDocumentError(candidate, "", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTechnicalDocumentError_IsDocumentProcessingOutcome() {
|
||||
// Verify type relationship
|
||||
var error = new TechnicalDocumentError(candidate, "Error", null);
|
||||
assertInstanceOf(DocumentProcessingOutcome.class, error);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPreCheckPassed_IsDocumentProcessingOutcome() {
|
||||
// Verify type relationship
|
||||
var extraction = new PdfExtractionSuccess("text", new PdfPageCount(1));
|
||||
var passed = new PreCheckPassed(candidate, extraction);
|
||||
assertInstanceOf(DocumentProcessingOutcome.class, passed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPreCheckFailed_IsDocumentProcessingOutcome() {
|
||||
// Verify type relationship
|
||||
var failed = new PreCheckFailed(candidate, "Test failure reason");
|
||||
assertInstanceOf(DocumentProcessingOutcome.class, failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAllOutcomesAreExhaustive() {
|
||||
// This test verifies that the outcome types are the only implementations
|
||||
var extraction = new PdfExtractionSuccess("text", new PdfPageCount(1));
|
||||
|
||||
DocumentProcessingOutcome[] outcomes = {
|
||||
new PreCheckPassed(candidate, extraction),
|
||||
new PreCheckFailed(candidate, "Deterministic content failure"),
|
||||
new TechnicalDocumentError(candidate, "Technical extraction error", null)
|
||||
};
|
||||
|
||||
for (DocumentProcessingOutcome outcome : outcomes) {
|
||||
assertInstanceOf(DocumentProcessingOutcome.class, outcome);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package de.gecheckt.pdf.umbenenner.domain.model;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests for M3 document processing outcome types.
|
||||
* <p>
|
||||
* Verifies that all four outcome types are properly created and validated.
|
||||
*/
|
||||
class M3DocumentProcessingOutcomeTest {
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
private SourceDocumentCandidate candidate;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
Path pdfFile = tempDir.resolve("doc.pdf");
|
||||
Files.createFile(pdfFile);
|
||||
SourceDocumentLocator locator = new SourceDocumentLocator(pdfFile.toString());
|
||||
candidate = new SourceDocumentCandidate("doc.pdf", 1024L, locator);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testM3TechnicalDocumentError_ValidConstruction() {
|
||||
// Act
|
||||
var error = new M3TechnicalDocumentError(candidate, "I/O error", null);
|
||||
|
||||
// Assert
|
||||
assertEquals(candidate, error.candidate());
|
||||
assertEquals("I/O error", error.errorMessage());
|
||||
assertNull(error.cause());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3TechnicalDocumentError_WithCause() {
|
||||
// Arrange
|
||||
var cause = new RuntimeException("File not found");
|
||||
|
||||
// Act
|
||||
var error = new M3TechnicalDocumentError(candidate, "I/O error", cause);
|
||||
|
||||
// Assert
|
||||
assertEquals(cause, error.cause());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3TechnicalDocumentError_WithNullCandidate_ThrowsException() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new M3TechnicalDocumentError(null, "Error", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3TechnicalDocumentError_WithNullErrorMessage_ThrowsException() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new M3TechnicalDocumentError(candidate, null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3TechnicalDocumentError_WithEmptyErrorMessage_ThrowsException() {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new M3TechnicalDocumentError(candidate, "", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3TechnicalDocumentError_IsM3DocumentProcessingOutcome() {
|
||||
// Verify type relationship
|
||||
var error = new M3TechnicalDocumentError(candidate, "Error", null);
|
||||
assertInstanceOf(M3DocumentProcessingOutcome.class, error);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3PreCheckPassed_IsM3DocumentProcessingOutcome() {
|
||||
// Verify type relationship
|
||||
var extraction = new PdfExtractionSuccess("text", new PdfPageCount(1));
|
||||
var passed = new M3PreCheckPassed(candidate, extraction);
|
||||
assertInstanceOf(M3DocumentProcessingOutcome.class, passed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testM3PreCheckFailed_IsM3DocumentProcessingOutcome() {
|
||||
// Verify type relationship
|
||||
var failed = new M3PreCheckFailed(candidate, "Test failure reason");
|
||||
assertInstanceOf(M3DocumentProcessingOutcome.class, failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAllThreeOutcomesAreExhaustive() {
|
||||
// This test verifies that the three outcome types are the only implementations
|
||||
// M3 has exactly three outcome types: passed, failed (deterministic), and technical error
|
||||
|
||||
var extraction = new PdfExtractionSuccess("text", new PdfPageCount(1));
|
||||
|
||||
M3DocumentProcessingOutcome[] outcomes = {
|
||||
new M3PreCheckPassed(candidate, extraction),
|
||||
new M3PreCheckFailed(candidate, "Deterministic content failure"),
|
||||
new M3TechnicalDocumentError(candidate, "Technical extraction error", null)
|
||||
};
|
||||
|
||||
for (M3DocumentProcessingOutcome outcome : outcomes) {
|
||||
assertInstanceOf(M3DocumentProcessingOutcome.class, outcome);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user