Skip to content

Commit

Permalink
Add flatExtracting for map #1034
Browse files Browse the repository at this point in the history
  • Loading branch information
dafenix authored and joel-costigliola committed Oct 21, 2017
1 parent e69a0de commit 65948f3
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/main/java/org/assertj/core/api/AbstractMapAssert.java
Expand Up @@ -1153,4 +1153,38 @@ public AbstractMapSizeAssert<SELF, ACTUAL, K, V> size() {
public AbstractObjectArrayAssert<?, Object> extracting(String... keys) {
return super.extracting(keys);
}

/**
* Flatten the list of values of the given keys from the actual map under test into an array, this new array becoming
* the object under test.
* <p>
* If a given key is not present in the map under test, a {@code null} value is extracted.
* <p>
* Example:
* <pre><code class='java'> Map&lt;String, List&lt;String&gt; map = new HashMap&lt;&gt;();
* map.put("name", Arrays.asList("Dave", "Jeff"));
* map.put("job", Arrays.asList("Plumber", "Builder"));
* map.put("city", Arrays.asList("Dover", "Boston", "Paris"));
*
* assertThat(map).flatExtracting("name","job","city")
* .containsExactly("Dave", "Jeff", "Plumber", "Builder", "Dover", "Boston", "Paris");
*
* // order of values is the order of key then key values:
* assertThat(map).flatExtracting("city", "job", "name")
* .containsExactly("Dover", "Boston", "Paris", "Plumber", "Builder", "Dave", "Jeff");
*
* // contains exactly null twice (one for each unknown keys)
* assertThat(map).flatExtracting("foo", "bar")
* .containsExactly(null, null);</code></pre>
* <p>
* Note that the order of values in the resulting array is the order of the map keys iteration then key values.
*
* @param keys the keys used to get values from the map under test
* @return a new assertion object whose object under test is the array containing the extracted map values
*/
@CheckReturnValue
@Override
public AbstractObjectArrayAssert<?, Object> flatExtracting(String... keys) {
return super.flatExtracting(keys);
}
}
23 changes: 23 additions & 0 deletions src/main/java/org/assertj/core/api/AbstractObjectAssert.java
Expand Up @@ -16,8 +16,11 @@
import static org.assertj.core.extractor.Extractors.byName;
import static org.assertj.core.extractor.Extractors.extractedDescriptionOf;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.assertj.core.description.Description;
Expand Down Expand Up @@ -546,10 +549,30 @@ public SELF hasFieldOrPropertyWithValue(String name, Object value) {
@CheckReturnValue
public AbstractObjectArrayAssert<?, Object> extracting(String... propertiesOrFields) {
Tuple values = byName(propertiesOrFields).extract(actual);
return extracting(values.toList(), propertiesOrFields);
}

private AbstractObjectArrayAssert<?, Object> extracting(List<Object> values, String...propertiesOrFields) {
String extractedPropertiesOrFieldsDescription = extractedDescriptionOf(propertiesOrFields);
String description = mostRelevantDescription(info.description(), extractedPropertiesOrFieldsDescription);
return new ObjectArrayAssert<>(values.toArray()).as(description);
}

@CheckReturnValue
public AbstractObjectArrayAssert<?, Object> flatExtracting(String... keys) {
Tuple values = byName(keys).extract(actual);
List<Object> valuesFlattened = flattenNonRecursive(values.toList());
return extracting(valuesFlattened,keys);
}

private static List<Object> flattenNonRecursive(Collection<Object> list) {
List<Object> result = new ArrayList<>();
for (Object item : list) {
if (item instanceof List<?>) result.addAll((List<?>) item);
else result.add(item);
}
return result;
}

/**
* Assert that the object under test (actual) is equal to the given object based on recursive a property/field by property/field comparison (including
Expand Down
@@ -0,0 +1,60 @@
/**
* 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-2017 the original author or authors.
*/
package org.assertj.core.api.map;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.assertj.core.api.MapAssert;
import org.junit.Before;
import org.junit.Test;

/**
* Tests for <code>{@link MapAssert#flatExtracting(String...)}</code>.
*
* @author Daniel Weber
*/
public class MapAssert_flatExtracting_Test {

private Map<String, List<String>> mapOfList;

@Before
public void beforeEachTest() {
mapOfList = new LinkedHashMap<>();
mapOfList.put("name", asList("Dave", "Jeff"));
mapOfList.put("job", asList("Plumber", "Builder"));
mapOfList.put("city", asList("Dover", "Boston", "Paris"));
}

@Test
public void should_allow_assertions_on_flattened_values_extracted_from_given_map_keys() {
assertThat(mapOfList).flatExtracting("name", "job", "city")
.containsExactly("Dave", "Jeff", "Plumber", "Builder", "Dover", "Boston", "Paris");
// order of values is the order of key then key values
assertThat(mapOfList).flatExtracting("city", "job", "name")
.containsExactly("Dover", "Boston", "Paris", "Plumber", "Builder", "Dave", "Jeff");
}

@Test
public void should_extract_null_from_unknown_key() {
assertThat(mapOfList).flatExtracting("name", "id", "city")
.containsExactly("Dave", "Jeff", null, "Dover", "Boston", "Paris");
assertThat(mapOfList).flatExtracting("foo", "bar")
.containsOnlyNulls();
}

}

0 comments on commit 65948f3

Please sign in to comment.