diff --git a/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/AuditSequenceStrictValidator.java b/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/AuditSequenceStrictValidator.java index 189a0dcbd..f2b68113a 100644 --- a/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/AuditSequenceStrictValidator.java +++ b/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/AuditSequenceStrictValidator.java @@ -70,20 +70,15 @@ public AuditSequenceStrictValidator(AuditReader auditReader, AuditEntryDefinitio public ValidationResult validate() { List 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 getValidationErrors(List expectedEntries, List actualEntries) { diff --git a/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/DefaultExceptionValidator.java b/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/DefaultExceptionValidator.java index 8fc9f23df..e498f22dd 100644 --- a/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/DefaultExceptionValidator.java +++ b/core/flamingock-test-support/src/main/java/io/flamingock/support/validation/impl/DefaultExceptionValidator.java @@ -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; @@ -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); } } diff --git a/core/flamingock-test-support/src/test/java/io/flamingock/support/validation/impl/DefaultExceptionValidatorTest.java b/core/flamingock-test-support/src/test/java/io/flamingock/support/validation/impl/DefaultExceptionValidatorTest.java new file mode 100644 index 000000000..f8d98a5b7 --- /dev/null +++ b/core/flamingock-test-support/src/test/java/io/flamingock/support/validation/impl/DefaultExceptionValidatorTest.java @@ -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()); + } +}