Meilenstein 1 vor Implementierung der Spezifikation

This commit is contained in:
2026-03-26 01:03:55 +01:00
parent fc4386ac99
commit 1b4b22b073
27 changed files with 873 additions and 374 deletions

View File

@@ -0,0 +1,218 @@
package de.gecheckt.asv.cli;
import de.gecheckt.asv.domain.model.Field;
import de.gecheckt.asv.domain.model.InputFile;
import de.gecheckt.asv.domain.model.Message;
import de.gecheckt.asv.domain.model.Segment;
import de.gecheckt.asv.parser.InputFileParseException;
import de.gecheckt.asv.parser.InputFileParser;
import de.gecheckt.asv.validation.InputFileValidator;
import de.gecheckt.asv.validation.model.ValidationError;
import de.gecheckt.asv.validation.model.ValidationResult;
import de.gecheckt.asv.validation.model.ValidationSeverity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
/**
* Zusätzliche Unittests für AsvValidatorApplication.
*/
class AsvValidatorApplicationAdditionalTest {
@TempDir
Path tempDir;
@Test
void testRunWithValidFileShouldReturnSuccessExitCode() throws InputFileParseException, IOException {
// Given
InputFileParser parser = mock(InputFileParser.class);
InputFileValidator validator = mock(InputFileValidator.class);
ValidationResultPrinter printer = mock(ValidationResultPrinter.class);
AsvValidatorApplication app = new AsvValidatorApplication(parser, validator, printer);
// Create a test file
Path testFile = tempDir.resolve("valid-file.txt");
String validContent = "HDR|TestHeader\n" +
"DTL|TestData|MoreData\n" +
"TRL|3";
Files.writeString(testFile, validContent);
String[] args = {testFile.toString()};
// Create real objects instead of mocks for final classes
Field hdrField1 = new Field(1, "HDR");
Field hdrField2 = new Field(2, "TestHeader");
Segment hdrSegment = new Segment("HDR", 1, List.of(hdrField1, hdrField2));
Field dtlField1 = new Field(1, "DTL");
Field dtlField2 = new Field(2, "TestData");
Field dtlField3 = new Field(3, "MoreData");
Segment dtlSegment = new Segment("DTL", 2, List.of(dtlField1, dtlField2, dtlField3));
Field trlField1 = new Field(1, "TRL");
Field trlField2 = new Field(2, "3");
Segment trlSegment = new Segment("TRL", 3, List.of(trlField1, trlField2));
Message message = new Message(1, List.of(hdrSegment, dtlSegment, trlSegment));
InputFile inputFile = new InputFile("valid-file.txt", List.of(message));
// Mock the parser and validator behavior
when(parser.parse(anyString(), anyString())).thenReturn(inputFile);
// Create a real ValidationResult with no errors
ValidationResult validationResult = new ValidationResult(List.of());
when(validator.validate(inputFile)).thenReturn(validationResult);
// Capture System.out
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
// When
int exitCode = app.run(args);
// Then
assertEquals(0, exitCode);
// Verify that the printer was called
verify(printer).printToConsole(validationResult);
} finally {
// Restore System.out
System.setOut(originalOut);
}
}
@Test
void testRunWithInvalidFileShouldReturnValidationErrorsExitCode() throws InputFileParseException, IOException {
// Given
InputFileParser parser = mock(InputFileParser.class);
InputFileValidator validator = mock(InputFileValidator.class);
ValidationResultPrinter printer = mock(ValidationResultPrinter.class);
AsvValidatorApplication app = new AsvValidatorApplication(parser, validator, printer);
// Create an invalid test file (missing required segments)
Path testFile = tempDir.resolve("invalid-file.txt");
String invalidContent = "DTL|TestData|MoreData\n" + // Missing HDR
"DTL|MoreData|EvenMoreData\n"; // Missing TRL
Files.writeString(testFile, invalidContent);
String[] args = {testFile.toString()};
// Create real objects instead of mocks for final classes
Field dtlField1 = new Field(1, "DTL");
Field dtlField2 = new Field(2, "TestData");
Field dtlField3 = new Field(3, "MoreData");
Segment dtlSegment1 = new Segment("DTL", 1, List.of(dtlField1, dtlField2, dtlField3));
Field dtlField4 = new Field(1, "DTL");
Field dtlField5 = new Field(2, "MoreData");
Field dtlField6 = new Field(3, "EvenMoreData");
Segment dtlSegment2 = new Segment("DTL", 2, List.of(dtlField4, dtlField5, dtlField6));
Message message = new Message(1, List.of(dtlSegment1, dtlSegment2));
InputFile inputFile = new InputFile("invalid-file.txt", List.of(message));
// Mock the parser and validator behavior
when(parser.parse(anyString(), anyString())).thenReturn(inputFile);
// Create a real ValidationResult with errors
ValidationError error = new ValidationError(
"MISSING_SEGMENT",
"Required segment HDR is missing",
ValidationSeverity.ERROR,
"HDR",
1,
"HDR",
1,
null,
"HDR segment is required"
);
ValidationResult validationResult = new ValidationResult(List.of(error));
when(validator.validate(inputFile)).thenReturn(validationResult);
// Capture System.out
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
// When
int exitCode = app.run(args);
// Then
assertEquals(3, exitCode); // Validation errors exit code
// Verify that the printer was called
verify(printer).printToConsole(validationResult);
} finally {
// Restore System.out
System.setOut(originalOut);
}
}
/**
* Spezialisierter Test für den Fall, dass ein technisch lesbares/parstabares Dokument
* Validierungsfehler enthält und der CLI Exit-Code 3 zurückgibt.
*
* Dieser Test konzentriert sich explizit auf:
* 1. Parser liefert ein InputFile
* 2. Validator liefert ein ValidationResult mit mindestens einem ERROR
* 3. CLI gibt daraufhin Exit-Code 3 zurück
*/
@Test
void testParserReturnsInputFileAndValidatorReturnsErrorsShouldReturnExitCodeThree() throws InputFileParseException, IOException {
// Given
InputFileParser parser = mock(InputFileParser.class);
InputFileValidator validator = mock(InputFileValidator.class);
ValidationResultPrinter printer = mock(ValidationResultPrinter.class);
AsvValidatorApplication app = new AsvValidatorApplication(parser, validator, printer);
// Create a dummy test file (content doesn't matter since we're mocking the parser)
Path testFile = tempDir.resolve("dummy-file.txt");
Files.writeString(testFile, "dummy content");
String[] args = {testFile.toString()};
// Mock: Parser liefert ein gültiges InputFile
InputFile inputFile = mock(InputFile.class);
when(parser.parse(anyString(), anyString())).thenReturn(inputFile);
// Mock: Validator liefert ein ValidationResult mit mindestens einem ERROR
ValidationError validationError = new ValidationError(
"TEST_ERROR_CODE",
"Test error message",
ValidationSeverity.ERROR, // Wichtig: ValidationSeverity.ERROR
"TEST_SEGMENT",
1,
"TEST_FIELD",
1,
null,
"Test error description"
);
ValidationResult validationResultWithErrors = new ValidationResult(List.of(validationError));
when(validator.validate(inputFile)).thenReturn(validationResultWithErrors);
// When
int exitCode = app.run(args);
// Then
// Prüfe explizit, dass der Exit-Code 3 ist
assertEquals(3, exitCode, "CLI should return exit code 3 when validation errors occur");
// Verify that the printer was called with the validation result
verify(printer).printToConsole(validationResultWithErrors);
}
}

