Meilenstein 1 vor Implementierung der Spezifikation
This commit is contained in:
163
src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java
Normal file
163
src/main/java/de/gecheckt/asv/cli/AsvValidatorApplication.java
Normal file
@@ -0,0 +1,163 @@
|
||||
package de.gecheckt.asv.cli;
|
||||
|
||||
import de.gecheckt.asv.domain.model.InputFile;
|
||||
import de.gecheckt.asv.parser.DefaultInputFileParser;
|
||||
import de.gecheckt.asv.parser.DefaultSegmentLineTokenizer;
|
||||
import de.gecheckt.asv.parser.InputFileParseException;
|
||||
import de.gecheckt.asv.parser.InputFileParser;
|
||||
import de.gecheckt.asv.parser.SegmentLineTokenizer;
|
||||
import de.gecheckt.asv.validation.DefaultInputFileValidator;
|
||||
import de.gecheckt.asv.validation.InputFileValidator;
|
||||
import de.gecheckt.asv.validation.field.DefaultFieldValidator;
|
||||
import de.gecheckt.asv.validation.field.FieldValidator;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
import de.gecheckt.asv.validation.structure.DefaultStructureValidator;
|
||||
import de.gecheckt.asv.validation.structure.StructureValidator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Haupteinstiegspunkt für die ASV Format Validator CLI-Anwendung.
|
||||
*
|
||||
* Diese Anwendung validiert Dateien gegen ein segmentorientiertes Dateiformat.
|
||||
* Sie nimmt einen Dateipfad als Kommandozeilenargument entgegen, parst die Datei,
|
||||
* validiert sie und gibt die Ergebnisse auf der Konsole aus.
|
||||
*/
|
||||
public class AsvValidatorApplication {
|
||||
|
||||
private static final int EXIT_CODE_SUCCESS = 0;
|
||||
private static final int EXIT_CODE_INVALID_ARGUMENTS = 1;
|
||||
private static final int EXIT_CODE_FILE_ERROR = 2;
|
||||
private static final int EXIT_CODE_VALIDATION_ERRORS = 3;
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(AsvValidatorApplication.class);
|
||||
|
||||
private final InputFileParser parser;
|
||||
private final InputFileValidator validator;
|
||||
private final ValidationResultPrinter printer;
|
||||
|
||||
/**
|
||||
* Konstruktor für einen AsvValidatorApplication mit Standardkomponenten.
|
||||
*/
|
||||
public AsvValidatorApplication() {
|
||||
// Initialize all required components
|
||||
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
|
||||
this.parser = new DefaultInputFileParser(tokenizer);
|
||||
|
||||
StructureValidator structureValidator = new DefaultStructureValidator();
|
||||
FieldValidator fieldValidator = new DefaultFieldValidator();
|
||||
this.validator = new DefaultInputFileValidator(structureValidator, fieldValidator);
|
||||
|
||||
this.printer = new ValidationResultPrinter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konstruktor für einen AsvValidatorApplication mit den bereitgestellten Komponenten.
|
||||
* Dieser Konstruktor unterstützt Dependency Injection für bessere Testbarkeit.
|
||||
*
|
||||
* @param parser der Parser zum Parsen von Eingabedateien
|
||||
* @param validator der Validator zum Validieren geparster Dateien
|
||||
* @param printer der Printer zum Anzeigen von Validierungsergebnissen
|
||||
*/
|
||||
public AsvValidatorApplication(InputFileParser parser, InputFileValidator validator, ValidationResultPrinter printer) {
|
||||
this.parser = parser;
|
||||
this.validator = validator;
|
||||
this.printer = printer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Haupteinstiegspunkt für die Anwendung.
|
||||
*
|
||||
* @param args Kommandozeilenargumente - erwartet genau ein Argument: den Dateipfad
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
AsvValidatorApplication app = new AsvValidatorApplication();
|
||||
int exitCode = app.run(args);
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt die Anwendung mit den bereitgestellten Argumenten aus.
|
||||
*
|
||||
* @param args Kommandozeilenargumente
|
||||
* @return Exit-Code (0 für Erfolg, ungleich 0 für Fehler)
|
||||
*/
|
||||
public int run(String[] args) {
|
||||
// Validate command line arguments
|
||||
if (args.length != 1) {
|
||||
printUsage();
|
||||
return EXIT_CODE_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
String filePath = args[0];
|
||||
|
||||
try {
|
||||
// Parse the file
|
||||
InputFile inputFile = parseFile(filePath);
|
||||
|
||||
// Validate the parsed file
|
||||
ValidationResult result = validator.validate(inputFile);
|
||||
|
||||
// Output results
|
||||
printer.printToConsole(result);
|
||||
|
||||
// Return appropriate exit code based on validation results
|
||||
return result.hasErrors() ? EXIT_CODE_VALIDATION_ERRORS : EXIT_CODE_SUCCESS;
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.error("Fehler beim Lesen der Datei: {}", e.getMessage(), e);
|
||||
System.err.println("Fehler beim Lesen der Datei: " + e.getMessage());
|
||||
return EXIT_CODE_FILE_ERROR;
|
||||
} catch (InputFileParseException e) {
|
||||
logger.error("Fehler beim Parsen der Datei: {}", e.getMessage(), e);
|
||||
System.err.println("Fehler beim Parsen der Datei: " + e.getMessage());
|
||||
return EXIT_CODE_FILE_ERROR;
|
||||
} catch (Exception e) {
|
||||
logger.error("Unerwarteter Fehler während der Validierung: {}", e.getMessage(), e);
|
||||
System.err.println("Unerwarteter Fehler während der Validierung: " + e.getMessage());
|
||||
return EXIT_CODE_FILE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parst eine Datei unter dem gegebenen Pfad.
|
||||
*
|
||||
* @param filePath Pfad zur zu parsenden Datei
|
||||
* @return geparstes InputFile-Objekt
|
||||
* @throws IOException wenn die Datei nicht gelesen werden kann
|
||||
* @throws InputFileParseException wenn die Datei nicht geparst werden kann
|
||||
*/
|
||||
private InputFile parseFile(String filePath) throws IOException, InputFileParseException {
|
||||
Path path = Paths.get(filePath);
|
||||
if (!Files.exists(path)) {
|
||||
throw new IOException("File does not exist: " + filePath);
|
||||
}
|
||||
|
||||
if (!Files.isRegularFile(path)) {
|
||||
throw new IOException("Path is not a regular file: " + filePath);
|
||||
}
|
||||
|
||||
if (!Files.isReadable(path)) {
|
||||
throw new IOException("File is not readable: " + filePath);
|
||||
}
|
||||
|
||||
String fileContent = Files.readString(path, StandardCharsets.UTF_8);
|
||||
return parser.parse(path.getFileName().toString(), fileContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt Nutzungsinformationen auf der Konsole aus.
|
||||
*/
|
||||
private void printUsage() {
|
||||
System.out.println("ASV Format Validator");
|
||||
System.out.println("Verwendung: java -jar asv-format-validator.jar <datei-pfad>");
|
||||
System.out.println(" <datei-pfad> Pfad zur zu validierenden Datei");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package de.gecheckt.asv.cli;
|
||||
|
||||
import de.gecheckt.asv.validation.model.ValidationError;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
|
||||
/**
|
||||
* Printer-Klasse zum Ausgeben von ValidationResult-Objekten auf der Konsole.
|
||||
* Diese Klasse trennt die Darstellungslogik vom Datenmodell.
|
||||
*/
|
||||
public class ValidationResultPrinter {
|
||||
|
||||
/**
|
||||
* Gibt ein ValidationResult formatiert auf der Konsole aus.
|
||||
*
|
||||
* @param result das auszugebende ValidationResult (darf nicht null sein)
|
||||
*/
|
||||
public void printToConsole(ValidationResult result) {
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException("ValidationResult must not be null");
|
||||
}
|
||||
|
||||
System.out.println("=== Validierungsergebnis ===");
|
||||
|
||||
if (result.hasErrors()) {
|
||||
System.out.println("Fehler (" + result.getErrors().size() + "):");
|
||||
result.getErrors().forEach(error -> System.out.println(" [ERROR] " + formatError(error)));
|
||||
}
|
||||
|
||||
if (result.hasWarnings()) {
|
||||
System.out.println("Warnungen (" + result.getWarnings().size() + "):");
|
||||
result.getWarnings().forEach(error -> System.out.println(" [WARNING] " + formatError(error)));
|
||||
}
|
||||
|
||||
if (result.hasInfos()) {
|
||||
System.out.println("Informationen (" + result.getInfos().size() + "):");
|
||||
result.getInfos().forEach(error -> System.out.println(" [INFO] " + formatError(error)));
|
||||
}
|
||||
|
||||
if (!result.hasErrors() && !result.hasWarnings() && !result.hasInfos()) {
|
||||
System.out.println("Keine Probleme gefunden.");
|
||||
}
|
||||
|
||||
System.out.println("============================");
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatiert einen ValidationError für die Konsolenausgabe.
|
||||
*
|
||||
* @param error der zu formatierende Fehler
|
||||
* @return formatierte Zeichenkettendarstellung des Fehlers
|
||||
*/
|
||||
private String formatError(ValidationError error) {
|
||||
var sb = new StringBuilder();
|
||||
sb.append(error.description());
|
||||
sb.append(" (Code: ").append(error.errorCode()).append(")");
|
||||
sb.append(" im Segment '").append(error.segmentName()).append("' Position ").append(error.segmentPosition());
|
||||
sb.append(", Feld '").append(error.fieldName()).append("' Position ").append(error.fieldPosition());
|
||||
|
||||
error.getActualValue().ifPresent(value ->
|
||||
sb.append(", Ist-Wert: '").append(value).append("'"));
|
||||
|
||||
error.getExpectedRule().ifPresent(rule ->
|
||||
sb.append(", Erwartet: '").append(rule).append("'"));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Represents a message in an input file.
|
||||
@@ -92,7 +91,7 @@ public record Message(int messagePosition, List<Segment> segments) {
|
||||
|
||||
return segments.stream()
|
||||
.filter(segment -> segmentName.equals(segment.segmentName()))
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,29 +5,28 @@ import de.gecheckt.asv.domain.model.InputFile;
|
||||
import de.gecheckt.asv.domain.model.Message;
|
||||
import de.gecheckt.asv.domain.model.Segment;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation of InputFileParser.
|
||||
* Standardimplementierung von InputFileParser.
|
||||
*/
|
||||
public class DefaultInputFileParser implements InputFileParser {
|
||||
|
||||
private final SegmentLineTokenizer tokenizer;
|
||||
|
||||
/**
|
||||
* Constructs a DefaultInputFileParser with the specified tokenizer.
|
||||
* Konstruktor für einen DefaultInputFileParser mit dem angegebenen Tokenizer.
|
||||
*
|
||||
* @param tokenizer the tokenizer to use for parsing segment lines
|
||||
* @param tokenizer der für das Parsen von Segmentzeilen zu verwendende Tokenizer
|
||||
*/
|
||||
public DefaultInputFileParser(SegmentLineTokenizer tokenizer) {
|
||||
this.tokenizer = tokenizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputFile parse(String fileName, String fileContent) throws IOException {
|
||||
public InputFile parse(String fileName, String fileContent) throws InputFileParseException {
|
||||
if (fileName == null || fileName.isEmpty()) {
|
||||
throw new IllegalArgumentException("File name must not be null or empty");
|
||||
}
|
||||
@@ -58,7 +57,8 @@ public class DefaultInputFileParser implements InputFileParser {
|
||||
|
||||
return new InputFile(fileName, messages);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Error parsing file: " + fileName, e);
|
||||
// Wrap all exceptions as parsing exceptions
|
||||
throw new InputFileParseException("Error parsing file: " + fileName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation of SegmentLineTokenizer that uses '+' as field separator
|
||||
* and assumes the first token is the segment name.
|
||||
* Standardimplementierung von SegmentLineTokenizer, die '+' als Feldtrennzeichen verwendet
|
||||
* und annimmt, dass das erste Token der Segmentname ist.
|
||||
*/
|
||||
public class DefaultSegmentLineTokenizer implements SegmentLineTokenizer {
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.gecheckt.asv.parser;
|
||||
|
||||
/**
|
||||
* Exception thrown when an input file cannot be parsed due to format or content issues.
|
||||
* This exception is used specifically for parsing-related problems, as opposed to
|
||||
* I/O issues which would be represented by IOException.
|
||||
*/
|
||||
public class InputFileParseException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs a new InputFileParseException with the specified detail message.
|
||||
*
|
||||
* @param message the detail message
|
||||
*/
|
||||
public InputFileParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new InputFileParseException with the specified detail message and cause.
|
||||
*
|
||||
* @param message the detail message
|
||||
* @param cause the cause of this exception
|
||||
*/
|
||||
public InputFileParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,19 @@
|
||||
package de.gecheckt.asv.parser;
|
||||
|
||||
import de.gecheckt.asv.domain.model.InputFile;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface for parsing input files into the domain model.
|
||||
* Interface für das Parsen von Eingabedateien in das Domänenmodell.
|
||||
*/
|
||||
public interface InputFileParser {
|
||||
|
||||
/**
|
||||
* Parses the content of a file into an InputFile domain object.
|
||||
* Parst den Inhalt einer Datei in ein InputFile-Domänenobjekt.
|
||||
*
|
||||
* @param fileName the name of the file to parse
|
||||
* @param fileContent the content of the file to parse
|
||||
* @return the parsed InputFile domain object
|
||||
* @throws IOException if there is an error reading or parsing the file
|
||||
* @param fileName der Name der zu parsenden Datei
|
||||
* @param fileContent der Inhalt der zu parsenden Datei
|
||||
* @return das geparste InputFile-Domänenobjekt
|
||||
* @throws InputFileParseException wenn beim Parsen des Dateiinhalts ein Fehler auftritt
|
||||
*/
|
||||
InputFile parse(String fileName, String fileContent) throws IOException;
|
||||
InputFile parse(String fileName, String fileContent) throws InputFileParseException;
|
||||
}
|
||||
@@ -4,23 +4,23 @@ import de.gecheckt.asv.domain.model.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for splitting a segment line into its components.
|
||||
* Interface für das Aufteilen einer Segmentzeile in ihre Bestandteile.
|
||||
*/
|
||||
public interface SegmentLineTokenizer {
|
||||
|
||||
/**
|
||||
* Extracts the segment name from a segment line.
|
||||
* Extrahiert den Segmentnamen aus einer Segmentzeile.
|
||||
*
|
||||
* @param segmentLine the line to extract the segment name from
|
||||
* @return the segment name
|
||||
* @param segmentLine die Zeile, aus der der Segmentname extrahiert werden soll
|
||||
* @return der Segmentname
|
||||
*/
|
||||
String extractSegmentName(String segmentLine);
|
||||
|
||||
/**
|
||||
* Splits a segment line into fields.
|
||||
* Teilt eine Segmentzeile in Felder auf.
|
||||
*
|
||||
* @param segmentLine the line to split into fields
|
||||
* @return the list of fields
|
||||
* @param segmentLine die in Felder aufzuteilende Zeile
|
||||
* @return die Liste der Felder
|
||||
*/
|
||||
List<Field> tokenizeFields(String segmentLine);
|
||||
}
|
||||
@@ -10,13 +10,14 @@ import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
import de.gecheckt.asv.validation.structure.StructureValidator;
|
||||
|
||||
/**
|
||||
* Default implementation of InputFileValidator that orchestrates multiple specialized validators.
|
||||
* Standardimplementierung von InputFileValidator, die mehrere spezialisierte Validatoren orchestriert.
|
||||
*
|
||||
* This orchestrator executes validators in a predefined order:
|
||||
* 1. StructureValidator - validates structural integrity
|
||||
* 2. FieldValidator - validates field-specific rules
|
||||
* Dieser Orchestrator führt Validatoren in einer vordefinierten Reihenfolge aus:
|
||||
* 1. StructureValidator - validiert die strukturelle Integrität
|
||||
* 2. FieldValidator - validiert feldspezifische Regeln
|
||||
*
|
||||
* Additional validators can be added in the future by extending this class or modifying the validation sequence.
|
||||
* Zusätzliche Validatoren können in Zukunft hinzugefügt werden, indem diese Klasse erweitert
|
||||
* oder die Validierungssequenz modifiziert wird.
|
||||
*/
|
||||
public class DefaultInputFileValidator implements InputFileValidator {
|
||||
|
||||
@@ -24,10 +25,10 @@ public class DefaultInputFileValidator implements InputFileValidator {
|
||||
private final FieldValidator fieldValidator;
|
||||
|
||||
/**
|
||||
* Constructs a DefaultInputFileValidator with the required validators.
|
||||
* Konstruktor für einen DefaultInputFileValidator mit den erforderlichen Validatoren.
|
||||
*
|
||||
* @param structureValidator the structure validator to use (must not be null)
|
||||
* @param fieldValidator the field validator to use (must not be null)
|
||||
* @param structureValidator der zu verwendende Strukturvalidator (darf nicht null sein)
|
||||
* @param fieldValidator der zu verwendende Feldvalidator (darf nicht null sein)
|
||||
*/
|
||||
public DefaultInputFileValidator(StructureValidator structureValidator, FieldValidator fieldValidator) {
|
||||
this.structureValidator = Objects.requireNonNull(structureValidator, "structureValidator must not be null");
|
||||
|
||||
@@ -4,17 +4,17 @@ import de.gecheckt.asv.domain.model.InputFile;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
|
||||
/**
|
||||
* Interface for orchestrating the validation of an ASV input file.
|
||||
* This validator coordinates multiple specialized validators to perform a complete validation.
|
||||
* Interface für die Orchestrierung der Validierung einer ASV-Eingabedatei.
|
||||
* Dieser Validator koordiniert mehrere spezialisierte Validatoren, um eine vollständige Validierung durchzuführen.
|
||||
*/
|
||||
public interface InputFileValidator {
|
||||
|
||||
/**
|
||||
* Validates the given input file using all configured validators.
|
||||
* Validiert die gegebene Eingabedatei unter Verwendung aller konfigurierten Validatoren.
|
||||
*
|
||||
* @param inputFile the input file to validate (must not be null)
|
||||
* @return a validation result containing all errors found by all validators
|
||||
* @throws IllegalArgumentException if inputFile is null
|
||||
* @param inputFile die zu validierende Eingabedatei (darf nicht null sein)
|
||||
* @return ein Validierungsergebnis, das alle von allen Validatoren gefundenen Fehler enthält
|
||||
* @throws IllegalArgumentException wenn inputFile null ist
|
||||
*/
|
||||
ValidationResult validate(InputFile inputFile);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package de.gecheckt.asv.validation.example;
|
||||
|
||||
import de.gecheckt.asv.validation.model.ValidationError;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
import de.gecheckt.asv.validation.model.ValidationSeverity;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Beispielanwendung zur Demonstration der Verwendung der Validierungsmodelle.
|
||||
*/
|
||||
public class ValidationExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Erstelle einige Beispielvalidierungsfehler
|
||||
ValidationError error1 = new ValidationError(
|
||||
"FORMAT001",
|
||||
"Ungültiges Datumsformat",
|
||||
ValidationSeverity.ERROR,
|
||||
"KOPF",
|
||||
1,
|
||||
"ERSTELLUNGSDATUM",
|
||||
3,
|
||||
"2023-99-99",
|
||||
"YYYY-MM-DD"
|
||||
);
|
||||
|
||||
ValidationError warning1 = new ValidationError(
|
||||
"LENGTH001",
|
||||
"Feldlänge überschritten",
|
||||
ValidationSeverity.WARNING,
|
||||
"POSITION",
|
||||
5,
|
||||
"ARTIKELBEZEICHNUNG",
|
||||
2,
|
||||
"Extrem langer Artikelname, der die maximale Feldlänge überschreitet",
|
||||
"Max. 30 Zeichen"
|
||||
);
|
||||
|
||||
ValidationError info1 = new ValidationError(
|
||||
"OPTIONAL001",
|
||||
"Optionales Feld ist leer",
|
||||
ValidationSeverity.INFO,
|
||||
"FUSS",
|
||||
100,
|
||||
"BEMERKUNG",
|
||||
1,
|
||||
null,
|
||||
"Freitextfeld für zusätzliche Informationen"
|
||||
);
|
||||
|
||||
// Erstelle ein ValidationResult-Objekt
|
||||
List<ValidationError> validationErrors = Arrays.asList(error1, warning1, info1);
|
||||
ValidationResult result = new ValidationResult(validationErrors);
|
||||
|
||||
// Gib das Ergebnis auf der Konsole aus
|
||||
result.printToConsole();
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,10 @@ import de.gecheckt.asv.validation.model.ValidationSeverity;
|
||||
* Default implementation of FieldValidator that checks general field rules.
|
||||
*
|
||||
* Rules checked:
|
||||
* 1. Field.rawValue must not be null
|
||||
* 2. Field.rawValue must not be empty
|
||||
* 3. Field.rawValue must not consist only of whitespaces
|
||||
* 4. fieldPosition must be positive
|
||||
* 5. Field positions within a segment should be consecutive without gaps, starting at 1
|
||||
* 6. If fieldName is set, it must not be empty or only whitespace
|
||||
* 1. Field.rawValue must not be empty
|
||||
* 2. Field.rawValue must not consist only of whitespaces
|
||||
* 3. Field positions within a segment should be consecutive without gaps, starting at 1
|
||||
* 4. If fieldName is set, it must not be empty or only whitespace
|
||||
*/
|
||||
public class DefaultFieldValidator implements FieldValidator {
|
||||
|
||||
@@ -73,65 +71,33 @@ public class DefaultFieldValidator implements FieldValidator {
|
||||
var fieldPosition = field.fieldPosition();
|
||||
var fieldName = field.getFieldName().orElse("");
|
||||
|
||||
// Rule 1: Field.rawValue must not be null
|
||||
// (This is already enforced by the domain model, but we check for completeness)
|
||||
if (rawValue == null) {
|
||||
// Rule 2: Field.rawValue must not be empty
|
||||
if (rawValue.isEmpty()) {
|
||||
errors.add(createError(
|
||||
"FIELD_001",
|
||||
"Field raw value must not be null",
|
||||
"FIELD_002",
|
||||
"Field raw value must not be empty",
|
||||
ValidationSeverity.ERROR,
|
||||
segmentName,
|
||||
segmentPosition,
|
||||
fieldName,
|
||||
fieldPosition,
|
||||
"null",
|
||||
"Non-null raw value required"
|
||||
rawValue,
|
||||
"Non-empty raw value required"
|
||||
));
|
||||
} else {
|
||||
// Rule 2: Field.rawValue must not be empty
|
||||
if (rawValue.isEmpty()) {
|
||||
errors.add(createError(
|
||||
"FIELD_002",
|
||||
"Field raw value must not be empty",
|
||||
ValidationSeverity.ERROR,
|
||||
segmentName,
|
||||
segmentPosition,
|
||||
fieldName,
|
||||
fieldPosition,
|
||||
rawValue,
|
||||
"Non-empty raw value required"
|
||||
));
|
||||
}
|
||||
|
||||
// Rule 3: Field.rawValue must not consist only of whitespaces
|
||||
if (rawValue.trim().isEmpty() && !rawValue.isEmpty()) {
|
||||
errors.add(createError(
|
||||
"FIELD_003",
|
||||
"Field raw value must not consist only of whitespaces",
|
||||
ValidationSeverity.ERROR,
|
||||
segmentName,
|
||||
segmentPosition,
|
||||
fieldName,
|
||||
fieldPosition,
|
||||
rawValue,
|
||||
"Non-whitespace-only raw value required"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Rule 4: fieldPosition must be positive
|
||||
// (This is already enforced by the domain model, but we check for completeness)
|
||||
if (fieldPosition <= 0) {
|
||||
// Rule 3: Field.rawValue must not consist only of whitespaces
|
||||
if (rawValue.trim().isEmpty() && !rawValue.isEmpty()) {
|
||||
errors.add(createError(
|
||||
"FIELD_004",
|
||||
"Field position must be positive",
|
||||
"FIELD_003",
|
||||
"Field raw value must not consist only of whitespaces",
|
||||
ValidationSeverity.ERROR,
|
||||
segmentName,
|
||||
segmentPosition,
|
||||
fieldName,
|
||||
fieldPosition,
|
||||
String.valueOf(fieldPosition),
|
||||
"Positive field position required"
|
||||
rawValue,
|
||||
"Non-whitespace-only raw value required"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,17 +4,17 @@ import de.gecheckt.asv.domain.model.InputFile;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
|
||||
/**
|
||||
* Interface for validating fields in an ASV input file.
|
||||
* This validator checks general field rules without requiring specification details.
|
||||
* Interface für die Validierung von Feldern in einer ASV-Eingabedatei.
|
||||
* Dieser Validator prüft allgemeine Feldregeln ohne Angabe von Spezifikationsdetails.
|
||||
*/
|
||||
public interface FieldValidator {
|
||||
|
||||
/**
|
||||
* Validates the fields in the given input file.
|
||||
* Validiert die Felder in der gegebenen Eingabedatei.
|
||||
*
|
||||
* @param inputFile the input file to validate (must not be null)
|
||||
* @return a validation result containing any field errors found
|
||||
* @throws IllegalArgumentException if inputFile is null
|
||||
* @param inputFile die zu validierende Eingabedatei (darf nicht null sein)
|
||||
* @return ein Validierungsergebnis, das alle gefundenen Feldfehler enthält
|
||||
* @throws IllegalArgumentException wenn inputFile null ist
|
||||
*/
|
||||
ValidationResult validate(InputFile inputFile);
|
||||
}
|
||||
@@ -109,56 +109,6 @@ public final class ValidationResult {
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt eine textbasierte Darstellung des Validierungsergebnisses auf der Konsole aus.
|
||||
*/
|
||||
public void printToConsole() {
|
||||
System.out.println("=== Validierungsergebnis ===");
|
||||
|
||||
if (hasErrors()) {
|
||||
System.out.println("Fehler (" + getErrors().size() + "):");
|
||||
getErrors().forEach(error -> System.out.println(" [ERROR] " + formatError(error)));
|
||||
}
|
||||
|
||||
if (hasWarnings()) {
|
||||
System.out.println("Warnungen (" + getWarnings().size() + "):");
|
||||
getWarnings().forEach(error -> System.out.println(" [WARNING] " + formatError(error)));
|
||||
}
|
||||
|
||||
if (hasInfos()) {
|
||||
System.out.println("Informationen (" + getInfos().size() + "):");
|
||||
getInfos().forEach(error -> System.out.println(" [INFO] " + formatError(error)));
|
||||
}
|
||||
|
||||
if (!hasErrors() && !hasWarnings() && !hasInfos()) {
|
||||
System.out.println("Keine Probleme gefunden.");
|
||||
}
|
||||
|
||||
System.out.println("============================");
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatiert einen ValidationError für die Konsolenausgabe.
|
||||
*
|
||||
* @param error der zu formatierende Fehler
|
||||
* @return formatierte Zeichenkette
|
||||
*/
|
||||
private String formatError(ValidationError error) {
|
||||
var sb = new StringBuilder();
|
||||
sb.append(error.description());
|
||||
sb.append(" (Code: ").append(error.errorCode()).append(")");
|
||||
sb.append(" im Segment '").append(error.segmentName()).append("' Position ").append(error.segmentPosition());
|
||||
sb.append(", Feld '").append(error.fieldName()).append("' Position ").append(error.fieldPosition());
|
||||
|
||||
error.getActualValue().ifPresent(value ->
|
||||
sb.append(", Ist-Wert: '").append(value).append("'"));
|
||||
|
||||
error.getExpectedRule().ifPresent(rule ->
|
||||
sb.append(", Erwartet: '").append(rule).append("'"));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -4,17 +4,17 @@ import de.gecheckt.asv.domain.model.InputFile;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
|
||||
/**
|
||||
* Interface for validating the structural integrity of an ASV input file.
|
||||
* This validator checks general structural rules without requiring specification details.
|
||||
* Interface für die Validierung der strukturellen Integrität einer ASV-Eingabedatei.
|
||||
* Dieser Validator prüft allgemeine Strukturregeln ohne Angabe von Spezifikationsdetails.
|
||||
*/
|
||||
public interface StructureValidator {
|
||||
|
||||
/**
|
||||
* Validates the structural integrity of the given input file.
|
||||
* Validiert die strukturelle Integrität der gegebenen Eingabedatei.
|
||||
*
|
||||
* @param inputFile the input file to validate (must not be null)
|
||||
* @return a validation result containing any structural errors found
|
||||
* @throws IllegalArgumentException if inputFile is null
|
||||
* @param inputFile die zu validierende Eingabedatei (darf nicht null sein)
|
||||
* @return ein Validierungsergebnis, das alle gefundenen Strukturfehler enthält
|
||||
* @throws IllegalArgumentException wenn inputFile null ist
|
||||
*/
|
||||
ValidationResult validate(InputFile inputFile);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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("============================"));
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user