From 44fb151828fc5bc7b7bdf72ba768ce084333528d Mon Sep 17 00:00:00 2001 From: Algent Date: Wed, 2 Sep 2026 00:28:11 +0200 Subject: [PATCH] test: characterize corner microblocks --- .../test/DefaultContentFunctionalTest.java | 55 ++++++ .../CornerMicroblockCharacterizationTest.java | 164 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 src/test/java/codechicken/microblock/CornerMicroblockCharacterizationTest.java diff --git a/src/functionalTest/java/codechicken/multipart/test/DefaultContentFunctionalTest.java b/src/functionalTest/java/codechicken/multipart/test/DefaultContentFunctionalTest.java index fd5a8dd..f59c8cc 100644 --- a/src/functionalTest/java/codechicken/multipart/test/DefaultContentFunctionalTest.java +++ b/src/functionalTest/java/codechicken/multipart/test/DefaultContentFunctionalTest.java @@ -23,7 +23,13 @@ import org.junit.jupiter.api.Test; import codechicken.lib.vec.Cuboid6; import codechicken.microblock.BlockMicroMaterial; import codechicken.microblock.CommonMicroClass; +import codechicken.microblock.CommonMicroblockClient; +import codechicken.microblock.CornerMicroClass; import codechicken.microblock.CornerMicroClass$; +import codechicken.microblock.CornerMicroblock; +import codechicken.microblock.CornerPlacement; +import codechicken.microblock.CornerPlacement$; +import codechicken.microblock.CornerPlacementGrid$; import codechicken.microblock.EdgeMicroClass$; import codechicken.microblock.FaceMicroClass; import codechicken.microblock.FaceMicroClass$; @@ -119,6 +125,48 @@ class DefaultContentFunctionalTest { } } + @Test + void keepsCornerFactoryPlacementAndAllFiftySixBounds() { + CornerMicroClass$ factory = CornerMicroClass$.MODULE$; + assertSame(factory, CornerPlacement$.MODULE$.microClass()); + assertSame(factory, CornerPlacement.microClass()); + assertSame(CornerPlacementGrid$.MODULE$, CornerPlacement$.MODULE$.placementGrid()); + assertSame(factory.aBounds(), CornerMicroClass.aBounds()); + assertEquals("mcr_cnr", factory.getName()); + assertEquals(CornerMicroblock.class, factory.baseTrait()); + assertEquals(CommonMicroblockClient.class, factory.clientTrait()); + assertEquals(7, factory.itemSlot()); + assertEquals(1f, factory.getResistanceFactor()); + + Cuboid6[] bounds = factory.aBounds(); + assertEquals(256, bounds.length); + int populated = 0; + for (int corner = 0; corner < 8; corner++) { + for (int size = 1; size < 8; size++) { + Cuboid6 expected = expectedCornerBounds(corner, size / 8d); + Cuboid6 actual = bounds[size << 4 | corner]; + assertCuboid(expected, actual); + populated++; + } + } + for (Cuboid6 bound : bounds) { + if (bound != null) { + populated--; + } + } + assertEquals(0, populated, "Only the 8 corners by 7 sizes may be populated"); + + Microblock generated = factory.create(false, 0); + assertTrue(generated instanceof CornerMicroblock); + for (int slot = 7; slot < 15; slot++) { + generated.setShape(3, slot); + CornerMicroblock corner = (CornerMicroblock) generated; + assertSame(bounds[3 << 4 | slot - 7], corner.getBounds()); + assertEquals(slot - 7, generated.getShape()); + assertEquals(slot, corner.getSlot()); + } + } + @Test void registersTheExactOrderedBuiltInMaterialsAndRemaps() throws Exception { List expectedNames = new ArrayList<>(); @@ -209,6 +257,13 @@ class DefaultContentFunctionalTest { } } + private static Cuboid6 expectedCornerBounds(int corner, double size) { + double minX = (corner & 4) == 0 ? 0 : 1 - size; + double minY = (corner & 1) == 0 ? 0 : 1 - size; + double minZ = (corner & 2) == 0 ? 0 : 1 - size; + return new Cuboid6(minX, minY, minZ, minX + size, minY + size, minZ + size); + } + private static void assertCuboid(Cuboid6 expected, Cuboid6 actual) { assertEquals(expected.min.x, actual.min.x, 1e-12); assertEquals(expected.min.y, actual.min.y, 1e-12); diff --git a/src/test/java/codechicken/microblock/CornerMicroblockCharacterizationTest.java b/src/test/java/codechicken/microblock/CornerMicroblockCharacterizationTest.java new file mode 100644 index 0000000..46dddb2 --- /dev/null +++ b/src/test/java/codechicken/microblock/CornerMicroblockCharacterizationTest.java @@ -0,0 +1,164 @@ +package codechicken.microblock; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; + +import org.junit.jupiter.api.Test; +import org.objectweb.asm.Type; + +import codechicken.lib.vec.Cuboid6; + +class CornerMicroblockCharacterizationTest { + + private static final Set PLACEMENT_FACADE_METHODS = signatures( + "customPlacement(Lcodechicken/microblock/MicroblockPlacement;)Lcodechicken/microblock/ExecutablePlacement;", + "expand(II)Z", + "microClass()Lcodechicken/microblock/CornerMicroClass$;", + "opposite(II)I", + "placementGrid()Lcodechicken/microblock/CornerPlacementGrid$;", + "sneakOpposite(II)Z"); + private static final Set PLACEMENT_COMPANION_METHODS = signatures( + "microClass()Lcodechicken/microblock/CornerMicroClass$;", + "microClass()Lcodechicken/microblock/MicroblockClass;", + "opposite(II)I", + "placementGrid()Lcodechicken/microblock/CornerPlacementGrid$;", + "placementGrid()Lcodechicken/microblock/PlacementGrid;"); + private static final Set CLASS_FACADE_METHODS = signatures( + "aBounds()[Lcodechicken/lib/vec/Cuboid6;", + "aBounds_$eq([Lcodechicken/lib/vec/Cuboid6;)V", + "baseTrait()Ljava/lang/Class;", + "baseTraitId()I", + "clientTrait()Ljava/lang/Class;", + "clientTraitId()I", + "create(ZI)Lcodechicken/microblock/Microblock;", + "createPart(Ljava/lang/String;Lcodechicken/lib/data/MCDataInput;)Lcodechicken/microblock/Microblock;", + "createPart(Ljava/lang/String;Lnet/minecraft/nbt/NBTTagCompound;)Lcodechicken/microblock/Microblock;", + "getClassId()I", + "getName()Ljava/lang/String;", + "getResistanceFactor()F", + "itemSlot()I", + "placementProperties()Lcodechicken/microblock/CornerPlacement$;", + "register()V", + "register(I)V"); + private static final Set CLASS_COMPANION_METHODS = signatures( + "aBounds()[Lcodechicken/lib/vec/Cuboid6;", + "aBounds_$eq([Lcodechicken/lib/vec/Cuboid6;)V", + "baseTrait()Ljava/lang/Class;", + "clientTrait()Ljava/lang/Class;", + "getName()Ljava/lang/String;", + "getResistanceFactor()F", + "itemSlot()I", + "placementProperties()Lcodechicken/microblock/CornerPlacement$;", + "placementProperties()Lcodechicken/microblock/PlacementProperties;"); + + @Test + void keepsFacadesCompanionsAndGeneratedTraitSurface() throws Exception { + assertFacade(CornerPlacement.class, PLACEMENT_FACADE_METHODS); + assertCompanion(CornerPlacement$.class, PlacementProperties.class, PLACEMENT_COMPANION_METHODS); + assertEquals(1, CornerPlacement$.class.getDeclaredFields().length); + + assertFacade(CornerMicroClass.class, CLASS_FACADE_METHODS); + assertCompanion(CornerMicroClass$.class, CommonMicroClass.class, CLASS_COMPANION_METHODS); + Field bounds = CornerMicroClass$.class.getDeclaredField("aBounds"); + assertSame(Cuboid6[].class, bounds.getType()); + assertTrue(Modifier.isPrivate(bounds.getModifiers())); + assertFalse(Modifier.isFinal(bounds.getModifiers())); + assertEquals(2, CornerMicroClass$.class.getDeclaredFields().length); + + assertTrait( + CornerMicroblock.class, + new Class[] { CommonMicroblock.class }, + signatures( + "getBounds()Lcodechicken/lib/vec/Cuboid6;", + "getSlot()I", + "microClass()Lcodechicken/microblock/CornerMicroClass$;", + "setShape(II)V")); + assertHelper( + "codechicken.microblock.CornerMicroblock$class", + signatures( + "$init$(Lcodechicken/microblock/CornerMicroblock;)V", + "getBounds(Lcodechicken/microblock/CornerMicroblock;)Lcodechicken/lib/vec/Cuboid6;", + "getSlot(Lcodechicken/microblock/CornerMicroblock;)I", + "microClass(Lcodechicken/microblock/CornerMicroblock;)Lcodechicken/microblock/CornerMicroClass$;", + "setShape(Lcodechicken/microblock/CornerMicroblock;II)V")); + } + + @Test + void keepsCornerPlacementRulesAndGridIdentity() { + CornerPlacement$ placement = CornerPlacement$.MODULE$; + assertSame(CornerPlacementGrid$.MODULE$, placement.placementGrid()); + assertSame(CornerPlacementGrid$.MODULE$, CornerPlacement.placementGrid()); + assertNull(placement.customPlacement(null)); + assertNull(CornerPlacement.customPlacement(null)); + + for (int slot = 7; slot < 15; slot++) { + for (int side = 0; side < 6; side++) { + int opposite = ((slot - 7) ^ (1 << (side >> 1))) + 7; + assertEquals(opposite, placement.opposite(slot, side)); + assertEquals(opposite, CornerPlacement.opposite(slot, side)); + assertTrue(placement.sneakOpposite(slot, side)); + assertTrue(CornerPlacement.sneakOpposite(slot, side)); + assertTrue(placement.expand(slot, side)); + assertTrue(CornerPlacement.expand(slot, side)); + } + } + } + + private static void assertFacade(Class type, Set methods) { + assertTrue(Modifier.isPublic(type.getModifiers())); + assertTrue(Modifier.isFinal(type.getModifiers())); + assertSame(Object.class, type.getSuperclass()); + assertEquals(0, type.getDeclaredFields().length); + assertEquals(methods, publicDeclaredMethods(type)); + } + + private static void assertCompanion(Class type, Class superclass, Set methods) throws Exception { + assertTrue(Modifier.isPublic(type.getModifiers())); + assertTrue(Modifier.isFinal(type.getModifiers())); + assertSame(superclass, type.getSuperclass()); + assertEquals(methods, publicDeclaredMethods(type)); + Field module = type.getField("MODULE$"); + assertSame(type, module.getType()); + assertTrue(Modifier.isStatic(module.getModifiers())); + assertTrue(Modifier.isFinal(module.getModifiers())); + } + + private static void assertTrait(Class type, Class[] interfaces, Set methods) { + assertTrue(type.isInterface()); + assertArrayEquals(interfaces, type.getInterfaces()); + assertEquals(methods, publicDeclaredMethods(type)); + } + + private static void assertHelper(String name, Set methods) throws Exception { + Class type = Class.forName(name, false, CornerMicroblockCharacterizationTest.class.getClassLoader()); + assertTrue(Modifier.isPublic(type.getModifiers())); + assertTrue(Modifier.isAbstract(type.getModifiers())); + assertSame(Object.class, type.getSuperclass()); + assertEquals(methods, publicDeclaredMethods(type)); + } + + private static Set publicDeclaredMethods(Class type) { + Set methods = new TreeSet<>(); + for (Method method : type.getDeclaredMethods()) { + if (Modifier.isPublic(method.getModifiers())) { + methods.add(method.getName() + Type.getMethodDescriptor(method)); + } + } + return methods; + } + + private static Set signatures(String... signatures) { + return new TreeSet<>(Arrays.asList(signatures)); + } +}