View File

@@ -0,0 +1,103 @@
package de.gecheckt.asv.cli;
import de.gecheckt.asv.parser.InputFileParser;
import de.gecheckt.asv.validation.InputFileValidator;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
/**
* Unittests für AsvValidatorApplication.
*/
class AsvValidatorApplicationTest {
@TempDir
Path tempDir;
@Test
void testRunWithNoArgumentsShouldPrintUsageAndReturnInvalidArgumentsExitCode() {
// Given
InputFileParser parser = mock(InputFileParser.class);
InputFileValidator validator = mock(InputFileValidator.class);
ValidationResultPrinter printer = mock(ValidationResultPrinter.class);
AsvValidatorApplication app = new AsvValidatorApplication(parser, validator, printer);
String[] args = {};
// Capture System.out
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
// When
int exitCode = app.run(args);
// Then
assertEquals(1, exitCode);
assertEquals(true, outContent.toString().contains("Verwendung:"), "Output should contain usage information");
} finally {
// Restore System.out
System.setOut(originalOut);
}
}
@Test
void testRunWithTooManyArgumentsShouldPrintUsageAndReturnInvalidArgumentsExitCode() {
// Given
InputFileParser parser = mock(InputFileParser.class);
InputFileValidator validator = mock(InputFileValidator.class);
ValidationResultPrinter printer = mock(ValidationResultPrinter.class);
AsvValidatorApplication app = new AsvValidatorApplication(parser, validator, printer);
String[] args = {"file1.txt", "file2.txt"};
// Capture System.out
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
// When
int exitCode = app.run(args);
// Then
assertEquals(1, exitCode);
assertEquals(true, outContent.toString().contains("Verwendung:"), "Output should contain usage information");
} finally {
// Restore System.out
System.setOut(originalOut);
}
}
@Test
void testRunWithNonExistentFileShouldReturnFileErrorExitCode() {
// Given
InputFileParser parser = mock(InputFileParser.class);
InputFileValidator validator = mock(InputFileValidator.class);
ValidationResultPrinter printer = mock(ValidationResultPrinter.class);
AsvValidatorApplication app = new AsvValidatorApplication(parser, validator, printer);
String[] args = {"/non/existent/file.txt"};
// Capture System.err
ByteArrayOutputStream errContent = new ByteArrayOutputStream();
PrintStream originalErr = System.err;
System.setErr(new PrintStream(errContent));
try {
// When
int exitCode = app.run(args);
// Then
assertEquals(2, exitCode);
assertEquals(true, errContent.toString().contains("File does not exist"), "Error output should contain file not found message");
} finally {
// Restore System.err
System.setErr(originalErr);
}
}
}

