Skip to content

Commit

Permalink
Allow to use comparators for specific fields.
Browse files Browse the repository at this point in the history
  • Loading branch information
joel-costigliola committed Feb 13, 2019
1 parent 1acb271 commit 0574849
Show file tree
Hide file tree
Showing 9 changed files with 438 additions and 43 deletions.
Expand Up @@ -22,6 +22,7 @@
import java.util.Map.Entry;
import java.util.Objects;
import java.util.TreeMap;
import java.util.stream.Stream;

import org.assertj.core.util.VisibleForTesting;

Expand All @@ -44,7 +45,7 @@ public FieldComparators() {
* @param comparator the comparator it self
* @param <T> the type of the objects for the comparator
*/
public <T> void register(FieldLocation fieldLocation, Comparator<? super T> comparator) {
public <T> void registerComparator(FieldLocation fieldLocation, Comparator<? super T> comparator) {
fieldComparators.put(fieldLocation, comparator);
}

Expand Down Expand Up @@ -78,4 +79,15 @@ private static String formatRegisteredComparator(Entry<FieldLocation, Comparator
return format("%s -> %s", fieldComparator, fieldComparator.getValue());
}

public boolean hasComparatorForField(FieldLocation fieldLocation) {
return fieldComparators.containsKey(fieldLocation);
}

public Comparator<?> getComparatorForField(FieldLocation fieldLocation) {
return fieldComparators.get(fieldLocation);
}

public Stream<Entry<FieldLocation, Comparator<?>>> getFieldComparators() {
return fieldComparators.entrySet().stream();
}
}
Expand Up @@ -68,4 +68,8 @@ static List<FieldLocation> from(String... fieldPaths) {
return Stream.of(fieldPaths).map(FieldLocation::new).collect(toList());
}

public static FieldLocation fielLocation(String fieldPath) {
return new FieldLocation(fieldPath);
}

}
Expand Up @@ -37,7 +37,7 @@
@Beta
public class RecursiveComparisonConfiguration {

public static final String INDENT_LEVEL_2 = "---";
public static final String INDENT_LEVEL_2 = " -";
// private boolean strictTypeCheck = true;

// fields to ignore section
Expand All @@ -52,26 +52,27 @@ public class RecursiveComparisonConfiguration {

// registered comparators section
private TypeComparators typeComparators = defaultTypeComparators();
// private FieldComparators fieldComparators = new FieldComparators();
private FieldComparators fieldComparators = new FieldComparators();

public Comparator getComparatorForField(String fieldName) {
return null;
}

public Comparator getComparatorForType(Class fieldType) {
return typeComparators.get(fieldType);
// TODO use FieldLocation instead of String ?
public boolean hasComparatorForField(String fieldName) {
return fieldComparators.hasComparatorForField(new FieldLocation(fieldName));
}

public boolean hasComparatorForField(String fieldName) {
return false;
public Comparator<?> getComparatorForField(String fieldName) {
return fieldComparators.getComparatorForField(new FieldLocation(fieldName));
}

public boolean hasComparatorForType(Class<?> keyType) {
return typeComparators.hasComparatorForType(keyType);
}

public boolean hasNoCustomComparators() {
return false;
return false; // TODO fail one test
}

public Comparator<?> getComparatorForType(Class<?> fieldType) {
return typeComparators.get(fieldType);
}

@VisibleForTesting
Expand Down Expand Up @@ -124,7 +125,8 @@ public void ignoreOverriddenEqualsByRegexes(String... regexes) {
.collect(toList());
}

public void ignoreOverriddenEqualsForTypes(Class... types) {
@VisibleForTesting
public void ignoreOverriddenEqualsForTypes(Class<?>... types) {
this.ignoredOverriddenEqualsForTypes = list(types);
}

Expand All @@ -134,7 +136,11 @@ public void ignoreOverriddenEqualsForFields(String... fieldPaths) {
}

public <T> void registerComparatorForType(Class<T> type, Comparator<? super T> comparator) {
this.comparatorForTypes.put(type, comparator);
this.typeComparators.put(type, comparator);
}

public void registerComparatorForField(FieldLocation fieldLocation, Comparator<?> comparator) {
this.fieldComparators.registerComparator(fieldLocation, comparator);
}

@Override
Expand All @@ -149,6 +155,7 @@ public String multiLineDescription(Representation representation) {
describeIgnoredFieldsRegexes(description);
describeOverriddenEqualsMethodsUsage(description, representation);
describeRegisteredComparatorByTypes(description);
describeRegisteredComparatorForFields(description);
return description.toString();
}

Expand Down Expand Up @@ -265,19 +272,40 @@ private boolean isConfiguredToIgnoreSomeOverriddenEqualsMethods() {
}

private void describeRegisteredComparatorByTypes(StringBuilder description) {
if (!comparatorForTypes.isEmpty()) {
description.append(format("- the following comparators were used in the comparison for these types:%n"));
if (!typeComparators.isEmpty()) {
description.append(format("- these types were compared with the following comparators:%n"));
describeComparatorForTypes(description);
}
}

private void describeComparatorForTypes(StringBuilder description) {
this.comparatorForTypes.registeredComparatorByTypes().stream()
.forEach(comparatorByType -> description.append(formatRegisteredComparatorByType(comparatorByType)));
typeComparators.registeredComparatorByTypes()
.map(this::formatRegisteredComparatorByType)
.forEach(description::append);
}

private String formatRegisteredComparatorByType(Entry<Class<?>, Comparator<?>> next) {
return format("%s %s -> %s%n", INDENT_LEVEL_2, next.getKey().getName(), next.getValue());
}

private void describeRegisteredComparatorForFields(StringBuilder description) {
if (!fieldComparators.isEmpty()) {
description.append(format("- these fields were compared with the following comparators:%n"));
describeComparatorForFields(description);
if (!typeComparators.isEmpty()) {
description.append(format("- field comparators take precedence over type comparators.%n"));
}
}
}

private void describeComparatorForFields(StringBuilder description) {
fieldComparators.getFieldComparators()
.map(this::formatRegisteredComparatorForField)
.forEach(description::append);
}

private String formatRegisteredComparatorForField(Entry<FieldLocation, Comparator<?>> comparatorForField) {
return format("%s %s -> %s%n", INDENT_LEVEL_2, comparatorForField.getKey().getFieldPath(), comparatorForField.getValue());
}

}
7 changes: 3 additions & 4 deletions src/main/java/org/assertj/core/internal/TypeComparators.java
Expand Up @@ -13,16 +13,15 @@
package org.assertj.core.internal;

import static java.lang.String.format;
import static java.util.Collections.unmodifiableSet;
import static org.assertj.core.util.Strings.join;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Stream;

import org.assertj.core.util.DoubleComparator;
import org.assertj.core.util.FloatComparator;
Expand Down Expand Up @@ -116,8 +115,8 @@ public boolean isEmpty() {
return typeComparators.isEmpty();
}

public Set<Entry<Class<?>, Comparator<?>>> registeredComparatorByTypes() {
return unmodifiableSet(typeComparators.entrySet());
public Stream<Entry<Class<?>, Comparator<?>>> registeredComparatorByTypes() {
return typeComparators.entrySet().stream();
}

@Override
Expand Down
@@ -0,0 +1,59 @@
/*
* 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.recursive.comparison;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.test.AlwaysEqualComparator.alwaysEqual;

import org.assertj.core.test.AlwaysEqualComparator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class FieldComparators_registerComparator_Test {

private FieldComparators fieldComparators;

@BeforeEach
public void setup() {
fieldComparators = new FieldComparators();
}

@Test
public void should_register_comparator_for_a_given_fieldLocation() {
// GIVEN
FieldLocation fooLocation = new FieldLocation("foo");
// WHEN
AlwaysEqualComparator<?> alwaysEqualComparator = alwaysEqual();
fieldComparators.registerComparator(fooLocation, alwaysEqualComparator);
// THEN
assertThat(fieldComparators.hasComparatorForField(fooLocation)).isTrue();
assertThat(fieldComparators.getComparatorForField(fooLocation)).isSameAs(alwaysEqualComparator);
}

@Test
public void hasComparatorForField_should_return_false_for_field_location_without_comparator() {
// GIVEN
FieldLocation fooLocation = new FieldLocation("foo");
// THEN
assertThat(fieldComparators.hasComparatorForField(fooLocation)).isFalse();
}

@Test
public void getComparatorForField_should_return_null_for_field_location_without_comparator() {
// GIVEN
FieldLocation fooLocation = new FieldLocation("foo");
// THEN
assertThat(fieldComparators.getComparatorForField(fooLocation)).isNull();
}

}
@@ -0,0 +1,52 @@
/*
* 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.recursive.comparison;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.recursive.comparison.FieldLocation.fielLocation;
import static org.assertj.core.test.AlwaysEqualComparator.ALWAY_EQUALS_TUPLE;

import org.assertj.core.util.AbsValueComparator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class RecursiveComparisonConfiguration_fieldComparators_Test {

private RecursiveComparisonConfiguration recursiveComparisonConfiguration;

@BeforeEach
public void setup() {
recursiveComparisonConfiguration = new RecursiveComparisonConfiguration();
}

@Test
public void should_register_given_field_comparators() {
// GIVEN
AbsValueComparator<Integer> integerComparator = new AbsValueComparator<>();
recursiveComparisonConfiguration.registerComparatorForField(fielLocation("height"), integerComparator);
recursiveComparisonConfiguration.registerComparatorForField(fielLocation("weight"), ALWAY_EQUALS_TUPLE);
// THEN
assertThat(recursiveComparisonConfiguration.getComparatorForField("height")).isSameAs(integerComparator);
assertThat(recursiveComparisonConfiguration.getComparatorForField("weight")).isSameAs(ALWAY_EQUALS_TUPLE);
}

@Test
public void should_replace_a_registered_field_comparator() {
// GIVEN
recursiveComparisonConfiguration.registerComparatorForField(fielLocation("height"), new AbsValueComparator<>());
recursiveComparisonConfiguration.registerComparatorForField(fielLocation("height"), ALWAY_EQUALS_TUPLE);
// THEN
assertThat(recursiveComparisonConfiguration.getComparatorForField("height")).isSameAs(ALWAY_EQUALS_TUPLE);
}

}

0 comments on commit 0574849

Please sign in to comment.