Skip to content

Commit

Permalink
Update gametest
Browse files Browse the repository at this point in the history
  • Loading branch information
IThundxr committed Aug 24, 2024
1 parent c4c0cd8 commit ddec7f6
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
import java.util.stream.Stream;
Expand All @@ -19,7 +18,7 @@
import com.google.gson.JsonPrimitive;

import io.github.fabricators_of_create.porting_lib.gametest.infrastructure.CustomGameTestHelper;
//import io.github.fabricators_of_create.porting_lib.gametest.infrastructure.ExtendedTestFunction;
import io.github.fabricators_of_create.porting_lib.gametest.infrastructure.ExtendedTestFunction;
import io.github.fabricators_of_create.porting_lib.gametest.infrastructure.GameTestGroup;
import io.github.fabricators_of_create.porting_lib.gametest.quickexport.AreaSelectorItem;
import io.github.fabricators_of_create.porting_lib.gametest.quickexport.QuickExportCommand;
Expand Down Expand Up @@ -51,15 +50,13 @@ public void onInitialize() {
* of {@link CustomGameTestHelper} and {@link GameTestGroup}.
*/
public static Collection<TestFunction> getTestsFrom(Class<?>... classes) {
return Collections.emptyList();
// fixme port me :plead:
// return Stream.of(classes)
// .map(Class::getDeclaredMethods)
// .flatMap(Stream::of)
// .map(ExtendedTestFunction::of)
// .filter(Objects::nonNull)
// .sorted(Comparator.comparing(TestFunction::testName))
// .toList();
return Stream.of(classes)
.map(Class::getDeclaredMethods)
.flatMap(Stream::of)
.map(ExtendedTestFunction::of)
.filter(Objects::nonNull)
.sorted(Comparator.comparing(TestFunction::testName))
.toList();
}

private static boolean checkEnabled() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package io.github.fabricators_of_create.porting_lib.gametest.infrastructure;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;

import org.jetbrains.annotations.ApiStatus.Internal;
import org.jetbrains.annotations.NotNull;
Expand All @@ -19,134 +17,105 @@
import net.minecraft.gametest.framework.GameTest;
import net.minecraft.gametest.framework.GameTestGenerator;
import net.minecraft.gametest.framework.GameTestHelper;
import net.minecraft.gametest.framework.GameTestInfo;
import net.minecraft.gametest.framework.StructureUtils;
import net.minecraft.gametest.framework.TestFunction;
import net.minecraft.world.level.block.Rotation;

// fixme port me :plead:
///**
// * An extension to game tests implementing functionality for {@link CustomGameTestHelper} and {@link GameTestGroup}.
// * To use, create a {@link GameTestGenerator} that provides tests using {@link PortingLibGameTest#getTestsFrom(Class[])}.
// */
//public class ExtendedTestFunction extends TestFunction {
// @Internal
// public static final Map<String, ExtendedTestFunction> NAMES_TO_FUNCTIONS = new HashMap<>();
//
// public final String fullyQualifiedName;
// public final String simpleName;
// private final UnaryOperator<GameTestHelper> helperProcessor;
//
// protected ExtendedTestFunction(String fullyQualifiedName, String simpleName, UnaryOperator<GameTestHelper> helperProcessor, String pBatchName,
// String pTestName, String pStructureName, Rotation pRotation, int pMaxTicks, long pSetupTicks,
// boolean pRequired, int pRequiredSuccesses, int pMaxAttempts, Consumer<GameTestHelper> pFunction) {
// super(pBatchName, pTestName, pStructureName, pRotation, pMaxTicks, pSetupTicks, pRequired, pRequiredSuccesses, pMaxAttempts, pFunction);
// this.fullyQualifiedName = fullyQualifiedName;
// this.simpleName = simpleName;
// NAMES_TO_FUNCTIONS.put(fullyQualifiedName, this);
// this.helperProcessor = helperProcessor;
// }
//
// @Override
// @NotNull
// public String getTestName() {
// return simpleName;
// }
//
// @Nullable
// public static TestFunction of(Method method) {
// GameTest gt = method.getAnnotation(GameTest.class);
// if (gt == null) // skip non-test methods
// return null;
// Class<?> owner = method.getDeclaringClass();
// String qualifiedName = owner.getSimpleName() + "." + method.getName();
// CustomGameTestHelper customHelper = getCustomHelper(method, owner);
// validateTestMethod(method, gt, owner, customHelper, qualifiedName);
// UnaryOperator<GameTestHelper> helperProcessor = getHelperProcessor(customHelper);
//
// String structure = getStructure(gt, owner);
// Rotation rotation = StructureUtils.getRotationForRotationSteps(gt.rotationSteps());
//
// String fullName = owner.getName() + '.' + method.getName();
// String simpleName = owner.getSimpleName() + '.' + method.getName();
// return new ExtendedTestFunction(
// // use structure for test name since that's what MC fills structure blocks with for some reason
// fullName, simpleName, helperProcessor, gt.batch(), structure, structure, rotation, gt.timeoutTicks(),
// gt.setupTicks(), gt.required(), gt.requiredSuccesses(), gt.attempts(), asConsumer(method)
// );
// }
//
// private static void validateTestMethod(Method method, GameTest gt, Class<?> owner, CustomGameTestHelper customHelper, String qualifiedName) {
// if (gt.template().isEmpty())
// throw new IllegalArgumentException(qualifiedName + " must provide a template structure");
//
// int modifiers = method.getModifiers();
// if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers))
// throw new IllegalArgumentException(qualifiedName + " must be public and static");
//
// if (!Modifier.isPublic(owner.getModifiers()))
// throw new IllegalStateException(owner.getName() + " must be public");
//
// if (method.getReturnType() != void.class)
// throw new IllegalArgumentException(qualifiedName + " must return void");
//
// Class<? extends GameTestHelper> helperClass = customHelper != null ? customHelper.value() : GameTestHelper.class;
// if (method.getParameterCount() != 1 || method.getParameterTypes()[0] != helperClass)
// throw new IllegalArgumentException(qualifiedName + " must take 1 parameter of type " + helperClass.getSimpleName());
// }
//
// private static String getStructure(GameTest gt, Class<?> owner) {
// GameTestGroup group = owner.getAnnotation(GameTestGroup.class);
// String structure = gt.template();
// if (group == null || structure.contains(":")) // override group if a full ID
// return structure;
// String groupDir = group.path();
// String path = groupDir.isEmpty() ? structure : groupDir + '/' + structure;
// // namespace:gametest/path/structure || namespace:gametest/structure
// return group.namespace() + ":gametest/" + path;
// }
//
// private static CustomGameTestHelper getCustomHelper(Method method, Class<?> owner) {
// CustomGameTestHelper methodCustom = method.getAnnotation(CustomGameTestHelper.class);
// return methodCustom != null ? methodCustom : owner.getAnnotation(CustomGameTestHelper.class);
// }
//
// private static UnaryOperator<GameTestHelper> getHelperProcessor(CustomGameTestHelper custom) {
// if (custom == null)
// return helper -> helper;
// Class<? extends GameTestHelper> klass = custom.value();
// try {
// Constructor<? extends GameTestHelper> constructor = klass.getConstructor(GameTestInfo.class);
// constructor.setAccessible(true);
// return helper -> {
// try {
// GameTestHelper newHelper = constructor.newInstance(helper.testInfo);
// newHelper.finalCheckAdded = helper.finalCheckAdded;
// return newHelper;
// } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
// throw new RuntimeException(e);
// }
// };
// } catch (NoSuchMethodException e) {
// throw new RuntimeException(e);
// }
// }
//
// private static Consumer<GameTestHelper> asConsumer(Method method) {
// return (helper) -> {
// try {
// method.invoke(null, helper);
// } catch (IllegalAccessException | InvocationTargetException e) {
// throw new RuntimeException(e);
// }
// };
// }
//
// @Override
// public void run(@NotNull GameTestHelper helper) {
// // give structure block test info for runthis
// StructureBlockEntityExtensions be = (StructureBlockEntityExtensions) helper.getBlockEntity(BlockPos.ZERO);
// be.setQualifiedTestName(fullyQualifiedName);
// super.run(helperProcessor.apply(helper));
// }
//}
/**
* An extension to game tests implementing functionality for {@link CustomGameTestHelper} and {@link GameTestGroup}.
* To use, create a {@link GameTestGenerator} that provides tests using {@link PortingLibGameTest#getTestsFrom(Class[])}.
*/
public class ExtendedTestFunction {
@Internal
public static final Map<String, ExtendedTestFunction> NAMES_TO_FUNCTIONS = new HashMap<>();

public final String fullName;
public final String simpleName;
public final TestFunction testFunction;

protected ExtendedTestFunction(String fullName, String simpleName, String pBatchName,
String pStructureName, Rotation pRotation, int pMaxTicks, long pSetupTicks,
boolean pRequired, int pMaxAttempts, int pRequiredSuccesses, Consumer<GameTestHelper> pFunction) {
testFunction = new TestFunction(pBatchName, simpleName, pStructureName, pRotation, pMaxTicks, pSetupTicks, pRequired, false, pMaxAttempts, pRequiredSuccesses, true, pFunction);
this.fullName = fullName;
this.simpleName = simpleName;
NAMES_TO_FUNCTIONS.put(fullName, this);
}

@Nullable
public static TestFunction of(Method method) {
GameTest gt = method.getAnnotation(GameTest.class);
if (gt == null) // skip non-test methods
return null;
Class<?> owner = method.getDeclaringClass();
String qualifiedName = owner.getSimpleName() + "." + method.getName();
CustomGameTestHelper customHelper = getCustomHelper(method, owner);
validateTestMethod(method, gt, owner, customHelper, qualifiedName);

String structure = getStructure(gt, owner);
Rotation rotation = StructureUtils.getRotationForRotationSteps(gt.rotationSteps());

String fullName = owner.getName() + '.' + method.getName();
String simpleName = owner.getSimpleName() + '.' + method.getName();
return new ExtendedTestFunction(
// use structure for test name since that's what MC fills structure blocks with for some reason
fullName, simpleName, gt.batch(), structure, rotation, gt.timeoutTicks(), gt.setupTicks(),
gt.required(), gt.attempts(), gt.requiredSuccesses(), run(fullName, asConsumer(method))
).testFunction;
}

private static void validateTestMethod(Method method, GameTest gt, Class<?> owner, CustomGameTestHelper customHelper, String qualifiedName) {
if (gt.template().isEmpty())
throw new IllegalArgumentException(qualifiedName + " must provide a template structure");

int modifiers = method.getModifiers();
if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers))
throw new IllegalArgumentException(qualifiedName + " must be public and static");

if (!Modifier.isPublic(owner.getModifiers()))
throw new IllegalStateException(owner.getName() + " must be public");

if (method.getReturnType() != void.class)
throw new IllegalArgumentException(qualifiedName + " must return void");

Class<? extends GameTestHelper> helperClass = customHelper != null ? customHelper.value() : GameTestHelper.class;
if (method.getParameterCount() != 1 || method.getParameterTypes()[0] != helperClass)
throw new IllegalArgumentException(qualifiedName + " must take 1 parameter of type " + helperClass.getSimpleName());
}

