Skip to content

Commit af714a5

Browse files
committed
Isolate entity text state tests
1 parent 0f2ddcb commit af714a5

3 files changed

Lines changed: 53 additions & 48 deletions

File tree

common/src/test/java/com/loohp/interactionvisualizer/entityholders/EntityCustomNameRawStateTest.java

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@
1313

1414
import com.loohp.interactionvisualizer.utils.LegacyTextComponentCache;
1515
import net.kyori.adventure.text.Component;
16-
import org.bukkit.Location;
17-
import org.bukkit.World;
1816
import org.junit.jupiter.api.AfterEach;
1917
import org.junit.jupiter.api.BeforeEach;
2018
import org.junit.jupiter.api.Test;
2119
import org.junit.jupiter.api.parallel.ResourceLock;
2220

23-
import java.lang.reflect.Proxy;
24-
import java.util.UUID;
25-
2621
import static org.junit.jupiter.api.Assertions.assertEquals;
2722
import static org.junit.jupiter.api.Assertions.assertFalse;
2823
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -44,8 +39,9 @@ void tearDown() {
4439
}
4540

4641
@Test
47-
void itemSkipsEqualRawTextAndInvalidatesTheSentinelForComponentAndNullSetters() {
48-
Item item = new Item(location());
42+
void itemSkipsEqualRawTextAndInvalidatesTheSentinelForComponentAndNullSetters()
43+
throws ReflectiveOperationException {
44+
Item item = EntityHolderTestFactory.allocate(Item.class);
4945
String raw = "§aReady";
5046

5147
assertTrue(item.updateCustomName(raw));
@@ -67,8 +63,9 @@ void itemSkipsEqualRawTextAndInvalidatesTheSentinelForComponentAndNullSetters()
6763
}
6864

6965
@Test
70-
void displaySkipsEqualRawTextAndInvalidatesTheSentinelForComponentAndNullSetters() {
71-
DisplayEntity display = new DisplayEntity(location());
66+
void displaySkipsEqualRawTextAndInvalidatesTheSentinelForComponentAndNullSetters()
67+
throws ReflectiveOperationException {
68+
DisplayEntity display = EntityHolderTestFactory.allocate(DisplayEntity.class);
7269
String raw = "§bWorking";
7370

7471
assertTrue(display.updateCustomName(raw, true));
@@ -91,8 +88,9 @@ void displaySkipsEqualRawTextAndInvalidatesTheSentinelForComponentAndNullSetters
9188
}
9289

9390
@Test
94-
void displayTreatsEqualPlainTextWithDifferentLegacyColorsAsARealChange() {
95-
DisplayEntity display = new DisplayEntity(location());
91+
void displayTreatsEqualPlainTextWithDifferentLegacyColorsAsARealChange()
92+
throws ReflectiveOperationException {
93+
DisplayEntity display = EntityHolderTestFactory.allocate(DisplayEntity.class);
9694
assertTrue(display.updateCustomName("§a||||", true));
9795
int greenRevision = display.cacheCode();
9896

@@ -101,27 +99,14 @@ void displayTreatsEqualPlainTextWithDifferentLegacyColorsAsARealChange() {
10199
}
102100

103101
@Test
104-
void displayTreatsEqualPlainTextWithDifferentFontsAsARealChange() {
105-
DisplayEntity display = new DisplayEntity(location());
102+
void displayTreatsEqualPlainTextWithDifferentFontsAsARealChange()
103+
throws ReflectiveOperationException {
104+
DisplayEntity display = EntityHolderTestFactory.allocate(DisplayEntity.class);
106105
assertTrue(display.updateCustomName("[font=minecraft:default]same", true));
107106
int defaultFontRevision = display.cacheCode();
108107

109108
assertTrue(display.updateCustomName("[font=minecraft:uniform]same", true));
110109
assertEquals(defaultFontRevision + 1, display.cacheCode());
111110
}
112111

113-
private static Location location() {
114-
UUID id = UUID.randomUUID();
115-
World world = (World) Proxy.newProxyInstance(
116-
World.class.getClassLoader(), new Class<?>[]{World.class}, (proxy, method, arguments) -> {
117-
return switch (method.getName()) {
118-
case "getUID" -> id;
119-
case "toString" -> "World[" + id + "]";
120-
case "hashCode" -> System.identityHashCode(proxy);
121-
case "equals" -> proxy == arguments[0];
122-
default -> throw new UnsupportedOperationException(method.getName());
123-
};
124-
});
125-
return new Location(world, 0.0D, 64.0D, 0.0D);
126-
}
127112
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* This file is part of InteractionVisualizer.
3+
*
4+
* Copyright (C) 2026. Contributors
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*/
11+
12+
package com.loohp.interactionvisualizer.entityholders;
13+
14+
import java.lang.reflect.Field;
15+
import java.lang.reflect.Method;
16+
import java.util.concurrent.atomic.AtomicInteger;
17+
18+
/** Test-only allocation that avoids Paper's server-backed ItemStack factory. */
19+
public final class EntityHolderTestFactory {
20+
21+
private EntityHolderTestFactory() {
22+
}
23+
24+
public static <T extends VisualizerEntity> T allocate(Class<T> type)
25+
throws ReflectiveOperationException {
26+
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
27+
Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
28+
unsafeField.setAccessible(true);
29+
Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);
30+
Object instance = allocateInstance.invoke(unsafeField.get(null), type);
31+
32+
Field revision = VisualizerEntity.class.getDeclaredField("revision");
33+
revision.setAccessible(true);
34+
revision.set(instance, new AtomicInteger(1));
35+
return type.cast(instance);
36+
}
37+
}

common/src/test/java/com/loohp/interactionvisualizer/utils/LegacyTextComponentCacheDisabledTest.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,11 @@
1212
package com.loohp.interactionvisualizer.utils;
1313

1414
import com.loohp.interactionvisualizer.entityholders.Item;
15-
import org.bukkit.Location;
16-
import org.bukkit.World;
15+
import com.loohp.interactionvisualizer.entityholders.EntityHolderTestFactory;
1716
import org.junit.jupiter.api.AfterEach;
1817
import org.junit.jupiter.api.BeforeEach;
1918
import org.junit.jupiter.api.Test;
2019

21-
import java.lang.reflect.Proxy;
22-
import java.util.UUID;
23-
2420
import static org.junit.jupiter.api.Assertions.assertEquals;
2521
import static org.junit.jupiter.api.Assertions.assertFalse;
2622
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -56,8 +52,9 @@ void disablePropertyBypassesTheSharedCache() {
5652
}
5753

5854
@Test
59-
void disablePropertyAlsoBypassesThePerEntityRawFastPath() {
60-
Item item = new Item(location());
55+
void disablePropertyAlsoBypassesThePerEntityRawFastPath()
56+
throws ReflectiveOperationException {
57+
Item item = EntityHolderTestFactory.allocate(Item.class);
6158
LegacyTextComponentCache.startMeasurement();
6259

6360
assertTrue(item.updateCustomName("§buncached"));
@@ -71,18 +68,4 @@ void disablePropertyAlsoBypassesThePerEntityRawFastPath() {
7168
assertEquals(0L, metrics.sameRawFastPaths());
7269
}
7370

74-
private static Location location() {
75-
UUID id = UUID.randomUUID();
76-
World world = (World) Proxy.newProxyInstance(
77-
World.class.getClassLoader(), new Class<?>[]{World.class}, (proxy, method, arguments) -> {
78-
return switch (method.getName()) {
79-
case "getUID" -> id;
80-
case "toString" -> "World[" + id + "]";
81-
case "hashCode" -> System.identityHashCode(proxy);
82-
case "equals" -> proxy == arguments[0];
83-
default -> throw new UnsupportedOperationException(method.getName());
84-
};
85-
});
86-
return new Location(world, 0.0D, 64.0D, 0.0D);
87-
}
8871
}

0 commit comments

Comments
 (0)