-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathTableRegionFingerprintServiceTest.java
More file actions
81 lines (72 loc) · 2.89 KB
/
Copy pathTableRegionFingerprintServiceTest.java
File metadata and controls
81 lines (72 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package top.ellan.mahjong.table.render;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Objects;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TableRegionFingerprintServiceTest {
@Test
void primitiveFieldsPreserveTheDelimitedTextFingerprint() throws ReflectiveOperationException {
Class<?> builderType = Class.forName(TableRegionFingerprintService.class.getName() + "$FingerprintBuilder");
Constructor<?> constructor = builderType.getDeclaredConstructor();
constructor.setAccessible(true);
Object builder = constructor.newInstance();
Method objectField = accessible(builderType.getDeclaredMethod("field", Object.class));
Method booleanField = accessible(builderType.getDeclaredMethod("field", boolean.class));
Method charField = accessible(builderType.getDeclaredMethod("field", char.class));
Method intField = accessible(builderType.getDeclaredMethod("field", int.class));
Method longField = accessible(builderType.getDeclaredMethod("field", long.class));
Method value = accessible(builderType.getDeclaredMethod("value"));
objectField.invoke(builder, "prefix");
booleanField.invoke(builder, true);
booleanField.invoke(builder, false);
charField.invoke(builder, 'Z');
intField.invoke(builder, 0);
intField.invoke(builder, 1);
intField.invoke(builder, -1);
intField.invoke(builder, Integer.MIN_VALUE);
intField.invoke(builder, Integer.MAX_VALUE);
longField.invoke(builder, Long.MIN_VALUE);
longField.invoke(builder, Long.MAX_VALUE);
objectField.invoke(builder, new Object[] {null});
assertEquals(
referenceFingerprint(
"prefix",
true,
false,
'Z',
0,
1,
-1,
Integer.MIN_VALUE,
Integer.MAX_VALUE,
Long.MIN_VALUE,
Long.MAX_VALUE,
null
),
value.invoke(builder)
);
}
private static Method accessible(Method method) {
method.setAccessible(true);
return method;
}
private static long referenceFingerprint(Object... fields) {
long hash = 0xcbf29ce484222325L;
boolean needsSeparator = false;
for (Object field : fields) {
if (needsSeparator) {
hash = mix(hash, ':');
}
String text = Objects.toString(field, "");
for (int index = 0; index < text.length(); index++) {
hash = mix(hash, text.charAt(index));
}
needsSeparator = true;
}
return hash;
}
private static long mix(long hash, char value) {
return (hash ^ value) * 0x100000001b3L;
}
}