Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,15 @@ public AuditSequenceStrictValidator(AuditReader auditReader, AuditEntryDefinitio
public ValidationResult validate() {
List<ValidationError> allErrors = new ArrayList<>();

int expectedSize = expectations.size();
int actualSize = actualEntries.size();

if (expectedSize != actualSize) {
if (expectations.size() != actualEntries.size()) {
allErrors.add(new CountMismatchError(getExpectedChangeIds(), getActualChangeIds()));
}

allErrors.addAll(getValidationErrors(expectations, actualEntries));

if (allErrors.isEmpty()) {
return ValidationResult.success(VALIDATOR_NAME);
}

return ValidationResult.failure(VALIDATOR_NAME, allErrors.toArray(new ValidationError[0]));
return allErrors.isEmpty()
? ValidationResult.success(VALIDATOR_NAME)
: ValidationResult.failure(VALIDATOR_NAME, allErrors.toArray(new ValidationError[0]));
}

private static List<ValidationError> getValidationErrors(List<AuditEntryExpectation> expectedEntries, List<AuditEntry> actualEntries) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package io.flamingock.support.validation.impl;

import io.flamingock.support.validation.ExceptionValidator;
import io.flamingock.support.validation.error.ExceptionNotExpectedError;
import io.flamingock.support.validation.error.ExceptionTypeMismatchError;
import io.flamingock.support.validation.error.ValidationResult;

import java.util.function.Consumer;
Expand All @@ -40,7 +42,30 @@ public void setActualException(Throwable actualException) {

@Override
public ValidationResult validate(Throwable actualException) {
// TODO: Implement actual validation logic
// No exception expected
if (expectedExceptionClass == null) {
if (actualException == null) {
return ValidationResult.success(VALIDATOR_NAME);
} else {
return ValidationResult.failure(VALIDATOR_NAME, new ExceptionNotExpectedError(actualException));
}
}

// An exception is expected but none was thrown
if (actualException == null) {
return ValidationResult.failure(VALIDATOR_NAME,
new ExceptionTypeMismatchError(expectedExceptionClass, null));
}

// Type mismatch
if (!expectedExceptionClass.isInstance(actualException)) {
return ValidationResult.failure(VALIDATOR_NAME,
new ExceptionTypeMismatchError(expectedExceptionClass, actualException.getClass()));
}

if (expectedExceptionConsumer != null) {
expectedExceptionConsumer.accept(actualException);
}
return ValidationResult.success(VALIDATOR_NAME);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2025 Flamingock (https://www.flamingock.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.flamingock.support.validation.impl;

import io.flamingock.support.validation.error.ExceptionNotExpectedError;
import io.flamingock.support.validation.error.ExceptionTypeMismatchError;
import io.flamingock.support.validation.error.ValidationResult;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.jupiter.api.Assertions.*;

class DefaultExceptionValidatorTest {

@Test
@DisplayName("DefaultExceptionValidatorTest: No exception expected and none thrown — should succeed")
void noExceptionExpected_andNoneThrown_shouldSucceed() {
DefaultExceptionValidator validator = new DefaultExceptionValidator(null, null);
ValidationResult result = validator.validate(null);
assertTrue(result.isSuccess());
assertFalse(result.hasErrors());
}

@Test
@DisplayName("DefaultExceptionValidatorTest: No exception expected but an exception thrown — should fail with ExceptionNotExpectedError")
void noExceptionExpected_butExceptionThrown_shouldFailWithNotExpected() {
DefaultExceptionValidator validator = new DefaultExceptionValidator(null, null);
RuntimeException ex = new RuntimeException("message");
ValidationResult result = validator.validate(ex);
assertTrue(result.hasErrors());
assertFalse(result.isSuccess());
assertEquals(1, result.getErrors().size());
assertInstanceOf(ExceptionNotExpectedError.class, result.getErrors().get(0));
}

@Test
@DisplayName("DefaultExceptionValidatorTest: Exception expected but none thrown — should fail with ExceptionTypeMismatchError (null actual)")
void exceptionExpected_butNoneThrown_shouldFailWithTypeMismatch_nullActual() {
DefaultExceptionValidator validator = new DefaultExceptionValidator(IOException.class, null);
ValidationResult result = validator.validate(null);
assertTrue(result.hasErrors());
assertEquals(1, result.getErrors().size());
assertInstanceOf(ExceptionTypeMismatchError.class, result.getErrors().get(0));
}

@Test
@DisplayName("DefaultExceptionValidatorTest: Exception expected but wrong type thrown — should fail with ExceptionTypeMismatchError")
void exceptionExpected_butWrongTypeThrown_shouldFailWithTypeMismatch() {
DefaultExceptionValidator validator = new DefaultExceptionValidator(IllegalArgumentException.class, null);
RuntimeException ex = new RuntimeException("message");
ValidationResult result = validator.validate(ex);
assertTrue(result.hasErrors());
assertEquals(1, result.getErrors().size());
assertInstanceOf(ExceptionTypeMismatchError.class, result.getErrors().get(0));
}

@Test
@DisplayName("DefaultExceptionValidatorTest: Exception expected and correct type thrown — should succeed and invoke consumer")
void exceptionExpected_andCorrectTypeThrown_shouldSucceed_andInvokeConsumer() {
AtomicBoolean consumed = new AtomicBoolean(false);
DefaultExceptionValidator validator = new DefaultExceptionValidator(RuntimeException.class, e -> consumed.set(true));
RuntimeException ex = new RuntimeException("message");
ValidationResult result = validator.validate(ex);
assertTrue(result.isSuccess());
assertFalse(result.hasErrors());
assertTrue(consumed.get());
}
}
Loading