This commit is contained in:
Brian Neumann-Fopiano
2026-07-27 13:46:24 -05:00
parent d5a55ccfcf
commit 74741ac83e
112 changed files with 3393 additions and 1025 deletions
@@ -0,0 +1,53 @@
package art.arcane.iris.client;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import static org.junit.Assert.assertEquals;
public class IrisClientCursorTest {
@Test
public void refreshesAnUnchangedPositionAfterTheRefreshInterval() {
AtomicLong clock = new AtomicLong(500L);
AtomicInteger frames = new AtomicInteger();
IrisClientCursor cursor = new IrisClientCursor(frame -> frames.incrementAndGet(), clock::get);
cursor.requestFor(10, 20);
clock.addAndGet(1_999L);
cursor.requestFor(10, 20);
clock.incrementAndGet();
cursor.requestFor(10, 20);
assertEquals(2, frames.get());
}
@Test
public void throttlesRapidPositionChanges() {
AtomicLong clock = new AtomicLong(500L);
AtomicInteger frames = new AtomicInteger();
IrisClientCursor cursor = new IrisClientCursor(frame -> frames.incrementAndGet(), clock::get);
cursor.requestFor(10, 20);
clock.addAndGet(499L);
cursor.requestFor(11, 20);
clock.incrementAndGet();
cursor.requestFor(11, 20);
assertEquals(2, frames.get());
}
@Test
public void clearAllowsImmediateRequestAtTheSamePosition() {
AtomicLong clock = new AtomicLong(500L);
AtomicInteger frames = new AtomicInteger();
IrisClientCursor cursor = new IrisClientCursor(frame -> frames.incrementAndGet(), clock::get);
cursor.requestFor(10, 20);
cursor.clear();
cursor.requestFor(10, 20);
assertEquals(2, frames.get());
}
}
@@ -0,0 +1,25 @@
package art.arcane.iris.client;
import art.arcane.iris.spi.protocol.IrisMessage;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class IrisClientDimensionTest {
@Test
public void packSeedAndHeightChangesInvalidateDimensionCaches() {
IrisClientDimension dimension = new IrisClientDimension();
IrisMessage.DimensionStatus initial = new IrisMessage.DimensionStatus(
"minecraft:overworld", "overworld", 1L, -64, 320, true);
assertTrue(dimension.onDimensionStatus(initial));
assertFalse(dimension.onDimensionStatus(initial));
assertTrue(dimension.onDimensionStatus(new IrisMessage.DimensionStatus(
"minecraft:overworld", "other", 1L, -64, 320, true)));
assertTrue(dimension.onDimensionStatus(new IrisMessage.DimensionStatus(
"minecraft:overworld", "other", 2L, -64, 320, true)));
assertTrue(dimension.onDimensionStatus(new IrisMessage.DimensionStatus(
"minecraft:overworld", "other", 2L, 0, 256, true)));
}
}
@@ -0,0 +1,57 @@
package art.arcane.iris.client;
import art.arcane.iris.spi.protocol.IrisMessage;
import art.arcane.iris.spi.protocol.IrisProtocol;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class IrisClientSessionTest {
@Test
public void retriesHelloAndEventuallyMarksUnsupported() {
AtomicLong clock = new AtomicLong();
AtomicInteger frames = new AtomicInteger();
IrisClientSession session = new IrisClientSession(clock::get);
session.bind(frame -> frames.incrementAndGet());
session.sendHello();
assertEquals(1, frames.get());
assertEquals(IrisClientSession.State.AWAITING_HELLO, session.state());
for (int attempt = 0; attempt < 5; attempt++) {
clock.addAndGet(2_000L);
session.tick();
}
assertEquals(5, frames.get());
assertEquals(IrisClientSession.State.UNSUPPORTED, session.state());
}
@Test
public void matchingHelloCompletesRetryingSession() {
AtomicLong clock = new AtomicLong();
IrisClientSession session = new IrisClientSession(clock::get);
session.bind(frame -> {
});
session.sendHello();
session.onServerHello(new IrisMessage.ServerHello(
IrisProtocol.PROTOCOL_VERSION, IrisProtocol.CAPABILITY_VISION, "Iris", true));
assertTrue(session.isReady());
assertEquals("Iris", session.serverBrand());
}
@Test
public void incompatibleHelloIsRejected() {
IrisClientSession session = new IrisClientSession();
session.onServerHello(new IrisMessage.ServerHello(
IrisProtocol.PROTOCOL_VERSION + 1, 0L, "Iris", true));
assertEquals(IrisClientSession.State.INCOMPATIBLE, session.state());
}
}
@@ -29,7 +29,7 @@ public class IrisModLanguageAssetsTest {
@Test
public void minecraftLanguageAssetsMatchSharedLocaleManifest() throws Exception {
JsonObject english = read("en_us");
assertEquals(2, english.size());
assertEquals(4, english.size());
for (String locale : VolmitLocales.nonEnglish()) {
String minecraftLocale = VolmitLocales.minecraftCode(locale);
@@ -73,9 +73,16 @@ public class IrisModLanguageAssetsTest {
private Set<String> resourceFiles() throws Exception {
URL resource = IrisModLanguageAssetsTest.class.getClassLoader().getResource(ROOT);
assertNotNull("Missing mod language resource directory", resource);
assertEquals("file", resource.getProtocol());
try (Stream<Path> paths = Files.list(Path.of(resource.toURI()))) {
Path directory;
if (resource != null && "file".equals(resource.getProtocol())) {
directory = Path.of(resource.toURI());
} else {
String sources = System.getProperty("iris.moddedCommonSources");
assertNotNull("Missing mod language resource directory and source root", sources);
directory = Path.of(sources).getParent()
.resolve("resources").resolve(ROOT);
}
try (Stream<Path> paths = Files.list(directory)) {
return paths
.filter(Files::isRegularFile)
.map(path -> path.getFileName().toString())
@@ -0,0 +1,87 @@
package art.arcane.iris.modded;
import org.junit.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
public class ModdedDimensionRegistryStoreTest {
@Test
public void registryRoundTripsPersistentDimensions() throws IOException {
Path root = Files.createTempDirectory("iris-dimension-registry");
Path file = root.resolve("iris-dimensions.json");
try {
List<ModdedDimensionRegistryStore.PersistentDimension> expected = List.of(
new ModdedDimensionRegistryStore.PersistentDimension(
"iris:first", "overworld", "overworld", 42L),
new ModdedDimensionRegistryStore.PersistentDimension(
"iris:second", "other", "surface", -9L));
ModdedDimensionRegistryStore.write(file, expected);
assertEquals(expected, ModdedDimensionRegistryStore.load(file));
} finally {
Files.deleteIfExists(file);
Files.deleteIfExists(root);
}
}
@Test
public void malformedEntryDoesNotDiscardHealthyEntries() throws IOException {
Path root = Files.createTempDirectory("iris-dimension-registry-partial");
Path file = root.resolve("iris-dimensions.json");
try {
Files.writeString(file, """
{
"dimensions": [
{"id":"iris:good","pack":"overworld","dimension":"overworld","seed":7},
{"id":"iris:broken","pack":"overworld"}
]
}
""", StandardCharsets.UTF_8);
assertEquals(List.of(new ModdedDimensionRegistryStore.PersistentDimension(
"iris:good", "overworld", "overworld", 7L)),
ModdedDimensionRegistryStore.load(file));
} finally {
Files.deleteIfExists(file);
Files.deleteIfExists(root);
}
}
@Test
public void truncatedRegistryNeverBecomesAnEmptySuccessfulLoad() throws IOException {
Path root = Files.createTempDirectory("iris-dimension-registry-truncated");
Path file = root.resolve("iris-dimensions.json");
try {
Files.writeString(file, "{\"dimensions\":[", StandardCharsets.UTF_8);
assertThrows(IllegalStateException.class,
() -> ModdedDimensionRegistryStore.load(file));
} finally {
Files.deleteIfExists(file);
Files.deleteIfExists(root);
}
}
@Test
public void missingDimensionsArrayNeverBecomesAnEmptySuccessfulLoad() throws IOException {
Path root = Files.createTempDirectory("iris-dimension-registry-missing-root");
Path file = root.resolve("iris-dimensions.json");
try {
Files.writeString(file, "{}", StandardCharsets.UTF_8);
assertThrows(IllegalStateException.class,
() -> ModdedDimensionRegistryStore.load(file));
} finally {
Files.deleteIfExists(file);
Files.deleteIfExists(root);
}
}
}
@@ -44,6 +44,7 @@ import static art.arcane.iris.engine.object.IrisDimensionTypeOptions.TriState.FA
import static art.arcane.iris.engine.object.IrisDimensionTypeOptions.TriState.TRUE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -54,9 +55,14 @@ public class ModdedDimensionTypeParityTest {
IrisDimension nether = dimension("nether", IrisEnvironment.NETHER, 0, 256, 256, new IrisDimensionTypeOptions());
IrisDimension end = dimension("the_end", IrisEnvironment.THE_END, 0, 256, 256, new IrisDimensionTypeOptions());
assertEquals("irisworldgen:overworld", ModdedForcedDatapack.dimensionTypeRef(overworld));
assertEquals("irisworldgen:nether", ModdedForcedDatapack.dimensionTypeRef(nether));
assertEquals("irisworldgen:the_end", ModdedForcedDatapack.dimensionTypeRef(end));
assertEquals("irisworldgen:packs/6f766572776f726c64/dimensions/6f766572776f726c64/dimension_type",
ModdedWorldgenIds.dimensionTypeRef("overworld", overworld.getLoadKey()));
assertEquals("irisworldgen:packs/6e6574686572/dimensions/6e6574686572/dimension_type",
ModdedWorldgenIds.dimensionTypeRef("nether", nether.getLoadKey()));
assertEquals("irisworldgen:packs/7468655f656e64/dimensions/7468655f656e64/dimension_type",
ModdedWorldgenIds.dimensionTypeRef("the_end", end.getLoadKey()));
assertNotEquals(ModdedWorldgenIds.dimensionTypeRef("first", "overworld"),
ModdedWorldgenIds.dimensionTypeRef("second", "overworld"));
}
@Test
@@ -77,18 +83,18 @@ public class ModdedDimensionTypeParityTest {
roots.add(packDirectory.toFile());
try {
for (IrisDimension dimension : dimensions) {
ModdedForcedDatapack.writeDimensionType(roots, fixer, dimension);
Path output = packDirectory.resolve("data/irisworldgen/dimension_type/"
+ dimension.getDimensionTypeKey() + ".json");
ModdedForcedDatapack.writeDimensionType(
roots, fixer, dimension, "contracts", dimension.getLoadKey());
Path output = typeFile(packDirectory, "contracts", dimension);
assertTrue(Files.isRegularFile(output));
assertEquals(dimension.getDimensionType().toJson(fixer),
Files.readString(output, StandardCharsets.UTF_8));
}
JSONObject overworldJson = readType(packDirectory, overworld);
JSONObject netherJson = readType(packDirectory, nether);
JSONObject endJson = readType(packDirectory, end);
JSONObject customJson = readType(packDirectory, custom);
JSONObject overworldJson = readType(packDirectory, "contracts", overworld);
JSONObject netherJson = readType(packDirectory, "contracts", nether);
JSONObject endJson = readType(packDirectory, "contracts", end);
JSONObject customJson = readType(packDirectory, "contracts", custom);
assertTrue(overworldJson.getBoolean("has_skylight"));
assertFalse(overworldJson.getBoolean("has_ceiling"));
@@ -166,10 +172,16 @@ public class ModdedDimensionTypeParityTest {
return dimension;
}
private static JSONObject readType(Path packDirectory, IrisDimension dimension) throws IOException {
Path output = packDirectory.resolve("data/irisworldgen/dimension_type/"
+ dimension.getDimensionTypeKey() + ".json");
return new JSONObject(Files.readString(output, StandardCharsets.UTF_8));
private static JSONObject readType(Path packDirectory, String pack,
IrisDimension dimension) throws IOException {
return new JSONObject(Files.readString(
typeFile(packDirectory, pack, dimension), StandardCharsets.UTF_8));
}
private static Path typeFile(Path packDirectory, String pack, IrisDimension dimension) {
String typeRef = ModdedWorldgenIds.dimensionTypeRef(pack, dimension.getLoadKey());
return packDirectory.resolve("data/irisworldgen/dimension_type/")
.resolve(typeRef.substring(typeRef.indexOf(':') + 1) + ".json");
}
private static void deleteTree(Path root) throws IOException {
@@ -39,6 +39,21 @@ import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class ModdedForcedDatapackTest {
@Test
public void packScopedIdsCannotCollideAndHaveReadableLabels() {
String first = ModdedWorldgenIds.presetRef("overworld", "overworld");
String second = ModdedWorldgenIds.presetRef("other", "overworld");
assertFalse(first.equals(second));
assertEquals("IRIS:Overworld",
ModdedWorldgenIds.displayName(first.substring(first.indexOf(':') + 1)));
assertEquals("IRIS:Other / Overworld",
ModdedWorldgenIds.displayName(second.substring(second.indexOf(':') + 1)));
assertEquals("iris:overworld", ModdedWorldgenIds.generatorIdentity("overworld"));
assertEquals("iris:other/overworld",
ModdedWorldgenIds.generatorIdentity("other:overworld"));
}
@Test
public void scopesSharedCustomBiomeIdsByNamespace() {
Map<String, KSet<String>> seenBiomes = new LinkedHashMap<>();
@@ -60,16 +60,15 @@ public class ModdedLifecycleFailureContractTest {
}
@Test
public void persistentReinjectionRethrowsTheOriginalCause() throws IOException {
public void persistentReinjectionQuarantinesBrokenEntriesAndContinues() throws IOException {
String source = source("ModdedStartup.java");
String reinjection = method(source, "private static void reinjectPersistentDimensions(");
String failure = catchBlock(reinjection);
assertTrue(failure.contains("LOGGER.error("));
assertFalse(failure.contains("e.toString()"));
assertFalse(failure.contains("continue;"));
assertTrue(failure.contains("throw new IllegalStateException("));
assertTrue(failure.contains(", e);"));
assertFalse(failure.contains("throw new IllegalStateException("));
assertTrue(reinjection.contains("injected++;"));
}
@Test
@@ -0,0 +1,84 @@
package art.arcane.iris.modded.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode;
import net.minecraft.SharedConstants;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.Bootstrap;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class IrisModdedCommandParityTest {
@Test
public void registersPluginParityWhatCommandsAndAliases() {
SharedConstants.tryDetectVersion();
Bootstrap.bootStrap();
CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
IrisModdedCommands.register(dispatcher);
CommandNode<CommandSourceStack> iris = child(dispatcher.getRoot(), "iris");
CommandNode<CommandSourceStack> what = child(iris, "what");
child(what, "here");
child(what, "biome");
child(what, "region");
child(what, "block");
child(what, "hand");
child(what, "markers");
child(iris, "dust");
child(iris, "d");
child(iris, "create");
child(iris, "c");
child(iris, "teleport");
child(iris, "tp");
child(iris, "height");
child(iris, "worlds");
child(iris, "accesslist");
CommandNode<CommandSourceStack> edit = child(iris, "edit");
child(edit, "b");
child(edit, "r");
child(edit, "d");
CommandNode<CommandSourceStack> studio = child(iris, "studio");
child(studio, "package");
child(studio, "pkg");
CommandNode<CommandSourceStack> download = child(iris, "download");
CommandNode<CommandSourceStack> pack = child(download, "pack");
child(pack, "force");
child(pack, "overwrite");
CommandNode<CommandSourceStack> branch = child(pack, "branch");
child(branch, "force");
child(branch, "overwrite");
assertSame(iris, child(dispatcher.getRoot(), "ir").getRedirect());
assertSame(iris, child(dispatcher.getRoot(), "irs").getRedirect());
}
@Test
public void helpDocumentsParityCommandsAndPlatformStubs() {
assertTrue(ModdedCommandHelp.documents("what", "here"));
assertTrue(ModdedCommandHelp.documents("what", "biome"));
assertTrue(ModdedCommandHelp.documents("what", "region"));
assertTrue(ModdedCommandHelp.documents("what", "block"));
assertTrue(ModdedCommandHelp.documents("what", "hand"));
assertTrue(ModdedCommandHelp.documents("what", "markers"));
assertTrue(ModdedCommandHelp.documents("", "dust"));
assertTrue(ModdedCommandHelp.documents("", "teleport"));
assertTrue(ModdedCommandHelp.documents("", "c"));
assertTrue(ModdedCommandHelp.documents("edit", "b"));
assertTrue(ModdedCommandHelp.documents("studio", "pkg"));
assertTrue(ModdedCommandHelp.documents("object", "we"));
assertTrue(ModdedCommandHelp.documents("world", "mainworld"));
}
private static CommandNode<CommandSourceStack> child(
CommandNode<CommandSourceStack> parent, String name) {
CommandNode<CommandSourceStack> child = parent.getChild(name);
assertNotNull(name, child);
return child;
}
}
@@ -25,7 +25,7 @@ public class IrisModdedStructureCommandTest {
assertTrue(source.contains("combineStructureKeys(irisKeys, nativeKeys)"));
assertTrue(source.contains("irisGenerator.isNativeStructureReachable(holder)"));
assertTrue(source.contains("LocateStatus.SEARCH_LIMIT_REACHED"));
assertTrue(source.contains("the density search safety limit was reached"));
assertTrue(source.contains("IRIS_MODDED_COMMANDS_UNABLE_LOCATE_IRIS_PLACED_STRUCTURE_DENSITY_SEARCH_SAFETY_LIMIT_WAS"));
assertTrue(source.contains("int targetX = result.originX()"));
assertTrue(source.contains("int targetY = result.baseY() + 2"));
assertTrue(source.contains("int targetZ = result.originZ()"));
@@ -0,0 +1,60 @@
package art.arcane.iris.modded.command;
import net.minecraft.core.BlockPos;
import org.junit.Test;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ModdedDustRevealerTest {
@Test
public void placementClassificationCoversObjectDecorationAndTerrain() {
assertTrue(ModdedDustRevealer.placementLine(3, 10, 13, "tree")
.contains("object/stilt 'tree'"));
assertTrue(ModdedDustRevealer.placementLine(3, 10, 13, null)
.contains("decoration/object/stilt"));
assertTrue(ModdedDustRevealer.placementLine(0, 10, 10, "ore")
.contains("buried object 'ore'"));
assertTrue(ModdedDustRevealer.placementLine(-4, 10, 6, null)
.contains("depth 4"));
}
@Test
public void revealTraversalUsesDiagonalAdjacencyButNotDisconnectedBlocks() {
Set<BlockPos> object = Set.of(
new BlockPos(0, 0, 0),
new BlockPos(1, 1, 1),
new BlockPos(3, 3, 3));
List<BlockPos> hits = ModdedDustRevealer.collect(
new BlockPos(0, 0, 0),
"object",
-64,
-64,
320,
new AtomicBoolean(),
(int x, int relativeY, int z) ->
object.contains(new BlockPos(x, relativeY - 64, z))
? "object"
: null);
assertEquals(List.of(new BlockPos(0, 0, 0), new BlockPos(1, 1, 1)), hits);
}
@Test
public void cancelledRevealDoesNoTraversal() {
List<BlockPos> hits = ModdedDustRevealer.collect(
new BlockPos(0, 0, 0),
"object",
-64,
-64,
320,
new AtomicBoolean(true),
(int x, int relativeY, int z) -> "object");
assertTrue(hits.isEmpty());
}
}