Skip to content

Commit

Permalink
Add noneSatisfy to AbstractMapAssert. Fixes #1420
Browse files Browse the repository at this point in the history
  • Loading branch information
epeee authored and joel-costigliola committed Feb 10, 2019
1 parent 61b237e commit 83bb091
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/main/java/org/assertj/core/api/AbstractMapAssert.java
Expand Up @@ -135,6 +135,41 @@ public SELF anySatisfy(BiConsumer<? super K, ? super V> entryRequirements) {
return myself;
}

/**
* Verifies that no map entry satisfies the given {@code entryRequirements} .
* <p>
* Example:
* <pre><code class='java'> Map&lt;TolkienCharacter, Ring&gt; elvesRingBearers = new HashMap&lt;&gt;();
* elvesRingBearers.put(galadriel, nenya);
* elvesRingBearers.put(gandalf, narya);
* elvesRingBearers.put(elrond, vilya);
*
* // this assertion succeeds:
* assertThat(elvesRingBearers).noneSatisfy((character, ring) -&gt; {
* assertThat(character.getRace()).isIn(HOBBIT, DWARF);M
* assertThat(ring).isIn(nenya, narya, vilya);
* });
*
* // this assertion fails as Gandalf is a maia.
* assertThat(elvesRingBearers).noneSatisfy((character, ring) -&gt; {
* assertThat(character.getRace()).isEqualTo(MAIA);
* assertThat(ring).isIn(nenya, narya, vilya);
* });</code></pre>
* <p>
* If the actual map is empty, this assertion succeeds as there is nothing to check.
*
* @param entryRequirements the given requirements that each entry must not satisfy.
* @return {@code this} assertion object.
* @throws NullPointerException if the given entryRequirements {@link BiConsumer} is {@code null}.
* @throws AssertionError if the actual map is {@code null}.
* @throws AssertionError if one or more entries satisfies the given requirements.
* @since 3.12.0
*/
public SELF noneSatisfy(BiConsumer<? super K, ? super V> entryRequirements) {
maps.assertNoneSatisfy(info, actual, entryRequirements);
return myself;
}

