Skip to content

Commit b792593

Browse files
committed
Restructure our GameTests:
- Added the tests for transporters from (#7748) - Reduced the number of game test sourcesets to one, and allow it to access all the other mekanism modules - Make use of Neo's Game Test Framework as it is nicer to work with and will eventually allow us to validate the tests via GHA - Moved the run configs to using their own run folders
1 parent 2401c84 commit b792593

File tree

12 files changed

+640
-216
lines changed

12 files changed

+640
-216
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ out
88

99
Mekanism*.jar
1010
MDK.zip
11-
/run
12-
/runGameTests
11+
/runs
1312
/.gradle
1413
*.classpath
1514
*.project

build.gradle

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import groovy.json.JsonSlurper
66
import mekanism.MergeJars
77
import net.darkhax.curseforgegradle.TaskPublishCurseForge
88
import net.darkhax.curseforgegradle.UploadArtifact
9+
import net.neoforged.gradle.dsl.common.runs.run.Run
910

1011
import java.util.function.Consumer
1112

@@ -31,7 +32,7 @@ defaultTasks 'build'
3132
idea {
3233
module {
3334
//Exclude directories from being managed
34-
for (String excludeDirName in ["run", "runGameTests", "out", "logs", "gradle"]) {
35+
for (String excludeDirName in ["runs", "out", "logs", "gradle"]) {
3536
excludeDirs.add(new File(projectDir, excludeDirName))
3637
}
3738
//Tell IDEA to always download sources/javadoc artifacts from maven.
@@ -45,7 +46,7 @@ ext {
4546
"emi_version": emi_version_range]
4647
jsonPatterns = ["**/*.json", "**/*.mcmeta"]
4748
secondaryModules = ['additions', 'defense', 'generators', 'tools']
48-
extraTypes = ['datagen', 'gameTest']
49+
extraTypes = ['datagen']
4950
}
5051

5152
sourceSets {
@@ -74,6 +75,13 @@ sourceSets {
7475
compileClasspath += api.output
7576
runtimeClasspath += api.output
7677
}
78+
gameTest {
79+
runs {
80+
modIdentifier = "mekanismtests"
81+
}
82+
compileClasspath += api.output
83+
runtimeClasspath += api.output
84+
}
7785
}
7886

7987
configurations {
@@ -82,6 +90,7 @@ configurations {
8290

8391
//Add all extra source sets that the main sourceSet should have
8492
setupExtraSourceSets(sourceSets.main)
93+
setupExtraSourceSets(sourceSets.gameTest, false)
8594

8695
configurations {
8796
//Make sure all our sub source set stuff extends the proper base methods so that
@@ -115,10 +124,14 @@ for (String name : secondaryModules) {
115124
//Setup the UPDATE_SOURCESET property in case we are doing any remappings
116125
project.ext."UPDATE_SOURCESETS" = project.sourceSets.collect { it.name }.join(';')
117126

118-
def setupExtraSourceSets(SourceSet base) {
127+
def setupExtraSourceSets(SourceSet base, boolean includeExtra = true) {
119128
//Expose the base module to junit
120129
project.sourceSets.test.compileClasspath += base.output
121130
project.sourceSets.test.runtimeClasspath += base.output
131+
if (base != project.sourceSets.gameTest) {
132+
project.sourceSets.gameTest.compileClasspath += base.output
133+
project.sourceSets.gameTest.runtimeClasspath += base.output
134+
}
122135
//Setup and extend configurations for alternate modules. First by making the implementation, compileOnly, runtimeOnly equivalents
123136
// for those modules extend the main ones
124137
def baseImplementation = project.configurations.maybeCreate(base.getTaskName(null, "implementation"))
@@ -130,19 +143,21 @@ def setupExtraSourceSets(SourceSet base) {
130143
baseCompileOnly.extendsFrom(project.configurations.getByName("compileOnly"))
131144
baseRuntimeOnly.extendsFrom(project.configurations.getByName("runtimeOnly"))
132145
}
133-
//And then setup and have all the extra sourceSets have their configurations extend the ones for the base module so that they can
134-
// properly access the dependency
135-
for (String extraType : extraTypes) {
136-
//Setup a source set in extraType/$name
137-
def extraSourceSet = setupExtraSourceSet(base, extraType)
138-
//And then setup the configurations for it
139-
def implExtends = [baseImplementation]
140-
if (extraType == 'datagen') {
141-
implExtends.add(project.configurations.getByName("datagenNonMod"))
146+
if (includeExtra) {
147+
//And then setup and have all the extra sourceSets have their configurations extend the ones for the base module so that they can
148+
// properly access the dependency
149+
for (String extraType : extraTypes) {
150+
//Setup a source set in extraType/$name
151+
def extraSourceSet = setupExtraSourceSet(base, extraType)
152+
//And then setup the configurations for it
153+
def implExtends = [baseImplementation]
154+
if (extraType == 'datagen') {
155+
implExtends.add(project.configurations.getByName("datagenNonMod"))
156+
}
157+
project.configurations.maybeCreate(extraSourceSet.getTaskName(null, "implementation")).extendsFrom(*implExtends)
158+
project.configurations.maybeCreate(extraSourceSet.getTaskName(null, "compileOnly")).extendsFrom(baseCompileOnly)
159+
project.configurations.maybeCreate(extraSourceSet.getTaskName(null, "runtimeOnly")).extendsFrom(baseRuntimeOnly)
142160
}
143-
project.configurations.maybeCreate(extraSourceSet.getTaskName(null, "implementation")).extendsFrom(*implExtends)
144-
project.configurations.maybeCreate(extraSourceSet.getTaskName(null, "compileOnly")).extendsFrom(baseCompileOnly)
145-
project.configurations.maybeCreate(extraSourceSet.getTaskName(null, "runtimeOnly")).extendsFrom(baseRuntimeOnly)
146161
}
147162
}
148163

@@ -271,21 +286,36 @@ minecraft {
271286
file('src/additions/resources/META-INF/accesstransformer.cfg'),
272287
//Dev time only ATs so the file name doesn't have to match accesstransformer.cfg
273288
file('src/datagen/main/resources/META-INF/datagen_ats.cfg'),
274-
file('src/gameTest/main/resources/META-INF/gametest_ats.cfg')
289+
file('src/gameTest/resources/META-INF/gametest_ats.cfg')
275290
)
276291
}
277292
}
278293

279-
runs {
280-
configureEach { net.neoforged.gradle.dsl.common.runs.run.Run run ->
281-
run.workingDirectory(file("run"))
282-
283-
boolean supportsGameTests = !run.isDataGenerator.get()
284-
if (supportsGameTests) {
285-
//Specify all our mods as domains to look for game tests
286-
run.systemProperty('neoforge.enabledGameTestNamespaces', 'mekanism,mekanismadditions,mekanismdefense,mekanismgenerators,mekanismtools')
287-
}
294+
static void setupClientAcc(Run run) {
295+
//The below if statements are to add args to your gradle.properties file in user home
296+
// (DO NOT add them directly to the gradle.properties file for this project)
297+
// Setting the below properties allows use of your normal Minecraft account in the
298+
// dev environment including having your skin load. Each property also has a comment
299+
// explaining what information to set the value to/format it expects
300+
// One thing to note is because of the caching that goes on, after changing these
301+
// variables, you need to refresh the project and rerun genIntellijRuns/genEclipseRuns
302+
if (run.project.hasProperty('mc_uuid')) {
303+
//Your uuid without any dashes in the middle
304+
run.programArguments('--uuid', (String) run.project.property('mc_uuid'))
305+
}
306+
if (run.project.hasProperty('mc_username')) {
307+
//Your username/display name, this is the name that shows up in chat
308+
// Note: This is not your email, even if you have a Mojang account
309+
run.programArguments('--username', (String) run.project.property('mc_username'))
310+
}
311+
if (run.project.hasProperty('mc_accessToken')) {
312+
//Your access token, you can find it in your '.minecraft/launcher_accounts.json' file
313+
run.programArguments('--accessToken', (String) run.project.property('mc_accessToken'))
314+
}
315+
}
288316

317+
runs {
318+
configureEach { Run run ->
289319
if (run.project.hasProperty('forge_force_ansi')) {
290320
//Force ansi if declared as a gradle variable, as the auto detection doesn't detect IntelliJ properly
291321
// or eclipse's plugin that adds support for ansi escape in console
@@ -294,45 +324,16 @@ runs {
294324

295325
run.modSources(sourceSets.main, sourceSets.api)
296326

297-
if (supportsGameTests) {
298-
run.modSource(sourceSets.gameTestMain)
299-
}
300-
301327
for (String name : secondaryModules) {
302-
def base = sourceSets.getByName(name)
303-
run.modSource(base)
304-
if (supportsGameTests) {
305-
run.modSource(getExtraSourceSet(base, 'gameTest'))
306-
}
328+
run.modSource(sourceSets.getByName(name))
307329
}
308330

309331
//if the selected toolchain is a JBR, enable DCEVM
310332
if (run.project.javaToolchains.launcherFor(java.toolchain).map { it.metadata.vendor }.getOrElse("").contains("JetBrains")) {
311333
run.jvmArgument("-XX:+AllowEnhancedClassRedefinition")
312334
}
313335
}
314-
client {
315-
//The below if statements are to add args to your gradle.properties file in user home
316-
// (DO NOT add them directly to the gradle.properties file for this project)
317-
// Setting the below properties allows use of your normal Minecraft account in the
318-
// dev environment including having your skin load. Each property also has a comment
319-
// explaining what information to set the value to/format it expects
320-
// One thing to note is because of the caching that goes on, after changing these
321-
// variables, you need to refresh the project and rerun genIntellijRuns/genEclipseRuns
322-
if (project.hasProperty('mc_uuid')) {
323-
//Your uuid without any dashes in the middle
324-
programArguments('--uuid', (String) project.property('mc_uuid'))
325-
}
326-
if (project.hasProperty('mc_username')) {
327-
//Your username/display name, this is the name that shows up in chat
328-
// Note: This is not your email, even if you have a Mojang account
329-
programArguments('--username', (String) project.property('mc_username'))
330-
}
331-
if (project.hasProperty('mc_accessToken')) {
332-
//Your access token, you can find it in your '.minecraft/launcher_accounts.json' file
333-
programArguments('--accessToken', (String) project.property('mc_accessToken'))
334-
}
335-
}
336+
client { run -> setupClientAcc(run) }
336337
clientAlt {
337338
configure("client")
338339
if (!project.hasProperty('mc_username')) {
@@ -342,10 +343,14 @@ runs {
342343
}
343344
}
344345
server {
345-
programArgument('--nogui')
346346
}
347347
gameTestServer {
348-
workingDirectory(file("runGameTests"))
348+
modSource(sourceSets.gameTest)
349+
}
350+
gameTestClient { run ->
351+
configure("client")
352+
setupClientAcc(run)
353+
modSource(sourceSets.gameTest)
349354
}
350355
data {
351356
programArguments('--all', '--output', project.file('src/datagen/generated/').getAbsolutePath(),
@@ -413,6 +418,7 @@ dependencies {
413418
implementation project(":annotation-processor")
414419
annotationProcessor project(":annotation-processor")
415420

421+
gameTestImplementation "net.neoforged:testframework:${forge_version}"
416422
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_version}"
417423
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit_version}"
418424
//We use https://github.com/quicktheories/QuickTheories to allow for implementing property based testing

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ minecraft_version=1.20.4
88
previous_minecraft_version=1.20.1
99
previous_minor_minecraft_version=1.20.2
1010
loader_version_range=[2,)
11-
forge_version=20.4.223
11+
forge_version=20.4.231
1212
mod_version=10.5.19
1313
#This determines the minimum version of forge required to use Mekanism
1414
# Only bump it whenever we need access to a feature in forge that is not available in earlier versions
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package mekanism.common.tests;
2+
3+
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
4+
import net.minecraft.commands.CommandSourceStack;
5+
import net.minecraft.commands.Commands;
6+
import net.minecraft.resources.ResourceLocation;
7+
import net.neoforged.bus.api.IEventBus;
8+
import net.neoforged.fml.ModContainer;
9+
import net.neoforged.fml.common.Mod;
10+
import net.neoforged.neoforge.common.NeoForge;
11+
import net.neoforged.neoforge.event.RegisterCommandsEvent;
12+
import net.neoforged.testframework.conf.ClientConfiguration;
13+
import net.neoforged.testframework.conf.Feature;
14+
import net.neoforged.testframework.conf.FrameworkConfiguration;
15+
import net.neoforged.testframework.impl.MutableTestFramework;
16+
import org.lwjgl.glfw.GLFW;
17+
18+
@Mod(MekanismTests.MODID)
19+
public class MekanismTests {
20+
21+
public static final String MODID = "mekanismtests";
22+
23+
public MekanismTests(IEventBus modBus, ModContainer container) {
24+
//More or less a copy of net.neoforged.neoforge.eventtest.internal.TestsMod but with a few tweaks
25+
final MutableTestFramework framework = FrameworkConfiguration.builder(rl("tests"))
26+
.clientConfiguration(() -> ClientConfiguration.builder()
27+
.toggleOverlayKey(GLFW.GLFW_KEY_O)
28+
.openManagerKey(GLFW.GLFW_KEY_M)
29+
.build())
30+
.enable(Feature.CLIENT_SYNC, Feature.TEST_STORE)
31+
//TODO: Figure out which dumpers we want to enable and how they work
32+
//.dumpers(new JUnitSummaryDumper(Path.of("gameTest/")), new GitHubActionsStepSummaryDumper())
33+
.build().create();
34+
35+
framework.init(modBus, container);
36+
37+
NeoForge.EVENT_BUS.addListener((final RegisterCommandsEvent event) -> {
38+
final LiteralArgumentBuilder<CommandSourceStack> node = Commands.literal("tests");
39+
framework.registerCommands(node);
40+
event.getDispatcher().register(node);
41+
});
42+
}
43+
44+
public static ResourceLocation rl(String path) {
45+
return new ResourceLocation(MODID, path);
46+
}
47+
}

0 commit comments

Comments
 (0)