Skip to content

Commit dbbe680

Browse files
committed
improve BeanComparator test coverage
1 parent a9d9af0 commit dbbe680

File tree

2 files changed

+104
-45
lines changed

2 files changed

+104
-45
lines changed

src/main/java/org/apache/commons/beanutils2/BeanComparator.java

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
* <p>
2525
* This comparator compares two beans by the specified bean property. It is also possible to compare beans based on nested, indexed, combined, mapped bean
2626
* properties. Please see the {@link PropertyUtilsBean} documentation for all property name possibilities.
27-
*
2827
* </p>
2928
* <p>
3029
* <strong>Note:</strong> The BeanComparator passes the values of the specified bean property to an internal natural order {@link Comparator}, if no comparator
@@ -42,49 +41,12 @@ public class BeanComparator<T, V> implements Comparator<T> {
4241
/**
4342
* A {@link Comparator Comparator} that compares {@link Comparable Comparable} objects.
4443
* <p>
45-
* This Comparator is useful, for example, for enforcing the natural order in custom implementations of {@link java.util.SortedSet SortedSet} and
46-
* {@link java.util.SortedMap SortedMap}.
44+
* This Comparator is useful, for example, for enforcing the natural order in custom implementations
45+
* of {@link java.util.SortedSet SortedSet} and {@link java.util.SortedMap SortedMap}.
4746
* </p>
48-
*
49-
* @param <E> the type of objects compared by this comparator
50-
* @see java.util.Collections#reverseOrder()
5147
*/
52-
private static final class NaturalOrderComparator<E extends Comparable<? super E>> implements Comparator<E> {
53-
54-
/** The singleton instance. */
55-
@SuppressWarnings("rawtypes")
56-
public static final NaturalOrderComparator INSTANCE = new NaturalOrderComparator();
57-
58-
/**
59-
* Private constructor to prevent instantiation. Only use INSTANCE.
60-
*/
61-
private NaturalOrderComparator() {
62-
}
63-
64-
/**
65-
* Compare the two {@link Comparable Comparable} arguments. This method is equivalent to:
66-
*
67-
* <pre>
68-
* ((Comparable) obj1).compareTo(obj2)
69-
* </pre>
70-
*/
71-
@Override
72-
public int compare(final E obj1, final E obj2) {
73-
return obj1.compareTo(obj2);
74-
}
75-
76-
@Override
77-
public boolean equals(final Object object) {
78-
return this == object || null != object && object.getClass().equals(this.getClass());
79-
}
80-
81-
@Override
82-
public int hashCode() {
83-
return "NaturalOrderComparator".hashCode();
84-
}
85-
}
86-
87-
private static final long serialVersionUID = 1L;
48+
@SuppressWarnings({"rawtypes", "unchecked"})
49+
private static final Comparator NATURAL_ORDER_COMPARATOR = (obj1, obj2) -> ((Comparable) obj1).compareTo(obj2);
8850

8951
/** Property. */
9052
private String property;
@@ -120,8 +82,9 @@ public BeanComparator() {
12082
* @param property String Name of a bean property, which may contain the name of a simple, nested, indexed, mapped, or combined property. See
12183
* {@link PropertyUtilsBean} for property query language syntax. If the property passed in is null then the actual objects will be compared
12284
*/
85+
@SuppressWarnings("unchecked")
12386
public BeanComparator(final String property) {
124-
this(property, NaturalOrderComparator.INSTANCE);
87+
this(property, NATURAL_ORDER_COMPARATOR);
12588
}
12689

12790
/**
@@ -135,7 +98,7 @@ public BeanComparator(final String property) {
13598
*/
13699
public BeanComparator(final String property, final Comparator<V> comparator) {
137100
setProperty(property);
138-
this.comparator = comparator != null ? comparator : NaturalOrderComparator.INSTANCE;
101+
this.comparator = comparator != null ? comparator : NATURAL_ORDER_COMPARATOR;
139102
}
140103

141104
/**
@@ -158,7 +121,7 @@ public int compare(final T o1, final T o2) {
158121
final Object value2 = PropertyUtils.getProperty(o2, property);
159122
return internalCompare(value1, value2);
160123
} catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
161-
throw new RuntimeException(e.getClass().getSimpleName() + ": " + e.toString());
124+
throw new RuntimeException(e.getClass().getSimpleName() + ": " + e);
162125
}
163126
}
164127

src/test/java/org/apache/commons/beanutils2/BeanComparatorTest.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717

1818
package org.apache.commons.beanutils2;
1919

20+
import static org.junit.jupiter.api.Assertions.assertAll;
2021
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2123
import static org.junit.jupiter.api.Assertions.assertThrows;
2224
import static org.junit.jupiter.api.Assertions.assertTrue;
2325

26+
import java.util.Comparator;
27+
2428
import org.junit.jupiter.api.AfterEach;
2529
import org.junit.jupiter.api.BeforeEach;
2630
import org.junit.jupiter.api.Test;
@@ -168,4 +172,96 @@ public void testSimpleCompareInverse() {
168172
final int result = beanComparator.compare(alphaBean2, alphaBean1);
169173
assertEquals(1, result, () -> "Comparator did not sort properly. Result:" + result);
170174
}
175+
176+
/**
177+
* Tests comparing two beans via their name using the default natural order Comparator
178+
*/
179+
@Test
180+
public void testSimpleCompareWithDefaultNaturalComparator() {
181+
final BeanComparator<AlphaBean, String> beanComparator = new BeanComparator<>("name", null);
182+
final int result = beanComparator.compare(alphaBean1, alphaBean2);
183+
assertEquals(-1, result, () -> "Comparator did not sort properly. Result:" + result);
184+
}
185+
186+
/**
187+
* Tests comparing two beans via their name using the default natural order Comparator, but the inverse
188+
*/
189+
@Test
190+
public void testSimpleCompareInverseWithDefaultNaturalComparator() {
191+
final BeanComparator<AlphaBean, String> beanComparator = new BeanComparator<>("name", null);
192+
final int result = beanComparator.compare(alphaBean2, alphaBean1);
193+
assertEquals(1, result, () -> "Comparator did not sort properly. Result:" + result);
194+
}
195+
196+
/**
197+
* Tests comparing two comparable beans using the default natural order Comparator
198+
*/
199+
@Test
200+
public void testNaturalCompare() {
201+
final BeanComparator<String, ?> beanComparator = new BeanComparator<>();
202+
final int result = beanComparator.compare("string1", "string2");
203+
assertEquals(-1, result, () -> "Comparator did not sort properly. Result:" + result);
204+
}
205+
206+
/**
207+
* Tests comparing two comparable beans using the default natural order Comparator, but the inverse
208+
*/
209+
@Test
210+
public void testNaturalCompareInverse() {
211+
final BeanComparator<String, ?> beanComparator = new BeanComparator<>();
212+
final int result = beanComparator.compare("string2", "string1");
213+
assertEquals(1, result, () -> "Comparator did not sort properly. Result:" + result);
214+
}
215+
216+
/**
217+
* Tests comparing two beans via their name using the default Comparator
218+
*/
219+
@Test
220+
public void testWithCustomComparator() {
221+
final Comparator<AlphaBean> comparator = Comparator.comparing(AlphaBean::getName);
222+
223+
final BeanComparator<AlphaBean, ?> beanComparator = new BeanComparator<>(null, comparator);
224+
final int result = beanComparator.compare(alphaBean1, alphaBean2);
225+
assertEquals(-1, result, () -> "Comparator did not sort properly. Result:" + result);
226+
}
227+
228+
/**
229+
* Tests comparing two beans via their name using the default Comparator
230+
*/
231+
@Test
232+
public void testWithCustomComparatorInverse() {
233+
final Comparator<AlphaBean> comparator = Comparator.comparing(AlphaBean::getName);
234+
235+
final BeanComparator<AlphaBean, ?> beanComparator = new BeanComparator<>(null, comparator);
236+
final int result = beanComparator.compare(alphaBean2, alphaBean1);
237+
assertEquals(1, result, () -> "Comparator did not sort properly. Result:" + result);
238+
}
239+
240+
@Test
241+
public void testEquals() {
242+
final Comparator<AlphaBean> comparator = Comparator.comparing(AlphaBean::getName);
243+
final BeanComparator<AlphaBean, String> nameComparator = new BeanComparator<>("name");
244+
final BeanComparator<AlphaBean, String> nameComparator2 = new BeanComparator<>("name");
245+
final BeanComparator<AlphaBean, String> nullPropertyComparator1 = new BeanComparator<>(null);
246+
final BeanComparator<AlphaBean, String> nullPropertyComparator2 = new BeanComparator<>(null);
247+
final BeanComparator<AlphaBean, String> nameComparatorDifferentComparator = new BeanComparator<>("name",
248+
String::compareTo);
249+
final BeanComparator<AlphaBean, Boolean> booleanComparator = new BeanComparator<>("booleanProperty");
250+
assertAll(
251+
() -> assertEquals(nameComparator, nameComparator,
252+
"an instance should be equal to itself"),
253+
() -> assertNotEquals(nameComparator, comparator,
254+
"an instance should not be equal to a non-BeanComparator"),
255+
() -> assertNotEquals(nameComparator, nameComparatorDifferentComparator,
256+
"an instance should not be equal to a BeanComparator using different comparator"),
257+
() -> assertNotEquals(nameComparator, booleanComparator,
258+
"an instance should not be equal to a BeanComparator using different property"),
259+
() -> assertEquals(nameComparator, nameComparator2,
260+
"an instance should be equal to a BeanComparator with same comparator and property"),
261+
() -> assertNotEquals(nullPropertyComparator1, booleanComparator,
262+
"an instance with null property comparator should not be equal to a BeanComparator using a property"),
263+
() -> assertEquals(nullPropertyComparator1, nullPropertyComparator2,
264+
"an instance with null property comparator should be equal to a BeanComparator with same comparator and a null property")
265+
);
266+
}
171267
}

0 commit comments

Comments
 (0)