Skip to content

Commit 8765403

Browse files
authored
Add fabric-loader-junit to allow unit testing of transformed classes. (#767)
Also updates the build script to Gradle 8
1 parent 0c5e3f4 commit 8765403

File tree

19 files changed

+260
-24
lines changed

19 files changed

+260
-24
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@
2121
!/settings.gradle
2222
!/proguard.conf
2323

24-
!/minecraft
24+
!/minecraft
25+
!/junit

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ plugins {
1212
id 'maven-publish'
1313
id 'checkstyle'
1414
id 'com.diffplug.spotless' version "6.12.0"
15-
id 'fabric-loom' version '1.0-SNAPSHOT' apply false
15+
id 'fabric-loom' version '1.1-SNAPSHOT' apply false
1616
id 'com.github.johnrengelman.shadow' version '7.1.2'
1717
id 'me.modmuss50.remotesign' version "0.4.0"
1818
}
@@ -84,7 +84,7 @@ dependencies {
8484
testCompileOnly 'org.jetbrains:annotations:23.0.0'
8585

8686
// Unit testing for mod metadata
87-
testImplementation('org.junit.jupiter:junit-jupiter:5.8.2')
87+
testImplementation('org.junit.jupiter:junit-jupiter:5.9.2')
8888
}
8989

9090
processResources {

gradle/wrapper/gradle-wrapper.jar

34 Bytes
Binary file not shown.
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip
44
networkTimeout=10000
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

gradlew

+2-2
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144144
case $MAX_FD in #(
145145
max*)
146146
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
147-
# shellcheck disable=SC3045
147+
# shellcheck disable=SC3045
148148
MAX_FD=$( ulimit -H -n ) ||
149149
warn "Could not query maximum file descriptor limit"
150150
esac
151151
case $MAX_FD in #(
152152
'' | soft) :;; #(
153153
*)
154154
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
155-
# shellcheck disable=SC3045
155+
# shellcheck disable=SC3045
156156
ulimit -n "$MAX_FD" ||
157157
warn "Could not set maximum file descriptor limit to $MAX_FD"
158158
esac

