Refactoring

This commit is contained in:
2026-03-25 23:41:30 +01:00
parent 8a8db1e8a1
commit fc4386ac99
15 changed files with 200 additions and 183 deletions

View File

@@ -38,6 +38,8 @@ public record InputFile(String sourceFileName, List<Message> messages) {
if (messages == null) { if (messages == null) {
throw new IllegalArgumentException("Messages must not be null"); throw new IllegalArgumentException("Messages must not be null");
} }
// Defensive copy to ensure immutability
messages = List.copyOf(messages);
} }
/** /**

View File

@@ -40,6 +40,8 @@ public record Message(int messagePosition, List<Segment> segments) {
if (segments == null) { if (segments == null) {
throw new IllegalArgumentException("Segments must not be null"); throw new IllegalArgumentException("Segments must not be null");
} }
// Defensive copy to ensure immutability
segments = List.copyOf(segments);
} }
/** /**

View File

@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
/** /**
* Represents a segment in a message from an input file. * Represents a segment in a message from an input file.
@@ -46,6 +45,8 @@ public record Segment(String segmentName, int segmentPosition, List<Field> field
if (fields == null) { if (fields == null) {
throw new IllegalArgumentException("Fields must not be null"); throw new IllegalArgumentException("Fields must not be null");
} }
// Defensive copy to ensure immutability
fields = List.copyOf(fields);
} }
/** /**

View File

@@ -5,8 +5,6 @@ import java.util.List;
import de.gecheckt.asv.domain.model.Field; import de.gecheckt.asv.domain.model.Field;
import de.gecheckt.asv.domain.model.InputFile; 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.validation.model.ValidationError; import de.gecheckt.asv.validation.model.ValidationError;
import de.gecheckt.asv.validation.model.ValidationResult; import de.gecheckt.asv.validation.model.ValidationResult;
import de.gecheckt.asv.validation.model.ValidationSeverity; import de.gecheckt.asv.validation.model.ValidationSeverity;

View File

@@ -1,10 +1,7 @@
package de.gecheckt.asv.validation.model; package de.gecheckt.asv.validation.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* Repräsentiert das Ergebnis einer Validierung mit allen gefundenen Fehlern, Warnungen und Infos. * Repräsentiert das Ergebnis einer Validierung mit allen gefundenen Fehlern, Warnungen und Infos.

View File

@@ -3,7 +3,6 @@ package de.gecheckt.asv.validation.structure;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import de.gecheckt.asv.domain.model.Field; import de.gecheckt.asv.domain.model.Field;
import de.gecheckt.asv.domain.model.InputFile; import de.gecheckt.asv.domain.model.InputFile;

View File

@@ -50,6 +50,12 @@ class InputFileTest {
assertThrows(UnsupportedOperationException.class, () -> { assertThrows(UnsupportedOperationException.class, () -> {
inputFile.getMessages().add(message); inputFile.getMessages().add(message);
}); });
// Also test that the internal list cannot be modified through the constructor parameter
java.util.List<Message> originalMessages = new java.util.ArrayList<>();
originalMessages.add(message);
InputFile inputFile2 = new InputFile("test.txt", originalMessages);
originalMessages.add(new Message(2));
assertEquals(1, inputFile2.messages().size()); // Should still be 1 due to defensive copy
} }
@Test @Test

View File

@@ -46,6 +46,12 @@ class MessageTest {
assertThrows(UnsupportedOperationException.class, () -> { assertThrows(UnsupportedOperationException.class, () -> {
message.getSegments().add(segment); message.getSegments().add(segment);
}); });
// Also test that the internal list cannot be modified through the constructor parameter
java.util.List<Segment> originalSegments = new java.util.ArrayList<>();
originalSegments.add(segment);
Message message2 = new Message(1, originalSegments);
originalSegments.add(new Segment("TEST2", 2));
assertEquals(1, message2.segments().size()); // Should still be 1 due to defensive copy
} }
@Test @Test

View File

@@ -58,6 +58,12 @@ class SegmentTest {
assertThrows(UnsupportedOperationException.class, () -> { assertThrows(UnsupportedOperationException.class, () -> {
segment.getFields().add(field); segment.getFields().add(field);
}); });
// Also test that the internal list cannot be modified through the constructor parameter
java.util.List<Field> originalFields = new java.util.ArrayList<>();
originalFields.add(field);
Segment segment2 = new Segment("TEST", 1, originalFields);
originalFields.add(new Field(2, "anotherValue"));
assertEquals(1, segment2.fields().size()); // Should still be 1 due to defensive copy
} }
@Test @Test

View File

@@ -26,57 +26,57 @@ class DefaultInputFileParserTest {
// Then // Then
assertNotNull(inputFile); assertNotNull(inputFile);
assertEquals(fileName, inputFile.getSourceFileName()); assertEquals(fileName, inputFile.sourceFileName());
assertEquals(1, inputFile.getMessageCount()); assertEquals(1, inputFile.messages().size());
List<Message> messages = inputFile.getMessages(); List<Message> messages = inputFile.messages();
assertEquals(1, messages.size()); assertEquals(1, messages.size());
Message message = messages.get(0); Message message = messages.get(0);
assertEquals(1, message.getMessagePosition()); assertEquals(1, message.messagePosition());
assertEquals(3, message.getSegmentCount()); assertEquals(3, message.segments().size());
// Check HDR segment // Check HDR segment
Segment hdrSegment = message.getSegments().get(0); Segment hdrSegment = message.segments().get(0);
assertEquals("HDR", hdrSegment.getSegmentName()); assertEquals("HDR", hdrSegment.segmentName());
assertEquals(1, hdrSegment.getSegmentPosition()); assertEquals(1, hdrSegment.segmentPosition());
assertEquals(2, hdrSegment.getFieldCount()); assertEquals(2, hdrSegment.fields().size());
Field hdrField1 = hdrSegment.getFields().get(0); Field hdrField1 = hdrSegment.fields().get(0);
assertEquals(1, hdrField1.getFieldPosition()); assertEquals(1, hdrField1.fieldPosition());
assertEquals("20260325", hdrField1.getRawValue()); assertEquals("20260325", hdrField1.rawValue());
Field hdrField2 = hdrSegment.getFields().get(1); Field hdrField2 = hdrSegment.fields().get(1);
assertEquals(2, hdrField2.getFieldPosition()); assertEquals(2, hdrField2.fieldPosition());
assertEquals("12345", hdrField2.getRawValue()); assertEquals("12345", hdrField2.rawValue());
// Check DAT segment // Check DAT segment
Segment datSegment = message.getSegments().get(1); Segment datSegment = message.segments().get(1);
assertEquals("DAT", datSegment.getSegmentName()); assertEquals("DAT", datSegment.segmentName());
assertEquals(2, datSegment.getSegmentPosition()); assertEquals(2, datSegment.segmentPosition());
assertEquals(3, datSegment.getFieldCount()); assertEquals(3, datSegment.fields().size());
Field datField1 = datSegment.getFields().get(0); Field datField1 = datSegment.fields().get(0);
assertEquals(1, datField1.getFieldPosition()); assertEquals(1, datField1.fieldPosition());
assertEquals("field1", datField1.getRawValue()); assertEquals("field1", datField1.rawValue());
Field datField2 = datSegment.getFields().get(1); Field datField2 = datSegment.fields().get(1);
assertEquals(2, datField2.getFieldPosition()); assertEquals(2, datField2.fieldPosition());
assertEquals("field2", datField2.getRawValue()); assertEquals("field2", datField2.rawValue());
Field datField3 = datSegment.getFields().get(2); Field datField3 = datSegment.fields().get(2);
assertEquals(3, datField3.getFieldPosition()); assertEquals(3, datField3.fieldPosition());
assertEquals("field3", datField3.getRawValue()); assertEquals("field3", datField3.rawValue());
// Check TRL segment // Check TRL segment
Segment trlSegment = message.getSegments().get(2); Segment trlSegment = message.segments().get(2);
assertEquals("TRL", trlSegment.getSegmentName()); assertEquals("TRL", trlSegment.segmentName());
assertEquals(3, trlSegment.getSegmentPosition()); assertEquals(3, trlSegment.segmentPosition());
assertEquals(1, trlSegment.getFieldCount()); assertEquals(1, trlSegment.fields().size());
Field trlField1 = trlSegment.getFields().get(0); Field trlField1 = trlSegment.fields().get(0);
assertEquals(1, trlField1.getFieldPosition()); assertEquals(1, trlField1.fieldPosition());
assertEquals("5", trlField1.getRawValue()); assertEquals("5", trlField1.rawValue());
} }
@Test @Test
@@ -98,20 +98,20 @@ class DefaultInputFileParserTest {
// Then // Then
assertNotNull(inputFile); assertNotNull(inputFile);
assertEquals(1, inputFile.getMessageCount()); assertEquals(1, inputFile.messages().size());
Message message = inputFile.getMessages().get(0); Message message = inputFile.messages().get(0);
assertEquals(3, message.getSegmentCount()); assertEquals(3, message.segments().size());
// Empty lines should be ignored // Empty lines should be ignored
Segment segment1 = message.getSegments().get(0); Segment segment1 = message.segments().get(0);
assertEquals("HDR", segment1.getSegmentName()); assertEquals("HDR", segment1.segmentName());
Segment segment2 = message.getSegments().get(1); Segment segment2 = message.segments().get(1);
assertEquals("DAT", segment2.getSegmentName()); assertEquals("DAT", segment2.segmentName());
Segment segment3 = message.getSegments().get(2); Segment segment3 = message.segments().get(2);
assertEquals("TRL", segment3.getSegmentName()); assertEquals("TRL", segment3.segmentName());
} }
@Test @Test
@@ -127,22 +127,22 @@ class DefaultInputFileParserTest {
// Then // Then
assertNotNull(inputFile); assertNotNull(inputFile);
assertEquals(1, inputFile.getMessageCount()); assertEquals(1, inputFile.messages().size());
Message message = inputFile.getMessages().get(0); Message message = inputFile.messages().get(0);
assertEquals(3, message.getSegmentCount()); assertEquals(3, message.segments().size());
Segment hdrSegment = message.getSegments().get(0); Segment hdrSegment = message.segments().get(0);
assertEquals("HDR", hdrSegment.getSegmentName()); assertEquals("HDR", hdrSegment.segmentName());
assertEquals(0, hdrSegment.getFieldCount()); assertEquals(0, hdrSegment.fields().size());
Segment datSegment = message.getSegments().get(1); Segment datSegment = message.segments().get(1);
assertEquals("DAT", datSegment.getSegmentName()); assertEquals("DAT", datSegment.segmentName());
assertEquals(0, datSegment.getFieldCount()); assertEquals(0, datSegment.fields().size());
Segment trlSegment = message.getSegments().get(2); Segment trlSegment = message.segments().get(2);
assertEquals("TRL", trlSegment.getSegmentName()); assertEquals("TRL", trlSegment.segmentName());
assertEquals(0, trlSegment.getFieldCount()); assertEquals(0, trlSegment.fields().size());
} }
@Test @Test

View File

@@ -34,22 +34,22 @@ class DefaultSegmentLineTokenizerTest {
// Then // Then
assertEquals(2, fields1.size()); assertEquals(2, fields1.size());
assertEquals(1, fields1.get(0).getFieldPosition()); assertEquals(1, fields1.get(0).fieldPosition());
assertEquals("20260325", fields1.get(0).getRawValue()); assertEquals("20260325", fields1.get(0).rawValue());
assertEquals(2, fields1.get(1).getFieldPosition()); assertEquals(2, fields1.get(1).fieldPosition());
assertEquals("12345", fields1.get(1).getRawValue()); assertEquals("12345", fields1.get(1).rawValue());
assertEquals(3, fields2.size()); assertEquals(3, fields2.size());
assertEquals(1, fields2.get(0).getFieldPosition()); assertEquals(1, fields2.get(0).fieldPosition());
assertEquals("field1", fields2.get(0).getRawValue()); assertEquals("field1", fields2.get(0).rawValue());
assertEquals(2, fields2.get(1).getFieldPosition()); assertEquals(2, fields2.get(1).fieldPosition());
assertEquals("field2", fields2.get(1).getRawValue()); assertEquals("field2", fields2.get(1).rawValue());
assertEquals(3, fields2.get(2).getFieldPosition()); assertEquals(3, fields2.get(2).fieldPosition());
assertEquals("field3", fields2.get(2).getRawValue()); assertEquals("field3", fields2.get(2).rawValue());
assertEquals(1, fields3.size()); assertEquals(1, fields3.size());
assertEquals(1, fields3.get(0).getFieldPosition()); assertEquals(1, fields3.get(0).fieldPosition());
assertEquals("5", fields3.get(0).getRawValue()); assertEquals("5", fields3.get(0).rawValue());
assertEquals(0, fields4.size()); assertEquals(0, fields4.size());
assertEquals(0, fields5.size()); assertEquals(0, fields5.size());
@@ -65,13 +65,13 @@ class DefaultSegmentLineTokenizerTest {
// Then // Then
assertEquals(4, fields.size()); assertEquals(4, fields.size());
assertEquals(1, fields.get(0).getFieldPosition()); assertEquals(1, fields.get(0).fieldPosition());
assertEquals("field", fields.get(0).getRawValue()); assertEquals("field", fields.get(0).rawValue());
assertEquals(2, fields.get(1).getFieldPosition()); assertEquals(2, fields.get(1).fieldPosition());
assertEquals("with", fields.get(1).getRawValue()); assertEquals("with", fields.get(1).rawValue());
assertEquals(3, fields.get(2).getFieldPosition()); assertEquals(3, fields.get(2).fieldPosition());
assertEquals("plus", fields.get(2).getRawValue()); assertEquals("plus", fields.get(2).rawValue());
assertEquals(4, fields.get(3).getFieldPosition()); assertEquals(4, fields.get(3).fieldPosition());
assertEquals("signs", fields.get(3).getRawValue()); assertEquals("signs", fields.get(3).rawValue());
} }
} }

View File

@@ -28,21 +28,21 @@ public class ParserExample {
InputFile inputFile = parser.parse(fileName, fileContent); InputFile inputFile = parser.parse(fileName, fileContent);
// Print the results // Print the results
System.out.println("Parsed file: " + inputFile.getSourceFileName()); System.out.println("Parsed file: " + inputFile.sourceFileName());
System.out.println("Number of messages: " + inputFile.getMessageCount()); System.out.println("Number of messages: " + inputFile.messages().size());
for (Message message : inputFile.getMessages()) { for (Message message : inputFile.messages()) {
System.out.println(" Message " + message.getMessagePosition() + System.out.println(" Message " + message.messagePosition() +
" has " + message.getSegmentCount() + " segments:"); " has " + message.segments().size() + " segments:");
for (Segment segment : message.getSegments()) { for (Segment segment : message.segments()) {
System.out.println(" Segment " + segment.getSegmentPosition() + System.out.println(" Segment " + segment.segmentPosition() +
" (" + segment.getSegmentName() + ") has " + " (" + segment.segmentName() + ") has " +
segment.getFieldCount() + " fields:"); segment.fields().size() + " fields:");
for (Field field : segment.getFields()) { for (Field field : segment.fields()) {
System.out.println(" Field " + field.getFieldPosition() + System.out.println(" Field " + field.fieldPosition() +
": '" + field.getRawValue() + "'"); ": '" + field.rawValue() + "'");
} }
} }
} }

View File

@@ -1,7 +1,6 @@
package de.gecheckt.asv.validation; package de.gecheckt.asv.validation;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.Collections; import java.util.Collections;
@@ -24,10 +23,23 @@ class DefaultInputFileValidatorTest {
@BeforeEach @BeforeEach
void setUp() { void setUp() {
structureValidator = mock(StructureValidator.class); // Verwende echte Instanzen statt Mocks, da Records final sind
fieldValidator = mock(FieldValidator.class); structureValidator = new StructureValidator() {
@Override
public ValidationResult validate(InputFile inputFile) {
return new ValidationResult(Collections.emptyList());
}
};
fieldValidator = new FieldValidator() {
@Override
public ValidationResult validate(InputFile inputFile) {
return new ValidationResult(Collections.emptyList());
}
};
validator = new DefaultInputFileValidator(structureValidator, fieldValidator); validator = new DefaultInputFileValidator(structureValidator, fieldValidator);
inputFile = mock(InputFile.class); inputFile = new InputFile("test.txt");
} }
@Test @Test
@@ -64,19 +76,28 @@ class DefaultInputFileValidatorTest {
"rule2" "rule2"
); );
ValidationResult structureResult = new ValidationResult(Collections.singletonList(structureError)); // Verwende echte Validator-Implementierungen für diesen Test
ValidationResult fieldResult = new ValidationResult(Collections.singletonList(fieldError)); StructureValidator structureValidatorWithErrors = new StructureValidator() {
@Override
public ValidationResult validate(InputFile inputFile) {
return new ValidationResult(Collections.singletonList(structureError));
}
};
when(structureValidator.validate(inputFile)).thenReturn(structureResult); FieldValidator fieldValidatorWithErrors = new FieldValidator() {
when(fieldValidator.validate(inputFile)).thenReturn(fieldResult); @Override
public ValidationResult validate(InputFile inputFile) {
return new ValidationResult(Collections.singletonList(fieldError));
}
};
DefaultInputFileValidator validatorWithErrors = new DefaultInputFileValidator(
structureValidatorWithErrors, fieldValidatorWithErrors);
// When // When
ValidationResult result = validator.validate(inputFile); ValidationResult result = validatorWithErrors.validate(inputFile);
// Then // Then
verify(structureValidator).validate(inputFile);
verify(fieldValidator).validate(inputFile);
assertEquals(2, result.getAllErrors().size()); assertEquals(2, result.getAllErrors().size());
assertTrue(result.getAllErrors().contains(structureError)); assertTrue(result.getAllErrors().contains(structureError));
assertTrue(result.getAllErrors().contains(fieldError)); assertTrue(result.getAllErrors().contains(fieldError));
@@ -86,18 +107,10 @@ class DefaultInputFileValidatorTest {
@Test @Test
void validate_shouldReturnEmptyResultWhenNoErrorsFound() { void validate_shouldReturnEmptyResultWhenNoErrorsFound() {
// Given
ValidationResult emptyResult = new ValidationResult(Collections.emptyList());
when(structureValidator.validate(inputFile)).thenReturn(emptyResult);
when(fieldValidator.validate(inputFile)).thenReturn(emptyResult);
// When // When
ValidationResult result = validator.validate(inputFile); ValidationResult result = validator.validate(inputFile);
// Then // Then
verify(structureValidator).validate(inputFile);
verify(fieldValidator).validate(inputFile);
assertEquals(0, result.getAllErrors().size()); assertEquals(0, result.getAllErrors().size());
assertFalse(result.hasErrors()); assertFalse(result.hasErrors());
assertFalse(result.hasWarnings()); assertFalse(result.hasWarnings());

View File

@@ -59,13 +59,13 @@ class DefaultFieldValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("FIELD_002", error.getErrorCode()); assertEquals("FIELD_002", error.errorCode());
assertEquals("Field raw value must not be empty", error.getDescription()); assertEquals("Field raw value must not be empty", error.description());
assertEquals(ValidationSeverity.ERROR, error.getSeverity()); assertEquals(ValidationSeverity.ERROR, error.severity());
assertEquals("SEG1", error.getSegmentName()); assertEquals("SEG1", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
assertEquals("Field1", error.getFieldName()); assertEquals("Field1", error.fieldName());
assertEquals(1, error.getFieldPosition()); assertEquals(1, error.fieldPosition());
assertEquals("", error.getActualValue().orElse(null)); assertEquals("", error.getActualValue().orElse(null));
assertEquals("Non-empty raw value required", error.getExpectedRule().orElse(null)); assertEquals("Non-empty raw value required", error.getExpectedRule().orElse(null));
} }
@@ -86,13 +86,13 @@ class DefaultFieldValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("FIELD_003", error.getErrorCode()); assertEquals("FIELD_003", error.errorCode());
assertEquals("Field raw value must not consist only of whitespaces", error.getDescription()); assertEquals("Field raw value must not consist only of whitespaces", error.description());
assertEquals(ValidationSeverity.ERROR, error.getSeverity()); assertEquals(ValidationSeverity.ERROR, error.severity());
assertEquals("SEG1", error.getSegmentName()); assertEquals("SEG1", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
assertEquals("Field1", error.getFieldName()); assertEquals("Field1", error.fieldName());
assertEquals(1, error.getFieldPosition()); assertEquals(1, error.fieldPosition());
assertEquals(" ", error.getActualValue().orElse(null)); assertEquals(" ", error.getActualValue().orElse(null));
assertEquals("Non-whitespace-only raw value required", error.getExpectedRule().orElse(null)); assertEquals("Non-whitespace-only raw value required", error.getExpectedRule().orElse(null));
} }
@@ -130,13 +130,13 @@ class DefaultFieldValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("FIELD_006", error.getErrorCode()); assertEquals("FIELD_006", error.errorCode());
assertEquals("Field name must not be empty", error.getDescription()); assertEquals("Field name must not be empty", error.description());
assertEquals(ValidationSeverity.ERROR, error.getSeverity()); assertEquals(ValidationSeverity.ERROR, error.severity());
assertEquals("SEG1", error.getSegmentName()); assertEquals("SEG1", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
assertEquals("", error.getFieldName()); assertEquals("", error.fieldName());
assertEquals(1, error.getFieldPosition()); assertEquals(1, error.fieldPosition());
assertEquals("", error.getActualValue().orElse(null)); assertEquals("", error.getActualValue().orElse(null));
assertEquals("Non-empty field name required", error.getExpectedRule().orElse(null)); assertEquals("Non-empty field name required", error.getExpectedRule().orElse(null));
} }
@@ -157,13 +157,13 @@ class DefaultFieldValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("FIELD_006", error.getErrorCode()); assertEquals("FIELD_006", error.errorCode());
assertEquals("Field name must not consist only of whitespaces", error.getDescription()); assertEquals("Field name must not consist only of whitespaces", error.description());
assertEquals(ValidationSeverity.ERROR, error.getSeverity()); assertEquals(ValidationSeverity.ERROR, error.severity());
assertEquals("SEG1", error.getSegmentName()); assertEquals("SEG1", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
assertEquals(" ", error.getFieldName()); assertEquals(" ", error.fieldName());
assertEquals(1, error.getFieldPosition()); assertEquals(1, error.fieldPosition());
assertEquals(" ", error.getActualValue().orElse(null)); assertEquals(" ", error.getActualValue().orElse(null));
assertEquals("Non-whitespace-only field name required", error.getExpectedRule().orElse(null)); assertEquals("Non-whitespace-only field name required", error.getExpectedRule().orElse(null));
} }
@@ -186,13 +186,13 @@ class DefaultFieldValidatorTest {
assertEquals(1, result.getWarnings().size()); assertEquals(1, result.getWarnings().size());
ValidationError warning = result.getWarnings().get(0); ValidationError warning = result.getWarnings().get(0);
assertEquals("FIELD_005", warning.getErrorCode()); assertEquals("FIELD_005", warning.errorCode());
assertEquals("Missing field at position 2 - field positions should be consecutive", warning.getDescription()); assertEquals("Missing field at position 2 - field positions should be consecutive", warning.description());
assertEquals(ValidationSeverity.WARNING, warning.getSeverity()); assertEquals(ValidationSeverity.WARNING, warning.severity());
assertEquals("SEG1", warning.getSegmentName()); assertEquals("SEG1", warning.segmentName());
assertEquals(1, warning.getSegmentPosition()); assertEquals(1, warning.segmentPosition());
assertEquals("", warning.getFieldName()); assertEquals("", warning.fieldName());
assertEquals(2, warning.getFieldPosition()); assertEquals(2, warning.fieldPosition());
assertEquals("", warning.getActualValue().orElse(null)); assertEquals("", warning.getActualValue().orElse(null));
assertEquals("Consecutive field positions starting at 1 required", warning.getExpectedRule().orElse(null)); assertEquals("Consecutive field positions starting at 1 required", warning.getExpectedRule().orElse(null));
} }
@@ -215,15 +215,15 @@ class DefaultFieldValidatorTest {
// Check that all expected errors are present // Check that all expected errors are present
boolean foundEmptyValueError = result.getErrors().stream() boolean foundEmptyValueError = result.getErrors().stream()
.anyMatch(e -> "FIELD_002".equals(e.getErrorCode()) && .anyMatch(e -> "FIELD_002".equals(e.errorCode()) &&
"".equals(e.getActualValue().orElse(null))); "".equals(e.getActualValue().orElse(null)));
boolean foundWhitespaceValueError = result.getErrors().stream() boolean foundWhitespaceValueError = result.getErrors().stream()
.anyMatch(e -> "FIELD_003".equals(e.getErrorCode()) && .anyMatch(e -> "FIELD_003".equals(e.errorCode()) &&
" ".equals(e.getActualValue().orElse(null))); " ".equals(e.getActualValue().orElse(null)));
boolean foundWhitespaceNameError = result.getErrors().stream() boolean foundWhitespaceNameError = result.getErrors().stream()
.anyMatch(e -> "FIELD_006".equals(e.getErrorCode()) && .anyMatch(e -> "FIELD_006".equals(e.errorCode()) &&
" ".equals(e.getActualValue().orElse(null))); " ".equals(e.getActualValue().orElse(null)));
assertTrue(foundEmptyValueError, "Should find empty value error"); assertTrue(foundEmptyValueError, "Should find empty value error");

View File

@@ -41,10 +41,10 @@ class DefaultStructureValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("STRUCTURE_001", error.getErrorCode()); assertEquals("STRUCTURE_001", error.errorCode());
assertEquals("Input file must contain at least one message", error.getDescription()); assertEquals("Input file must contain at least one message", error.description());
assertEquals("", error.getSegmentName()); assertEquals("", error.segmentName());
assertEquals(0, error.getSegmentPosition()); assertEquals(0, error.segmentPosition());
} }
@Test @Test
@@ -58,10 +58,10 @@ class DefaultStructureValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("STRUCTURE_002", error.getErrorCode()); assertEquals("STRUCTURE_002", error.errorCode());
assertEquals("Message must contain at least one segment", error.getDescription()); assertEquals("Message must contain at least one segment", error.description());
assertEquals("", error.getSegmentName()); assertEquals("", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
} }
@Test @Test
@@ -77,10 +77,10 @@ class DefaultStructureValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("STRUCTURE_005", error.getErrorCode()); assertEquals("STRUCTURE_005", error.errorCode());
assertEquals("Duplicate segment position: 1", error.getDescription()); assertEquals("Duplicate segment position: 1", error.description());
assertEquals("SEG2", error.getSegmentName()); assertEquals("SEG2", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
} }
@Test @Test
@@ -97,24 +97,11 @@ class DefaultStructureValidatorTest {
assertEquals(1, result.getErrors().size()); assertEquals(1, result.getErrors().size());
ValidationError error = result.getErrors().get(0); ValidationError error = result.getErrors().get(0);
assertEquals("STRUCTURE_004", error.getErrorCode()); assertEquals("STRUCTURE_004", error.errorCode());
assertEquals("Duplicate field position: 1", error.getDescription()); assertEquals("Duplicate field position: 1", error.description());
assertEquals("SEG1", error.getSegmentName()); assertEquals("SEG1", error.segmentName());
assertEquals(1, error.getSegmentPosition()); assertEquals(1, error.segmentPosition());
assertEquals(1, error.getFieldPosition()); assertEquals(1, error.fieldPosition());
}
@Test
void validate_shouldReportErrorWhenMessageHasDuplicatePositions() {
// Since we cannot create Messages with duplicate positions due to domain model constraints,
// we'll test a scenario that would produce similar validation errors
Message message1 = new Message(1);
Message message2 = new Message(2);
// We'll simulate the error condition differently
// Actually, let's just remove this test since the domain model prevents this scenario
// and our validator correctly handles what it can validate
assertTrue(true); // Placeholder assertion
} }
@Test @Test