View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3.builder;
18  
19  import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.math.BigInteger;
25  import java.util.Objects;
26  
27  import org.junit.jupiter.api.Test;
28  
29  /**
30   * Tests {@link CompareToBuilder}.
31   */
32  class CompareToBuilderTest extends AbstractBuilderTest {
33  
34      static class TestObject implements Comparable<TestObject> {
35          private int a;
36          TestObject(final int a) {
37              this.a = a;
38          }
39          @Override
40          public int compareTo(final TestObject rhs) {
41              return Integer.compare(a, rhs.a);
42          }
43  
44          @Override
45          public boolean equals(final Object o) {
46              if (o == this) {
47                  return true;
48              }
49              if (!(o instanceof TestObject)) {
50                  return false;
51              }
52              final TestObject rhs = (TestObject) o;
53              return a == rhs.a;
54          }
55  
56          public int getA() {
57              return a;
58          }
59  
60          @Override
61          public int hashCode() {
62              return a;
63          }
64          public void setA(final int a) {
65              this.a = a;
66          }
67      }
68  
69      static class TestSubObject extends TestObject {
70          private int b;
71  
72          TestSubObject() {
73              super(0);
74          }
75  
76          TestSubObject(final int a, final int b) {
77              super(a);
78              this.b = b;
79          }
80  
81          @Override
82          public boolean equals(final Object o) {
83              if (o == this) {
84                  return true;
85              }
86              if (!(o instanceof TestSubObject)) {
87                  return false;
88              }
89              final TestSubObject rhs = (TestSubObject) o;
90              return super.equals(o) && b == rhs.b;
91          }
92  
93          @Override
94          public int hashCode() {
95              return Objects.hash(getA(), b);
96          }
97      }
98  
99      static class TestTransientSubObject extends TestObject {
100         @SuppressWarnings("unused")
101         private final transient int t;
102         TestTransientSubObject(final int a, final int t) {
103             super(a);
104             this.t = t;
105         }
106     }
107 
108     /**
109      * See "Effective Java" under "Consider Implementing Comparable".
110      *
111      * @param x An object to compare
112      * @param y An object to compare
113      * @param z An object to compare
114      * @param testTransients Whether to include transients in the comparison
115      * @param excludeFields fields to exclude
116      * @param expectAccessibleFactor Whether accessibility is expected.
117      */
118     private void assertReflectionCompareContract(final Object x, final Object y, final Object z, final boolean testTransients, final String[] excludeFields,
119             final boolean expectAccessibleFactor) {
120         // signum
121         assertEquals(reflectionCompareSignum(x, y, testTransients, excludeFields), -reflectionCompareSignum(y, x, testTransients, excludeFields));
122 
123         // transitive
124         if (CompareToBuilder.reflectionCompare(x, y, testTransients, null, excludeFields) > 0
125                 && CompareToBuilder.reflectionCompare(y, z, testTransients, null, excludeFields) > 0) {
126             assertTrue(CompareToBuilder.reflectionCompare(x, z, testTransients, null, excludeFields) > 0);
127         }
128 
129         // un-named
130         if (CompareToBuilder.reflectionCompare(x, y, testTransients, null, excludeFields) == 0) {
131             assertEquals(reflectionCompareSignum(x, z, testTransients, excludeFields), -reflectionCompareSignum(y, z, testTransients, excludeFields));
132         }
133 
134         // strongly recommended but not strictly required
135         // assertTrue(CompareToBuilder.reflectionCompare(x, y, testTransients) == 0 == EqualsBuilder.reflectionEquals(x, y, testTransients));
136         //assertTrueIfAccessible(CompareToBuilder.reflectionCompare(x, y, testTransients) == 0 == EqualsBuilder.reflectionEquals(x, y, testTransients));
137         final boolean actual = CompareToBuilder.reflectionCompare(x, y, testTransients) == 0 == EqualsBuilder.reflectionEquals(x, y, testTransients);
138         if (isForceAccessible()) {
139             assertEqualsIfAccessible(expectAccessibleFactor, actual);
140         } else {
141             assertEqualsIfAccessible(isForceAccessible() || expectAccessibleFactor, actual);
142         }
143     }
144 
145     private void assertXYZCompareOrder(final Object x, final Object y, final Object z, final boolean testTransients, final String[] excludeFields) {
146         assertEquals(0, CompareToBuilder.reflectionCompare(x, x, testTransients, null, excludeFields));
147         assertEquals(0, CompareToBuilder.reflectionCompare(y, y, testTransients, null, excludeFields));
148         assertEquals(0, CompareToBuilder.reflectionCompare(z, z, testTransients, null, excludeFields));
149 
150         assertTrueIfAccessible(0 > CompareToBuilder.reflectionCompare(x, y, testTransients, null, excludeFields));
151         assertTrueIfAccessible(0 > CompareToBuilder.reflectionCompare(x, z, testTransients, null, excludeFields));
152         assertTrueIfAccessible(0 > CompareToBuilder.reflectionCompare(y, z, testTransients, null, excludeFields));
153 
154         assertTrueIfAccessible(0 < CompareToBuilder.reflectionCompare(y, x, testTransients, null, excludeFields));
155         assertTrueIfAccessible(0 < CompareToBuilder.reflectionCompare(z, x, testTransients, null, excludeFields));
156         assertTrueIfAccessible(0 < CompareToBuilder.reflectionCompare(z, y, testTransients, null, excludeFields));
157     }
158 
159     /**
160      * Returns the signum of the result of comparing x and y with
161      * {@code CompareToBuilder.reflectionCompare}
162      *
163      * @param lhs The "left-hand-side" of the comparison.
164      * @param rhs The "right-hand-side" of the comparison.
165      * @param testTransients Whether to include transients in the comparison
166      * @param excludeFields fields to exclude
167      * @return int The signum
168      */
169     private int reflectionCompareSignum(final Object lhs, final Object rhs, final boolean testTransients, final String[] excludeFields) {
170         return BigInteger.valueOf(CompareToBuilder.reflectionCompare(lhs, rhs, testTransients)).signum();
171     }
172 
173     @Test
174     void testAppendSuper() {
175         final TestObject o1 = new TestObject(4);
176         final TestObject o2 = new TestObject(5);
177         assertEquals(0, new CompareToBuilder().appendSuper(0).append(o1, o1).toComparison());
178         assertTrue(new CompareToBuilder().appendSuper(0).append(o1, o2).toComparison() < 0);
179         assertTrue(new CompareToBuilder().appendSuper(0).append(o2, o1).toComparison() > 0);
180 
181         assertTrue(new CompareToBuilder().appendSuper(-1).append(o1, o1).toComparison() < 0);
182         assertTrue(new CompareToBuilder().appendSuper(-1).append(o1, o2).toComparison() < 0);
183 
184         assertTrue(new CompareToBuilder().appendSuper(1).append(o1, o1).toComparison() > 0);
185         assertTrue(new CompareToBuilder().appendSuper(1).append(o1, o2).toComparison() > 0);
186     }
187 
188     @Test
189     void testBoolean() {
190         final boolean o1 = true;
191         final boolean o2 = false;
192         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
193         assertEquals(0, new CompareToBuilder().append(o2, o2).toComparison());
194         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() > 0);
195         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() < 0);
196     }
197 
198     @Test
199     void testBooleanArray() {
200         final boolean[] obj1 = new boolean[2];
201         obj1[0] = true;
202         obj1[1] = false;
203         final boolean[] obj2 = new boolean[2];
204         obj2[0] = true;
205         obj2[1] = false;
206         final boolean[] obj3 = new boolean[3];
207         obj3[0] = true;
208         obj3[1] = false;
209         obj3[2] = true;
210 
211         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
212         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
213         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
214         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
215 
216         obj1[1] = true;
217         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
218         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
219 
220         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
221         assertEquals(0, new CompareToBuilder().append((boolean[]) null, null).toComparison());
222         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
223     }
224 
225     @Test
226     void testBooleanArrayHiddenByObject() {
227         final boolean[] array1 = new boolean[2];
228         array1[0] = true;
229         array1[1] = false;
230         final boolean[] array2 = new boolean[2];
231         array2[0] = true;
232         array2[1] = false;
233         final boolean[] array3 = new boolean[3];
234         array3[0] = true;
235         array3[1] = false;
236         array3[2] = true;
237         final Object obj1 = array1;
238         final Object obj2 = array2;
239         final Object obj3 = array3;
240         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
241         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
242         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
243         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
244 
245         array1[1] = true;
246         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
247         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
248     }
249 
250     @Test
251     void testByte() {
252         final byte o1 = 1;
253         final byte o2 = 2;
254         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
255         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
256         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
257         assertTrue(new CompareToBuilder().append(o1, Byte.MAX_VALUE).toComparison() < 0);
258         assertTrue(new CompareToBuilder().append(Byte.MAX_VALUE, o1).toComparison() > 0);
259         assertTrue(new CompareToBuilder().append(o1, Byte.MIN_VALUE).toComparison() > 0);
260         assertTrue(new CompareToBuilder().append(Byte.MIN_VALUE, o1).toComparison() < 0);
261     }
262 
263     @Test
264     void testByteArray() {
265         final byte[] obj1 = new byte[2];
266         obj1[0] = 5;
267         obj1[1] = 6;
268         final byte[] obj2 = new byte[2];
269         obj2[0] = 5;
270         obj2[1] = 6;
271         final byte[] obj3 = new byte[3];
272         obj3[0] = 5;
273         obj3[1] = 6;
274         obj3[2] = 7;
275 
276         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
277         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
278         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
279         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
280 
281         obj1[1] = 7;
282         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
283         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
284 
285         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
286         assertEquals(0, new CompareToBuilder().append((byte[]) null, null).toComparison());
287         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
288     }
289 
290     @Test
291     void testByteArrayHiddenByObject() {
292         final byte[] array1 = new byte[2];
293         array1[0] = 5;
294         array1[1] = 6;
295         final byte[] array2 = new byte[2];
296         array2[0] = 5;
297         array2[1] = 6;
298         final byte[] array3 = new byte[3];
299         array3[0] = 5;
300         array3[1] = 6;
301         array3[2] = 7;
302         final Object obj1 = array1;
303         final Object obj2 = array2;
304         final Object obj3 = array3;
305         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
306         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
307         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
308         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
309 
310         array1[1] = 7;
311         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
312         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
313     }
314 
315     @Test
316     void testChar() {
317         final char o1 = 1;
318         final char o2 = 2;
319         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
320         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
321         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
322         assertTrue(new CompareToBuilder().append(o1, Character.MAX_VALUE).toComparison() < 0);
323         assertTrue(new CompareToBuilder().append(Character.MAX_VALUE, o1).toComparison() > 0);
324         assertTrue(new CompareToBuilder().append(o1, Character.MIN_VALUE).toComparison() > 0);
325         assertTrue(new CompareToBuilder().append(Character.MIN_VALUE, o1).toComparison() < 0);
326     }
327 
328     @Test
329     void testCharArray() {
330         final char[] obj1 = new char[2];
331         obj1[0] = 5;
332         obj1[1] = 6;
333         final char[] obj2 = new char[2];
334         obj2[0] = 5;
335         obj2[1] = 6;
336         final char[] obj3 = new char[3];
337         obj3[0] = 5;
338         obj3[1] = 6;
339         obj3[2] = 7;
340 
341         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
342         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
343         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
344         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
345 
346         obj1[1] = 7;
347         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
348         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
349 
350         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
351         assertEquals(0, new CompareToBuilder().append((char[]) null, null).toComparison());
352         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
353     }
354 
355     @Test
356     void testCharArrayHiddenByObject() {
357         final char[] array1 = new char[2];
358         array1[0] = 5;
359         array1[1] = 6;
360         final char[] array2 = new char[2];
361         array2[0] = 5;
362         array2[1] = 6;
363         final char[] array3 = new char[3];
364         array3[0] = 5;
365         array3[1] = 6;
366         array3[2] = 7;
367         final Object obj1 = array1;
368         final Object obj2 = array2;
369         final Object obj3 = array3;
370         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
371         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
372         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
373         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
374 
375         array1[1] = 7;
376         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
377         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
378     }
379 
380     /**
381      * Mutually-referential {@code Object[]}s: {@code a[0] = b}, {@code b[0] = a}, with {@code a != b}. The recursion is
382      * {@code append(a,b) -> append(a[0]=b, b[0]=a) -> append(b,a) ->
383      * append(b[0]=a, a[0]=b) -> append(a,b)}, never terminating.
384      */
385     @Test
386     void testCycleMutuallyReferentialObjectArrays() {
387         final Object[] a = new Object[1];
388         final Object[] b = new Object[1];
389         a[0] = b;
390         b[0] = a;
391         assertEquals(0, new CompareToBuilder().append(a, b, null).toComparison());
392         assertEquals(0, new CompareToBuilder().append((Object) a, (Object) b, null).toComparison());
393     }
394 
395     /**
396      * Two distinct self-referential {@code Object[]}s: {@code a[0] = a}, {@code b[0] = b}, with {@code a != b}. The recursion is
397      * {@code append(a,b) -> append(a[0]=a, b[0]=b) -> append(a,b)}, never terminating.
398      */
399     @Test
400     void testCycleTwoDistinctSelfReferentialObjectArrays() {
401         final Object[] a = new Object[1];
402         final Object[] b = new Object[1];
403         a[0] = a;
404         b[0] = b;
405         assertEquals(0, new CompareToBuilder().append(a, b, null).toComparison());
406         assertEquals(0, new CompareToBuilder().append((Object) a, (Object) b, null).toComparison());
407     }
408 
409     @Test
410     void testDouble() {
411         final double o1 = 1;
412         final double o2 = 2;
413         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
414         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
415         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
416         assertTrue(new CompareToBuilder().append(o1, Double.MAX_VALUE).toComparison() < 0);
417         assertTrue(new CompareToBuilder().append(Double.MAX_VALUE, o1).toComparison() > 0);
418         assertTrue(new CompareToBuilder().append(o1, Double.MIN_VALUE).toComparison() > 0);
419         assertTrue(new CompareToBuilder().append(Double.MIN_VALUE, o1).toComparison() < 0);
420         assertEquals(0, new CompareToBuilder().append(Double.NaN, Double.NaN).toComparison());
421         assertTrue(new CompareToBuilder().append(Double.NaN, Double.MAX_VALUE).toComparison() > 0);
422         assertTrue(new CompareToBuilder().append(Double.POSITIVE_INFINITY, Double.MAX_VALUE).toComparison() > 0);
423         assertTrue(new CompareToBuilder().append(Double.NEGATIVE_INFINITY, Double.MIN_VALUE).toComparison() < 0);
424         assertTrue(new CompareToBuilder().append(o1, Double.NaN).toComparison() < 0);
425         assertTrue(new CompareToBuilder().append(Double.NaN, o1).toComparison() > 0);
426         assertTrue(new CompareToBuilder().append(-0.0, 0.0).toComparison() < 0);
427         assertTrue(new CompareToBuilder().append(0.0, -0.0).toComparison() > 0);
428     }
429 
430     @Test
431     void testDoubleArray() {
432         final double[] obj1 = new double[2];
433         obj1[0] = 5;
434         obj1[1] = 6;
435         final double[] obj2 = new double[2];
436         obj2[0] = 5;
437         obj2[1] = 6;
438         final double[] obj3 = new double[3];
439         obj3[0] = 5;
440         obj3[1] = 6;
441         obj3[2] = 7;
442 
443         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
444         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
445         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
446         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
447 
448         obj1[1] = 7;
449         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
450         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
451 
452         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
453         assertEquals(0, new CompareToBuilder().append((double[]) null, null).toComparison());
454         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
455     }
456 
457     @Test
458     void testDoubleArrayHiddenByObject() {
459         final double[] array1 = new double[2];
460         array1[0] = 5;
461         array1[1] = 6;
462         final double[] array2 = new double[2];
463         array2[0] = 5;
464         array2[1] = 6;
465         final double[] array3 = new double[3];
466         array3[0] = 5;
467         array3[1] = 6;
468         array3[2] = 7;
469         final Object obj1 = array1;
470         final Object obj2 = array2;
471         final Object obj3 = array3;
472         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
473         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
474         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
475         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
476 
477         array1[1] = 7;
478         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
479         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
480     }
481 
482     @Test
483     void testFloat() {
484         final float o1 = 1;
485         final float o2 = 2;
486         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
487         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
488         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
489         assertTrue(new CompareToBuilder().append(o1, Float.MAX_VALUE).toComparison() < 0);
490         assertTrue(new CompareToBuilder().append(Float.MAX_VALUE, o1).toComparison() > 0);
491         assertTrue(new CompareToBuilder().append(o1, Float.MIN_VALUE).toComparison() > 0);
492         assertTrue(new CompareToBuilder().append(Float.MIN_VALUE, o1).toComparison() < 0);
493         assertEquals(0, new CompareToBuilder().append(Float.NaN, Float.NaN).toComparison());
494         assertTrue(new CompareToBuilder().append(Float.NaN, Float.MAX_VALUE).toComparison() > 0);
495         assertTrue(new CompareToBuilder().append(Float.POSITIVE_INFINITY, Float.MAX_VALUE).toComparison() > 0);
496         assertTrue(new CompareToBuilder().append(Float.NEGATIVE_INFINITY, Float.MIN_VALUE).toComparison() < 0);
497         assertTrue(new CompareToBuilder().append(o1, Float.NaN).toComparison() < 0);
498         assertTrue(new CompareToBuilder().append(Float.NaN, o1).toComparison() > 0);
499         assertTrue(new CompareToBuilder().append(-0.0, 0.0).toComparison() < 0);
500         assertTrue(new CompareToBuilder().append(0.0, -0.0).toComparison() > 0);
501     }
502 
503     @Test
504     void testFloatArray() {
505         final float[] obj1 = new float[2];
506         obj1[0] = 5;
507         obj1[1] = 6;
508         final float[] obj2 = new float[2];
509         obj2[0] = 5;
510         obj2[1] = 6;
511         final float[] obj3 = new float[3];
512         obj3[0] = 5;
513         obj3[1] = 6;
514         obj3[2] = 7;
515 
516         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
517         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
518         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
519         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
520 
521         obj1[1] = 7;
522         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
523         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
524 
525         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
526         assertEquals(0, new CompareToBuilder().append((float[]) null, null).toComparison());
527         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
528     }
529 
530     @Test
531     void testFloatArrayHiddenByObject() {
532         final float[] array1 = new float[2];
533         array1[0] = 5;
534         array1[1] = 6;
535         final float[] array2 = new float[2];
536         array2[0] = 5;
537         array2[1] = 6;
538         final float[] array3 = new float[3];
539         array3[0] = 5;
540         array3[1] = 6;
541         array3[2] = 7;
542         final Object obj1 = array1;
543         final Object obj2 = array2;
544         final Object obj3 = array3;
545         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
546         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
547         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
548         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
549 
550         array1[1] = 7;
551         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
552         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
553     }
554 
555     @Test
556     void testInt() {
557         final int o1 = 1;
558         final int o2 = 2;
559         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
560         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
561         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
562         assertTrue(new CompareToBuilder().append(o1, Integer.MAX_VALUE).toComparison() < 0);
563         assertTrue(new CompareToBuilder().append(Integer.MAX_VALUE, o1).toComparison() > 0);
564         assertTrue(new CompareToBuilder().append(o1, Integer.MIN_VALUE).toComparison() > 0);
565         assertTrue(new CompareToBuilder().append(Integer.MIN_VALUE, o1).toComparison() < 0);
566     }
567 
568     @Test
569     void testIntArray() {
570         final int[] obj1 = new int[2];
571         obj1[0] = 5;
572         obj1[1] = 6;
573         final int[] obj2 = new int[2];
574         obj2[0] = 5;
575         obj2[1] = 6;
576         final int[] obj3 = new int[3];
577         obj3[0] = 5;
578         obj3[1] = 6;
579         obj3[2] = 7;
580 
581         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
582         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
583         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
584         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
585 
586         obj1[1] = 7;
587         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
588         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
589 
590         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
591         assertEquals(0, new CompareToBuilder().append((int[]) null, null).toComparison());
592         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
593     }
594 
595     @Test
596     void testIntArrayHiddenByObject() {
597         final int[] array1 = new int[2];
598         array1[0] = 5;
599         array1[1] = 6;
600         final int[] array2 = new int[2];
601         array2[0] = 5;
602         array2[1] = 6;
603         final int[] array3 = new int[3];
604         array3[0] = 5;
605         array3[1] = 6;
606         array3[2] = 7;
607         final Object obj1 = array1;
608         final Object obj2 = array2;
609         final Object obj3 = array3;
610         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
611         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
612         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
613         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
614 
615         array1[1] = 7;
616         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
617         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
618     }
619 
620     @Test
621     void testLong() {
622         final long o1 = 1L;
623         final long o2 = 2L;
624         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
625         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
626         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
627         assertTrue(new CompareToBuilder().append(o1, Long.MAX_VALUE).toComparison() < 0);
628         assertTrue(new CompareToBuilder().append(Long.MAX_VALUE, o1).toComparison() > 0);
629         assertTrue(new CompareToBuilder().append(o1, Long.MIN_VALUE).toComparison() > 0);
630         assertTrue(new CompareToBuilder().append(Long.MIN_VALUE, o1).toComparison() < 0);
631     }
632 
633     @Test
634     void testLongArray() {
635         final long[] obj1 = new long[2];
636         obj1[0] = 5L;
637         obj1[1] = 6L;
638         final long[] obj2 = new long[2];
639         obj2[0] = 5L;
640         obj2[1] = 6L;
641         final long[] obj3 = new long[3];
642         obj3[0] = 5L;
643         obj3[1] = 6L;
644         obj3[2] = 7L;
645 
646         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
647         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
648         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
649         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
650 
651         obj1[1] = 7;
652         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
653         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
654 
655         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
656         assertEquals(0, new CompareToBuilder().append((long[]) null, null).toComparison());
657         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
658     }
659 
660     @Test
661     void testLongArrayHiddenByObject() {
662         final long[] array1 = new long[2];
663         array1[0] = 5L;
664         array1[1] = 6L;
665         final long[] array2 = new long[2];
666         array2[0] = 5L;
667         array2[1] = 6L;
668         final long[] array3 = new long[3];
669         array3[0] = 5L;
670         array3[1] = 6L;
671         array3[2] = 7L;
672         final Object obj1 = array1;
673         final Object obj2 = array2;
674         final Object obj3 = array3;
675         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
676         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
677         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
678         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
679 
680         array1[1] = 7;
681         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
682         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
683     }
684 
685     @Test
686     void testMixedArray() {
687         final Object[] array1 = new Object[2];
688         final Object[] array2 = new Object[2];
689         final Object[] array3 = new Object[2];
690         for (int i = 0; i < array1.length; ++i) {
691             array1[i] = new long[2];
692             array2[i] = new long[2];
693             array3[i] = new long[3];
694             for (int j = 0; j < 2; ++j) {
695                 ((long[]) array1[i])[j] = (i + 1) * (j + 1);
696                 ((long[]) array2[i])[j] = (i + 1) * (j + 1);
697                 ((long[]) array3[i])[j] = (i + 1) * (j + 1);
698             }
699         }
700         ((long[]) array3[0])[2] = 1;
701         ((long[]) array3[1])[2] = 1;
702         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
703         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
704         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
705         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
706         ((long[]) array1[1])[1] = 200;
707         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
708         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
709     }
710 
711     @Test
712     void testMultiBooleanArray() {
713         final boolean[][] array1 = new boolean[2][2];
714         final boolean[][] array2 = new boolean[2][2];
715         final boolean[][] array3 = new boolean[2][3];
716         for (int i = 0; i < array1.length; ++i) {
717             for (int j = 0; j < array1[0].length; j++) {
718                 array1[i][j] = i == 1 ^ j == 1;
719                 array2[i][j] = i == 1 ^ j == 1;
720                 array3[i][j] = i == 1 ^ j == 1;
721             }
722         }
723         array3[1][2] = false;
724         array3[1][2] = false;
725 
726         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
727         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
728         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
729         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
730         array1[1][1] = true;
731         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
732         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
733     }
734 
735     @Test
736     void testMultiByteArray() {
737         final byte[][] array1 = new byte[2][2];
738         final byte[][] array2 = new byte[2][2];
739         final byte[][] array3 = new byte[2][3];
740         for (byte i = 0; i < array1.length; ++i) {
741             for (byte j = 0; j < array1[0].length; j++) {
742                 array1[i][j] = (byte) ((i + 1) * (j + 1));
743                 array2[i][j] = (byte) ((i + 1) * (j + 1));
744                 array3[i][j] = (byte) ((i + 1) * (j + 1));
745             }
746         }
747         array3[1][2] = 100;
748         array3[1][2] = 100;
749 
750         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
751         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
752         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
753         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
754         array1[1][1] = 127;
755         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
756         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
757     }
758 
759     @Test
760     void testMultiCharArray() {
761         final char[][] array1 = new char[2][2];
762         final char[][] array2 = new char[2][2];
763         final char[][] array3 = new char[2][3];
764         for (short i = 0; i < array1.length; ++i) {
765             for (short j = 0; j < array1[0].length; j++) {
766                 array1[i][j] = (char) ((i + 1) * (j + 1));
767                 array2[i][j] = (char) ((i + 1) * (j + 1));
768                 array3[i][j] = (char) ((i + 1) * (j + 1));
769             }
770         }
771         array3[1][2] = 100;
772         array3[1][2] = 100;
773 
774         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
775         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
776         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
777         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
778         array1[1][1] = 200;
779         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
780         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
781     }
782 
783     @Test
784     void testMultiDoubleArray() {
785         final double[][] array1 = new double[2][2];
786         final double[][] array2 = new double[2][2];
787         final double[][] array3 = new double[2][3];
788         for (int i = 0; i < array1.length; ++i) {
789             for (int j = 0; j < array1[0].length; j++) {
790                 array1[i][j] = (i + 1) * (j + 1);
791                 array2[i][j] = (i + 1) * (j + 1);
792                 array3[i][j] = (i + 1) * (j + 1);
793             }
794         }
795         array3[1][2] = 100;
796         array3[1][2] = 100;
797 
798         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
799         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
800         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
801         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
802         array1[1][1] = 127;
803         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
804         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
805     }
806 
807     @Test
808     void testMultiFloatArray() {
809         final float[][] array1 = new float[2][2];
810         final float[][] array2 = new float[2][2];
811         final float[][] array3 = new float[2][3];
812         for (int i = 0; i < array1.length; ++i) {
813             for (int j = 0; j < array1[0].length; j++) {
814                 array1[i][j] = (i + 1) * (j + 1);
815                 array2[i][j] = (i + 1) * (j + 1);
816                 array3[i][j] = (i + 1) * (j + 1);
817             }
818         }
819         array3[1][2] = 100;
820         array3[1][2] = 100;
821 
822         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
823         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
824         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
825         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
826         array1[1][1] = 127;
827         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
828         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
829     }
830 
831     @Test
832     void testMultiIntArray() {
833         final int[][] array1 = new int[2][2];
834         final int[][] array2 = new int[2][2];
835         final int[][] array3 = new int[2][3];
836         for (int i = 0; i < array1.length; ++i) {
837             for (int j = 0; j < array1[0].length; j++) {
838                 array1[i][j] = (i + 1) * (j + 1);
839                 array2[i][j] = (i + 1) * (j + 1);
840                 array3[i][j] = (i + 1) * (j + 1);
841             }
842         }
843         array3[1][2] = 100;
844         array3[1][2] = 100;
845 
846         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
847         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
848         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
849         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
850         array1[1][1] = 200;
851         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
852         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
853     }
854 
855     @Test
856     void testMultiLongArray() {
857         final long[][] array1 = new long[2][2];
858         final long[][] array2 = new long[2][2];
859         final long[][] array3 = new long[2][3];
860         for (int i = 0; i < array1.length; ++i) {
861             for (int j = 0; j < array1[0].length; j++) {
862                 array1[i][j] = (i + 1) * (j + 1);
863                 array2[i][j] = (i + 1) * (j + 1);
864                 array3[i][j] = (i + 1) * (j + 1);
865             }
866         }
867         array3[1][2] = 100;
868         array3[1][2] = 100;
869 
870         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
871         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
872         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
873         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
874         array1[1][1] = 200;
875         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
876         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
877     }
878 
879     @Test
880     void testMultiShortArray() {
881         final short[][] array1 = new short[2][2];
882         final short[][] array2 = new short[2][2];
883         final short[][] array3 = new short[2][3];
884         for (short i = 0; i < array1.length; ++i) {
885             for (short j = 0; j < array1[0].length; j++) {
886                 array1[i][j] = (short) ((i + 1) * (j + 1));
887                 array2[i][j] = (short) ((i + 1) * (j + 1));
888                 array3[i][j] = (short) ((i + 1) * (j + 1));
889             }
890         }
891         array3[1][2] = 100;
892         array3[1][2] = 100;
893 
894         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
895         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
896         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
897         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
898         array1[1][1] = 200;
899         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
900         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
901     }
902 
903     @Test
904     void testObject() {
905         final TestObject o1 = new TestObject(4);
906         final TestObject o2 = new TestObject(4);
907         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
908         assertEquals(0, new CompareToBuilder().append(o1, o2).toComparison());
909         o2.setA(5);
910         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
911         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
912 
913         assertTrue(new CompareToBuilder().append(o1, null).toComparison() > 0);
914         assertEquals(0, new CompareToBuilder().append((Object) null, null).toComparison());
915         assertTrue(new CompareToBuilder().append(null, o1).toComparison() < 0);
916     }
917 
918     @Test
919     void testObjectArray() {
920         final TestObject[] obj1 = new TestObject[2];
921         obj1[0] = new TestObject(4);
922         obj1[1] = new TestObject(5);
923         final TestObject[] obj2 = new TestObject[2];
924         obj2[0] = new TestObject(4);
925         obj2[1] = new TestObject(5);
926         final TestObject[] obj3 = new TestObject[3];
927         obj3[0] = new TestObject(4);
928         obj3[1] = new TestObject(5);
929         obj3[2] = new TestObject(6);
930 
931         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
932         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
933         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
934         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
935 
936         obj1[1] = new TestObject(7);
937         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
938         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
939 
940         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
941         assertEquals(0, new CompareToBuilder().append((Object[]) null, null).toComparison());
942         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
943     }
944 
945     @Test
946     void testObjectArrayHiddenByObject() {
947         final TestObject[] array1 = new TestObject[2];
948         array1[0] = new TestObject(4);
949         array1[1] = new TestObject(5);
950         final TestObject[] array2 = new TestObject[2];
951         array2[0] = new TestObject(4);
952         array2[1] = new TestObject(5);
953         final TestObject[] array3 = new TestObject[3];
954         array3[0] = new TestObject(4);
955         array3[1] = new TestObject(5);
956         array3[2] = new TestObject(6);
957 
958         final Object obj1 = array1;
959         final Object obj2 = array2;
960         final Object obj3 = array3;
961 
962         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
963         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
964         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
965         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
966 
967         array1[1] = new TestObject(7);
968         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
969         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
970     }
971 
972     @Test
973     void testObjectBuild() {
974         final TestObject o1 = new TestObject(4);
975         final TestObject o2 = new TestObject(4);
976         assertEquals(Integer.valueOf(0), new CompareToBuilder().append(o1, o1).build());
977         assertEquals(Integer.valueOf(0), new CompareToBuilder().append(o1, o2).build());
978         o2.setA(5);
979         assertTrue(new CompareToBuilder().append(o1, o2).build().intValue() < 0);
980         assertTrue(new CompareToBuilder().append(o2, o1).build().intValue() > 0);
981 
982         assertTrue(new CompareToBuilder().append(o1, null).build().intValue() > 0);
983         assertEquals(Integer.valueOf(0), new CompareToBuilder().append((Object) null, null).build());
984         assertTrue(new CompareToBuilder().append(null, o1).build().intValue() < 0);
985     }
986 
987     @Test
988     void testObjectComparator() {
989         final String o1 = "Fred";
990         String o2 = "Fred";
991         assertEquals(0, new CompareToBuilder().append(o1, o1, String.CASE_INSENSITIVE_ORDER).toComparison());
992         assertEquals(0, new CompareToBuilder().append(o1, o2, String.CASE_INSENSITIVE_ORDER).toComparison());
993         o2 = "FRED";
994         assertEquals(0, new CompareToBuilder().append(o1, o2, String.CASE_INSENSITIVE_ORDER).toComparison());
995         assertEquals(0, new CompareToBuilder().append(o2, o1, String.CASE_INSENSITIVE_ORDER).toComparison());
996         o2 = "FREDA";
997         assertTrue(new CompareToBuilder().append(o1, o2, String.CASE_INSENSITIVE_ORDER).toComparison() < 0);
998         assertTrue(new CompareToBuilder().append(o2, o1, String.CASE_INSENSITIVE_ORDER).toComparison() > 0);
999 
1000         assertTrue(new CompareToBuilder().append(o1, null, String.CASE_INSENSITIVE_ORDER).toComparison() > 0);
1001         assertEquals(0, new CompareToBuilder().append(null, null, String.CASE_INSENSITIVE_ORDER).toComparison());
1002         assertTrue(new CompareToBuilder().append(null, o1, String.CASE_INSENSITIVE_ORDER).toComparison() < 0);
1003     }
1004 
1005     @Test
1006     void testObjectComparatorNull() {
1007         final String o1 = "Fred";
1008         String o2 = "Fred";
1009         assertEquals(0, new CompareToBuilder().append(o1, o1, null).toComparison());
1010         assertEquals(0, new CompareToBuilder().append(o1, o2, null).toComparison());
1011         o2 = "Zebra";
1012         assertTrue(new CompareToBuilder().append(o1, o2, null).toComparison() < 0);
1013         assertTrue(new CompareToBuilder().append(o2, o1, null).toComparison() > 0);
1014 
1015         assertTrue(new CompareToBuilder().append(o1, null, null).toComparison() > 0);
1016         assertEquals(0, new CompareToBuilder().append(null, null, null).toComparison());
1017         assertTrue(new CompareToBuilder().append(null, o1, null).toComparison() < 0);
1018     }
1019 
1020     @Test
1021     void testObjectEx2() {
1022         final TestObject o1 = new TestObject(4);
1023         final Object o2 = new Object();
1024         assertThrows(ClassCastException.class, () -> new CompareToBuilder().append(o1, o2));
1025     }
1026 
1027     @Test
1028     void testRaggedArray() {
1029         final long[][] array1 = new long[2][];
1030         final long[][] array2 = new long[2][];
1031         final long[][] array3 = new long[3][];
1032         for (int i = 0; i < array1.length; ++i) {
1033             array1[i] = new long[2];
1034             array2[i] = new long[2];
1035             array3[i] = new long[3];
1036             for (int j = 0; j < array1[i].length; ++j) {
1037                 array1[i][j] = (i + 1) * (j + 1);
1038                 array2[i][j] = (i + 1) * (j + 1);
1039                 array3[i][j] = (i + 1) * (j + 1);
1040             }
1041         }
1042         array3[1][2] = 100;
1043         array3[1][2] = 100;
1044 
1045         assertEquals(0, new CompareToBuilder().append(array1, array1).toComparison());
1046         assertEquals(0, new CompareToBuilder().append(array1, array2).toComparison());
1047         assertTrue(new CompareToBuilder().append(array1, array3).toComparison() < 0);
1048         assertTrue(new CompareToBuilder().append(array3, array1).toComparison() > 0);
1049         array1[1][1] = 200;
1050         assertTrue(new CompareToBuilder().append(array1, array2).toComparison() > 0);
1051         assertTrue(new CompareToBuilder().append(array2, array1).toComparison() < 0);
1052     }
1053 
1054     @Test
1055     void testReflectionCompare() {
1056         final TestObject o1 = new TestObject(4);
1057         final TestObject o2 = new TestObject(4);
1058         assertEquals(0, CompareToBuilder.reflectionCompare(o1, o1));
1059         assertEquals(0, CompareToBuilder.reflectionCompare(o1, o2));
1060         o2.setA(5);
1061         assertTrueIfAccessible(CompareToBuilder.reflectionCompare(o1, o2) < 0);
1062         assertTrueIfAccessible(CompareToBuilder.reflectionCompare(o2, o1) > 0);
1063     }
1064 
1065     @Test
1066     void testReflectionCompareEx1() {
1067         final TestObject o1 = new TestObject(4);
1068         assertNullPointerException(() -> CompareToBuilder.reflectionCompare(o1, null));
1069     }
1070 
1071     @Test
1072     void testReflectionCompareEx2() {
1073         final TestObject o1 = new TestObject(4);
1074         final Object o2 = new Object();
1075         assertThrows(ClassCastException.class, () -> CompareToBuilder.reflectionCompare(o1, o2));
1076     }
1077 
1078     @Test
1079     void testReflectionHierarchyCompare() {
1080         testReflectionHierarchyCompare(false, null);
1081     }
1082 
1083     private void testReflectionHierarchyCompare(final boolean testTransients, final String[] excludeFields) {
1084         final TestObject to1 = new TestObject(1);
1085         final TestObject to2 = new TestObject(2);
1086         final TestObject to3 = new TestObject(3);
1087         final TestSubObject tso1 = new TestSubObject(1, 1);
1088         final TestSubObject tso2 = new TestSubObject(2, 2);
1089         final TestSubObject tso3 = new TestSubObject(3, 3);
1090 
1091         assertReflectionCompareContract(to1, to1, to1, false, excludeFields, isForceAccessible());
1092         assertReflectionCompareContract(to1, to2, to3, false, excludeFields, isForceAccessible());
1093         assertReflectionCompareContract(tso1, tso1, tso1, false, excludeFields, isForceAccessible());
1094         assertReflectionCompareContract(tso1, tso2, tso3, false, excludeFields, isForceAccessible());
1095         assertReflectionCompareContract("1", "2", "3", false, excludeFields, true);
1096 
1097         assertTrueIfAccessible(0 != CompareToBuilder.reflectionCompare(tso1, new TestSubObject(1, 0), testTransients));
1098         assertTrueIfAccessible(0 != CompareToBuilder.reflectionCompare(tso1, new TestSubObject(0, 1), testTransients));
1099 
1100         // root class
1101         assertXYZCompareOrder(to1, to2, to3, true, null);
1102         // subclass
1103         assertXYZCompareOrder(tso1, tso2, tso3, true, null);
1104     }
1105 
1106     @Test
1107     void testReflectionHierarchyCompareExcludeFields() {
1108         final String[] excludeFields = { "b" };
1109         testReflectionHierarchyCompare(true, excludeFields);
1110 
1111         TestSubObject x;
1112         TestSubObject y;
1113         TestSubObject z;
1114 
1115         x = new TestSubObject(1, 1);
1116         y = new TestSubObject(2, 1);
1117         z = new TestSubObject(3, 1);
1118         assertXYZCompareOrder(x, y, z, true, excludeFields);
1119 
1120         x = new TestSubObject(1, 3);
1121         y = new TestSubObject(2, 2);
1122         z = new TestSubObject(3, 1);
1123         assertXYZCompareOrder(x, y, z, true, excludeFields);
1124     }
1125 
1126     @Test
1127     void testReflectionHierarchyCompareTransients() {
1128         testReflectionHierarchyCompare(true, null);
1129 
1130         TestTransientSubObject x;
1131         TestTransientSubObject y;
1132         TestTransientSubObject z;
1133 
1134         x = new TestTransientSubObject(1, 1);
1135         y = new TestTransientSubObject(2, 2);
1136         z = new TestTransientSubObject(3, 3);
1137         assertXYZCompareOrder(x, y, z, true, null);
1138 
1139         x = new TestTransientSubObject(1, 1);
1140         y = new TestTransientSubObject(1, 2);
1141         z = new TestTransientSubObject(1, 3);
1142         assertXYZCompareOrder(x, y, z, true, null);
1143     }
1144 
1145     @Test
1146     void testShort() {
1147         final short o1 = 1;
1148         final short o2 = 2;
1149         assertEquals(0, new CompareToBuilder().append(o1, o1).toComparison());
1150         assertTrue(new CompareToBuilder().append(o1, o2).toComparison() < 0);
1151         assertTrue(new CompareToBuilder().append(o2, o1).toComparison() > 0);
1152         assertTrue(new CompareToBuilder().append(o1, Short.MAX_VALUE).toComparison() < 0);
1153         assertTrue(new CompareToBuilder().append(Short.MAX_VALUE, o1).toComparison() > 0);
1154         assertTrue(new CompareToBuilder().append(o1, Short.MIN_VALUE).toComparison() > 0);
1155         assertTrue(new CompareToBuilder().append(Short.MIN_VALUE, o1).toComparison() < 0);
1156     }
1157 
1158     @Test
1159     void testShortArray() {
1160         final short[] obj1 = new short[2];
1161         obj1[0] = 5;
1162         obj1[1] = 6;
1163         final short[] obj2 = new short[2];
1164         obj2[0] = 5;
1165         obj2[1] = 6;
1166         final short[] obj3 = new short[3];
1167         obj3[0] = 5;
1168         obj3[1] = 6;
1169         obj3[2] = 7;
1170 
1171         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
1172         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
1173         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
1174         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
1175 
1176         obj1[1] = 7;
1177         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
1178         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
1179 
1180         assertTrue(new CompareToBuilder().append(obj1, null).toComparison() > 0);
1181         assertEquals(0, new CompareToBuilder().append((short[]) null, null).toComparison());
1182         assertTrue(new CompareToBuilder().append(null, obj1).toComparison() < 0);
1183     }
1184 
1185     @Test
1186     void testShortArrayHiddenByObject() {
1187         final short[] array1 = new short[2];
1188         array1[0] = 5;
1189         array1[1] = 6;
1190         final short[] array2 = new short[2];
1191         array2[0] = 5;
1192         array2[1] = 6;
1193         final short[] array3 = new short[3];
1194         array3[0] = 5;
1195         array3[1] = 6;
1196         array3[2] = 7;
1197         final Object obj1 = array1;
1198         final Object obj2 = array2;
1199         final Object obj3 = array3;
1200         assertEquals(0, new CompareToBuilder().append(obj1, obj1).toComparison());
1201         assertEquals(0, new CompareToBuilder().append(obj1, obj2).toComparison());
1202         assertTrue(new CompareToBuilder().append(obj1, obj3).toComparison() < 0);
1203         assertTrue(new CompareToBuilder().append(obj3, obj1).toComparison() > 0);
1204 
1205         array1[1] = 7;
1206         assertTrue(new CompareToBuilder().append(obj1, obj2).toComparison() > 0);
1207         assertTrue(new CompareToBuilder().append(obj2, obj1).toComparison() < 0);
1208     }
1209 
1210  }