junit/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Ignore everything
2+
/*
3+
4+
!/src
5+
!/build.gradle
6+
!/.gitignore

junit/build.gradle

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
apply plugin: 'maven-publish'
2+
apply plugin: 'me.modmuss50.remotesign'
3+
4+
sourceCompatibility = JavaVersion.VERSION_1_8
5+
targetCompatibility = JavaVersion.VERSION_1_8
6+
7+
archivesBaseName = "fabric-loader-junit"
8+
version = rootProject.version
9+
group = rootProject.group
10+
11+
def ENV = System.getenv()
12+
def signingEnabled = ENV.SIGNING_SERVER
13+
14+
repositories {
15+
mavenCentral()
16+
}
17+
18+
dependencies {
19+
api project(":")
20+
21+
api platform("org.junit:junit-bom:5.9.2")
22+
api "org.junit.jupiter:junit-jupiter-engine"
23+
implementation "org.junit.platform:junit-platform-launcher"
24+
}
25+
26+
java {
27+
withSourcesJar()
28+
}
29+
30+
if (signingEnabled) {
31+
remoteSign {
32+
requestUrl = ENV.SIGNING_SERVER
33+
pgpAuthKey = ENV.SIGNING_PGP_KEY
34+
jarAuthKey = ENV.SIGNING_JAR_KEY
35+
36+
afterEvaluate {
37+
sign publishing.publications.maven
38+
}
39+
}
40+
}
41+
42+
publishing {
43+
publications {
44+
mavenJava(MavenPublication) {
45+
artifactId project.archivesBaseName
46+
from components.java
47+
}
48+
}
49+
50+
repositories {
51+
if (ENV.MAVEN_URL) {
52+
maven {
53+
url ENV.MAVEN_URL
54+
credentials {
55+
username ENV.MAVEN_USERNAME
56+
password ENV.MAVEN_PASSWORD
57+
}
58+
}
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2016 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.loader.impl.junit;
18+
19+
import org.junit.platform.launcher.LauncherSession;
20+
import org.junit.platform.launcher.LauncherSessionListener;
21+
22+
import net.fabricmc.api.EnvType;
23+
import net.fabricmc.loader.impl.launch.knot.Knot;
24+
import net.fabricmc.loader.impl.util.SystemProperties;
25+
26+
public class FabricLoaderLauncherSessionListener implements LauncherSessionListener {
27+
static {
28+
System.setProperty(SystemProperties.DEVELOPMENT, "true");
29+
System.setProperty(SystemProperties.UNIT_TEST, "true");
30+
}
31+
32+
private final Knot knot;
33+
private final ClassLoader classLoader;
34+
35+
private ClassLoader launcherSessionClassLoader;
36+
37+
public FabricLoaderLauncherSessionListener() {
38+
final Thread currentThread = Thread.currentThread();
39+
final ClassLoader originalClassLoader = currentThread.getContextClassLoader();
40+
41+
try {
42+
knot = new Knot(EnvType.CLIENT);
43+
classLoader = knot.init(new String[]{});
44+
} finally {
45+
// Knot.init sets the context class loader, revert it back for now.
46+
currentThread.setContextClassLoader(originalClassLoader);
47+
}
48+
}
49+
50+
@Override
51+
public void launcherSessionOpened(LauncherSession session) {
52+
final Thread currentThread = Thread.currentThread();
53+
launcherSessionClassLoader = currentThread.getContextClassLoader();
54+
currentThread.setContextClassLoader(classLoader);
55+
}
56+
57+
@Override
58+
public void launcherSessionClosed(LauncherSession session) {
59+
final Thread currentThread = Thread.currentThread();
60+
currentThread.setContextClassLoader(launcherSessionClassLoader);
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
net.fabricmc.loader.impl.junit.FabricLoaderLauncherSessionListener

minecraft/minecraft-test/build.gradle

+12
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ loom {
1111

1212
def minecraft_version = "1.19.3";
1313

14+
repositories {
15+
mavenCentral()
16+
}
17+
1418
dependencies {
1519
minecraft "com.mojang:minecraft:${minecraft_version}"
1620
mappings "net.fabricmc:yarn:${minecraft_version}+build.3:v2"
1721

1822
implementation project(":minecraft")
23+
implementation project(":minecraft").sourceSets.main.output
24+
implementation project(":").sourceSets.main.output
1925

2026
// Required for mixin annotation processor
2127
annotationProcessor "org.ow2.asm:asm:${project.asm_version}"
@@ -32,6 +38,12 @@ dependencies {
3238
exclude module: 'launchwrapper'
3339
exclude module: 'guava'
3440
}
41+
42+
testImplementation project(":junit")
43+
}
44+
45+
test {
46+
useJUnitPlatform()
3547
}
3648

3749
tasks.withType(JavaCompile).configureEach {

minecraft/minecraft-test/src/main/java/net/fabricmc/minecraft/test/mixin/MixinGuiMain.java renamed to minecraft/minecraft-test/src/main/java/net/fabricmc/minecraft/test/mixin/MixinGrassBlock.java

+11-14
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,18 @@
1919
import org.spongepowered.asm.mixin.Mixin;
2020
import org.spongepowered.asm.mixin.injection.At;
2121
import org.spongepowered.asm.mixin.injection.Inject;
22-
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
22+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
2323

24-
import net.minecraft.client.gui.screen.Screen;
25-
import net.minecraft.client.gui.screen.TitleScreen;
26-
import net.minecraft.client.util.math.MatrixStack;
27-
import net.minecraft.text.Text;
24+
import net.minecraft.block.BlockState;
25+
import net.minecraft.block.GrassBlock;
26+
import net.minecraft.util.math.BlockPos;
27+
import net.minecraft.util.math.random.Random;
28+
import net.minecraft.world.World;
2829

29-
@Mixin(value = TitleScreen.class, remap = false)
30-
public abstract class MixinGuiMain extends Screen {
31-
protected MixinGuiMain(Text textComponent_1) {
32-
super(textComponent_1);
33-
}
34-
35-
@Inject(method = "render", at = @At("RETURN"))
36-
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float delta, CallbackInfo info) {
37-
this.textRenderer.draw(matrixStack, "Fabric Test Mod", 2, this.height - 30, -1);
30+
@Mixin(GrassBlock.class)
31+
public class MixinGrassBlock {
32+
@Inject(method = "canGrow", at = @At("HEAD"), cancellable = true)
33+
public void canGrow(World world, Random random, BlockPos pos, BlockState state, CallbackInfoReturnable<Boolean> cir) {
34+
cir.setReturnValue(false);
3835
}
3936
}

minecraft/minecraft-test/src/main/resources/fabricmc.test.mixins.client.json

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"package": "net.fabricmc.minecraft.test.mixin",
44
"compatibilityLevel": "JAVA_8",
55
"mixins": [
6+
"MixinGrassBlock"
67
],
78
"injectors": {
89
"defaultRequire": 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2016 FabricMC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.fabricmc.minecraft.test.junit;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
21+
22+
import org.junit.jupiter.api.BeforeAll;
23+
import org.junit.jupiter.api.Test;
24+
25+
import net.minecraft.Bootstrap;
26+
import net.minecraft.SharedConstants;
27+
import net.minecraft.block.Blocks;
28+
import net.minecraft.block.GrassBlock;
29+
import net.minecraft.item.Items;
30+
import net.minecraft.registry.Registries;
31+
import net.minecraft.util.Identifier;
32+
33+
import net.fabricmc.loader.api.FabricLoader;
34+
35+
public class JunitTest {
36+
@BeforeAll
37+
public static void setup() {
38+
SharedConstants.createGameVersion();
39+
Bootstrap.initialize();
40+
}
41+
42+
@Test
43+
public void testItems() {
44+
Identifier id = Registries.ITEM.getId(Items.DIAMOND);
45+
assertEquals(id.toString(), "minecraft:diamond");
46+
47+
System.out.println(id);
48+
}
49+
50+
@Test
51+
public void testMixin() {
52+
// MixinGrassBlock sets canGrow to false
53+
GrassBlock grassBlock = (GrassBlock) Blocks.GRASS_BLOCK;
54+
boolean canGrow = grassBlock.canGrow(null, null, null, null);
55+
assertFalse(canGrow);
56+
}
57+
58+
@Test
59+
public void testAccessLoader() {
60+
FabricLoader.getInstance().getAllMods();
61+
}
62+
}

minecraft/src/main/java/net/fabricmc/loader/impl/game/minecraft/MinecraftGameProvider.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,8 @@ public void initialize(FabricLauncher launcher) {
325325
realmsJar = obfJars.get("realms");
326326
}
327327

328-
if (!logJars.isEmpty()) {
328+
// Load the logger libraries on the platform CL when in a unit test
329+
if (!logJars.isEmpty() && !Boolean.getBoolean(SystemProperties.UNIT_TEST)) {
329330
for (Path jar : logJars) {
330331
if (gameJars.contains(jar)) {
331332
launcher.addToClassPath(jar, ALLOWED_EARLY_CLASS_PREFIXES);

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pluginManagement {
1010
rootProject.name='fabric-loader'
1111

1212
include "minecraft"
13+
include "junit"
1314

1415
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) {
1516
include "minecraft:minecraft-test"

0 commit comments

Comments
 (0)