View File

@@ -0,0 +1,69 @@
package de.gecheckt.asv.cli;
import de.gecheckt.asv.validation.model.ValidationError;
import de.gecheckt.asv.validation.model.ValidationResult;
import de.gecheckt.asv.validation.model.ValidationSeverity;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class ValidationResultPrinterTest {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final PrintStream originalOut = System.out;
@BeforeEach
void setUp() {
System.setOut(new PrintStream(outContent));
}
@AfterEach
void tearDown() {
System.setOut(originalOut);
}
@Test
void testPrintToConsoleWithNullResult() {
ValidationResultPrinter printer = new ValidationResultPrinter();
assertThrows(IllegalArgumentException.class, () -> printer.printToConsole(null));
}
@Test
void testPrintToConsoleWithEmptyResult() {
ValidationResultPrinter printer = new ValidationResultPrinter();
ValidationResult result = new ValidationResult(List.of());
printer.printToConsole(result);
String output = outContent.toString();
assertTrue(output.contains("=== Validierungsergebnis ==="));
assertTrue(output.contains("Keine Probleme gefunden."));
assertTrue(output.contains("============================"));
}
@Test
void testPrintToConsoleWithError() {
ValidationError error = new ValidationError(
"TEST001", "Test error", ValidationSeverity.ERROR,
"SEGMENT", 1, "FIELD", 1, "actual", "expected"
);
ValidationResult result = new ValidationResult(List.of(error));
ValidationResultPrinter printer = new ValidationResultPrinter();
printer.printToConsole(result);
String output = outContent.toString();
assertTrue(output.contains("=== Validierungsergebnis ==="));
assertTrue(output.contains("Fehler (1):"));
assertTrue(output.contains("[ERROR] Test error (Code: TEST001)"));
assertTrue(output.contains("im Segment 'SEGMENT' Position 1, Feld 'FIELD' Position 1"));
assertTrue(output.contains("Ist-Wert: 'actual'"));
assertTrue(output.contains("Erwartet: 'expected'"));
assertTrue(output.contains("============================"));
}
}

View File

