1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.builder;
18
19 import static org.hamcrest.MatcherAssert.assertThat;
20 import static org.hamcrest.core.IsEqual.equalTo;
21 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertNotEquals;
24 import static org.junit.jupiter.api.Assertions.assertNotSame;
25 import static org.junit.jupiter.api.Assertions.assertSame;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27
28 import org.apache.commons.lang3.AbstractLangTest;
29 import org.apache.commons.lang3.ArrayUtils;
30 import org.hamcrest.Matcher;
31 import org.junit.jupiter.api.Test;
32
33
34
35
36
37 public class DiffBuilderTest extends AbstractLangTest {
38
39 private static final class TypeTestClass implements Diffable<TypeTestClass> {
40 private ToStringStyle style = SHORT_STYLE;
41 private boolean booleanField = true;
42 private boolean[] booleanArrayField = {true};
43 private byte byteField = (byte) 0xFF;
44 private byte[] byteArrayField = {(byte) 0xFF};
45 private char charField = 'a';
46 private char[] charArrayField = {'a'};
47 private double doubleField = 1.0;
48 private double[] doubleArrayField = {1.0};
49 private float floatField = 1.0f;
50 private float[] floatArrayField = {1.0f};
51 private int intField = 1;
52 private int[] intArrayField = {1};
53 private long longField = 1L;
54 private long[] longArrayField = {1L};
55 private short shortField = 1;
56 private short[] shortArrayField = {1};
57 private Object objectField;
58 private Object[] objectArrayField = {null};
59
60 @Override
61 public DiffResult<TypeTestClass> diff(final TypeTestClass obj) {
62 return new DiffBuilder<>(this, obj, style)
63 .append("boolean", booleanField, obj.booleanField)
64 .append("booleanArray", booleanArrayField, obj.booleanArrayField)
65 .append("byte", byteField, obj.byteField)
66 .append("byteArray", byteArrayField, obj.byteArrayField)
67 .append("char", charField, obj.charField)
68 .append("charArray", charArrayField, obj.charArrayField)
69 .append("double", doubleField, obj.doubleField)
70 .append("doubleArray", doubleArrayField, obj.doubleArrayField)
71 .append("float", floatField, obj.floatField)
72 .append("floatArray", floatArrayField, obj.floatArrayField)
73 .append("int", intField, obj.intField)
74 .append("intArray", intArrayField, obj.intArrayField)
75 .append("long", longField, obj.longField)
76 .append("longArray", longArrayField, obj.longArrayField)
77 .append("short", shortField, obj.shortField)
78 .append("shortArray", shortArrayField, obj.shortArrayField)
79 .append("objectField", objectField, obj.objectField)
80 .append("objectArrayField", objectArrayField, obj.objectArrayField)
81 .build();
82 }
83
84 @Override
85 public boolean equals(final Object obj) {
86 return EqualsBuilder.reflectionEquals(this, obj, false);
87 }
88
89 @Override
90 public int hashCode() {
91 return HashCodeBuilder.reflectionHashCode(this, false);
92 }
93 }
94
95 private static final ToStringStyle SHORT_STYLE = ToStringStyle.SHORT_PREFIX_STYLE;
96
97 @Test
98 public void testBoolean() {
99 final TypeTestClass class1 = new TypeTestClass();
100 final TypeTestClass class2 = new TypeTestClass();
101 class2.booleanField = false;
102 final DiffResult<TypeTestClass> list = class1.diff(class2);
103 assertEquals(1, list.getNumberOfDiffs());
104 final Diff<?> diff = list.getDiffs().get(0);
105 assertEquals(Boolean.class, diff.getType());
106 assertEquals(Boolean.TRUE, diff.getLeft());
107 assertEquals(Boolean.FALSE, diff.getRight());
108 }
109
110 @Test
111 public void testBooleanArray() {
112 final TypeTestClass class1 = new TypeTestClass();
113 final TypeTestClass class2 = new TypeTestClass();
114 class2.booleanArrayField = new boolean[] {false, false};
115 final DiffResult<TypeTestClass> list = class1.diff(class2);
116 assertEquals(1, list.getNumberOfDiffs());
117 final Diff<?> diff = list.getDiffs().get(0);
118 assertArrayEquals(ArrayUtils.toObject(class1.booleanArrayField),
119 (Object[]) diff.getLeft());
120 assertArrayEquals(ArrayUtils.toObject(class2.booleanArrayField),
121 (Object[]) diff.getRight());
122 }
123
124 @Test
125 public void testByte() {
126 final TypeTestClass class1 = new TypeTestClass();
127 final TypeTestClass class2 = new TypeTestClass();
128 class2.byteField = 0x01;
129 final DiffResult<TypeTestClass> list = class1.diff(class2);
130 assertEquals(1, list.getNumberOfDiffs());
131 final Diff<?> diff = list.getDiffs().get(0);
132 assertEquals(Byte.valueOf(class1.byteField), diff.getLeft());
133 assertEquals(Byte.valueOf(class2.byteField), diff.getRight());
134 }
135
136 @Test
137 public void testByteArray() {
138 final TypeTestClass class1 = new TypeTestClass();
139 final TypeTestClass class2 = new TypeTestClass();
140 class2.byteArrayField= new byte[] {0x01, 0x02};
141 final DiffResult<TypeTestClass> list = class1.diff(class2);
142 assertEquals(1, list.getNumberOfDiffs());
143 final Diff<?> diff = list.getDiffs().get(0);
144 assertArrayEquals(ArrayUtils.toObject(class1.byteArrayField),
145 (Object[]) diff.getLeft());
146 assertArrayEquals(ArrayUtils.toObject(class2.byteArrayField),
147 (Object[]) diff.getRight());
148 }
149
150 @Test
151 public void testByteArrayEqualAsObject() {
152 final DiffResult<String> list = new DiffBuilder<>("String1", "String2", SHORT_STYLE)
153 .append("foo", new boolean[] {false}, new boolean[] {false})
154 .append("foo", new byte[] {0x01}, new byte[] {0x01})
155 .append("foo", new char[] {'a'}, new char[] {'a'})
156 .append("foo", new double[] {1.0}, new double[] {1.0})
157 .append("foo", new float[] {1.0F}, new float[] {1.0F})
158 .append("foo", new int[] {1}, new int[] {1})
159 .append("foo", new long[] {1L}, new long[] {1L})
160 .append("foo", new short[] {1}, new short[] {1})
161 .append("foo", new Object[] {1, "two"}, new Object[] {1, "two"})
162 .build();
163
164 assertEquals(0, list.getNumberOfDiffs());
165 }
166
167 @Test
168 public void testChar() {
169 final TypeTestClass class1 = new TypeTestClass();
170 final TypeTestClass class2 = new TypeTestClass();
171 class2.charField = 'z';
172 final DiffResult<TypeTestClass> list = class1.diff(class2);
173 assertEquals(1, list.getNumberOfDiffs());
174 final Diff<?> diff = list.getDiffs().get(0);
175 assertEquals(Character.valueOf(class1.charField), diff.getLeft());
176 assertEquals(Character.valueOf(class2.charField), diff.getRight());
177 }
178
179 @Test
180 public void testCharArray() {
181 final TypeTestClass class1 = new TypeTestClass();
182 final TypeTestClass class2 = new TypeTestClass();
183 class2.charArrayField = new char[] {'f', 'o', 'o'};
184 final DiffResult<TypeTestClass> list = class1.diff(class2);
185 assertEquals(1, list.getNumberOfDiffs());
186 final Diff<?> diff = list.getDiffs().get(0);
187 assertArrayEquals(ArrayUtils.toObject(class1.charArrayField),
188 (Object[]) diff.getLeft());
189 assertArrayEquals(ArrayUtils.toObject(class2.charArrayField),
190 (Object[]) diff.getRight());
191 }
192
193 @Test
194 public void testDiffResult() {
195 final TypeTestClass class1 = new TypeTestClass();
196 final TypeTestClass class2 = new TypeTestClass();
197 class2.intField = 2;
198
199 final DiffResult<TypeTestClass> list = new DiffBuilder<>(class1, class2, SHORT_STYLE)
200 .append("prop1", class1.diff(class2))
201 .build();
202 assertEquals(1, list.getNumberOfDiffs());
203 assertEquals("prop1.int", list.getDiffs().get(0).getFieldName());
204 }
205
206 @Test
207 public void testDouble() {
208 final TypeTestClass class1 = new TypeTestClass();
209 final TypeTestClass class2 = new TypeTestClass();
210 class2.doubleField = 99.99;
211 final DiffResult<TypeTestClass> list = class1.diff(class2);
212 assertEquals(1, list.getNumberOfDiffs());
213 final Diff<?> diff = list.getDiffs().get(0);
214 assertEquals(Double.valueOf(class1.doubleField), diff.getLeft());
215 assertEquals(Double.valueOf(class2.doubleField), diff.getRight());
216 }
217
218 @Test
219 public void testDoubleArray() {
220 final TypeTestClass class1 = new TypeTestClass();
221 final TypeTestClass class2 = new TypeTestClass();
222 class2.doubleArrayField = new double[] {3.0, 2.9, 2.8};
223 final DiffResult<TypeTestClass> list = class1.diff(class2);
224 assertEquals(1, list.getNumberOfDiffs());
225 final Diff<?> diff = list.getDiffs().get(0);
226 assertArrayEquals(ArrayUtils.toObject(class1.doubleArrayField),
227 (Object[]) diff.getLeft());
228 assertArrayEquals(ArrayUtils.toObject(class2.doubleArrayField),
229 (Object[]) diff.getRight());
230 }
231
232 @Test
233 public void testFloat() {
234 final TypeTestClass class1 = new TypeTestClass();
235 final TypeTestClass class2 = new TypeTestClass();
236 class2.floatField = 99.99F;
237 final DiffResult<TypeTestClass> list = class1.diff(class2);
238 assertEquals(1, list.getNumberOfDiffs());
239 final Diff<?> diff = list.getDiffs().get(0);
240 assertEquals(Float.valueOf(class1.floatField), diff.getLeft());
241 assertEquals(Float.valueOf(class2.floatField), diff.getRight());
242 }
243
244 @Test
245 public void testFloatArray() {
246 final TypeTestClass class1 = new TypeTestClass();
247 final TypeTestClass class2 = new TypeTestClass();
248 class2.floatArrayField = new float[] {3.0F, 2.9F, 2.8F};
249 final DiffResult<TypeTestClass> list = class1.diff(class2);
250 assertEquals(1, list.getNumberOfDiffs());
251 final Diff<?> diff = list.getDiffs().get(0);
252 assertArrayEquals(ArrayUtils.toObject(class1.floatArrayField),
253 (Object[]) diff.getLeft());
254 assertArrayEquals(ArrayUtils.toObject(class2.floatArrayField),
255 (Object[]) diff.getRight());
256 }
257
258 @Test
259 public void testInt() {
260 final TypeTestClass class1 = new TypeTestClass();
261 final TypeTestClass class2 = new TypeTestClass();
262 class2.intField = 42;
263 final DiffResult<TypeTestClass> list = class1.diff(class2);
264 assertEquals(1, list.getNumberOfDiffs());
265 final Diff<?> diff = list.getDiffs().get(0);
266 assertEquals(Integer.valueOf(class1.intField), diff.getLeft());
267 assertEquals(Integer.valueOf(class2.intField), diff.getRight());
268 }
269
270 @Test
271 public void testIntArray() {
272 final TypeTestClass class1 = new TypeTestClass();
273 final TypeTestClass class2 = new TypeTestClass();
274 class2.intArrayField = new int[] {3, 2, 1};
275 final DiffResult<TypeTestClass> list = class1.diff(class2);
276 assertEquals(1, list.getNumberOfDiffs());
277 final Diff<?> diff = list.getDiffs().get(0);
278 assertArrayEquals(ArrayUtils.toObject(class1.intArrayField),
279 (Object[]) diff.getLeft());
280 assertArrayEquals(ArrayUtils.toObject(class2.intArrayField),
281 (Object[]) diff.getRight());
282 }
283
284 @Test
285 public void testLong() {
286 final TypeTestClass class1 = new TypeTestClass();
287 final TypeTestClass class2 = new TypeTestClass();
288 class2.longField = 42L;
289 final DiffResult<TypeTestClass> list = class1.diff(class2);
290 assertEquals(1, list.getNumberOfDiffs());
291 final Diff<?> diff = list.getDiffs().get(0);
292 assertEquals(Long.valueOf(class1.longField), diff.getLeft());
293 assertEquals(Long.valueOf(class2.longField), diff.getRight());
294 }
295
296 @Test
297 public void testLongArray() {
298 final TypeTestClass class1 = new TypeTestClass();
299 final TypeTestClass class2 = new TypeTestClass();
300 class2.longArrayField = new long[] {3L, 2L, 1L};
301 final DiffResult<TypeTestClass> list = class1.diff(class2);
302 assertEquals(1, list.getNumberOfDiffs());
303 final Diff<?> diff = list.getDiffs().get(0);
304 assertArrayEquals(ArrayUtils.toObject(class1.longArrayField),
305 (Object[]) diff.getLeft());
306 assertArrayEquals(ArrayUtils.toObject(class2.longArrayField),
307 (Object[]) diff.getRight());
308 }
309
310 @Test
311 public void testNullLhs() {
312 assertThrows(NullPointerException.class, () -> new DiffBuilder<>(null, this, ToStringStyle.DEFAULT_STYLE));
313 }
314
315 @Test
316 public void testNullLhs_4args() {
317 assertThrows(NullPointerException.class, () -> new DiffBuilder<>(null, this, ToStringStyle.DEFAULT_STYLE, true));
318 }
319
320 @Test
321 public void testNullRhs() {
322 assertThrows(NullPointerException.class, () -> new DiffBuilder<>(this, null, ToStringStyle.DEFAULT_STYLE));
323 }
324
325 @Test
326 public void testNullRhs_4args() {
327 assertThrows(NullPointerException.class, () -> new DiffBuilder<>(this, null, ToStringStyle.DEFAULT_STYLE, true));
328 }
329
330 @Test
331 public void testObject() {
332 final TypeTestClass class1 = new TypeTestClass();
333 final TypeTestClass class2 = new TypeTestClass();
334 class2.objectField = "Some string";
335 final DiffResult<TypeTestClass> list = class1.diff(class2);
336 assertEquals(1, list.getNumberOfDiffs());
337 final Diff<?> diff = list.getDiffs().get(0);
338 assertEquals(class1.objectField, diff.getLeft());
339 assertEquals(class2.objectField, diff.getRight());
340 }
341
342 @Test
343 public void testObjectArray() {
344 final TypeTestClass class1 = new TypeTestClass();
345 final TypeTestClass class2 = new TypeTestClass();
346 class2.objectArrayField = new Object[] {"string", 1, 2};
347 final DiffResult<TypeTestClass> list = class1.diff(class2);
348 assertEquals(1, list.getNumberOfDiffs());
349 final Diff<?> diff = list.getDiffs().get(0);
350 assertArrayEquals(class1.objectArrayField, (Object[]) diff.getLeft());
351 assertArrayEquals(class2.objectArrayField, (Object[]) diff.getRight());
352 }
353
354 @Test
355 public void testObjectArrayEqual() {
356 final TypeTestClass class1 = new TypeTestClass();
357 final TypeTestClass class2 = new TypeTestClass();
358 class1.objectArrayField = new Object[] {"string", 1, 2};
359 class2.objectArrayField = new Object[] {"string", 1, 2};
360 final DiffResult<TypeTestClass> list = class1.diff(class2);
361 assertEquals(0, list.getNumberOfDiffs());
362 }
363
364
365
366
367 @Test
368 public void testObjectsNotSameButEqual() {
369 final TypeTestClass left = new TypeTestClass();
370 left.objectField = Integer.valueOf(1000);
371 final TypeTestClass right = new TypeTestClass();
372 right.objectField = Integer.valueOf(1000);
373 assertNotSame(left.objectField, right.objectField);
374 assertEquals(left.objectField, right.objectField);
375
376 final DiffResult<TypeTestClass> list = left.diff(right);
377 assertEquals(0, list.getNumberOfDiffs());
378 }
379
380
381
382
383 @Test
384 public void testObjectsNotSameNorEqual() {
385 final TypeTestClass left = new TypeTestClass();
386 left.objectField = 4;
387 final TypeTestClass right = new TypeTestClass();
388 right.objectField = 100;
389 assertNotSame(left.objectField, right.objectField);
390 assertNotEquals(left.objectField, right.objectField);
391
392 final DiffResult<TypeTestClass> list = left.diff(right);
393 assertEquals(1, list.getNumberOfDiffs());
394 }
395
396
397
398
399 @Test
400 public void testObjectsSameAndEqual() {
401 final Integer sameObject = 1;
402 final TypeTestClass left = new TypeTestClass();
403 left.objectField = sameObject;
404 final TypeTestClass right = new TypeTestClass();
405 right.objectField = sameObject;
406 assertSame(left.objectField, right.objectField);
407 assertEquals(left.objectField, right.objectField);
408
409 final DiffResult<TypeTestClass> list = left.diff(right);
410 assertEquals(0, list.getNumberOfDiffs());
411 }
412
413 @Test
414 public void testSameObjectIgnoresAppends() {
415 final TypeTestClass testClass = new TypeTestClass();
416 final DiffResult<TypeTestClass> list = new DiffBuilder<>(testClass, testClass, SHORT_STYLE)
417 .append("ignored", false, true)
418 .build();
419 assertEquals(0, list.getNumberOfDiffs());
420 }
421
422 @Test
423 public void testShort() {
424 final TypeTestClass class1 = new TypeTestClass();
425 final TypeTestClass class2 = new TypeTestClass();
426 class2.shortField = 42;
427 final DiffResult<TypeTestClass> list = class1.diff(class2);
428 assertEquals(1, list.getNumberOfDiffs());
429 final Diff<?> diff = list.getDiffs().get(0);
430 assertEquals(Short.valueOf(class1.shortField), diff.getLeft());
431 assertEquals(Short.valueOf(class2.shortField), diff.getRight());
432 }
433
434 @Test
435 public void testShortArray() {
436 final TypeTestClass class1 = new TypeTestClass();
437 final TypeTestClass class2 = new TypeTestClass();
438 class2.shortArrayField = new short[] {3, 2, 1};
439 final DiffResult<TypeTestClass> list = class1.diff(class2);
440 assertEquals(1, list.getNumberOfDiffs());
441 final Diff<?> diff = list.getDiffs().get(0);
442 assertArrayEquals(ArrayUtils.toObject(class1.shortArrayField),
443 (Object[]) diff.getLeft());
444 assertArrayEquals(ArrayUtils.toObject(class2.shortArrayField),
445 (Object[]) diff.getRight());
446 }
447
448 @Test
449 public void testSimilarObjectIgnoresAppends() {
450 final TypeTestClass testClass1 = new TypeTestClass();
451 final TypeTestClass testClass2 = new TypeTestClass();
452 final DiffResult<TypeTestClass> list = new DiffBuilder<>(testClass1, testClass2, SHORT_STYLE)
453 .append("ignored", false, true)
454 .build();
455 assertEquals(0, list.getNumberOfDiffs());
456 }
457
458 @Test
459 public void testStylePassedToDiffResult() {
460 final TypeTestClass class1 = new TypeTestClass();
461 DiffResult<TypeTestClass> list = class1.diff(class1);
462 assertEquals(SHORT_STYLE, list.getToStringStyle());
463
464 class1.style = ToStringStyle.MULTI_LINE_STYLE;
465 list = class1.diff(class1);
466 assertEquals(ToStringStyle.MULTI_LINE_STYLE, list.getToStringStyle());
467 }
468
469 @Test
470 public void testTriviallyEqualTestDisabled() {
471 final Matcher<Integer> equalToOne = equalTo(1);
472
473
474 final DiffBuilder<Integer> explicitTestAndNotEqual1 = new DiffBuilder<>(1, 2, null, false);
475 explicitTestAndNotEqual1.append("letter", "X", "Y");
476 assertThat(explicitTestAndNotEqual1.build().getNumberOfDiffs(), equalToOne);
477
478
479 final DiffBuilder<Integer> explicitTestAndNotEqual2 = new DiffBuilder<>(1, 1, null, false);
480
481 explicitTestAndNotEqual2.append("letter", "X", "Y");
482 assertThat(explicitTestAndNotEqual2.build().getNumberOfDiffs(), equalToOne);
483 }
484
485 @Test
486 public void testTriviallyEqualTestEnabled() {
487 final Matcher<Integer> equalToZero = equalTo(0);
488 final Matcher<Integer> equalToOne = equalTo(1);
489
490
491 final DiffBuilder<Integer> implicitTestAndEqual = new DiffBuilder<>(1, 1, null);
492
493 implicitTestAndEqual.append("letter", "X", "Y");
494 assertThat(implicitTestAndEqual.build().getNumberOfDiffs(), equalToZero);
495
496 final DiffBuilder<Integer> implicitTestAndNotEqual = new DiffBuilder<>(1, 2, null);
497
498
499 implicitTestAndNotEqual.append("letter", "X", "Y");
500 assertThat(implicitTestAndNotEqual.build().getNumberOfDiffs(), equalToOne);
501
502
503 final DiffBuilder<Integer> explicitTestAndEqual = new DiffBuilder<>(1, 1, null, true);
504 explicitTestAndEqual.append("letter", "X", "Y");
505 assertThat(explicitTestAndEqual.build().getNumberOfDiffs(), equalToZero);
506 }
507
508 }