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.assertNotNull;
21
22 import java.math.BigDecimal;
23 import java.math.BigInteger;
24
25 import org.apache.commons.lang3.AbstractLangTest;
26 import org.junit.jupiter.api.Test;
27
28
29
30
31 class ReflectionDiffBuilderTest extends AbstractLangTest {
32
33 @SuppressWarnings("unused")
34 private static final class TypeTestChildClass extends TypeTestClass {
35 String field = "a";
36 }
37
38 @SuppressWarnings("unused")
39 private static class TypeTestClass implements Diffable<TypeTestClass> {
40
41 private static int staticField;
42 private final ToStringStyle style = SHORT_STYLE;
43 private final boolean booleanField = true;
44 private final boolean[] booleanArrayField = { true };
45 private final byte byteField = (byte) 0xFF;
46 private final byte[] byteArrayField = { (byte) 0xFF };
47 private char charField = 'a';
48 private char[] charArrayField = { 'a' };
49 private final double doubleField = 1.0;
50 private final double[] doubleArrayField = { 1.0 };
51 private final float floatField = 1.0f;
52 private final float[] floatArrayField = { 1.0f };
53 int intField = 1;
54 private final int[] intArrayField = { 1 };
55 private final long longField = 1L;
56 private final long[] longArrayField = { 1L };
57 private final short shortField = 1;
58 private final short[] shortArrayField = { 1 };
59 private final Object objectField = null;
60 private final Object[] objectArrayField = { null };
61 private transient String transientField;
62 private BigDecimal bigDecimal = BigDecimal.valueOf(20, 1);
63 private BigInteger bigInteger = BigInteger.valueOf(2);
64 @DiffExclude
65 private String annotatedField = "a";
66 private String excludedField = "a";
67
68 @Override
69 public DiffResult<TypeTestClass> diff(final TypeTestClass obj) {
70
71 return ReflectionDiffBuilder.<TypeTestClass>builder()
72 .setDiffBuilder(diffBuilder(obj))
73 .setExcludeFieldNames("excludedField")
74 .build()
75 .build();
76
77 }
78
79 DiffBuilder<TypeTestClass> diffBuilder(final TypeTestClass obj) {
80
81 return DiffBuilder.<TypeTestClass>builder()
82 .setLeft(this)
83 .setRight(obj)
84 .setStyle(style)
85 .build();
86
87 }
88
89 public DiffResult<TypeTestClass> diffDeprecated(final TypeTestClass obj) {
90 return new ReflectionDiffBuilder<>(this, obj, style).setExcludeFieldNames("excludedField").build();
91 }
92
93 @Override
94 public boolean equals(final Object obj) {
95 return EqualsBuilder.reflectionEquals(this, obj, false);
96 }
97
98 @Override
99 public int hashCode() {
100 return HashCodeBuilder.reflectionHashCode(this, false);
101 }
102 }
103
104 private static final ToStringStyle SHORT_STYLE = ToStringStyle.SHORT_PREFIX_STYLE;
105
106 @Test
107 void testArrayDifference() {
108 final TypeTestClass firstObject = new TypeTestClass();
109 firstObject.charArrayField = new char[] { 'c' };
110 final TypeTestClass secondObject = new TypeTestClass();
111
112 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
113 assertEquals(1, list.getNumberOfDiffs());
114
115 list = firstObject.diffDeprecated(secondObject);
116 assertEquals(1, list.getNumberOfDiffs());
117 }
118
119 @Test
120 void testBigDecimalDifference() {
121 final TypeTestClass firstObject = new TypeTestClass();
122
123 firstObject.bigDecimal = BigDecimal.valueOf(200, 2);
124 final TypeTestClass secondObject = new TypeTestClass();
125 final DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
126 assertEquals(1, list.getNumberOfDiffs());
127 }
128
129 @Test
130 void testBigIntegerDifference() {
131 final TypeTestClass firstObject = new TypeTestClass();
132 firstObject.bigInteger = BigInteger.valueOf(100);
133 final TypeTestClass secondObject = new TypeTestClass();
134
135 final DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
136 assertEquals(1, list.getNumberOfDiffs());
137 }
138
139 @Test
140 void testDifferenceInInherited_field() {
141 final TypeTestChildClass firstObject = new TypeTestChildClass();
142 firstObject.intField = 99;
143 final TypeTestChildClass secondObject = new TypeTestChildClass();
144
145 final DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
146 assertEquals(1, list.getNumberOfDiffs());
147 }
148
149 @Test
150 void testGetExcludeFieldNamesWithNullExcludedFieldNames() {
151
152 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder = ReflectionDiffBuilder.<TypeTestClass>builder()
153 .setDiffBuilder(DiffBuilder.<TypeTestClass>builder()
154 .setLeft(new TypeTestClass())
155 .setRight(new TypeTestChildClass())
156 .setStyle(SHORT_STYLE)
157 .build())
158 .build();
159
160 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
161 assertNotNull(excludeFieldNames);
162 assertEquals(0, excludeFieldNames.length);
163 assertNotNull(reflectionDiffBuilder.build());
164 }
165
166 @Test
167 void testGetExcludeFieldNamesWithNullExcludedFieldNamesCtor() {
168
169 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder =
170 new ReflectionDiffBuilder<>(new TypeTestClass(), new TypeTestChildClass(), SHORT_STYLE);
171
172 reflectionDiffBuilder.setExcludeFieldNames(null);
173 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
174 assertNotNull(excludeFieldNames);
175 assertEquals(0, excludeFieldNames.length);
176 assertNotNull(reflectionDiffBuilder.build());
177 }
178
179 @Test
180 void testGetExcludeFieldNamesWithNullValuesInExcludedFieldNames() {
181
182 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder = ReflectionDiffBuilder.<TypeTestClass>builder()
183 .setDiffBuilder(DiffBuilder.<TypeTestClass>builder()
184 .setLeft(new TypeTestClass())
185 .setRight(new TypeTestChildClass())
186 .setStyle(SHORT_STYLE)
187 .build())
188 .setExcludeFieldNames("charField", null)
189 .build();
190
191 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
192 assertNotNull(excludeFieldNames);
193 assertEquals(1, excludeFieldNames.length);
194 assertEquals("charField", excludeFieldNames[0]);
195 assertNotNull(reflectionDiffBuilder.build());
196 }
197
198 @Test
199 void testGetExcludeFieldNamesWithNullValuesInExcludedFieldNamesCtor() {
200
201 final ReflectionDiffBuilder<TypeTestClass> reflectionDiffBuilder =
202 new ReflectionDiffBuilder<>(new TypeTestClass(), new TypeTestChildClass(), SHORT_STYLE);
203
204 reflectionDiffBuilder.setExcludeFieldNames("charField", null);
205 final String[] excludeFieldNames = reflectionDiffBuilder.getExcludeFieldNames();
206 assertNotNull(excludeFieldNames);
207 assertEquals(1, excludeFieldNames.length);
208 assertEquals("charField", excludeFieldNames[0]);
209 assertNotNull(reflectionDiffBuilder.build());
210 }
211
212 @Test
213 void testNoDifferences() {
214 final TypeTestClass firstObject = new TypeTestClass();
215 final TypeTestClass secondObject = new TypeTestClass();
216 assertEquals(0, firstObject.diff(secondObject).getNumberOfDiffs());
217 assertEquals(0, firstObject.diffDeprecated(secondObject).getNumberOfDiffs());
218 }
219
220 @Test
221 void testNoDifferencesDiffExcludeAnnotatedField() {
222 final TypeTestClass firstObject = new TypeTestClass();
223 firstObject.annotatedField = "b";
224 final TypeTestClass secondObject = new TypeTestClass();
225 assertEquals(0, firstObject.diff(secondObject).getNumberOfDiffs());
226 assertEquals(0, firstObject.diffDeprecated(secondObject).getNumberOfDiffs());
227 }
228
229 @Test
230 void testNoDifferencesDiffExcludedFieldAndExcludeAnnotatedField() {
231 final TypeTestClass firstObject = new TypeTestClass();
232 firstObject.excludedField = "b";
233 firstObject.annotatedField = "b";
234 final TypeTestClass secondObject = new TypeTestClass();
235 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
236 assertEquals(0, list.getNumberOfDiffs());
237 list = firstObject.diffDeprecated(secondObject);
238 assertEquals(0, list.getNumberOfDiffs());
239 }
240
241 @Test
242 void testNoDifferencesExcludedField() {
243 final TypeTestClass firstObject = new TypeTestClass();
244 firstObject.excludedField = "b";
245 final TypeTestClass secondObject = new TypeTestClass();
246 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
247 assertEquals(0, list.getNumberOfDiffs());
248 list = firstObject.diffDeprecated(secondObject);
249 assertEquals(0, list.getNumberOfDiffs());
250 }
251
252 @Test
253 void testNoDifferencesInheritance() {
254 final TypeTestChildClass firstObject = new TypeTestChildClass();
255 final TypeTestChildClass secondObject = new TypeTestChildClass();
256 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
257 assertEquals(0, list.getNumberOfDiffs());
258 list = firstObject.diffDeprecated(secondObject);
259 assertEquals(0, list.getNumberOfDiffs());
260 }
261
262 @Test
263 void testPrimitiveDifference() {
264 final TypeTestClass firstObject = new TypeTestClass();
265 firstObject.charField = 'c';
266 final TypeTestClass secondObject = new TypeTestClass();
267 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
268 assertEquals(1, list.getNumberOfDiffs());
269 list = firstObject.diffDeprecated(secondObject);
270 assertEquals(1, list.getNumberOfDiffs());
271 }
272
273 @Test
274 void testRetention() throws Exception {
275
276 for (int i = 0; i < Integer.getInteger("testRecursive", 10_000); i++) {
277 final Class<?> clazz = TestClassBuilder.defineSimpleClass(getClass().getPackage().getName(), i);
278 final Object firstObject = clazz.newInstance();
279 final Object secondObject = clazz.newInstance();
280 final ReflectionDiffBuilder<Object> reflectionDiffBuilder = new ReflectionDiffBuilder<>(firstObject, secondObject, SHORT_STYLE);
281 assertNotNull(reflectionDiffBuilder.build());
282 }
283 }
284
285 @Test
286 void testTransientFieldDifference() {
287 final TypeTestClass firstObject = new TypeTestClass();
288 firstObject.transientField = "a";
289 final TypeTestClass secondObject = new TypeTestClass();
290 secondObject.transientField = "b";
291 DiffResult<TypeTestClass> list = firstObject.diff(secondObject);
292 assertEquals(0, list.getNumberOfDiffs());
293 list = firstObject.diffDeprecated(secondObject);
294 assertEquals(0, list.getNumberOfDiffs());
295 }
296
297 }