1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.lang3.builder;
19
20 import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
21 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
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.assertTrue;
25
26 import org.apache.commons.lang3.AbstractLangTest;
27 import org.junit.jupiter.api.Test;
28
29
30
31
32 class HashCodeBuilderTest extends AbstractLangTest {
33
34
35
36
37 static class ReflectionTestCycleA {
38 ReflectionTestCycleB b;
39
40 @Override
41 public boolean equals(final Object o) {
42
43 return super.equals(o);
44 }
45
46 @Override
47 public int hashCode() {
48 return HashCodeBuilder.reflectionHashCode(this);
49 }
50 }
51
52
53
54 static class ReflectionTestCycleB {
55 ReflectionTestCycleA a;
56
57 @Override
58 public boolean equals(final Object o) {
59
60 return super.equals(o);
61 }
62
63 @Override
64 public int hashCode() {
65 return HashCodeBuilder.reflectionHashCode(this);
66 }
67 }
68
69 static class TestObject {
70 private int a;
71
72 TestObject(final int a) {
73 this.a = a;
74 }
75
76 @Override
77 public boolean equals(final Object o) {
78 if (o == this) {
79 return true;
80 }
81 if (!(o instanceof TestObject)) {
82 return false;
83 }
84 final TestObject rhs = (TestObject) o;
85 return a == rhs.a;
86 }
87
88 public int getA() {
89 return a;
90 }
91
92 @Override
93 public int hashCode() {
94 return a;
95 }
96
97 public void setA(final int a) {
98 this.a = a;
99 }
100 }
101
102 static class TestObjectHashCodeExclude {
103 @HashCodeExclude
104 private final int a;
105 private final int b;
106
107 TestObjectHashCodeExclude(final int a, final int b) {
108 this.a = a;
109 this.b = b;
110 }
111
112 public int getA() {
113 return a;
114 }
115
116 public int getB() {
117 return b;
118 }
119 }
120
121 static class TestObjectHashCodeExclude2 {
122 @HashCodeExclude
123 private final int a;
124 @HashCodeExclude
125 private final int b;
126
127 TestObjectHashCodeExclude2(final int a, final int b) {
128 this.a = a;
129 this.b = b;
130 }
131
132 public int getA() {
133 return a;
134 }
135
136 public int getB() {
137 return b;
138 }
139 }
140
141 static class TestObjectWithMultipleFields {
142 @SuppressWarnings("unused")
143 private final int one;
144
145 @SuppressWarnings("unused")
146 private final int two;
147
148 @SuppressWarnings("unused")
149 private final int three;
150
151 TestObjectWithMultipleFields(final int one, final int two, final int three) {
152 this.one = one;
153 this.two = two;
154 this.three = three;
155 }
156 }
157
158 static class TestSubObject extends TestObject {
159 private int b;
160
161 @SuppressWarnings("unused")
162 private transient int t;
163
164 TestSubObject() {
165 super(0);
166 }
167
168 TestSubObject(final int a, final int b, final int t) {
169 super(a);
170 this.b = b;
171 this.t = t;
172 }
173
174 @Override
175 public boolean equals(final Object o) {
176 if (o == this) {
177 return true;
178 }
179 if (!(o instanceof TestSubObject)) {
180 return false;
181 }
182 final TestSubObject rhs = (TestSubObject) o;
183 return super.equals(o) && b == rhs.b;
184 }
185
186 @Override
187 public int hashCode() {
188 return b * INITIAL + super.hashCode();
189 }
190
191 }
192
193 private static final int INITIAL = 17;
194
195 private static final int CONSTANT = 37;
196
197 @Test
198 void testBoolean() {
199 assertEquals(INITIAL * CONSTANT + 0, new HashCodeBuilder(INITIAL, CONSTANT).append(true).toHashCode());
200 assertEquals(INITIAL * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append(false).toHashCode());
201 }
202
203 @Test
204 void testBooleanArray() {
205 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((boolean[]) null).toHashCode());
206 final boolean[] obj = new boolean[2];
207 assertEquals((INITIAL * CONSTANT + 1) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
208 obj[0] = true;
209 assertEquals((INITIAL * CONSTANT + 0) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
210 obj[1] = false;
211 assertEquals((INITIAL * CONSTANT + 0) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
212 }
213
214 @Test
215 void testBooleanArrayAsObject() {
216 final boolean[] obj = new boolean[2];
217 assertEquals((INITIAL * CONSTANT + 1) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
218 obj[0] = true;
219 assertEquals((INITIAL * CONSTANT + 0) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
220 obj[1] = false;
221 assertEquals((INITIAL * CONSTANT + 0) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
222 }
223
224 @Test
225 void testBooleanMultiArray() {
226 final boolean[][] obj = new boolean[2][];
227 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
228 obj[0] = new boolean[0];
229 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
230 obj[0] = new boolean[1];
231 assertEquals((INITIAL * CONSTANT + 1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
232 obj[0] = new boolean[2];
233 assertEquals(((INITIAL * CONSTANT + 1) * CONSTANT + 1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
234 obj[0][0] = true;
235 assertEquals(((INITIAL * CONSTANT + 0) * CONSTANT + 1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
236 obj[1] = new boolean[1];
237 assertEquals(((INITIAL * CONSTANT + 0) * CONSTANT + 1) * CONSTANT + 1, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
238 }
239
240 @Test
241 void testByte() {
242 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((byte) 0).toHashCode());
243 assertEquals(INITIAL * CONSTANT + 123, new HashCodeBuilder(INITIAL, CONSTANT).append((byte) 123).toHashCode());
244 }
245
246 @Test
247 void testByteArray() {
248 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((byte[]) null).toHashCode());
249 final byte[] obj = new byte[2];
250 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
251 obj[0] = (byte) 5;
252 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
253 obj[1] = (byte) 6;
254 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
255 }
256
257 @Test
258 void testByteArrayAsObject() {
259 final byte[] obj = new byte[2];
260 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
261 obj[0] = (byte) 5;
262 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
263 obj[1] = (byte) 6;
264 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
265 }
266
267 @Test
268 void testChar() {
269 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((char) 0).toHashCode());
270 assertEquals(INITIAL * CONSTANT + 1234, new HashCodeBuilder(INITIAL, CONSTANT).append((char) 1234).toHashCode());
271 }
272
273 @Test
274 void testCharArray() {
275 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((char[]) null).toHashCode());
276 final char[] obj = new char[2];
277 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
278 obj[0] = (char) 5;
279 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
280 obj[1] = (char) 6;
281 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
282 }
283
284 @Test
285 void testCharArrayAsObject() {
286 final char[] obj = new char[2];
287 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
288 obj[0] = (char) 5;
289 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
290 obj[1] = (char) 6;
291 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
292 }
293
294 @Test
295 void testConstructorExEvenFirst() {
296 assertIllegalArgumentException(() -> new HashCodeBuilder(2, 3));
297 }
298
299 @Test
300 void testConstructorExEvenNegative() {
301 assertIllegalArgumentException(() -> new HashCodeBuilder(-2, -2));
302 }
303
304 @Test
305 void testConstructorExEvenSecond() {
306 assertIllegalArgumentException(() -> new HashCodeBuilder(3, 2));
307 }
308
309 @Test
310 void testConstructorExZero() {
311 assertIllegalArgumentException(() -> new HashCodeBuilder(0, 0));
312 }
313
314 @Test
315 void testDouble() {
316 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(0d).toHashCode());
317 final double d = 1234567.89;
318 final long l = Double.doubleToLongBits(d);
319 assertEquals(INITIAL * CONSTANT + (int) (l ^ l >> 32), new HashCodeBuilder(INITIAL, CONSTANT).append(d).toHashCode());
320 }
321
322 @Test
323 void testDoubleArray() {
324 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((double[]) null).toHashCode());
325 final double[] obj = new double[2];
326 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
327 obj[0] = 5.4d;
328 final long l1 = Double.doubleToLongBits(5.4d);
329 final int h1 = (int) (l1 ^ l1 >> 32);
330 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
331 obj[1] = 6.3d;
332 final long l2 = Double.doubleToLongBits(6.3d);
333 final int h2 = (int) (l2 ^ l2 >> 32);
334 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT + h2, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
335 }
336
337 @Test
338 void testDoubleArrayAsObject() {
339 final double[] obj = new double[2];
340 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
341 obj[0] = 5.4d;
342 final long l1 = Double.doubleToLongBits(5.4d);
343 final int h1 = (int) (l1 ^ l1 >> 32);
344 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
345 obj[1] = 6.3d;
346 final long l2 = Double.doubleToLongBits(6.3d);
347 final int h2 = (int) (l2 ^ l2 >> 32);
348 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT + h2, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
349 }
350
351 @Test
352 void testEquals() {
353 final HashCodeBuilder hcb1 = new HashCodeBuilder(INITIAL, CONSTANT).append(1).append('a');
354 final HashCodeBuilder hcb2 = new HashCodeBuilder(INITIAL, CONSTANT).append(1).append('a');
355 final HashCodeBuilder hcb3 = new HashCodeBuilder(INITIAL, CONSTANT).append(2).append('c');
356 assertEquals(hcb1, hcb1);
357 assertEquals(hcb1, hcb2);
358 assertEquals(hcb2, hcb1);
359 assertNotEquals(hcb1, hcb3);
360 assertNotEquals(hcb2, hcb3);
361 }
362
363 @Test
364 void testFloat() {
365 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(0f).toHashCode());
366 final float f = 1234.89f;
367 final int i = Float.floatToIntBits(f);
368 assertEquals(INITIAL * CONSTANT + i, new HashCodeBuilder(INITIAL, CONSTANT).append(f).toHashCode());
369 }
370
371 @Test
372 void testFloatArray() {
373 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((float[]) null).toHashCode());
374 final float[] obj = new float[2];
375 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
376 obj[0] = 5.4f;
377 final int h1 = Float.floatToIntBits(5.4f);
378 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
379 obj[1] = 6.3f;
380 final int h2 = Float.floatToIntBits(6.3f);
381 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT + h2, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
382 }
383
384 @Test
385 void testFloatArrayAsObject() {
386 final float[] obj = new float[2];
387 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
388 obj[0] = 5.4f;
389 final int h1 = Float.floatToIntBits(5.4f);
390 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
391 obj[1] = 6.3f;
392 final int h2 = Float.floatToIntBits(6.3f);
393 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT + h2, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
394 }
395
396 @Test
397 void testInt() {
398 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(0).toHashCode());
399 assertEquals(INITIAL * CONSTANT + 123456, new HashCodeBuilder(INITIAL, CONSTANT).append(123456).toHashCode());
400 }
401
402 @Test
403 void testIntArray() {
404 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((int[]) null).toHashCode());
405 final int[] obj = new int[2];
406 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
407 obj[0] = 5;
408 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
409 obj[1] = 6;
410 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
411 }
412
413 @Test
414 void testIntArrayAsObject() {
415 final int[] obj = new int[2];
416 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
417 obj[0] = 5;
418 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
419 obj[1] = 6;
420 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
421 }
422
423 @Test
424 void testLong() {
425 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(0L).toHashCode());
426 assertEquals(INITIAL * CONSTANT + (int) (123456789L ^ 123456789L >> 32), new HashCodeBuilder(INITIAL, CONSTANT).append(
427 123456789L).toHashCode());
428 }
429
430 @Test
431 void testLongArray() {
432 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((long[]) null).toHashCode());
433 final long[] obj = new long[2];
434 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
435 obj[0] = 5L;
436 final int h1 = (int) (5L ^ 5L >> 32);
437 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
438 obj[1] = 6L;
439 final int h2 = (int) (6L ^ 6L >> 32);
440 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT + h2, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
441 }
442
443 @Test
444 void testLongArrayAsObject() {
445 final long[] obj = new long[2];
446 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
447 obj[0] = 5L;
448 final int h1 = (int) (5L ^ 5L >> 32);
449 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
450 obj[1] = 6L;
451 final int h2 = (int) (6L ^ 6L >> 32);
452 assertEquals((INITIAL * CONSTANT + h1) * CONSTANT + h2, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
453 }
454
455 @Test
456 void testObject() {
457 Object obj = null;
458 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
459 obj = new Object();
460 assertEquals(INITIAL * CONSTANT + obj.hashCode(), new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
461 }
462
463 @Test
464 void testObjectArray() {
465 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object[]) null).toHashCode());
466 final Object[] obj = new Object[2];
467 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
468 obj[0] = new Object();
469 assertEquals((INITIAL * CONSTANT + obj[0].hashCode()) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
470 obj[1] = new Object();
471 assertEquals((INITIAL * CONSTANT + obj[0].hashCode()) * CONSTANT + obj[1].hashCode(), new HashCodeBuilder(INITIAL, CONSTANT).append(obj)
472 .toHashCode());
473 }
474
475 @Test
476 void testObjectArrayAsObject() {
477 final Object[] obj = new Object[2];
478 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
479 obj[0] = new Object();
480 assertEquals((INITIAL * CONSTANT + obj[0].hashCode()) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
481 obj[1] = new Object();
482 assertEquals((INITIAL * CONSTANT + obj[0].hashCode()) * CONSTANT + obj[1].hashCode(), new HashCodeBuilder(INITIAL, CONSTANT).append(
483 (Object) obj).toHashCode());
484 }
485
486 @Test
487 void testObjectBuild() {
488 Object obj = null;
489 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).build().intValue());
490 obj = new Object();
491 assertEquals(INITIAL * CONSTANT + obj.hashCode(), new HashCodeBuilder(INITIAL, CONSTANT).append(obj).build().intValue());
492 }
493
494 @Test
495 void testReflectionHashCode() {
496 assertEquals(INITIAL * CONSTANT, HashCodeBuilder.reflectionHashCode(new TestObject(0)));
497 assertEquals(INITIAL * CONSTANT + 123456, HashCodeBuilder.reflectionHashCode(new TestObject(123456)));
498 }
499
500 @Test
501 void testReflectionHashCodeEx1() {
502 assertIllegalArgumentException(() -> HashCodeBuilder.reflectionHashCode(0, 0, new TestObject(0), true));
503 }
504
505 @Test
506 void testReflectionHashCodeEx2() {
507 assertIllegalArgumentException(() -> HashCodeBuilder.reflectionHashCode(2, 2, new TestObject(0), true));
508 }
509
510 @Test
511 void testReflectionHashCodeEx3() {
512 assertNullPointerException(() -> HashCodeBuilder.reflectionHashCode(13, 19, null, true));
513 }
514
515 @Test
516 void testReflectionHashCodeExcludeFields() {
517 final TestObjectWithMultipleFields x = new TestObjectWithMultipleFields(1, 2, 3);
518
519 assertEquals(((INITIAL * CONSTANT + 1) * CONSTANT + 3) * CONSTANT + 2, HashCodeBuilder.reflectionHashCode(x));
520
521 assertEquals(((INITIAL * CONSTANT + 1) * CONSTANT + 3) * CONSTANT + 2, HashCodeBuilder.reflectionHashCode(x, (String[]) null));
522 assertEquals(((INITIAL * CONSTANT + 1) * CONSTANT + 3) * CONSTANT + 2, HashCodeBuilder.reflectionHashCode(x));
523 assertEquals(((INITIAL * CONSTANT + 1) * CONSTANT + 3) * CONSTANT + 2, HashCodeBuilder.reflectionHashCode(x, "xxx"));
524
525 assertEquals((INITIAL * CONSTANT + 1) * CONSTANT + 3, HashCodeBuilder.reflectionHashCode(x, "two"));
526 assertEquals((INITIAL * CONSTANT + 1) * CONSTANT + 2, HashCodeBuilder.reflectionHashCode(x, "three"));
527
528 assertEquals(INITIAL * CONSTANT + 1, HashCodeBuilder.reflectionHashCode(x, "two", "three"));
529
530 assertEquals(INITIAL, HashCodeBuilder.reflectionHashCode(x, "one", "two", "three"));
531 assertEquals(INITIAL, HashCodeBuilder.reflectionHashCode(x, "one", "two", "three", "xxx"));
532 }
533
534 @Test
535 void testReflectionHierarchyHashCode() {
536 assertEquals(INITIAL * CONSTANT * CONSTANT, HashCodeBuilder.reflectionHashCode(new TestSubObject(0, 0, 0)));
537 assertEquals(INITIAL * CONSTANT * CONSTANT * CONSTANT, HashCodeBuilder.reflectionHashCode(new TestSubObject(0, 0, 0), true));
538 assertEquals((INITIAL * CONSTANT + 7890) * CONSTANT + 123456, HashCodeBuilder.reflectionHashCode(new TestSubObject(123456, 7890,
539 0)));
540 assertEquals(((INITIAL * CONSTANT + 7890) * CONSTANT + 0) * CONSTANT + 123456, HashCodeBuilder.reflectionHashCode(new TestSubObject(
541 123456, 7890, 0), true));
542 }
543
544 @Test
545 void testReflectionHierarchyHashCodeEx1() {
546 assertIllegalArgumentException(() -> HashCodeBuilder.reflectionHashCode(0, 0, new TestSubObject(0, 0, 0), true));
547 }
548
549 @Test
550 void testReflectionHierarchyHashCodeEx2() {
551 assertIllegalArgumentException(() -> HashCodeBuilder.reflectionHashCode(2, 2, new TestSubObject(0, 0, 0), true));
552 }
553
554
555
556
557 @Test
558 void testReflectionObjectCycle() {
559 final ReflectionTestCycleA a = new ReflectionTestCycleA();
560 final ReflectionTestCycleB b = new ReflectionTestCycleB();
561 a.b = b;
562 b.a = a;
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581 a.hashCode();
582 assertTrue(HashCodeBuilder.getRegistry().isEmpty());
583 b.hashCode();
584 assertTrue(HashCodeBuilder.getRegistry().isEmpty());
585 }
586
587 @Test
588 void testShort() {
589 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((short) 0).toHashCode());
590 assertEquals(INITIAL * CONSTANT + 12345, new HashCodeBuilder(INITIAL, CONSTANT).append((short) 12345).toHashCode());
591 }
592
593 @Test
594 void testShortArray() {
595 assertEquals(INITIAL * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((short[]) null).toHashCode());
596 final short[] obj = new short[2];
597 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
598 obj[0] = (short) 5;
599 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
600 obj[1] = (short) 6;
601 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append(obj).toHashCode());
602 }
603
604 @Test
605 void testShortArrayAsObject() {
606 final short[] obj = new short[2];
607 assertEquals(INITIAL * CONSTANT * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
608 obj[0] = (short) 5;
609 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
610 obj[1] = (short) 6;
611 assertEquals((INITIAL * CONSTANT + 5) * CONSTANT + 6, new HashCodeBuilder(INITIAL, CONSTANT).append((Object) obj).toHashCode());
612 }
613
614 @Test
615 void testSuper() {
616 final Object obj = new Object();
617 assertEquals(INITIAL * CONSTANT + 19 * 41 + obj.hashCode(), new HashCodeBuilder(INITIAL, CONSTANT).appendSuper(
618 new HashCodeBuilder(19, 41).append(obj).toHashCode()).toHashCode());
619 }
620
621
622
623
624 @Test
625 void testToHashCodeEqualsHashCode() {
626 final HashCodeBuilder hcb = new HashCodeBuilder(INITIAL, CONSTANT).append(new Object()).append('a');
627 assertEquals(hcb.toHashCode(), hcb.hashCode(),
628 "hashCode() is no longer returning the same value as toHashCode() - see LANG-520");
629 }
630
631 @Test
632 void testToHashCodeExclude() {
633 final TestObjectHashCodeExclude one = new TestObjectHashCodeExclude(1, 2);
634 final TestObjectHashCodeExclude2 two = new TestObjectHashCodeExclude2(1, 2);
635 assertEquals(INITIAL * CONSTANT + 2, HashCodeBuilder.reflectionHashCode(one));
636 assertEquals(INITIAL, HashCodeBuilder.reflectionHashCode(two));
637 }
638
639 }