Skip to content

Commit

Permalink
anySatisfy: report failing requirements by elements (maps and iterables)
Browse files Browse the repository at this point in the history
  • Loading branch information
epeee authored and joel-costigliola committed Jan 25, 2019
1 parent 5408848 commit 91bda0e
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 64 deletions.
36 changes: 18 additions & 18 deletions src/main/java/org/assertj/core/error/ElementsShouldSatisfy.java
Expand Up @@ -19,30 +19,26 @@

public class ElementsShouldSatisfy extends BasicErrorMessageFactory {

public static ErrorMessageFactory elementsShouldSatisfyAny(Object actual) {
return new ElementsShouldSatisfy(actual);
public static ErrorMessageFactory elementsShouldSatisfyAny(Object actual,
List<UnsatisfiedRequirement> elementsNotSatisfyingRequirements) {
return new ElementsShouldSatisfy("%n" +
"Expecting any element of:%n" +
" <%s>%n" +
"to satisfy the given assertions requirements but none did:%n%n",
actual, elementsNotSatisfyingRequirements);
}

public static ErrorMessageFactory elementsShouldSatisfy(Object actual,
List<UnsatisfiedRequirement> elementsNotSatisfyingRestrictions) {
return new ElementsShouldSatisfy(actual, elementsNotSatisfyingRestrictions);
return new ElementsShouldSatisfy("%n" +
"Expecting all elements of:%n" +
" <%s>%n" +
"to satisfy given requirements, but these elements did not:%n%n",
actual, elementsNotSatisfyingRestrictions);
}

private ElementsShouldSatisfy(Object actual) {
super("%n" +
"Expecting any element of:%n" +
" <%s>%n" +
"to satisfy the given assertions requirements but none did.",
actual);
}

private ElementsShouldSatisfy(Object actual, List<UnsatisfiedRequirement> elementsNotSatisfyingRequirements) {
super("%n" +
"Expecting all elements of:%n" +
" <%s>%n" +
"to satisfy given requirements, but these elements did not:%n%n" +
describeErrors(elementsNotSatisfyingRequirements),
actual);
private ElementsShouldSatisfy(String message, Object actual, List<UnsatisfiedRequirement> elementsNotSatisfyingRequirements) {
super(message + describeErrors(elementsNotSatisfyingRequirements), actual);
}

private static String describeErrors(List<UnsatisfiedRequirement> elementsNotSatisfyingRequirements) {
Expand All @@ -51,6 +47,10 @@ private static String describeErrors(List<UnsatisfiedRequirement> elementsNotSat
.collect(joining(String.format("%n%n"))));
}

public static UnsatisfiedRequirement unsatisfiedRequirement(Object elementNotSatisfyingRequirements, String errorMessage) {
return new ElementsShouldSatisfy.UnsatisfiedRequirement(elementNotSatisfyingRequirements, errorMessage);
}

public static class UnsatisfiedRequirement {

private final Object elementNotSatisfyingRequirements;
Expand Down
17 changes: 7 additions & 10 deletions src/main/java/org/assertj/core/internal/Iterables.java
Expand Up @@ -1160,17 +1160,14 @@ private <ACTUAL_ELEMENT, OTHER_ELEMENT> Optional<ZipSatisfyError> failsZipRequir
public <E> void assertAnySatisfy(AssertionInfo info, Iterable<? extends E> actual, Consumer<? super E> requirements) {
assertNotNull(info, actual);
requireNonNull(requirements, "The Consumer<T> expressing the assertions requirements must not be null");
boolean anyMatch = stream(actual).anyMatch(e -> {
try {
requirements.accept(e);
} catch (AssertionError ex) {
return false;
}
return true;
});

if (!anyMatch) {
throw failures.failure(info, elementsShouldSatisfyAny(actual));
List<UnsatisfiedRequirement> unsatisfiedRequirements = stream(actual).map(element -> failsRequirements(requirements, element))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(toList());
if (unsatisfiedRequirements.size() == sizeOf(actual)) {
// all elements have failed the requirements!
throw failures.failure(info, elementsShouldSatisfyAny(actual, unsatisfiedRequirements));
}
}

Expand Down
21 changes: 10 additions & 11 deletions src/main/java/org/assertj/core/internal/Maps.java
Expand Up @@ -92,8 +92,7 @@ public static Maps instance() {
Conditions conditions = Conditions.instance();

@VisibleForTesting
Maps() {
}
Maps() {}

public <K, V> void assertAllSatisfy(AssertionInfo info, Map<K, V> actual,
BiConsumer<? super K, ? super V> entryRequirements) {
Expand Down Expand Up @@ -122,16 +121,16 @@ public <K, V> void assertAnySatisfy(AssertionInfo info, Map<K, V> actual,
BiConsumer<? super K, ? super V> entryRequirements) {
checkNotNull(entryRequirements, "The BiConsumer<K, V> expressing the assertions requirements must not be null");
assertNotNull(info, actual);
boolean anyMatch = actual.entrySet().stream().anyMatch(e -> {
try {
entryRequirements.accept(e.getKey(), e.getValue());
} catch (AssertionError ex) {
return false;
}
return true;
});

if (!anyMatch) throw failures.failure(info, elementsShouldSatisfyAny(actual));
List<UnsatisfiedRequirement> unsatisfiedRequirements = actual.entrySet().stream()
.map(entry -> failsRequirements(entryRequirements, entry))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(toList());
if (unsatisfiedRequirements.size() == actual.size()) {
// all elements have failed the requirements!
throw failures.failure(info, elementsShouldSatisfyAny(actual, unsatisfiedRequirements));
}
}

/**
Expand Down
Expand Up @@ -12,31 +12,32 @@
*/
package org.assertj.core.api.iterable;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;

import java.util.function.Predicate;
import java.util.function.Consumer;

import org.assertj.core.api.ConcreteIterableAssert;
import org.assertj.core.api.IterableAssertBaseTest;
import org.assertj.core.presentation.PredicateDescription;
import org.junit.jupiter.api.BeforeEach;

public class IterableAssert_anyMatch_Test extends IterableAssertBaseTest {

private Predicate<Object> predicate;
private Consumer<Object> restrictions;

@BeforeEach
public void beforeOnce() {
predicate = o -> o != null;
public void beforeEach() {
restrictions = o -> assertThat(o).isNotNull();
}

@Override
protected ConcreteIterableAssert<Object> invoke_api_method() {
return assertions.anyMatch(predicate);
return assertions.anySatisfy(restrictions);
}

@Override
protected void verify_internal_effects() {
verify(iterables).assertAnyMatch(getInfo(assertions), getActual(assertions), predicate, PredicateDescription.GIVEN);
verify(iterables).assertAnySatisfy(getInfo(assertions), getActual(assertions), restrictions);

}
}
@@ -0,0 +1,42 @@
/*
* 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-2018 the original author or authors.
*/
package org.assertj.core.api.iterable;

import static org.mockito.Mockito.verify;

import java.util.function.Predicate;

import org.assertj.core.api.ConcreteIterableAssert;
import org.assertj.core.api.IterableAssertBaseTest;
import org.assertj.core.presentation.PredicateDescription;
import org.junit.jupiter.api.BeforeEach;

public class IterableAssert_anySatisfy_Test extends IterableAssertBaseTest {

private Predicate<Object> predicate;

@BeforeEach
public void beforeOnce() {
predicate = o -> o != null;
}

@Override
protected ConcreteIterableAssert<Object> invoke_api_method() {
return assertions.anyMatch(predicate);
}

@Override
protected void verify_internal_effects() {
verify(iterables).assertAnyMatch(getInfo(assertions), getActual(assertions), predicate, PredicateDescription.GIVEN);
}
}
Expand Up @@ -16,6 +16,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.error.ElementsShouldSatisfy.elementsShouldSatisfy;
import static org.assertj.core.error.ElementsShouldSatisfy.elementsShouldSatisfyAny;
import static org.assertj.core.error.ElementsShouldSatisfy.unsatisfiedRequirement;
import static org.assertj.core.presentation.StandardRepresentation.STANDARD_REPRESENTATION;
import static org.assertj.core.util.Lists.list;

Expand All @@ -30,8 +31,8 @@ public class ElementsShouldSatisfy_create_Test {
@Test
public void should_create_error_message_all() {
// GIVEN
List<UnsatisfiedRequirement> unsatisfiedRequirements = list(new UnsatisfiedRequirement("Leia", "Leia mistake."),
new UnsatisfiedRequirement("Luke", "Luke mistake."));
List<UnsatisfiedRequirement> unsatisfiedRequirements = list(unsatisfiedRequirement("Leia", "Leia mistake."),
unsatisfiedRequirement("Luke", "Luke mistake."));
ErrorMessageFactory factory = elementsShouldSatisfy(list("Leia", "Luke", "Yoda"), unsatisfiedRequirements);
// WHEN
String message = factory.create(new TextDescription("Test"), STANDARD_REPRESENTATION);
Expand All @@ -47,8 +48,8 @@ public void should_create_error_message_all() {
@Test
public void should_create_error_message_all_and_escape_percent_correctly() {
// GIVEN
List<UnsatisfiedRequirement> unsatisfiedRequirements = list(new UnsatisfiedRequirement("Leia%s", "Leia mistake."),
new UnsatisfiedRequirement("Luke", "Luke mistake."));
List<UnsatisfiedRequirement> unsatisfiedRequirements = list(unsatisfiedRequirement("Leia%s", "Leia mistake."),
unsatisfiedRequirement("Luke", "Luke mistake."));
ErrorMessageFactory factory = elementsShouldSatisfy(list("Leia%s", "Luke", "Yoda"), unsatisfiedRequirements);
// WHEN
String message = factory.create(new TextDescription("Test"), STANDARD_REPRESENTATION);
Expand All @@ -64,26 +65,34 @@ public void should_create_error_message_all_and_escape_percent_correctly() {
@Test
public void should_create_error_message_any() {
// GIVEN
ErrorMessageFactory factory = elementsShouldSatisfyAny(list("Luke", "Yoda"));
List<UnsatisfiedRequirement> unsatisfiedRequirements = list(unsatisfiedRequirement("Leia", "Leia mistake."),
unsatisfiedRequirement("Luke", "Luke mistake."));
ErrorMessageFactory factory = elementsShouldSatisfyAny(list("Luke", "Yoda"), unsatisfiedRequirements);
// WHEN
String message = factory.create(new TextDescription("Test"), STANDARD_REPRESENTATION);
// THEN
assertThat(message).isEqualTo(format("[Test] %n" +
"Expecting any element of:%n" +
" <[\"Luke\", \"Yoda\"]>%n" +
"to satisfy the given assertions requirements but none did."));
"to satisfy the given assertions requirements but none did:%n%n" +
" <Leia> Leia mistake.%n%n" +
" <Luke> Luke mistake."));
}

@Test
public void should_create_error_message_any_and_escape_percent_correctly() {
// GIVEN
ErrorMessageFactory factory = elementsShouldSatisfyAny(list("Lu%dke", "Yoda"));
List<UnsatisfiedRequirement> unsatisfiedRequirements = list(unsatisfiedRequirement("Leia", "Leia mistake."),
unsatisfiedRequirement("Luke", "Luke mistake."));
ErrorMessageFactory factory = elementsShouldSatisfyAny(list("Lu%dke", "Yoda"), unsatisfiedRequirements);
// WHEN
String message = factory.create(new TextDescription("Test"), STANDARD_REPRESENTATION);
// THEN
assertThat(message).isEqualTo(format("[Test] %n" +
"Expecting any element of:%n" +
" <[\"Lu%%dke\", \"Yoda\"]>%n" +
"to satisfy the given assertions requirements but none did."));
"to satisfy the given assertions requirements but none did:%n%n" +
" <Leia> Leia mistake.%n%n" +
" <Luke> Luke mistake."));
}
}
Expand Up @@ -12,18 +12,23 @@
*/
package org.assertj.core.internal.iterables;

import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
import static org.assertj.core.error.ElementsShouldSatisfy.elementsShouldSatisfyAny;
import static org.assertj.core.error.ElementsShouldSatisfy.unsatisfiedRequirement;
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
import static org.assertj.core.util.FailureMessages.actualIsNull;
import static org.assertj.core.util.Lists.emptyList;
import static org.assertj.core.util.Lists.list;
import static org.assertj.core.util.Lists.newArrayList;
import static org.mockito.Mockito.verify;

import java.util.List;

import org.assertj.core.error.ElementsShouldSatisfy;
import org.assertj.core.internal.IterablesBaseTest;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -60,7 +65,26 @@ iterables.<String> assertAnySatisfy(someInfo(), actual, s -> {
assertThat(s).contains("W");
});
} catch (AssertionError e) {
verify(failures).failure(info, elementsShouldSatisfyAny(actual));
List<ElementsShouldSatisfy.UnsatisfiedRequirement> errors = list(unsatisfiedRequirement("Luke", format("%n" +
"Expecting:%n" +
" <\"Luke\">%n" +
"to contain:%n" +
" <\"W\"> ")),
unsatisfiedRequirement("Leia", format("%n" +
"Expecting:%n" +
" <\"Leia\">%n" +
"to contain:%n" +
" <\"W\"> ")),
unsatisfiedRequirement("Yoda", format("%n" +
"Expecting:%n" +
" <\"Yoda\">%n" +
"to contain:%n" +
" <\"W\"> ")),
unsatisfiedRequirement("Obiwan", format("%n" +
"Expected size:<4> but was:<6> in:%n"
+
"<\"Obiwan\">")));
verify(failures).failure(info, elementsShouldSatisfyAny(actual, errors));
return;
}
failBecauseExpectedAssertionErrorWasNotThrown();
Expand All @@ -72,7 +96,8 @@ public void should_fail_if_the_iterable_under_test_is_empty_whatever_the_asserti
try {
iterables.<String> assertAnySatisfy(someInfo(), actual, $ -> assertThat(true).isTrue());
} catch (AssertionError e) {
verify(failures).failure(info, elementsShouldSatisfyAny(actual));
List<ElementsShouldSatisfy.UnsatisfiedRequirement> errors = emptyList();
verify(failures).failure(info, elementsShouldSatisfyAny(actual, errors));
return;
}
failBecauseExpectedAssertionErrorWasNotThrown();
Expand All @@ -86,9 +111,9 @@ public void should_fail_if_consumer_is_null() {

@Test
public void should_fail_if_actual_is_null() {
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->{
actual = null;
assertThat(actual).anySatisfy(null);
}).withMessage(actualIsNull());
// WHEN
AssertionError error = expectAssertionError(() -> iterables.assertAnySatisfy(someInfo(), null, $ -> {}));
// THEN
assertThat(error).hasMessage(actualIsNull());
}
}
}

0 comments on commit 91bda0e

Please sign in to comment.