From 64cc0f6f24a64a33b1be17064f3ab8ea1046e7fb Mon Sep 17 00:00:00 2001 From: Philip Date: Thu, 18 Jul 2024 11:45:19 +0100 Subject: [PATCH] Add doesNotMatch predicate and DoesNotMatchPredicateTest --- .../org/assertj/core/api/AbstractAssert.java | 49 ++++++++++ .../condition/DoesNotMatchPredicateTest.java | 92 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 assertj-core/src/test/java/org/assertj/core/condition/DoesNotMatchPredicateTest.java diff --git a/assertj-core/src/main/java/org/assertj/core/api/AbstractAssert.java b/assertj-core/src/main/java/org/assertj/core/api/AbstractAssert.java index eac89f448a..8890ff9076 100644 --- a/assertj-core/src/main/java/org/assertj/core/api/AbstractAssert.java +++ b/assertj-core/src/main/java/org/assertj/core/api/AbstractAssert.java @@ -19,6 +19,7 @@ import static org.assertj.core.description.Description.mostRelevantDescription; import static org.assertj.core.error.ShouldMatch.shouldMatch; import static org.assertj.core.error.ShouldNotBeNull.shouldNotBeNull; +import static org.assertj.core.error.ShouldNotMatch.shouldNotMatch; import static org.assertj.core.extractor.Extractors.byName; import static org.assertj.core.extractor.Extractors.extractedDescriptionOf; import static org.assertj.core.util.Lists.list; @@ -809,6 +810,48 @@ public SELF matches(Predicate predicate, String predicateDescrip return matches(predicate, new PredicateDescription(predicateDescription)); } + /** + * Verifies that the actual object does not match the given predicate. + *

+ * Example : + * + *

 assertThat(player).doesNotMatch(p -> p.isRookie());
+ * + * @param predicate the {@link Predicate} to check does not match + * @return {@code this} assertion object. + * @throws AssertionError if {@code actual} does match the given {@link Predicate}. + * @throws NullPointerException if given {@link Predicate} is null. + */ + public SELF doesNotMatch(Predicate predicate) { + // use default PredicateDescription + return doesNotMatch(predicate, PredicateDescription.GIVEN); + } + + /** + * Verifies that the actual object does not match the given predicate, the predicate description is used to get an + * informative error message. + *

+ * Example : + * + *

 assertThat(player).doesNotMatch(p -> p.isRookie(), "is not rookie");
+ * + * The error message contains the predicate description, if the previous assertion fails, it will be: + * + *
 Expecting:
+   *   <player>
+   * to not match 'is rookie' predicate.
+ * + * @param predicate the {@link Predicate} to check does not match + * @param predicateDescription a description of the {@link Predicate} used in the error message + * @return {@code this} assertion object. + * @throws AssertionError if {@code actual} does match the given {@link Predicate}. + * @throws NullPointerException if given {@link Predicate} is null. + * @throws NullPointerException if given predicateDescription is null. + */ + public SELF doesNotMatch(Predicate predicate, String predicateDescription) { + return doesNotMatch(predicate, new PredicateDescription(predicateDescription)); + } + /** * Verifies that the actual object satisfied the given requirements expressed as {@link Consumer}s. *

@@ -1029,6 +1072,12 @@ private SELF matches(Predicate predicate, PredicateDescription p throw Failures.instance().failure(info, shouldMatch(actual, predicate, predicateDescription)); } + private SELF doesNotMatch(Predicate predicate, PredicateDescription predicateDescription) { + requireNonNull(predicate, "The predicate must not be null"); + if (!predicate.test(actual)) return myself; + throw Failures.instance().failure(info, shouldNotMatch(actual, predicate, predicateDescription)); + } + public static void setCustomRepresentation(Representation customRepresentation) { ConfigurationProvider.loadRegisteredConfiguration(); AbstractAssert.customRepresentation = customRepresentation; diff --git a/assertj-core/src/test/java/org/assertj/core/condition/DoesNotMatchPredicateTest.java b/assertj-core/src/test/java/org/assertj/core/condition/DoesNotMatchPredicateTest.java new file mode 100644 index 0000000000..4e064e43b4 --- /dev/null +++ b/assertj-core/src/test/java/org/assertj/core/condition/DoesNotMatchPredicateTest.java @@ -0,0 +1,92 @@ +/* + * 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. + * + * Copyright 2012-2024 the original author or authors. + */ +package org.assertj.core.condition; + +import static java.lang.String.format; +import static org.assertj.core.internal.ErrorMessages.predicateIsNull; + +import org.assertj.core.api.WithAssertions; +import org.assertj.core.testkit.Jedi; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class DoesNotMatchPredicateTest implements WithAssertions { + + private Jedi yoda; + + @BeforeEach + public void setup() { + yoda = new Jedi("Yoda", "Green"); + } + + @Test + void should_not_match_predicate() { + assertThat(yoda).doesNotMatch(x -> x.lightSaberColor.equals("Blue")); + } + + @Test + void should_not_match_predicate_with_description() { + assertThat(yoda).doesNotMatch(x -> x.lightSaberColor.equals("Blue"), "has blue light saber"); + } + + @Test + void should_fail_if_object_does_match_predicate() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertThat(yoda).doesNotMatch(x -> x.lightSaberColor.equals("Green"))) + .withMessage(format("%n" + + "Expecting actual:%n" + + " Yoda the Jedi%n" + + "not to match given predicate.%n" + + "%n" + + "You can use 'doesNotMatch(Predicate p, String description)' to have a better error message%n" + + + "For example:%n" + + " assertThat(player).doesNotMatch(p -> p.isRookie(), \"is not rookie\");%n" + + + "will give an error message looking like:%n" + + "%n" + + "Expecting actual:%n" + + " player%n" + + "not to match 'is not rookie' predicate")); + } + + @Test + void should_fail_if_object_does_match_predicate_and_use_predicate_description_in_error_message() { + assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertThat(yoda).as("check light saber") + .doesNotMatch(x -> x.lightSaberColor.equals("Green"), + "has red light saber")) + .withMessage(format("[check light saber] %n" + + "Expecting actual:%n" + + " Yoda the Jedi%n" + + "not to match 'has red light saber' predicate.")); + } + + @Test + void should_fail_if_given_predicate_is_null() { + assertThatNullPointerException().isThrownBy(() -> assertThat(yoda).matches(null)) + .withMessage(predicateIsNull()); + } + + @Test + void should_fail_if_given_predicate_with_description_is_null() { + assertThatNullPointerException().isThrownBy(() -> assertThat(yoda).matches(null, + "whatever ...")) + .withMessage(predicateIsNull()); + } + + @Test + void should_fail_if_given_predicate_description_is_null() { + assertThatNullPointerException().isThrownBy(() -> assertThat(yoda).matches(x -> x.lightSaberColor.equals("Green"), + null)) + .withMessage("The predicate description must not be null"); + } +}