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.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertSame;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.math.BigDecimal;
27 import java.math.BigInteger;
28 import java.util.List;
29 import java.util.Objects;
30 import java.util.concurrent.atomic.AtomicInteger;
31
32 import org.apache.commons.lang3.AbstractLangTest;
33 import org.junit.jupiter.api.Test;
34
35
36
37
38 class ReflectionDiffBuilderTest extends AbstractLangTest {
39
40 private static class AtomicIntegerWrapper {
41
42 private AtomicInteger value;
43
44 AtomicIntegerWrapper(final int a) {
45 value = new AtomicInteger(a);
46 }
47 }
48
49 private static final class CycleDiffableNode implements Diffable<CycleDiffableNode> {
50 @SuppressWarnings("unused")
51 private CycleDiffableNode self;
52 @SuppressWarnings("unused")
53 private final String value;
54
55 CycleDiffableNode(final String value) {
56 this.value = value;
57 }
58
59 @Override
60 public DiffResult<CycleDiffableNode> diff(final CycleDiffableNode obj) {
61 return ReflectionDiffBuilder.<CycleDiffableNode>builder()
62 .setDiffBuilder(DiffBuilder.<CycleDiffableNode>builder()
63 .setLeft(this)
64 .setRight(obj)
65 .setStyle(ToStringStyle.SHORT_PREFIX_STYLE)
66 .build())
67 .build()
68 .build();
69 }
70
71 @Override
72 public boolean equals(final Object obj) {
73 return EqualsBuilder.reflectionEquals(this, obj);
74 }
75
76 @Override
77 public int hashCode() {
78 return HashCodeBuilder.reflectionHashCode(this);
79 }
80 }
81
82 private static class FloatWrapper {
83
84 private float value;
85
86 FloatWrapper(final float a) {
87 value = a;
88 }
89 }
90
91 private static class FloatWrapperEquals {
92
93 private float value;
94
95 FloatWrapperEquals(final float a) {
96 value = a;
97 }
98
99 @Override
100 public boolean equals(final Object obj) {
101 if (this == obj) {
102 return true;
103 }
104 if (obj == null || getClass() != obj.getClass()) {
105 return false;
106 }
107 final FloatWrapperEquals other = (FloatWrapperEquals) obj;
108 return Float.floatToIntBits(value) == Float.floatToIntBits(other.value);
109 }
110
111 @Override
112 public int hashCode() {
113 return Objects.hash(value);
114 }
115 }
116
117 private static class FloatWrapperWrapper {
118
119 private FloatWrapper value;
120
121 FloatWrapperWrapper(final float a) {
122 value = new FloatWrapper(a);
123 }
124 }
125
126 private static class FloatWrapperWrapperDeepEquals {
127
128 private FloatWrapperEquals value;
129
130 FloatWrapperWrapperDeepEquals(final float a) {
131 value = new FloatWrapperEquals(a);
132 }
133
134 FloatWrapperWrapperDeepEquals(final FloatWrapperEquals a) {
135 value = a;
136 }
137
138 @Override
139 public boolean equals(final Object obj) {
140 if (this == obj) {
141 return true;
142 }
143 if (obj == null || getClass() != obj.getClass()) {
144 return false;
145 }
146 final FloatWrapperWrapperDeepEquals other = (FloatWrapperWrapperDeepEquals) obj;
147 return Objects.equals(value, other.value);
148 }
149
150 @Override
151 public int hashCode() {
152 return Objects.hash(value);
153 }
154
155 }
156
157 private static class FloatWrapperWrapperEquals {
158
159 private FloatWrapper value;
160
161 FloatWrapperWrapperEquals(final float a) {
162 value = new FloatWrapper(a);
163 }
164
165 FloatWrapperWrapperEquals(final FloatWrapper a) {
166 value = a;
167 }
168
169 @Override
170 public boolean equals(final Object obj) {
171 if (this == obj) {
172 return true;
173 }
174 if (obj == null || getClass() != obj.getClass()) {
175 return false;
176 }
177 final FloatWrapperWrapperEquals other = (FloatWrapperWrapperEquals) obj;
178 return Objects.equals(value, other.value);
179 }
180
181 @Override
182 public int hashCode() {
183 return Objects.hash(value);
184 }
185
186 }
187
188 private static final class MutualDiffableNode implements Diffable<MutualDiffableNode> {
189 @SuppressWarnings("unused")
190 private MutualDiffableNode other;
191 @SuppressWarnings("unused")
192 private final String name;
193
194 MutualDiffableNode(final String name) {
195 this.name = name;
196 }
197
198 @Override
199 public DiffResult<MutualDiffableNode> diff(final MutualDiffableNode obj) {
200 return ReflectionDiffBuilder.<MutualDiffableNode>builder()
201 .setDiffBuilder(DiffBuilder.<MutualDiffableNode>builder()
202 .setLeft(this)
203 .setRight(obj)
204 .setStyle(ToStringStyle.SHORT_PREFIX_STYLE)
205 .build())
206 .build()
207 .build();
208 }
209
210 @Override
211 public boolean equals(final Object obj) {
212 return EqualsBuilder.reflectionEquals(this, obj);
213 }
214
215 @Override
216 public int hashCode() {
217 return HashCodeBuilder.reflectionHashCode(this);
218 }
219 }
220
221 private static final class NodeDiffable implements Diffable<NodeDiffable> {
222 @SuppressWarnings("unused")
223 private NodeDiffable next;
224 @SuppressWarnings("unused")
225 private final String id;
226
227 NodeDiffable(final String id) {
228 this.id = id;
229 }
230
231 @Override
232 public DiffResult<NodeDiffable> diff(final NodeDiffable obj) {
233 return ReflectionDiffBuilder.<NodeDiffable>builder()
234 .setDiffBuilder(DiffBuilder.<NodeDiffable>builder()
235 .setLeft(this)
236 .setRight(obj)
237 .setStyle(ToStringStyle.SHORT_PREFIX_STYLE)
238 .build())
239 .build()
240 .build();
241 }
242
243 @Override
244 public boolean equals(final Object obj) {
245 return EqualsBuilder.reflectionEquals(this, obj);
246 }
247
248 @Override
249 public int hashCode() {
250 return HashCodeBuilder.reflectionHashCode(this);
251 }
252 }
253
254 @SuppressWarnings("unused")
255 private static final class TypeTestChildClass extends TypeTestClass {
256 String field = "a";
257 }
258
259 @SuppressWarnings("unused")
260 private static class TypeTestClass implements Diffable<TypeTestClass> {
261
262 private static int staticField;
263 private final ToStringStyle style = SHORT_STYLE;
264 private final boolean booleanField = true;
265 private final boolean[] booleanArrayField = { true };
266 private final byte byteField = (byte) 0xFF;
267 private final byte[] byteArrayField = { (byte) 0xFF };
268 private char charField = 'a';
269 private char[] charArrayField = { 'a' };
270 private final double doubleField = 1.0;
271 private final double[] doubleArrayField = { 1.0 };
272 private final float floatField = 1.0f;
273 private final float[] floatArrayField = { 1.0f };
274 int intField = 1;
275 private final int[] intArrayField = { 1 };
276 private final long longField = 1L;
277 private final long[] longArrayField = { 1L };
278 private final short shortField = 1;
279 private final short[] shortArrayField = { 1 };
280 private final Object objectField = null;
281 private final Object[] objectArrayField = { null };
282 private transient String transientField;
283 private BigDecimal bigDecimal = BigDecimal.valueOf(20, 1);
284 private BigInteger bigInteger = BigInteger.valueOf(2);
285 @DiffExclude
286 private String annotatedField = "a";
287 private String excludedField = "a";
288
289 @Override
290 public DiffResult<TypeTestClass> diff(final TypeTestClass obj) {
291
292 return ReflectionDiffBuilder.<TypeTestClass>builder()
293 .setDiffBuilder(diffBuilder(obj))
294 .setExcludeFieldNames("excludedField")
295 .build()
296 .build();
297
298 }
299
300 DiffBuilder<TypeTestClass> diffBuilder(final TypeTestClass obj) {
301
302 return DiffBuilder.<TypeTestClass>builder()
303 .setLeft(this)
304 .setRight(obj)
305 .setStyle(style)
306 .build();
307
308 }
309
310 public DiffResult<TypeTestClass> diffDeprecated(final TypeTestClass obj) {
311 return new ReflectionDiffBuilder<>(this, obj, style).setExcludeFieldNames("excludedField").build();
312 }
313
314 @Override
315 public boolean equals(final Object obj) {
316 return EqualsBuilder.reflectionEquals(this, obj, false);
317 }
318
319 @Override
320 public int hashCode() {
321 return HashCodeBuilder.reflectionHashCode(this, false);
322 }
323 }
324
325 private static final ToStringStyle SHORT_STYLE = ToStringStyle.SHORT_PREFIX_STYLE;
326
327 @Test
328 void testArrayDifference() {
329 final TypeTestClass firstObject = new TypeTestClass();
330 firstObject.charArrayField = new char[] { 'c' };
331 final TypeTestClass secondObject = new TypeTestClass();
332
333 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
334 assertEquals(1, list.getNumberOfDiffs());
335
336 list = firstObject.diffDeprecated(secondObject);
337 assertEquals(1, list.getNumberOfDiffs());
338 }
339
340 @Test
341 void testBigDecimalDifference() {
342 final TypeTestClass firstObject = new TypeTestClass();
343
344 firstObject.bigDecimal = BigDecimal.valueOf(200, 2);
345 final TypeTestClass secondObject = new TypeTestClass();
346 final DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
347 assertEquals(1, list.getNumberOfDiffs());
348 }
349
350 @Test
351 void testBigIntegerDifference() {
352 final TypeTestClass firstObject = new TypeTestClass();
353 firstObject.bigInteger = BigInteger.valueOf(100);
354 final TypeTestClass secondObject = new TypeTestClass();
355
356 final DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
357 assertEquals(1, list.getNumberOfDiffs());
358 }
359
360 @Test
361 void testBuilderGetAndSetForceAccessible() {
362 final TypeTestClass first = new TypeTestClass();
363 final TypeTestClass second = new TypeTestClass();
364 final ReflectionDiffBuilder.Builder<TypeTestClass> builder = ReflectionDiffBuilder.<TypeTestClass>builder()
365 .setDiffBuilder(DiffBuilder.<TypeTestClass>builder().setLeft(first).setRight(second).build())
366 .setForceAccessible(true);
367 final ReflectionDiffBuilder<TypeTestClass> diffBuilder = builder.get();
368 assertNotNull(diffBuilder);
369 assertTrue(diffBuilder.isForceAccessible());
370 assertEquals(0, diffBuilder.build().getNumberOfDiffs());
371 }
372
373 @Test
374 void testCycleAsymmetric() {
375 final CycleDiffableNode first = new CycleDiffableNode("a");
376 final CycleDiffableNode second = new CycleDiffableNode("a");
377 first.self = first;
378 second.self = null;
379
380 final DiffResult<CycleDiffableNode> result = first.diff(second);
381 assertEquals(1, result.getNumberOfDiffs());
382 assertEquals("self", result.getDiffs().get(0).getFieldName());
383 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
384 }
385
386 @Test
387 void testCycleMutuallyReferential() {
388 final MutualDiffableNode a = new MutualDiffableNode("node");
389 final MutualDiffableNode b = new MutualDiffableNode("node");
390 a.other = b;
391 b.other = a;
392
393 final MutualDiffableNode c = new MutualDiffableNode("node");
394 final MutualDiffableNode d = new MutualDiffableNode("node");
395 c.other = d;
396 d.other = c;
397
398 final DiffResult<MutualDiffableNode> result = a.diff(c);
399 assertEquals(0, result.getNumberOfDiffs());
400 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
401 }
402
403 @Test
404 void testCycleMutuallyReferentialWithDifference() {
405 final MutualDiffableNode a = new MutualDiffableNode("nodeA");
406 final MutualDiffableNode b = new MutualDiffableNode("nodeB");
407 a.other = b;
408 b.other = a;
409
410 final MutualDiffableNode c = new MutualDiffableNode("nodeA");
411 final MutualDiffableNode d = new MutualDiffableNode("nodeChanged");
412 c.other = d;
413 d.other = c;
414
415 final DiffResult<MutualDiffableNode> result = a.diff(c);
416 assertEquals(1, result.getNumberOfDiffs());
417 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
418 }
419
420 @Test
421 void testCycleSelfReferential() {
422 final CycleDiffableNode first = new CycleDiffableNode("a");
423 final CycleDiffableNode second = new CycleDiffableNode("a");
424 first.self = first;
425 second.self = second;
426
427 final DiffResult<CycleDiffableNode> result = first.diff(second);
428 assertEquals(0, result.getNumberOfDiffs());
429 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
430 }
431
432 @Test
433 void testCycleSelfReferentialWithDifference() {
434 final CycleDiffableNode first = new CycleDiffableNode("a");
435 final CycleDiffableNode second = new CycleDiffableNode("b");
436 first.self = first;
437 second.self = second;
438
439 final DiffResult<CycleDiffableNode> result = first.diff(second);
440 assertEquals(2, result.getNumberOfDiffs());
441 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
442 }
443
444 @Test
445 void testCycleThreeNode() {
446 final NodeDiffable a1 = new NodeDiffable("a");
447 final NodeDiffable b1 = new NodeDiffable("b");
448 final NodeDiffable c1 = new NodeDiffable("c");
449 a1.next = b1;
450 b1.next = c1;
451 c1.next = a1;
452
453 final NodeDiffable a2 = new NodeDiffable("a");
454 final NodeDiffable b2 = new NodeDiffable("b");
455 final NodeDiffable c2 = new NodeDiffable("c");
456 a2.next = b2;
457 b2.next = c2;
458 c2.next = a2;
459
460 final DiffResult<NodeDiffable> result = a1.diff(a2);
461 assertEquals(0, result.getNumberOfDiffs());
462 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
463 }
464
465 @Test
466 void testCycleThreeNodeWithDifference() {
467 final NodeDiffable a1 = new NodeDiffable("a");
468 final NodeDiffable b1 = new NodeDiffable("b");
469 final NodeDiffable c1 = new NodeDiffable("c");
470 a1.next = b1;
471 b1.next = c1;
472 c1.next = a1;
473
474 final NodeDiffable a2 = new NodeDiffable("a");
475 final NodeDiffable b2 = new NodeDiffable("b");
476 final NodeDiffable c2 = new NodeDiffable("changed");
477 a2.next = b2;
478 b2.next = c2;
479 c2.next = a2;
480
481 final DiffResult<NodeDiffable> result = a1.diff(a2);
482 assertEquals(1, result.getNumberOfDiffs());
483 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
484 }
485
486 @Test
487 void testCycleWithNullReference() {
488 final CycleDiffableNode first = new CycleDiffableNode("a");
489 final CycleDiffableNode second = new CycleDiffableNode("a");
490 first.self = null;
491 second.self = null;
492
493 final DiffResult<CycleDiffableNode> result = first.diff(second);
494 assertEquals(0, result.getNumberOfDiffs());
495 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
496 }
497
498 @Test
499 void testDifferenceInInherited_field() {
500 final TypeTestChildClass firstObject = new TypeTestChildClass();
501 firstObject.intField = 99;
502 final TypeTestChildClass secondObject = new TypeTestChildClass();
503
504 final DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
505 assertEquals(1, list.getNumberOfDiffs());
506 }
507
508 @Test
509 void testForceAccessibleFalseWithCycle() {
510 final CycleDiffableNode first = new CycleDiffableNode("a");
511 final CycleDiffableNode second = new CycleDiffableNode("a");
512 first.self = first;
513 second.self = second;
514
515 final ReflectionDiffBuilder.Builder<CycleDiffableNode> builder = ReflectionDiffBuilder.<CycleDiffableNode>builder()
516 .setDiffBuilder(DiffBuilder.<CycleDiffableNode>builder()
517 .setLeft(first)
518 .setRight(second)
519 .setStyle(ToStringStyle.SHORT_PREFIX_STYLE)
520 .build())
521 .setForceAccessible(false);
522 final ReflectionDiffBuilder<CycleDiffableNode> diffBuilder = builder.get();
523 assertNotNull(diffBuilder);
524 assertFalse(diffBuilder.isForceAccessible());
525 final DiffResult<CycleDiffableNode> result = diffBuilder.build();
526 assertEquals(0, result.getNumberOfDiffs());
527 assertTrue(ReflectionDiffBuilder.getRegistry().isEmpty(), "Registry must be empty after diff");
528 }
529
530
531
532
533 @Test
534 void testGetDiffAtomicInteger() {
535 final AtomicInteger a = new AtomicInteger(1);
536 final AtomicInteger b = new AtomicInteger(1);
537 assertEquals(0, new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs().size());
538 assertEquals(0, new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs().size());
539 assertEquals(1,
540 ((List<Diff<?>>) new ReflectionDiffBuilder<>(new AtomicInteger(1), new AtomicInteger(2), ToStringStyle.JSON_STYLE).build().getDiffs()).size());
541 }
542
543
544
545
546 @Test
547 void testGetDiffAtomicIntegerWrapper() {
548 final AtomicIntegerWrapper a = new AtomicIntegerWrapper(1);
549 final AtomicIntegerWrapper b = new AtomicIntegerWrapper(1);
550 final List<Diff<?>> diffList = new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs();
551 assertEquals(1, diffList.size());
552 final Diff<?> diff = diffList.get(0);
553 assertFalse(diffList.isEmpty(), diff.toString());
554 assertSame(a.value, diff.getKey());
555 assertSame(b.value, diff.getValue());
556 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
557 }
558
559
560
561
562 @Test
563 void testGetDiffFloatWrapper() {
564 final FloatWrapper a = new FloatWrapper(1f);
565 final FloatWrapper b = new FloatWrapper(1f);
566 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
567 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
568 assertEquals(1,
569 ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapper(1f), new FloatWrapper(2f), ToStringStyle.JSON_STYLE).build().getDiffs()).size());
570 }
571
572
573
574
575 @Test
576 void testGetDiffFloatWrapperDeepEquals() {
577 final FloatWrapperWrapperDeepEquals a = new FloatWrapperWrapperDeepEquals(1f);
578 final FloatWrapperWrapperDeepEquals b = new FloatWrapperWrapperDeepEquals(1f);
579 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
580 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
581 assertEquals(1, ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperWrapperDeepEquals(1f), new FloatWrapperWrapperDeepEquals(2f),
582 ToStringStyle.JSON_STYLE).build().getDiffs()).size());
583 final FloatWrapperEquals fw1 = new FloatWrapperEquals(1f);
584 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperWrapperDeepEquals(fw1), new FloatWrapperWrapperDeepEquals(fw1),
585 ToStringStyle.JSON_STYLE).build().getDiffs()).size());
586 final FloatWrapperEquals fw2 = new FloatWrapperEquals(2f);
587 assertEquals(1, ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperWrapperDeepEquals(fw1), new FloatWrapperWrapperDeepEquals(fw2),
588 ToStringStyle.JSON_STYLE).build().getDiffs()).size());
589 }
590
591
592
593
594 @Test
595 void testGetDiffFloatWrapperEquals() {
596 final FloatWrapperEquals a = new FloatWrapperEquals(1f);
597 final FloatWrapperEquals b = new FloatWrapperEquals(1f);
598 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
599 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
600 assertEquals(1,
601 ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperEquals(1f), new FloatWrapperEquals(2f), ToStringStyle.JSON_STYLE).build().getDiffs())
602 .size());
603 }
604
605
606
607
608 @Test
609 void testGetDiffFloatWrapperWrapper() {
610 final FloatWrapperWrapper a = new FloatWrapperWrapper(1f);
611 final FloatWrapperWrapper b = new FloatWrapperWrapper(1f);
612 final List<Diff<?>> diffList = new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs();
613 assertEquals(1, diffList.size());
614 final Diff<?> diff = diffList.get(0);
615 assertFalse(diffList.isEmpty(), diff.toString());
616 assertSame(a.value, diff.getKey());
617 assertSame(b.value, diff.getValue());
618 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
619 assertEquals(1,
620 ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperWrapper(1f), new FloatWrapperWrapper(2f), ToStringStyle.JSON_STYLE)
621 .build().getDiffs()).size());
622 }
623
624
625
626
627 @Test
628 void testGetDiffFloatWrapperWrapperEquals() {
629 final FloatWrapperWrapperEquals a = new FloatWrapperWrapperEquals(1f);
630 final FloatWrapperWrapperEquals b = new FloatWrapperWrapperEquals(1f);
631 final List<Diff<?>> diffList = new ReflectionDiffBuilder<>(a, b, ToStringStyle.JSON_STYLE).build().getDiffs();
632 assertEquals(1, diffList.size());
633 final Diff<?> diff = diffList.get(0);
634 assertFalse(diffList.isEmpty(), diff.toString());
635 assertSame(a.value, diff.getKey());
636 assertSame(b.value, diff.getValue());
637 assertEquals(0, ((List<Diff<?>>) new ReflectionDiffBuilder<>(a, a, ToStringStyle.JSON_STYLE).build().getDiffs()).size());
638 assertEquals(1,
639 ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperWrapperEquals(1f), new FloatWrapperWrapperEquals(2f), ToStringStyle.JSON_STYLE)
640 .build().getDiffs()).size());
641 final FloatWrapper fw1 = new FloatWrapper(1f);
642 assertEquals(0,
643 ((List<Diff<?>>) new ReflectionDiffBuilder<>(new FloatWrapperWrapperEquals(fw1), new FloatWrapperWrapperEquals(fw1), ToStringStyle.JSON_STYLE)
644 .build().getDiffs()).size());
645 }
646
647 @Test
648 void testGetExcludeFieldNamesEmpty() {
649 final ReflectionDiffBuilder<?> reflectionDiffBuilder = new ReflectionDiffBuilder<>(new TypeTestClass(), new TypeTestChildClass(), SHORT_STYLE);
650 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
651 assertNotNull(excludeFieldNames);
652 assertEquals(0, excludeFieldNames.length);
653 }
654
655 @Test
656 void testGetExcludeFieldNamesWithNullExcludedFieldNames() {
657
658 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder = ReflectionDiffBuilder.<TypeTestClass>builder()
659 .setDiffBuilder(DiffBuilder.<TypeTestClass>builder()
660 .setLeft(new TypeTestClass())
661 .setRight(new TypeTestChildClass())
662 .setStyle(SHORT_STYLE)
663 .build())
664 .build();
665
666 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
667 assertNotNull(excludeFieldNames);
668 assertEquals(0, excludeFieldNames.length);
669 assertNotNull(reflectionDiffBuilder.build());
670 }
671
672 @Test
673 void testGetExcludeFieldNamesWithNullExcludedFieldNamesCtor() {
674
675 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder =
676 new ReflectionDiffBuilder<>(new TypeTestClass(), new TypeTestChildClass(), SHORT_STYLE);
677
678 reflectionDiffBuilder.setExcludeFieldNames((String[]) null);
679 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
680 assertNotNull(excludeFieldNames);
681 assertEquals(0, excludeFieldNames.length);
682 assertNotNull(reflectionDiffBuilder.build());
683 }
684
685 @Test
686 void testGetExcludeFieldNamesWithNullValuesInExcludedFieldNames() {
687
688 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder = ReflectionDiffBuilder.<TypeTestClass>builder()
689 .setDiffBuilder(DiffBuilder.<TypeTestClass>builder()
690 .setLeft(new TypeTestClass())
691 .setRight(new TypeTestChildClass())
692 .setStyle(SHORT_STYLE)
693 .build())
694 .setExcludeFieldNames("charField", null)
695 .build();
696
697 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
698 assertNotNull(excludeFieldNames);
699 assertEquals(1, excludeFieldNames.length);
700 assertEquals("charField", excludeFieldNames[0]);
701 assertNotNull(reflectionDiffBuilder.build());
702 }
703
704 @Test
705 void testGetExcludeFieldNamesWithNullValuesInExcludedFieldNamesCtor() {
706
707 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder =
708 new ReflectionDiffBuilder<>(new TypeTestClass(), new TypeTestChildClass(), SHORT_STYLE);
709
710 reflectionDiffBuilder.setExcludeFieldNames("charField", null);
711 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
712 assertNotNull(excludeFieldNames);
713 assertEquals(1, excludeFieldNames.length);
714 assertEquals("charField", excludeFieldNames[0]);
715 assertNotNull(reflectionDiffBuilder.build());
716 }
717
718 @Test
719 void testNoDiffBuilderSet() {
720 assertThrows(NullPointerException.class, () -> ReflectionDiffBuilder.<TypeTestClass>builder().build());
721 }
722
723 @Test
724 void testNoDifferences() {
725 final TypeTestClass firstObject = new TypeTestClass();
726 final TypeTestClass secondObject = new TypeTestClass();
727 assertEquals(0, firstObject.diff(secondObject).getNumberOfDiffs());
728 assertEquals(0, firstObject.diffDeprecated(secondObject).getNumberOfDiffs());
729 }
730
731 @Test
732 void testNoDifferencesDiffExcludeAnnotatedField() {
733 final TypeTestClass firstObject = new TypeTestClass();
734 firstObject.annotatedField = "b";
735 final TypeTestClass secondObject = new TypeTestClass();
736 assertEquals(0, firstObject.diff(secondObject).getNumberOfDiffs());
737 assertEquals(0, firstObject.diffDeprecated(secondObject).getNumberOfDiffs());
738 }
739
740 @Test
741 void testNoDifferencesDiffExcludedFieldAndExcludeAnnotatedField() {
742 final TypeTestClass firstObject = new TypeTestClass();
743 firstObject.excludedField = "b";
744 firstObject.annotatedField = "b";
745 final TypeTestClass secondObject = new TypeTestClass();
746 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
747 assertEquals(0, list.getNumberOfDiffs());
748 list = firstObject.diffDeprecated(secondObject);
749 assertEquals(0, list.getNumberOfDiffs());
750 }
751
752 @Test
753 void testNoDifferencesExcludedField() {
754 final TypeTestClass firstObject = new TypeTestClass();
755 firstObject.excludedField = "b";
756 final TypeTestClass secondObject = new TypeTestClass();
757 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
758 assertEquals(0, list.getNumberOfDiffs());
759 list = firstObject.diffDeprecated(secondObject);
760 assertEquals(0, list.getNumberOfDiffs());
761 }
762
763 @Test
764 void testNoDifferencesInheritance() {
765 final TypeTestChildClass firstObject = new TypeTestChildClass();
766 final TypeTestChildClass secondObject = new TypeTestChildClass();
767 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
768 assertEquals(0, list.getNumberOfDiffs());
769 list = firstObject.diffDeprecated(secondObject);
770 assertEquals(0, list.getNumberOfDiffs());
771 }
772
773 @Test
774 void testPrimitiveDifference() {
775 final TypeTestClass firstObject = new TypeTestClass();
776 firstObject.charField = 'c';
777 final TypeTestClass secondObject = new TypeTestClass();
778 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
779 assertEquals(1, list.getNumberOfDiffs());
780 list = firstObject.diffDeprecated(secondObject);
781 assertEquals(1, list.getNumberOfDiffs());
782 }
783
784 @Test
785 void testRetention() throws Exception {
786
787 for (int i = 0; i < Integer.getInteger("testRecursive", 10_000); i++) {
788 final Class<?> clazz = TestClassBuilder.defineSimpleClass(getClass().getPackage().getName(), i);
789 final Object firstObject = clazz.newInstance();
790 final Object secondObject = clazz.newInstance();
791 final ReflectionDiffBuilder<Object> reflectionDiffBuilder = new ReflectionDiffBuilder<>(firstObject, secondObject, SHORT_STYLE);
792 assertNotNull(reflectionDiffBuilder.build());
793 }
794 }
795
796 @Test
797 void testTransientFieldDifference() {
798 final TypeTestClass firstObject = new TypeTestClass();
799 firstObject.transientField = "a";
800 final TypeTestClass secondObject = new TypeTestClass();
801 secondObject.transientField = "b";
802 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
803 assertEquals(0, list.getNumberOfDiffs());
804 list = firstObject.diffDeprecated(secondObject);
805 assertEquals(0, list.getNumberOfDiffs());
806 }
807
808 }