Skip to content

Commit c3d6c01

Browse files
authored
Fixes #38 (#53)
* #38 Adds basic Map assertions * Adds MapAssert.isEmpty tests * Adds MapAssert.isNullOrEmpty tests * Adds MapAssert.isNotEmpty tests * Adds MapAssert.hasSize tests * Adds MapAssert.hasSameSizeAs_Iterable tests * Adds MapAssert.hasSameSizeAs_Array tests * Corrects assertions on exceptions messages * Formatting * Adds MapAssert.allSatisfy assertion * Adds MapAssert.contains multiple entries assertion * Adds MapAssert.contains multiple entries assertion * Adds MapAssert.containsAnyOf entries assertion * Adds MapAssert.containsAllEntriesOf assertion * Adds MapAssert.containsEntry assertion * Adds MapAssert.doesNotContainEntry assertion * Adds MapAssert.doesNotContain entries assertion
1 parent 09dd50b commit c3d6c01

17 files changed

+1297
-0
lines changed
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package org.assertj.vavr.api;
2+
3+
/*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
* <p>
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
* <p>
13+
* Copyright 2012-2019 the original author or authors.
14+
*/
15+
16+
import io.vavr.Tuple;
17+
import io.vavr.Tuple2;
18+
import io.vavr.collection.Map;
19+
import org.assertj.core.api.AbstractObjectAssert;
20+
import org.assertj.core.api.EnumerableAssert;
21+
import org.assertj.core.internal.ComparatorBasedComparisonStrategy;
22+
import org.assertj.core.internal.ComparisonStrategy;
23+
import org.assertj.core.internal.StandardComparisonStrategy;
24+
import org.assertj.vavr.internal.Maps;
25+
26+
import java.util.Comparator;
27+
import java.util.function.BiConsumer;
28+
import java.util.stream.StreamSupport;
29+
30+
import static org.assertj.core.error.ShouldBeEmpty.shouldBeEmpty;
31+
import static org.assertj.core.error.ShouldBeNullOrEmpty.shouldBeNullOrEmpty;
32+
import static org.assertj.core.error.ShouldHaveSameSizeAs.shouldHaveSameSizeAs;
33+
import static org.assertj.core.error.ShouldHaveSize.shouldHaveSize;
34+
import static org.assertj.core.error.ShouldNotBeEmpty.shouldNotBeEmpty;
35+
import static org.assertj.core.internal.Arrays.assertIsArray;
36+
import static org.assertj.core.internal.CommonValidations.hasSameSizeAsCheck;
37+
import static org.assertj.core.util.Arrays.array;
38+
import static org.assertj.core.util.IterableUtil.sizeOf;
39+
import static org.assertj.core.util.Preconditions.checkNotNull;
40+
41+
/**
42+
* Assertions for {@link Map}.
43+
*
44+
* @param <KEY> key type of the {@link Map}.
45+
* @param <VALUE> value type of the {@link Map}.
46+
*/
47+
abstract class AbstractMapAssert<SELF extends AbstractMapAssert<SELF, ACTUAL, KEY, VALUE>, ACTUAL extends Map<KEY, VALUE>, KEY, VALUE>
48+
extends AbstractObjectAssert<SELF, ACTUAL> implements EnumerableAssert<SELF, Tuple2<? extends KEY, ? extends VALUE>> {
49+
50+
private final Maps maps = Maps.instance();
51+
private ComparisonStrategy elementComparisonStrategy;
52+
53+
AbstractMapAssert(ACTUAL actual, Class<?> selfType) {
54+
super(actual, selfType);
55+
this.elementComparisonStrategy = StandardComparisonStrategy.instance();
56+
}
57+
58+
/**
59+
* Verifies that all the actual map entries satisfy the given {@code entryRequirements}.
60+
* If the actual map is empty, this assertion succeeds as there is nothing to check.
61+
*
62+
* @param entryRequirements the given requirements that each entry must sastify.
63+
* @return {@code this} assertion object.
64+
* @throws NullPointerException if the given entryRequirements {@link BiConsumer} is {@code null}.
65+
* @throws AssertionError if the actual map is {@code null}.
66+
* @throws AssertionError if one or more entries don't satisfy the given requirements.
67+
*/
68+
public SELF allSatisfy(BiConsumer<? super KEY, ? super VALUE> entryRequirements) {
69+
checkNotNull(entryRequirements, "The BiConsumer<K, V> expressing the assertions requirements must not be null");
70+
isNotNull();
71+
actual.forEach(entry -> entryRequirements.accept(entry._1, entry._2));
72+
return myself;
73+
}
74+
75+
@Override
76+
public void isNullOrEmpty() {
77+
if (actual != null && !actual.isEmpty()) throwAssertionError(shouldBeNullOrEmpty(actual));
78+
}
79+
80+
@Override
81+
public void isEmpty() {
82+
isNotNull();
83+
if (!actual.isEmpty()) throwAssertionError(shouldBeEmpty(actual));
84+
}
85+
86+
@Override
87+
public SELF isNotEmpty() {
88+
isNotNull();
89+
if (actual.isEmpty()) throwAssertionError(shouldNotBeEmpty());
90+
return myself;
91+
}
92+
93+
/**
94+
* Verifies that the actual map contains the given entries, in any order.
95+
* <p>This assertion succeeds if both actual map and given entries are empty.</p>
96+
*
97+
* @param entries the given entries.
98+
* @return {@code this} assertion object.
99+
* @throws NullPointerException if the given argument is {@code null}.
100+
* @throws NullPointerException if any of the entries in the given array is {@code null}.
101+
* @throws AssertionError if the actual map is not empty and the given argument is an empty array.
102+
* @throws AssertionError if the actual map is {@code null}.
103+
* @throws AssertionError if the actual map does not contain the given entries.
104+
*/
105+
public SELF contains(@SuppressWarnings("unchecked") Tuple2<KEY, VALUE>... entries) {
106+
maps.assertContains(info, actual, entries);
107+
return myself;
108+
}
109+
110+
/**
111+
* Verifies that the actual map contains at least one of the given entries.
112+
*
113+
* @param entries the given entries.
114+
* @return {@code this} assertion object.
115+
* @throws NullPointerException if the given argument is {@code null}.
116+
* @throws NullPointerException if any of the entries in the given array is {@code null}.
117+
* @throws AssertionError if the actual map is not empty and the given argument is an empty array.
118+
* @throws AssertionError if the actual map is {@code null}.
119+
* @throws AssertionError if the actual map does not contain any of the given entries.
120+
*/
121+
public SELF containsAnyOf(@SuppressWarnings("unchecked") Tuple2<KEY, VALUE>... entries) {
122+
maps.assertContainsAnyOf(info, actual, entries);
123+
return myself;
124+
}
125+
126+
/**
127+
* Verifies that the actual map contains all entries of the given iterable, in any order.
128+
*
129+
* @param other the iterable with the given entries.
130+
* @return {@code this} assertion object.
131+
* @throws NullPointerException if the given argument is {@code null}.
132+
* @throws NullPointerException if any of the entries in the given iterable is {@code null}.
133+
* @throws AssertionError if the actual map is not empty and the given argument is an empty iterable.
134+
* @throws AssertionError if the actual map is {@code null}.
135+
* @throws AssertionError if the actual map does not contain the given entries.
136+
*/
137+
@SuppressWarnings("unchecked")
138+
public SELF containsAllEntriesOf(Iterable<Tuple2<KEY, VALUE>> other) {
139+
final Tuple2<KEY, VALUE>[] entries = StreamSupport.stream(other.spliterator(), false).toArray(Tuple2[]::new);
140+
maps.assertContains(info, actual, entries);
141+
return myself;
142+
}
143+
144+
/**
145+
* Verifies that the actual map contains the given entry.
146+
*
147+
* @param key the given key to check.
148+
* @param value the given value to check.
149+
* @return {@code this} assertion object.
150+
* @throws AssertionError if the actual map is {@code null}.
151+
* @throws AssertionError if the actual map does not contain the given entries.
152+
*/
153+
public SELF containsEntry(KEY key, VALUE value) {
154+
maps.assertContains(info, actual, array(Tuple.of(key, value)));
155+
return myself;
156+
}
157+
158+
/**
159+
* Verifies that the actual map does not contain the given entries.
160+
*
161+
* @param entries the given entries.
162+
* @return {@code this} assertion object.
163+
* @throws NullPointerException if the given argument is {@code null}.
164+
* @throws IllegalArgumentException if the given argument is an empty array.
165+
* @throws AssertionError if the actual map is {@code null}.
166+
* @throws AssertionError if the actual map contains any of the given entries.
167+
*/
168+
public SELF doesNotContain(Tuple2<KEY, VALUE>... entries) {
169+
maps.assertDoesNotContain(info, actual, entries);
170+
return myself;
171+
}
172+
173+
/**
174+
* Verifies that the actual map does not contain the given entry.
175+
*
176+
* @param key key of the entry.
177+
* @param value value of the entry.
178+
* @return {@code this} assertion object.
179+
* @throws NullPointerException if the given argument is {@code null}.
180+
* @throws IllegalArgumentException if the given argument is an empty array.
181+
* @throws AssertionError if the actual map is {@code null}.
182+
* @throws AssertionError if the actual map contains any of the given entries.
183+
*/
184+
public SELF doesNotContainEntry(KEY key, VALUE value) {
185+
maps.assertDoesNotContain(info, actual, array(Tuple.of(key, value)));
186+
return myself;
187+
}
188+
189+
@Override
190+
public SELF hasSize(int expectedSize) {
191+
isNotNull();
192+
if (actual.size() != expectedSize)
193+
throwAssertionError(shouldHaveSize(actual, actual.size(), expectedSize));
194+
return myself;
195+
}
196+
197+
@Override
198+
public SELF hasSameSizeAs(Iterable<?> other) {
199+
isNotNull();
200+
checkNotNull(other, "The other Iterable to compare actual size with should not be null");
201+
final long expectedSize = sizeOf(other);
202+
if (actual.size() != expectedSize)
203+
throwAssertionError(shouldHaveSameSizeAs(actual, actual.size(), expectedSize));
204+
return myself;
205+
}
206+
207+
@Override
208+
public SELF hasSameSizeAs(Object array) {
209+
isNotNull();
210+
assertIsArray(info, array);
211+
hasSameSizeAsCheck(info, actual, array, actual.size());
212+
return myself;
213+
}
214+
215+
@Override
216+
public SELF usingElementComparator(Comparator<? super Tuple2<? extends KEY, ? extends VALUE>> customComparator) {
217+
elementComparisonStrategy = new ComparatorBasedComparisonStrategy(customComparator);
218+
return myself;
219+
}
220+
221+
@Override
222+
public SELF usingDefaultElementComparator() {
223+
elementComparisonStrategy = StandardComparisonStrategy.instance();
224+
return myself;
225+
}
226+
227+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.assertj.vavr.api;
2+
3+
import io.vavr.collection.Map;
4+
5+
/**
6+
* Assertions for {@link io.vavr.collection.Map}.
7+
*
8+
* @param <KEY> key type of the {@link Map}.
9+
* @param <VALUE> value type of the {@link Map}.
10+
* @author Michał Chmielarz
11+
*/
12+
public class MapAssert<KEY, VALUE> extends AbstractMapAssert<MapAssert<KEY, VALUE>, Map<KEY, VALUE>, KEY, VALUE> {
13+
MapAssert(Map<KEY, VALUE> actual) {
14+
super(actual, MapAssert.class);
15+
}
16+
17+
}

src/main/java/org/assertj/vavr/api/VavrAssertions.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import io.vavr.Lazy;
1616
import io.vavr.collection.List;
17+
import io.vavr.collection.Map;
1718
import io.vavr.collection.Seq;
1819
import io.vavr.control.Either;
1920
import io.vavr.control.Option;
@@ -106,4 +107,18 @@ public static <VALUE> SeqAssert<VALUE> assertThat(Seq<VALUE> actual) {
106107
public static <INVALID, VALID> ValidationAssert<INVALID, VALID> assertThat(Validation<INVALID, VALID> actual) {
107108
return new ValidationAssert<>(actual);
108109
}
110+
111+
/**
112+
* Create assertion for {@link io.vavr.collection.Map}.
113+
*
114+
* @param <KEY> key type of the {@link Map}.
115+
* @param <VALUE> value type of the {@link Map}.
116+
* @param actual the actual value.
117+
* @return the created assertion object.
118+
*/
119+
@CheckReturnValue
120+
public static <KEY, VALUE> MapAssert<KEY, VALUE> assertThat(Map<KEY, VALUE> actual) {
121+
return new MapAssert<>(actual);
122+
}
123+
109124
}

0 commit comments

Comments
 (0)