private static String getStructure(GameTest gt, Class<?> owner) {
GameTestGroup group = owner.getAnnotation(GameTestGroup.class);
String structure = gt.template();
if (group == null || structure.contains(":")) // override group if a full ID
return structure;
String groupDir = group.path();
String path = groupDir.isEmpty() ? structure : groupDir + '/' + structure;
// namespace:gametest/path/structure || namespace:gametest/structure
return group.namespace() + ":gametest/" + path;
}

private static CustomGameTestHelper getCustomHelper(Method method, Class<?> owner) {
CustomGameTestHelper methodCustom = method.getAnnotation(CustomGameTestHelper.class);
return methodCustom != null ? methodCustom : owner.getAnnotation(CustomGameTestHelper.class);
}

private static Consumer<GameTestHelper> asConsumer(Method method) {
return (helper) -> {
try {
method.invoke(null, helper);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
};
}

public static Consumer<GameTestHelper> run(String fullName, @NotNull Consumer<GameTestHelper> helper) {
return consumer -> {
helper.andThen(gameTestHelper -> {
// give structure block test info
StructureBlockEntityExtensions be = (StructureBlockEntityExtensions) gameTestHelper.getBlockEntity(BlockPos.ZERO);
be.setQualifiedTestName(fullName);
}).accept(consumer);
};
}
}

0 comments on commit ddec7f6

Please sign in to comment.