This commit is contained in:
Brian Neumann-Fopiano committed 2026-08-24 02:27:26 -04:00
1 parent fe5651f854
commit e20bb86f40
228 files changed
+5716 -3577

No files matched your search

@@ -5,44 +5,31 @@ import org.junit.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CommandIrisFoliaCreateContractTest {
@Test
public void ordinaryFoliaCreateRestartsOnlyAfterSuccessfulStagingAndFeedback() throws Exception {
public void ordinaryFoliaCreateUsesTheSharedRuntimeCreationPath() throws Exception {
String source = Files.readString(Path.of(System.getProperty("iris.commandIrisSource")));
String foliaCreate = source.substring(
source.indexOf("if (J.isFolia()) {"),
source.indexOf(" try {", source.indexOf("if (J.isFolia()) {"))
String create = source.substring(
source.indexOf(" public void create("),
source.indexOf(" @Director(", source.indexOf(" public void create("))
);
int stage = foliaCreate.indexOf("stageFoliaWorldCreation(worldName, dimension, seed)");
int failureExit = foliaCreate.indexOf("if (!staged)");
int feedback = foliaCreate.indexOf("COMMAND_IRIS_WORLD_STAGING_COMPLETED_RESTARTING_SERVER_GENERATE_LOAD");
int restart = foliaCreate.indexOf("ServerConfigurator.restart(\"Iris staged Folia world");
assertTrue(stage >= 0);
assertTrue(stage < failureExit);
assertTrue(failureExit < feedback);
assertTrue(feedback < restart);
assertTrue(create.contains("IrisToolbelt.createWorld()"));
assertTrue(create.contains(".studio(false)"));
assertTrue(create.contains(".create();"));
assertFalse(create.contains("J.isFolia()"));
assertFalse(create.contains("ServerConfigurator.restart("));
}
@Test
public void foliaStagePublishesCurrentPaperDataBeforeRegisteringStartupAlias() throws Exception {
public void obsoleteFoliaStagingSurfaceIsRemoved() throws Exception {
String source = Files.readString(Path.of(System.getProperty("iris.commandIrisSource")));
int methodStart = source.indexOf("private boolean stageFoliaWorldCreation(");
int methodEnd = source.indexOf("private boolean registerWorldInBukkitYml(", methodStart);
String staging = source.substring(methodStart, methodEnd);
int currentPaperData = staging.indexOf("INMS.get().writeCurrentPaperWorldData(");
int pack = staging.indexOf("installIntoWorld(");
int publication = staging.indexOf("AtomicDirectoryPublisher.publishAbsent(");
int registration = staging.indexOf("registerWorldInBukkitYml(worldKey");
assertTrue(currentPaperData >= 0);
assertTrue(currentPaperData < pack);
assertTrue(pack < publication);
assertTrue(publication < registration);
assertTrue(source.contains("IrisWorldStorage.configuredWorldName("));
assertFalse(source.contains("stageFoliaWorldCreation"));
assertFalse(source.contains("writeCurrentPaperWorldData"));
assertFalse(source.contains("COMMAND_IRIS_RUNTIME_WORLD_CREATION_IS_DISABLED_ON_FOLIA"));
}
}
@@ -0,0 +1,255 @@
package art.arcane.iris.core.gui;
import art.arcane.iris.core.runtime.WorldRuntimeControlService;
import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.engine.object.IrisWorld;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.platform.bukkit.BukkitWorldBinding;
import art.arcane.iris.util.common.scheduling.J;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.mockito.MockedStatic;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
public class BukkitVisionOverlayFoliaContractTest {
@Test
public void teleportLoadsTheDestinationChunkBeforeItsOwningRegionReadsTheSurface() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/gui/BukkitVisionOverlay.java"
)).replace("\r\n", "\n");
String request = method(source, "private void requestTeleportChunk(");
assertBefore(request, "requestChunkAsync(", "requested.whenComplete(");
assertBefore(request, "requested.whenComplete(", "J.runRegion(");
assertBefore(request, "J.runRegion(", "world.getHighestBlockYAt(");
assertBefore(request, "world.getHighestBlockYAt(", "J.runEntity(");
assertTrue(request.contains("chunkX,\n chunkZ,\n true,\n true"));
assertEquals(1, occurrences(request, "world.getHighestBlockYAt("));
}
@Test
public void teleportReportsAsyncAndSchedulingFailuresWithDestinationContext() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/gui/BukkitVisionOverlay.java"
)).replace("\r\n", "\n");
String request = method(source, "private void requestTeleportChunk(");
String reporter = method(source, "private void reportTeleportFailure(");
assertTrue(request.contains("if (requested == null)"));
assertTrue(request.contains("if (failure != null)"));
assertTrue(request.contains("if (chunk == null ||"));
assertTrue(request.contains("if (!J.runEntity("));
assertTrue(request.contains("if (!scheduled)"));
assertTrue(reporter.contains("IrisLogging.reportError("));
assertTrue(reporter.contains("world.getName()"));
assertTrue(reporter.contains("blockX + \",\" + blockZ"));
}
@Test
public void teleportObservesNativeCompletionAndRejectsFalseSettlement() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/gui/BukkitVisionOverlay.java"
)).replace("\r\n", "\n");
String delegate = method(source, "private void delegateTeleport(");
assertTrue(delegate.contains("teleport.whenComplete("));
assertTrue(delegate.contains("!Boolean.TRUE.equals(success)"));
assertTrue(delegate.contains("restartLatest(request)"));
}
@Test
public void staleChunkCompletionCannotTeleportOverTheLatestRequest() {
VisionHarness harness = new VisionHarness();
CompletableFuture<Chunk> firstChunk = new CompletableFuture<>();
CompletableFuture<Chunk> secondChunk = new CompletableFuture<>();
harness.stubChunk(0, 0, firstChunk);
harness.stubChunk(2, 2, secondChunk);
try (harness) {
harness.overlay.teleport(1.5D, 1.5D);
harness.overlay.teleport(33.5D, 33.5D);
firstChunk.complete(harness.chunk);
assertEquals(0, harness.destinations.size());
secondChunk.complete(harness.chunk);
assertEquals(1, harness.destinations.size());
assertEquals(33, harness.destinations.get(0).getBlockX());
assertEquals(33, harness.destinations.get(0).getBlockZ());
}
}
@Test
public void latestRequestRunsAfterAnOlderNativeTeleportSettles() {
VisionHarness harness = new VisionHarness();
harness.stubChunk(0, 0, CompletableFuture.completedFuture(harness.chunk));
harness.stubChunk(2, 2, CompletableFuture.completedFuture(harness.chunk));
CompletableFuture<Boolean> firstTeleport = new CompletableFuture<>();
CompletableFuture<Boolean> secondTeleport = new CompletableFuture<>();
harness.nativeTeleports.add(firstTeleport);
harness.nativeTeleports.add(secondTeleport);
try (harness) {
harness.overlay.teleport(1.5D, 1.5D);
harness.overlay.teleport(33.5D, 33.5D);
assertEquals(1, harness.destinations.size());
firstTeleport.complete(true);
assertEquals(2, harness.destinations.size());
assertEquals(33, harness.destinations.get(1).getBlockX());
assertEquals(33, harness.destinations.get(1).getBlockZ());
secondTeleport.complete(true);
}
}
private static void assertBefore(String source, String first, String second) {
int firstIndex = source.indexOf(first);
int secondIndex = source.indexOf(second);
assertTrue("Missing source contract token: " + first, firstIndex >= 0);
assertTrue("Missing source contract token: " + second, secondIndex >= 0);
assertTrue(first + " must occur before " + second, firstIndex < secondIndex);
}
private static int occurrences(String source, String match) {
int count = 0;
int offset = 0;
while ((offset = source.indexOf(match, offset)) >= 0) {
count++;
offset += match.length();
}
return count;
}
private static String method(String source, String signature) {
int start = source.indexOf(signature);
assertTrue("Missing source contract signature: " + signature, start >= 0);
int openBrace = source.indexOf('{', start);
assertTrue("Missing source contract method body: " + signature, openBrace >= 0);
int depth = 0;
for (int index = openBrace; index < source.length(); index++) {
char current = source.charAt(index);
if (current == '{') {
depth++;
} else if (current == '}') {
depth--;
if (depth == 0) {
return source.substring(start, index + 1);
}
}
}
throw new IllegalArgumentException("Unclosed source contract method: " + signature);
}
private static final class VisionHarness implements AutoCloseable {
private final Engine engine;
private final IrisWorld target;
private final World world;
private final Player player;
private final Chunk chunk;
private final WorldRuntimeControlService runtime;
private final MockedStatic<J> scheduling;
private final MockedStatic<BukkitWorldBinding> binding;
private final MockedStatic<WorldRuntimeControlService> runtimeAccess;
private final MockedStatic<BukkitPlatform> platform;
private final List<Location> destinations;
private final List<CompletableFuture<Boolean>> nativeTeleports;
private final AtomicInteger nativeTeleportIndex;
private final BukkitVisionOverlay overlay;
private VisionHarness() {
engine = mock(Engine.class);
target = mock(IrisWorld.class);
world = mock(World.class);
player = mock(Player.class);
chunk = mock(Chunk.class);
runtime = mock(WorldRuntimeControlService.class);
destinations = new ArrayList<>();
nativeTeleports = new ArrayList<>();
nativeTeleportIndex = new AtomicInteger();
when(engine.getWorld()).thenReturn(target);
when(target.hasPlatformWorld()).thenReturn(true);
when(player.isOnline()).thenReturn(true);
when(player.getWorld()).thenReturn(world);
when(chunk.getWorld()).thenReturn(world);
when(world.getHighestBlockYAt(anyInt(), anyInt())).thenReturn(70);
scheduling = mockStatic(J.class);
scheduling.when(() -> J.runGlobal(any(Runnable.class))).thenAnswer(invocation -> {
invocation.getArgument(0, Runnable.class).run();
return true;
});
scheduling.when(() -> J.runRegion(
same(world),
anyInt(),
anyInt(),
any(Runnable.class)))
.thenAnswer(invocation -> {
invocation.getArgument(3, Runnable.class).run();
return true;
});
scheduling.when(() -> J.runEntity(same(player), any(Runnable.class))).thenAnswer(invocation -> {
invocation.getArgument(1, Runnable.class).run();
return true;
});
binding = mockStatic(BukkitWorldBinding.class);
binding.when(() -> BukkitWorldBinding.world(target)).thenReturn(world);
binding.when(() -> BukkitWorldBinding.players(target)).thenReturn(List.of(player));
runtimeAccess = mockStatic(WorldRuntimeControlService.class);
runtimeAccess.when(WorldRuntimeControlService::get).thenReturn(runtime);
platform = mockStatic(BukkitPlatform.class);
platform.when(() -> BukkitPlatform.teleportAsync(same(player), any(Location.class)))
.thenAnswer(invocation -> {
destinations.add(invocation.getArgument(1, Location.class));
int index = nativeTeleportIndex.getAndIncrement();
return index < nativeTeleports.size()
? nativeTeleports.get(index)
: CompletableFuture.completedFuture(true);
});
overlay = new BukkitVisionOverlay(engine);
}
private void stubChunk(
int chunkX,
int chunkZ,
CompletableFuture<Chunk> requested
) {
when(runtime.requestChunkAsync(
same(world),
eq(chunkX),
eq(chunkZ),
eq(true),
eq(true))).thenReturn(requested);
}
@Override
public void close() {
platform.close();
runtimeAccess.close();
binding.close();
scheduling.close();
}
}
}
@@ -11,15 +11,14 @@ import static org.junit.Assert.assertTrue;
public class StudioPlayerModeContractTest {
@Test
public void studioEntryKeepsPlayersEligibleForNaturalSpawning() throws IOException {
public void autoStartedStudioUsesSpectatorMode() throws IOException {
String plugin = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n");
String commands = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandStudio.java")).replace("\r\n", "\n");
assertFalse(plugin.contains("GameMode.SPECTATOR"));
assertFalse(commands.contains("GameMode.SPECTATOR"));
assertTrue(plugin.contains("GameMode.CREATIVE"));
assertTrue(commands.contains("GameMode.CREATIVE"));
assertFalse(plugin.contains("GameMode.CREATIVE"));
assertFalse(commands.contains("GameMode.CREATIVE"));
assertTrue(plugin.contains("GameMode.SPECTATOR"));
}
@Test
@@ -32,8 +31,23 @@ public class StudioPlayerModeContractTest {
assertTrue(method.contains("StudioSVC studioService = Iris.service(StudioSVC.class)"));
assertTrue(method.contains("studioService.teleportToActiveProject(player)"));
assertFalse(method.contains("setGameMode("));
assertFalse(method.contains("getActiveProject()"));
assertFalse(method.contains("BukkitPlatform.teleportAsync"));
assertFalse(method.contains("BukkitWorldBinding.spawnLocation"));
}
@Test
public void editingStudiosRemainCreative() throws IOException {
String objectCommands = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandObject.java")).replace("\r\n", "\n");
String jigsawCommands = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n");
assertTrue(objectCommands.contains("GameMode.CREATIVE"));
assertTrue(objectCommands.contains("StudioOpenCoordinator.StudioOpenKind.OBJECT"));
assertTrue(jigsawCommands.contains("GameMode.CREATIVE"));
assertFalse(objectCommands.contains("GameMode.SPECTATOR"));
assertFalse(jigsawCommands.contains("GameMode.SPECTATOR"));
}
}