@@ -2,6 +2,7 @@ package de.gecheckt.asv.domain.model;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
/**
* Unit tests for the InputFile class.
@@ -20,7 +21,7 @@ class InputFileTest {
@Test
void constructorWithFileNameAndMessagesShouldCreateInputFile() {
Message message = new Message(1);
InputFile inputFile = new InputFile("test.txt", java.util.Arrays.asList(message));
InputFile inputFile = new InputFile("test.txt", List.of(message));
assertEquals("test.txt", inputFile.sourceFileName());
assertEquals(1, inputFile.messages().size());
@@ -45,7 +46,7 @@ class InputFileTest {
@Test
void getMessagesShouldReturnUnmodifiableList() {
Message message = new Message(1);
InputFile inputFile = new InputFile("test.txt", java.util.Arrays.asList(message));
InputFile inputFile = new InputFile("test.txt", List.of(message));
assertThrows(UnsupportedOperationException.class, () -> {
inputFile.getMessages().add(message);
@@ -62,7 +63,7 @@ class InputFileTest {
void getMessageCountShouldReturnCorrectCount() {
Message message1 = new Message(1);
Message message2 = new Message(2);
InputFile inputFile = new InputFile("test.txt", java.util.Arrays.asList(message1, message2));
InputFile inputFile = new InputFile("test.txt", List.of(message1, message2));
assertEquals(2, inputFile.getMessageCount());
}
@@ -70,9 +71,9 @@ class InputFileTest {
@Test
void equalsAndHashCodeShouldWorkCorrectly() {
Message message = new Message(1);
InputFile inputFile1 = new InputFile("test.txt", java.util.Arrays.asList(message));
InputFile inputFile2 = new InputFile("test.txt", java.util.Arrays.asList(message));
InputFile inputFile3 = new InputFile("other.txt", java.util.Arrays.asList(message));
InputFile inputFile1 = new InputFile("test.txt", List.of(message));
InputFile inputFile2 = new InputFile("test.txt", List.of(message));
InputFile inputFile3 = new InputFile("other.txt", List.of(message));
assertEquals(inputFile1, inputFile2);
assertNotEquals(inputFile1, inputFile3);
@@ -82,7 +83,7 @@ class InputFileTest {
@Test
void toStringShouldReturnValidString() {
Message message = new Message(1);
InputFile inputFile = new InputFile("test.txt", java.util.Arrays.asList(message));
InputFile inputFile = new InputFile("test.txt", List.of(message));
String result = inputFile.toString();
assertTrue(result.contains("sourceFileName=test.txt"));

View File

@@ -2,6 +2,7 @@ package de.gecheckt.asv.domain.model;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
/**
* Unit tests for the Message class.
@@ -20,7 +21,7 @@ class MessageTest {
@Test
void constructorWithPositionAndSegmentsShouldCreateMessage() {
Segment segment = new Segment("TEST", 1);
Message message = new Message(1, java.util.Arrays.asList(segment));
Message message = new Message(1, List.of(segment));
assertEquals(1, message.messagePosition());
assertEquals(1, message.segments().size());
@@ -41,7 +42,7 @@ class MessageTest {
@Test
void getSegmentsShouldReturnUnmodifiableList() {
Segment segment = new Segment("TEST", 1);
Message message = new Message(1, java.util.Arrays.asList(segment));
Message message = new Message(1, List.of(segment));
assertThrows(UnsupportedOperationException.class, () -> {
message.getSegments().add(segment);
@@ -58,7 +59,7 @@ class MessageTest {
void hasSegmentShouldWorkCorrectly() {
Segment segment1 = new Segment("TEST1", 1);
Segment segment2 = new Segment("TEST2", 2);
Message message = new Message(1, java.util.Arrays.asList(segment1, segment2));
Message message = new Message(1, List.of(segment1, segment2));
assertTrue(message.hasSegment("TEST1"));
assertTrue(message.hasSegment("TEST2"));
@@ -71,7 +72,7 @@ class MessageTest {
void getSegmentCountShouldReturnCorrectCount() {
Segment segment1 = new Segment("TEST1", 1);
Segment segment2 = new Segment("TEST2", 2);
Message message = new Message(1, java.util.Arrays.asList(segment1, segment2));
Message message = new Message(1, List.of(segment1, segment2));
assertEquals(2, message.getSegmentCount());
}
@@ -81,7 +82,7 @@ class MessageTest {
Segment segment1 = new Segment("TEST", 1);
Segment segment2 = new Segment("TEST", 2);
Segment segment3 = new Segment("OTHER", 3);
Message message = new Message(1, java.util.Arrays.asList(segment1, segment2, segment3));
Message message = new Message(1, List.of(segment1, segment2, segment3));
var segments = message.getSegments("TEST");
assertEquals(2, segments.size());
@@ -95,7 +96,7 @@ class MessageTest {
void getFirstSegmentShouldReturnCorrectSegment() {
Segment segment1 = new Segment("TEST1", 1);
Segment segment2 = new Segment("TEST2", 2);
Message message = new Message(1, java.util.Arrays.asList(segment1, segment2));
Message message = new Message(1, List.of(segment1, segment2));
assertTrue(message.getFirstSegment("TEST1").isPresent());
assertEquals(segment1, message.getFirstSegment("TEST1").get());
@@ -109,9 +110,9 @@ class MessageTest {
@Test
void equalsAndHashCodeShouldWorkCorrectly() {
Segment segment = new Segment("TEST", 1);
Message message1 = new Message(1, java.util.Arrays.asList(segment));
Message message2 = new Message(1, java.util.Arrays.asList(segment));
Message message3 = new Message(2, java.util.Arrays.asList(segment));
Message message1 = new Message(1, List.of(segment));
Message message2 = new Message(1, List.of(segment));
Message message3 = new Message(2, List.of(segment));
assertEquals(message1, message2);
assertNotEquals(message1, message3);
@@ -121,7 +122,7 @@ class MessageTest {
@Test
void toStringShouldReturnValidString() {
Segment segment = new Segment("TEST", 1);
Message message = new Message(1, java.util.Arrays.asList(segment));
Message message = new Message(1, List.of(segment));
String result = message.toString();
assertTrue(result.contains("messagePosition=1"));

View File

@@ -2,6 +2,7 @@ package de.gecheckt.asv.domain.model;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
/**
* Unit tests for the Segment class.
@@ -21,7 +22,7 @@ class SegmentTest {
@Test
void constructorWithNamePositionAndFieldsShouldCreateSegment() {
Field field = new Field(1, "value");
Segment segment = new Segment("TEST", 1, java.util.Arrays.asList(field));
Segment segment = new Segment("TEST", 1, List.of(field));
assertEquals("TEST", segment.segmentName());
assertEquals(1, segment.segmentPosition());
@@ -53,7 +54,7 @@ class SegmentTest {
@Test
void getFieldsShouldReturnUnmodifiableList() {
Field field = new Field(1, "value");
Segment segment = new Segment("TEST", 1, java.util.Arrays.asList(field));
Segment segment = new Segment("TEST", 1, List.of(field));
assertThrows(UnsupportedOperationException.class, () -> {
segment.getFields().add(field);
@@ -70,7 +71,7 @@ class SegmentTest {
void hasFieldAtShouldWorkCorrectly() {
Field field1 = new Field(1, "value1");
Field field2 = new Field(3, "value3");
Segment segment = new Segment("TEST", 1, java.util.Arrays.asList(field1, field2));
Segment segment = new Segment("TEST", 1, List.of(field1, field2));
assertTrue(segment.hasFieldAt(1));
assertFalse(segment.hasFieldAt(2));
@@ -82,7 +83,7 @@ class SegmentTest {
void getFieldCountShouldReturnCorrectCount() {
Field field1 = new Field(1, "value1");
Field field2 = new Field(2, "value2");
Segment segment = new Segment("TEST", 1, java.util.Arrays.asList(field1, field2));
Segment segment = new Segment("TEST", 1, List.of(field1, field2));
assertEquals(2, segment.getFieldCount());
}
@@ -91,7 +92,7 @@ class SegmentTest {
void getFieldShouldReturnCorrectField() {
Field field1 = new Field(1, "value1");
Field field2 = new Field(2, "value2");
Segment segment = new Segment("TEST", 1, java.util.Arrays.asList(field1, field2));
Segment segment = new Segment("TEST", 1, List.of(field1, field2));
assertTrue(segment.getField(1).isPresent());
assertEquals(field1, segment.getField(1).get());
@@ -103,9 +104,9 @@ class SegmentTest {
@Test
void equalsAndHashCodeShouldWorkCorrectly() {
Field field = new Field(1, "value");
Segment segment1 = new Segment("TEST", 1, java.util.Arrays.asList(field));
Segment segment2 = new Segment("TEST", 1, java.util.Arrays.asList(field));
Segment segment3 = new Segment("OTHER", 1, java.util.Arrays.asList(field));
Segment segment1 = new Segment("TEST", 1, List.of(field));
Segment segment2 = new Segment("TEST", 1, List.of(field));
Segment segment3 = new Segment("OTHER", 1, List.of(field));
assertEquals(segment1, segment2);
assertNotEquals(segment1, segment3);
@@ -115,7 +116,7 @@ class SegmentTest {
@Test
void toStringShouldReturnValidString() {
Field field = new Field(1, "value");
Segment segment = new Segment("TEST", 1, java.util.Arrays.asList(field));
Segment segment = new Segment("TEST", 1, List.of(field));
String result = segment.toString();
assertTrue(result.contains("segmentName=TEST"));

View File

@@ -6,13 +6,12 @@ import de.gecheckt.asv.domain.model.InputFile;
import de.gecheckt.asv.domain.model.Message;
import de.gecheckt.asv.domain.model.Segment;
import de.gecheckt.asv.domain.model.Field;
import java.io.IOException;
import java.util.List;
class DefaultInputFileParserTest {
@Test
void testParseSimpleFile() throws IOException {
void testParseSimpleFile() throws InputFileParseException {
// Given
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
InputFileParser parser = new DefaultInputFileParser(tokenizer);
@@ -80,7 +79,7 @@ class DefaultInputFileParserTest {
}
@Test
void testParseWithEmptyLines() throws IOException {
void testParseWithEmptyLines() throws InputFileParseException {
// Given
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
InputFileParser parser = new DefaultInputFileParser(tokenizer);
@@ -115,7 +114,7 @@ class DefaultInputFileParserTest {
}
@Test
void testParseWithNoFields() throws IOException {
void testParseWithNoFields() throws InputFileParseException {
// Given
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
InputFileParser parser = new DefaultInputFileParser(tokenizer);
@@ -184,4 +183,89 @@ class DefaultInputFileParserTest {
parser.parse(fileName, null);
});
}
@Test
void testParseInvalidContent() {
// Given
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
InputFileParser parser = new DefaultInputFileParser(tokenizer);
String fileName = "test.asv";
String fileContent = "HDR+20260325+12345\n" +
"DAT+field1+field2+field3\n" +
"TRL"; // Missing field that might cause issues in downstream processing
// When / Then
// This should not throw an exception as our simple parser handles this case
assertDoesNotThrow(() -> {
parser.parse(fileName, fileContent);
});
}
@Test
void testParseWithWindowsLineEndings() throws InputFileParseException {
// Given
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
InputFileParser parser = new DefaultInputFileParser(tokenizer);
String fileName = "test-windows.asv";
String fileContent = "HDR+20260325+12345\r\n" +
"DAT+field1+field2+field3\r\n" +
"TRL+5";
// When
InputFile inputFile = parser.parse(fileName, fileContent);
// Then
assertNotNull(inputFile);
assertEquals(fileName, inputFile.sourceFileName());
assertEquals(1, inputFile.messages().size());
List<Message> messages = inputFile.messages();
assertEquals(1, messages.size());
Message message = messages.get(0);
assertEquals(1, message.messagePosition());
assertEquals(3, message.segments().size());
// Check HDR segment
Segment hdrSegment = message.segments().get(0);
assertEquals("HDR", hdrSegment.segmentName());
assertEquals(1, hdrSegment.segmentPosition());
assertEquals(2, hdrSegment.fields().size());
Field hdrField1 = hdrSegment.fields().get(0);
assertEquals(1, hdrField1.fieldPosition());
assertEquals("20260325", hdrField1.rawValue());
Field hdrField2 = hdrSegment.fields().get(1);
assertEquals(2, hdrField2.fieldPosition());
assertEquals("12345", hdrField2.rawValue());
// Check DAT segment
Segment datSegment = message.segments().get(1);
assertEquals("DAT", datSegment.segmentName());
assertEquals(2, datSegment.segmentPosition());
assertEquals(3, datSegment.fields().size());
Field datField1 = datSegment.fields().get(0);
assertEquals(1, datField1.fieldPosition());
assertEquals("field1", datField1.rawValue());
Field datField2 = datSegment.fields().get(1);
assertEquals(2, datField2.fieldPosition());
assertEquals("field2", datField2.rawValue());
Field datField3 = datSegment.fields().get(2);
assertEquals(3, datField3.fieldPosition());
assertEquals("field3", datField3.rawValue());
// Check TRL segment
Segment trlSegment = message.segments().get(2);
assertEquals("TRL", trlSegment.segmentName());
assertEquals(3, trlSegment.segmentPosition());
assertEquals(1, trlSegment.fields().size());
Field trlField1 = trlSegment.fields().get(0);
assertEquals(1, trlField1.fieldPosition());
assertEquals("5", trlField1.rawValue());
}
}

View File

@@ -1,54 +0,0 @@
package de.gecheckt.asv.parser;
import de.gecheckt.asv.domain.model.InputFile;
import de.gecheckt.asv.domain.model.Message;
import de.gecheckt.asv.domain.model.Segment;
import de.gecheckt.asv.domain.model.Field;
import java.io.IOException;
/**
* Example usage of the parser.
*/
public class ParserExample {
public static void main(String[] args) {
try {
// Create the parser
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
InputFileParser parser = new DefaultInputFileParser(tokenizer);
// Sample file content
String fileName = "sample.asv";
String fileContent = "HDR+20260325+12345\n" +
"DAT+John+Doe+30\n" +
"DAT+Jane+Smith+25\n" +
"TRL+2";
// Parse the file
InputFile inputFile = parser.parse(fileName, fileContent);
// Print the results
System.out.println("Parsed file: " + inputFile.sourceFileName());
System.out.println("Number of messages: " + inputFile.messages().size());
for (Message message : inputFile.messages()) {
System.out.println(" Message " + message.messagePosition() +
" has " + message.segments().size() + " segments:");
for (Segment segment : message.segments()) {
System.out.println(" Segment " + segment.segmentPosition() +
" (" + segment.segmentName() + ") has " +
segment.fields().size() + " fields:");
for (Field field : segment.fields()) {
System.out.println(" Field " + field.fieldPosition() +
": '" + field.rawValue() + "'");
}
}
}
} catch (IOException e) {
System.err.println("Error parsing file: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -2,8 +2,8 @@ package de.gecheckt.asv.validation.field;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -29,9 +29,9 @@ class DefaultFieldValidatorTest {
// Arrange
Field field1 = new Field(1, "value1", "Field1");
Field field2 = new Field(2, "value2", "Field2");
Segment segment = new Segment("SEG1", 1, Arrays.asList(field1, field2));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field1, field2));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -47,9 +47,9 @@ class DefaultFieldValidatorTest {
void testValidate_withEmptyRawValue_returnsError() {
// Arrange
Field field = new Field(1, "", "Field1");
Segment segment = new Segment("SEG1", 1, Arrays.asList(field));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -74,9 +74,9 @@ class DefaultFieldValidatorTest {
void testValidate_withWhitespaceOnlyRawValue_returnsError() {
// Arrange
Field field = new Field(1, " ", "Field1");
Segment segment = new Segment("SEG1", 1, Arrays.asList(field));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -97,30 +97,14 @@ class DefaultFieldValidatorTest {
assertEquals("Non-whitespace-only raw value required", error.getExpectedRule().orElse(null));
}
@Test
void testValidate_withZeroFieldPosition_returnsError() {
// Note: This test creates a field with an invalid position that would normally be rejected by the domain model.
// We're testing the validator's ability to handle such cases if they were to occur.
// In practice, the domain model prevents this, but we include the check for completeness.
// For this test, we'll simulate the scenario by directly creating the objects
// Since the domain model prevents zero/negative positions, we'll skip this test for now
// as it would require changing the domain model which is outside our scope.
}
@Test
void testValidate_withNegativeFieldPosition_returnsError() {
// Note: Similar to the zero position test, this would require bypassing the domain model restrictions.
// We'll skip this test for the same reasons.
}
@Test
void testValidate_withEmptyFieldName_returnsError() {
// Arrange
Field field = new Field(1, "value1", "");
Segment segment = new Segment("SEG1", 1, Arrays.asList(field));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -145,9 +129,9 @@ class DefaultFieldValidatorTest {
void testValidate_withWhitespaceOnlyFieldName_returnsError() {
// Arrange
Field field = new Field(1, "value1", " ");
Segment segment = new Segment("SEG1", 1, Arrays.asList(field));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -173,9 +157,9 @@ class DefaultFieldValidatorTest {
// Arrange
Field field1 = new Field(1, "value1", "Field1");
Field field3 = new Field(3, "value3", "Field3"); // Missing field at position 2
Segment segment = new Segment("SEG1", 1, Arrays.asList(field1, field3));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field1, field3));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -202,9 +186,9 @@ class DefaultFieldValidatorTest {
// Arrange
Field field1 = new Field(1, "", "Field1"); // Empty value
Field field2 = new Field(2, " ", " "); // Whitespace only value and name
Segment segment = new Segment("SEG1", 1, Arrays.asList(field1, field2));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field1, field2));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);
@@ -235,8 +219,8 @@ class DefaultFieldValidatorTest {
void testValidate_withNoFields_returnsNoErrors() {
// Arrange
Segment segment = new Segment("SEG1", 1, Collections.emptyList());
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.asv", Arrays.asList(message));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.asv", List.of(message));
// Act
ValidationResult result = validator.validate(inputFile);

View File

@@ -2,6 +2,7 @@ package de.gecheckt.asv.validation.model;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
class ValidationResultTest {
@@ -12,7 +13,7 @@ class ValidationResultTest {
"TEST001", "Test error", ValidationSeverity.ERROR,
"SEGMENT", 1, "FIELD", 1, "actual", "expected"
);
ValidationResult result = new ValidationResult(java.util.Arrays.asList(error));
ValidationResult result = new ValidationResult(List.of(error));
// When & Then
assertTrue(result.hasErrors());
@@ -27,33 +28,11 @@ class ValidationResultTest {
"TEST001", "Test error", ValidationSeverity.ERROR,
"SEGMENT", 1, "FIELD", 1, "actual", "expected"
);
ValidationResult result = new ValidationResult(java.util.Arrays.asList(error));
ValidationResult result = new ValidationResult(List.of(error));
// When & Then
assertThrows(UnsupportedOperationException.class, () -> {
result.getErrors().add(error);
});
}
@Test
void testValidationErrorCreationAndAccess() {
// Given
ValidationError error = new ValidationError(
"TEST001", "Test error", ValidationSeverity.ERROR,
"SEGMENT", 1, "FIELD", 2, "actualValue", "expectedRule"
);
// When & Then
assertEquals("TEST001", error.errorCode());
assertEquals("Test error", error.description());
assertEquals(ValidationSeverity.ERROR, error.severity());
assertEquals("SEGMENT", error.segmentName());
assertEquals(1, error.segmentPosition());
assertEquals("FIELD", error.fieldName());
assertEquals(2, error.fieldPosition());
assertTrue(error.getActualValue().isPresent());
assertEquals("actualValue", error.getActualValue().get());
assertTrue(error.getExpectedRule().isPresent());
assertEquals("expectedRule", error.getExpectedRule().get());
}
}

View File

@@ -2,8 +2,8 @@ package de.gecheckt.asv.validation.structure;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -50,7 +50,7 @@ class DefaultStructureValidatorTest {
@Test
void validate_shouldReportErrorWhenMessageHasNoSegments() {
Message message = new Message(1, Collections.emptyList());
InputFile inputFile = new InputFile("test.txt", Arrays.asList(message));
InputFile inputFile = new InputFile("test.txt", List.of(message));
ValidationResult result = validator.validate(inputFile);
@@ -68,8 +68,8 @@ class DefaultStructureValidatorTest {
void validate_shouldReportErrorWhenSegmentHasDuplicatePositions() {
Segment segment1 = new Segment("SEG1", 1);
Segment segment2 = new Segment("SEG2", 1); // Duplicate position
Message message = new Message(1, Arrays.asList(segment1, segment2));
InputFile inputFile = new InputFile("test.txt", Arrays.asList(message));
Message message = new Message(1, List.of(segment1, segment2));
InputFile inputFile = new InputFile("test.txt", List.of(message));
ValidationResult result = validator.validate(inputFile);
@@ -87,9 +87,9 @@ class DefaultStructureValidatorTest {
void validate_shouldReportErrorWhenFieldHasDuplicatePositions() {
Field field1 = new Field(1, "value1");
Field field2 = new Field(1, "value2"); // Duplicate position
Segment segment = new Segment("SEG1", 1, Arrays.asList(field1, field2));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.txt", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field1, field2));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.txt", List.of(message));
ValidationResult result = validator.validate(inputFile);
@@ -108,9 +108,9 @@ class DefaultStructureValidatorTest {
void validate_shouldReturnNoErrorsForValidStructure() {
Field field1 = new Field(1, "value1");
Field field2 = new Field(2, "value2");
Segment segment = new Segment("SEG1", 1, Arrays.asList(field1, field2));
Message message = new Message(1, Arrays.asList(segment));
InputFile inputFile = new InputFile("test.txt", Arrays.asList(message));
Segment segment = new Segment("SEG1", 1, List.of(field1, field2));
Message message = new Message(1, List.of(segment));
InputFile inputFile = new InputFile("test.txt", List.of(message));
ValidationResult result = validator.validate(inputFile);