Files
ForgeMultipart/src/test/java/codechicken/microblock/MicroMaterialRegistryBinaryCompatibilityTest.java
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

75 lines
3.1 KiB
Java
Raw Normal View History

2026-08-14 22:03:04 +02:00
package codechicken.microblock;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;
import java.util.Scanner;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial;
/**
* Loads a Scala class compiled against the reference dev jar. It reads MicroMaterialRegistry$.MODULE$ and calls the
* instance methods ProjRed links against, plus the scala.Tuple2 array getIdMap that extrautilities links against.
*
* Registration is global, so this registers its own uniquely named material and only asserts facts about it.
*/
class MicroMaterialRegistryBinaryCompatibilityTest {
private static final String NAME = "test:binarycompat";
@BeforeAll
static void register() {
// The other test class may already have registered the placeholder; re-registering would hit the error path.
if (MicroMaterialRegistry.getMaterial(MissingMicroMaterial.key()) == null) {
MicroMaterialRegistry.registerMaterial(MissingMicroMaterial$.MODULE$, MissingMicroMaterial.key());
}
if (MicroMaterialRegistry.getMaterial(NAME) == null) {
MicroMaterialRegistry.registerMaterial(MissingMicroMaterial$.MODULE$, NAME);
}
MicroMaterialRegistry$.MODULE$.setupIDMap();
}
@Test
void referenceScalaConsumerStillLinksAgainstTheSingletonAndIdMap() throws Exception {
Class<?> fixtureClass = new FixtureClassLoader(MicroMaterialRegistry.class.getClassLoader())
.define(loadFixture());
Object fixture = fixtureClass.getDeclaredConstructor().newInstance();
int id = (Integer) fixtureClass.getMethod("idOf", String.class).invoke(fixture, NAME);
assertEquals(NAME, fixtureClass.getMethod("nameOf", int.class).invoke(fixture, id));
Object material = fixtureClass.getMethod("materialAt", int.class).invoke(fixture, id);
assertSame(MicroMaterialRegistry.getMaterial(id), material);
assertSame(MicroMaterialRegistry.getMaterial(id), (IMicroMaterial) material);
// Reads the raw scala.Tuple2 array rather than the accessors.
assertEquals(NAME + "=true", fixtureClass.getMethod("idMapEntry", int.class).invoke(fixture, id));
}
private static byte[] loadFixture() {
InputStream input = Objects.requireNonNull(
MicroMaterialRegistryBinaryCompatibilityTest.class
.getResourceAsStream("/compat/ReferenceScalaMicroMaterialConsumer.class.b64"));
try (Scanner scanner = new Scanner(input, StandardCharsets.US_ASCII.name()).useDelimiter("\\A")) {
return Base64.getMimeDecoder().decode(scanner.next());
}
}
private static final class FixtureClassLoader extends ClassLoader {
private FixtureClassLoader(ClassLoader parent) {
super(parent);
}
private Class<?> define(byte[] bytecode) {
return defineClass(null, bytecode, 0, bytecode.length);
}
}
}