Patching Cleanup

This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-11 00:38:08 -04:00
1 parent bf12f30d26
commit 29a31a69e0
44 files changed
+1340 -970

No files matched your search

@@ -64,8 +64,27 @@ public class PackCompatReportTest {
public void findingLineAndDedupKey() {
CompatFinding finding = finding(CompatAction.EXCLUDED, "cave/sulfur", "layers[0].palette[1]");
assertEquals("minecraft:sulfur (block): excluded Biome cave/sulfur at layers[0].palette[1]", finding.line());
assertEquals("excluded Biome cave/sulfur at layers[0].palette[1]", finding.subjectLine());
assertEquals("BLOCK:minecraft:sulfur|EXCLUDED|Biome|cave/sulfur", finding.dedupKey());
CompatFinding blank = new CompatFinding(CompatRegistry.ENTITY, "minecraft:camel", CompatAction.DROPPED, null, null, null);
assertEquals("minecraft:camel (entity): dropped", blank.line());
assertEquals("dropped", blank.subjectLine());
}
@Test
public void findingRendersEachOptionalSubjectFieldIndependently() {
CompatFinding typeOnly = new CompatFinding(
CompatRegistry.BLOCK, "minecraft:sulfur", CompatAction.EXCLUDED, "Biome", "", "");
CompatFinding keyOnly = new CompatFinding(
CompatRegistry.BLOCK, "minecraft:sulfur", CompatAction.EXCLUDED, "", "cave/sulfur", "");
CompatFinding detailOnly = new CompatFinding(
CompatRegistry.BLOCK, "minecraft:sulfur", CompatAction.EXCLUDED, "", "", "layers[0]");
assertEquals("excluded Biome", typeOnly.subjectLine());
assertEquals("excluded cave/sulfur", keyOnly.subjectLine());
assertEquals("excluded at layers[0]", detailOnly.subjectLine());
assertEquals("minecraft:sulfur (block): excluded Biome", typeOnly.line());
assertEquals("minecraft:sulfur (block): excluded cave/sulfur", keyOnly.line());
assertEquals("minecraft:sulfur (block): excluded at layers[0]", detailOnly.line());
}
}
@@ -16,6 +16,9 @@ import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -77,4 +80,29 @@ public class IrisDataAuthoringCacheTest {
assertEquals(3.0, retained.getZoom(), 0.0);
assertEquals("{\"zoom\":3.0}", Files.readString(epochRoot.resolve("generators/sample.json")));
}
@Test
public void resourceKeyDiscoveryPreservesNestedNamesAndCachedArrays() throws Exception {
Path root = temporary.newFolder("resource-keys").toPath();
for (String name : List.of(
"generators/plain.json", "generators/nested.json/ridge.json.alt.json", "generators/ignored.JSON",
"images/plain.png", "images/nested.png/ridge.png.alt.png", "images/ignored.PNG",
"matter/plain.mat", "matter/nested.mat/ridge.mat.alt.mat", "matter/ignored.MAT")) {
Path file = root.resolve(name);
Files.createDirectories(file.getParent());
Files.write(file, new byte[0]);
}
source = IrisData.get(root.toFile());
Map<ResourceLoader<?>, Set<String>> expected = Map.of(
source.getGeneratorLoader(), Set.of("plain", "nested/ridge.alt"),
source.getImageLoader(), Set.of("plain", "nested.png/ridge.alt"),
source.getMatterLoader(), Set.of("plain", "nested.mat/ridge.alt"));
for (Map.Entry<ResourceLoader<?>, Set<String>> entry : expected.entrySet()) {
String[] keys = entry.getKey().getPossibleKeys();
assertEquals(entry.getValue(), Set.of(keys));
assertEquals(entry.getValue().size(), keys.length);
assertSame(keys, entry.getKey().getPossibleKeys());
}
}
}
@@ -703,6 +703,33 @@ public class StructureTransactionWriterTest {
assertFalse(Files.exists(transactionRoot(root, token.transactionId())));
}
@Test
public void preparedRemovalRejectsMissingAndInvalidJournalsWithoutDeletingRecoveryData() throws IOException {
Path root = temporaryFolder.newFolder("owned-removal-invalid-journal").toPath();
StructureTransactionWriter writer = new StructureTransactionWriter(root);
StructureTransactionWriter.PreparedRemovalToken token =
new StructureTransactionWriter.PreparedRemovalToken(root, UUID.randomUUID());
Path transactionRoot = transactionRoot(token.packRoot(), token.transactionId());
Path journalPath = transactionRoot.resolve(StructureTransactionJournal.FILE_NAME);
Files.createDirectories(transactionRoot);
for (boolean commit : new boolean[]{false, true}) {
IOException failure = assertThrows(
IOException.class, () -> writer.resolvePreparedRemoval(token, commit));
assertEquals("Missing prepared removal journal at " + transactionRoot, failure.getMessage());
assertTrue(Files.isDirectory(transactionRoot));
}
Files.writeString(journalPath, "not-json", StandardCharsets.UTF_8);
for (boolean commit : new boolean[]{false, true}) {
IOException failure = assertThrows(
IOException.class, () -> writer.resolvePreparedRemoval(token, commit));
assertEquals("Invalid prepared removal journal at " + journalPath, failure.getMessage());
assertTrue(failure.getCause() instanceof RuntimeException);
assertEquals("not-json", Files.readString(journalPath, StandardCharsets.UTF_8));
}
}
@Test
public void symbolicLinkAncestorsCannotEscapeThePackRoot() throws IOException {
Path root = temporaryFolder.newFolder("symlink-pack").toPath();
@@ -0,0 +1,191 @@
package art.arcane.iris.engine.hydrology;
import art.arcane.iris.engine.hydrology.cave.CavePosition;
import art.arcane.iris.engine.hydrology.cave.CaveVoxel;
import art.arcane.iris.engine.hydrology.cave.CaveVoxelPrecondition;
import art.arcane.iris.engine.hydrology.cave.CaveVoxelView;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveAction;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveCandidate;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveFluidPolicy;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveGrottoShape;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveMode;
import art.arcane.iris.engine.hydrology.cave.HydrologyCavePlan;
import art.arcane.iris.engine.hydrology.cave.HydrologyCavePlannerSettings;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveRejection;
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveSource;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.OptionalLong;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
public class HydrologyCaveTerminalAlignmentTest {
private static final CavePosition SHARED = new CavePosition(0, 20, 0);
private static final List<HydrologyCaveAction> PRIORITY = List.of(
HydrologyCaveAction.FALLING_FLUID,
HydrologyCaveAction.WET_SOURCE,
HydrologyCaveAction.DRY_AIR,
HydrologyCaveAction.SEAL_GUARD
);
@Test
public void candidatesPreserveActionOrderAndExposureIdentityForEveryPriorityPair() {
HydrologyCaveCourseFilter filter = filter();
Map<Long, RiverCourse> courses = Map.of(1L, course(1L, 10L), 2L, course(2L, 10L));
for (int firstPriority = 0; firstPriority < PRIORITY.size(); firstPriority++) {
for (int secondPriority = 0; secondPriority < PRIORITY.size(); secondPriority++) {
HydrologyCaveCandidate first = candidate(1L, PRIORITY.get(firstPriority));
HydrologyCaveCandidate second = candidate(2L, PRIORITY.get(secondPriority));
ArrayList<HydrologyCaveCandidate> candidates = new ArrayList<>(List.of(first, second));
Set<HydrologyCaveCandidate> exposed = Collections.newSetFromMap(new IdentityHashMap<>());
exposed.add(first);
filter.alignSharedTerminalCandidateActions(candidates, courses, exposed);
HydrologyCaveAction expected = PRIORITY.get(Math.min(firstPriority, secondPriority));
assertEquals(expected, candidates.getFirst().actions().get(SHARED));
assertEquals(expected, candidates.getLast().actions().get(SHARED));
assertEquals(List.copyOf(first.actions().keySet()), List.copyOf(candidates.getFirst().actions().keySet()));
assertEquals(List.copyOf(second.actions().keySet()), List.copyOf(candidates.getLast().actions().keySet()));
assertEquals(PRIORITY.get(firstPriority), first.actions().get(SHARED));
assertEquals(PRIORITY.get(secondPriority), second.actions().get(SHARED));
assertEquals(1, exposed.size());
assertTrue(exposed.contains(candidates.getFirst()));
assertFalse(exposed.contains(candidates.getLast()));
if (firstPriority == secondPriority) {
assertSame(first, candidates.getFirst());
assertSame(second, candidates.getLast());
} else {
assertNotSame(first, candidates.getFirst());
assertNotSame(second, candidates.getLast());
assertFalse(exposed.contains(first));
}
}
}
}
@Test
public void plansPreserveActionOrderAndBaselineForEveryPriorityPair() {
HydrologyCaveCourseFilter filter = filter();
Map<Long, RiverCourse> courses = Map.of(1L, course(1L, 10L), 2L, course(2L, 10L));
for (int firstPriority = 0; firstPriority < PRIORITY.size(); firstPriority++) {
for (int secondPriority = 0; secondPriority < PRIORITY.size(); secondPriority++) {
HydrologyCaveCandidate firstCandidate = candidate(1L, PRIORITY.get(firstPriority));
HydrologyCaveCandidate secondCandidate = candidate(2L, PRIORITY.get(secondPriority));
HydrologyCavePlan first = plan(firstCandidate);
HydrologyCavePlan second = plan(secondCandidate);
List<HydrologyCavePlan> aligned = filter.alignSharedTerminalPlanActions(
List.of(first, second), List.of(firstCandidate, secondCandidate), courses);
HydrologyCaveAction expected = PRIORITY.get(Math.min(firstPriority, secondPriority));
assertEquals(expected, aligned.getFirst().actions().get(SHARED));
assertEquals(expected, aligned.getLast().actions().get(SHARED));
assertEquals(List.copyOf(first.actions().keySet()), List.copyOf(aligned.getFirst().actions().keySet()));
assertEquals(List.copyOf(second.actions().keySet()), List.copyOf(aligned.getLast().actions().keySet()));
assertEquals(first.baselinePreconditions(), aligned.getFirst().baselinePreconditions());
assertEquals(second.baselinePreconditions(), aligned.getLast().baselinePreconditions());
assertEquals(List.copyOf(first.baselinePreconditions().keySet()),
List.copyOf(aligned.getFirst().baselinePreconditions().keySet()));
assertEquals(List.copyOf(second.baselinePreconditions().keySet()),
List.copyOf(aligned.getLast().baselinePreconditions().keySet()));
assertEquals(PRIORITY.get(firstPriority), first.actions().get(SHARED));
assertEquals(PRIORITY.get(secondPriority), second.actions().get(SHARED));
if (firstPriority == secondPriority) {
assertSame(first, aligned.getFirst());
assertSame(second, aligned.getLast());
} else {
assertNotSame(first, aligned.getFirst());
assertNotSame(second, aligned.getLast());
}
}
}
}
@Test
public void unrelatedOutletsRetainCandidateIdentity() {
HydrologyCaveCandidate first = candidate(1L, HydrologyCaveAction.WET_SOURCE);
HydrologyCaveCandidate second = candidate(2L, HydrologyCaveAction.DRY_AIR);
ArrayList<HydrologyCaveCandidate> candidates = new ArrayList<>(List.of(first, second));
filter().alignSharedTerminalCandidateActions(candidates,
Map.of(1L, course(1L, 10L), 2L, course(2L, 20L)), Set.of());
assertSame(first, candidates.getFirst());
assertSame(second, candidates.getLast());
}
@Test
public void incompatibleOrRejectedPlansRetainIdentity() {
HydrologyCaveCandidate firstCandidate = candidate(1L, HydrologyCaveAction.WET_SOURCE);
HydrologyCaveCandidate secondCandidate = candidate(2L, HydrologyCaveAction.DRY_AIR);
HydrologyCaveCandidate incompatible = new HydrologyCaveCandidate(secondCandidate.source(), "lava",
secondCandidate.settings(), false, secondCandidate.actions(), secondCandidate.intentionalOpenings());
HydrologyCavePlan first = plan(firstCandidate);
HydrologyCavePlan second = plan(secondCandidate);
HydrologyCavePlan rejected = new HydrologyCavePlan(secondCandidate.source(), HydrologyCaveRejection.OPEN_SURFACE,
Map.of(), Map.of(), OptionalLong.empty());
Map<Long, RiverCourse> courses = Map.of(1L, course(1L, 10L), 2L, course(2L, 10L));
List<HydrologyCavePlan> incompatibleResult = filter().alignSharedTerminalPlanActions(
List.of(first, second), List.of(firstCandidate, incompatible), courses);
List<HydrologyCavePlan> rejectedResult = filter().alignSharedTerminalPlanActions(
List.of(first, rejected), List.of(firstCandidate, secondCandidate), courses);
assertSame(first, incompatibleResult.getFirst());
assertSame(second, incompatibleResult.getLast());
assertSame(first, rejectedResult.getFirst());
assertSame(rejected, rejectedResult.getLast());
}
private HydrologyCaveCourseFilter filter() {
return new HydrologyCaveCourseFilter(mock(CaveVoxelView.class),
new HydrologyCaveCourseFilter.Options(false, 8192, 8192));
}
private HydrologyCaveCandidate candidate(long id, HydrologyCaveAction sharedAction) {
CavePosition own = new CavePosition((int) id, 20, 0);
LinkedHashMap<CavePosition, HydrologyCaveAction> actions = new LinkedHashMap<>();
if (id == 2L) {
actions.put(SHARED, sharedAction);
}
actions.put(own, HydrologyCaveAction.DRY_AIR);
actions.put(SHARED, sharedAction);
return new HydrologyCaveCandidate(
new HydrologyCaveSource(id, SHARED, SHARED, 20, HydrologyCaveMode.GENERATED_GROTTO),
"water", new HydrologyCavePlannerSettings(8, 8, 32, 1, 1, 1, 1, 0,
HydrologyCaveFluidPolicy.REJECT_EXISTING, HydrologyCaveGrottoShape.ELLIPSOID, 8, 8),
false, actions, Set.of(own));
}
private HydrologyCavePlan plan(HydrologyCaveCandidate candidate) {
LinkedHashMap<CavePosition, CaveVoxelPrecondition> baseline = new LinkedHashMap<>();
for (CavePosition position : candidate.actions().keySet()) {
baseline.put(position, new CaveVoxelPrecondition(CaveVoxel.SOLID, false));
}
baseline.put(new CavePosition(-(int) candidate.source().sourceId(), 20, 0),
new CaveVoxelPrecondition(CaveVoxel.SOLID, false));
return new HydrologyCavePlan(candidate.source(), HydrologyCaveRejection.NONE, candidate.actions(),
baseline, OptionalLong.empty());
}
private RiverCourse course(long id, long outletId) {
HydraulicSegment segment = new HydraulicSegment(id, id, HydrologyFeatureType.UNDERGROUND_POOL,
20, 20, 2, 2, false, false, List.of(new HydrologyPoint(0, 20, 0)),
HydraulicChannelProfile.uniform(2, 2));
return new RiverCourse(id, RiverCourseType.UNDERGROUND, OptionalLong.of(id), OptionalLong.of(outletId),
"water", 1, List.of(), List.of(segment));
}
}
@@ -27,7 +27,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class IrisHydrologyRuntimeSettingsTest {
public class IrisHydrologySettingsCompilerTest {
@Test
@SuppressWarnings("unchecked")
public void regionalSurfaceControlsFingerprintAllScopesAndExpandSpacingReach() {
@@ -47,20 +47,20 @@ public class IrisHydrologyRuntimeSettingsTest {
when(biomes.loadAll(any(String[].class))).thenReturn(new KList<>(volcanic));
HydrologyPlannerSettings baseline = settings(dimension);
HydrologyPlannerSettings regional = IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> data);
HydrologyPlannerSettings regional = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> data);
assertEquals(HydrologyPlannerSettings.SurfacePolicyBounds.NONE, baseline.surfacePolicyBounds());
assertNotEquals(baseline.fingerprint(), regional.fingerprint());
assertEquals(384, regional.maximumSurfaceSourceSpacing());
volcanic.getRiverPolicy().setSurfaceSourceSpacing(1600);
HydrologyPlannerSettings widened = IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> data);
HydrologyPlannerSettings widened = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> data);
assertNotEquals(regional.fingerprint(), widened.fingerprint());
assertEquals(1600, widened.maximumSurfaceSourceSpacing());
assertTrue(widened.publicationRadius() >= 1600);
assertEquals(widened.fingerprint(), IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> data).fingerprint());
assertEquals(widened.fingerprint(), IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> data).fingerprint());
dimension.getRiverPolicy().setSurfaceInlandOutlets(7);
assertNotEquals(widened.fingerprint(), IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> data).fingerprint());
assertNotEquals(widened.fingerprint(), IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> data).fingerprint());
}
@Test
@@ -90,7 +90,7 @@ public class IrisHydrologyRuntimeSettingsTest {
IrisRiverRoutingConfig routing = new IrisRiverRoutingConfig()
.setTileSize(256);
assertEquals(128, IrisHydrologyRuntime.maximumDeepChannelLength(deepFluid, routing));
assertEquals(128, IrisHydrologySettingsCompiler.maximumDeepChannelLength(deepFluid, routing));
}
@Test
@@ -101,7 +101,7 @@ public class IrisHydrologyRuntimeSettingsTest {
IrisRiverRoutingConfig routing = new IrisRiverRoutingConfig()
.setTileSize(256);
assertEquals(0, IrisHydrologyRuntime.maximumDeepChannelLength(deepFluid, routing));
assertEquals(0, IrisHydrologySettingsCompiler.maximumDeepChannelLength(deepFluid, routing));
}
@Test
@@ -112,12 +112,12 @@ public class IrisHydrologyRuntimeSettingsTest {
rivers.getGrottos().getInland().setEnabled(true).setConnectSurfaceRivers(true);
rivers.getRouting().getInlandOutlets().add(IrisRiverInlandOutlet.SINKHOLE_GROTTO);
assertTrue(IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
assertTrue(IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.outlets().surfaceSinkholesEnabled());
rivers.getRouting().getInlandOutlets().clear();
assertFalse(IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
assertFalse(IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.outlets().surfaceSinkholesEnabled());
}
@@ -132,13 +132,13 @@ public class IrisHydrologyRuntimeSettingsTest {
rivers.getUnderground().getSources().setDensity(4.5D);
rivers.getRouting().setSampleSpacing(64);
assertEquals(5, IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
assertEquals(5, IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.surface().sources().maximumPerTile());
assertEquals(384, IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
assertEquals(384, IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.surface().sources().minimumSpacing());
assertEquals(5, IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
assertEquals(5, IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.underground().sources().maximumPerTile());
assertEquals(512, IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
assertEquals(512, IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.underground().sources().minimumSpacing());
}
@@ -173,7 +173,7 @@ public class IrisHydrologyRuntimeSettingsTest {
.setSlopePenalty(3D)
.setConfluenceAttraction(0.4D);
HydrologyPlannerSettings settings = IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null);
HydrologyPlannerSettings settings = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null);
HydrologyPlannerSettings.Banks banks = settings.surface().banks();
assertEquals(2, banks.sink());
@@ -220,8 +220,7 @@ public class IrisHydrologyRuntimeSettingsTest {
.setMaximumOutletsPerTile(2)
.setMaximumCoastalOutletsPerTile(5);
HydrologyPlannerSettings.Outlets outlets = IrisHydrologyRuntime
.createSettings(dimension, dimension.getHydrology(), () -> null)
HydrologyPlannerSettings.Outlets outlets = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.outlets();
assertEquals(2, outlets.maximumPerTile());
@@ -252,8 +251,7 @@ public class IrisHydrologyRuntimeSettingsTest {
.setBasinWidthRatio(2.1D)
.setMaximumBasinDepth(9);
HydrologyPlannerSettings.Geometry geometry = IrisHydrologyRuntime
.createSettings(dimension, dimension.getHydrology(), () -> null)
HydrologyPlannerSettings.Geometry geometry = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.geometry();
assertEquals(47, geometry.meanders().primaryWavelength());
@@ -284,12 +282,12 @@ public class IrisHydrologyRuntimeSettingsTest {
coastal.setEnabled(true);
coastal.getSeaCaves().setEnabled(true).setMaximumPerTile(5).setMinimumSpacing(200).setMinimumCoastHeight(9).setDepth(20);
HydrologyPlannerSettings.SeaCaves mapped = IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
HydrologyPlannerSettings.SeaCaves mapped = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.seaCaves();
assertEquals(HydrologyPlannerSettings.SeaCaves.of(true, 5, 200, 9, 20), mapped);
coastal.setEnabled(false);
HydrologyPlannerSettings.SeaCaves withoutCoastalGrottos = IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null)
HydrologyPlannerSettings.SeaCaves withoutCoastalGrottos = IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null)
.seaCaves();
assertFalse(withoutCoastalGrottos.enabled());
assertEquals(5, withoutCoastalGrottos.maximumPerTile());
@@ -297,7 +295,7 @@ public class IrisHydrologyRuntimeSettingsTest {
coastal.setEnabled(true);
coastal.getSeaCaves().setEnabled(false);
assertFalse(IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null).seaCaves().enabled());
assertFalse(IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null).seaCaves().enabled());
}
@Test
@@ -488,7 +486,7 @@ public class IrisHydrologyRuntimeSettingsTest {
IrisDimension dimension = new IrisDimension().setRegions(new KList<>("valley"));
dimension.getRiverPolicy().setShoreWidth(4D);
assertEquals(4D, IrisHydrologyRuntime.widestShoreBiomeWidth(dimension, () -> null, 1.5D), 0D);
assertEquals(4D, IrisHydrologySettingsCompiler.widestShoreBiomeWidth(dimension, () -> null, 1.5D), 0D);
assertEquals(4D, settings(dimension).widestShoreBiomeWidth(), 0D);
IrisRegion valley = new IrisRegion().setRiverPolicy(new IrisRiverPolicy().setShoreBiomeWidth(6D));
@@ -503,18 +501,18 @@ public class IrisHydrologyRuntimeSettingsTest {
when(biomeLoader.getPossibleKeys()).thenReturn(new String[]{"beach", "plain"});
when(biomeLoader.loadAll(any(String[].class))).thenReturn(new KList<>(beach, plain));
assertEquals(9D, IrisHydrologyRuntime.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
assertEquals(9D, IrisHydrologySettingsCompiler.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
beach.getRiverPolicy().setShoreWidth(null).setShoreBiomeWidth(11D);
assertEquals(11D, IrisHydrologyRuntime.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
assertEquals(11D, IrisHydrologySettingsCompiler.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
valley.getRiverPolicy().setShoreWidth(12D);
assertEquals(12D, IrisHydrologyRuntime.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
assertEquals(12D, IrisHydrologySettingsCompiler.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
dimension.getRiverPolicy().setShoreWidth(null);
valley.getRiverPolicy().setShoreWidth(null).setShoreBiomeWidth(null);
beach.getRiverPolicy().setShoreBiomeWidth(null);
assertEquals(1.5D, IrisHydrologyRuntime.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
assertEquals(1.5D, IrisHydrologySettingsCompiler.widestShoreBiomeWidth(dimension, () -> data, 1.5D), 0D);
}
@Test
@@ -537,6 +535,6 @@ public class IrisHydrologyRuntimeSettingsTest {
}
private static HydrologyPlannerSettings settings(IrisDimension dimension) {
return IrisHydrologyRuntime.createSettings(dimension, dimension.getHydrology(), () -> null);
return IrisHydrologySettingsCompiler.compile(dimension, dimension.getHydrology(), () -> null);
}
}
@@ -6,6 +6,39 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SurfaceNoiseTest {
@Test
public void scalarBitsPreserveChannelGeometry() {
long[][] samples = {
{0L, 0, 0, 1, 0x3fc9ff45ea7ce2bcL, 0xbfe3005d0ac18ea2L},
{77L, -40, 39, 1, 0x3fe1608c5d9f966eL, 0x3fb608c5d9f966e0L},
{77L, -40, 39, 2, 0x3fd12fd3b2255266L, 0xbfdda0589bb55b34L},
{77L, -40, 39, 3, 0x3fde59c9633f9d3eL, 0xbfaa6369cc062c20L},
{77L, -40, 39, 7, 0x3febee1ee702b638L, 0x3fe7dc3dce056c70L},
{77L, -40, 39, 12, 0x3fe58a3d8c6a3a26L, 0x3fd628f631a8e898L},
{77L, -40, 39, 16, 0x3fe379956dd75dfbL, 0x3fcbccab6ebaefd8L},
{77L, -40, 39, 31, 0x3fdd9757689aa0dcL, 0xbfb34544bb2af920L},
{77L, -40, 39, 64, 0x3fe0968a66559de7L, 0x3fa2d14ccab3bce0L},
{0L, -12, -12, 12, 0x3fa2ed0fbd6e4760L, 0xbfeda25e08523714L},
{0L, -13, -11, 12, 0x3fabab89552088a4L, 0xbfec8a8ed55beeecL},
{-1L, 12, -12, 12, 0x3fc3b99ed5ce495cL, 0xbfe623309518db52L},
{Long.MIN_VALUE, -1, 1, 31, 0x3fe213950b5ed096L, 0x3fc09ca85af684b0L},
{Long.MAX_VALUE, 255, -257, 256, 0x3fcb1a5a870174baL, 0xbfe272d2bc7f45a3L},
{1337L, -12345, 67890, 8192, 0x3fd4e8d04021f6aaL, 0xbfd62e5f7fbc12acL},
{1337L, Integer.MIN_VALUE, Integer.MAX_VALUE, 1, 0x3fdc5d75fb3dcf0cL, 0xbfbd1450261187a0L},
{1337L, Integer.MIN_VALUE, Integer.MAX_VALUE, 12, 0x3feb8585bd4cd270L, 0x3fe70b0b7a99a4e0L},
{1337L, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, 0x3fed6ff84c27d2e8L, 0x3feadff0984fa5d0L}
};
for (long[] sample : samples) {
long seed = sample[0];
int x = (int) sample[1];
int z = (int) sample[2];
int wavelength = (int) sample[3];
String context = "seed=" + seed + ", x=" + x + ", z=" + z + ", wavelength=" + wavelength;
assertEquals(context, sample[4], Double.doubleToLongBits(SurfaceNoise.value(seed, x, z, wavelength)));
assertEquals(context, sample[5], Double.doubleToLongBits(SurfaceNoise.signed(seed, x, z, wavelength)));
}
}
@Test
public void valuesStayInRangeAndAreDeterministic() {
for (int x = -40; x < 40; x++) {
@@ -2,12 +2,15 @@ package art.arcane.iris.engine.object;
import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.iris.util.common.math.IrisBlockVector;
import art.arcane.volmlib.util.collection.KMap;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@@ -51,6 +54,39 @@ public class IrisObjectIoWriteLimitsTest {
return object;
}
@Test
public void preservesV2HeaderSignedCoordinatesAndTilePayload() throws IOException {
IrisObject object = new IrisObject(7, 9, 11);
object.blocks.put(new IrisBlockVector(-3, 2, -1), state("minecraft:chest"));
KMap<String, Object> properties = new KMap<>();
properties.put("marker", "stored");
object.states.put(new IrisBlockVector(-3, 2, -1), new TileData("minecraft:chest", properties));
ByteArrayOutputStream encoded = new ByteArrayOutputStream();
IrisObjectIO.write(object, encoded);
try (DataInputStream input = new DataInputStream(new ByteArrayInputStream(encoded.toByteArray()))) {
assertEquals(7, input.readInt());
assertEquals(9, input.readInt());
assertEquals(11, input.readInt());
assertEquals("Iris V2 IOB;", input.readUTF());
assertEquals(1, input.readShort());
assertEquals("minecraft:chest", input.readUTF());
assertEquals(1, input.readInt());
assertEquals(-3, input.readShort());
assertEquals(2, input.readShort());
assertEquals(-1, input.readShort());
assertEquals(0, input.readShort());
assertEquals(1, input.readInt());
assertEquals(-3, input.readShort());
assertEquals(2, input.readShort());
assertEquals(-1, input.readShort());
assertEquals("minecraft:chest", input.readUTF());
assertEquals("{\"marker\":\"stored\"}", input.readUTF());
assertEquals(-1, input.read());
}
}
@Test
public void rejectsPaletteOverflowInsteadOfWrappingTheShort() {
IrisObject object = oversizedPaletteObject;
@@ -0,0 +1,36 @@
package art.arcane.iris.platform;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
public class BlockStateKeyTest {
@Test
public void namespaceIgnoresPropertyValues() {
assertEquals("minecraft", BlockStateKey.namespace("stone"));
assertEquals("minecraft", BlockStateKey.namespace("stone[variant=custom:stone]"));
assertEquals("custom", BlockStateKey.namespace("custom:stone[variant=minecraft:stone]"));
assertEquals("", BlockStateKey.namespace(":stone"));
}
@Test
public void addsAndReplacesPropertiesInEncounterOrder() {
assertEquals("minecraft:stairs[facing=east]",
BlockStateKey.withProperty("minecraft:stairs", "facing", "east"));
assertEquals("minecraft:stairs[facing=east,half=top]",
BlockStateKey.withProperty("minecraft:stairs[facing=north,half=top]", "facing", "east"));
assertEquals("minecraft:stairs[facing=north,half=top,waterlogged=true]",
BlockStateKey.withProperty("minecraft:stairs[facing=north,half=top]", "waterlogged", "true"));
}
@Test
public void retainsDuplicateAndMalformedEntryHandling() {
assertEquals("custom:block[a=last,b=left=right,c=value]",
BlockStateKey.withProperty("custom:block[ a = first ,invalid,b=left=right,a=last]", "c", "value"));
assertEquals("stone[x=y]", BlockStateKey.withProperty("stone[]", "x", "y"));
assertThrows(StringIndexOutOfBoundsException.class,
() -> BlockStateKey.withProperty("stone[x=y", "x", "z"));
assertThrows(NullPointerException.class, () -> BlockStateKey.namespace(null));
}
}