/**
* Verifies that the {@link Map} is {@code null} or empty.
* <p>
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/assertj/core/internal/Maps.java
Expand Up @@ -17,6 +17,7 @@
import static org.assertj.core.error.ElementsShouldBe.elementsShouldBe;
import static org.assertj.core.error.ElementsShouldSatisfy.elementsShouldSatisfy;
import static org.assertj.core.error.ElementsShouldSatisfy.elementsShouldSatisfyAny;
import static org.assertj.core.error.NoElementsShouldSatisfy.noElementsShouldSatisfy;
import static org.assertj.core.error.ShouldBeEmpty.shouldBeEmpty;
import static org.assertj.core.error.ShouldBeNullOrEmpty.shouldBeNullOrEmpty;
import static org.assertj.core.error.ShouldContain.shouldContain;
Expand Down Expand Up @@ -134,6 +135,30 @@ public <K, V> void assertAnySatisfy(AssertionInfo info, Map<K, V> actual,
}
}

public <K, V> void assertNoneSatisfy(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);

List<Map.Entry<K, V>> erroneousEntries = actual.entrySet().stream()
.map(entry -> failsRestrictions(entry, entryRequirements))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(toList());

if (erroneousEntries.size() > 0) throw failures.failure(info, noElementsShouldSatisfy(actual, erroneousEntries));
}

private <V, K> Optional<Map.Entry<K, V>> failsRestrictions(Map.Entry<K,V> entry, BiConsumer<? super K,? super V> entryRequirements) {
try {
entryRequirements.accept(entry.getKey(), entry.getValue());
} catch (AssertionError e) {
// element is supposed not to meet the given restrictions
return Optional.empty();
}
// element meets the given restrictions!
return Optional.of(entry);
}

/**
* Asserts that the given {@code Map} is {@code null} or empty.
*
Expand Down
@@ -0,0 +1,35 @@
/*
* 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.map;

import static org.mockito.Mockito.verify;

import java.util.function.BiConsumer;

import org.assertj.core.api.MapAssert;
import org.assertj.core.api.MapAssertBaseTest;

public class MapAssert_noneSatisfy_Test extends MapAssertBaseTest {

private BiConsumer<Object, Object> requirements = (k, v) -> {};

@Override
protected MapAssert<Object, Object> invoke_api_method() {
return assertions.noneSatisfy(requirements);
}

@Override
protected void verify_internal_effects() {
verify(maps).assertNoneSatisfy(getInfo(assertions), getActual(assertions), requirements);
}
}
@@ -0,0 +1,105 @@
/*
* 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.internal.maps;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
import static org.assertj.core.data.MapEntry.entry;
import static org.assertj.core.error.NoElementsShouldSatisfy.noElementsShouldSatisfy;
import static org.assertj.core.test.Maps.mapOf;
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
import static org.assertj.core.util.FailureMessages.actualIsNull;
import static org.assertj.core.util.Lists.list;

import java.util.AbstractMap;
import java.util.List;
import java.util.Map;

import org.assertj.core.internal.MapsBaseTest;
import org.assertj.core.test.Player;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class Maps_assertNoneSatisfy_Test extends MapsBaseTest {

private Map<String, Player> greatPlayers;

@Override
@BeforeEach
public void setUp() {
super.setUp();
greatPlayers = mapOf(entry("Bulls", jordan), entry("Spurs", duncan), entry("Lakers", magic));
}

@Test
void should_pass_if_no_entries_satisfy_the_given_requirements() {
maps.assertNoneSatisfy(someInfo(), greatPlayers, (team, player) -> {
assertThat(team).isIn("Spurs");
assertThat(player.getPointsPerGame()).isGreaterThan(20);
});
}

@Test
void should_pass_if_actual_map_is_empty() {
// GIVEN
greatPlayers.clear();
// THEN
maps.assertNoneSatisfy(someInfo(), greatPlayers, ($1, $2) -> assertThat(true).isFalse());
}

@Test
void should_fail_if_one_entry_satisfies_the_given_requirements() {
// WHEN
AssertionError error = expectAssertionError(() -> maps.assertNoneSatisfy(someInfo(), greatPlayers, (team, player) -> {
assertThat(team).isIn("Lakers", "Bulls");
assertThat(player.getPointsPerGame()).as("%s %s ppg", player.getName().first, player.getName().getLast())
.isLessThan(30);
}));
// THEN
List<Map.Entry<?, ?>> erroneousEntries = list(createEntry("Lakers", magic));
assertThat(error).hasMessage(noElementsShouldSatisfy(greatPlayers, erroneousEntries).create());
}

@Test
void should_fail_if_multiple_entries_satisfy_the_given_requirements() {
// WHEN
AssertionError error = expectAssertionError(() -> maps.assertNoneSatisfy(someInfo(), greatPlayers, (team, player) -> {
assertThat(team).isIn("Lakers", "Bulls", "Spurs");
assertThat(player.getPointsPerGame()).as("%s %s ppg", player.getName().first, player.getName().getLast())
.isLessThan(30);
}));
// THEN
List<Map.Entry<?, ?>> erroneousEntries = list(createEntry("Spurs", duncan),
createEntry("Lakers", magic));
assertThat(error).hasMessage(noElementsShouldSatisfy(greatPlayers, erroneousEntries).create());
}

@Test
void should_fail_if_actual_is_null() {
// WHEN
AssertionError error = expectAssertionError(() -> maps.assertNoneSatisfy(someInfo(), null, (team, player) -> {}));
// THEN
assertThat(error).hasMessage(actualIsNull());
}

@Test
void should_fail_if_given_requirements_are_null() {
assertThatNullPointerException().isThrownBy(() -> maps.assertNoneSatisfy(someInfo(), greatPlayers, null))
.withMessage("The BiConsumer<K, V> expressing the assertions requirements must not be null");
}

private static Map.Entry<String, Player> createEntry(String team, Player player) {
return new AbstractMap.SimpleEntry<>(team, player);
}
}

0 comments on commit 83bb091

Please sign in to comment.