Retire source-text tests

- Delete 22 test classes whose assertions only read production .java text and check call ordering or literal presence
- Remove 77 source-text assertion methods from 34 test classes that keep real behavioural coverage
- Replace the core process-stream source grep with an ASM gate over compiled core classes in CoreProcessStreamPurityGateTest
- Replace the packs-root source grep in PacksFolderContractTest with an ASM call-site gate over compiled core classes
- Replace the IrisData registered-root regex in PackTypeBukkitPurityGateTest with an ASM scan of the registerLoader class constants
- Trim six mixed tests down to their behavioural assertions and drop their source-text tails
- Drop the eight iris.*Source and three iris.moddedCommonSources test system properties now that nothing reads them
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-08 04:01:33 -04:00
1 parent 7841efed54
commit c75cfd387e
65 files changed
+245 -4273

No files matched your search

@@ -3,14 +3,10 @@ package art.arcane.iris;
import art.arcane.iris.spi.LogLevel;
import org.junit.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.logging.Level;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Core states a severity on every message it logs and the modded adapters honour it. Bukkit must preserve
@@ -33,58 +29,4 @@ public class IrisDiagnosticLogLevelTest {
public void lifecycleNoticesReachThePluginLoggerAtInfo() {
assertEquals(Level.INFO, Iris.diagnosticLevel(LogLevel.NOTICE));
}
@Test
public void adapterSideWarningsCarryTheSameSeverityAsCoreWarnings() throws Exception {
String source = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n");
String warn = method(source, "public static void warn(String format, Object... objs)");
assertTrue(warn, warn.contains("diagnostic(Level.WARNING"));
assertFalse(warn, warn.contains("msg("));
String error = method(source, "public static void error(String format, Object... objs)");
assertTrue(error, error.contains("diagnostic(Level.SEVERE"));
assertFalse(error, error.contains("msg("));
}
@Test
public void theCoreLogBridgeRoutesDiagnosticsToThePluginLogger() throws Exception {
String source = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n");
String bridge = method(source, "private static void bridgeLog(LogLevel level, String message)");
assertTrue(bridge, bridge.contains("diagnosticLevel(target)"));
assertTrue(bridge, bridge.contains("diagnostic(diagnostic, message)"));
String diagnostic = method(source, "private static void diagnostic(Level level, String message)");
assertTrue(diagnostic, diagnostic.contains("ComponentLog.log("));
assertTrue(diagnostic, diagnostic.contains("ComponentText.literal(line)"));
}
@Test
public void informationalMessagesUseTheSharedComponentLogger() throws Exception {
String source = Files.readString(Path.of("src/main/java/art/arcane/iris/Iris.java")).replace("\r\n", "\n");
String message = method(source, "public static void msg(String string)");
assertTrue(message, message.contains("ComponentLog.logMarkup("));
assertTrue(message, message.contains("logPrefix(plugin)"));
assertFalse(message, message.contains("getSender().sendMessage"));
}
private static String method(String source, String signature) {
int start = source.indexOf(signature);
assertTrue("method not found: " + signature, start >= 0);
int open = source.indexOf('{', start);
int depth = 0;
for (int i = open; i < source.length(); i++) {
char c = source.charAt(i);
if (c == '{') {
depth++;
} else if (c == '}') {
depth--;
if (depth == 0) {
return source.substring(start, i + 1);
}
}
}
throw new AssertionError("unterminated method: " + signature);
}
}
@@ -1,72 +0,0 @@
package art.arcane.iris.core;
import org.junit.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.Assert.assertTrue;
public class IrisStartupOrderingTest {
@Test
public void admissionGateIsRegisteredBeforeStartupValidationBegins() throws Exception {
String source = Files.readString(Path.of(System.getProperty("iris.startupSource")));
String onEnable = section(source, "public void onEnable()", "public void onDisable()");
assertOrdered(onEnable,
"IrisStartupValidation.begin();",
"registerEvents(new IrisStartupAdmissionListener(), this);",
"enable();");
}
@Test
public void externalDatapacksValidateBeforeDimensionPacks() throws Exception {
String source = Files.readString(Path.of(System.getProperty("iris.startupSource")));
String enable = section(source, "private boolean enable()", "public void addShutdownHook()");
assertOrdered(enable,
"DatapackIngestService.validateOnStartup();",
"generatorResolver.validateAllPacks();");
}
@Test
public void externalProvidersEnableBeforePackValidation() throws Exception {
String source = Files.readString(Path.of(System.getProperty("iris.startupSource")));
String enable = section(source, "private boolean enable()", "public void addShutdownHook()");
assertOrdered(enable,
"service.onEnable();",
"setContentChangeListener(generatorResolver::requestExternalContentRefresh)",
"generatorResolver.validateAllPacks();");
}
@Test
public void restartRequiredStartupTerminatesAfterPluginInitialization() throws Exception {
String source = Files.readString(Path.of(System.getProperty("iris.startupSource")));
String onEnable = section(source, "public void onEnable()", "public void onDisable()");
assertOrdered(onEnable,
"BukkitGuiHost.install();",
"super.onEnable();",
"IrisStartupValidation.isRestartRequired()",
"ServerConfigurator.restartAtStartupBoundary(restartReason);");
}
private static String section(String source, String startMarker, String endMarker) {
int start = source.indexOf(startMarker);
int end = source.indexOf(endMarker, start);
assertTrue("Missing source section starting with " + startMarker, start >= 0);
assertTrue("Missing source section ending with " + endMarker, end > start);
return source.substring(start, end);
}
private static void assertOrdered(String source, String... markers) {
int previous = -1;
for (String marker : markers) {
int current = source.indexOf(marker);
assertTrue("Missing source marker " + marker, current >= 0);
assertTrue("Source marker is out of order: " + marker, current > previous);
previous = current;
}
}
}
@@ -140,23 +140,6 @@ public class IrisWorldGeneratorResolverTest {
}
}
@Test
public void startupValidationPublishesFingerprintBoundExactRootResults() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/IrisWorldGeneratorResolver.java")).replace("\r\n", "\n");
int validateAll = source.indexOf("public void validateAllPacks()");
int snapshot = source.indexOf("ServerConfigurator.computePackContentSnapshot(packsRoot)", validateAll);
int perPackFingerprint = source.indexOf("contentSnapshot.packContents()", snapshot);
int exactRootPublish = source.indexOf(
"PackValidationRegistry.publish(packDirectory.toPath(), result, packFingerprint)",
perPackFingerprint);
assertTrue(validateAll >= 0);
assertTrue(snapshot > validateAll);
assertTrue(perPackFingerprint > snapshot);
assertTrue(exactRootPublish > perPackFingerprint);
}
@Test
public void paperStartupAliasResolvesToCanonicalRuntimeKey() throws Exception {
File levelRoot = ownedLevelRoot("startup-alias", "moon");
@@ -251,87 +234,6 @@ public class IrisWorldGeneratorResolverTest {
return levelRoot;
}
@Test
public void configuredWorldResolutionUsesOnlyActiveImmutableGenerationPack() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/IrisWorldGeneratorResolver.java")).replace("\r\n", "\n");
int resolverStart = source.indexOf("private ChunkGenerator resolveFrozenWorldGenerator(");
int resolverEnd = source.indexOf("private record FreshValidation", resolverStart);
String resolver = source.substring(resolverStart, resolverEnd);
int dimensionRoot = resolver.indexOf("IrisWorldStorage.requireFrozenDimensionRoot(");
int currentPlatformRoot = resolver.indexOf("WorldCreatorCompat.persistentDimensionRoot(worldKey)");
int layoutRefusal = resolver.indexOf(
"Frozen Iris world storage does not match the current platform layout",
currentPlatformRoot
);
int history = resolver.indexOf("requireGenerationHistory(dimensionRoot, id, worldSeed)");
int snapshotRoot = resolver.indexOf("requireActivePack(history)", history);
int validation = resolver.indexOf("requireSnapshotLoadable(snapshotRoot)");
int exactLoad = resolver.indexOf("requireHistoricalDimension(history, snapshotRoot, id)");
int canonicalIdentity = resolver.indexOf(".platformIdentity(worldKey.toString())");
int historicalSeed = resolver.indexOf(".seed(history.activeEpoch().worldSeed())");
int resolvedStorage = resolver.indexOf(".worldFolder(dimensionRoot)");
assertTrue(dimensionRoot >= 0);
assertTrue(currentPlatformRoot > dimensionRoot);
assertTrue(layoutRefusal > currentPlatformRoot);
assertTrue(history > layoutRefusal);
assertTrue(snapshotRoot > history);
assertTrue(validation > snapshotRoot);
assertTrue(exactLoad > validation);
assertTrue(canonicalIdentity > exactLoad);
assertTrue(historicalSeed > canonicalIdentity);
assertTrue(resolvedStorage > historicalSeed);
assertFalse(resolver.contains("loadDimension("));
assertFalse(resolver.contains("loadAnyDimension("));
assertFalse(resolver.contains("replaceIntoWorld("));
assertFalse(resolver.contains("installIntoWorld("));
assertFalse(resolver.contains(".seed(1337)"));
assertTrue(resolver.contains("GenerationHistory.openIfPresent(root, worldSeed)"));
assertTrue(resolver.contains("GenerationHistory.adoptLegacyPack("));
assertTrue(resolver.contains("GenerationRegistryContractFactory.captureRequiredDefinitions("));
}
@Test
public void ownedWorldSnapshotFailureStopsStartupAndRethrows() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/IrisWorldGeneratorResolver.java")).replace("\r\n", "\n");
int resolverStart = source.indexOf("public ChunkGenerator resolveDefaultWorldGenerator(");
int resolverEnd = source.indexOf("private ChunkGenerator resolveFrozenWorldGenerator(", resolverStart);
String resolver = source.substring(resolverStart, resolverEnd);
int plotSquaredProbe = resolver.indexOf("isPlotSquaredGeneratorDiscoveryProbe(worldName, id)");
int probe = resolver.indexOf("isGeneratorDiscoveryProbe(worldName, id)", plotSquaredProbe);
int denial = resolver.indexOf("IrisStartupValidation.denialReason()", probe);
int failClosed = resolver.indexOf("IrisFailClosedChunkGenerator.startupLock(", denial);
int staged = resolver.indexOf("WorldLifecycleStaging.consumeGenerator(worldName)", failClosed);
int duplicateGuard = resolver.indexOf("requireWorldKeyAvailable(worldName, worldKey)");
int ownership = resolver.indexOf("requireOwnedWorld(worldName, levelRoot, worldKey)");
int frozen = resolver.indexOf("return resolveFrozenWorldGenerator(", ownership);
int failureCapture = resolver.indexOf("catch (RuntimeException failure)", frozen);
int report = resolver.indexOf("Iris.reportError(", failureCapture);
int shutdown = resolver.indexOf("Bukkit.shutdown()", report);
int rethrow = resolver.indexOf("throw failure", shutdown);
assertTrue(plotSquaredProbe >= 0);
assertTrue(probe > plotSquaredProbe);
assertTrue(denial > probe);
assertTrue(failClosed > denial);
assertTrue(staged > failClosed);
assertTrue(duplicateGuard > staged);
assertTrue(ownership > duplicateGuard);
assertTrue(frozen > ownership);
assertTrue(failureCapture > frozen);
assertTrue(report > failureCapture);
assertTrue(shutdown > report);
assertTrue(rethrow > shutdown);
String shutdownScope = "the fail-fast shutdown must stay scoped to the frozen snapshot of an owned world";
assertEquals(shutdownScope, resolverStart + shutdown, source.indexOf("Bukkit.shutdown()"));
assertEquals(shutdownScope, resolverStart + shutdown, source.lastIndexOf("Bukkit.shutdown()"));
}
@Test
public void plotSquaredDiscoveryProbeIsIgnoredQuietly() {
try (MockedStatic<Bukkit> bukkit = mockStatic(Bukkit.class);
@@ -1,26 +0,0 @@
package art.arcane.iris.core.commands;
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 final class CommandDeveloperGenerationHistoryTest {
@Test
public void updateWorldStagesThePackWithTheLiveWorldSeed() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandDeveloper.java"
)).replace("\r\n", "\n");
int updateStart = source.indexOf("public void updateWorld(");
int updateEnd = source.indexOf("@Director(description = \"Test\"", updateStart);
String update = source.substring(updateStart, updateEnd);
assertTrue(update.contains(
"replaceIntoWorld(sender(), pack, folder, world.getSeed())"
));
assertFalse(update.contains("iris/pack"));
}
}
@@ -7,8 +7,6 @@ import org.junit.Test;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
@@ -73,26 +71,4 @@ public class CommandIrisCreateOverwriteContractTest {
assertEquals(Long.valueOf(Long.MAX_VALUE), handler.parse(Long.toString(Long.MAX_VALUE), false));
assertThrows(DirectorParsingException.class, () -> handler.parse("9223372036854775808", false));
}
@Test
public void createAndReplaceUseLocalizedStyledMissingDimensionFeedback() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandIris.java"
)).replace("\r\n", "\n");
assertEquals(2, occurrences(source, "COMMAND_IRIS_DIMENSION_NOT_FOUND"));
assertEquals(2, occurrences(source, "COMMAND_IRIS_INSTALL_PACK_AND_RESTART"));
assertFalse(source.contains("sendMessage(\"Could not find dimension"));
assertFalse(source.contains("sendMessage(\"Install its pack with"));
}
private static int occurrences(String value, String match) {
int count = 0;
int offset = 0;
while ((offset = value.indexOf(match, offset)) >= 0) {
count++;
offset += match.length();
}
return count;
}
}
@@ -5,13 +5,10 @@ import org.junit.Test;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
@@ -47,20 +44,6 @@ public class CommandIrisDownloadContractTest {
assertThrows(Exception.class, () -> handler.parse("custom", false));
}
@Test
public void commandDelegatesAcceptedDownloadsWithoutRawPreamble() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandIris.java"
)).replace("\r\n", "\n");
String download = method(source, "public void download(");
assertTrue(download.contains("downloadBuiltIn(sender(), builtInPack)"));
assertTrue(download.contains("downloadUrl(sender(), directLink)"));
assertFalse(download.contains("Downloading built-in Iris pack"));
assertFalse(download.contains("Downloading Iris pack from"));
assertFalse(download.contains("sendMessage(directLink"));
}
private static String method(String source, String signature) {
int start = source.indexOf(signature);
assertTrue(start >= 0);
@@ -115,21 +115,6 @@ public class CommandJigsawContractTest {
new IllegalStateException("Unexpected Studio failure")));
}
@Test
public void committedActivationStartsInitialEvaluationBeforePlayerBinding() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n");
int commit = source.indexOf("JigsawStudioActivation.commit(staged)");
int evaluation = source.indexOf(
"studioService.activationCommitted(world, request.requestId())",
commit);
int binding = source.indexOf("PLAYER_PACKS.put", evaluation);
assertTrue(commit >= 0);
assertTrue(evaluation > commit);
assertTrue(binding > evaluation);
}
@Test
public void convertIsAddOnlyWorkflowWithAliasesAndDefaults() throws Exception {
Method convert = CommandJigsaw.class.getDeclaredMethod(
@@ -358,20 +343,6 @@ public class CommandJigsawContractTest {
.getAnnotation(Director.class));
}
@Test
public void pieceCreateUsesResolvedWorkcellCapacityInsteadOfLayoutDefault() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n");
int pieceCommands = source.indexOf("public static class CommandJigsawPiece");
int create = source.indexOf("public void create(", pieceCommands);
int add = source.indexOf("public void add(", create);
String createSource = source.substring(create, add);
assertTrue(createSource.contains("targetWorkcell = contextual;"));
assertTrue(createSource.contains("JigsawStudioCellDimensions dimensions = targetWorkcell.capacity();"));
assertFalse(createSource.contains("layout().cellDimensions()"));
}
@Test
public void pieceAddUsesCanonicalAxesForRotatedRectangularPlanarWorkcells() {
JigsawStudioLayout layout = nonuniformPlanarLayout();
@@ -510,25 +481,6 @@ public class CommandJigsawContractTest {
assertEquals(1, releases.get());
}
@Test
public void exportSourceAcquiresStudioLeaseBeforeStaticLeaseAndReleasesBothPaths() throws Exception {
String source = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandJigsaw.java")).replace("\r\n", "\n");
int serviceLease = source.indexOf("studioService.tryBeginExport(requestId, playerId)");
int staticLease = source.indexOf("beginExport(playerId, destination)", serviceLease);
int dispatch = source.indexOf("J.a(() -> runExport(operation))", staticLease);
int schedulingRelease = source.indexOf("operation.lease().release()", dispatch);
int exporter = source.indexOf("new VanillaJigsawDatapackExporter().export(operation.request())", dispatch);
int completionRelease = source.indexOf("operation.lease().release()", exporter);
assertTrue(serviceLease >= 0);
assertTrue(staticLease > serviceLease);
assertTrue(dispatch > staticLease);
assertTrue(schedulingRelease > dispatch);
assertTrue(exporter > schedulingRelease);
assertTrue(completionRelease > exporter);
}
private static void assertCommand(String name, Class<?>... parameterTypes) throws Exception {
Method method = CommandJigsaw.class.getDeclaredMethod(name, parameterTypes);
assertNotNull(method.getAnnotation(Director.class));
@@ -7,8 +7,6 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.junit.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
@@ -212,20 +210,6 @@ public class IrisPapiExpansionTest {
assertTrue(expansion.persist());
}
@Test
public void theReadmeDocumentsEveryPublishedKeyAndEveryRetiredOne() throws Exception {
String readme = Files.readString(Path.of(System.getProperty("iris.readmeSource")));
for (String key : PUBLISHED_KEYS) {
assertTrue("README must document %iris_" + key + "%", readme.contains("%iris_" + key + "%"));
}
for (String retired : RETIRED_KEYS) {
assertTrue("README must carry the migration row for %iris_" + retired + "%",
readme.contains("%iris_" + retired + "%"));
}
}
@Test
public void theTerrainServiceIsTheOnlyDoorIntoIris() {
IrisTerrainService service = new FakeIrisTerrainService();
@@ -1,137 +0,0 @@
package art.arcane.iris.core.link;
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 IrisPapiLifecycleTest {
private static final Path PLUGIN_SOURCE = Path.of("src/main/java/art/arcane/iris/Iris.java");
private static final String SETUP = "private void setupPapi() {";
private static final String TEARDOWN = "private void teardownPapi() {";
private static String source() throws Exception {
// The assertions below match against literals written with \n, so a CRLF checkout has to
// be folded first or every multi-line expectation misses.
return Files.readString(PLUGIN_SOURCE).replace("\r\n", "\n");
}
private static String body(String declaration) throws Exception {
String source = source();
int start = source.indexOf(declaration);
assertTrue("Iris.java must declare " + declaration, start >= 0);
int open = source.indexOf('{', start);
int depth = 0;
for (int index = open; index < source.length(); index++) {
char character = source.charAt(index);
if (character == '{') {
depth++;
continue;
}
if (character != '}') {
continue;
}
depth--;
if (depth == 0) {
return source.substring(open + 1, index);
}
}
throw new AssertionError(declaration + " is not brace balanced");
}
@Test
public void registrationIsGatedOnPlaceholderApiBeingEnabled() throws Exception {
assertTrue("setupPapi must bail out when PlaceholderAPI is absent",
body(SETUP).contains("if (!PlaceholderRegistration.isPlaceholderApiEnabled()) {"));
}
@Test
public void theRegistrationTheListenerAndTheStateAreAllRetained() throws Exception {
String source = source();
assertTrue(source.contains("private volatile PlaceholderRegistration papiRegistration;"));
assertTrue(source.contains("private volatile IrisPapiListener papiListener;"));
assertTrue(source.contains("private volatile IrisPapiState papiState;"));
}
@Test
public void teardownUnregistersTheExpansionTheListenerAndClearsTheState() throws Exception {
String teardown = body(TEARDOWN);
assertTrue("the retained registration must be unregistered inside teardownPapi",
teardown.contains("registration.unregister();"));
assertTrue("the retained listener must be detached inside teardownPapi",
teardown.contains("HandlerList.unregisterAll(listener);"));
assertTrue("the retained state must drop every held world reference inside teardownPapi",
teardown.contains("state.clear();"));
assertTrue("teardownPapi must drop the retained listener", teardown.contains("papiListener = null;"));
assertTrue("teardownPapi must drop the retained registration", teardown.contains("papiRegistration = null;"));
assertTrue("teardownPapi must drop the retained state", teardown.contains("papiState = null;"));
}
@Test
public void bothDisablePathsTearThePlaceholderSurfaceDown() throws Exception {
String disable = body("public void onDisable() {");
String preUnload = body("public void onPreUnload(ReloadAware.PreUnloadReason reason) {");
int disableTeardown = disable.indexOf("teardownPapi();");
int preUnloadTeardown = preUnload.indexOf("teardownPapi();");
assertTrue("onDisable must tear the expansion down before branching into runtime shutdown",
disableTeardown >= 0 && disableTeardown < disable.indexOf("IrisToolbelt.isServerStopping()"));
assertTrue("the BileTools pre-unload hook must tear the expansion down before any shutdown branch",
preUnloadTeardown >= 0 && preUnloadTeardown < preUnload.indexOf("IrisToolbelt.isServerStopping()"));
}
@Test
public void aFailedListenerAttachDoesNotLeaveTheExpansionRegistered() throws Exception {
String setup = body(SETUP);
int attach = setup.indexOf("registerEvents(listener, this)");
assertTrue("the listener must be attached inside setupPapi", attach >= 0);
int rescue = setup.indexOf("} catch (Throwable failure) {", attach);
assertTrue("the attach must be guarded inside setupPapi", rescue > attach);
int rollback = setup.indexOf("registration.unregister();", rescue);
assertTrue("a failed attach must roll the registration back inside setupPapi", rollback > rescue);
int bail = setup.indexOf("return;", rollback);
assertTrue("a failed attach must leave setupPapi", bail > rollback);
int retained = setup.indexOf("papiRegistration = registration;");
assertTrue("setupPapi must retain the registration", retained > 0);
assertTrue("the registration may only be retained after a successful attach", retained > bail);
}
@Test
public void theExpansionIsNeverConstructedFromAPluginStatic() throws Exception {
String setup = body(SETUP);
assertFalse("the plugin class must not construct the expansion: that forces PlaceholderExpansion to load during enable and crashes a server without PlaceholderAPI",
setup.contains("new IrisPapiExpansion("));
assertTrue("the expansion takes its state as a constructor argument, built inside the installer",
installerSource().contains("new IrisPapiExpansion(state, logger)"));
assertFalse("the hand rolled PlaceholderAPI presence check must be gone",
source().contains("isPluginEnabled(\"PlaceholderAPI\")"));
}
private static String installerSource() throws Exception {
return java.nio.file.Files.readString(java.nio.file.Path.of(
"src/main/java/art/arcane/iris/core/link/IrisPapiInstaller.java")).replace("\r\n", "\n");
}
}
@@ -1,53 +0,0 @@
package art.arcane.iris.core.runtime;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class StudioPlayerModeContractTest {
@Test
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.CREATIVE"));
assertFalse(commands.contains("GameMode.CREATIVE"));
assertTrue(plugin.contains("GameMode.SPECTATOR"));
}
@Test
public void tpStudioUsesThePreparedCoordinatorEntry() throws IOException {
String commands = Files.readString(Path.of(
"src/main/java/art/arcane/iris/core/commands/CommandStudio.java")).replace("\r\n", "\n");
int methodStart = commands.indexOf("public void tpstudio()");
int methodEnd = commands.indexOf("\n @Director", methodStart);
String method = commands.substring(methodStart, methodEnd);
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"));
}
}
@@ -1,195 +0,0 @@
package art.arcane.iris.core.service;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class IrisApiWiringContractTest {
@Test
public void theTerrainServiceRegistersOnBothRegistriesAndReleasesBoth() throws IOException {
String source = source("iris.terrainSvcSource");
String onEnable = method(source, "public void onEnable()");
String onDisable = method(source, "public void onDisable()");
assertTrue(onEnable.contains("Bukkit.getServicesManager().register("));
assertTrue(onEnable.contains("IrisTerrainService.class"));
assertTrue(onEnable.contains("IrisServices.register(IrisTerrainService.class, this)"));
assertTrue(onDisable.contains("Bukkit.getServicesManager().unregister(IrisTerrainService.class, this)"));
assertTrue(onDisable.contains("IrisServices.remove(IrisTerrainService.class)"));
assertBefore(onDisable, "serviceEnabled.set(false)", "Bukkit.getServicesManager().unregister(");
}
@Test
public void theTerrainServiceNeverForcesEngineInitialisationOrLoadsTheMantle() throws IOException {
String source = source("iris.terrainSvcSource");
assertFalse("isIrisWorld must not touch the generator", source.contains("IrisToolbelt"));
assertFalse("isIrisWorld must not touch the generator", source.contains(".touch("));
assertFalse("terrain queries must not load mantle chunks", source.contains("getMantle()"));
assertFalse("terrain queries must not load mantle chunks", source.contains("getObjectsAt("));
assertFalse("terrain queries must not load mantle chunks", source.contains("getPOIsAt("));
assertFalse("terrain queries must not load mantle chunks", source.contains("getCaveOrMantleBiome("));
assertFalse("terrain queries must never block", source.contains(".join()"));
assertFalse("terrain queries must never block", source.contains("synchronized"));
assertFalse("terrain queries must never block", source.contains("J.sfut("));
}
@Test
public void sampleColumnsBoundsTheQueryBeforeItWalksAndTreatsAThrowingSinkAsARefusal() throws IOException {
String sampleColumns = method(source("iris.terrainSvcSource"),
"public boolean sampleColumns(World world, IrisColumnQuery query, IrisColumnSink sink)");
assertBefore(sampleColumns, "IrisSampleLimits.withinLimits(", "IrisColumnWalk.walk(");
assertBefore(sampleColumns, "IrisColumnWalk.walk(", "catch (Throwable error)");
assertTrue(sampleColumns.contains("reportSinkFault(world, error)"));
assertTrue(sampleColumns.contains("return false;"));
assertTrue("the walk must abort when the engine closes underneath it",
sampleColumns.contains("engine.isClosed()"));
}
@Test
public void thePregeneratorDispatchesPhasesFromItsExistingTickAndNeverBlocksOnTheSink() throws IOException {
String source = source("iris.pregeneratorJobSource");
String dispatch = method(source, "private void dispatchApiPhases(List<PregenApiPhase> phases)");
assertTrue(dispatch.contains("IrisServices.getOrNull(PregenApiSink.class)"));
assertTrue(dispatch.contains("catch (Throwable error)"));
assertBefore(dispatch, "sink.pregen(phase, progress)", "catch (Throwable error)");
assertFalse(dispatch.contains(".join()"));
assertTrue(method(source, "public void onTick(").contains("dispatchApiPhases(apiPhases.onTick(paused()))"));
assertTrue(method(source, "public void onSaving()").contains("dispatchApiPhases(apiPhases.onSaving())"));
assertTrue(method(source, "public void onClose()").contains("dispatchApiPhases(apiPhases.onClose(reachedTotal()))"));
}
@Test
public void worldPhasesAreFiredOutsideTheRegistrationLock() throws IOException {
String source = source("iris.engineSvcSource");
String add = method(source, "private void add(World world)");
assertBefore(add, "catch (RejectedExecutionException exception)", "phases.ready(world)");
assertBefore(add, "registered = true;", "phases.ready(world)");
String remove = method(source,
"private boolean remove(World world, CompletionStage<Boolean> unloadBoundary)");
assertBefore(remove, "registered = worlds.remove(world)", "phases.closing(world)");
assertBefore(remove, "phases.closing(world)",
"deferCloseUntilWorldUnload(world, registered, closing, unloadBoundary)");
}
@Test
public void everyRegisteredWorldIsAnnouncedClosingWhenTheServiceShutsDown() throws IOException {
String onDisable = method(source("iris.engineSvcSource"), "public void onDisable()");
assertTrue("service shutdown must announce ENGINE_CLOSING for every registered world",
onDisable.contains("phases.closing(teardown.world())"));
assertBefore(onDisable, "worlds.clear()", "phases.closing(teardown.world())");
assertBefore(onDisable, "phases.closing(teardown.world())", "shutdownAndDrain(activeService)");
assertBefore(onDisable, "phases.closing(teardown.world())",
"startClose(teardown.registered(), teardown.closing())");
}
@Test
public void aReplacedEngineIsAnnouncedClosingBeforeTheRetryReRegistersTheWorld() throws IOException {
String add = method(source("iris.engineSvcSource"), "private void add(World world)");
assertBefore(add, "catch (RejectedExecutionException exception)", "phases.closing(world)");
assertBefore(add, "phases.closing(world)", "retryRegistrationAfterClose(world, retryAfter)");
assertBefore(add, "phases.closing(world)", "startClose(replaced, replacementClose)");
}
@Test
public void aWorldPhaseIsNeverConditionalOnAnotherServicesRegistration() throws IOException {
String source = source("iris.apiEventSvcSource");
String fire = method(source, "public static void fireWorldPhase(World world, IrisWorldPhase phase)");
assertFalse("world lifecycle must not resolve a swappable service to build its payload",
fire.contains("IrisServices"));
assertFalse("world lifecycle must not resolve a swappable service to build its payload",
fire.contains("IrisTerrainService"));
assertTrue(fire.contains("deliver(new IrisWorldEngineEvent(world, phase, describe(world, phase)))"));
String describe = method(source, "private static IrisWorldInfo describe(World world, IrisWorldPhase phase)");
assertTrue(describe.contains("IrisWorldInfoFactory.forWorld(world)"));
assertTrue("an undescribable world must be reported, not swallowed",
describe.contains("IrisLogging.reportError("));
assertTrue("an undescribable world must still deliver the phase", describe.contains("return null;"));
}
@Test
public void aWorldPhaseRaisedFromAServerThreadIsDeliveredBeforeThatThreadMovesOn() throws IOException {
String deliver = method(source("iris.apiEventSvcSource"), "private static void deliver(Event event)");
assertBefore(deliver, "Bukkit.isPrimaryThread()", "Bukkit.getPluginManager().callEvent(event)");
assertBefore(deliver, "Bukkit.getPluginManager().callEvent(event)", "Iris.callEvent(event)");
}
@Test
public void theWorldInfoFactoryNeverForcesEngineInitialisationOrLoadsTheMantle() throws IOException {
String source = source("iris.worldInfoFactorySource");
assertFalse("the factory must not touch the generator", source.contains("IrisToolbelt"));
assertFalse("the factory must not touch the generator", source.contains(".touch("));
assertFalse("the factory must not load mantle chunks", source.contains("getMantle()"));
assertFalse("the factory must never block", source.contains(".join()"));
assertFalse("the factory must never block", source.contains("synchronized"));
assertTrue("the factory must refuse a closed engine", source.contains("engine.isClosed()"));
}
@Test
public void theHotloadHookStillFiresTheLegacyEventAlongsideTheApiEvent() throws IOException {
String hook = method(source("iris.bukkitEnginePlatformHooksSource"), "public void fireHotloadEvent(Engine engine)");
assertBefore(hook, "new IrisEngineHotloadEvent(engine)",
"IrisApiEventSVC.fireWorldPhase(BukkitWorldBinding.world(engine.getWorld()), IrisWorldPhase.ENGINE_HOTLOADED)");
}
@Test
public void theEventServiceNeverLetsAThirdPartyFailureEscapeALifecyclePath() throws IOException {
String fire = method(source("iris.apiEventSvcSource"),
"public static void fireWorldPhase(World world, IrisWorldPhase phase)");
assertTrue(fire.contains("catch (Throwable error)"));
assertTrue(fire.contains("IrisLogging.reportError("));
assertFalse(fire.contains("printStackTrace"));
}
private static String source(String property) throws IOException {
String path = System.getProperty(property);
assertTrue("missing source property " + property, path != null && !path.isBlank());
return Files.readString(Path.of(path));
}
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 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);
}
}