diff options
author | miozune <miozune@gmail.com> | 2023-12-06 16:41:24 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-06 16:41:24 +0900 |
commit | b527397a391b0f95d066e53b891afa902cd38ca2 (patch) | |
tree | ec26f92d7c0eeef665cd429d8f459dc32c697791 | |
parent | 93a498be21d2dad69bfd036bd33f28e9eeb60e6e (diff) | |
download | GT5-Unofficial-b527397a391b0f95d066e53b891afa902cd38ca2.tar.gz GT5-Unofficial-b527397a391b0f95d066e53b891afa902cd38ca2.tar.bz2 GT5-Unofficial-b527397a391b0f95d066e53b891afa902cd38ca2.zip |
Add unit test for recipe search (#2394)
-rw-r--r-- | addon.gradle | 40 | ||||
-rw-r--r-- | dependencies.gradle | 6 | ||||
-rw-r--r-- | src/functionalTest/java/gregtech/test/GT5TestMod.java | 86 | ||||
-rw-r--r-- | src/functionalTest/java/gregtech/test/GTRecipeTest.java | 185 | ||||
-rw-r--r-- | src/functionalTest/resources/mcmod.info | 15 | ||||
-rw-r--r-- | src/test/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_TeleporterTest.java | 0 |
6 files changed, 332 insertions, 0 deletions
diff --git a/addon.gradle b/addon.gradle index edd0b173a3..f760bb1537 100644 --- a/addon.gradle +++ b/addon.gradle @@ -39,3 +39,43 @@ minecraft { injectedTags.put 'VERSION_PATCH', vPatch project.logger.log(logLevel, 'Using ({}, {}, {}) as NBT version', vMajor, vMinor, vPatch) } + +SourceSet functionalTestSet = null + +sourceSets { + functionalTestSet = create("functionalTest") { + java { + srcDir("src/functionalTest/java") + compileClasspath += sourceSets.patchedMc.output + sourceSets.main.output + } + } +} + +configurations { configs -> + // Keep all dependencies from the main mod in the functional test mod + named(functionalTestSet.compileClasspathConfigurationName).configure {it.extendsFrom(named("compileClasspath").get())} + named(functionalTestSet.runtimeClasspathConfigurationName).configure {it.extendsFrom(named("runtimeClasspath").get())} + named(functionalTestSet.annotationProcessorConfigurationName).configure {it.extendsFrom(named("annotationProcessor").get())} +} + +tasks.register(functionalTestSet.jarTaskName, Jar) { + from(functionalTestSet.output) + archiveClassifier.set("functionalTests") + // we don't care about the version number here, keep it stable to avoid polluting the tmp directory + archiveVersion.set("1.0") + destinationDirectory.set(new File(buildDir, "tmp")) +} +tasks.named("assemble").configure { + dependsOn(functionalTestSet.jarTaskName) +} + +// Run tests in the default runServer/runClient configurations +tasks.named("runServer", JavaExec).configure { + dependsOn(functionalTestSet.jarTaskName) + classpath(configurations.named(functionalTestSet.runtimeClasspathConfigurationName), tasks.named(functionalTestSet.jarTaskName)) +} + +tasks.named("runClient", JavaExec).configure { + dependsOn(functionalTestSet.jarTaskName) + classpath(configurations.named(functionalTestSet.runtimeClasspathConfigurationName), tasks.named(functionalTestSet.jarTaskName)) +} diff --git a/dependencies.gradle b/dependencies.gradle index 98319824e8..826bcf09d6 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -74,4 +74,10 @@ dependencies { testImplementation(platform('org.junit:junit-bom:5.9.2')) testImplementation('org.junit.jupiter:junit-jupiter') testImplementation("org.mockito:mockito-core:3.+") + + functionalTestImplementation(platform('org.junit:junit-bom:5.9.2')) + functionalTestImplementation('org.junit.jupiter:junit-jupiter') + functionalTestImplementation('org.junit.platform:junit-platform-engine') + functionalTestImplementation('org.junit.platform:junit-platform-launcher') + functionalTestImplementation('org.junit.platform:junit-platform-reporting') } diff --git a/src/functionalTest/java/gregtech/test/GT5TestMod.java b/src/functionalTest/java/gregtech/test/GT5TestMod.java new file mode 100644 index 0000000000..88029f641d --- /dev/null +++ b/src/functionalTest/java/gregtech/test/GT5TestMod.java @@ -0,0 +1,86 @@ +package gregtech.test; + +import java.io.File; +import java.io.PrintWriter; +import java.nio.file.FileSystems; +import java.nio.file.Path; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentText; + +import org.apache.commons.io.output.CloseShieldOutputStream; +import org.junit.platform.engine.discovery.DiscoverySelectors; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; +import org.junit.platform.reporting.legacy.xml.LegacyXmlReportGeneratingListener; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.event.FMLServerStartedEvent; + +@Mod(modid = "gt5-tests", name = "GT5 Dev Tests", version = "1.0", dependencies = "required-after:gregtech") +public class GT5TestMod { + + @Mod.EventHandler + public void onServerStarted(FMLServerStartedEvent event) { + MinecraftServer.getServer() + .addChatMessage(new ChatComponentText("Running GT5 unit tests...")); + runTests(); + MinecraftServer.getServer() + .addChatMessage(new ChatComponentText("Running GT5 unit tests finished")); + } + + private void runTests() { + // https://junit.org/junit5/docs/current/user-guide/#launcher-api + System.setProperty("junit.platform.reporting.open.xml.enabled", "false"); + final Path testsXmlOutDir = FileSystems.getDefault() + .getPath("./junit-out/") + .toAbsolutePath(); + final File testsXmlOutDirFile = testsXmlOutDir.toFile(); + testsXmlOutDirFile.mkdirs(); + { + File[] fileList = testsXmlOutDirFile.listFiles(); + if (fileList != null) { + for (File child : fileList) { + if (child.isFile() && child.getName() + .endsWith(".xml")) { + child.delete(); + } + } + } + } + final LauncherDiscoveryRequest discovery = LauncherDiscoveryRequestBuilder.request() + .selectors(DiscoverySelectors.selectPackage("gregtech.test")) + .build(); + final SummaryGeneratingListener summaryGenerator = new SummaryGeneratingListener(); + final TestExecutionSummary summary; + try (PrintWriter stderrWriter = new PrintWriter(new CloseShieldOutputStream(System.err), true)) { + final LegacyXmlReportGeneratingListener xmlGenerator = new LegacyXmlReportGeneratingListener( + testsXmlOutDir, + stderrWriter); + try (LauncherSession session = LauncherFactory.openSession()) { + final Launcher launcher = session.getLauncher(); + final TestPlan plan = launcher.discover(discovery); + launcher.registerTestExecutionListeners(summaryGenerator, xmlGenerator); + launcher.execute(plan); + } + summary = summaryGenerator.getSummary(); + + summary.printFailuresTo(stderrWriter, 32); + summary.printTo(stderrWriter); + stderrWriter.flush(); + } + // Throw an exception if running via `runServer` + if (summary.getTotalFailureCount() > 0 && FMLCommonHandler.instance() + .getSide() + .isServer()) { + throw new RuntimeException("Some of the unit tests failed to execute, check the log for details"); + } + } +} diff --git a/src/functionalTest/java/gregtech/test/GTRecipeTest.java b/src/functionalTest/java/gregtech/test/GTRecipeTest.java new file mode 100644 index 0000000000..cf9245dbec --- /dev/null +++ b/src/functionalTest/java/gregtech/test/GTRecipeTest.java @@ -0,0 +1,185 @@ +package gregtech.test; + +import static gregtech.api.enums.GT_Values.RA; +import static gregtech.api.enums.ItemList.Circuit_Advanced; +import static gregtech.api.enums.ItemList.Circuit_Nanoprocessor; +import static gregtech.api.enums.ItemList.Circuit_Parts_Crystal_Chip_Master; +import static gregtech.api.enums.ItemList.IC2_LapotronCrystal; +import static gregtech.api.enums.Materials.Advanced; +import static gregtech.api.enums.Materials.BlueTopaz; +import static gregtech.api.enums.Mods.GregTech; +import static gregtech.api.enums.OrePrefixes.circuit; +import static gregtech.api.enums.OrePrefixes.lens; +import static gregtech.api.util.GT_ModHandler.getModItem; +import static gregtech.api.util.GT_OreDictUnificator.get; +import static gregtech.api.util.GT_OreDictUnificator.isItemStackInstanceOf; +import static gregtech.api.util.GT_Utility.copyAmount; +import static net.minecraft.init.Blocks.chest; +import static net.minecraft.init.Blocks.iron_ore; +import static net.minecraft.init.Blocks.lapis_block; +import static net.minecraft.init.Blocks.log; +import static net.minecraft.init.Blocks.planks; +import static net.minecraft.init.Items.iron_ingot; +import static net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMapBuilder; +import gregtech.api.util.GT_Recipe; + +class GTRecipeTest { + + static RecipeMap<?> recipeMap; + static GT_Recipe lapotronChipRecipe; + + @BeforeAll + static void setup() { + recipeMap = RecipeMapBuilder.of("__test__") + .maxIO(9, 1, 1, 0) + .build(); + + RA.stdBuilder() + .itemInputs(new ItemStack(log, 2, WILDCARD_VALUE), new ItemStack(planks, 2, WILDCARD_VALUE)) + .itemOutputs(new ItemStack(chest, 1)) + .duration(0) + .eut(0) + .addTo(recipeMap); + + RA.stdBuilder() + .itemInputs(new ItemStack(lapis_block, 1), get(circuit, Advanced, 1)) + .itemOutputs(IC2_LapotronCrystal.get(1)) + .duration(0) + .eut(0) + .addTo(recipeMap); + + lapotronChipRecipe = RA.stdBuilder() + .itemInputs(IC2_LapotronCrystal.getWildcard(1), copyAmount(0, get(lens, BlueTopaz, 1))) + .itemOutputs(Circuit_Parts_Crystal_Chip_Master.get(3)) + .duration(0) + .eut(0) + .addTo(recipeMap) + .toArray(new GT_Recipe[0])[0]; + + RA.stdBuilder() + .itemInputs(getModItem(GregTech.ID, "gt.blockores", 1, 32)) + .itemOutputs(new ItemStack(iron_ingot, 1)) + .duration(0) + .eut(0) + .addTo(recipeMap); + } + + @Test + void ensureRecipesAdded() { + assertEquals( + recipeMap.getAllRecipes() + .size(), + 4); + } + + @Test + void findWithExactSameInputs() { + GT_Recipe recipe = recipeMap.findRecipeQuery() + .items(new ItemStack(lapis_block, 1), get(circuit, Advanced, 1)) + .find(); + assertNotNull(recipe); + } + + @Test + void findWildcardWithExactSameInputs() { + GT_Recipe chestRecipe = recipeMap.findRecipeQuery() + .items(new ItemStack(log, 2, WILDCARD_VALUE), new ItemStack(planks, 2, WILDCARD_VALUE)) + .find(); + assertNotNull(chestRecipe); + + GT_Recipe lapotronChipRecipe = recipeMap.findRecipeQuery() + .items(IC2_LapotronCrystal.getWildcard(1), copyAmount(0, get(lens, BlueTopaz, 1))) + .find(); + assertNotNull(lapotronChipRecipe); + } + + @Test + void findWildcardWithDifferentMeta() { + // https://github.com/GTNewHorizons/GT5-Unofficial/pull/2364/commits/e7112fce5f24431f3a4ad19288d662b93cbb91f2 + GT_Recipe recipe = recipeMap.findRecipeQuery() + .items(new ItemStack(log, 2, 0), new ItemStack(planks, 2, 1)) + .find(); + assertNotNull(recipe); + } + + @Test + void findWithNBT() { + // https://github.com/GTNewHorizons/GT5-Unofficial/pull/2364/commits/844a38662b05494b42a4439bbc0e6d4d7df1a683 + ItemStack lapisBlock = new ItemStack(lapis_block, 1); + NBTTagCompound tag = new NBTTagCompound(); + tag.setFloat("charge", 123456); + lapisBlock.stackTagCompound = tag; + GT_Recipe recipe = recipeMap.findRecipeQuery() + .items(lapisBlock, get(circuit, Advanced, 1)) + .find(); + assertNotNull(recipe); + } + + @Test + void rejectWithInsufficientAmount() { + GT_Recipe recipe = recipeMap.findRecipeQuery() + .items(new ItemStack(log, 1, 0), new ItemStack(planks, 1, 0)) + .find(); + assertNull(recipe); + } + + @Test + void rejectWithoutNonConsumable() { + // https://github.com/GTNewHorizons/GT5-Unofficial/pull/2364/commits/bfc93bff7ed34616021e8c5b6dbdc50dd7096af5 + GT_Recipe recipe = recipeMap.findRecipeQuery() + .items(IC2_LapotronCrystal.get(1)) + .cachedRecipe(lapotronChipRecipe) + .find(); + assertNull(recipe); + } + + @Test + void findOredicted() { + // https://github.com/GTNewHorizons/GT5-Unofficial/pull/2373 + assertTrue( + isItemStackInstanceOf(Circuit_Nanoprocessor.get(1), "circuitAdvanced"), + "Nanoprocessor is not registered as HV circuit"); + GT_Recipe recipeByNanoProcessor = recipeMap.findRecipeQuery() + .items(new ItemStack(lapis_block, 1), Circuit_Nanoprocessor.get(1)) + .find(); + assertNotNull(recipeByNanoProcessor); + + assertTrue( + isItemStackInstanceOf(Circuit_Advanced.get(1), "circuitAdvanced"), + "Processor Assembly is not registered as HV circuit"); + GT_Recipe recipeByCircuitAssembly = recipeMap.findRecipeQuery() + .items(new ItemStack(lapis_block, 1), Circuit_Advanced.get(1)) + .find(); + assertNotNull(recipeByCircuitAssembly); + } + + @Test + void findWithSpecificOreDictionary() { + // https://github.com/GTNewHorizons/GT5-Unofficial/pull/2379 + // We cannot use circuit assembling recipe like the issue mentioned above, + // as mUnificationTarget is not set for circuits in GT5. + // But it works in the same way; specific circuit -> GT ore block, unificated circuit -> vanilla ore block + GT_Recipe recipeCorrectOre = recipeMap.findRecipeQuery() + .items(getModItem(GregTech.ID, "gt.blockores", 1, 32)) + .find(); + assertNotNull(recipeCorrectOre); + + GT_Recipe recipeWrongOre = recipeMap.findRecipeQuery() + .items(new ItemStack(iron_ore, 1)) + .find(); + assertNull(recipeWrongOre); + } +} diff --git a/src/functionalTest/resources/mcmod.info b/src/functionalTest/resources/mcmod.info new file mode 100644 index 0000000000..393d6459cf --- /dev/null +++ b/src/functionalTest/resources/mcmod.info @@ -0,0 +1,15 @@ +[ + { + "modid":"GT5-tests", + "name":"GT5 Dev Tests", + "description":"GT5 Tests to run in the development environment", + "version":"1.0", + "mcversion":"1.7.10", + "url":"https://github.com/GTNewHorizons/GT5-Unofficial", + "updateUrl":"", + "authorList":[], + "credits":"", + "logoFile":"", + "screenshots":[] + } +] diff --git a/src/test/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_TeleporterTest.java b/src/test/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_TeleporterTest.java deleted file mode 100644 index e69de29bb2..0000000000 --- a/src/test/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_TeleporterTest.java +++ /dev/null |