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