Skip to content

Commit

Permalink
anySatisfy: do not continue evaluating elements once we found a match
Browse files Browse the repository at this point in the history
  • Loading branch information
epeee authored and joel-costigliola committed Feb 27, 2019
1 parent c8a6798 commit fb75625
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
15 changes: 8 additions & 7 deletions src/main/java/org/assertj/core/internal/Iterables.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import static org.assertj.core.util.Lists.newArrayList;
import static org.assertj.core.util.Streams.stream;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -1162,14 +1163,14 @@ public <E> void assertAnySatisfy(AssertionInfo info, Iterable<? extends E> actua
assertNotNull(info, actual);
requireNonNull(requirements, "The Consumer<T> expressing the assertions requirements must not be null");

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, info));
List<UnsatisfiedRequirement> unsatisfiedRequirements = new ArrayList<>();
for (E element : actual) {
Optional<UnsatisfiedRequirement> result = failsRequirements(requirements, element);
if (!result.isPresent()) return; // element satisfied the requirements
unsatisfiedRequirements.add(result.get());
}

throw failures.failure(info, elementsShouldSatisfyAny(actual, unsatisfiedRequirements, info));
}

public <E> void assertAllMatch(AssertionInfo info, Iterable<? extends E> actual, Predicate<? super E> predicate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@
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.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.util.List;
import java.util.function.Consumer;

import org.assertj.core.error.ElementsShouldSatisfy;
import org.assertj.core.internal.IterablesBaseTest;
Expand All @@ -36,6 +41,19 @@ public class Iterables_assertAnySatisfy_Test extends IterablesBaseTest {

private List<String> actual = newArrayList("Luke", "Leia", "Yoda", "Obiwan");

@Test
public void must_not_check_all_elements() {
// GIVEN
Consumer<String> consumer = mock(Consumer.class);
// first element does not match -> assertion error, 2nd element does match -> doNothing()
doThrow(new AssertionError("some error message")).doNothing().when(consumer).accept(anyString());
// WHEN
iterables.assertAnySatisfy(someInfo(), actual, consumer);
// THEN
// make sure that we only evaluated 2 out of 4 elements
verify(consumer, times(2)).accept(anyString());
}

@Test
public void should_pass_when_one_element_satisfies_the_single_assertion_requirement() {
iterables.<String> assertAnySatisfy(someInfo(), actual, s -> assertThat(s).hasSize(6));
Expand Down

0 comments on commit fb75625

Please sign in to comment.