diff --git a/src/main/java/org/assertj/core/util/introspection/PropertyOrFieldSupport.java b/src/main/java/org/assertj/core/util/introspection/PropertyOrFieldSupport.java index b1242bbba0..1868fe7f16 100644 --- a/src/main/java/org/assertj/core/util/introspection/PropertyOrFieldSupport.java +++ b/src/main/java/org/assertj/core/util/introspection/PropertyOrFieldSupport.java @@ -15,10 +15,10 @@ import static java.lang.String.format; import static org.assertj.core.util.Preconditions.checkArgument; -import org.assertj.core.util.VisibleForTesting; - import java.util.Map; +import org.assertj.core.util.VisibleForTesting; + public class PropertyOrFieldSupport { private static final String SEPARATOR = "."; private PropertySupport propertySupport; @@ -60,28 +60,30 @@ public Object getValueOf(String propertyOrFieldName, Object input) { return getSimpleValue(propertyOrFieldName, input); } - public Object getSimpleValue(String propertyOrFieldName, Object input) { - // first check if input object is a map - if (input instanceof Map) { - Map map = (Map) input; - return map.get(propertyOrFieldName); - } - - // then try to get given property values from objects, then try fields + public Object getSimpleValue(String name, Object input) { + // try to get name as a property, then try as a field, then try as a map key try { - return propertySupport.propertyValueOf(propertyOrFieldName, Object.class, input); + return propertySupport.propertyValueOf(name, Object.class, input); } catch (IntrospectionError propertyIntrospectionError) { - // no luck with properties, let's try fields + // no luck as a property, let's try as a field try { - return fieldSupport.fieldValue(propertyOrFieldName, Object.class, input); + return fieldSupport.fieldValue(name, Object.class, input); } catch (IntrospectionError fieldIntrospectionError) { - // no field nor property found with given name, it is considered as an error + // neither field nor property found with given name + + // if the input object is a map, try name as a map key + if (input instanceof Map) { + Map map = (Map) input; + return map.get(name); + } + + // no value found with given name, it is considered as an error String message = format("%nCan't find any field or property with name '%s'.%n" + "Error when introspecting properties was :%n" + "- %s %n" + "Error when introspecting fields was :%n" + "- %s", - propertyOrFieldName, propertyIntrospectionError.getMessage(), + name, propertyIntrospectionError.getMessage(), fieldIntrospectionError.getMessage()); throw new IntrospectionError(message, fieldIntrospectionError); } diff --git a/src/test/java/org/assertj/core/util/introspection/PropertyOrFieldSupport_getSimpleValue_with_Map_input_Test.java b/src/test/java/org/assertj/core/util/introspection/PropertyOrFieldSupport_getSimpleValue_with_Map_input_Test.java new file mode 100644 index 0000000000..1763d2c6d9 --- /dev/null +++ b/src/test/java/org/assertj/core/util/introspection/PropertyOrFieldSupport_getSimpleValue_with_Map_input_Test.java @@ -0,0 +1,73 @@ +/* + * 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-2020 the original author or authors. + */ +package org.assertj.core.util.introspection; + +import static org.assertj.core.api.BDDAssertions.then; + +import java.util.AbstractMap; +import java.util.Collection; +import java.util.HashMap; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * Tests for {@link PropertyOrFieldSupport#getSimpleValue(String, Object)} with {@code Map} input. + * + * @author Stefano Cordio + */ +@DisplayName("PropertyOrFieldSupport getSimpleValue(String, Map)") +class PropertyOrFieldSupport_getSimpleValue_with_Map_input_Test { + + private final PropertyOrFieldSupport underTest = PropertyOrFieldSupport.EXTRACTION; + private final AbstractMap map = new HashMap<>(); + + @Test + void should_extract_property_value_even_if_map_key_matches_given_name() { + // GIVEN + map.put("empty", "value"); // key clashes with AbstractMap#isEmpty() + // WHEN + Object value = underTest.getSimpleValue("empty", map); + // THEN + then(value).isInstanceOf(Boolean.class); + } + + @Test + void should_extract_field_value_even_if_map_key_matches_given_name() { + // GIVEN + map.put("keySet", "value"); // key clashes with AbstractMap#keySet + // WHEN + Object value = underTest.getSimpleValue("keySet", map); + // THEN + then(value).isInstanceOf(Collection.class); + } + + @Test + void should_extract_map_value_when_no_property_or_field_matches_given_name() { + // GIVEN + map.put("key", "value"); + // WHEN + Object value = underTest.getSimpleValue("key", map); + // THEN + then(value).isEqualTo("value"); + } + + @Test + void should_extract_null_when_given_name_is_not_found() { + // WHEN + Object value = underTest.getSimpleValue("unknown", map); + // THEN + then(value).isNull(); + } + +}