From 2c8da2a754abd6007e20388170740bc7a55e8f3a Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Sun, 20 Jul 2025 17:36:57 +0200 Subject: [PATCH 01/11] Unit tests on all platforms --- .../bootstrap/dev/DevClasspath.java | 2 +- forge/build.gradle.kts | 35 ++++++++- .../forge/lang/locator/DummyModLocator.java | 35 +++++++++ ...necraftforge.forgespi.locating.IModLocator | 1 + .../forge/locator/DummyModLocator.java | 35 +++++++++ ...necraftforge.forgespi.locating.IModLocator | 1 + .../org/spongepowered/forge/ServerTest.java | 36 +++++++++ .../forge/boot/SpongeSessionListener.java | 48 ++++++++++++ .../forge/boot/SpongeTestBoot.java | 40 ++++++++++ ....platform.launcher.LauncherSessionListener | 1 + gradle.properties | 2 +- neoforge/build.gradle.kts | 41 +++++++++- .../resources/mixins.spongeneo.core.json | 4 +- .../spongepowered/neoforge/ServerTest.java | 36 +++++++++ .../neoforge/boot/SpongeSessionListener.java | 48 ++++++++++++ .../neoforge/boot/SpongeTestBoot.java | 46 +++++++++++ ....platform.launcher.LauncherSessionListener | 1 + .../applaunch/test/GameClassLoaderHolder.java | 37 +++++++++ .../spongepowered/common/launch/Launch.java | 2 + .../core/server/MinecraftServerMixin.java | 18 +++-- .../common/mixin/plugin/TestPlugin.java | 38 +++++++++ .../server/MinecraftServerMixin_Test.java | 78 +++++++++++++++++++ .../dedicated/DedicatedServerMixin_Test.java | 46 +++++++++++ .../server/dedicated/SettingsMixin_Test.java | 44 +++++++++++ src/mixins/resources/mixins.sponge.test.json | 10 +++ vanilla/build.gradle.kts | 34 +++++++- .../org/spongepowered/vanilla/ServerTest.java | 36 +++++++++ .../vanilla/boot/SpongeSessionListener.java | 48 ++++++++++++ .../vanilla/boot/SpongeTestBoot.java | 40 ++++++++++ ....platform.launcher.LauncherSessionListener | 1 + 30 files changed, 824 insertions(+), 20 deletions(-) create mode 100644 forge/src/lang/java/org/spongepowered/forge/lang/locator/DummyModLocator.java create mode 100644 forge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator create mode 100644 forge/src/main/java/org/spongepowered/forge/locator/DummyModLocator.java create mode 100644 forge/src/main/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator create mode 100644 forge/src/test/java/org/spongepowered/forge/ServerTest.java create mode 100644 forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java create mode 100644 forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java create mode 100644 forge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener create mode 100644 neoforge/src/test/java/org/spongepowered/neoforge/ServerTest.java create mode 100644 neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java create mode 100644 neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java create mode 100644 neoforge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener create mode 100644 src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/plugin/TestPlugin.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java create mode 100644 src/mixins/resources/mixins.sponge.test.json create mode 100644 vanilla/src/test/java/org/spongepowered/vanilla/ServerTest.java create mode 100644 vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java create mode 100644 vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java create mode 100644 vanilla/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener diff --git a/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java b/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java index a2ad50a357b..5b0d65f20c9 100644 --- a/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java +++ b/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java @@ -125,7 +125,7 @@ public static List resolve() { final String fileName = path.getFileName().toString(); - if (false) { + if (fileName.startsWith("junit-")) { if (Bootstrap.DEBUG) { System.out.println("Ignored: " + path); } diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index c0212ff9802..605cd138435 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -1,6 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.minecraftforge.gradle.common.util.RunConfig -import net.minecraftforge.gradle.userdev.UserDevExtension import org.gradle.api.tasks.JavaExec import org.gradle.internal.DefaultTaskExecutionRequest import org.spongepowered.gradle.impl.AWToAT @@ -167,6 +166,10 @@ val main by sourceSets.named("main") { spongeImpl.addDependencyToRuntimeOnly(bootstrapMain.get(), this) spongeImpl.addDependencyToRuntimeOnly(bootstrapForge.get(), this) } +sourceSets.named("test") { + spongeImpl.addDependencyToImplementation(bootstrapMain.get(), this) + spongeImpl.addDependencyToImplementation(bootstrapForge.get(), this) +} configurations.configureEach { // Fix that can be found in Forge MDK too @@ -175,6 +178,10 @@ configurations.configureEach { } } +configurations.testRuntimeOnly { + exclude(module = "testplugins") +} + dependencies { "minecraft"("net.minecraftforge:forge:$minecraftVersion-$forgeVersion") @@ -213,6 +220,12 @@ dependencies { testPluginsProject?.also { runtimeOnly(project(it.path)) } + + testImplementation(platform(apiLibs.junit.bom)) + testImplementation(apiLibs.junit.api) + testImplementation(apiLibs.junit.params) + testImplementation(apiLibs.junit.launcher) + testRuntimeOnly(apiLibs.junit.engine) } val awFiles: Set = files(commonMain.get().resources, main.resources).filter { it.name.endsWith(".accesswidener") }.files @@ -221,7 +234,7 @@ AWToAT.convert(awFiles, atFile) val mixinConfigs: MutableSet = spongeImpl.mixinConfigurations -extensions.configure(UserDevExtension::class) { +minecraft { mappings("official", "1.21.4") accessTransformers.from(atFile) reobf = false @@ -246,7 +259,7 @@ extensions.configure(UserDevExtension::class) { } afterEvaluate { - extensions.configure(UserDevExtension::class) { + minecraft { // Configure bootstrap dev val bootFileNames = spongeImpl.buildRuntimeFileNames(serviceLayerConfig.get()) // service in boot during dev val gameShadedFileNames = spongeImpl.buildRuntimeFileNames(gameShadedLibrariesConfig.get()) @@ -399,6 +412,22 @@ tasks { assemble { dependsOn(universalJar) } + + test { + useJUnitPlatform() + + val runServer = minecraft.runs.getByName("server") + jvmArgs(runServer.jvmArgs) + jvmArgs("-Dsponge.test.args=" + runServer.args.joinToString(" ")) + workingDir = layout.buildDirectory.dir("test-run").get().asFile + + doFirst { + // reset test directory + workingDir.deleteRecursively() + workingDir.mkdirs() + workingDir.resolve("eula.txt").writeText("eula=true") + } + } } if (IdeHelper.isIdeaSync()) { diff --git a/forge/src/lang/java/org/spongepowered/forge/lang/locator/DummyModLocator.java b/forge/src/lang/java/org/spongepowered/forge/lang/locator/DummyModLocator.java new file mode 100644 index 00000000000..4eef306572a --- /dev/null +++ b/forge/src/lang/java/org/spongepowered/forge/lang/locator/DummyModLocator.java @@ -0,0 +1,35 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.lang.locator; + +import net.minecraftforge.forgespi.locating.IModLocator; + +/** + * Hack. + * FML ClasspathLocator in our test env wants to load the lang/resources directory without a union, causing a conflict. + * Fortunately, when it detects certain services, it just skips the directory. + */ +public abstract class DummyModLocator implements IModLocator { +} diff --git a/forge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator b/forge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator new file mode 100644 index 00000000000..1be92fd2bbd --- /dev/null +++ b/forge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator @@ -0,0 +1 @@ +org.spongepowered.forge.lang.locator.DummyModLocator diff --git a/forge/src/main/java/org/spongepowered/forge/locator/DummyModLocator.java b/forge/src/main/java/org/spongepowered/forge/locator/DummyModLocator.java new file mode 100644 index 00000000000..fc85ba085fe --- /dev/null +++ b/forge/src/main/java/org/spongepowered/forge/locator/DummyModLocator.java @@ -0,0 +1,35 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.locator; + +import net.minecraftforge.forgespi.locating.IModLocator; + +/** + * Hack. + * FML ClasspathLocator in our test env wants to load the main/resources directory without a union, causing a conflict. + * Fortunately, when it detects certain services, it just skips the directory. + */ +public abstract class DummyModLocator implements IModLocator { +} diff --git a/forge/src/main/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator b/forge/src/main/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator new file mode 100644 index 00000000000..7884741e014 --- /dev/null +++ b/forge/src/main/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator @@ -0,0 +1 @@ +org.spongepowered.forge.locator.DummyModLocator diff --git a/forge/src/test/java/org/spongepowered/forge/ServerTest.java b/forge/src/test/java/org/spongepowered/forge/ServerTest.java new file mode 100644 index 00000000000..792b0832172 --- /dev/null +++ b/forge/src/test/java/org/spongepowered/forge/ServerTest.java @@ -0,0 +1,36 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import org.junit.jupiter.api.Test; +import org.spongepowered.api.Sponge; + +public class ServerTest { + + @Test + public void serverAvailable() { + Sponge.server(); + } +} diff --git a/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java b/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java new file mode 100644 index 00000000000..c865f7a68ed --- /dev/null +++ b/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java @@ -0,0 +1,48 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.boot; + +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.LauncherSessionListener; + +public class SpongeSessionListener implements LauncherSessionListener { + private ClassLoader previousLoader; + + @Override + public void launcherSessionOpened(final LauncherSession session) { + this.previousLoader = Thread.currentThread().getContextClassLoader(); + + try { + Thread.currentThread().setContextClassLoader(SpongeTestBoot.getGameClassLoader()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void launcherSessionClosed(final LauncherSession session) { + Thread.currentThread().setContextClassLoader(this.previousLoader); + } +} diff --git a/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java b/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java new file mode 100644 index 00000000000..7b0299df2cb --- /dev/null +++ b/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java @@ -0,0 +1,40 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.boot; + +import org.spongepowered.bootstrap.forge.ForgeBootstrap; +import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; + +public class SpongeTestBoot { + + public static ClassLoader getGameClassLoader() throws Exception { + if (GameClassLoaderHolder.loader == null) { + final String[] args = System.getProperty("sponge.test.args").split(" "); + System.setProperty("sponge.test.active", "true"); + new ForgeBootstrap(args).devBoot(false); + } + return GameClassLoaderHolder.loader; + } +} diff --git a/forge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener b/forge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener new file mode 100644 index 00000000000..363e6b24c85 --- /dev/null +++ b/forge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener @@ -0,0 +1 @@ +org.spongepowered.forge.boot.SpongeSessionListener diff --git a/gradle.properties b/gradle.properties index 2f01c48ff1e..948f91c0633 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ projectDescription=The SpongeAPI implementation targeting vanilla Minecraft and mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.concurrent.json,mixins.sponge.core.json,\ mixins.sponge.entityactivation.json,mixins.sponge.exploit.json,mixins.sponge.inventory.json,mixins.sponge.movementcheck.json,\ - mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json + mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange minecraftVersion=1.21.4 diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index fb6deb72cfc..01b44992e9c 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -1,6 +1,6 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import net.neoforged.moddevgradle.dsl.NeoForgeExtension import net.neoforged.moddevgradle.internal.RunGameTask +import org.gradle.api.tasks.JavaExec import org.spongepowered.gradle.impl.AWToAT buildscript { @@ -158,6 +158,14 @@ val main by sourceSets.named("main") { spongeImpl.addDependencyToRuntimeOnly(bootstrapMain.get(), this) spongeImpl.addDependencyToRuntimeOnly(bootstrapNeoForge.get(), this) } +sourceSets.named("test") { + spongeImpl.addDependencyToImplementation(bootstrapMain.get(), this) + spongeImpl.addDependencyToImplementation(bootstrapNeoForge.get(), this) +} + +configurations.testRuntimeOnly { + exclude(module = "testplugins") +} val awFiles: Set = files(commonMain.get().resources, main.resources).filter { it.name.endsWith(".accesswidener") }.files val atFile = project.layout.buildDirectory.file("generated/resources/at.cfg").get().asFile @@ -165,7 +173,7 @@ AWToAT.convert(awFiles, atFile) val mixinConfigs: MutableSet = spongeImpl.mixinConfigurations -extensions.configure(NeoForgeExtension::class) { +neoForge { version = neoForgeVersion accessTransformers.from(atFile) @@ -189,6 +197,7 @@ extensions.configure(NeoForgeExtension::class) { } bootLibrariesConfig.get().extendsFrom(configurations.getByName("modDevCompileDependencies")) +configurations.testRuntimeOnly.get().extendsFrom(configurations.getByName("modDevRuntimeDependencies")) dependencies { val service = serviceLibrariesConfig.name @@ -217,10 +226,16 @@ dependencies { testPluginsProject?.also { runtimeOnly(project(it.path)) } + + testImplementation(platform(apiLibs.junit.bom)) + testImplementation(apiLibs.junit.api) + testImplementation(apiLibs.junit.params) + testImplementation(apiLibs.junit.launcher) + testRuntimeOnly(apiLibs.junit.engine) } afterEvaluate { - extensions.configure(NeoForgeExtension::class) { + neoForge { // Configure bootstrap dev val bootFileNames = spongeImpl.buildRuntimeFileNames(serviceLayerConfig.get()) // service in boot during dev val gameShadedFileNames = spongeImpl.buildRuntimeFileNames(gameShadedLibrariesConfig.get()) @@ -370,6 +385,26 @@ tasks { assemble { dependsOn(universalJar) } + + val runServer = named("runServer", JavaExec::class) + val prepareServerRun = named("prepareServerRun") + + test { + useJUnitPlatform() + + jvmArgs(runServer.get().jvmArgs) + jvmArgs("-Dsponge.test.args=" + runServer.get().args!!.joinToString(" ")) + workingDir = layout.buildDirectory.dir("test-run").get().asFile + + doFirst { + // reset test directory + workingDir.deleteRecursively() + workingDir.mkdirs() + workingDir.resolve("eula.txt").writeText("eula=true") + } + + dependsOn(prepareServerRun) + } } publishing { diff --git a/neoforge/src/mixins/resources/mixins.spongeneo.core.json b/neoforge/src/mixins/resources/mixins.spongeneo.core.json index 135ad8490aa..4424652efdd 100644 --- a/neoforge/src/mixins/resources/mixins.spongeneo.core.json +++ b/neoforge/src/mixins/resources/mixins.spongeneo.core.json @@ -8,9 +8,8 @@ "api.event.block.ChangeBlockEvent_AllMixin_Neo", "api.event.entity.ChangeEntityWorldEvent_PreMixin_Neo", "api.event.entity.ChangeEventWorldEvent_PostMixin_Neo", - "neoforge.event.entity.item.ItemTossEventMixin_Neo", "commands.CommandsMixin_Neo", - "neoforge.NeoForgeMixin_Neo", + "neoforge.event.entity.item.ItemTossEventMixin_Neo", "neoforge.event.entity.EntityTravelToDimensionEventMixin_Neo", "neoforge.event.entity.player.PlayerEvent_PlayerChangedDimensionEventMixin_Neo", "neoforge.event.world.BlockEvent_BreakEventMixin_Neo", @@ -18,6 +17,7 @@ "neoforge.internal.BrandingControlMixin_Neo", "neoforge.registries.GameDataMixin_Neo", "neoforge.registries.RegistryManagerMixin_Neo", + "neoforge.NeoForgeMixin_Neo", "network.ConnectionMixin_Neo", "server.BootstrapMixin_Neo", "server.MinecraftServerMixin_Neo", diff --git a/neoforge/src/test/java/org/spongepowered/neoforge/ServerTest.java b/neoforge/src/test/java/org/spongepowered/neoforge/ServerTest.java new file mode 100644 index 00000000000..a02de5b083a --- /dev/null +++ b/neoforge/src/test/java/org/spongepowered/neoforge/ServerTest.java @@ -0,0 +1,36 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.neoforge; + +import org.junit.jupiter.api.Test; +import org.spongepowered.api.Sponge; + +public class ServerTest { + + @Test + public void serverAvailable() { + Sponge.server(); + } +} diff --git a/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java new file mode 100644 index 00000000000..07323da67b4 --- /dev/null +++ b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java @@ -0,0 +1,48 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.neoforge.boot; + +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.LauncherSessionListener; + +public class SpongeSessionListener implements LauncherSessionListener { + private ClassLoader previousLoader; + + @Override + public void launcherSessionOpened(final LauncherSession session) { + this.previousLoader = Thread.currentThread().getContextClassLoader(); + + try { + Thread.currentThread().setContextClassLoader(SpongeTestBoot.getGameClassLoader()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void launcherSessionClosed(final LauncherSession session) { + Thread.currentThread().setContextClassLoader(this.previousLoader); + } +} diff --git a/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java new file mode 100644 index 00000000000..e14bea8bbd4 --- /dev/null +++ b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.neoforge.boot; + +import org.spongepowered.bootstrap.neoforge.NeoForgeBootstrap; +import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; + +import java.nio.file.Files; +import java.nio.file.Path; + +public class SpongeTestBoot { + + public static ClassLoader getGameClassLoader() throws Exception { + if (GameClassLoaderHolder.loader == null) { + final Path argsFile = Path.of(System.getProperty("sponge.test.args").substring(1)); + final String[] args = Files.lines(argsFile).map(String::trim).filter(line -> !line.startsWith("#") && !line.isEmpty()) + .skip(1) // main class + .toArray(String[]::new); + System.setProperty("sponge.test.active", "true"); + new NeoForgeBootstrap(args).devBoot(false); + } + return GameClassLoaderHolder.loader; + } +} diff --git a/neoforge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener b/neoforge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener new file mode 100644 index 00000000000..5c360ba009e --- /dev/null +++ b/neoforge/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener @@ -0,0 +1 @@ +org.spongepowered.neoforge.boot.SpongeSessionListener diff --git a/src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java b/src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java new file mode 100644 index 00000000000..e921b1ed3d7 --- /dev/null +++ b/src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java @@ -0,0 +1,37 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.applaunch.test; + +public class GameClassLoaderHolder { + public static ClassLoader loader; + + public static void set(final ClassLoader loader) { + try { + ClassLoader.getSystemClassLoader().loadClass(GameClassLoaderHolder.class.getName()).getField("loader").set(null, loader); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/launch/java/org/spongepowered/common/launch/Launch.java b/src/launch/java/org/spongepowered/common/launch/Launch.java index ab1684504c3..169c8364cc4 100644 --- a/src/launch/java/org/spongepowered/common/launch/Launch.java +++ b/src/launch/java/org/spongepowered/common/launch/Launch.java @@ -32,6 +32,7 @@ import org.spongepowered.api.plugin.PluginManager; import org.spongepowered.asm.mixin.MixinEnvironment; import org.spongepowered.common.applaunch.plugin.PluginPlatform; +import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; import org.spongepowered.common.launch.plugin.SpongePluginManager; import org.spongepowered.plugin.PluginContainer; @@ -67,6 +68,7 @@ public static void setInstance(final Launch instance) { } Launch.INSTANCE = Objects.requireNonNull(instance); + GameClassLoaderHolder.set(instance.getClass().getClassLoader()); } public final String id() { diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java index 138e867ba6d..53a0c966a89 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java @@ -28,6 +28,7 @@ import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.datafixers.DataFixer; import net.kyori.adventure.resource.ResourcePackRequest; import net.minecraft.Util; import net.minecraft.commands.CommandSourceStack; @@ -39,9 +40,11 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerFunctionManager; +import net.minecraft.server.Services; import net.minecraft.server.WorldStem; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.server.level.progress.ChunkProgressListenerFactory; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.SimpleReloadInstance; @@ -85,7 +88,6 @@ import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.SpongeServer; import org.spongepowered.common.accessor.server.ServerFunctionManagerAccessor; @@ -115,14 +117,13 @@ import org.spongepowered.common.world.server.SpongeWorldManager; import java.io.IOException; +import java.net.Proxy; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; @Mixin(MinecraftServer.class) public abstract class MinecraftServerMixin implements SpongeServer, MinecraftServerBridge, CommandSourceProviderBridge, SubjectProxy, @@ -203,11 +204,12 @@ public Subject subject() { return SpongeCommon.game().systemSubject(); } - @Inject(method = "spin", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILEXCEPTION) - private static void impl$setThreadOnServerPhaseTracker(final Function p_240784_0_, - final CallbackInfoReturnable cir, - final AtomicReference atomicReference, - final Thread thread) { + @Inject(method = "", at = @At("RETURN")) + private void impl$setThreadOnServerPhaseTracker( + Thread thread, LevelStorageSource.LevelStorageAccess storageAccess, PackRepository packRepo, + WorldStem stem, Proxy proxy, DataFixer fixer, + Services services, ChunkProgressListenerFactory progress, CallbackInfo ci + ) { try { PhaseTracker.getServerInstanceExplicitly().setThread(thread); } catch (final IllegalAccessException e) { diff --git a/src/mixins/java/org/spongepowered/common/mixin/plugin/TestPlugin.java b/src/mixins/java/org/spongepowered/common/mixin/plugin/TestPlugin.java new file mode 100644 index 00000000000..a51d74ab859 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/plugin/TestPlugin.java @@ -0,0 +1,38 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.plugin; + +public final class TestPlugin extends AbstractMixinConfigPlugin { + private final boolean active; + + public TestPlugin() { + this.active = "true".equals(System.getProperty("sponge.test.active")); + } + + @Override + public boolean shouldApplyMixin(final String targetClassName, final String mixinClassName) { + return this.active; + } +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java new file mode 100644 index 00000000000..12eac43294e --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java @@ -0,0 +1,78 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.test.server; + +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.io.IOException; +import java.util.function.Function; + +@Mixin(MinecraftServer.class) +public abstract class MinecraftServerMixin_Test { + + @Shadow + protected abstract boolean initServer() throws IOException; + + @Shadow + private volatile boolean running; + + @Shadow + private boolean stopped; + + @Shadow + public abstract void stopServer(); + + /** + * @author Yeregorix + * @reason Stay on the same thread and do not tick the server. + */ + @Inject(method = "spin", at = @At("HEAD"), cancellable = true) + private static void spin(final Function supplier, CallbackInfoReturnable cir) { + final MinecraftServer server = supplier.apply(Thread.currentThread()); + try { + ((MinecraftServerMixin_Test) (Object) server).initServer(); + } catch (IOException e) { + throw new RuntimeException(e); + } + cir.setReturnValue(server); + } + + /** + * @author Yeregorix + * @reason Stops the server instead of the loop. + */ + @Overwrite + public void halt(final boolean join) { + this.running = false; + this.stopped = true; + this.stopServer(); + } +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java new file mode 100644 index 00000000000..24af936e95c --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.test.server.dedicated; + +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.network.ServerConnectionListener; +import org.slf4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.net.InetAddress; + +@Mixin(DedicatedServer.class) +public class DedicatedServerMixin_Test { + @Shadow @Final static Logger LOGGER; + + @Redirect(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerConnectionListener;startTcpServerListener(Ljava/net/InetAddress;I)V")) + private void dontStartTcpServer(final ServerConnectionListener listener, final InetAddress address, final int port) { + DedicatedServerMixin_Test.LOGGER.info("[TEST] TCP server not started."); + } +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java new file mode 100644 index 00000000000..510deef81fa --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java @@ -0,0 +1,44 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.mixin.test.server.dedicated; + +import net.minecraft.server.dedicated.Settings; +import org.slf4j.Logger; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.nio.file.NoSuchFileException; + +@Mixin(Settings.class) +public class SettingsMixin_Test { + + @Redirect(method = "loadFromFile", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V")) + private static void onLoadFromFileError(final Logger logger, final String message, final Object path, final Object exception) { + if (!(exception instanceof NoSuchFileException)) { + logger.error(message, path, exception); + } + } +} diff --git a/src/mixins/resources/mixins.sponge.test.json b/src/mixins/resources/mixins.sponge.test.json new file mode 100644 index 00000000000..d1d903f4dda --- /dev/null +++ b/src/mixins/resources/mixins.sponge.test.json @@ -0,0 +1,10 @@ +{ + "parent": "mixins.sponge.parent.json", + "package": "org.spongepowered.common.mixin.test", + "plugin": "org.spongepowered.common.mixin.plugin.TestPlugin", + "mixins": [ + "server.MinecraftServerMixin_Test", + "server.dedicated.DedicatedServerMixin_Test", + "server.dedicated.SettingsMixin_Test" + ] +} diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index 9a2129e87f6..f0a129baa74 100644 --- a/vanilla/build.gradle.kts +++ b/vanilla/build.gradle.kts @@ -138,6 +138,10 @@ val main by sourceSets.named("main") { spongeImpl.addDependencyToRuntimeOnly(bootstrapMain.get(), this) spongeImpl.addDependencyToRuntimeOnly(bootstrapForge.get(), this) } +sourceSets.named("test") { + spongeImpl.addDependencyToImplementation(bootstrapMain.get(), this) + spongeImpl.addDependencyToImplementation(bootstrapForge.get(), this) +} val superclassConfigs = spongeImpl.getNamedConfigurations("superClassChanges") val mixinConfigs = spongeImpl.mixinConfigurations @@ -154,6 +158,10 @@ configurations.configureEach { } } +configurations.testRuntimeOnly { + exclude(module = "testplugins") +} + dependencies { val installer = installerLibrariesConfig.name installer(libs.securemodules) @@ -242,15 +250,21 @@ dependencies { testPluginsProject?.also { runtimeOnly(project(it.path)) } + + testImplementation(platform(apiLibs.junit.bom)) + testImplementation(apiLibs.junit.api) + testImplementation(apiLibs.junit.params) + testImplementation(apiLibs.junit.launcher) + testRuntimeOnly(apiLibs.junit.engine) } minecraft { runs { // Full development environment - server("runServer") { + server() { args("--nogui", "--launchTarget", "sponge_server_dev") } - client("runClient") { + client() { args("--launchTarget", "sponge_client_dev") } @@ -476,6 +490,22 @@ tasks { assemble { dependsOn(universalJar) } + + test { + useJUnitPlatform() + + val runServer = minecraft.runs.server().get() + jvmArgs(runServer.allJvmArguments()) + jvmArgs("-Dsponge.test.args=" + runServer.allArguments().joinToString(" ")) + workingDir = layout.buildDirectory.dir("test-run").get().asFile + + doFirst { + // reset test directory + workingDir.deleteRecursively() + workingDir.mkdirs() + workingDir.resolve("eula.txt").writeText("eula=true") + } + } } publishing { diff --git a/vanilla/src/test/java/org/spongepowered/vanilla/ServerTest.java b/vanilla/src/test/java/org/spongepowered/vanilla/ServerTest.java new file mode 100644 index 00000000000..d08e581f7c2 --- /dev/null +++ b/vanilla/src/test/java/org/spongepowered/vanilla/ServerTest.java @@ -0,0 +1,36 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.vanilla; + +import org.junit.jupiter.api.Test; +import org.spongepowered.api.Sponge; + +public class ServerTest { + + @Test + public void serverAvailable() { + Sponge.server(); + } +} diff --git a/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java new file mode 100644 index 00000000000..b30074b2a1c --- /dev/null +++ b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java @@ -0,0 +1,48 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.vanilla.boot; + +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.LauncherSessionListener; + +public class SpongeSessionListener implements LauncherSessionListener { + private ClassLoader previousLoader; + + @Override + public void launcherSessionOpened(final LauncherSession session) { + this.previousLoader = Thread.currentThread().getContextClassLoader(); + + try { + Thread.currentThread().setContextClassLoader(SpongeTestBoot.getGameClassLoader()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void launcherSessionClosed(final LauncherSession session) { + Thread.currentThread().setContextClassLoader(this.previousLoader); + } +} diff --git a/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java new file mode 100644 index 00000000000..108fa6a7a4f --- /dev/null +++ b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java @@ -0,0 +1,40 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.vanilla.boot; + +import org.spongepowered.bootstrap.forge.VanillaBootstrap; +import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; + +public class SpongeTestBoot { + + public static ClassLoader getGameClassLoader() throws Exception { + if (GameClassLoaderHolder.loader == null) { + final String[] args = System.getProperty("sponge.test.args").split(" "); + System.setProperty("sponge.test.active", "true"); + new VanillaBootstrap(args).devBoot(false); + } + return GameClassLoaderHolder.loader; + } +} diff --git a/vanilla/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener b/vanilla/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener new file mode 100644 index 00000000000..7eb5ad2f411 --- /dev/null +++ b/vanilla/src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener @@ -0,0 +1 @@ +org.spongepowered.vanilla.boot.SpongeSessionListener From f12b974f2fc900cb4be748f64b20b089efad93b4 Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Mon, 21 Jul 2025 16:28:04 +0200 Subject: [PATCH 02/11] Shutdown test server when junit session is closing --- .../forge/boot/SpongeSessionListener.java | 2 + .../forge/boot/SpongeTestBoot.java | 6 +-- .../neoforge/boot/SpongeSessionListener.java | 2 + .../neoforge/boot/SpongeTestBoot.java | 6 +-- .../applaunch/test/TestGameAccess.java} | 44 ++++++++++++++++--- .../spongepowered/common/launch/Launch.java | 2 - .../server/MinecraftServerMixin_Test.java | 36 +++++++++++++-- .../BlockableEventLoopMixin_Tracker.java | 4 +- .../vanilla/boot/SpongeSessionListener.java | 2 + .../vanilla/boot/SpongeTestBoot.java | 6 +-- 10 files changed, 87 insertions(+), 23 deletions(-) rename src/{applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java => applaunchConfig/java/org/spongepowered/common/applaunch/test/TestGameAccess.java} (51%) diff --git a/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java b/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java index c865f7a68ed..7e93cdd7301 100644 --- a/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java +++ b/forge/src/test/java/org/spongepowered/forge/boot/SpongeSessionListener.java @@ -26,6 +26,7 @@ import org.junit.platform.launcher.LauncherSession; import org.junit.platform.launcher.LauncherSessionListener; +import org.spongepowered.common.applaunch.test.TestGameAccess; public class SpongeSessionListener implements LauncherSessionListener { private ClassLoader previousLoader; @@ -43,6 +44,7 @@ public void launcherSessionOpened(final LauncherSession session) { @Override public void launcherSessionClosed(final LauncherSession session) { + TestGameAccess.shutdownGame(); Thread.currentThread().setContextClassLoader(this.previousLoader); } } diff --git a/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java b/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java index 7b0299df2cb..e02fdb51ded 100644 --- a/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java +++ b/forge/src/test/java/org/spongepowered/forge/boot/SpongeTestBoot.java @@ -25,16 +25,16 @@ package org.spongepowered.forge.boot; import org.spongepowered.bootstrap.forge.ForgeBootstrap; -import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; +import org.spongepowered.common.applaunch.test.TestGameAccess; public class SpongeTestBoot { public static ClassLoader getGameClassLoader() throws Exception { - if (GameClassLoaderHolder.loader == null) { + if (TestGameAccess.getGameClassLoader() == null) { final String[] args = System.getProperty("sponge.test.args").split(" "); System.setProperty("sponge.test.active", "true"); new ForgeBootstrap(args).devBoot(false); } - return GameClassLoaderHolder.loader; + return TestGameAccess.getGameClassLoader(); } } diff --git a/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java index 07323da67b4..53916709244 100644 --- a/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java +++ b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeSessionListener.java @@ -26,6 +26,7 @@ import org.junit.platform.launcher.LauncherSession; import org.junit.platform.launcher.LauncherSessionListener; +import org.spongepowered.common.applaunch.test.TestGameAccess; public class SpongeSessionListener implements LauncherSessionListener { private ClassLoader previousLoader; @@ -43,6 +44,7 @@ public void launcherSessionOpened(final LauncherSession session) { @Override public void launcherSessionClosed(final LauncherSession session) { + TestGameAccess.shutdownGame(); Thread.currentThread().setContextClassLoader(this.previousLoader); } } diff --git a/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java index e14bea8bbd4..416b5317e49 100644 --- a/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java +++ b/neoforge/src/test/java/org/spongepowered/neoforge/boot/SpongeTestBoot.java @@ -25,7 +25,7 @@ package org.spongepowered.neoforge.boot; import org.spongepowered.bootstrap.neoforge.NeoForgeBootstrap; -import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; +import org.spongepowered.common.applaunch.test.TestGameAccess; import java.nio.file.Files; import java.nio.file.Path; @@ -33,7 +33,7 @@ public class SpongeTestBoot { public static ClassLoader getGameClassLoader() throws Exception { - if (GameClassLoaderHolder.loader == null) { + if (TestGameAccess.getGameClassLoader() == null) { final Path argsFile = Path.of(System.getProperty("sponge.test.args").substring(1)); final String[] args = Files.lines(argsFile).map(String::trim).filter(line -> !line.startsWith("#") && !line.isEmpty()) .skip(1) // main class @@ -41,6 +41,6 @@ public static ClassLoader getGameClassLoader() throws Exception { System.setProperty("sponge.test.active", "true"); new NeoForgeBootstrap(args).devBoot(false); } - return GameClassLoaderHolder.loader; + return TestGameAccess.getGameClassLoader(); } } diff --git a/src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java b/src/applaunchConfig/java/org/spongepowered/common/applaunch/test/TestGameAccess.java similarity index 51% rename from src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java rename to src/applaunchConfig/java/org/spongepowered/common/applaunch/test/TestGameAccess.java index e921b1ed3d7..20bfaad482b 100644 --- a/src/applaunch/java/org/spongepowered/common/applaunch/test/GameClassLoaderHolder.java +++ b/src/applaunchConfig/java/org/spongepowered/common/applaunch/test/TestGameAccess.java @@ -24,14 +24,46 @@ */ package org.spongepowered.common.applaunch.test; -public class GameClassLoaderHolder { - public static ClassLoader loader; +import java.lang.reflect.Field; - public static void set(final ClassLoader loader) { +/** + * Caution: this class exists in multiple classloaders + */ +@SuppressWarnings("unused") +public class TestGameAccess { + private static Runnable shutdownGame; + + public static ClassLoader getGameClassLoader() { + return TestGameAccess.shutdownGame == null ? null : TestGameAccess.shutdownGame.getClass().getClassLoader(); + } + + public static void shutdownGame() { + try { + if (TestGameAccess.shutdownGame != null) { + TestGameAccess.shutdownGame.run(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void set(final String name, final Object value) { + final Class cl; + try { + cl = ClassLoader.getSystemClassLoader().loadClass(TestGameAccess.class.getName()); + } catch (final ClassNotFoundException e) { + return; + } try { - ClassLoader.getSystemClassLoader().loadClass(GameClassLoaderHolder.class.getName()).getField("loader").set(null, loader); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); + final Field field = cl.getDeclaredField(name); + field.setAccessible(true); + field.set(null, value); + } catch (final ReflectiveOperationException e) { + e.printStackTrace(); } } + + public static void setup(final Runnable shutdownGame) { + TestGameAccess.set("shutdownGame", shutdownGame); + } } diff --git a/src/launch/java/org/spongepowered/common/launch/Launch.java b/src/launch/java/org/spongepowered/common/launch/Launch.java index 169c8364cc4..ab1684504c3 100644 --- a/src/launch/java/org/spongepowered/common/launch/Launch.java +++ b/src/launch/java/org/spongepowered/common/launch/Launch.java @@ -32,7 +32,6 @@ import org.spongepowered.api.plugin.PluginManager; import org.spongepowered.asm.mixin.MixinEnvironment; import org.spongepowered.common.applaunch.plugin.PluginPlatform; -import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; import org.spongepowered.common.launch.plugin.SpongePluginManager; import org.spongepowered.plugin.PluginContainer; @@ -68,7 +67,6 @@ public static void setInstance(final Launch instance) { } Launch.INSTANCE = Objects.requireNonNull(instance); - GameClassLoaderHolder.set(instance.getClass().getClassLoader()); } public final String id() { diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java index 12eac43294e..8d191bdfdd8 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java @@ -25,18 +25,26 @@ package org.spongepowered.common.mixin.test.server; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.TickTask; +import net.minecraft.util.thread.ReentrantBlockableEventLoop; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.common.applaunch.test.TestGameAccess; import java.io.IOException; import java.util.function.Function; @Mixin(MinecraftServer.class) -public abstract class MinecraftServerMixin_Test { +public abstract class MinecraftServerMixin_Test extends ReentrantBlockableEventLoop { + + public MinecraftServerMixin_Test(String name) { + super(name); + } @Shadow protected abstract boolean initServer() throws IOException; @@ -50,6 +58,11 @@ public abstract class MinecraftServerMixin_Test { @Shadow public abstract void stopServer(); + @Inject(method = "", at = @At("RETURN")) + private void onInit(final CallbackInfo ci) { + TestGameAccess.setup(this::impl$stop); + } + /** * @author Yeregorix * @reason Stay on the same thread and do not tick the server. @@ -65,14 +78,29 @@ private static void spin(final Function suppl cir.setReturnValue(server); } + private void impl$stop() { + if (this.running) { + this.running = false; + this.stopped = true; + this.stopServer(); + } + } + /** * @author Yeregorix * @reason Stops the server instead of the loop. */ @Overwrite public void halt(final boolean join) { - this.running = false; - this.stopped = true; - this.stopServer(); + this.impl$stop(); + } + + /** + * @author Yeregorix + * @reason The server is not ticking. + */ + @Overwrite + public void waitUntilNextTick() { + this.runAllTasks(); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/util/thread/BlockableEventLoopMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/util/thread/BlockableEventLoopMixin_Tracker.java index 7484b626e8c..da8b8c93d59 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/util/thread/BlockableEventLoopMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/util/thread/BlockableEventLoopMixin_Tracker.java @@ -31,7 +31,6 @@ import org.spongepowered.common.event.tracking.PhaseTracker; import org.spongepowered.common.event.tracking.phase.plugin.BasicPluginContext; import org.spongepowered.common.event.tracking.phase.plugin.PluginPhase; -import org.spongepowered.common.hooks.PlatformHooks; @Mixin(BlockableEventLoop.class) public abstract class BlockableEventLoopMixin_Tracker { @@ -43,7 +42,8 @@ public abstract class BlockableEventLoopMixin_Tracker { remap = false)) private void tracker$callOnMainThreadWithPhaseState(final Runnable runnable) { // This method can be called async while server is stopping - if (this.tracker$isServerAndIsServerStopped() && !PlatformHooks.INSTANCE.getGeneralHooks().onServerThread()) { + // TODO find why this cause a runaway phase during shutdown of the test server + if (this.tracker$isServerAndIsServerStopped()/* && !PlatformHooks.INSTANCE.getGeneralHooks().onServerThread() */) { runnable.run(); return; } diff --git a/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java index b30074b2a1c..df8888cb032 100644 --- a/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java +++ b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeSessionListener.java @@ -26,6 +26,7 @@ import org.junit.platform.launcher.LauncherSession; import org.junit.platform.launcher.LauncherSessionListener; +import org.spongepowered.common.applaunch.test.TestGameAccess; public class SpongeSessionListener implements LauncherSessionListener { private ClassLoader previousLoader; @@ -43,6 +44,7 @@ public void launcherSessionOpened(final LauncherSession session) { @Override public void launcherSessionClosed(final LauncherSession session) { + TestGameAccess.shutdownGame(); Thread.currentThread().setContextClassLoader(this.previousLoader); } } diff --git a/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java index 108fa6a7a4f..308264a6407 100644 --- a/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java +++ b/vanilla/src/test/java/org/spongepowered/vanilla/boot/SpongeTestBoot.java @@ -25,16 +25,16 @@ package org.spongepowered.vanilla.boot; import org.spongepowered.bootstrap.forge.VanillaBootstrap; -import org.spongepowered.common.applaunch.test.GameClassLoaderHolder; +import org.spongepowered.common.applaunch.test.TestGameAccess; public class SpongeTestBoot { public static ClassLoader getGameClassLoader() throws Exception { - if (GameClassLoaderHolder.loader == null) { + if (TestGameAccess.getGameClassLoader() == null) { final String[] args = System.getProperty("sponge.test.args").split(" "); System.setProperty("sponge.test.active", "true"); new VanillaBootstrap(args).devBoot(false); } - return GameClassLoaderHolder.loader; + return TestGameAccess.getGameClassLoader(); } } From b3e90021610202a68617d4b58e4b14adefcd2a9f Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Wed, 23 Jul 2025 11:37:07 +0200 Subject: [PATCH 03/11] Force test server properties --- .../dedicated/DedicatedServerMixin_Test.java | 17 ++++++++----- ...=> DedicatedServerSettingsMixin_Test.java} | 24 +++++++++++-------- src/mixins/resources/mixins.sponge.test.json | 2 +- 3 files changed, 26 insertions(+), 17 deletions(-) rename src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/{SettingsMixin_Test.java => DedicatedServerSettingsMixin_Test.java} (62%) diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java index 24af936e95c..34ed5efd881 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerMixin_Test.java @@ -27,20 +27,25 @@ import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.network.ServerConnectionListener; import org.slf4j.Logger; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; import java.net.InetAddress; @Mixin(DedicatedServer.class) public class DedicatedServerMixin_Test { - @Shadow @Final static Logger LOGGER; - @Redirect(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerConnectionListener;startTcpServerListener(Ljava/net/InetAddress;I)V")) - private void dontStartTcpServer(final ServerConnectionListener listener, final InetAddress address, final int port) { - DedicatedServerMixin_Test.LOGGER.info("[TEST] TCP server not started."); + @Redirect(method = "initServer", + at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;info(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V"), + slice = @Slice( + from = @At(value = "INVOKE", target = "net/minecraft/server/dedicated/DedicatedServer.initializeKeyPair()V"), + to = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerConnectionListener;startTcpServerListener(Ljava/net/InetAddress;I)V"))) + private void removeAddressInLog(final Logger logger, final String message, final Object arg1, final Object arg2) { + logger.info("Starting Minecraft test server"); } + + @Redirect(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerConnectionListener;startTcpServerListener(Ljava/net/InetAddress;I)V")) + private void dontStartTcpServer(final ServerConnectionListener listener, final InetAddress address, final int port) {} } diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java similarity index 62% rename from src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java rename to src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java index 510deef81fa..47385cbc346 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/SettingsMixin_Test.java +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java @@ -24,21 +24,25 @@ */ package org.spongepowered.common.mixin.test.server.dedicated; -import net.minecraft.server.dedicated.Settings; -import org.slf4j.Logger; +import net.minecraft.server.dedicated.DedicatedServerProperties; +import net.minecraft.server.dedicated.DedicatedServerSettings; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.Properties; -@Mixin(Settings.class) -public class SettingsMixin_Test { +@Mixin(DedicatedServerSettings.class) +public class DedicatedServerSettingsMixin_Test { - @Redirect(method = "loadFromFile", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V")) - private static void onLoadFromFileError(final Logger logger, final String message, final Object path, final Object exception) { - if (!(exception instanceof NoSuchFileException)) { - logger.error(message, path, exception); - } + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/DedicatedServerProperties;fromFile(Ljava/nio/file/Path;)Lnet/minecraft/server/dedicated/DedicatedServerProperties;")) + public DedicatedServerProperties forceTestProperties(final Path path) { + final Properties props = new Properties(); + props.setProperty("spawn-protection", "0"); + props.setProperty("level-seed", "0"); + props.setProperty("level-type", "flat"); + props.setProperty("enable-command-block", "true"); + return new DedicatedServerProperties(props); } } diff --git a/src/mixins/resources/mixins.sponge.test.json b/src/mixins/resources/mixins.sponge.test.json index d1d903f4dda..d05a9f81b2e 100644 --- a/src/mixins/resources/mixins.sponge.test.json +++ b/src/mixins/resources/mixins.sponge.test.json @@ -5,6 +5,6 @@ "mixins": [ "server.MinecraftServerMixin_Test", "server.dedicated.DedicatedServerMixin_Test", - "server.dedicated.SettingsMixin_Test" + "server.dedicated.DedicatedServerSettingsMixin_Test" ] } From 1752ed55aa457d7f85903731e30d081da4e042f0 Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Wed, 23 Jul 2025 14:14:30 +0200 Subject: [PATCH 04/11] Run SpongeCommon tests in submodules --- build.gradle.kts | 3 ++- forge/build.gradle.kts | 12 +++++++++++- neoforge/build.gradle.kts | 12 +++++++++++- vanilla/build.gradle.kts | 12 +++++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index aa8d5c06871..bda3857402b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -437,7 +437,8 @@ tasks { } test { - useJUnitPlatform() + // tests can only be run in subprojects + enabled = false } check { diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 605cd138435..2e893adfe95 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -88,6 +88,7 @@ val commonAppLaunch = commonProject.sourceSets.named("applaunch") val commonAppLaunchConf = commonProject.sourceSets.named("applaunchConfig") val commonMixins = commonProject.sourceSets.named("mixins") val commonMain = commonProject.sourceSets.named("main") +val commonTest = commonProject.sourceSets.named("test") // SpongeForge source sets // Service layer @@ -166,7 +167,9 @@ val main by sourceSets.named("main") { spongeImpl.addDependencyToRuntimeOnly(bootstrapMain.get(), this) spongeImpl.addDependencyToRuntimeOnly(bootstrapForge.get(), this) } -sourceSets.named("test") { +val testSources = sourceSets.named("test") { + spongeImpl.addDependencyToImplementation(commonTest.get(), this) + spongeImpl.addDependencyToImplementation(bootstrapMain.get(), this) spongeImpl.addDependencyToImplementation(bootstrapForge.get(), this) } @@ -226,6 +229,11 @@ dependencies { testImplementation(apiLibs.junit.params) testImplementation(apiLibs.junit.launcher) testRuntimeOnly(apiLibs.junit.engine) + + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junitJupiter) { + exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") + } } val awFiles: Set = files(commonMain.get().resources, main.resources).filter { it.name.endsWith(".accesswidener") }.files @@ -416,6 +424,8 @@ tasks { test { useJUnitPlatform() + testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs + val runServer = minecraft.runs.getByName("server") jvmArgs(runServer.jvmArgs) jvmArgs("-Dsponge.test.args=" + runServer.args.joinToString(" ")) diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index 01b44992e9c..a78cc276381 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -80,6 +80,7 @@ val commonAppLaunch = commonProject.sourceSets.named("applaunch") val commonAppLaunchConf = commonProject.sourceSets.named("applaunchConfig") val commonMixins = commonProject.sourceSets.named("mixins") val commonMain = commonProject.sourceSets.named("main") +val commonTest = commonProject.sourceSets.named("test") // SpongeNeo source sets // Service layer @@ -158,7 +159,9 @@ val main by sourceSets.named("main") { spongeImpl.addDependencyToRuntimeOnly(bootstrapMain.get(), this) spongeImpl.addDependencyToRuntimeOnly(bootstrapNeoForge.get(), this) } -sourceSets.named("test") { +val testSources = sourceSets.named("test") { + spongeImpl.addDependencyToImplementation(commonTest.get(), this) + spongeImpl.addDependencyToImplementation(bootstrapMain.get(), this) spongeImpl.addDependencyToImplementation(bootstrapNeoForge.get(), this) } @@ -232,6 +235,11 @@ dependencies { testImplementation(apiLibs.junit.params) testImplementation(apiLibs.junit.launcher) testRuntimeOnly(apiLibs.junit.engine) + + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junitJupiter) { + exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") + } } afterEvaluate { @@ -392,6 +400,8 @@ tasks { test { useJUnitPlatform() + testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs + jvmArgs(runServer.get().jvmArgs) jvmArgs("-Dsponge.test.args=" + runServer.get().args!!.joinToString(" ")) workingDir = layout.buildDirectory.dir("test-run").get().asFile diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index f0a129baa74..4f5a36bca04 100644 --- a/vanilla/build.gradle.kts +++ b/vanilla/build.gradle.kts @@ -56,6 +56,7 @@ val commonAppLaunch = commonProject.sourceSets.named("applaunch") val commonAppLaunchConf = commonProject.sourceSets.named("applaunchConfig") val commonMixins = commonProject.sourceSets.named("mixins") val commonMain = commonProject.sourceSets.named("main") +val commonTest = commonProject.sourceSets.named("test") // SpongeVanilla source sets // Prod launch @@ -138,7 +139,9 @@ val main by sourceSets.named("main") { spongeImpl.addDependencyToRuntimeOnly(bootstrapMain.get(), this) spongeImpl.addDependencyToRuntimeOnly(bootstrapForge.get(), this) } -sourceSets.named("test") { +val testSources = sourceSets.named("test") { + spongeImpl.addDependencyToImplementation(commonTest.get(), this) + spongeImpl.addDependencyToImplementation(bootstrapMain.get(), this) spongeImpl.addDependencyToImplementation(bootstrapForge.get(), this) } @@ -256,6 +259,11 @@ dependencies { testImplementation(apiLibs.junit.params) testImplementation(apiLibs.junit.launcher) testRuntimeOnly(apiLibs.junit.engine) + + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junitJupiter) { + exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") + } } minecraft { @@ -494,6 +502,8 @@ tasks { test { useJUnitPlatform() + testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs + val runServer = minecraft.runs.server().get() jvmArgs(runServer.allJvmArguments()) jvmArgs("-Dsponge.test.args=" + runServer.allArguments().joinToString(" ")) From d72cdbd720cdc60a71697ee2296fa2b208ad8a9e Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Wed, 23 Jul 2025 14:14:42 +0200 Subject: [PATCH 05/11] Update existing unit tests --- .../persistence/ConfigurateDataViewTest.java | 20 +- .../common/data/persistence/SimpleData.java | 34 +-- .../tracking/BlockChangeFlagManagerTest.java | 4 +- .../GameTransactionIteratorTest.java | 12 +- .../context/transaction/StubEvent.java | 6 +- .../server/permission/NodeTreeTest.java | 6 +- .../server/permission/package-info.java | 26 --- .../common/test/TestEventManager.java | 12 -- .../spongepowered/common/test/TestLaunch.java | 64 ------ .../common/test/TestPluginPlatform.java | 95 --------- .../common/test/UnitTestExtension.java | 46 ---- .../common/test/block/SpongeBlock.java | 34 --- .../event/EventManagerRegistrationTest.java | 7 +- .../common/test/stub/StubGame.java | 135 ------------ .../common/test/stub/StubKey.java | 72 ------- .../common/test/stub/StubModule.java | 40 ---- .../common/test/stub/block/StubBlock.java | 139 ------------ .../common/test/stub/block/StubState.java | 197 ------------------ .../common/test/stub/block/package-info.java | 29 --- .../common/test/stub/package-info.java | 29 --- .../stub/registry/StubRegistryFactory.java | 47 ----- .../stub/registry/StubRegistryHolder.java | 71 ------- .../test/stub/registry/StubbedRegistry.java | 149 ------------- .../test/stub/registry/package-info.java | 29 --- .../common/test/stub/util/StubMirror.java | 42 ---- .../common/test/stub/util/StubRotations.java | 92 -------- .../common/test/stub/util/package-info.java | 29 --- .../schematic/StubBlockStatePaletteType.java | 46 ---- .../stub/world/schematic/StubPaletteType.java | 53 ----- .../stub/world/schematic/package-info.java | 29 --- .../common/util/ReflectionTest.java | 37 ---- .../common/util/TypeTokenUtilTest.java | 1 - .../VolumeTransformationTest.java | 185 ++++------------ 33 files changed, 64 insertions(+), 1753 deletions(-) delete mode 100644 src/test/java/org/spongepowered/common/service/server/permission/package-info.java delete mode 100644 src/test/java/org/spongepowered/common/test/TestLaunch.java delete mode 100644 src/test/java/org/spongepowered/common/test/TestPluginPlatform.java delete mode 100644 src/test/java/org/spongepowered/common/test/UnitTestExtension.java delete mode 100644 src/test/java/org/spongepowered/common/test/block/SpongeBlock.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/StubGame.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/StubKey.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/StubModule.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/block/StubBlock.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/block/StubState.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/block/package-info.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/package-info.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryFactory.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryHolder.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/registry/StubbedRegistry.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/registry/package-info.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/util/StubMirror.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/util/StubRotations.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/util/package-info.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/world/schematic/StubBlockStatePaletteType.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/world/schematic/StubPaletteType.java delete mode 100644 src/test/java/org/spongepowered/common/test/stub/world/schematic/package-info.java delete mode 100644 src/test/java/org/spongepowered/common/util/ReflectionTest.java diff --git a/src/test/java/org/spongepowered/common/data/persistence/ConfigurateDataViewTest.java b/src/test/java/org/spongepowered/common/data/persistence/ConfigurateDataViewTest.java index 98eb9c236fd..a6d461e3847 100644 --- a/src/test/java/org/spongepowered/common/data/persistence/ConfigurateDataViewTest.java +++ b/src/test/java/org/spongepowered/common/data/persistence/ConfigurateDataViewTest.java @@ -30,7 +30,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.common.collect.Lists; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.data.persistence.DataContainer; @@ -54,7 +53,6 @@ import java.util.List; import java.util.Map; -@Disabled("Can't run these tests without access to a ResourceKey implementation") public class ConfigurateDataViewTest { private static final HoconDataFormat HOCON = new HoconDataFormat(); @@ -71,7 +69,7 @@ void testNodeToData() { node.node("foo", "stringList").raw(stringList); final List dataList = new ArrayList<>(); for (int i = 0; i < 100; i++) { - dataList.add(new SimpleData(i, 10.0 + i, "String" + i, Collections.emptyList())); + dataList.add(new SimpleData(i, 10.0 + i, "String" + i, new String[0])); } node.node("foo", "nested", "Data").raw(dataList); @@ -141,7 +139,7 @@ void testFireworkEffectData() throws IOException { } @Test - void testRespawnLocationData() throws IOException { + void testRespawnLocationData() { final Map m = new HashMap<>(); for (int i = 0; i < 5; i++) { final ResourceKey key = ResourceKey.sponge("overworld" + i); @@ -159,7 +157,7 @@ void testRespawnLocationData() throws IOException { } @Test - void testNumber() throws IOException { + void testNumber() { final DataContainer container = DataContainer.createNew().set(DataQuery.of("double"), 1.0); final ConfigurationNode node = ConfigurateTranslator.instance().translate(container); @@ -193,18 +191,6 @@ void testNullRootKey() { ConfigurateTranslator.instance().translate(BasicConfigurationNode.root().raw("bar"))); } - @Test - void testNullMapKey() { - final ConfigurationNode node = CommentedConfigurationNode.root(); - final Map map = Collections.singletonMap(null, "v"); - final List list = Arrays.asList("e", map); - - node.node("foo").raw("bar"); - node.node("l").raw(list); - - assertThrows(IllegalArgumentException.class, () -> ConfigurateTranslator.instance().translate(node)); - } - @Test void testNonRootNodeToData() { final ConfigurationNode root = CommentedConfigurationNode.root(n -> { diff --git a/src/test/java/org/spongepowered/common/data/persistence/SimpleData.java b/src/test/java/org/spongepowered/common/data/persistence/SimpleData.java index dcfc57fcb0c..4f71b5fdb27 100644 --- a/src/test/java/org/spongepowered/common/data/persistence/SimpleData.java +++ b/src/test/java/org/spongepowered/common/data/persistence/SimpleData.java @@ -24,44 +24,14 @@ */ package org.spongepowered.common.data.persistence; -import com.google.common.collect.ImmutableList; import org.spongepowered.api.data.persistence.DataContainer; import org.spongepowered.api.data.persistence.DataQuery; import org.spongepowered.api.data.persistence.DataSerializable; import java.util.Arrays; -import java.util.List; import java.util.Objects; -final class SimpleData implements DataSerializable { - - private final int testInt; - private final double testDouble; - private final String testString; - private final String[] testList; - - SimpleData(final int testInt, final double testDouble, final String testString, final List testList) { - this.testInt = testInt; - this.testDouble = testDouble; - this.testString = testString; - this.testList = testList.toArray(new String[testList.size()]); - } - - public int getTestInt() { - return this.testInt; - } - - public double getTestDouble() { - return this.testDouble; - } - - public String getTestString() { - return this.testString; - } - - public List getTestList() { - return ImmutableList.copyOf(this.testList); - } +public record SimpleData(int testInt, double testDouble, String testString, String[] testList) implements DataSerializable { @Override public int contentVersion() { @@ -80,7 +50,7 @@ public DataContainer toContainer() { @Override public int hashCode() { - return Objects.hash(this.testInt, this.testDouble, this.testString, this.testList); + return Objects.hash(this.testInt, this.testDouble, this.testString, Arrays.hashCode(this.testList)); } @Override diff --git a/src/test/java/org/spongepowered/common/event/tracking/BlockChangeFlagManagerTest.java b/src/test/java/org/spongepowered/common/event/tracking/BlockChangeFlagManagerTest.java index b2dcc241e94..68d1fce545a 100644 --- a/src/test/java/org/spongepowered/common/event/tracking/BlockChangeFlagManagerTest.java +++ b/src/test/java/org/spongepowered/common/event/tracking/BlockChangeFlagManagerTest.java @@ -34,7 +34,7 @@ import org.spongepowered.common.util.Constants; import org.spongepowered.common.world.SpongeBlockChangeFlag; -class BlockChangeFlagManagerTest { +public class BlockChangeFlagManagerTest { @BeforeAll public static void setupBlockChangeFlagManager() { @@ -280,7 +280,7 @@ void verifyNestedNeighborPhysics() { final SpongeBlockChangeFlag flag = BlockChangeFlagManagerTest.createDefaultFlag(); assertTrue(flag.updateNeighboringShapes()); // 16 assertTrue(flag.getRawFlag() != 0); - assertEquals((flag.getRawFlag() & 32), 0); + assertEquals(0, (flag.getRawFlag() & 32)); assertTrue(flag.neighborDropsAllowed()); final SpongeBlockChangeFlag nestedNeighbor = flag.asNestedNeighborUpdates(); assertFalse(nestedNeighbor.updateNeighbors()); diff --git a/src/test/java/org/spongepowered/common/event/tracking/context/transaction/GameTransactionIteratorTest.java b/src/test/java/org/spongepowered/common/event/tracking/context/transaction/GameTransactionIteratorTest.java index 385ea7cd738..25c47a6ad0e 100644 --- a/src/test/java/org/spongepowered/common/event/tracking/context/transaction/GameTransactionIteratorTest.java +++ b/src/test/java/org/spongepowered/common/event/tracking/context/transaction/GameTransactionIteratorTest.java @@ -28,7 +28,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -36,14 +35,11 @@ import org.spongepowered.common.event.tracking.PhaseTracker; import org.spongepowered.common.event.tracking.context.StubPhaseState; import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect; -import org.spongepowered.common.test.UnitTestExtension; import java.util.Iterator; import java.util.stream.Stream; @Disabled -@SuppressWarnings("deprecation") -@ExtendWith(UnitTestExtension.class) public class GameTransactionIteratorTest { @Test @@ -56,7 +52,7 @@ public void verifyIterator() { @Test public void verifyNestedIterator() { final StubTransaction stubTransaction = new StubTransaction(); - final ResultingTransactionBySideEffect effect = new ResultingTransactionBySideEffect( + final ResultingTransactionBySideEffect effect = new ResultingTransactionBySideEffect<>( InventoryEffect.getInstance()); stubTransaction.addLast(effect); final StubTransaction child1 = new StubTransaction(); @@ -83,7 +79,7 @@ public void verifyDeeplyNestedIterator(final int effectCount, final int childCou final PhaseContext<@NonNull ?> phaseContext = StubPhaseState.getInstance().createPhaseContext(PhaseTracker.getInstance()); phaseContext.buildAndSwitch(); for (int i = 0; i < effectCount; i++) { - final ResultingTransactionBySideEffect effect = new ResultingTransactionBySideEffect( + final ResultingTransactionBySideEffect effect = new ResultingTransactionBySideEffect<>( InventoryEffect.getInstance()); parent.addLast(effect); for (int j = 0; j < childCount; j++) { @@ -120,6 +116,8 @@ private static Stream validateTransactionalIterator() { Arguments.of(293, 87, 112) ); } + + @SuppressWarnings("deprecation") @ParameterizedTest @MethodSource(value = "validateTransactionalIterator") public void validateTransactionalIterator(final int transactionCount, final int effectCount, final int childCount) { @@ -134,7 +132,7 @@ public void validateTransactionalIterator(final int transactionCount, final int transactions[t] = transaction; transactor.logTransaction(transaction); for (int i = 0; i < effectCount; i++) { - final ResultingTransactionBySideEffect effect = new ResultingTransactionBySideEffect( + final ResultingTransactionBySideEffect effect = new ResultingTransactionBySideEffect<>( InventoryEffect.getInstance()); try (final EffectTransactor ignored = transactor.pushEffect(effect)) { for (int j = 0; j < childCount; j++) { diff --git a/src/test/java/org/spongepowered/common/event/tracking/context/transaction/StubEvent.java b/src/test/java/org/spongepowered/common/event/tracking/context/transaction/StubEvent.java index 57224c7ad40..2c668dcafcf 100644 --- a/src/test/java/org/spongepowered/common/event/tracking/context/transaction/StubEvent.java +++ b/src/test/java/org/spongepowered/common/event/tracking/context/transaction/StubEvent.java @@ -26,13 +26,13 @@ import org.spongepowered.api.event.Cancellable; import org.spongepowered.api.event.Cause; -import org.spongepowered.api.event.Event; import org.spongepowered.api.event.EventContext; +import org.spongepowered.api.event.impl.AbstractEvent; import java.util.Collections; -class StubEvent implements Event, Cancellable { - boolean cancelled = false; +public class StubEvent extends AbstractEvent implements Cancellable { + private boolean cancelled = false; @Override public boolean isCancelled() { diff --git a/src/test/java/org/spongepowered/common/service/server/permission/NodeTreeTest.java b/src/test/java/org/spongepowered/common/service/server/permission/NodeTreeTest.java index 12b8fe6342d..4f1d7253c35 100644 --- a/src/test/java/org/spongepowered/common/service/server/permission/NodeTreeTest.java +++ b/src/test/java/org/spongepowered/common/service/server/permission/NodeTreeTest.java @@ -51,7 +51,7 @@ public void testAsMap() { } @Test - public void testWithValue() throws Exception { + public void testWithValue() { final Map testPermissions = new HashMap<>(); testPermissions.put("generate.rainbow", true); testPermissions.put("generate.sunset", false); @@ -66,7 +66,7 @@ public void testWithValue() throws Exception { } @Test - public void testWithAll() throws Exception { + public void testWithAll() { final Map testPermissions = new HashMap<>(); testPermissions.put("generate.rainbow", true); testPermissions.put("generate.sunset", false); @@ -93,7 +93,7 @@ public void testWithAll() throws Exception { } @Test - public void testCreateFromValues() throws Exception { + public void testCreateFromValues() { final Map testPermissions = new HashMap<>(); testPermissions.put("generate.rainbow", true); testPermissions.put("generate.sunset", false); diff --git a/src/test/java/org/spongepowered/common/service/server/permission/package-info.java b/src/test/java/org/spongepowered/common/service/server/permission/package-info.java deleted file mode 100644 index 19060966f56..00000000000 --- a/src/test/java/org/spongepowered/common/service/server/permission/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -@org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class) -package org.spongepowered.common.service.server.permission; diff --git a/src/test/java/org/spongepowered/common/test/TestEventManager.java b/src/test/java/org/spongepowered/common/test/TestEventManager.java index 94a37a48fae..7ba12eaca53 100644 --- a/src/test/java/org/spongepowered/common/test/TestEventManager.java +++ b/src/test/java/org/spongepowered/common/test/TestEventManager.java @@ -24,19 +24,7 @@ */ package org.spongepowered.common.test; -import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.common.event.manager.SpongeEventManager; -import org.spongepowered.common.util.DefinableClassLoader; public class TestEventManager extends SpongeEventManager { - - private final @Nullable DefinableClassLoader loader; - - public TestEventManager(final DefinableClassLoader loader) { - this.loader = loader; - } - - public TestEventManager() { - this.loader = null; - } } diff --git a/src/test/java/org/spongepowered/common/test/TestLaunch.java b/src/test/java/org/spongepowered/common/test/TestLaunch.java deleted file mode 100644 index 365f3f774cc..00000000000 --- a/src/test/java/org/spongepowered/common/test/TestLaunch.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import com.google.inject.Injector; -import com.google.inject.Stage; -import org.spongepowered.common.applaunch.plugin.PluginPlatform; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.common.launch.plugin.SpongePluginManager; -import org.spongepowered.plugin.PluginContainer; - -public class TestLaunch extends Launch { - - protected TestLaunch(final PluginPlatform pluginPlatform) { - super(pluginPlatform); - } - - @Override - public boolean dedicatedServer() { - return false; - } - - @Override - public SpongePluginManager pluginManager() { - return null; - } - - @Override - public Stage injectionStage() { - return null; - } - - @Override - public PluginContainer platformPlugin() { - return null; - } - - @Override - public Injector createInjector() { - return null; - } -} diff --git a/src/test/java/org/spongepowered/common/test/TestPluginPlatform.java b/src/test/java/org/spongepowered/common/test/TestPluginPlatform.java deleted file mode 100644 index 922e8e4a7e4..00000000000 --- a/src/test/java/org/spongepowered/common/test/TestPluginPlatform.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.common.applaunch.config.LaunchConfig; -import org.spongepowered.common.applaunch.config.TokenReplacement; -import org.spongepowered.common.applaunch.plugin.PluginPlatform; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.List; - -/** - * The absolute minimum required to have a plugin platform to function - * with regard to SpongeCommon's configurations being usable. Required - * to be used if the {@link org.spongepowered.common.event.tracking.PhaseTracker} - * is being utilized since the configurations are being checked. - */ -public class TestPluginPlatform implements PluginPlatform { - - private static final Logger LOGGER = LogManager.getLogger("UnitTestPlatform"); - - private final Path baseDirectory; - private final Path pluginsDirectory; - - public TestPluginPlatform() { - this.baseDirectory = Paths.get("."); - this.pluginsDirectory = this.baseDirectory.resolve("plugins"); - } - - @Override - public String version() { - return "unit-test"; - } - - @Override - public Logger logger() { - return TestPluginPlatform.LOGGER; - } - - @Override - public boolean vanilla() { - return true; - } - - @Override - public Path baseDirectory() { - return this.baseDirectory; - } - - @Override - public Path configDirectory() { - return this.baseDirectory.resolve("config"); - } - - @Override - public LaunchConfig config() { - return LaunchConfig.DEFAULT; - } - - @Override - public TokenReplacement tokens() { - return new TokenReplacement(); - } - - @Override - public List pluginDirectories() { - return Collections.singletonList(this.pluginsDirectory); - } -} diff --git a/src/test/java/org/spongepowered/common/test/UnitTestExtension.java b/src/test/java/org/spongepowered/common/test/UnitTestExtension.java deleted file mode 100644 index 58c31d5db42..00000000000 --- a/src/test/java/org/spongepowered/common/test/UnitTestExtension.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import net.minecraft.DetectedVersion; -import net.minecraft.SharedConstants; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.spongepowered.common.applaunch.AppLaunch; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.common.launch.config.core.SpongeConfigs; - -public class UnitTestExtension implements BeforeAllCallback { - @Override - public void beforeAll(final ExtensionContext context) throws Exception { - final TestPluginPlatform platform = new TestPluginPlatform(); - if (AppLaunch.pluginPlatform() == null) { - AppLaunch.setPluginPlatform(platform); - Launch.setInstance(new TestLaunch(platform)); - SpongeConfigs.getCommon(); - SharedConstants.setVersion(DetectedVersion.tryDetectVersion()); - } - } -} diff --git a/src/test/java/org/spongepowered/common/test/block/SpongeBlock.java b/src/test/java/org/spongepowered/common/test/block/SpongeBlock.java deleted file mode 100644 index 3fbae6a0c5f..00000000000 --- a/src/test/java/org/spongepowered/common/test/block/SpongeBlock.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.block; - -import net.minecraft.world.level.block.Block; - -public class SpongeBlock extends Block { - public SpongeBlock(Properties param0) { - super(param0); - } - -} diff --git a/src/test/java/org/spongepowered/common/test/event/EventManagerRegistrationTest.java b/src/test/java/org/spongepowered/common/test/event/EventManagerRegistrationTest.java index afe094ba1a4..c920b2173ed 100644 --- a/src/test/java/org/spongepowered/common/test/event/EventManagerRegistrationTest.java +++ b/src/test/java/org/spongepowered/common/test/event/EventManagerRegistrationTest.java @@ -24,9 +24,7 @@ */ package org.spongepowered.common.test.event; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; @@ -46,14 +44,11 @@ import org.spongepowered.api.event.lifecycle.StoppedGameEvent; import org.spongepowered.api.service.economy.EconomyService; import org.spongepowered.common.test.TestEventManager; -import org.spongepowered.common.test.UnitTestExtension; import org.spongepowered.common.util.DefinableClassLoader; import org.spongepowered.plugin.PluginContainer; import java.lang.reflect.InvocationTargetException; -@Disabled -@ExtendWith(UnitTestExtension.class) public class EventManagerRegistrationTest { @Test @@ -77,7 +72,7 @@ public void successfulRegistrationWithAsmDefinedClass() throws InstantiationException, IllegalAccessException { final var loader = new DefinableClassLoader(Thread.currentThread().getContextClassLoader()); - final EventManager eventManager = new TestEventManager(loader); + final EventManager eventManager = new TestEventManager(); final PluginContainer mock = Mockito.mock(PluginContainer.class); final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); writer.visit( diff --git a/src/test/java/org/spongepowered/common/test/stub/StubGame.java b/src/test/java/org/spongepowered/common/test/stub/StubGame.java deleted file mode 100644 index 504500fdc8f..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/StubGame.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.Game; -import org.spongepowered.api.Platform; -import org.spongepowered.api.Server; -import org.spongepowered.api.SystemSubject; -import org.spongepowered.api.config.ConfigManager; -import org.spongepowered.api.data.DataManager; -import org.spongepowered.api.event.EventManager; -import org.spongepowered.api.network.channel.ChannelManager; -import org.spongepowered.api.plugin.PluginManager; -import org.spongepowered.api.scheduler.Scheduler; -import org.spongepowered.api.service.ServiceProvider; -import org.spongepowered.api.util.metric.MetricsConfigManager; -import org.spongepowered.common.registry.SpongeBuilderProvider; -import org.spongepowered.common.registry.SpongeFactoryProvider; -import org.spongepowered.common.test.stub.registry.StubRegistryHolder; - -import java.nio.file.Path; -import java.util.Locale; - -import javax.inject.Singleton; - -@Singleton -public class StubGame extends StubRegistryHolder implements Game { - - private final SpongeFactoryProvider provider = new SpongeFactoryProvider(); - private final SpongeBuilderProvider builder = new SpongeBuilderProvider(); - - @Override - public Scheduler asyncScheduler() { - return null; - } - - @Override - public Path gameDirectory() { - return null; - } - - @Override - public boolean isServerAvailable() { - return false; - } - - @Override - public Server server() { - return null; - } - - @Override - public SystemSubject systemSubject() { - return null; - } - - @Override - public Locale locale(@NonNull String locale) { - return null; - } - - @Override - public Platform platform() { - return null; - } - - @Override - public SpongeBuilderProvider builderProvider() { - return this.builder; - } - - @Override - public SpongeFactoryProvider factoryProvider() { - return this.provider; - } - - @Override - public DataManager dataManager() { - return null; - } - - @Override - public PluginManager pluginManager() { - return null; - } - - @Override - public EventManager eventManager() { - return null; - } - - @Override - public ConfigManager configManager() { - return null; - } - - @Override - public ChannelManager channelManager() { - return null; - } - - @Override - public MetricsConfigManager metricsConfigManager() { - return null; - } - - @Override - public ServiceProvider.GameScoped serviceProvider() { - return null; - } - -} diff --git a/src/test/java/org/spongepowered/common/test/stub/StubKey.java b/src/test/java/org/spongepowered/common/test/stub/StubKey.java deleted file mode 100644 index c67fd9206e5..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/StubKey.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.ResourceKey; - -import java.util.Objects; - -public final class StubKey implements ResourceKey { - public final String namespace; - public final String key; - - public StubKey(final String namespace, final String key) { - this.namespace = namespace; - this.key = key; - } - - @Override - public @NonNull String namespace() { - return this.namespace; - } - - @Override - public @NonNull String value() { - return this.key; - } - - @Override - public String toString() { - return this.asString(); - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - final StubKey stubKey = (StubKey) o; - return this.namespace.equals(stubKey.namespace) && this.key.equals(stubKey.key); - } - - @Override - public int hashCode() { - return Objects.hash(this.namespace, this.key); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/StubModule.java b/src/test/java/org/spongepowered/common/test/stub/StubModule.java deleted file mode 100644 index 2cee5e30330..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/StubModule.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub; - -import com.google.inject.AbstractModule; -import org.spongepowered.api.Game; -import org.spongepowered.api.Sponge; - -public class StubModule extends AbstractModule { - - @Override - protected void configure() { - this.bind(Game.class).to(StubGame.class); - - this.requestStaticInjection(Sponge.class); - - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/block/StubBlock.java b/src/test/java/org/spongepowered/common/test/stub/block/StubBlock.java deleted file mode 100644 index e376dd32df5..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/block/StubBlock.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.block; - -import com.google.common.collect.ImmutableList; -import net.kyori.adventure.text.Component; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.block.BlockSoundGroup; -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockType; -import org.spongepowered.api.item.ItemType; -import org.spongepowered.api.registry.DefaultedRegistryType; -import org.spongepowered.api.state.StateProperty; -import org.spongepowered.api.tag.Tag; -import org.spongepowered.common.data.holder.SpongeImmutableDataHolder; -import org.spongepowered.math.vector.Vector3i; - -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; -import java.util.function.Supplier; -import java.util.stream.Stream; - -public class StubBlock implements SpongeImmutableDataHolder, BlockType { - - private static final Vector3i INVALID_STUB_POSITION = Vector3i.from( - Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); - private final BlockState air; - public final Vector3i deducedPos; - public StubBlock(final ResourceKey key) { - final Vector3i deducedPos; - final String value = key.value(); - if (value.startsWith("volumetest")) { - final String replace = value.replace("volumetest{", "") - .replace("}", ""); - final String[] split = replace.split(","); - if (split.length == 3) { - final int x = Integer.parseInt(split[0].replace(" ", "")); - final int y = Integer.parseInt(split[1].replace(" ", "")); - final int z = Integer.parseInt(split[2].replace(" ", "")); - deducedPos = new Vector3i(x, y, z); - } else { - deducedPos = StubBlock.INVALID_STUB_POSITION; - } - } else { - deducedPos = StubBlock.INVALID_STUB_POSITION; - } - this.air = new StubState(this, key, deducedPos); - this.deducedPos = deducedPos; - } - - @Override - public Optional item() { - return Optional.empty(); - } - - @Override - public boolean doesUpdateRandomly() { - return false; - } - - @Override - public void setUpdateRandomly(final boolean updateRandomly) { - - } - - @Override - public BlockSoundGroup soundGroup() { - return null; - } - - @Override - public boolean isAnyOf(final Supplier... types) { - return false; - } - - @Override - public boolean isAnyOf(final BlockType... types) { - return false; - } - - @Override - public boolean hasBlockEntity() { - return false; - } - - @Override - public @NonNull Component asComponent() { - return null; - } - - @Override - public ImmutableList validStates() { - return ImmutableList.of(this.air); - } - - @Override - public BlockState defaultState() { - return this.air; - } - - @Override - public Collection> stateProperties() { - return Collections.emptyList(); - } - - @Override - public Optional> findStateProperty(final String name) { - return Optional.empty(); - } - - @Override - public Stream> tags(DefaultedRegistryType registryType) { - return Stream.empty(); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/block/StubState.java b/src/test/java/org/spongepowered/common/test/stub/block/StubState.java deleted file mode 100644 index 70902f9bff4..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/block/StubState.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.block; - -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.block.BlockSnapshot; -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockType; -import org.spongepowered.api.data.Key; -import org.spongepowered.api.data.persistence.DataContainer; -import org.spongepowered.api.data.persistence.DataView; -import org.spongepowered.api.data.persistence.InvalidDataException; -import org.spongepowered.api.data.value.Value; -import org.spongepowered.api.fluid.FluidState; -import org.spongepowered.api.state.StateProperty; -import org.spongepowered.api.util.Cycleable; -import org.spongepowered.api.util.Direction; -import org.spongepowered.api.util.mirror.Mirror; -import org.spongepowered.api.util.rotation.Rotation; -import org.spongepowered.api.world.server.ServerLocation; -import org.spongepowered.common.data.holder.SpongeImmutableDataHolder; -import org.spongepowered.math.vector.Vector3i; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.StringJoiner; - -public final class StubState implements BlockState, SpongeImmutableDataHolder { - - private final BlockType mocked; - public final ResourceKey key; - public final Vector3i deducedPos; - - public StubState(final BlockType mocked, final ResourceKey key, final Vector3i deducedPos) { - this.mocked = mocked; - this.key = key; - this.deducedPos = deducedPos; - } - - @Override - public BlockType type() { - return this.type(); - } - - @Override - public FluidState fluidState() { - return null; - } - - @Override - public BlockSnapshot snapshotFor(final ServerLocation location) { - return null; - } - - @Override - public BlockState rotate(final Rotation rotation) { - return this; - } - - @Override - public BlockState mirror(final Mirror mirror) { - return this; - } - - @Override - public String asString() { - return null; - } - - @Override - public Optional get( - final Direction direction, final Key> key - ) { - return Optional.empty(); - } - - @Override - public boolean validateRawData(final DataView container) { - return false; - } - - @Override - public BlockState withRawData(final DataView container) throws InvalidDataException { - return this; - } - - @Override - public BlockState copy() { - return this; - } - - @Override - public int contentVersion() { - return 0; - } - - @Override - public DataContainer toContainer() { - return null; - } - - @Override - public > Optional stateProperty(final StateProperty stateProperty) { - return Optional.empty(); - } - - @Override - public Optional> findStateProperty(final String name) { - return Optional.empty(); - } - - @Override - public , V extends T> Optional withStateProperty( - final StateProperty stateProperty, final V value - ) { - return Optional.empty(); - } - - @Override - public > Optional cycleStateProperty( - final StateProperty stateProperty - ) { - return Optional.empty(); - } - - @Override - public > Optional cycleValue( - final Key> key - ) { - return Optional.empty(); - } - - @Override - public Collection> stateProperties() { - return Collections.emptySet(); - } - - @Override - public Collection statePropertyValues() { - return Collections.emptySet(); - } - - @Override - public Map, ?> statePropertyMap() { - return Collections.emptyMap(); - } - - @Override - public String toString() { - return new StringJoiner(", ", StubState.class.getSimpleName() + "[", "]") - .add("mocked=" + this.mocked) - .add("key=" + this.key) - .toString(); - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - final StubState stubState = (StubState) o; - return this.mocked.equals(stubState.mocked) && this.key.equals(stubState.key); - } - - @Override - public int hashCode() { - return Objects.hash(this.mocked, this.key); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/block/package-info.java b/src/test/java/org/spongepowered/common/test/stub/block/package-info.java deleted file mode 100644 index 652738343db..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/block/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -@DefaultQualifier(NonNull.class) -package org.spongepowered.common.test.stub.block; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/test/java/org/spongepowered/common/test/stub/package-info.java b/src/test/java/org/spongepowered/common/test/stub/package-info.java deleted file mode 100644 index c4df1f35dfa..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -@DefaultQualifier(NonNull.class) -package org.spongepowered.common.test.stub; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryFactory.java b/src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryFactory.java deleted file mode 100644 index 8c2a5f26616..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.registry; - -import org.spongepowered.api.ResourceKey; -import org.spongepowered.common.test.stub.StubKey; -import org.spongepowered.plugin.PluginContainer; - -public class StubRegistryFactory implements ResourceKey.Factory{ - - @Override - public ResourceKey of(final String namespace, final String value) { - return new StubKey(namespace, value); - } - - @Override - public ResourceKey of(final PluginContainer plugin, final String value) { - return new StubKey(plugin.metadata().id(), value); - } - - @Override - public ResourceKey resolve(final String formatted) { - return new StubKey(formatted.split(":")[0], formatted.split(":")[1]); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryHolder.java b/src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryHolder.java deleted file mode 100644 index 86433b2234d..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/registry/StubRegistryHolder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.registry; - -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.registry.Registry; -import org.spongepowered.api.registry.RegistryHolder; -import org.spongepowered.api.registry.RegistryType; - -import java.util.Collection; -import java.util.Optional; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.stream.Stream; - -public class StubRegistryHolder implements RegistryHolder { - - private final Collection> registries = new ConcurrentLinkedDeque<>(); - - public void register(final StubbedRegistry registry) { - this.registries.add(registry); - } - - @SuppressWarnings("unchecked") - @Override - public Registry registry(final RegistryType type) { - return this.registries.stream().filter(r -> r.type() == type).findFirst() - .map(r -> (Registry) r) - .orElseThrow(() -> new IllegalStateException("Registry for type not available:" + type.toString())); - } - - @SuppressWarnings("unchecked") - @Override - public Optional> findRegistry( - final RegistryType type - ) { - return this.registries.stream().filter(r -> r.type() == type).findFirst() - .map(r -> (Registry) r); - } - - @Override - public Stream> streamRegistries() { - return Stream.empty(); - } - - @Override - public Stream> streamRegistries(final ResourceKey root) { - return Stream.of(); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/registry/StubbedRegistry.java b/src/test/java/org/spongepowered/common/test/stub/registry/StubbedRegistry.java deleted file mode 100644 index 59651a29340..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/registry/StubbedRegistry.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.registry; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.registry.Registry; -import org.spongepowered.api.registry.RegistryEntry; -import org.spongepowered.api.registry.RegistryType; -import org.spongepowered.api.tag.Tag; -import org.spongepowered.common.registry.SpongeRegistryEntry; -import org.spongepowered.common.test.stub.StubKey; - -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Stream; - -public class StubbedRegistry implements Registry { - - private final BiMap stubs = HashBiMap.create(); - private final BiMap> entries = HashBiMap.create(); - private final Supplier> typeSupplier; - private final Function generator; - - public StubbedRegistry(final Supplier> typeSupplier, final Function generator) { - this.typeSupplier = typeSupplier; - this.generator = generator; - } - - public T createEntry(final String namespace, final String desired) { - final ResourceKey key = new StubKey(namespace, desired); - return this.getOrCreate(key); - } - - @Override - public RegistryType type() { - return this.typeSupplier.get(); - } - - @Override - public ResourceKey valueKey(final T value) { - return this.findValueKey(value).orElseThrow(() -> new IllegalArgumentException("Could not find key for value: " + value)); - } - - @Override - public Optional findValueKey(final T value) { - final ResourceKey resourceKey = this.stubs.inverse().get(value); - return Optional.ofNullable(resourceKey); - } - - @SuppressWarnings("unchecked") - @Override - public Optional> findEntry( - final ResourceKey key - ) { - final RegistryEntry entry = this.entries.computeIfAbsent(key, (k) -> { - final T stub = this.getOrCreate(k); - return new SpongeRegistryEntry<>(this.type(), k, stub); - }); - return Optional.of((RegistryEntry) entry); - } - - private T getOrCreate(final ResourceKey key) { - if (this.stubs.containsKey(key)) { - return this.stubs.get(key); - } - // otherwise, set up the blocks - final T type = this.generator.apply(key); - this.stubs.put(key, type); - this.entries.put(key, new SpongeRegistryEntry<>(this.type(), key, type)); - return type; - } - - @SuppressWarnings("unchecked") - @Override - public Optional findValue(final ResourceKey key) { - - return Optional.of((V) this.getOrCreate(key)); - } - - @SuppressWarnings("unchecked") - @Override - public V value(final ResourceKey key) { - return (V) this.getOrCreate(key); - } - - @Override - public Stream taggedValues(final Tag tag) { - return Stream.empty(); - } - - @Override - public Stream> tags() { - return Stream.empty(); - } - - @Override - public Stream> streamEntries() { - return this.entries.values().stream(); - } - - @Override - public Stream stream() { - return this.stubs.values().stream(); - } - - @Override - public boolean isDynamic() { - return false; - } - - @SuppressWarnings("unchecked") - @Override - public Optional> register(final ResourceKey key, final V value) { - final RegistryEntry entry; - if (!this.entries.containsKey(key)) { - entry = new SpongeRegistryEntry<>(this.type(), key, value); - this.entries.put(key, entry); - this.stubs.put(key, value); - } else { - entry = this.entries.get(key); - } - return Optional.of((RegistryEntry) entry); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/registry/package-info.java b/src/test/java/org/spongepowered/common/test/stub/registry/package-info.java deleted file mode 100644 index d1822b80116..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/registry/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -@DefaultQualifier(NonNull.class) -package org.spongepowered.common.test.stub.registry; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/test/java/org/spongepowered/common/test/stub/util/StubMirror.java b/src/test/java/org/spongepowered/common/test/stub/util/StubMirror.java deleted file mode 100644 index 9e022af2715..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/util/StubMirror.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.util; - -import org.spongepowered.api.util.mirror.Mirror; -import org.spongepowered.common.test.stub.StubKey; -import org.spongepowered.common.test.stub.registry.StubbedRegistry; - -public enum StubMirror implements Mirror { - NONE, - LEFT_RIGHT, - FRONT_BACK; - - public static void registerDefaults(final StubbedRegistry registry) { - registry.register(new StubKey("sponge", "none"), StubMirror.NONE); - registry.register(new StubKey("sponge", "left_right"), StubMirror.LEFT_RIGHT); - registry.register(new StubKey("sponge", "front_back"), StubMirror.FRONT_BACK); - } - -} diff --git a/src/test/java/org/spongepowered/common/test/stub/util/StubRotations.java b/src/test/java/org/spongepowered/common/test/stub/util/StubRotations.java deleted file mode 100644 index ae07d2b3486..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/util/StubRotations.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.util; - -import org.spongepowered.api.util.Angle; -import org.spongepowered.api.util.rotation.Rotation; -import org.spongepowered.common.test.stub.StubKey; -import org.spongepowered.common.test.stub.registry.StubbedRegistry; - -public enum StubRotations implements Rotation { - NONE(0), - CLOCKWISE_90(90), - CLOCKWISE_180(180), - COUNTERCLOCKWISE_90(-90); - - public static void registerDefaults(final StubbedRegistry registry) { - registry.register(new StubKey("sponge", "none"), StubRotations.NONE); - registry.register(new StubKey("sponge", "clockwise_90"), StubRotations.CLOCKWISE_90); - registry.register(new StubKey("sponge", "clockwise_180"), StubRotations.CLOCKWISE_180); - registry.register(new StubKey("sponge", "counterclockwise_90"), StubRotations.COUNTERCLOCKWISE_90); - } - - private final int angle; - - StubRotations(final int angle) { - this.angle = angle; - } - - @Override - public Rotation and(final Rotation rotation) { - if (!(rotation instanceof StubRotations)) { - throw new IllegalStateException("Shouldn't be operating on anything but stubrotations"); - } - if (((StubRotations) rotation).angle == 0) { - return this; - } - final StubRotations stub = (StubRotations) rotation; - switch (this) { - case NONE: return rotation; - case CLOCKWISE_90: { - switch (stub) { - case CLOCKWISE_90: return StubRotations.CLOCKWISE_180; - case CLOCKWISE_180: return StubRotations.COUNTERCLOCKWISE_90; - case COUNTERCLOCKWISE_90: return StubRotations.NONE; - default: return this; - } - } - case CLOCKWISE_180: { - switch (stub) { - case CLOCKWISE_90: return StubRotations.COUNTERCLOCKWISE_90; - case CLOCKWISE_180: return StubRotations.NONE; - case COUNTERCLOCKWISE_90: return StubRotations.CLOCKWISE_90; - } - } - case COUNTERCLOCKWISE_90: { - switch (stub) { - case CLOCKWISE_90: return StubRotations.NONE; - case CLOCKWISE_180: return StubRotations.CLOCKWISE_90; - case COUNTERCLOCKWISE_90: return StubRotations.CLOCKWISE_180; - } - } - } - throw new IllegalStateException("Impossible state"); - } - - @Override - public Angle angle() { - return Angle.fromDegrees(this.angle); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/util/package-info.java b/src/test/java/org/spongepowered/common/test/stub/util/package-info.java deleted file mode 100644 index 5f94753ba74..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/util/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -@DefaultQualifier(NonNull.class) -package org.spongepowered.common.test.stub.util; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/test/java/org/spongepowered/common/test/stub/world/schematic/StubBlockStatePaletteType.java b/src/test/java/org/spongepowered/common/test/stub/world/schematic/StubBlockStatePaletteType.java deleted file mode 100644 index 119c0f27761..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/world/schematic/StubBlockStatePaletteType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.world.schematic; - -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockType; -import org.spongepowered.api.registry.Registry; -import org.spongepowered.common.test.stub.StubKey; -import org.spongepowered.common.test.stub.block.StubState; -import org.spongepowered.common.world.schematic.SpongePaletteType; - -import java.util.Optional; - -public class StubBlockStatePaletteType extends SpongePaletteType { - public StubBlockStatePaletteType() { - super(StubBlockStatePaletteType::apply, (rRegistry, t) -> ((StubState) t).key.asString()); - } - - private static Optional apply(final String s, final Registry r) { - final String[] split = s.split(":"); - final StubKey key = new StubKey(split[0], split[1]); - return r.findValue(key).map(BlockType::defaultState); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/world/schematic/StubPaletteType.java b/src/test/java/org/spongepowered/common/test/stub/world/schematic/StubPaletteType.java deleted file mode 100644 index 4d1c11b2c15..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/world/schematic/StubPaletteType.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.stub.world.schematic; - -import org.spongepowered.api.block.BlockType; -import org.spongepowered.api.registry.Registry; -import org.spongepowered.api.registry.RegistryTypes; -import org.spongepowered.common.test.stub.StubKey; -import org.spongepowered.common.test.stub.block.StubState; -import org.spongepowered.common.world.schematic.SpongePaletteType; - -import java.util.Optional; - -@SuppressWarnings({"rawtypes", "unchecked"}) -public class StubPaletteType extends SpongePaletteType { - @SuppressWarnings("UnnecessaryLocalVariable") - public StubPaletteType() { - super((s, r) -> { - final String[] split = s.split(":"); - final StubKey key = new StubKey(split[0], split[1]); - if (r.type() == RegistryTypes.BLOCK_TYPE) { - final Optional t = r.findValue(key).map(v -> ((BlockType) v).defaultState()); - return t; - } - final Optional value = r.findValue(key); - return value; - }, ((rRegistry, t) -> (t instanceof StubState) - ? ((StubState) t).key.asString() - : ((Registry) rRegistry).valueKey(t).asString())); - } -} diff --git a/src/test/java/org/spongepowered/common/test/stub/world/schematic/package-info.java b/src/test/java/org/spongepowered/common/test/stub/world/schematic/package-info.java deleted file mode 100644 index 8ff6b259b6b..00000000000 --- a/src/test/java/org/spongepowered/common/test/stub/world/schematic/package-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -@DefaultQualifier(NonNull.class) -package org.spongepowered.common.test.stub.world.schematic; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/src/test/java/org/spongepowered/common/util/ReflectionTest.java b/src/test/java/org/spongepowered/common/util/ReflectionTest.java deleted file mode 100644 index 6f40b536677..00000000000 --- a/src/test/java/org/spongepowered/common/util/ReflectionTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.util; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.extension.ExtendWith; -import org.spongepowered.common.test.UnitTestExtension; - - -@Disabled -@ExtendWith(UnitTestExtension.class) -public class ReflectionTest { - - -} diff --git a/src/test/java/org/spongepowered/common/util/TypeTokenUtilTest.java b/src/test/java/org/spongepowered/common/util/TypeTokenUtilTest.java index 7ad58972742..19c39bff052 100644 --- a/src/test/java/org/spongepowered/common/util/TypeTokenUtilTest.java +++ b/src/test/java/org/spongepowered/common/util/TypeTokenUtilTest.java @@ -43,7 +43,6 @@ public final class TypeTokenUtilTest { @SuppressWarnings("rawtypes") - @Test @Disabled public void testA() { assertTrue(TypeTokenUtil.isAssignable( diff --git a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java index b78ad302ca2..a8c28ec8297 100644 --- a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java +++ b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java @@ -24,134 +24,44 @@ */ package org.spongepowered.common.util.transformation; -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.Injector; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.spongepowered.api.Game; -import org.spongepowered.api.ResourceKey; import org.spongepowered.api.Sponge; -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockType; -import org.spongepowered.api.event.EventContextKey; +import org.spongepowered.api.block.entity.BlockEntityArchetype; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.data.persistence.DataQuery; import org.spongepowered.api.registry.RegistryHolder; -import org.spongepowered.api.registry.RegistryKey; -import org.spongepowered.api.registry.RegistryType; -import org.spongepowered.api.registry.RegistryTypes; -import org.spongepowered.api.util.mirror.Mirror; import org.spongepowered.api.util.rotation.Rotation; import org.spongepowered.api.util.rotation.Rotations; import org.spongepowered.api.util.transformation.Transformation; -import org.spongepowered.api.world.biome.Biome; -import org.spongepowered.api.world.schematic.PaletteReference; -import org.spongepowered.api.world.schematic.PaletteType; import org.spongepowered.api.world.volume.archetype.ArchetypeVolume; import org.spongepowered.api.world.volume.stream.StreamOptions; import org.spongepowered.api.world.volume.stream.VolumePositionTranslators; -import org.spongepowered.common.event.SpongeEventContextKeyBuilder; -import org.spongepowered.common.registry.SpongeBuilderProvider; -import org.spongepowered.common.registry.SpongeFactoryProvider; -import org.spongepowered.common.registry.SpongeRegistryKey; -import org.spongepowered.common.registry.SpongeRegistryType; -import org.spongepowered.common.test.UnitTestExtension; -import org.spongepowered.common.test.stub.StubGame; -import org.spongepowered.common.test.stub.StubKey; -import org.spongepowered.common.test.stub.StubModule; -import org.spongepowered.common.test.stub.block.StubBlock; -import org.spongepowered.common.test.stub.block.StubState; -import org.spongepowered.common.test.stub.registry.StubRegistryFactory; -import org.spongepowered.common.test.stub.registry.StubbedRegistry; -import org.spongepowered.common.test.stub.util.StubMirror; -import org.spongepowered.common.test.stub.util.StubRotations; -import org.spongepowered.common.test.stub.world.schematic.StubBlockStatePaletteType; -import org.spongepowered.common.test.stub.world.schematic.StubPaletteType; -import org.spongepowered.common.world.schematic.SpongePaletteReferenceFactory; import org.spongepowered.common.world.volume.buffer.archetype.AbstractReferentArchetypeVolume; import org.spongepowered.common.world.volume.buffer.archetype.SpongeArchetypeVolume; -import org.spongepowered.common.world.volume.stream.SpongeStreamOptionsBuilder; import org.spongepowered.math.vector.Vector3d; import org.spongepowered.math.vector.Vector3i; -import java.util.stream.IntStream; +import java.util.Optional; import java.util.stream.Stream; @Disabled -@SuppressWarnings("rawtypes") -@ExtendWith({ MockitoExtension.class, UnitTestExtension.class }) +@ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) public final class VolumeTransformationTest { private static final Vector3i INVALID_STUB_POSITION = Vector3i.from( Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); - private static final Injector guice = Guice.createInjector(new StubModule()); + private static final DataQuery POS = DataQuery.of("pos"); - @SuppressWarnings("unused") - static class DummyInjectable { - @Inject Game game; - } - - @BeforeAll - static void setup() { - VolumeTransformationTest.guice.injectMembers(new DummyInjectable()); - final StubGame game = (StubGame) Sponge.game(); - - final SpongeFactoryProvider factoryProvider = game.factoryProvider(); - final SpongeBuilderProvider builderProvider = game.builderProvider(); - // Set up Rotations - final StubbedRegistry rotation = new StubbedRegistry<>( - () -> RegistryTypes.ROTATION, - (k) -> Rotations.NONE.get() - ); - - // Set up Blocks and BlockState - final StubbedRegistry blocktypes = new StubbedRegistry<>( - () -> RegistryTypes.BLOCK_TYPE, - StubBlock::new - ); - // Set up biomes - final StubbedRegistry biomes = new StubbedRegistry<>( - () -> RegistryTypes.BIOME, - (key) -> Mockito.mock(Biome.class) - ); - // Set up palettes - final StubbedRegistry> paletteTypeRegistry = new StubbedRegistry<>( - () -> RegistryTypes.PALETTE_TYPE, - (key) -> new StubPaletteType<>() - ); - factoryProvider.registerFactory(RegistryType.Factory.class, new SpongeRegistryType.FactoryImpl()); - factoryProvider.registerFactory(RegistryKey.Factory.class, new SpongeRegistryKey.FactoryImpl()); - factoryProvider.registerFactory(PaletteReference.Factory.class, new SpongePaletteReferenceFactory()); - // and finally, set up the resourcekey stuff - factoryProvider.registerFactory(ResourceKey.Factory.class, new StubRegistryFactory()); - game.register(rotation); - game.register(blocktypes); - game.register(biomes); - game.register(paletteTypeRegistry); - final StubbedRegistry mirror = new StubbedRegistry<>( - () -> RegistryTypes.MIRROR, (k) -> Mockito.mock(Mirror.class)); - StubMirror.registerDefaults(mirror); - game.register(mirror); - - builderProvider.register(EventContextKey.Builder.class, SpongeEventContextKeyBuilder::new); - builderProvider.register(Transformation.Builder.class, SpongeTransformationBuilder::new); - builderProvider.register(StreamOptions.Builder.class, SpongeStreamOptionsBuilder::new); - StubRotations.registerDefaults(rotation); - - paletteTypeRegistry.register(new StubKey("sponge", "block_state_palette"), new StubBlockStatePaletteType()); - } - - @SuppressWarnings("unused") // IDEA bug not noticing this method is used by junit to populate parameters private static Stream testTransformationsOfPositions() { return Stream.of( Arguments.of( @@ -160,7 +70,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.ZERO, Vector3i.from(1, 1, 1), 0, - StubRotations.NONE + Rotations.NONE.get() ), Arguments.of( Vector3i.ZERO, @@ -168,7 +78,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.UNIT_X, Vector3i.from(1, 1, 1), 1, - StubRotations.CLOCKWISE_90 + Rotations.CLOCKWISE_90.get() ), Arguments.of( Vector3i.ZERO, @@ -176,7 +86,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.from(-1, 1, 4), Vector3i.from(1, 1, 1), 0, - StubRotations.NONE + Rotations.NONE.get() ), Arguments.of( Vector3i.ZERO, @@ -184,7 +94,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.from(-1, 1, 4), Vector3i.from(1, 1, 1), 1, - StubRotations.CLOCKWISE_90 + Rotations.CLOCKWISE_90.get() ), Arguments.of( Vector3i.from(1, -1, -1), @@ -192,7 +102,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.ZERO, Vector3i.from(1, -1, -1), 1, - StubRotations.CLOCKWISE_90 + Rotations.CLOCKWISE_90.get() ), Arguments.of( Vector3i.from(1, -1, -1), @@ -200,7 +110,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.ZERO, Vector3i.from(1, -1, -1), 2, - StubRotations.COUNTERCLOCKWISE_90 + Rotations.COUNTERCLOCKWISE_90.get() ), Arguments.of( Vector3i.from(1, -1, -1), @@ -208,7 +118,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.ZERO, Vector3i.from(1, -1, -1), 4, - StubRotations.CLOCKWISE_180 + Rotations.CLOCKWISE_180.get() ), Arguments.of( Vector3i.from(-4, -1, -5), @@ -216,7 +126,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.ZERO, Vector3i.from(1, -3, -1), 8, - StubRotations.CLOCKWISE_90 + Rotations.CLOCKWISE_90.get() ), Arguments.of( Vector3i.from(-4, -1, -5), @@ -224,7 +134,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.from(-8, 3, -7), Vector3i.from(1, -3, -1), 8, - StubRotations.CLOCKWISE_90 + Rotations.CLOCKWISE_90.get() ), Arguments.of( Vector3i.from(-11, -4, -10), @@ -232,7 +142,7 @@ private static Stream testTransformationsOfPositions() { Vector3i.from(-6, 2, -4), Vector3i.from(1, -3, -1), 8, - StubRotations.CLOCKWISE_90 + Rotations.CLOCKWISE_90.get() ) ); } @@ -245,16 +155,14 @@ private static SpongeArchetypeVolume fillVolume(final Vector3i min, final Vector final RegistryHolder holder = Sponge.game(); final SpongeArchetypeVolume volume = new SpongeArchetypeVolume(relativeMin, size, holder); - final StubbedRegistry blockRegistry = (StubbedRegistry) RegistryTypes.BLOCK_TYPE.get(); final Vector3i volMax = volume.max().add(Vector3i.ONE); - IntStream.range(relativeMin.x(), volMax.x()).forEach(x -> IntStream.range(relativeMin.z(), volMax.z()) - .forEach(z -> IntStream.range(relativeMin.y(), volMax.y()) - .forEach(y -> { - final BlockType block = blockRegistry.createEntry( - "minecraft", String.format("volumetest{%d, %d, %d}", x, y, z)); - final BlockState blockState = block.defaultState(); - volume.setBlock(x, y, z, blockState); - }))); + for (int x = relativeMin.x(); x < volMax.x(); x++) { + for (int z = relativeMin.z(); z < volMax.z(); z++) { + for (int y = relativeMin.y(); y < volMax.y(); y++) { + volume.addBlockEntity(x, y, z, BlockEntityArchetype.builder().blockEntityData(DataContainer.createNew().set(VolumeTransformationTest.POS, new Vector3i(x, y, z))).build()); + } + } + } return volume; } @@ -262,7 +170,7 @@ private static SpongeArchetypeVolume fillVolume(final Vector3i min, final Vector @ParameterizedTest void testTransformationsOfPositions( final Vector3i min, final Vector3i max, final Vector3i origin, final Vector3i testForRoundTrip, - final int rotationCount, final StubRotations wanted + final int rotationCount, final Rotation wanted ) { final SpongeArchetypeVolume volume = VolumeTransformationTest.fillVolume(min, max, origin); final Vector3i size = volume.size(); @@ -303,16 +211,16 @@ void testTransformationsOfPositions( final int relativeY = y + relativeMin.y(); final int relativeZ = z + relativeMin.z(); final Vector3d rawRelativePosition = new Vector3d(relativeX, relativeY, relativeZ); - final BlockState untransformedState = volume.block(relativeX, relativeY, relativeZ); + final Optional untransformedEntity = volume.blockEntityArchetype(relativeX, relativeY, relativeZ); final Vector3i transformedPosition = expectedTransform.transformPosition( rawRelativePosition).toInt(); - final BlockState transformedState = rotated.block( + final Optional transformedEntity = rotated.blockEntityArchetype( transformedPosition.x(), transformedPosition.y(), transformedPosition.z()); - Assertions.assertEquals(untransformedState, transformedState, () -> String.format( - "Block Check Failed!\nOriginal(%d, %d, %d): %s\nTransformed(%d, %d, %d): %s\n", - relativeX, relativeY, relativeZ, untransformedState, + Assertions.assertEquals(untransformedEntity, transformedEntity, () -> String.format( + "Block entity check failed!\nOriginal(%d, %d, %d): %s\nTransformed(%d, %d, %d): %s\n", + relativeX, relativeY, relativeZ, untransformedEntity, transformedPosition.x(), transformedPosition.y(), - transformedPosition.z(), transformedState + transformedPosition.z(), transformedEntity )); } } @@ -322,40 +230,37 @@ void testTransformationsOfPositions( } // At this point, we should have an abstract referent volume at least - rotated.blockStateStream(rotated.min(), rotated.max(), StreamOptions.lazily()) - .forEach((rotatedRef, type, x, y, z) -> { + rotated.blockEntityArchetypeStream(rotated.min(), rotated.max(), StreamOptions.lazily()) + .forEach((rotatedRef, entity, x, y, z) -> { final Vector3d transformedPos = new Vector3d(x, y, z); // We have this offset in the stream, so we have to undo it here. final Vector3d invertedTransformedPos = inverse .transformPosition(transformedPos.add(VolumePositionTranslators.BLOCK_OFFSET)) .sub(VolumePositionTranslators.BLOCK_OFFSET); final Vector3i invertedBlockPos = invertedTransformedPos.toInt(); - final Vector3i expectedPos; - Assertions.assertInstanceOf(StubState.class, type, - () -> String.format("expected state to be a stub state for pos: [%f, %f, %f] but got %s", x, y, z, - type - ) - ); + + final Vector3i expectedPos = (Vector3i) entity.blockEntityData().get(VolumeTransformationTest.POS).get(); + Assertions.assertNotEquals( - ((StubState) type).deducedPos, VolumeTransformationTest.INVALID_STUB_POSITION, - () -> String.format("expected to have a positioned stub state: [%f, %f, %f] but got %s", x, y, z, - type + expectedPos, + () -> String.format("expected to have a positioned block entity: [%f, %f, %f] but got %s", x, y, z, + entity ) ); - expectedPos = ((StubState) type).deducedPos; + Assertions.assertEquals(expectedPos, invertedBlockPos, () -> String.format( - "expected untransformed position %s for state %s does not match reverse transformed position: %s", - expectedPos, type, invertedBlockPos + "expected untransformed position %s for block entity %s does not match reverse transformed position: %s", + expectedPos, entity, invertedBlockPos ) ); - final BlockState block = volume.block(expectedPos.x(), expectedPos.y(), expectedPos.z()); - Assertions.assertEquals(type, block, + final BlockEntityArchetype originalEntity = volume.blockEntityArchetype(expectedPos.x(), expectedPos.y(), expectedPos.z()).orElse(null); + Assertions.assertEquals(entity, originalEntity, () -> String.format( - "Expected deduced state to be equal from the original target volume but had a mismatch: Original target %s does not match %s", - block, type + "Expected deduced block entity to be equal from the original target volume but had a mismatch: Original target %s does not match %s", + originalEntity, entity ) ); }); From c473e6c79e04ac50b924a5a0ba7e7cce8ab7403c Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Wed, 23 Jul 2025 17:37:04 +0200 Subject: [PATCH 06/11] Update invalid unit tests --- build.gradle.kts | 2 + .../common/data/manipulator/DataTestUtil.java | 80 ---- .../data/manipulator/ManipulatorTest.java | 363 ------------------ .../data/manipulator/SpecialCaseDataTest.java | 45 --- .../data/util/ExperienceHolderUtilsTest.java | 124 ------ .../common/event/CauseStackManagerTest.java | 93 ----- .../invalid/common/event/ShouldFireTest.java | 133 ------- .../common/event/SnapshotGenerationTest.java | 112 ------ .../invalid/common/launch/TestTweaker.java | 57 --- .../common/launch/mixin/ItemMixin_Test.java | 44 --- .../mixin/SchematicTranslatorMixin_Test.java | 47 --- .../mixin/SpongeImplHooksMixin_Test.java | 44 --- .../registry/CatalogTypeClassesTest.java | 72 ---- .../registry/CatalogTypeMethodTest.java | 165 -------- .../common/registry/RegistryModuleTest.java | 74 ---- .../common/registry/RegistryTestUtil.java | 112 ------ .../common/regression/registry/Test1Tile.java | 29 -- .../common/regression/registry/Test2Tile.java | 29 -- .../common/regression/registry/Test3Tile.java | 29 -- .../registry/TileEntityRegistrationTest.java | 93 ----- .../pagination/PaginationCalculatorTest.java | 54 --- .../invalid/common/test/RegressionTest.java | 68 ---- src/test/invalid/common/test/TestGame.java | 59 --- src/test/invalid/common/test/TestMain.java | 48 --- src/test/invalid/common/test/TestServer.java | 262 ------------- .../test/inject/TestImplementationModule.java | 70 ---- .../invalid/common/text/LegacyParserTest.java | 71 ---- .../common/text/LegacySerializerTest.java | 78 ---- .../world/storage/SpongeChunkLayoutTest.java | 170 -------- .../common/config/core}/IpSetTest.java | 25 +- .../common/event/EventFilterTest.java | 239 ++++++------ .../common/event/ShouldFireTest.java | 123 ++++++ .../common/event/SnapshotGenerationTest.java | 83 ++++ .../event/listener/AllCauseListener.java | 4 +- .../listener/BeforeAfterCauseListener.java | 8 +- .../event/listener/CancelledListener.java | 0 .../listener/CovariantGetterListener.java | 0 .../event/listener/DataHasListener.java | 13 +- .../event/listener/DataSupportsListener.java | 13 +- .../common/event/listener/DoubleListener.java | 4 +- .../listener/FirstLastCauseListener.java | 0 .../common/event/listener/GetterListener.java | 0 .../listener/IncludeExcludeListener.java | 4 +- .../InvalidIncludeExcludeListener.java | 0 .../common/event/listener/NonPreListener.java | 2 +- .../common/event/listener}/PreListener.java | 4 +- .../common/event/listener/RootListener.java | 0 .../common/event/listener/SimpleListener.java | 0 .../manager/ListenerClassVisitorHelper.java} | 38 +- .../event/tracking/PhaseTrackerTest.java | 87 +++++ .../common/mixin}/MixinTest.java | 9 +- .../common/registry/RegistryTest.java | 131 +++++++ .../common/util/ExperienceHolderUtilTest.java | 84 ++++ .../util/persistence/data/FakeBuilder.java | 4 +- .../persistence/data/FakeSerializable.java | 12 +- .../persistence/data/NBTTranslationTest.java | 20 +- .../VolumeTransformationTest.java | 2 +- .../world/schematic/SchematicTest.java} | 27 +- .../world/storage/SpongeChunkLayoutTest.java | 168 ++++++++ 59 files changed, 887 insertions(+), 2844 deletions(-) delete mode 100644 src/test/invalid/common/data/manipulator/DataTestUtil.java delete mode 100644 src/test/invalid/common/data/manipulator/ManipulatorTest.java delete mode 100644 src/test/invalid/common/data/manipulator/SpecialCaseDataTest.java delete mode 100644 src/test/invalid/common/data/util/ExperienceHolderUtilsTest.java delete mode 100644 src/test/invalid/common/event/CauseStackManagerTest.java delete mode 100644 src/test/invalid/common/event/ShouldFireTest.java delete mode 100644 src/test/invalid/common/event/SnapshotGenerationTest.java delete mode 100644 src/test/invalid/common/launch/TestTweaker.java delete mode 100644 src/test/invalid/common/launch/mixin/ItemMixin_Test.java delete mode 100644 src/test/invalid/common/launch/mixin/SchematicTranslatorMixin_Test.java delete mode 100644 src/test/invalid/common/launch/mixin/SpongeImplHooksMixin_Test.java delete mode 100644 src/test/invalid/common/registry/CatalogTypeClassesTest.java delete mode 100644 src/test/invalid/common/registry/CatalogTypeMethodTest.java delete mode 100644 src/test/invalid/common/registry/RegistryModuleTest.java delete mode 100644 src/test/invalid/common/registry/RegistryTestUtil.java delete mode 100644 src/test/invalid/common/regression/registry/Test1Tile.java delete mode 100644 src/test/invalid/common/regression/registry/Test2Tile.java delete mode 100644 src/test/invalid/common/regression/registry/Test3Tile.java delete mode 100644 src/test/invalid/common/regression/registry/TileEntityRegistrationTest.java delete mode 100644 src/test/invalid/common/service/pagination/PaginationCalculatorTest.java delete mode 100644 src/test/invalid/common/test/RegressionTest.java delete mode 100644 src/test/invalid/common/test/TestGame.java delete mode 100644 src/test/invalid/common/test/TestMain.java delete mode 100644 src/test/invalid/common/test/TestServer.java delete mode 100644 src/test/invalid/common/test/inject/TestImplementationModule.java delete mode 100644 src/test/invalid/common/text/LegacyParserTest.java delete mode 100644 src/test/invalid/common/text/LegacySerializerTest.java delete mode 100644 src/test/invalid/common/world/storage/SpongeChunkLayoutTest.java rename src/test/{invalid/common/util => java/org/spongepowered/common/config/core}/IpSetTest.java (70%) rename src/test/{invalid => java/org/spongepowered}/common/event/EventFilterTest.java (54%) create mode 100644 src/test/java/org/spongepowered/common/event/ShouldFireTest.java create mode 100644 src/test/java/org/spongepowered/common/event/SnapshotGenerationTest.java rename src/test/{invalid => java/org/spongepowered}/common/event/listener/AllCauseListener.java (94%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/BeforeAfterCauseListener.java (91%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/CancelledListener.java (100%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/CovariantGetterListener.java (100%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/DataHasListener.java (76%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/DataSupportsListener.java (75%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/DoubleListener.java (90%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/FirstLastCauseListener.java (100%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/GetterListener.java (100%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/IncludeExcludeListener.java (96%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/InvalidIncludeExcludeListener.java (100%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/NonPreListener.java (97%) rename src/test/{invalid/common/event => java/org/spongepowered/common/event/listener}/PreListener.java (94%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/RootListener.java (100%) rename src/test/{invalid => java/org/spongepowered}/common/event/listener/SimpleListener.java (100%) rename src/test/{invalid/common/InjectedTest.java => java/org/spongepowered/common/event/manager/ListenerClassVisitorHelper.java} (57%) create mode 100644 src/test/java/org/spongepowered/common/event/tracking/PhaseTrackerTest.java rename src/test/{invalid/common => java/org/spongepowered/common/mixin}/MixinTest.java (88%) create mode 100644 src/test/java/org/spongepowered/common/registry/RegistryTest.java create mode 100644 src/test/java/org/spongepowered/common/util/ExperienceHolderUtilTest.java rename src/test/{invalid => java/org/spongepowered}/common/util/persistence/data/FakeBuilder.java (95%) rename src/test/{invalid => java/org/spongepowered}/common/util/persistence/data/FakeSerializable.java (87%) rename src/test/{invalid => java/org/spongepowered}/common/util/persistence/data/NBTTranslationTest.java (80%) rename src/test/{invalid/common/regression/SchematicUpgradeTest.java => java/org/spongepowered/common/world/schematic/SchematicTest.java} (77%) create mode 100644 src/test/java/org/spongepowered/common/world/storage/SpongeChunkLayoutTest.java diff --git a/build.gradle.kts b/build.gradle.kts index bda3857402b..19455e530d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -170,6 +170,8 @@ dependencies { testImplementation(libs.mockito.junitJupiter) { exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") } + + testImplementation(libs.mixin) } minecraft { diff --git a/src/test/invalid/common/data/manipulator/DataTestUtil.java b/src/test/invalid/common/data/manipulator/DataTestUtil.java deleted file mode 100644 index baecf4f6cca..00000000000 --- a/src/test/invalid/common/data/manipulator/DataTestUtil.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.data.manipulator; - -import org.spongepowered.api.data.manipulator.DataManipulator; -import org.spongepowered.api.data.manipulator.DataManipulatorBuilder; -import org.spongepowered.common.data.SpongeDataManager; -import org.spongepowered.common.data.SpongeManipulatorRegistry; -import org.spongepowered.common.data.util.DataProcessorDelegate; -import org.spongepowered.common.data.util.ImplementationRequiredForTest; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -final class DataTestUtil { - - private DataTestUtil() {} - - static List generateManipulatorTestObjects() throws Exception { - final Map>, DataManipulatorBuilder> manipulatorBuilderMap = getBuilderMap(); - final Map>, DataProcessorDelegate> delegateMap = getDelegateMap(); - return delegateMap.entrySet().stream() - .filter(entry -> isValidForTesting(entry.getKey())) - .flatMap(entry -> { - String name = entry.getKey().getSimpleName(); - Class> key = entry.getKey(); - DataManipulatorBuilder builder = manipulatorBuilderMap.get(key); - - return Stream.of(new Object[]{name, key, builder, false}, new Object[]{name, key, builder, true}); - }) - .collect(Collectors.toList()); - } - - private static boolean isValidForTesting(Class clazz) { - return !Modifier.isInterface(clazz.getModifiers()) && !Modifier.isAbstract(clazz.getModifiers()) - && clazz.getAnnotation(ImplementationRequiredForTest.class) == null; - } - - @SuppressWarnings("unchecked") - private static Map>, DataProcessorDelegate> getDelegateMap() throws Exception { - final Field delegateField = SpongeManipulatorRegistry.class.getDeclaredField("dataProcessorDelegates"); - delegateField.setAccessible(true); - return (Map>, DataProcessorDelegate>) delegateField.get(SpongeManipulatorRegistry.getInstance()); - - } - - @SuppressWarnings("unchecked") - private static Map>, DataManipulatorBuilder> getBuilderMap() throws Exception { - final Field builderMap = SpongeDataManager.class.getDeclaredField("builderMap"); - builderMap.setAccessible(true); - return (Map>, DataManipulatorBuilder>) builderMap.get(SpongeDataManager.getInstance()); - } - -} diff --git a/src/test/invalid/common/data/manipulator/ManipulatorTest.java b/src/test/invalid/common/data/manipulator/ManipulatorTest.java deleted file mode 100644 index c9a39a0e2ba..00000000000 --- a/src/test/invalid/common/data/manipulator/ManipulatorTest.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.data.manipulator; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -import com.google.common.collect.Lists; -import io.leangen.geantyref.TypeToken; -import org.checkerframework.checker.nullness.Opt; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.data.DataContainer; -import org.spongepowered.api.data.DataQuery; -import org.spongepowered.api.data.DataView; -import org.spongepowered.api.data.key.Key; -import org.spongepowered.api.data.manipulator.DataManipulator; -import org.spongepowered.api.data.manipulator.DataManipulatorBuilder; -import org.spongepowered.api.data.manipulator.ImmutableDataManipulator; -import org.spongepowered.api.data.value.BaseValue; -import org.spongepowered.api.data.value.immutable.ImmutableValue; -import org.spongepowered.api.effect.potion.PotionEffect; -import org.spongepowered.api.entity.EntitySnapshot; -import org.spongepowered.api.event.SpongeEventFactoryTest; -import org.spongepowered.api.item.merchant.TradeOffer; -import org.spongepowered.api.util.PEBKACException; -import org.spongepowered.asm.util.PrettyPrinter; -import org.spongepowered.common.util.TypeTokenHelper; -import org.spongepowered.lwts.runner.LaunchWrapperParameterized; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -@RunWith(LaunchWrapperParameterized.class) -public class ManipulatorTest { - - @Parameterized.Parameters(name = "{index} Data: {0} generateValues: {3}") - public static Iterable data() throws Exception { - return DataTestUtil.generateManipulatorTestObjects(); - } - - private String dataName; - private Class> manipulatorClass; - private DataManipulatorBuilder builder; - private boolean generateValues; - - public ManipulatorTest(String simpleName, Class> manipulatorClass, DataManipulatorBuilder builder, boolean generateValues) { - this.manipulatorClass = manipulatorClass; - this.dataName = simpleName; - this.builder = builder; - this.generateValues = generateValues; - } - - @SuppressWarnings("unchecked") - private DataManipulator createManipulator() { - try { - final Constructor ctor = this.manipulatorClass.getConstructor(); - DataManipulator manipulator = (DataManipulator) ctor.newInstance(); - - if (this.generateValues) { - final Set> keys = manipulator.getKeys(); - - for (Key key: keys) { - Optional value = createValueElement((Key) key); - value.ifPresent(o -> manipulator.set((Key) key, o)); - } - } - return manipulator; - } catch (InstantiationException | InvocationTargetException e) { - throw new IllegalStateException("Failed to construct manipulator: " + this.dataName, e); - } catch (Exception e) { - throw new RuntimeException("There was an unknown exception, probably with validation of the Immutable copy for: " - + this.manipulatorClass.getSimpleName() + ". \n It may be required to use @ImplementationRequiredForTest on " - + "the DataManipulator implementation class to avoid testing a DataManipulator dependent on a CatalogType.", e); - } - } - - @Test - public void testCreateData() { - try { - DataManipulator manipulator = this.createManipulator(); - manipulator.asImmutable(); - } catch (Exception e) { - throw new RuntimeException("There was an unknown exception, probably with validation of the Immutable copy for: " - + this.manipulatorClass.getSimpleName() + ". \n It may be required to use @ImplementationRequiredForTest on " - + "the DataManipulator implementation class to avoid testing a DataManipulator dependent on a CatalogType.", e); - } - } - - @Test - public void testValueEquals() { - final DataManipulator manipulator = this.createManipulator(); - final ImmutableDataManipulator immutable = manipulator.asImmutable(); - final Set> manipulatorValues = manipulator.getValues(); - final Set> immutableValues = immutable.getValues(); - assertThat("The ImmutableDataManipulator is missing values present from the DataManipulator! " + this.dataName, - manipulatorValues.containsAll(immutableValues), is(true)); - assertThat("The DataManipulator is missing values present from the ImmutableDataManipulator! " + this.dataName, - immutableValues.containsAll(manipulatorValues), is(true)); - } - - @Test - public void testMutableImmutable() { - final DataManipulator manipulator = this.createManipulator(); - final ImmutableDataManipulator immutableDataManipulator = manipulator.asImmutable(); - final DataManipulator newManipulator = immutableDataManipulator.asMutable(); - - assertThat("The DataManipulator constructed by ImmutableDataManipulator#asMutable is not " - + "equal to original DataManipulator!\n" - + "This shouldn't be the case, as aDataManipulator constructed from an ImmutableDataManipulator " - + "should store exactly the same keys and values as the original DataManipulator, and therefore " - + "be equal to it.\n" - + "The mutable manipulator in question: " + this.dataName + "\n" - + "The immutable manipulator in question: " + immutableDataManipulator.getClass().getSimpleName(), - manipulator.getValues().equals(newManipulator.getValues()), is(true)); - } - - @Test - public void testSameKeys() { - final DataManipulator manipulator = this.createManipulator(); - final ImmutableDataManipulator immutableDataManipulator = manipulator.asImmutable(); - final Set> mutableKeys = manipulator.getKeys(); - final Set> immutableKeys = immutableDataManipulator.getKeys(); - assertThat("The DataManipulator and ImmutableDataManipulator have differing keys!\n" - + "This shouldn't be the case as a DataManipulator is contractually obliged to store the exact same" - + "key/values as the ImmutableDataManipulator and vice versa.\n" - + "The mutable manipulator in question: " + this.dataName +"\n" - + "The immutable manipulator in question: " + immutableDataManipulator.getClass().getSimpleName(), - immutableKeys, equalTo(mutableKeys)); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - @Test - public void testGetValues() { - final DataManipulator manipulator = this.createManipulator(); - final ImmutableDataManipulator immutableDataManipulator = manipulator.asImmutable(); - final Set> keys = manipulator.getKeys(); - for (Key> key : keys) { - Optional mutable = manipulator.get((Key) key); - Optional immutable = immutableDataManipulator.get((Key) key); - assertThat("The DataManipulator failed to retrieve a value that a key was registered for!\n" - + "The manipulator in question: " + this.dataName, mutable.isPresent(), is(true)); - assertThat("The ImmutableDataManipulator failed to retrieve a value that a key was registered for!\n" - + "The manipulator in question: " + immutableDataManipulator.getClass().getSimpleName(), immutable.isPresent(), is(true)); - assertThat("The returned values do not equal eachother!\n" - + "DataManipulator: " + this.dataName + "\nImmutableDataManipulator: " - + immutableDataManipulator.getClass().getSimpleName(), mutable.equals(immutable), is(true)); - } - } - - @SuppressWarnings("unchecked") - private Optional createValueElement(Key type) { - Class elementClass = (Class) type.getElementToken().getRawType(); - if (Optional.class.isAssignableFrom(elementClass)) { - Class wrappedType = TypeTokenHelper.getGenericParam(type.getElementToken(), 0); - // The innermost optional is the actual type of the Key. The outer optional - // indicates to the caller that we were able to create something for this key. - return (Optional) Optional.of(Optional.of(createType(wrappedType))); - } else if (List.class.isAssignableFrom(elementClass)) { - Class wrappedType = TypeTokenHelper.getGenericParam(type.getElementToken(), 0); - - return (Optional) Optional.of(Lists.newArrayList(createType(wrappedType))); - } - return Optional.empty(); - } - - - @SuppressWarnings("unchecked") - private T createType(Class type) { - if (CatalogType.class.isAssignableFrom(type)) { - return (T) Sponge.getRegistry().getAllOf((Class) type).iterator().next(); - } else if (isBuildable(type)) { - return (T) createFromBuilder(type); - } else { - return (T) SpongeEventFactoryTest.mockParam(type); - } - } - - private boolean isBuildable(Class type) { - // The 'child' methods on Text.Builder interact oddly - // with our code, so skip building Text for now - if (type == Text.class) { - return false; - } - // EntitySnapshot can't be built with null values - // We need a dummy EntitySnapshot - // Skip building EntitySnapshot for now - if (type == EntitySnapshot.class) { - return false; - } - try { - type.getMethod("builder"); - return true; - } catch (NoSuchMethodException e) { - return false; - } - } - - private Object createFromBuilder(Class type) { - try { - Method methodbuilder = type.getMethod("builder"); - Class builderType = methodbuilder.getReturnType(); - Method methodBuild = builderType.getMethod("build"); - Object builderObject = methodbuilder.invoke(nullValue()); - - for (Method builderSetter: builderType.getMethods()) { - if (!this.isBuilderSetter(builderType, type, builderSetter)) { - continue; - } - Class paramType = builderSetter.getParameterTypes()[0]; - Object param = this.createBuilderParam(paramType); - - builderSetter.invoke(builderObject, param); - } - - Object finalType = methodBuild.invoke(builderObject); - return finalType; - - } catch (Exception e) { - throw new RuntimeException("Exception while creating builder for type " + type, e); - } - } - - private Object createBuilderParam(Class paramType) { - // Many builder methods require that that integer parameters be greater than 0 - if (paramType.equals(int.class) || paramType.equals(Integer.class)) { - return 1; - } - return this.createType(paramType); - } - - private boolean isBuilderSetter(Class builderType, Class type, Method method) { - if (method.getReturnType().equals(builderType) && method.getParameterCount() == 1) { - // Don't try to call any methods that take the type we're building - Class paramType = method.getParameterTypes()[0]; - return !paramType.equals(type) - && !paramType.equals(Class.class) - && !paramType.equals(DataManipulator.class) - && !paramType.equals(ImmutableDataManipulator.class) - && !method.getName().startsWith("from"); - } - return false; - } - @SuppressWarnings("unchecked") - @Test - public void testSerialization() { - try { - final DataManipulator manipulator = this.createManipulator(); - - final DataContainer container = manipulator.toContainer(); - if (this.builder != null) { - final Optional> optional; - try { - optional = (Optional>) this.builder.build(container); - } catch (Exception e) { - printExceptionBuildingData(container, e); - throw e; - } - if (!optional.isPresent()) { - printEmptyBuild(container); - throw new IllegalArgumentException("[Serialization]: A builder did not translate the data manipulator: " - + this.dataName + "\n[Serialization]: Providing the DataContainer: " + container.toString()); - } - - final DataManipulator deserialized = this.builder.build(container).get(); - final boolean equals = manipulator.equals(deserialized); - if (!equals) { - printNonEqual(container, manipulator, deserialized); - } - assertThat(manipulator, equalTo(deserialized)); - } - } catch (Exception e) { - throw new RuntimeException("There was an unknown exception trying to test " + this.dataName - + ". Probably because the DataManipulator relies on an implementation class.", e); - } - } - - private void printNonEqual(DataContainer container, DataManipulator original, DataManipulator deserialized) { - final PrettyPrinter printer = new PrettyPrinter(60).centre().add("Unequal Data").hr() - .add("Something something equals....") - .add() - .add("Provided manipulators don't equal eachother."); - printRemaining(container, printer); - - } - - private void printEmptyBuild(DataContainer container) { - final PrettyPrinter printer = new PrettyPrinter(60).centre().add("Did not build data!").hr() - .add("Something something builders....") - .add() - .add("Provided container didn't get built into a manipulator!"); - printRemaining(container, printer); - } - - private void printExceptionBuildingData(DataContainer container, Exception exception) { - final PrettyPrinter printer = new PrettyPrinter(60).centre().add("Could not build data!").hr() - .add(exception) - .add("Something something data....") - .add() - .add("Here's the provided container:"); - printRemaining(container, printer); - } - - private void printRemaining(DataContainer container, PrettyPrinter printer) { - printContainerToPrinter(printer, container, 2); - printer.add() - .add("Manipulator class: " + this.manipulatorClass) - .print(System.err); - } - - - private static void printContainerToPrinter(PrettyPrinter printer, DataView container, int indentation) { - for (DataQuery dataQuery : container.getKeys(false)) { - final Object o = container.get(dataQuery).get(); - final StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < indentation; i++) { - stringBuilder.append(" "); - } - final List parts = dataQuery.getParts(); - - printer.add(stringBuilder.toString() + "- Query: " + parts.get(parts.size() - 1)); - if (o instanceof DataView) { - // Paginate the internal views. - printContainerToPrinter(printer, (DataView) o, indentation * 2); - } else { - printer .add(stringBuilder.toString() + "- Value: " + o); - - } - } - } -} diff --git a/src/test/invalid/common/data/manipulator/SpecialCaseDataTest.java b/src/test/invalid/common/data/manipulator/SpecialCaseDataTest.java deleted file mode 100644 index 5b6e08f316d..00000000000 --- a/src/test/invalid/common/data/manipulator/SpecialCaseDataTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.data.manipulator; - -public class SpecialCaseDataTest { - - //@RunWith(Parameterized.class) - public static final class CatalogDataTest { - // todo mock a fake catalog - // todo create a test datamanipulator - // todo create a test immutable datamanipulator - // todo write tests for validating the catalog data abstraction layer - } - - //@RunWith(Parameterized.class) - public static final class ItemStackDataTest { - - // todo write a test based on a fake implemented ItemStack - // same as CatalogDataTest - - } - -} diff --git a/src/test/invalid/common/data/util/ExperienceHolderUtilsTest.java b/src/test/invalid/common/data/util/ExperienceHolderUtilsTest.java deleted file mode 100644 index dee670452ef..00000000000 --- a/src/test/invalid/common/data/util/ExperienceHolderUtilsTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.data.util; - -import com.mojang.authlib.GameProfile; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.profiler.Profiler; -import net.minecraft.world.World; -import net.minecraft.world.WorldProviderSurface; -import net.minecraft.world.chunk.IChunkProvider; -import net.minecraft.world.storage.WorldInfo; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.spongepowered.common.data.provider.entity.player.ExperienceHolderUtils; - -import java.util.Iterator; -import java.util.UUID; - -@RunWith(Parameterized.class) -public final class ExperienceHolderUtilsTest { - - private final int level; - private final int startExp; - private final int expInLevel; - - public ExperienceHolderUtilsTest(int level, int startExp, int expInLevel) { - this.level = level; - this.startExp = startExp; - this.expInLevel = expInLevel; - } - - @Parameterized.Parameters - public static Iterable data() { - World world = new World(null, new WorldInfo(new NBTTagCompound()), new WorldProviderSurface(), new Profiler(), false) { - - @Override - protected IChunkProvider createChunkProvider() { - return null; - } - - @Override - protected boolean isChunkLoaded(int x, int z, boolean allowEmpty) { - return false; - } - }; - //noinspection EntityConstructor - EntityPlayer player = new EntityPlayer(world, new GameProfile(UUID.randomUUID(), "Player")) { - - @Override - public boolean isSpectator() { - return false; - } - - @Override - public boolean isCreative() { - return false; - } - }; - return () -> new Iterator() { - - private int level; - private int startExp; - - @Override - public boolean hasNext() { - return level < 50; - } - - @Override - public Object[] next() { - player.experienceLevel = level; - Object[] data = {level, startExp, player.xpBarCap()}; - startExp += player.xpBarCap(); - level++; - return data; - } - }; - } - - @Test - public void testGetExpBetweenLevels() { - Assert.assertEquals(expInLevel, ExperienceHolderUtils.getExpBetweenLevels(level)); - } - - @Test - public void testXpAtLevel() { - Assert.assertEquals(startExp, ExperienceHolderUtils.xpAtLevel(level)); - } - - @Test - public void testGetLevelForXpStart() { - Assert.assertEquals(level, ExperienceHolderUtils.getLevelForExp(startExp)); - } - - @Test - public void testGetLevelForXpMiddle() { - Assert.assertEquals(level, ExperienceHolderUtils.getLevelForExp(startExp + 1)); - } -} diff --git a/src/test/invalid/common/event/CauseStackManagerTest.java b/src/test/invalid/common/event/CauseStackManagerTest.java deleted file mode 100644 index b9c1dc2bad1..00000000000 --- a/src/test/invalid/common/event/CauseStackManagerTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.event; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.spongepowered.api.entity.living.player.User; -import org.spongepowered.api.event.cause.EventContextKeys; -import org.spongepowered.common.SpongeImpl; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; - -@RunWith(LaunchWrapperTestRunner.class) -public class CauseStackManagerTest { - - @Test - public void testPoppingFramePopsCauses() throws Exception { - final SpongeCauseStackManager causeStackManager = SpongeImpl.getCauseStackManager(); - - // We start by pushing a frame... - SpongeCauseStackManager.StackFrame frame1 = causeStackManager.pushCauseFrame(); - causeStackManager.pushCause(1); - causeStackManager.pushCause(2); - - // Then we push another frame - SpongeCauseStackManager.StackFrame frame = causeStackManager.pushCauseFrame(); - causeStackManager.pushCause(3); - - Assert.assertEquals(3, causeStackManager.getCurrentCause().root()); - Assert.assertEquals(3, causeStackManager.getCurrentCause().all().size()); - - // Now pop the frame - causeStackManager.popCauseFrame(frame); - Assert.assertEquals(2, causeStackManager.getCurrentCause().root()); - Assert.assertEquals(2, causeStackManager.getCurrentCause().all().size()); - - // Remove for next tests. - causeStackManager.popCauseFrame(frame1); - } - - @Test - public void testPoppingFrameRemovesFrameContexts() throws Exception { - final SpongeCauseStackManager causeStackManager = SpongeImpl.getCauseStackManager(); - - User user = Mockito.mock(User.class); - Mockito.when(user.getName()).thenReturn("first"); - - User user2 = Mockito.mock(User.class); - Mockito.when(user.getName()).thenReturn("second"); - - // We start by pushing a frame... - SpongeCauseStackManager.StackFrame frame1 = causeStackManager.pushCauseFrame(); - causeStackManager.pushCause(1); - causeStackManager.addContext(EventContextKeys.OWNER, user); - - // Then we push another frame - SpongeCauseStackManager.StackFrame frame = causeStackManager.pushCauseFrame(); - causeStackManager.addContext(EventContextKeys.OWNER, user2); - - Assert.assertEquals(user2, causeStackManager.getContext(EventContextKeys.OWNER).get()); - - // Now pop the frame - causeStackManager.popCauseFrame(frame); - Assert.assertEquals(user, causeStackManager.getContext(EventContextKeys.OWNER).get()); - - causeStackManager.popCauseFrame(frame1); - Assert.assertFalse(causeStackManager.getContext(EventContextKeys.OWNER).isPresent()); - } - -} diff --git a/src/test/invalid/common/event/ShouldFireTest.java b/src/test/invalid/common/event/ShouldFireTest.java deleted file mode 100644 index 7f185e86cbf..00000000000 --- a/src/test/invalid/common/event/ShouldFireTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.event; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import org.spongepowered.api.event.EventManager; -import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.entity.SpawnEntityEvent; -import org.spongepowered.api.plugin.PluginManager; -import org.spongepowered.common.InjectedTest; -import org.spongepowered.plugin.PluginContainer; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Optional; - -public class ShouldFireTest extends InjectedTest { - - private EventManager eventManager; - private Object plugin; - private PluginContainer container; - - @Before - public void init() throws Exception { - PluginManager manager = Mockito.mock(PluginManager.class); - this.eventManager = new SpongeEventManager(this.logger, manager); - - this.plugin = new Object(); - this.container = Mockito.mock(PluginContainer.class); - Mockito.when(manager.fromInstance(this.plugin)).thenReturn(Optional.of(this.container)); - - this.resetStatics(); - } - - private void resetStatics() throws IllegalAccessException { - for (Field field: ShouldFire.class.getDeclaredFields()) { - if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { - field.set(null, false); - } - } - } - - @Test - public void testSpawn() { - SpawnListener listener = new SpawnListener(); - - Assert.assertFalse("SPAWN_ENTITY_EVENT is not false!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - Assert.assertFalse("DROP_ITEM_EVENT_DISPENSE is not false!", ShouldFire.DROP_ITEM_EVENT_DISPENSE); - - this.eventManager.registerListeners(this.plugin, listener); - Assert.assertTrue("SPAWN_ENTITY_EVENT is not true!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertTrue("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not true!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - Assert.assertTrue("DROP_ITEM_EVENT_DISPENSE it not true!", ShouldFire.DROP_ITEM_EVENT_DISPENSE); - - this.eventManager.unregisterListeners(listener); - Assert.assertFalse("SPAWN_ENTITY_EVENT is not false!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - Assert.assertFalse("DROP_ITEM_EVENT_DISPENSE is not false!", ShouldFire.DROP_ITEM_EVENT_DISPENSE); - } - - @Test - public void testMultipleListeners() { - SpawnListener spawnBaseListener = new SpawnListener(); - SubListener spawnCustomListener = new SubListener(); - - Assert.assertFalse("SPAWN_ENTITY_EVENT is not false!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CUSTOM is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - - this.eventManager.registerListeners(this.plugin, spawnCustomListener); - - Assert.assertTrue("SPAWN_ENTITY_EVENT is not true!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertTrue("SPAWN_ENTITY_EVENT_CUSTOM is not true!", ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - - this.eventManager.registerListeners(this.plugin, spawnBaseListener); - - Assert.assertTrue("SPAWN_ENTITY_EVENT is not true!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertTrue("SPAWN_ENTITY_EVENT_CUSTOM is not true!", ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM); - Assert.assertTrue("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not true!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - - this.eventManager.unregisterListeners(spawnCustomListener); - - Assert.assertTrue("SPAWN_ENTITY_EVENT is not true!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertTrue("SPAWN_ENTITY_EVENT_CUSTOM is not true!", ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM); - Assert.assertTrue("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not true!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - - this.eventManager.unregisterListeners(spawnBaseListener); - - Assert.assertFalse("SPAWN_ENTITY_EVENT is not false!", ShouldFire.SPAWN_ENTITY_EVENT); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CUSTOM is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM); - Assert.assertFalse("SPAWN_ENTITY_EVENT_CHUNK_LOAD is not false!", ShouldFire.SPAWN_ENTITY_EVENT_CHUNK_LOAD); - } - - private static class SpawnListener { - - @Listener - public void onSpawn(SpawnEntityEvent event) {} - } - - private static class SubListener { - - @Listener - public void onCustom(SpawnEntityEvent.Custom event) {} - } - -} diff --git a/src/test/invalid/common/event/SnapshotGenerationTest.java b/src/test/invalid/common/event/SnapshotGenerationTest.java deleted file mode 100644 index 8a4c04f4e80..00000000000 --- a/src/test/invalid/common/event/SnapshotGenerationTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.event; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.withSettings; - -import co.aikar.timings.Timings; -import co.aikar.timings.TimingsFactory; -import com.google.common.collect.Lists; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.spongepowered.api.Game; -import org.spongepowered.api.entity.Entity; -import org.spongepowered.api.event.CauseStackManager; -import org.spongepowered.api.event.EventManager; -import org.spongepowered.api.event.SpongeEventFactory; -import org.spongepowered.api.event.cause.Cause; -import org.spongepowered.api.event.cause.EventContext; -import org.spongepowered.api.event.entity.SpawnEntityEvent; -import org.spongepowered.api.plugin.PluginManager; -import org.spongepowered.common.InjectedTest; -import org.spongepowered.common.event.listener.NonPreListener; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; -import org.spongepowered.plugin.PluginContainer; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Optional; - -@RunWith(LaunchWrapperTestRunner.class) -public class SnapshotGenerationTest extends InjectedTest { - - private Entity entity; - private SpawnEntityEvent event; - private EventManager eventManager; - private Object plugin; - - @Before - public void init() { - PluginManager manager = Mockito.mock(PluginManager.class); - this.eventManager = new SpongeEventManager(this.logger, manager); - - try { - Field field = Timings.class.getDeclaredField("factory"); - field.setAccessible(true); - - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - - field.set(null, Mockito.mock(TimingsFactory.class)); - } catch (IllegalAccessException | NoSuchFieldException e) { - e.printStackTrace(); - } - - this.plugin = new Object(); - PluginContainer container = Mockito.mock(PluginContainer.class); - Mockito.when(manager.fromInstance(this.plugin)).thenReturn(Optional.of(container)); - - Cause cause = Cause.of(EventContext.empty(), this); - this.entity = Mockito.mock(Entity.class, withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)); - - this.event = SpongeEventFactory.createSpawnEntityEvent(cause, Lists.newArrayList(this.entity)); - - Game game = mock(Game.class); - CauseStackManager csm = mock(CauseStackManager.class); - Mockito.when(game.getCauseStackManager()).thenReturn(csm); - } - - @Test - public void testPreListener() { - this.eventManager.registerListeners(this.plugin, new PreListener()); - this.eventManager.registerListeners(this.plugin, new NonPreListener()); - this.eventManager.post(this.event); - - verify(this.entity).createSnapshot(); - this.event.getEntitySnapshots(); - } - - @Test(expected = IllegalStateException.class) - public void testNonPreListener() { - this.eventManager.post(this.event); - this.event.getEntitySnapshots(); - } - -} diff --git a/src/test/invalid/common/launch/TestTweaker.java b/src/test/invalid/common/launch/TestTweaker.java deleted file mode 100644 index 15157d70ef9..00000000000 --- a/src/test/invalid/common/launch/TestTweaker.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.launch; - -import static org.spongepowered.asm.mixin.MixinEnvironment.Side.SERVER; - -import net.minecraft.launchwrapper.LaunchClassLoader; -import org.spongepowered.asm.mixin.MixinEnvironment; -import org.spongepowered.asm.mixin.Mixins; -import org.spongepowered.lwts.AbstractTestTweaker; - -import java.io.File; - -public class TestTweaker extends AbstractTestTweaker { - - @Override - public void injectIntoClassLoader(LaunchClassLoader loader) { - super.injectIntoClassLoader(loader); - loader.addClassLoaderExclusion("org.slf4j."); - - registerAccessTransformer("META-INF/common_at.cfg"); - - SpongeLaunch.initPaths(new File(".")); - - SpongeLaunch.setupMixinEnvironment(); - Mixins.addConfiguration("mixins.common.test.json"); - MixinEnvironment.getDefaultEnvironment().setSide(SERVER); - } - - @Override - public String getLaunchTarget() { - return "org.spongepowered.common.test.TestMain"; - } - -} diff --git a/src/test/invalid/common/launch/mixin/ItemMixin_Test.java b/src/test/invalid/common/launch/mixin/ItemMixin_Test.java deleted file mode 100644 index 55bd87771f8..00000000000 --- a/src/test/invalid/common/launch/mixin/ItemMixin_Test.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.launch.mixin; - -import net.minecraft.item.Item; -import net.minecraft.util.ResourceLocation; -import org.spongepowered.api.item.ItemType; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(value = Item.class, remap = false) -public abstract class ItemMixin_Test { - - // Register items - @Inject(method = "registerItem(ILnet/minecraft/util/ResourceLocation;Lnet/minecraft/item/Item;)V", at = @At("RETURN")) - private static void registerMinecraftItem(final int id, final ResourceLocation name, final Item item, final CallbackInfo ci) { - ItemTypeRegistryModule.getInstance().registerAdditionalCatalog((ItemType) item); - } - -} diff --git a/src/test/invalid/common/launch/mixin/SchematicTranslatorMixin_Test.java b/src/test/invalid/common/launch/mixin/SchematicTranslatorMixin_Test.java deleted file mode 100644 index d7bbf90c2aa..00000000000 --- a/src/test/invalid/common/launch/mixin/SchematicTranslatorMixin_Test.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.launch.mixin; - -import net.minecraft.util.datafix.DataFixer; -import net.minecraft.util.datafix.DataFixesManager; -import org.spongepowered.api.data.DataView; -import org.spongepowered.api.world.schematic.Schematic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.common.data.persistence.SchematicTranslator; - -@Mixin(value = SchematicTranslator.class, remap = false) -public class SchematicTranslatorMixin_Test { - - @Shadow private static DataFixer VANILLA_FIXER; - - @Inject(method = "translate(Lorg/spongepowered/api/data/DataView;)Lorg/spongepowered/api/world/schematic/Schematic;", at = @At("HEAD")) - private void setDummyDataFixer(final DataView unprocessed, final CallbackInfoReturnable cir) { - VANILLA_FIXER = DataFixesManager.createFixer(); - } -} diff --git a/src/test/invalid/common/launch/mixin/SpongeImplHooksMixin_Test.java b/src/test/invalid/common/launch/mixin/SpongeImplHooksMixin_Test.java deleted file mode 100644 index b2603789bf1..00000000000 --- a/src/test/invalid/common/launch/mixin/SpongeImplHooksMixin_Test.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.launch.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.common.SpongeImplHooks; - -@Mixin(value = SpongeImplHooks.class, remap = false) -public class SpongeImplHooksMixin_Test { - - /** - * @author gabizou - unit test - * @reason unit test. - * - * @return - */ - @Overwrite - public static boolean isMainThread() { - return true; - } -} diff --git a/src/test/invalid/common/registry/CatalogTypeClassesTest.java b/src/test/invalid/common/registry/CatalogTypeClassesTest.java deleted file mode 100644 index 7c06af208a7..00000000000 --- a/src/test/invalid/common/registry/CatalogTypeClassesTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.registry; - -import static org.junit.Assume.assumeFalse; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.spongepowered.api.registry.RegistryException; -import org.spongepowered.lwts.runner.LaunchWrapperParameterized; - -import java.lang.reflect.Field; - -@RunWith(LaunchWrapperParameterized.class) -public class CatalogTypeClassesTest { - - @Parameterized.Parameters(name = "{index} Catalog Type: {1} Field : {0}") - public static Iterable data() throws Exception { - return RegistryTestUtil.generateCatalogContainerTestObjects(); - } - - @Parameterized.Parameter(0) public String fieldName; - @Parameterized.Parameter(1) public Class catalogClass; - @Parameterized.Parameter(2) public Class catalogContainerClass; - @Parameterized.Parameter(3) public CatalogRegistryModule registryModule; - @Parameterized.Parameter(4) public Field targetedField; - - private boolean isDummy = false; - - @Test - public void testCatalogFieldExists() throws Exception { - try { - final CatalogType o = (CatalogType) this.targetedField.get(null); - o.getId(); // Validates that the field is not a dummy object. If it is, it will throw an exception. - } catch (Exception e) { - this.isDummy = true; - throw e; - } - } - - @Test - public void testCatalogCanBeRetrieved() throws Exception { - assumeFalse(this.isDummy); - final CatalogType o = (CatalogType) this.targetedField.get(null); - this.registryModule.getById(o.getId()) - .orElseThrow(() -> new RegistryException("Could not locate " + this.fieldName + " in the registry: " + this.registryModule)); - } - -} diff --git a/src/test/invalid/common/registry/CatalogTypeMethodTest.java b/src/test/invalid/common/registry/CatalogTypeMethodTest.java deleted file mode 100644 index 134f5443c86..00000000000 --- a/src/test/invalid/common/registry/CatalogTypeMethodTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.registry; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.spongepowered.lwts.runner.LaunchWrapperParameterized; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; - -@RunWith(LaunchWrapperParameterized.class) -public class CatalogTypeMethodTest { - - private static final Logger LOG = LoggerFactory.getLogger(CatalogTypeMethodTest.class); - - @Parameterized.Parameters(name = "{index} Catalog Type: {0} Id : {3} Method: {5} ({6})") - public static Iterable data() throws Exception { - return RegistryTestUtil.generateCatalogTypeMethodTestObjects(); - } - - // TODO: Fix this list - private static final Set ignoredFailures = ImmutableSet.builder() - .add("org.spongepowered.common.statistic.SpongeEntityStatistic#getEntityType()") - .add("org.spongepowered.common.world.gen.SpongePopulatorType#getTranslation()") - .add("net.minecraft.util.EnumHand#getTranslation()") - // AbstractMethodErrors - .add("net.minecraft.block.BlockDirt$DirtType#getTranslation()") - .add("net.minecraft.block.BlockPistonExtension$EnumPistonType#getTranslation()") - .add("net.minecraft.block.BlockPrismarine$EnumType#getTranslation()") - .add("net.minecraft.block.BlockQuartz$EnumType#getTranslation()") - .add("net.minecraft.block.BlockSand$EnumType#getTranslation()") - .add("net.minecraft.block.BlockSandStone$EnumType#getTranslation()") - .add("net.minecraft.block.BlockStone$EnumType#getTranslation()") - .add("net.minecraft.block.BlockStoneBrick$EnumType#getTranslation()") - .add("net.minecraft.block.BlockStoneSlab$EnumType#getTranslation()") - .add("net.minecraft.block.BlockStoneSlabNew$EnumType#getTranslation()") - .add("net.minecraft.item.ItemArmor$ArmorMaterial#getRepairItemType()") - .build(); - - // Ignored translation prefixes + whether it was provided by sponge - private static final Map ignoredTranslationPrefixes = ImmutableMap.builder() - .put("sponge.statistic.type.", true) - .put("item.", false) - .put("entity.", false) - .put("stat.", false) - .put("tile.", false) - .put("potion.effect.missing", false) // Needs API changes - .put("gameMode.", false) - .build(); - - @Parameterized.Parameter(0) - public String name; - @Parameterized.Parameter(1) - public Class catalogClass; - @Parameterized.Parameter(2) - public CatalogType catalogType; - @Parameterized.Parameter(3) - public String catalogId; - @Parameterized.Parameter(4) - public Method method; - @Parameterized.Parameter(5) - public String methodName; - @Parameterized.Parameter(6) - public String implementationClass; - - @Test - public void testCatalogMethodImpl() throws Throwable { - try { - try { - testResult(checkNotNull(this.method.invoke(this.catalogType), "return value")); - } catch (InvocationTargetException e) { - // Unwrap exception to avoid useless stacktrace entries - if (e.getCause() != null) { - throw e.getCause(); - } - throw e; - } - } catch (Throwable t) { - if (ignoredFailures.contains(this.implementationClass + "#" + this.method.getName() + "()")) { -// LOG.warn("Catalog Type: {} Id : {} has broken Method: {} ({}): {}", this.name, this.catalogId, this.methodName, this.implementationClass, t); - return; - } - throw t; - } - } - - private void testResult(Object object) { - checkNotNull(object, "contained value"); - if (object instanceof Optional) { - ((Optional) object).ifPresent(this::testResult); - } - if (object instanceof Iterable) { - int index = 0; - for (Object elem : (Iterable) object) { - try { - testResult(elem); - index++; - } catch (Throwable t) { - throw new RuntimeException("Failed on sub-element: " + index, t); - } - } - } - if (object instanceof Translatable) { - testResult(((Translatable) object).getTranslation()); - } - if (object instanceof Translation) { - Translation translation = (Translation) object; - String translationId = checkNotNull(translation.getId(), "translationId"); - String translated = checkNotNull(translation.get(), "translated"); - if (translationId.equals(translated)) { - boolean ignore = false; - boolean silent = false; - for (Entry entry : ignoredTranslationPrefixes.entrySet()) { - if (translationId.startsWith(entry.getKey())) { - ignore = true; - silent = entry.getValue(); - } - } - if (silent) { - // Do nothing - } else if (ignore) { - // Disabling logging for now, until someone ends up fixing the translations and tests. - // LOG.warn("Catalog Type: {} Id : {} fails to provide translation: '{}' in {} ({})", this.name, this.catalogId, translationId, this.methodName, this.implementationClass); - } else { - throw new RuntimeException("No translation present for " + translationId); - } - } - } - } - -} diff --git a/src/test/invalid/common/registry/RegistryModuleTest.java b/src/test/invalid/common/registry/RegistryModuleTest.java deleted file mode 100644 index d0933ac796a..00000000000 --- a/src/test/invalid/common/registry/RegistryModuleTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.registry; - - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.spongepowered.lwts.runner.LaunchWrapperParameterized; - -@RunWith(LaunchWrapperParameterized.class) -public class RegistryModuleTest { - - @Parameterized.Parameters(name = "{index} Catalog Type: {0} Id : {4}") - public static Iterable data() throws Exception { - return RegistryTestUtil.generateRegistryTestObjects(); - } - - @Parameterized.Parameter(0) public String name; - @Parameterized.Parameter(1) public Class catalogClass; - @Parameterized.Parameter(2) public CatalogRegistryModule registryModule; - @Parameterized.Parameter(3) public CatalogType catalogType; - @Parameterized.Parameter(4) public String catalogId; - -// @Test -// @Ignore -// public void testIdValidity() { -// assertThat("The CatalogType " + this.catalogType.getName() + " has an invalid id", this.catalogId.startsWith("minecraft:") || this.catalogId.startsWith("sponge:")); -// assertThat("The CatalogType " + this.catalogType.getName() + " has spaces! It should never be spaced!", !this.catalogId.contains(" ")); -// } - - @Test - public void testGetCatalogTypeFromAll() { - final boolean contains = this.registryModule.getAll().contains(this.catalogType); - assertThat("The CatalogType " + this.catalogType.getId() + " could not be located in the \n" - + "all collection of " + this.registryModule.getClass().getSimpleName() + ".", - contains, is(true)); - } - - @Test - public void testGetCatalogTypeById() { - assertThat("The CatalogType " + this.catalogType.getId() + " could not be retrieved by id \n" - + "from " + this.registryModule.getClass().getSimpleName() + " with the following id: \n" - + this.catalogId, - this.registryModule.getById(this.catalogType.getId()).isPresent(), is(true)); - } - - -} diff --git a/src/test/invalid/common/registry/RegistryTestUtil.java b/src/test/invalid/common/registry/RegistryTestUtil.java deleted file mode 100644 index ed21337f36c..00000000000 --- a/src/test/invalid/common/registry/RegistryTestUtil.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.registry; - -import org.spongepowered.api.util.annotation.CatalogedBy; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -class RegistryTestUtil { - - static Iterable generateRegistryTestObjects() { - - final ArrayList array = new ArrayList<>(); - for (Map.Entry, CatalogRegistryModule> entry : SpongeGameRegistry.REGISTRY_MAP.entrySet()) { - for (CatalogType catalogType : entry.getValue().getAll()) { - array.add(new Object[]{entry.getKey().getSimpleName(), entry.getKey(), entry.getValue(), catalogType, catalogType.getId()}); - } - } - return array; - } - - static Iterable generateCatalogContainerTestObjects() { - - final ArrayList objects = new ArrayList<>(); - for (Map.Entry, CatalogRegistryModule> entry : SpongeGameRegistry.REGISTRY_MAP.entrySet()) { - final Class key = entry.getKey(); - final CatalogedBy catalogedBy = key.getAnnotation(CatalogedBy.class); - if (catalogedBy != null) { - for (Class containerClass : catalogedBy.value()) { - for (Field field : containerClass.getFields()) { - if (Modifier.isStatic(field.getModifiers())) { - objects.add(new Object[] {field.getName(), entry.getKey(), containerClass, entry.getValue(), field}); - } - } - } - } - } - - return objects; - } - - static Iterable generateCatalogTypeMethodTestObjects() { - - final ArrayList array = new ArrayList<>(); - for (Map.Entry, CatalogRegistryModule> entry : SpongeGameRegistry.REGISTRY_MAP.entrySet()) { - for (CatalogType catalogType : entry.getValue().getAll()) { - for (Method method : getTestableApiMethods(getApplicableApiCatalogTypeInterfaces(catalogType))) { - array.add(new Object[] {entry.getKey().getSimpleName(), entry.getKey(), catalogType, catalogType.getId(), method, - method.getDeclaringClass().getSimpleName() + "#" + method.getName() + "()", catalogType.getClass().getName()}); - } - } - } - return array; - } - - static Stream> getApplicableApiInterfaces(Object instance) { - Collection> interfaces = new LinkedHashSet<>(); - Class current = instance.getClass(); - while (current != null) { - interfaces.addAll(Arrays.asList(current.getInterfaces())); - current = current.getSuperclass(); - } - return interfaces.stream() - .filter(clazz -> clazz.getName().startsWith("org.spongepowered.api.")); - } - - static Stream> getApplicableApiCatalogTypeInterfaces(Object instance) { - return getApplicableApiInterfaces(instance) - .filter(CatalogType.class::isAssignableFrom) - .map(clazz -> clazz.asSubclass(CatalogType.class)); - } - - static Set getTestableApiMethods(Stream> clazzes) { - return clazzes.map(Class::getMethods) - .flatMap(Arrays::stream) - .filter(m -> m.getParameters().length == 0) - .collect(Collectors.toSet()); - } - -} diff --git a/src/test/invalid/common/regression/registry/Test1Tile.java b/src/test/invalid/common/regression/registry/Test1Tile.java deleted file mode 100644 index 9e959f85276..00000000000 --- a/src/test/invalid/common/regression/registry/Test1Tile.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.regression.registry; - -import net.minecraft.tileentity.TileEntity; - -public final class Test1Tile extends TileEntity { } diff --git a/src/test/invalid/common/regression/registry/Test2Tile.java b/src/test/invalid/common/regression/registry/Test2Tile.java deleted file mode 100644 index 90faf1c8bc4..00000000000 --- a/src/test/invalid/common/regression/registry/Test2Tile.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.regression.registry; - -import net.minecraft.tileentity.TileEntity; - -public final class Test2Tile extends TileEntity { } diff --git a/src/test/invalid/common/regression/registry/Test3Tile.java b/src/test/invalid/common/regression/registry/Test3Tile.java deleted file mode 100644 index 583dde5cbc0..00000000000 --- a/src/test/invalid/common/regression/registry/Test3Tile.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.regression.registry; - -import net.minecraft.tileentity.TileEntity; - -public final class Test3Tile extends TileEntity { } diff --git a/src/test/invalid/common/regression/registry/TileEntityRegistrationTest.java b/src/test/invalid/common/regression/registry/TileEntityRegistrationTest.java deleted file mode 100644 index 625a3d4824c..00000000000 --- a/src/test/invalid/common/regression/registry/TileEntityRegistrationTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.regression.registry; - -import static org.junit.Assert.assertEquals; - -import com.flowpowered.math.vector.Vector3i; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.chunk.storage.AnvilSaveHandler; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.spongepowered.api.block.tileentity.TileEntityType; -import org.spongepowered.common.registry.type.block.TileEntityTypeRegistryModule; -import org.spongepowered.common.test.RegressionTest; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -@RunWith(LaunchWrapperTestRunner.class) -public class TileEntityRegistrationTest { - - - @RegressionTest(ghIssue = "https://github.com/SpongePowered/SpongeForge/issues/2761", - relatedCommits = "https://github.com/SpongePowered/sponge/commit/2e394dc71f03026f937ad332eab57020eb55e536" - ) - public static final String UNQUALIFIED_TILE_ID = "mod.you.are"; - public static final String CORRECTLY_QUALIFIED_ID = "sponge:myfodo"; - public static final String MINECRAFT_PREFIXED_ID = "minecraft:mod.and.youAreMySamwise"; - - @BeforeClass - public static void setupSchematic() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - // Idea: register a few dummy tile entities with the following: - // 'mod.sponge.herpaderpa' - // 'sponge:herpaderpderp' - // 'minecraft:mod.sponge.herpadpera' - final Method tileRegisterMethod = TileEntity.class.getDeclaredMethod("register", String.class, Class.class); - tileRegisterMethod.setAccessible(true); - tileRegisterMethod.invoke(null, UNQUALIFIED_TILE_ID, Test1Tile.class); - tileRegisterMethod.invoke(null, CORRECTLY_QUALIFIED_ID, Test2Tile.class); - tileRegisterMethod.invoke(null, MINECRAFT_PREFIXED_ID, Test3Tile.class); - } - - /** - * This verifies that our custom tile entity types are being registered, both as sponge mod prefixed, and - * the rare case where a forge mod is being registered as "minecraft:" prefixed. These come into play for the - * required mods section of schematics. - */ - @RegressionTest(ghIssue = "https://github.com/SpongePowered/SpongeForge/issues/2785") - @SuppressWarnings("ConstantConditions") - @Test - public void testGettingTileEntityTypes() { - final TileEntityType test1type = TileEntityTypeRegistryModule.getInstance().getForClass(Test1Tile.class); - final TileEntityType test2type = TileEntityTypeRegistryModule.getInstance().getForClass(Test2Tile.class); - final TileEntityType test3type = TileEntityTypeRegistryModule.getInstance().getForClass(Test3Tile.class); - - @RegressionTest(ghIssue = "https://github.com/SpongePowered/SpongeForge/issues/2785", - comment = "Specifically put, Forge has a weird case where they auto-prefix mod provided" - + "id's " - ) - final String autoPrefixed = "sponge:" + UNQUALIFIED_TILE_ID; - assertEquals(autoPrefixed, test1type.getId()); // Note that SpongeImplHooks by default will prefix based on package, so we're good. - assertEquals(CORRECTLY_QUALIFIED_ID, test2type.getId()); - assertEquals(MINECRAFT_PREFIXED_ID, test3type.getId()); - - assertEquals(((org.spongepowered.api.block.tileentity.TileEntity) (Object) new Test1Tile()).getType(), test1type); - assertEquals(((org.spongepowered.api.block.tileentity.TileEntity) (Object) new Test2Tile()).getType(), test2type); - assertEquals(((org.spongepowered.api.block.tileentity.TileEntity) (Object) new Test3Tile()).getType(), test3type); - } -} diff --git a/src/test/invalid/common/service/pagination/PaginationCalculatorTest.java b/src/test/invalid/common/service/pagination/PaginationCalculatorTest.java deleted file mode 100644 index d3b7a416dd8..00000000000 --- a/src/test/invalid/common/service/pagination/PaginationCalculatorTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.service.game.pagination; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyZeroInteractions; - -import org.junit.Before; -import org.junit.Test; -import org.spongepowered.api.text.channel.MessageReceiver; - -public class PaginationCalculatorTest { - - PaginationCalculator pc; - private MessageReceiver src; - - @Before - public void setUp() throws Exception { - this.pc = new PaginationCalculator(10); - this.src = mock(MessageReceiver.class); - } - - @Test - public void linesTest() throws Exception { - int lines = this.pc.getLinesPerPage(this.src); - assertEquals("Lines per page should be 10", 10, lines); - //Current implementation doesn't use source, update tests once PaginationCalculator is actually source specific. - verifyZeroInteractions(this.src); - } - -} diff --git a/src/test/invalid/common/test/RegressionTest.java b/src/test/invalid/common/test/RegressionTest.java deleted file mode 100644 index 56fedcc69de..00000000000 --- a/src/test/invalid/common/test/RegressionTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An annotation used to mark tests that ensure that a specific - * Sponge issue has not regressed. These will usually, but not always, - * be written using Mctester. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.LOCAL_VARIABLE}) -public @interface RegressionTest { - - /** - * A fully-qualified link to the GitHub issue being tested by this test. - * - *

Example: 'https://github.com/SpongePowered/Sponge/issues/1945'

- * - * @return The URL of the issue - */ - String ghIssue(); - - /** - * A fully qualified link to a commit related to the issue where possible - * regressions took place as a byproduct to said commits. - * - *

Example: 'https://github.com/SpongePowered/Sponge/commit/2e394dc71f03026f937ad332eab57020eb55e536'

- * - * @return The URL of the related commits - */ - String[] relatedCommits() default {}; - - /** - * Any additional comments about the regresion issue that can be made, maybe outside - * the javadoc comment of the overall test. - * - * @return The comment about the regression to avoid - */ - String comment() default ""; - -} diff --git a/src/test/invalid/common/test/TestGame.java b/src/test/invalid/common/test/TestGame.java deleted file mode 100644 index a526e498a6e..00000000000 --- a/src/test/invalid/common/test/TestGame.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.spongepowered.api.Server; -import org.spongepowered.common.SpongeGame; - -import java.nio.file.Path; - -@Singleton -public class TestGame extends SpongeGame { - - private TestServer server; - - @Inject - public TestGame(TestServer server) { - this.server = server; - } - - @Override - public boolean isServerAvailable() { - return false; - } - - @Override - public Server getServer() { - return this.server; - } - - @Override - public Path getSavesDirectory() { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/test/invalid/common/test/TestMain.java b/src/test/invalid/common/test/TestMain.java deleted file mode 100644 index 173584d1e1d..00000000000 --- a/src/test/invalid/common/test/TestMain.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import com.google.inject.Guice; -import net.minecraft.init.Bootstrap; -import org.spongepowered.common.inject.SpongeModule; -import org.spongepowered.common.test.inject.TestImplementationModule; - -public final class TestMain { - - private TestMain() { - } - - public static void main(String[] args) { - Bootstrap.register(); - SpongeGameRegistry registry = Guice.createInjector(new SpongeModule(), new TestImplementationModule()) - .getInstance(SpongeGameRegistry.class); - - registry.preRegistryInit(); - registry.preInit(); - registry.init(); - registry.postInit(); - } - -} diff --git a/src/test/invalid/common/test/TestServer.java b/src/test/invalid/common/test/TestServer.java deleted file mode 100644 index 43b7e3e968c..00000000000 --- a/src/test/invalid/common/test/TestServer.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test; - -import com.google.inject.Singleton; -import org.spongepowered.api.Server; -import org.spongepowered.api.command.source.ConsoleSource; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.profile.GameProfileManager; -import org.spongepowered.api.resourcepack.ResourcePack; -import org.spongepowered.api.scoreboard.Scoreboard; -import org.spongepowered.api.world.ChunkTicketManager; -import org.spongepowered.api.world.World; -import org.spongepowered.api.world.WorldArchetype; -import org.spongepowered.api.world.storage.ChunkLayout; -import org.spongepowered.api.world.storage.WorldProperties; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.Collections; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -@Singleton -public class TestServer implements Server { - - @Override - public Collection getOnlinePlayers() { - return Collections.emptyList(); - } - - @Override - public int getMaxPlayers() { - return 0; - } - - @Override - public Optional getPlayer(UUID uniqueId) { - return Optional.empty(); - } - - @Override - public Optional getPlayer(String name) { - return Optional.empty(); - } - - @Override - public Collection getWorlds() { - return Collections.emptyList(); - } - - @Override - public Collection getUnloadedWorlds() { - return Collections.emptyList(); - } - - @Override - public Collection getAllWorldProperties() { - return Collections.emptyList(); - } - - @Override - public Optional getWorld(UUID uniqueId) { - return Optional.empty(); - } - - @Override - public Optional getWorld(String worldName) { - return Optional.empty(); - } - - @Override - public Optional getDefaultWorld() { - return Optional.empty(); - } - - @Override - public String getDefaultWorldName() { - return "test"; - } - - @Override - public Optional loadWorld(String worldName) { - return Optional.empty(); - } - - @Override - public Optional loadWorld(UUID uniqueId) { - return Optional.empty(); - } - - @Override - public Optional loadWorld(WorldProperties properties) { - return Optional.empty(); - } - - @Override - public Optional getWorldProperties(String worldName) { - return Optional.empty(); - } - - @Override - public Optional getWorldProperties(UUID uniqueId) { - return Optional.empty(); - } - - @Override - public boolean unloadWorld(World world) { - return false; - } - - @Override - public WorldProperties createWorldProperties(String folderName, WorldArchetype archetype) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public CompletableFuture> copyWorld(WorldProperties worldProperties, String copyName) { - throw new UnsupportedOperationException(); - } - - @Override - public Optional renameWorld(WorldProperties worldProperties, String newName) { - return Optional.empty(); - } - - @Override - public CompletableFuture deleteWorld(WorldProperties worldProperties) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean saveWorldProperties(WorldProperties properties) { - return false; - } - - @Override - public Optional getServerScoreboard() { - return Optional.empty(); - } - - @Override - public ChunkLayout getChunkLayout() { - throw new UnsupportedOperationException(); - } - - @Override - public int getRunningTimeTicks() { - return 0; - } - - @Override - public MessageChannel getBroadcastChannel() { - throw new UnsupportedOperationException(); - } - - @Override - public void setBroadcastChannel(MessageChannel channel) { - throw new UnsupportedOperationException(); - - } - - @Override - public Optional getBoundAddress() { - return Optional.empty(); - } - - @Override - public boolean hasWhitelist() { - return false; - } - - @Override - public void setHasWhitelist(boolean enabled) { - throw new NoSuchElementException(); - } - - @Override - public boolean getOnlineMode() { - return false; - } - - @Override - public Text getMotd() { - throw new UnsupportedOperationException(); - } - - @Override - public void shutdown() { - throw new UnsupportedOperationException(); - } - - @Override - public void shutdown(Text kickMessage) { - throw new UnsupportedOperationException(); - } - - @Override - public ConsoleSource getConsole() { - throw new NoSuchElementException(); - } - - @Override - public ChunkTicketManager getChunkTicketManager() { - throw new NoSuchElementException(); - } - - @Override - public GameProfileManager getGameProfileManager() { - throw new NoSuchElementException(); - } - - @Override - public double getTicksPerSecond() { - return 0; - } - - @Override - public Optional getDefaultResourcePack() { - return Optional.empty(); - } - - @Override - public int getPlayerIdleTimeout() { - return 0; - } - - @Override - public void setPlayerIdleTimeout(int timeout) { - - } - - @Override - public boolean isMainThread() { - return true; - } -} diff --git a/src/test/invalid/common/test/inject/TestImplementationModule.java b/src/test/invalid/common/test/inject/TestImplementationModule.java deleted file mode 100644 index 997e6ea6cfe..00000000000 --- a/src/test/invalid/common/test/inject/TestImplementationModule.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.test.inject; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.spongepowered.api.Platform; -import org.spongepowered.api.Server; -import org.spongepowered.api.event.EventManager; -import org.spongepowered.api.network.ChannelRegistrar; -import org.spongepowered.api.plugin.PluginManager; -import org.spongepowered.common.SpongeGame; -import org.spongepowered.common.SpongeImpl; -import org.spongepowered.common.inject.SpongeImplementationModule; -import org.spongepowered.common.test.TestGame; -import org.spongepowered.common.test.TestServer; -import org.spongepowered.plugin.PluginContainer; - -import java.util.Optional; - -public class TestImplementationModule extends SpongeImplementationModule { - - @Override - protected void configure() { - super.configure(); - - this.bind(Server.class).to(TestServer.class); - this.bind(SpongeGame.class).to(TestGame.class); - Platform platform = mock(Platform.class); - when(platform.getExecutionType()).thenReturn(Platform.Type.SERVER); - PluginContainer mock = mock(PluginContainer.class); - when(platform.getContainer(any())).thenReturn(mock); - this.bind(Platform.class).toInstance(platform); - - PluginManager manager = mock(PluginManager.class); - when(mock.getId()).thenReturn("sponge"); - when(manager.getPlugin(anyString())).thenReturn(Optional.of(mock)); - when(manager.fromInstance(any())).thenReturn(Optional.of(mock)); - this.bind(PluginManager.class).toInstance(manager); - PluginContainer common = mock(PluginContainer.class); - SpongeImpl.setSpongePlugin(common); - this.bind(EventManager.class).toInstance(mock(EventManager.class)); - this.bind(ChannelRegistrar.class).toInstance(mock(ChannelRegistrar.class)); - } -} diff --git a/src/test/invalid/common/text/LegacyParserTest.java b/src/test/invalid/common/text/LegacyParserTest.java deleted file mode 100644 index acef8be771d..00000000000 --- a/src/test/invalid/common/text/LegacyParserTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.text; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; - -@RunWith(LaunchWrapperTestRunner.class) -public class LegacyParserTest { - - private static Text parse(String input) { - return TextSerializers.FORMATTING_CODE.deserialize(input); - } - - @Test - public void testPlain() { - assertEquals(Text.EMPTY, parse("")); - assertEquals(Text.of("&&"), parse("&&")); - assertEquals(Text.of("Sponge"), parse("Sponge")); - assertEquals(Text.of("Sponge & Water"), parse("Sponge & Water")); - } - - @Test - public void testSimple() { - assertEquals(Text.builder("Sponge").color(TextColors.GOLD).build(), parse("&6Sponge")); - } - - @Test - public void testMany() { - assertEquals(Text.builder("Hello ").append(Text.builder("Sponge").color(TextColors.YELLOW).build()).build(), - parse("Hello &eSponge")); - assertEquals(Text.builder().append( - Text.builder("Sponge").color(TextColors.YELLOW).style(TextStyles.BOLD).build(), - Text.builder(" & ").color(TextColors.RESET).build(), - Text.builder("Water").color(TextColors.AQUA).style(TextStyles.ITALIC).build()).build(), - parse("&e&lSponge&r & &b&oWater")); - } - - @Test - public void testRedundantFormattingCodes() { - assertEquals(Text.EMPTY, parse("&c&e&l&f")); - assertEquals(Text.builder("Hello ").append(Text.builder("Sponge").color(TextColors.YELLOW).build()).build(), - parse("Hello &a&f&e&eSponge")); - } - -} diff --git a/src/test/invalid/common/text/LegacySerializerTest.java b/src/test/invalid/common/text/LegacySerializerTest.java deleted file mode 100644 index cd192d8fe1b..00000000000 --- a/src/test/invalid/common/text/LegacySerializerTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.text; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.spongepowered.common.text.SpongeTexts.COLOR_CHAR; - -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; - -@RunWith(LaunchWrapperTestRunner.class) -public class LegacySerializerTest { - - @Test - public void testPlainText() { - assertThat(SpongeTexts.toLegacy(new TextComponentString("test")), is("test")); - } - - @Test - public void testTranslatableText() { - assertThat(SpongeTexts.toLegacy(new TextComponentTranslation("test")), is("test")); - } - - @Test - public void testColoredText() { - ITextComponent component = new TextComponentString("test"); - component.getStyle().setColor(TextFormatting.RED); - assertThat(SpongeTexts.toLegacy(component), is(COLOR_CHAR + "ctest")); - } - - @Test - public void testNestedText() { - ITextComponent component = new TextComponentString("first"); - component.getStyle().setColor(TextFormatting.RED); - - component.appendSibling(new TextComponentString("second")); - - TextComponentString component2 = new TextComponentString("third"); - component2.getStyle().setColor(TextFormatting.BLUE); - component.appendSibling(component2); - - assertThat(SpongeTexts.toLegacy(component), is(COLOR_CHAR + "cfirstsecond" + COLOR_CHAR + "9third")); - } - - @Test - public void testEmptyTranslatableText() { - assertThat(SpongeTexts.toLegacy(new TextComponentString("blah").appendSibling(new TextComponentTranslation(""))), is("blah")); - } - -} diff --git a/src/test/invalid/common/world/storage/SpongeChunkLayoutTest.java b/src/test/invalid/common/world/storage/SpongeChunkLayoutTest.java deleted file mode 100644 index 0ef2a22cbbd..00000000000 --- a/src/test/invalid/common/world/storage/SpongeChunkLayoutTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.common.world.storage; - -import com.flowpowered.math.vector.Vector3i; -import org.junit.Assert; -import org.junit.Test; -import org.spongepowered.api.util.Direction; - -public class SpongeChunkLayoutTest { - - @Test - public void testConstants() { - Assert.assertEquals(new Vector3i(16, 256, 16), SpongeChunkLayout.instance.getChunkSize()); - Assert.assertEquals(new Vector3i(1874999, 0, 1874999), SpongeChunkLayout.instance.getSpaceMax()); - Assert.assertEquals(new Vector3i(-1875000, 0, -1875000), SpongeChunkLayout.instance.getSpaceMin()); - Assert.assertEquals(new Vector3i(3750000, 1, 3750000), SpongeChunkLayout.instance.getSpaceSize()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.getSpaceOrigin()); - } - - @Test - public void testCoordValidation() { - Assert.assertTrue(SpongeChunkLayout.instance.isValidChunk(new Vector3i(0, 0, 0))); - Assert.assertTrue(SpongeChunkLayout.instance.isValidChunk(0, 0, 0)); - Assert.assertTrue(SpongeChunkLayout.instance.isValidChunk(new Vector3i(1874999, 0, 1874999))); - Assert.assertTrue(SpongeChunkLayout.instance.isValidChunk(1874999, 0, 1874999)); - Assert.assertTrue(SpongeChunkLayout.instance.isValidChunk(new Vector3i(-1875000, 0, -1875000))); - Assert.assertTrue(SpongeChunkLayout.instance.isValidChunk(-1875000, 0, -1875000)); - - Assert.assertFalse(SpongeChunkLayout.instance.isValidChunk(1875000, 0, 1874999)); - Assert.assertFalse(SpongeChunkLayout.instance.isValidChunk(1874999, 1, 1874999)); - Assert.assertFalse(SpongeChunkLayout.instance.isValidChunk(1874999, 0, 1875000)); - Assert.assertFalse(SpongeChunkLayout.instance.isValidChunk(-1875001, 0, -1875000)); - Assert.assertFalse(SpongeChunkLayout.instance.isValidChunk(-1875000, -1, -1875000)); - Assert.assertFalse(SpongeChunkLayout.instance.isValidChunk(-1875000, 0, -1875001)); - - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(0, 0, 0)); - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(new Vector3i(14, 125, 9))); - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(14, 125, 9)); - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(15, 255, 15)); - - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(new Vector3i(-1, 0, 0))); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(new Vector3i(0, -1, 0))); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(new Vector3i(0, 0, -1))); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(-1, 0, 0)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(0, -1, 0)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(0, 0, -1)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(16, 255, 15)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(15, 256, 15)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(15, 255, 16)); - - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(0, 0, 0, 0, 0, 0)); - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(new Vector3i(30, 125, -7), new Vector3i(1, 0, -1))); - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(30, 125, -7, 1, 0, -1)); - Assert.assertTrue(SpongeChunkLayout.instance.isInChunk(65, 255, -33, 4, 0, -3)); - - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(new Vector3i(-17, 0, 0), new Vector3i(-1, 0, 0))); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(new Vector3i(0, -257, 0), new Vector3i(0, -1, 0))); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(new Vector3i(0, 0, -17), new Vector3i(0, 0, -1))); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(-17, 0, 0, -1, 0, 0)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(0, -257, 0, 0, -1, 0)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(0, 0, -17, 0, 0, -1)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(32, 255, 31, 1, 0, 1)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(31, 256, 31, 1, 0, 1)); - Assert.assertFalse(SpongeChunkLayout.instance.isInChunk(31, 255, 32, 1, 0, 1)); - } - - @Test - public void testCoordConversion() { - // chunk to world - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.toChunk(Vector3i.ZERO).get()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.toChunk(0, 0, 0).get()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.toChunk(new Vector3i(15, 255, 15)).get()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.toChunk(15, 255, 15).get()); - - Assert.assertEquals(new Vector3i(2, 0, 4), SpongeChunkLayout.instance.toChunk(new Vector3i(34, 121, 72)).get()); - Assert.assertEquals(new Vector3i(2, 0, 4), SpongeChunkLayout.instance.toChunk(34, 121, 72).get()); - - Assert.assertEquals(new Vector3i(-6, 0, -13), SpongeChunkLayout.instance.toChunk(new Vector3i(-83, 62, -203)).get()); - Assert.assertEquals(new Vector3i(-6, 0, -13), SpongeChunkLayout.instance.toChunk(-83, 62, -203).get()); - - Assert.assertFalse(SpongeChunkLayout.instance.toChunk(30000000, 0, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toChunk(-30000001, 0, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toChunk(0, 256, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toChunk(0, -1, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toChunk(0, 0, 30000000).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toChunk(0, 0, -30000001).isPresent()); - - // world to chunk - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.toWorld(Vector3i.ZERO).get()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.toWorld(0, 0, 0).get()); - - Assert.assertEquals(new Vector3i(32, 0, 64), SpongeChunkLayout.instance.toWorld(new Vector3i(2, 0, 4)).get()); - Assert.assertEquals(new Vector3i(32, 0, 64), SpongeChunkLayout.instance.toWorld(2, 0, 4).get()); - - Assert.assertEquals(new Vector3i(-96, 0, -208), SpongeChunkLayout.instance.toWorld(new Vector3i(-6, 0, -13)).get()); - Assert.assertEquals(new Vector3i(-96, 0, -208), SpongeChunkLayout.instance.toWorld(-6, 0, -13).get()); - - Assert.assertFalse(SpongeChunkLayout.instance.toWorld(1875000, 0, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toWorld(-1875001, 0, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toWorld(0, 1, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toWorld(0, -1, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toWorld(0, 0, 1875000).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.toWorld(0, 0, -1875001).isPresent()); - } - - @Test - public void testCoordAdd() { - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.addToChunk(Vector3i.ZERO, Vector3i.ZERO).get()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.addToChunk(0, 0, 0, 0, 0, 0).get()); - - Assert.assertEquals(new Vector3i(7, 0, 5), SpongeChunkLayout.instance.addToChunk(3, 0, 5, 4, 0, 0).get()); - Assert.assertEquals(new Vector3i(7, 0, 9), SpongeChunkLayout.instance.addToChunk(3, 0, 5, 4, 0, 4).get()); - - Assert.assertFalse(SpongeChunkLayout.instance.addToChunk(1874999, 0, 0, 1, 0, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.addToChunk(0, 0, 0, 0, 1, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.addToChunk(0, 0, 1874999, 0, 0, 1).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.addToChunk(-1875000, 0, 0, -1, 0, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.addToChunk(0, 0, 0, 0, -1, 0).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.addToChunk(0, 0, -1875000, 0, 0, -1).isPresent()); - } - - @Test - public void testCoordMove() { - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.moveToChunk(Vector3i.ZERO, Direction.NONE).get()); - Assert.assertEquals(Vector3i.ZERO, SpongeChunkLayout.instance.moveToChunk(0, 0, 0, Direction.NONE).get()); - - Assert.assertEquals(new Vector3i(4, 0, 5), SpongeChunkLayout.instance.moveToChunk(3, 0, 5, Direction.EAST).get()); - Assert.assertEquals(new Vector3i(7, 0, 5), SpongeChunkLayout.instance.moveToChunk(3, 0, 5, Direction.EAST, 4).get()); - Assert.assertEquals(new Vector3i(4, 0, 6), SpongeChunkLayout.instance.moveToChunk(3, 0, 5, Direction.SOUTHEAST).get()); - Assert.assertEquals(new Vector3i(7, 0, 9), SpongeChunkLayout.instance.moveToChunk(3, 0, 5, Direction.SOUTHEAST, 4).get()); - - Assert.assertFalse(SpongeChunkLayout.instance.moveToChunk(1874999, 0, 0, Direction.EAST).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.moveToChunk(0, 0, 0, Direction.UP).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.moveToChunk(0, 0, 1874999, Direction.SOUTH).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.moveToChunk(-1875000, 0, 0, Direction.WEST).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.moveToChunk(0, 0, 0, Direction.DOWN).isPresent()); - Assert.assertFalse(SpongeChunkLayout.instance.moveToChunk(0, 0, -1875000, Direction.NORTH).isPresent()); - - try { - SpongeChunkLayout.instance.moveToChunk(0, 0, 0, Direction.SOUTH_SOUTHEAST); - Assert.fail(); - } catch (IllegalArgumentException ignored) { - // we expect this exception - } - } - -} diff --git a/src/test/invalid/common/util/IpSetTest.java b/src/test/java/org/spongepowered/common/config/core/IpSetTest.java similarity index 70% rename from src/test/invalid/common/util/IpSetTest.java rename to src/test/java/org/spongepowered/common/config/core/IpSetTest.java index 0c4381f3aff..e13decb39d8 100644 --- a/src/test/invalid/common/util/IpSetTest.java +++ b/src/test/java/org/spongepowered/common/config/core/IpSetTest.java @@ -22,12 +22,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.util; +package org.spongepowered.common.config.core; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.spongepowered.common.launch.config.core.IpSet; import java.net.InetAddress; import java.net.UnknownHostException; @@ -36,29 +37,29 @@ public class IpSetTest { @Test public void testIpv4Set() throws UnknownHostException { IpSet spec = IpSet.fromCidr("10.42.0.0/16"); - assertTrue(spec.apply(InetAddress.getByName("10.42.2.5"))); - assertFalse(spec.apply(InetAddress.getByName("10.43.2.5"))); + assertTrue(spec.test(InetAddress.getByName("10.42.2.5"))); + assertFalse(spec.test(InetAddress.getByName("10.43.2.5"))); } @Test public void testIpv6Set() throws UnknownHostException { IpSet spec = IpSet.fromCidr("[fc00::]/8"); - assertTrue(spec.apply(InetAddress.getByName("fcc0:c0b2:2a14:7afc:5216:1854:1a2f:2c13"))); + assertTrue(spec.test(InetAddress.getByName("fcc0:c0b2:2a14:7afc:5216:1854:1a2f:2c13"))); spec = IpSet.fromCidr("::/0"); - assertTrue(spec.apply(InetAddress.getByName("::dead:beef"))); + assertTrue(spec.test(InetAddress.getByName("::dead:beef"))); } @Test public void testNonByteAlignedSets() throws UnknownHostException { IpSet spec = IpSet.fromCidr("[2064:45:300::]/40"); - assertTrue(spec.apply(InetAddress.getByName("2064:45:310::cafe"))); - assertFalse(spec.apply(InetAddress.getByName("2064:45:410::cafe"))); + assertTrue(spec.test(InetAddress.getByName("2064:45:310::cafe"))); + assertFalse(spec.test(InetAddress.getByName("2064:45:410::cafe"))); } @Test public void testFullLengthSets() throws UnknownHostException { IpSet specv4 = IpSet.fromCidr("10.0.0.1/32"); - assertTrue(specv4.apply(InetAddress.getByName("10.0.0.1"))); - assertFalse(specv4.apply(InetAddress.getByName("10.0.0.2"))); + assertTrue(specv4.test(InetAddress.getByName("10.0.0.1"))); + assertFalse(specv4.test(InetAddress.getByName("10.0.0.2"))); } } diff --git a/src/test/invalid/common/event/EventFilterTest.java b/src/test/java/org/spongepowered/common/event/EventFilterTest.java similarity index 54% rename from src/test/invalid/common/event/EventFilterTest.java rename to src/test/java/org/spongepowered/common/event/EventFilterTest.java index 7d06ee6b8ff..35e3344274f 100644 --- a/src/test/invalid/common/event/EventFilterTest.java +++ b/src/test/java/org/spongepowered/common/event/EventFilterTest.java @@ -24,65 +24,57 @@ */ package org.spongepowered.common.event; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.junit.Assert; -import org.junit.Test; +import net.kyori.adventure.text.Component; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.data.manipulator.mutable.entity.SkinData; +import org.spongepowered.api.data.Keys; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Cancellable; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.event.Event; -import org.spongepowered.api.event.block.ChangeBlockEvent; -import org.spongepowered.api.event.cause.Cause; -import org.spongepowered.api.event.cause.EventContext; +import org.spongepowered.api.event.EventContext; +import org.spongepowered.api.event.block.InteractBlockEvent; import org.spongepowered.api.item.inventory.ItemStack; -import org.spongepowered.api.world.biome.BiomeTypes; -import org.spongepowered.api.world.extent.Extent; -import org.spongepowered.common.event.filter.FilterFactory; -import org.spongepowered.common.event.listener.AllCauseListener; -import org.spongepowered.common.event.listener.BeforeAfterCauseListener; -import org.spongepowered.common.event.listener.CancelledListener; -import org.spongepowered.common.event.listener.CovariantGetterListener; -import org.spongepowered.common.event.listener.DataHasListener; -import org.spongepowered.common.event.listener.DataSupportsListener; -import org.spongepowered.common.event.listener.DoubleListener; -import org.spongepowered.common.event.listener.FirstLastCauseListener; -import org.spongepowered.common.event.listener.GetterListener; -import org.spongepowered.common.event.listener.IncludeExcludeListener; -import org.spongepowered.common.event.listener.InvalidIncludeExcludeListener; -import org.spongepowered.common.event.listener.RootListener; -import org.spongepowered.common.event.listener.SimpleListener; +import org.spongepowered.api.world.World; +import org.spongepowered.common.event.filter.FilterGenerator; +import org.spongepowered.common.event.listener.*; +import org.spongepowered.common.event.manager.AnnotatedEventListener; +import org.spongepowered.common.event.manager.ClassEventListenerFactory; +import org.spongepowered.common.event.manager.ListenerClassVisitorHelper; import java.lang.invoke.MethodHandles; import java.util.Optional; public class EventFilterTest { - + public static final Cause TEST_CAUSE = Cause.of(EventContext.empty(), EventFilterTest.class); private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); - private final AnnotatedEventListener.Factory handlerFactory = new ClassEventListenerFactory(new FilterFactory(LOOKUP), LOOKUP); + private final AnnotatedEventListener.Factory handlerFactory = new ClassEventListenerFactory(FilterGenerator::create); @Test - public void testSimpleEvent() throws Exception { + public void testSimpleEvent() throws Throwable { SimpleListener listener = new SimpleListener(); AnnotatedEventListener annotatedEventListener = this.getListener(listener, "onEvent"); annotatedEventListener.handle(new SubEvent(TEST_CAUSE)); - Assert.assertTrue("Simple listener was not called!", listener.called); + assertTrue(listener.called, "Simple listener was not called!"); } @Test - public void testDoubleListener() throws Exception { + public void testDoubleListener() throws Throwable { DoubleListener listener = new DoubleListener(); - this.getListener(listener, "onEvent", ChangeBlockEvent.Break.class, Player.class, ItemStack.class); + this.getListener(listener, "onEvent", InteractBlockEvent.Primary.class, Player.class, ItemStack.class); } @Test - public void testCancelledEvent() throws Exception { + public void testCancelledEvent() throws Throwable { CancelledListener listener = new CancelledListener(); SubEvent event = new SubEvent(TEST_CAUSE); @@ -92,31 +84,29 @@ public void testCancelledEvent() throws Exception { AnnotatedEventListener alwaysCalledListener = this.getListener(listener, "alwaysCalledListener"); normalListener.handle(event); - Assert.assertTrue("Un-annotated listener was not called when event was not cancelled!", listener.normalListenerWasCalled); + assertTrue(listener.normalListenerWasCalled, "Un-annotated listener was not called when event was not cancelled!"); alwaysCalledListener.handle(event); - Assert.assertTrue("Listener annotated with @IsCancelled(Tristate.UNDEFINED) was not called when event was not cancelled!", listener.alwaysCalledWasCalled); + assertTrue(listener.alwaysCalledWasCalled, "Listener annotated with @IsCancelled(Tristate.UNDEFINED) was not called when event was not cancelled!"); event.setCancelled(true); listener.normalListenerWasCalled = false; - /* - * normalListener.handle(event); Assert.assertFalse( - * "Un-annotated listener was called when event was cancelled!", listener.normalListenerWasCalled); - */ + normalListener.handle(event); + assertFalse(listener.normalListenerWasCalled, "Un-annotated listener was called when event was cancelled!"); uncalledListener.handle(event); - Assert.assertFalse("Listener annotated with @IsCancelled(Tristate.FALSE) was called!", listener.uncalledWasCalled); + assertFalse(listener.uncalledWasCalled, "Listener annotated with @IsCancelled(Tristate.FALSE) was called!"); afterCancelledListener.handle(event); - Assert.assertTrue("Listener annotated with @IsCancelled was not called!", listener.afterCancelledWasCalled); + assertTrue(listener.afterCancelledWasCalled, "Listener annotated with @IsCancelled was not called!"); alwaysCalledListener.handle(event); - Assert.assertTrue("Listener annotated with @IsCancelled(Tristate.UNDEFINED) was not called!", listener.alwaysCalledWasCalled); + assertTrue(listener.alwaysCalledWasCalled, "Listener annotated with @IsCancelled(Tristate.UNDEFINED) was not called!"); } @Test - public void testIncludeExcludeListener() throws Exception { + public void testIncludeExcludeListener() throws Throwable { IncludeExcludeListener listener = new IncludeExcludeListener(); AnnotatedEventListener includeListener = this.getListener(listener, "includeListener", TestEvent.class); @@ -129,37 +119,38 @@ public void testIncludeExcludeListener() throws Exception { SubEvent subEvent = new SubEvent(TEST_CAUSE); includeListener.handle(testEvent); - Assert.assertFalse("Listener annotated with @Include was called!", listener.includeListenerCalled); + assertFalse(listener.includeListenerCalled, "Listener annotated with @Include was called!"); includeListener.handle(subEvent); - Assert.assertTrue("Listener annotated with @Include was not called!", listener.includeListenerCalled); + assertTrue(listener.includeListenerCalled, "Listener annotated with @Include was not called!"); excludeListener.handle(subEvent); - Assert.assertFalse("Listener annotated with @Exclude was called!", listener.exlcudeListenerCalled); + assertFalse(listener.excludeListenerCalled, "Listener annotated with @Exclude was called!"); excludeListener.handle(testEvent); - Assert.assertTrue("Listener annotated with @Exclude was not called!", listener.exlcudeListenerCalled); + assertTrue(listener.excludeListenerCalled, "Listener annotated with @Exclude was not called!"); multiIncludeListener.handle(testEvent); - Assert.assertFalse("Listener annotated with multi-target @Include was called!", listener.multiIncludeListenerCalled); + assertFalse(listener.multiIncludeListenerCalled, "Listener annotated with multi-target @Include was called!"); multiIncludeListener.handle(subEvent); - Assert.assertTrue("Listener annotated with multi-target @Include was not called!", listener.multiIncludeListenerCalled); + assertTrue(listener.multiIncludeListenerCalled, "Listener annotated with multi-target @Include was not called!"); multiExcludeListener.handle(subEvent); - Assert.assertFalse("Listener annotated with multi-target @Exclude was called!", listener.multiExcludeListenerCalled); + assertFalse(listener.multiExcludeListenerCalled, "Listener annotated with multi-target @Exclude was called!"); multiExcludeListener.handle(testEvent); - Assert.assertTrue("Listener annotated with multi-target @Exclude was not called!", listener.multiExcludeListenerCalled); + assertTrue(listener.multiExcludeListenerCalled, "Listener annotated with multi-target @Exclude was not called!"); } - @Test(expected = RuntimeException.class) - public void testIncludeExcludeListener_InvalidListener() throws Exception { - this.getListener(new InvalidIncludeExcludeListener(), "invalidListener", TestEvent.class); + @Test + public void testIncludeExcludeListener_InvalidListener() { + assertThrows(RuntimeException.class, () -> this.getListener(new InvalidIncludeExcludeListener(), "invalidListener", TestEvent.class)); } + @Disabled @Test - public void testFirstLastCauseListener() throws Exception { + public void testFirstLastCauseListener() throws Throwable { FirstLastCauseListener listener = new FirstLastCauseListener(); AnnotatedEventListener firstCauseListener = this.getListener(listener, "firstCauseListener", SubEvent.class, Player.class); AnnotatedEventListener lastCauseListener = this.getListener(listener, "lastCauseListener", SubEvent.class, Player.class); @@ -175,34 +166,34 @@ public void testFirstLastCauseListener() throws Exception { SubEvent event2 = new SubEvent(cause2); firstCauseListener.handle(event1); - Assert.assertFalse("Listener was called with improper @First parameter!", listener.firstCauseCalled); + assertFalse(listener.firstCauseCalled, "Listener was called with improper @First parameter!"); firstCauseListener.handle(event2); - Assert.assertTrue("Listener with @First parameter was not called when proper Cause was provided!", listener.firstCauseCalled); + assertTrue(listener.firstCauseCalled, "Listener with @First parameter was not called when proper Cause was provided!"); lastCauseListener.handle(event1); - Assert.assertFalse("Listener was called with improper @Last parameter!", listener.lastCauseCalled); + assertFalse(listener.lastCauseCalled, "Listener was called with improper @Last parameter!"); lastCauseListener.handle(event2); - Assert.assertTrue("Listener with @Last parameter was not called when proper Cause was provided!", listener.lastCauseCalled); + assertTrue(listener.lastCauseCalled, "Listener with @Last parameter was not called when proper Cause was provided!"); firstCauseListenerInc.handle(event2); - Assert.assertTrue("Listener with @First with inclusions was not called when proper Cause was provided!", listener.firstCauseCalledInc); + assertTrue(listener.firstCauseCalledInc, "Listener with @First with inclusions was not called when proper Cause was provided!"); firstCauseListenerEx.handle(event2); - Assert.assertFalse("Listener with @First with exclusions was called when an improper Cause was provided!", listener.firstCauseCalledEx); + assertFalse(listener.firstCauseCalledEx, "Listener with @First with exclusions was called when an improper Cause was provided!"); lastCauseListenerInc.handle(event2); - Assert.assertTrue("Listener with @Last with inclusions was not called when proper Cause was provided!", listener.lastCauseCalledInc); + assertTrue(listener.lastCauseCalledInc, "Listener with @Last with inclusions was not called when proper Cause was provided!"); lastCauseListenerEx.handle(event2); - Assert.assertFalse("Listener with @Last with exclusions was called when an improper Cause was provided!", listener.lastCauseCalledEx); + assertFalse(listener.lastCauseCalledEx, "Listener with @Last with exclusions was called when an improper Cause was provided!"); } @Test - public void testAllCauseListener() throws Exception { + public void testAllCauseListener() throws Throwable { AllCauseListener listener = new AllCauseListener(); - AnnotatedEventListener emptyListener = this.getListener(listener, "emptyListener", SubEvent.class, BiomeTypes[].class); + AnnotatedEventListener emptyListener = this.getListener(listener, "emptyListener", SubEvent.class, Component[].class); AnnotatedEventListener allCauseListener = this.getListener(listener, "allCauseListener", SubEvent.class, Player[].class); Cause cause1 = TEST_CAUSE; @@ -212,31 +203,31 @@ public void testAllCauseListener() throws Exception { SubEvent event2 = new SubEvent(cause2); emptyListener.handle(event1); - Assert.assertTrue("Listener with @All(ignoreEmpty = false) was not called!", listener.emptyListenerCalled); + assertTrue(listener.emptyListenerCalled, "Listener with @All(ignoreEmpty = false) was not called!"); listener.emptyListenerCalled = false; emptyListener.handle(event2); - Assert.assertTrue("Listener with @All(ignoreEmpty = false) was not called!", listener.emptyListenerCalled); + assertTrue(listener.emptyListenerCalled, "Listener with @All(ignoreEmpty = false) was not called!"); allCauseListener.handle(event1); - Assert.assertFalse("Listener with @All was called with improper array parameter!", listener.allCauseListenerCalled); + assertFalse(listener.allCauseListenerCalled, "Listener with @All was called with improper array parameter!"); allCauseListener.handle(event2); - Assert.assertTrue("Listener with @All was not called when proper Cause was provided!", listener.allCauseListenerCalled); + assertTrue(listener.allCauseListenerCalled, "Listener with @All was not called when proper Cause was provided!"); } @Test - public void testDataSupportsListener() throws Exception { + public void testDataSupportsListener() throws Throwable { DataSupportsListener listener = new DataSupportsListener(); - AnnotatedEventListener supportsSkinListener = this.getListener(listener, "supportsSkinListener", SubEvent.class, Player.class); - AnnotatedEventListener inverseSupportsSkinListener = this.getListener(listener, "inverseSupportsSkinListener", SubEvent.class, Player.class); + AnnotatedEventListener supportsDisplayNameListener = this.getListener(listener, "supportsDisplayNameListener", SubEvent.class, Player.class); + AnnotatedEventListener inverseSupportsDisplayNameListener = this.getListener(listener, "inverseSupportsDisplayNameListener", SubEvent.class, Player.class); Player player1 = mock(Player.class); - when(player1.supports(SkinData.class)).thenReturn(false); + when(player1.supports(Keys.DISPLAY_NAME)).thenReturn(false); Player player2 = mock(Player.class); - when(player2.supports(SkinData.class)).thenReturn(true); + when(player2.supports(Keys.DISPLAY_NAME)).thenReturn(true); Cause cause1 = Cause.of(EventContext.empty(), player1); Cause cause2 = Cause.of(EventContext.empty(), player2); @@ -244,30 +235,30 @@ public void testDataSupportsListener() throws Exception { SubEvent event1 = new SubEvent(cause1); SubEvent event2 = new SubEvent(cause2); - supportsSkinListener.handle(event1); - Assert.assertFalse("Listener with @Supports was called!", listener.supportsSkinListenerCalled); + supportsDisplayNameListener.handle(event1); + assertFalse(listener.supportsDisplayNameListenerCalled, "Listener with @Supports was called!"); - supportsSkinListener.handle(event2); - Assert.assertTrue("Listener with @Supports was not called!", listener.supportsSkinListenerCalled); + supportsDisplayNameListener.handle(event2); + assertTrue(listener.supportsDisplayNameListenerCalled, "Listener with @Supports was not called!"); - inverseSupportsSkinListener.handle(event2); - Assert.assertFalse("Inverse listener with @Supports was called!", listener.inverseSupportsSkinListenerCalled); + inverseSupportsDisplayNameListener.handle(event2); + assertFalse(listener.inverseSupportsDisplayNameListenerCalled, "Inverse listener with @Supports was called!"); - inverseSupportsSkinListener.handle(event1); - Assert.assertTrue("Inverse listener with @Supports was not called!", listener.inverseSupportsSkinListenerCalled); + inverseSupportsDisplayNameListener.handle(event1); + assertTrue(listener.inverseSupportsDisplayNameListenerCalled, "Inverse listener with @Supports was not called!"); } @Test - public void testDataHasListener() throws Exception { + public void testDataHasListener() throws Throwable { DataHasListener listener = new DataHasListener(); - AnnotatedEventListener hasSkinListener = this.getListener(listener, "hasSkinListener", SubEvent.class, Player.class); - AnnotatedEventListener inversehasSkinListener = this.getListener(listener, "inverseHasSkinListener", SubEvent.class, Player.class); + AnnotatedEventListener hasDisplayNameListener = this.getListener(listener, "hasDisplayNameListener", SubEvent.class, Player.class); + AnnotatedEventListener inverseHasDisplayNameListener = this.getListener(listener, "inverseHasDisplayNameListener", SubEvent.class, Player.class); Player player1 = mock(Player.class); - when(player1.get(SkinData.class)).thenReturn(Optional.empty()); + when(player1.get(Keys.DISPLAY_NAME)).thenReturn(Optional.empty()); Player player2 = mock(Player.class); - when(player2.get(SkinData.class)).thenReturn(Optional.of(mock(SkinData.class))); + when(player2.get(Keys.DISPLAY_NAME)).thenReturn(Optional.of(Component.text("name"))); Cause cause1 = Cause.of(EventContext.empty(), player1); Cause cause2 = Cause.of(EventContext.empty(), player2); @@ -275,21 +266,22 @@ public void testDataHasListener() throws Exception { SubEvent event1 = new SubEvent(cause1); SubEvent event2 = new SubEvent(cause2); - hasSkinListener.handle(event1); - Assert.assertFalse("Listener with @Has was called!", listener.hasSkinListenerCalled); + hasDisplayNameListener.handle(event1); + assertFalse(listener.hasDisplayNameListenerCalled, "Listener with @Has was called!"); - hasSkinListener.handle(event2); - Assert.assertTrue("Listener with @Has was not called!", listener.hasSkinListenerCalled); + hasDisplayNameListener.handle(event2); + assertTrue(listener.hasDisplayNameListenerCalled, "Listener with @Has was not called!"); - inversehasSkinListener.handle(event2); - Assert.assertFalse("Inverse listener with @Has was called!", listener.inverseHasSkinListenerCalled); + inverseHasDisplayNameListener.handle(event2); + assertFalse(listener.inverseDisplayNameListenerCalled, "Inverse listener with @Has was called!"); - inversehasSkinListener.handle(event1); - Assert.assertTrue("Inverse listener with @Has was not called!", listener.inverseHasSkinListenerCalled); + inverseHasDisplayNameListener.handle(event1); + assertTrue(listener.inverseDisplayNameListenerCalled, "Inverse listener with @Has was not called!"); } + @Disabled @Test - public void testRootListener() throws Exception { + public void testRootListener() throws Throwable { RootListener listener = new RootListener(); AnnotatedEventListener rootListener = this.getListener(listener, "rootListener", SubEvent.class, Player.class); AnnotatedEventListener rootListenerInc = this.getListener(listener, "rootListenerInclude", SubEvent.class, Object.class); @@ -302,26 +294,27 @@ public void testRootListener() throws Exception { SubEvent event2 = new SubEvent(cause2); rootListener.handle(event1); - Assert.assertFalse("Listener with @Root was called with improper parameter!", listener.rootListenerCalled); + assertFalse(listener.rootListenerCalled, "Listener with @Root was called with improper parameter!"); rootListener.handle(event2); - Assert.assertTrue("Listener with @Root was not called when proper Cause was provided!", listener.rootListenerCalled); + assertTrue(listener.rootListenerCalled, "Listener with @Root was not called when proper Cause was provided!"); rootListenerInc.handle(event1); - Assert.assertFalse("Listener with @Root with include was called with improper parameter!", listener.rootListenerCalledInc); + assertFalse(listener.rootListenerCalledInc, "Listener with @Root with include was called with improper parameter!"); rootListenerInc.handle(event2); - Assert.assertTrue("Listener with @Root with include was not called when proper Cause was provided!", listener.rootListenerCalledInc); + assertTrue(listener.rootListenerCalledInc, "Listener with @Root with include was not called when proper Cause was provided!"); rootListenerEx.handle(event2); - Assert.assertFalse("Listener with @Root with exclude was called with improper parameter!", listener.rootListenerCalledEx); + assertFalse(listener.rootListenerCalledEx, "Listener with @Root with exclude was called with improper parameter!"); rootListenerEx.handle(event1); - Assert.assertTrue("Listener with @Root with exclude was not called when proper Cause was provided!", listener.rootListenerCalledEx); + assertTrue(listener.rootListenerCalledEx, "Listener with @Root with exclude was not called when proper Cause was provided!"); } + @Disabled @Test - public void testBeforeCauseListener() throws Exception { + public void testBeforeCauseListener() throws Throwable { BeforeAfterCauseListener listener = new BeforeAfterCauseListener(); AnnotatedEventListener beforeCauseListener = this.getListener(listener, "beforeCauseListener", SubEvent.class, Player.class); AnnotatedEventListener afterCauseListener = this.getListener(listener, "afterCauseListener", SubEvent.class, Entity.class); @@ -330,73 +323,75 @@ public void testBeforeCauseListener() throws Exception { AnnotatedEventListener afterCauseListenerInc = this.getListener(listener, "afterCauseListenerInclude", SubEvent.class, Entity.class); AnnotatedEventListener afterCauseListenerEx = this.getListener(listener, "afterCauseListenerExclude", SubEvent.class, Entity.class); - Cause cause1 = Cause.of(EventContext.empty(), "Foo", mock(Player.class), mock(Extent.class)); + Cause cause1 = Cause.of(EventContext.empty(), "Foo", mock(Player.class), mock(World.class)); Cause cause2 = Cause.of(EventContext.empty(), "Me", mock(BlockState.class), mock(Entity.class)); SubEvent event1 = new SubEvent(cause1); SubEvent event2 = new SubEvent(cause2); beforeCauseListener.handle(event2); - Assert.assertFalse("Listener with @Before was called with improper parameter!", listener.beforeCauseCalled); + assertFalse(listener.beforeCauseCalled, "Listener with @Before was called with improper parameter!"); beforeCauseListener.handle(event1); - Assert.assertTrue("Listener with @Before was not called when proper Cause was provided!", listener.beforeCauseCalled); + assertTrue(listener.beforeCauseCalled, "Listener with @Before was not called when proper Cause was provided!"); afterCauseListener.handle(event1); - Assert.assertFalse("Listener with @After was called with improper parameter!", listener.afterCauseCalled); + assertFalse(listener.afterCauseCalled, "Listener with @After was called with improper parameter!"); afterCauseListener.handle(event2); - Assert.assertTrue("Listener with @After was not called when proper Cause was provided!", listener.afterCauseCalled); + assertTrue(listener.afterCauseCalled, "Listener with @After was not called when proper Cause was provided!"); beforeCauseListenerInc.handle(event1); - Assert.assertTrue("Listener with @Before with inclusions was not called when proper Cause was provided!", listener.beforeCauseCalledInc); + assertTrue(listener.beforeCauseCalledInc, "Listener with @Before with inclusions was not called when proper Cause was provided!"); beforeCauseListenerEx.handle(event1); - Assert.assertFalse("Listener with @Before with exclusions was called when an improper Cause was provided!", listener.beforeCauseCalledEx); + assertFalse(listener.beforeCauseCalledEx, "Listener with @Before with exclusions was called when an improper Cause was provided!"); afterCauseListenerInc.handle(event2); - Assert.assertFalse("Listener with @After with inclusions was called when an improper Cause was provided!", listener.afterCauseCalledInc); + assertFalse(listener.afterCauseCalledInc, "Listener with @After with inclusions was called when an improper Cause was provided!"); afterCauseListenerEx.handle(event2); - Assert.assertTrue("Listener with @After with exclusions was not called when proper Cause was provided!", listener.afterCauseCalledEx); + assertTrue(listener.afterCauseCalledEx, "Listener with @After with exclusions was not called when proper Cause was provided!"); } @Test - public void testGetter() throws Exception { + public void testGetter() throws Throwable { GetterListener listener = new GetterListener(); AnnotatedEventListener normalListener = this.getListener(listener, "normalListener", GetterEvent.class, TestObject.class); AnnotatedEventListener subClassListener = this.getListener(listener, "subClassListener", GetterEvent.class, SubObject.class); - Cause cause = Cause.of(EventContext.empty(), Text.of()); + Cause cause = Cause.of(EventContext.empty(), Component.text()); GetterEvent normalEvent = new GetterEvent(cause, new TestObject()); GetterEvent subClassEvent = new GetterEvent(cause, new SubObject()); normalListener.handle(normalEvent); - Assert.assertTrue("Listener with @Getter was not called when the targeted getter returned the same type!", listener.normalCalled); + assertTrue(listener.normalCalled, "Listener with @Getter was not called when the targeted getter returned the same type!"); listener.normalCalled = false; normalListener.handle(subClassEvent); - Assert.assertTrue("Listener with @Getter was not called when the targeted getter returned a subtype of the expected type!", listener.normalCalled); + assertTrue(listener.normalCalled, "Listener with @Getter was not called when the targeted getter returned a subtype of the expected type!"); subClassListener.handle(normalEvent); - Assert.assertFalse("Listener with @Getter was called when the targeted getter returned a supertype! How is this even possible???", listener.subClassCalled); + assertFalse(listener.subClassCalled, + "Listener with @Getter was called when the targeted getter returned a supertype! How is this even possible???"); listener.subClassCalled = false; subClassListener.handle(subClassEvent); - Assert.assertTrue("Listener with @Getter was not called when the targeted getter returned a subtype of the expected type, which matched the parameter type!", listener.normalCalled); + assertTrue(listener.normalCalled, + "Listener with @Getter was not called when the targeted getter returned a subtype of the expected type, which matched the parameter type!"); } @Test - public void testCovariantGetter() throws Exception { + public void testCovariantGetter() throws Throwable { CovariantGetterListener listener = new CovariantGetterListener(); AnnotatedEventListener covariantListener = this.getListener(listener, "covariantListener", CovariantEvent.OverloadedEvent.class, SubObject.class); - covariantListener.handle(new CovariantEvent.OverloadedEvent(Cause.of(EventContext.empty(), Text.of()), new SubObject())); - Assert.assertTrue("Listener with @Getter targeting a method with a covariant return type was not called!", listener.covariantListenerCalled); + covariantListener.handle(new CovariantEvent.OverloadedEvent(Cause.of(EventContext.empty(), Component.text()), new SubObject())); + assertTrue(listener.covariantListenerCalled, "Listener with @Getter targeting a method with a covariant return type was not called!"); } @@ -410,7 +405,7 @@ public TestEvent(Cause cause) { } @Override - public Cause getCause() { + public Cause cause() { return this.cause; } @@ -473,7 +468,7 @@ public CovariantEvent(Cause cause, TestObject testObject) { } @Override - public Cause getCause() { + public Cause cause() { return this.cause; } @@ -494,11 +489,11 @@ public SubObject getTestObject() { } } - private AnnotatedEventListener getListener(Object listener, String method) throws Exception { + private AnnotatedEventListener getListener(Object listener, String method) throws Throwable { return this.getListener(listener, method, SubEvent.class); } - private AnnotatedEventListener getListener(Object listener, String method, Class... classes) throws Exception { - return this.handlerFactory.create(listener, listener.getClass().getMethod(method, classes)); + private AnnotatedEventListener getListener(Object listener, String methodName, Class... parameterTypes) throws Throwable { + return this.handlerFactory.create(listener, ListenerClassVisitorHelper.getMethod(listener.getClass(), methodName, parameterTypes), LOOKUP); } } diff --git a/src/test/java/org/spongepowered/common/event/ShouldFireTest.java b/src/test/java/org/spongepowered/common/event/ShouldFireTest.java new file mode 100644 index 00000000000..0e2053f629b --- /dev/null +++ b/src/test/java/org/spongepowered/common/event/ShouldFireTest.java @@ -0,0 +1,123 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.event; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.event.EventManager; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.entity.SpawnEntityEvent; +import org.spongepowered.plugin.PluginContainer; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public class ShouldFireTest { + + @BeforeEach + public void resetShouldFireFields() throws IllegalAccessException { + for (Field field : ShouldFire.class.getDeclaredFields()) { + if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { + field.set(null, false); + } + } + } + + @Test + public void testSpawn() { + final EventManager eventManager = Sponge.eventManager(); + final PluginContainer plugin = Mockito.mock(PluginContainer.class); + + final SpawnListener listener = new SpawnListener(); + + assertFalse(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not false!"); + assertFalse(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not false!"); + + eventManager.registerListeners(plugin, listener); + + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not true!"); + assertTrue(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE it not true!"); + + eventManager.unregisterListeners(listener); + + assertFalse(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not false!"); + assertFalse(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not false!"); + } + + @Test + public void testMultipleListeners() { + final EventManager eventManager = Sponge.eventManager(); + final PluginContainer plugin = Mockito.mock(PluginContainer.class); + + SpawnListener spawnListener = new SpawnListener(); + SpawnCustomListener spawnCustomListener = new SpawnCustomListener(); + + assertFalse(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not false!"); + assertFalse(ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM, "SPAWN_ENTITY_EVENT_CUSTOM is not false!"); + assertFalse(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not false!"); + + eventManager.registerListeners(plugin, spawnCustomListener); + + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not true!"); + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM, "SPAWN_ENTITY_EVENT_CUSTOM is not true!"); + assertFalse(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not false!"); + + eventManager.registerListeners(plugin, spawnListener); + + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not true!"); + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM, "SPAWN_ENTITY_EVENT_CUSTOM is not true!"); + assertTrue(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not true!"); + + eventManager.unregisterListeners(spawnCustomListener); + + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not true!"); + assertTrue(ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM, "SPAWN_ENTITY_EVENT_CUSTOM is not true!"); + assertTrue(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not true!"); + + eventManager.unregisterListeners(spawnListener); + + assertFalse(ShouldFire.SPAWN_ENTITY_EVENT, "SPAWN_ENTITY_EVENT is not false!"); + assertFalse(ShouldFire.SPAWN_ENTITY_EVENT_CUSTOM, "SPAWN_ENTITY_EVENT_CUSTOM is not false!"); + assertFalse(ShouldFire.DROP_ITEM_EVENT_DISPENSE, "DROP_ITEM_EVENT_DISPENSE is not false!"); + } + + private static class SpawnListener { + + @Listener + public void onSpawn(SpawnEntityEvent event) {} + } + + private static class SpawnCustomListener { + + @Listener + public void onCustom(SpawnEntityEvent.Custom event) {} + } + +} diff --git a/src/test/java/org/spongepowered/common/event/SnapshotGenerationTest.java b/src/test/java/org/spongepowered/common/event/SnapshotGenerationTest.java new file mode 100644 index 00000000000..8f292b75155 --- /dev/null +++ b/src/test/java/org/spongepowered/common/event/SnapshotGenerationTest.java @@ -0,0 +1,83 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.event; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.*; + +import com.google.common.collect.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.event.*; +import org.spongepowered.api.event.cause.entity.SpawnTypes; +import org.spongepowered.api.event.entity.SpawnEntityEvent; +import org.spongepowered.common.event.listener.NonPreListener; +import org.spongepowered.common.event.listener.PreListener; +import org.spongepowered.plugin.PluginContainer; + +public class SnapshotGenerationTest { + private Entity entity; + private SpawnEntityEvent event; + + @BeforeEach + public void prepare() { + this.entity = Mockito.mock(Entity.class, withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)); + final Cause cause = Cause.of(EventContext.builder().add(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLUGIN.get()).build(), this); + this.event = SpongeEventFactory.createSpawnEntityEvent(cause, Lists.newArrayList(this.entity)); + } + + @Test + public void testPreListener() { + final EventManager eventManager = Sponge.game().eventManager(); + final PluginContainer plugin = mock(PluginContainer.class); + final Object[] listeners = {new PreListener(), new NonPreListener()}; + + for (Object listener : listeners) { + eventManager.registerListeners(plugin, listener); + } + + eventManager.post(this.event); + + verify(this.entity).createSnapshot(); + this.event.entitySnapshots(); + + // Cleanup registered listeners to not interfere with other tests + for (Object listener : listeners) { + eventManager.unregisterListeners(listener); + } + } + + @Test + public void testNonPreListener() { + final EventManager eventManager = Sponge.game().eventManager(); + eventManager.post(this.event); + + assertThrows(IllegalStateException.class, () -> this.event.entitySnapshots()); + } + +} diff --git a/src/test/invalid/common/event/listener/AllCauseListener.java b/src/test/java/org/spongepowered/common/event/listener/AllCauseListener.java similarity index 94% rename from src/test/invalid/common/event/listener/AllCauseListener.java rename to src/test/java/org/spongepowered/common/event/listener/AllCauseListener.java index 448058cfb7a..91915bc195c 100644 --- a/src/test/invalid/common/event/listener/AllCauseListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/AllCauseListener.java @@ -24,10 +24,10 @@ */ package org.spongepowered.common.event.listener; +import net.kyori.adventure.text.Component; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.filter.cause.All; -import org.spongepowered.api.world.biome.BiomeTypes; import org.spongepowered.common.event.EventFilterTest; public class AllCauseListener { @@ -36,7 +36,7 @@ public class AllCauseListener { public boolean allCauseListenerCalled; @Listener - public void emptyListener(EventFilterTest.SubEvent event, @All(ignoreEmpty = false) BiomeTypes[] players) { + public void emptyListener(EventFilterTest.SubEvent event, @All(ignoreEmpty = false) Component[] components) { this.emptyListenerCalled = true; } diff --git a/src/test/invalid/common/event/listener/BeforeAfterCauseListener.java b/src/test/java/org/spongepowered/common/event/listener/BeforeAfterCauseListener.java similarity index 91% rename from src/test/invalid/common/event/listener/BeforeAfterCauseListener.java rename to src/test/java/org/spongepowered/common/event/listener/BeforeAfterCauseListener.java index a2e81afb4ba..9adcc5c7a76 100644 --- a/src/test/invalid/common/event/listener/BeforeAfterCauseListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/BeforeAfterCauseListener.java @@ -30,7 +30,7 @@ import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.filter.cause.After; import org.spongepowered.api.event.filter.cause.Before; -import org.spongepowered.api.world.extent.Extent; +import org.spongepowered.api.world.World; import org.spongepowered.common.event.EventFilterTest; public class BeforeAfterCauseListener { @@ -44,7 +44,7 @@ public class BeforeAfterCauseListener { public boolean afterCauseCalledEx; @Listener - public void beforeCauseListener(EventFilterTest.SubEvent event, @Before(Extent.class) Player player) { + public void beforeCauseListener(EventFilterTest.SubEvent event, @Before(World.class) Player player) { this.beforeCauseCalled = true; } @@ -54,12 +54,12 @@ public void afterCauseListener(EventFilterTest.SubEvent event, @After(BlockState } @Listener - public void beforeCauseListenerInclude(EventFilterTest.SubEvent event, @Before(value = Extent.class, typeFilter = Player.class) Player player) { + public void beforeCauseListenerInclude(EventFilterTest.SubEvent event, @Before(value = World.class, typeFilter = Player.class) Player player) { this.beforeCauseCalledInc = true; } @Listener - public void beforeCauseListenerExclude(EventFilterTest.SubEvent event, @Before(value = Extent.class, typeFilter = Player.class, inverse = true) Player player) { + public void beforeCauseListenerExclude(EventFilterTest.SubEvent event, @Before(value = World.class, typeFilter = Player.class, inverse = true) Player player) { this.beforeCauseCalledEx = true; } diff --git a/src/test/invalid/common/event/listener/CancelledListener.java b/src/test/java/org/spongepowered/common/event/listener/CancelledListener.java similarity index 100% rename from src/test/invalid/common/event/listener/CancelledListener.java rename to src/test/java/org/spongepowered/common/event/listener/CancelledListener.java diff --git a/src/test/invalid/common/event/listener/CovariantGetterListener.java b/src/test/java/org/spongepowered/common/event/listener/CovariantGetterListener.java similarity index 100% rename from src/test/invalid/common/event/listener/CovariantGetterListener.java rename to src/test/java/org/spongepowered/common/event/listener/CovariantGetterListener.java diff --git a/src/test/invalid/common/event/listener/DataHasListener.java b/src/test/java/org/spongepowered/common/event/listener/DataHasListener.java similarity index 76% rename from src/test/invalid/common/event/listener/DataHasListener.java rename to src/test/java/org/spongepowered/common/event/listener/DataHasListener.java index 58ead5e800c..0e1ad09dd6b 100644 --- a/src/test/invalid/common/event/listener/DataHasListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/DataHasListener.java @@ -24,7 +24,6 @@ */ package org.spongepowered.common.event.listener; -import org.spongepowered.api.data.manipulator.mutable.entity.SkinData; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.filter.cause.First; @@ -33,17 +32,17 @@ public class DataHasListener { - public boolean hasSkinListenerCalled; - public boolean inverseHasSkinListenerCalled; + public boolean hasDisplayNameListenerCalled; + public boolean inverseDisplayNameListenerCalled; @Listener - public void hasSkinListener(EventFilterTest.SubEvent event, @First @Has(SkinData.class) Player player) { - this.hasSkinListenerCalled = true; + public void hasDisplayNameListener(EventFilterTest.SubEvent event, @First @Has("DISPLAY_NAME") Player player) { + this.hasDisplayNameListenerCalled = true; } @Listener - public void inverseHasSkinListener(EventFilterTest.SubEvent event, @First @Has(value = SkinData.class, inverse = true) Player player) { - this.inverseHasSkinListenerCalled = true; + public void inverseHasDisplayNameListener(EventFilterTest.SubEvent event, @First @Has(value = "DISPLAY_NAME", inverse = true) Player player) { + this.inverseDisplayNameListenerCalled = true; } } diff --git a/src/test/invalid/common/event/listener/DataSupportsListener.java b/src/test/java/org/spongepowered/common/event/listener/DataSupportsListener.java similarity index 75% rename from src/test/invalid/common/event/listener/DataSupportsListener.java rename to src/test/java/org/spongepowered/common/event/listener/DataSupportsListener.java index dd8acb703be..1efc509760b 100644 --- a/src/test/invalid/common/event/listener/DataSupportsListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/DataSupportsListener.java @@ -24,7 +24,6 @@ */ package org.spongepowered.common.event.listener; -import org.spongepowered.api.data.manipulator.mutable.entity.SkinData; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.filter.cause.First; @@ -33,16 +32,16 @@ public class DataSupportsListener { - public boolean supportsSkinListenerCalled; - public boolean inverseSupportsSkinListenerCalled; + public boolean supportsDisplayNameListenerCalled; + public boolean inverseSupportsDisplayNameListenerCalled; @Listener - public void supportsSkinListener(EventFilterTest.SubEvent event, @First @Supports(SkinData.class) Player player) { - this.supportsSkinListenerCalled = true; + public void supportsDisplayNameListener(EventFilterTest.SubEvent event, @First @Supports("DISPLAY_NAME") Player player) { + this.supportsDisplayNameListenerCalled = true; } @Listener - public void inverseSupportsSkinListener(EventFilterTest.SubEvent event, @First @Supports(value = SkinData.class, inverse = true) Player player) { - this.inverseSupportsSkinListenerCalled = true; + public void inverseSupportsDisplayNameListener(EventFilterTest.SubEvent event, @First @Supports(value = "DISPLAY_NAME", inverse = true) Player player) { + this.inverseSupportsDisplayNameListenerCalled = true; } } diff --git a/src/test/invalid/common/event/listener/DoubleListener.java b/src/test/java/org/spongepowered/common/event/listener/DoubleListener.java similarity index 90% rename from src/test/invalid/common/event/listener/DoubleListener.java rename to src/test/java/org/spongepowered/common/event/listener/DoubleListener.java index f174b75963d..8ca6114fc0c 100644 --- a/src/test/invalid/common/event/listener/DoubleListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/DoubleListener.java @@ -26,14 +26,14 @@ import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.block.ChangeBlockEvent; +import org.spongepowered.api.event.block.InteractBlockEvent; import org.spongepowered.api.event.filter.cause.First; import org.spongepowered.api.item.inventory.ItemStack; public class DoubleListener { @Listener - public void onEvent(ChangeBlockEvent.Break e, @First Player p, @First ItemStack stack) { + public void onEvent(InteractBlockEvent.Primary e, @First Player p, @First ItemStack stack) { e.getClass(); } diff --git a/src/test/invalid/common/event/listener/FirstLastCauseListener.java b/src/test/java/org/spongepowered/common/event/listener/FirstLastCauseListener.java similarity index 100% rename from src/test/invalid/common/event/listener/FirstLastCauseListener.java rename to src/test/java/org/spongepowered/common/event/listener/FirstLastCauseListener.java diff --git a/src/test/invalid/common/event/listener/GetterListener.java b/src/test/java/org/spongepowered/common/event/listener/GetterListener.java similarity index 100% rename from src/test/invalid/common/event/listener/GetterListener.java rename to src/test/java/org/spongepowered/common/event/listener/GetterListener.java diff --git a/src/test/invalid/common/event/listener/IncludeExcludeListener.java b/src/test/java/org/spongepowered/common/event/listener/IncludeExcludeListener.java similarity index 96% rename from src/test/invalid/common/event/listener/IncludeExcludeListener.java rename to src/test/java/org/spongepowered/common/event/listener/IncludeExcludeListener.java index 589fb1bb4fc..535708dcb44 100644 --- a/src/test/invalid/common/event/listener/IncludeExcludeListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/IncludeExcludeListener.java @@ -34,7 +34,7 @@ public class IncludeExcludeListener { public boolean includeListenerCalled; public boolean multiIncludeListenerCalled; - public boolean exlcudeListenerCalled; + public boolean excludeListenerCalled; public boolean multiExcludeListenerCalled; @Listener @@ -52,7 +52,7 @@ public void multiIncludeListener(EventFilterTest.TestEvent event) { @Listener @Exclude(EventFilterTest.SubEvent.class) public void excludeListener(EventFilterTest.TestEvent event) { - this.exlcudeListenerCalled = true; + this.excludeListenerCalled = true; } @Listener diff --git a/src/test/invalid/common/event/listener/InvalidIncludeExcludeListener.java b/src/test/java/org/spongepowered/common/event/listener/InvalidIncludeExcludeListener.java similarity index 100% rename from src/test/invalid/common/event/listener/InvalidIncludeExcludeListener.java rename to src/test/java/org/spongepowered/common/event/listener/InvalidIncludeExcludeListener.java diff --git a/src/test/invalid/common/event/listener/NonPreListener.java b/src/test/java/org/spongepowered/common/event/listener/NonPreListener.java similarity index 97% rename from src/test/invalid/common/event/listener/NonPreListener.java rename to src/test/java/org/spongepowered/common/event/listener/NonPreListener.java index 92428a233f4..610a3b43c14 100644 --- a/src/test/invalid/common/event/listener/NonPreListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/NonPreListener.java @@ -31,7 +31,7 @@ public class NonPreListener { @Listener public void onSpawnEntity(SpawnEntityEvent event) { - event.getEntitySnapshots(); + event.entitySnapshots(); } } diff --git a/src/test/invalid/common/event/PreListener.java b/src/test/java/org/spongepowered/common/event/listener/PreListener.java similarity index 94% rename from src/test/invalid/common/event/PreListener.java rename to src/test/java/org/spongepowered/common/event/listener/PreListener.java index c04126e5945..6b10e7aead5 100644 --- a/src/test/invalid/common/event/PreListener.java +++ b/src/test/java/org/spongepowered/common/event/listener/PreListener.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.event; +package org.spongepowered.common.event.listener; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; @@ -32,7 +32,7 @@ public class PreListener { @Listener(order = Order.PRE) public void onSpawn(SpawnEntityEvent event) { - event.getEntitySnapshots(); + event.entitySnapshots(); } } diff --git a/src/test/invalid/common/event/listener/RootListener.java b/src/test/java/org/spongepowered/common/event/listener/RootListener.java similarity index 100% rename from src/test/invalid/common/event/listener/RootListener.java rename to src/test/java/org/spongepowered/common/event/listener/RootListener.java diff --git a/src/test/invalid/common/event/listener/SimpleListener.java b/src/test/java/org/spongepowered/common/event/listener/SimpleListener.java similarity index 100% rename from src/test/invalid/common/event/listener/SimpleListener.java rename to src/test/java/org/spongepowered/common/event/listener/SimpleListener.java diff --git a/src/test/invalid/common/InjectedTest.java b/src/test/java/org/spongepowered/common/event/manager/ListenerClassVisitorHelper.java similarity index 57% rename from src/test/invalid/common/InjectedTest.java rename to src/test/java/org/spongepowered/common/event/manager/ListenerClassVisitorHelper.java index f12c3863626..dda50291de5 100644 --- a/src/test/invalid/common/InjectedTest.java +++ b/src/test/java/org/spongepowered/common/event/manager/ListenerClassVisitorHelper.java @@ -22,32 +22,28 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common; +package org.spongepowered.common.event.manager; -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Inject; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.junit.Before; +import org.objectweb.asm.Type; -public class InjectedTest { +import java.io.IOException; +import java.util.Arrays; - @Inject protected Logger logger; +public class ListenerClassVisitorHelper { - @Before - public void before() { - Guice.createInjector(new TestModule()); - } - - public class TestModule extends AbstractModule { + public static ListenerClassVisitor.DiscoveredMethod getMethod(Class clazz, String name, Class... parameterTypes) + throws IOException, NoSuchMethodException { + final Object[] expectedParameterTypeNames = Arrays.stream(parameterTypes).map(Type::getInternalName).toArray(); - @Override - protected void configure() { - this.bind(org.slf4j.Logger.class).toInstance(org.slf4j.LoggerFactory.getLogger("sponge")); - this.bind(Logger.class).toInstance(LogManager.getLogger("sponge")); - - this.requestInjection(InjectedTest.this); + for (ListenerClassVisitor.DiscoveredMethod m : ListenerClassVisitor.getEventListenerMethods(clazz)) { + if (m.methodName().equals(name)) { + final Object[] parameterTypeNames = Arrays.stream(m.parameterTypes()).map(p -> p.type().getInternalName()).toArray(); + if (Arrays.equals(parameterTypeNames, expectedParameterTypeNames)) { + return m; + } + } } + + throw new NoSuchMethodException(name); } } diff --git a/src/test/java/org/spongepowered/common/event/tracking/PhaseTrackerTest.java b/src/test/java/org/spongepowered/common/event/tracking/PhaseTrackerTest.java new file mode 100644 index 00000000000..1555dfc1cdb --- /dev/null +++ b/src/test/java/org/spongepowered/common/event/tracking/PhaseTrackerTest.java @@ -0,0 +1,87 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.event.tracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; +import org.spongepowered.api.event.CauseStackManager; +import org.spongepowered.api.event.EventContextKeys; + +public class PhaseTrackerTest { + + @Test + public void testPoppingFramePopsCauses() { + final PhaseTracker phaseTracker = PhaseTracker.getInstance(); + + // We start by pushing a frame... + CauseStackManager.StackFrame frame1 = phaseTracker.pushCauseFrame(); + phaseTracker.pushCause(1); + phaseTracker.pushCause(2); + + // Then we push another frame + CauseStackManager.StackFrame frame = phaseTracker.pushCauseFrame(); + phaseTracker.pushCause(3); + + assertEquals(3, phaseTracker.currentCause().root()); + assertEquals(3, phaseTracker.currentCause().all().size()); + + // Now pop the frame + phaseTracker.popCauseFrame(frame); + assertEquals(2, phaseTracker.currentCause().root()); + assertEquals(2, phaseTracker.currentCause().all().size()); + + // Remove for next tests. + phaseTracker.popCauseFrame(frame1); + } + + @Test + public void testPoppingFrameRemovesFrameContexts() { + final PhaseTracker phaseTracker = PhaseTracker.getInstance(); + + String cmd1 = "one"; + String cmd2 = "two"; + + // We start by pushing a frame... + CauseStackManager.StackFrame frame1 = phaseTracker.pushCauseFrame(); + phaseTracker.pushCause(1); + phaseTracker.addContext(EventContextKeys.COMMAND, cmd1); + + // Then we push another frame + CauseStackManager.StackFrame frame = phaseTracker.pushCauseFrame(); + phaseTracker.addContext(EventContextKeys.COMMAND, cmd2); + + assertEquals(cmd2, phaseTracker.context(EventContextKeys.COMMAND).get()); + + // Now pop the frame + phaseTracker.popCauseFrame(frame); + assertEquals(cmd1, phaseTracker.context(EventContextKeys.COMMAND).get()); + + phaseTracker.popCauseFrame(frame1); + assertFalse(phaseTracker.context(EventContextKeys.COMMAND).isPresent()); + } + +} diff --git a/src/test/invalid/common/MixinTest.java b/src/test/java/org/spongepowered/common/mixin/MixinTest.java similarity index 88% rename from src/test/invalid/common/MixinTest.java rename to src/test/java/org/spongepowered/common/mixin/MixinTest.java index d6e1a2ce63a..d7b0811f417 100644 --- a/src/test/invalid/common/MixinTest.java +++ b/src/test/java/org/spongepowered/common/mixin/MixinTest.java @@ -22,16 +22,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common; +package org.spongepowered.common.mixin; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.spongepowered.asm.mixin.MixinEnvironment; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; -@RunWith(LaunchWrapperTestRunner.class) public class MixinTest { + @Disabled @Test public void auditMixins() { // Ensure all Mixins apply without error diff --git a/src/test/java/org/spongepowered/common/registry/RegistryTest.java b/src/test/java/org/spongepowered/common/registry/RegistryTest.java new file mode 100644 index 00000000000..7622087b8ff --- /dev/null +++ b/src/test/java/org/spongepowered/common/registry/RegistryTest.java @@ -0,0 +1,131 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.registry; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +import com.google.common.reflect.TypeToken; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.registry.*; +import org.spongepowered.api.util.annotation.CatalogedBy; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Optional; +import java.util.stream.Stream; + +public class RegistryTest { + + private static Stream> streamRegistries(final ResourceKey root) { + return Stream.concat(Sponge.game().streamRegistries(root), Sponge.server().streamRegistries(root)).distinct(); + } + + private static Stream> streamRegistries() { + return Stream.concat(RegistryTest.streamRegistries(RegistryRoots.MINECRAFT), RegistryTest.streamRegistries(RegistryRoots.SPONGE)); + } + + @TestFactory + public Stream generateRegistryFindTests() { + return RegistryTest.streamRegistries().flatMap((Registry registry) -> registry.streamEntries().map((RegistryEntry entry) -> { + final String name = "Find key " + entry.key() + " in registry " + registry.type().location() + " in " + registry.type().root(); + return dynamicTest(name, () -> { + final Optional> entryByKey = registry.findEntry(entry.key()); + assertTrue(entryByKey.isPresent()); + assertEquals(entryByKey.get().value(), registry.value(entry.key())); // same key -> same value + }); + })); + } + + private static boolean isPublicStatic(Field field) { + return Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()); + } + + private static Stream streamDefaultedReferenceFields() { + return Arrays.stream(RegistryTypes.class.getDeclaredFields()) + .filter(RegistryTest::isPublicStatic) + .flatMap(registryField -> { + final Class valueType = TypeToken.of(((ParameterizedType) registryField.getGenericType()).getActualTypeArguments()[0]).getRawType(); + + final CatalogedBy catalogedBy = valueType.getAnnotation(CatalogedBy.class); + if (catalogedBy == null) { + return Stream.empty(); + } + + return Arrays.stream(catalogedBy.value()); + }) + .flatMap(container -> Arrays.stream(container.getDeclaredFields())) + .filter(field -> isPublicStatic(field) && DefaultedRegistryReference.class.isAssignableFrom(field.getType())); + } + + @Disabled + @TestFactory + public Stream generateDefaultedReferenceTests() { + return RegistryTest.streamDefaultedReferenceFields().map(field -> { + final String name = "Field " + field.getDeclaringClass().getSimpleName() + "#" + field.getName(); + return dynamicTest(name, () -> { + final DefaultedRegistryReference ref = (DefaultedRegistryReference) field.get(null); + assertNotNull(ref.get()); + }); + }); + } + + private static Stream> streamApiInterfaces(final Object instance) { + final Collection> interfaces = new LinkedHashSet<>(); + Class current = instance.getClass(); + while (current != null) { + interfaces.addAll(Arrays.asList(current.getInterfaces())); + current = current.getSuperclass(); + } + return interfaces.stream() + .filter(clazz -> clazz.getName().startsWith("org.spongepowered.api.")); + } + + @Disabled + @TestFactory + public Stream generateMethodTests() { + return RegistryTest.streamRegistries().flatMap(Registry::streamEntries) + .flatMap((RegistryEntry entry) -> { + final Object value = entry.value(); + return streamApiInterfaces(value).flatMap(c -> Arrays.stream(c.getDeclaredMethods())) + .filter(m -> !Modifier.isStatic(m.getModifiers()) && m.getParameterCount() == 0) + .map(m -> { + final String name = "Invoke " + m.getDeclaringClass().getSimpleName() + "#" + m.getName() + " on " + entry.key(); + return dynamicTest(name, () -> { + final Object result = m.invoke(value); + assertNotNull(result); + }); + }); + }); + } +} diff --git a/src/test/java/org/spongepowered/common/util/ExperienceHolderUtilTest.java b/src/test/java/org/spongepowered/common/util/ExperienceHolderUtilTest.java new file mode 100644 index 00000000000..e0e20b4ed5c --- /dev/null +++ b/src/test/java/org/spongepowered/common/util/ExperienceHolderUtilTest.java @@ -0,0 +1,84 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.mojang.authlib.GameProfile; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.storage.PrimaryLevelData; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public final class ExperienceHolderUtilTest { + + public static List testExp() { + final Level world = mock(Level.class); + when(world.getLevelData()).thenReturn(mock(PrimaryLevelData.class)); + + final Player player = new Player(world, BlockPos.ZERO, 0, new GameProfile(UUID.randomUUID(), "Player")) { + @Override + public boolean isSpectator() { + return false; + } + + @Override + public boolean isCreative() { + return false; + } + }; + + final List list = new ArrayList<>(); + + int level = 0; + int startExp = 0; + while (level < 50) { + player.experienceLevel = level; + list.add(Arguments.of(level, startExp, player.getXpNeededForNextLevel())); + startExp += player.getXpNeededForNextLevel(); + level++; + } + + return list; + } + + @MethodSource + @ParameterizedTest + public void testExp(final int level, final int startExp, final int expInLevel) { + assertEquals(expInLevel, ExperienceHolderUtil.getExpBetweenLevels(level)); + assertEquals(startExp, ExperienceHolderUtil.xpAtLevel(level)); + assertEquals(level, ExperienceHolderUtil.getLevelForExp(startExp)); + assertEquals(level, ExperienceHolderUtil.getLevelForExp(startExp + 1)); + } +} diff --git a/src/test/invalid/common/util/persistence/data/FakeBuilder.java b/src/test/java/org/spongepowered/common/util/persistence/data/FakeBuilder.java similarity index 95% rename from src/test/invalid/common/util/persistence/data/FakeBuilder.java rename to src/test/java/org/spongepowered/common/util/persistence/data/FakeBuilder.java index ad94c43f53d..e133826f154 100644 --- a/src/test/invalid/common/util/persistence/data/FakeBuilder.java +++ b/src/test/java/org/spongepowered/common/util/persistence/data/FakeBuilder.java @@ -24,9 +24,9 @@ */ package org.spongepowered.common.util.persistence.data; -import org.spongepowered.api.data.DataQuery; -import org.spongepowered.api.data.DataView; import org.spongepowered.api.data.persistence.DataBuilder; +import org.spongepowered.api.data.persistence.DataQuery; +import org.spongepowered.api.data.persistence.DataView; import org.spongepowered.api.data.persistence.InvalidDataException; import java.util.Optional; diff --git a/src/test/invalid/common/util/persistence/data/FakeSerializable.java b/src/test/java/org/spongepowered/common/util/persistence/data/FakeSerializable.java similarity index 87% rename from src/test/invalid/common/util/persistence/data/FakeSerializable.java rename to src/test/java/org/spongepowered/common/util/persistence/data/FakeSerializable.java index 0a696b4ef3d..3f293abcd9f 100644 --- a/src/test/invalid/common/util/persistence/data/FakeSerializable.java +++ b/src/test/java/org/spongepowered/common/util/persistence/data/FakeSerializable.java @@ -24,10 +24,10 @@ */ package org.spongepowered.common.util.persistence.data; -import org.spongepowered.api.data.DataContainer; -import org.spongepowered.api.data.DataQuery; -import org.spongepowered.api.data.DataSerializable; -import org.spongepowered.api.data.Queries; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.data.persistence.DataQuery; +import org.spongepowered.api.data.persistence.DataSerializable; +import org.spongepowered.api.data.persistence.Queries; public class FakeSerializable implements DataSerializable { @@ -46,14 +46,14 @@ public FakeSerializable(String foo, int myInt, double theDouble, String nestedCo } @Override - public int getContentVersion() { + public int contentVersion() { return 1; } @Override public DataContainer toContainer() { DataContainer container = DataContainer.createNew(); - container.set(Queries.CONTENT_VERSION, getContentVersion()); + container.set(Queries.CONTENT_VERSION, contentVersion()); container.set(DataQuery.of("foo"), this.foo); container.set(DataQuery.of("myInt"), this.myInt); container.set(DataQuery.of("theDouble"), this.theDouble); diff --git a/src/test/invalid/common/util/persistence/data/NBTTranslationTest.java b/src/test/java/org/spongepowered/common/util/persistence/data/NBTTranslationTest.java similarity index 80% rename from src/test/invalid/common/util/persistence/data/NBTTranslationTest.java rename to src/test/java/org/spongepowered/common/util/persistence/data/NBTTranslationTest.java index 653ae66ce91..804b2038c3c 100644 --- a/src/test/invalid/common/util/persistence/data/NBTTranslationTest.java +++ b/src/test/java/org/spongepowered/common/util/persistence/data/NBTTranslationTest.java @@ -24,18 +24,18 @@ */ package org.spongepowered.common.util.persistence.data; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; -import net.minecraft.nbt.NBTTagCompound; -import org.junit.Test; +import net.minecraft.nbt.CompoundTag; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import org.spongepowered.api.data.DataContainer; import org.spongepowered.api.data.DataManager; -import org.spongepowered.api.data.DataQuery; -import org.spongepowered.api.data.DataView; import org.spongepowered.api.data.persistence.DataBuilder; -import org.spongepowered.common.data.persistence.NbtTranslator; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.data.persistence.DataQuery; +import org.spongepowered.api.data.persistence.DataView; +import org.spongepowered.common.data.persistence.NBTTranslator; import java.util.Optional; @@ -45,12 +45,12 @@ public class NBTTranslationTest { public void testContainerToNBT() { DataManager service = Mockito.mock(DataManager.class); DataBuilder builder = new FakeBuilder(); - when(service.getBuilder(FakeSerializable.class)).thenReturn(Optional.of(builder)); + when(service.builder(FakeSerializable.class)).thenReturn(Optional.of(builder)); DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED); container.set(DataQuery.of("foo"), "bar"); FakeSerializable temp = new FakeSerializable("bar", 7, 10.0D, "nested"); container.set(DataQuery.of("myFake"), temp); - NBTTagCompound compound = NBTTranslator.INSTANCE.translateData(container); + CompoundTag compound = NBTTranslator.INSTANCE.translate(container); DataView translatedContainer = NBTTranslator.INSTANCE.translateFrom(compound); assertEquals(container, translatedContainer); } @@ -58,7 +58,7 @@ public void testContainerToNBT() { @Test public void testDotContainerKeys() { final DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED).set(DataQuery.of("my.key.to.data"), 1); - NBTTagCompound compound = NBTTranslator.INSTANCE.translateData(container); + CompoundTag compound = NBTTranslator.INSTANCE.translate(container); DataView translatedContainer = NBTTranslator.INSTANCE.translateFrom(compound); assertEquals(container, translatedContainer); } diff --git a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java index a8c28ec8297..8853e8fb264 100644 --- a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java +++ b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java @@ -166,7 +166,7 @@ private static SpongeArchetypeVolume fillVolume(final Vector3i min, final Vector return volume; } - @MethodSource("testTransformationsOfPositions") + @MethodSource @ParameterizedTest void testTransformationsOfPositions( final Vector3i min, final Vector3i max, final Vector3i origin, final Vector3i testForRoundTrip, diff --git a/src/test/invalid/common/regression/SchematicUpgradeTest.java b/src/test/java/org/spongepowered/common/world/schematic/SchematicTest.java similarity index 77% rename from src/test/invalid/common/regression/SchematicUpgradeTest.java rename to src/test/java/org/spongepowered/common/world/schematic/SchematicTest.java index fbdaa959fc5..07454b75d52 100644 --- a/src/test/invalid/common/regression/SchematicUpgradeTest.java +++ b/src/test/java/org/spongepowered/common/world/schematic/SchematicTest.java @@ -22,35 +22,36 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.regression; +package org.spongepowered.common.world.schematic; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.spongepowered.api.data.DataContainer; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.spongepowered.api.data.persistence.DataContainer; import org.spongepowered.api.data.persistence.DataFormats; import org.spongepowered.api.world.schematic.Schematic; -import org.spongepowered.lwts.runner.LaunchWrapperTestRunner; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPInputStream; -@RunWith(LaunchWrapperTestRunner.class) -public class SchematicUpgradeTest { +@Disabled +public class SchematicTest { @Test public void testUpgradingv1Tov2() throws IOException { final ClassLoader classLoader = this.getClass().getClassLoader(); + final SchematicTranslator translator = SchematicTranslator.get(); + try (final InputStream v1InputStream = classLoader.getResource("loadv1.schematic").openStream(); final InputStream v2InputStream = classLoader.getResource("loadv2.schematic").openStream(); final GZIPInputStream v1GzipInputStream = new GZIPInputStream(v1InputStream); - final GZIPInputStream v2GzipInputStream = new GZIPInputStream(v2InputStream)){ - final DataContainer v1Container = DataFormats.NBT.readFrom(v1GzipInputStream); - final Schematic v1Schem = DataTranslators.SCHEMATIC.translate(v1Container); - final DataContainer v2Container = DataFormats.NBT.readFrom(v2GzipInputStream); - final Schematic v2Schem = DataTranslators.SCHEMATIC.translate(v2Container); + final GZIPInputStream v2GzipInputStream = new GZIPInputStream(v2InputStream)) { + final DataContainer v1Container = DataFormats.NBT.get().readFrom(v1GzipInputStream); + final Schematic v1Schem = translator.translate(v1Container); + final DataContainer v2Container = DataFormats.NBT.get().readFrom(v2GzipInputStream); + final Schematic v2Schem = translator.translate(v2Container); assertEquals(v1Schem, v2Schem); } } diff --git a/src/test/java/org/spongepowered/common/world/storage/SpongeChunkLayoutTest.java b/src/test/java/org/spongepowered/common/world/storage/SpongeChunkLayoutTest.java new file mode 100644 index 00000000000..ad94566499b --- /dev/null +++ b/src/test/java/org/spongepowered/common/world/storage/SpongeChunkLayoutTest.java @@ -0,0 +1,168 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.world.storage; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.spongepowered.api.util.Direction; +import org.spongepowered.math.vector.Vector3i; + +@Disabled +public class SpongeChunkLayoutTest { + + @Test + public void testConstants() { + assertEquals(new Vector3i(16, 256, 16), SpongeChunkLayout.INSTANCE.chunkSize()); + assertEquals(new Vector3i(1874999, 0, 1874999), SpongeChunkLayout.INSTANCE.spaceMax()); + assertEquals(new Vector3i(-1875000, 0, -1875000), SpongeChunkLayout.INSTANCE.spaceMin()); + assertEquals(new Vector3i(3750000, 1, 3750000), SpongeChunkLayout.INSTANCE.spaceSize()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.spaceOrigin()); + } + + @Test + public void testCoordValidation() { + assertTrue(SpongeChunkLayout.INSTANCE.isValidChunk(new Vector3i(0, 0, 0))); + assertTrue(SpongeChunkLayout.INSTANCE.isValidChunk(0, 0, 0)); + assertTrue(SpongeChunkLayout.INSTANCE.isValidChunk(new Vector3i(1874999, 0, 1874999))); + assertTrue(SpongeChunkLayout.INSTANCE.isValidChunk(1874999, 0, 1874999)); + assertTrue(SpongeChunkLayout.INSTANCE.isValidChunk(new Vector3i(-1875000, 0, -1875000))); + assertTrue(SpongeChunkLayout.INSTANCE.isValidChunk(-1875000, 0, -1875000)); + + assertFalse(SpongeChunkLayout.INSTANCE.isValidChunk(1875000, 0, 1874999)); + assertFalse(SpongeChunkLayout.INSTANCE.isValidChunk(1874999, 1, 1874999)); + assertFalse(SpongeChunkLayout.INSTANCE.isValidChunk(1874999, 0, 1875000)); + assertFalse(SpongeChunkLayout.INSTANCE.isValidChunk(-1875001, 0, -1875000)); + assertFalse(SpongeChunkLayout.INSTANCE.isValidChunk(-1875000, -1, -1875000)); + assertFalse(SpongeChunkLayout.INSTANCE.isValidChunk(-1875000, 0, -1875001)); + + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(0, 0, 0)); + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(14, 125, 9))); + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(14, 125, 9)); + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(15, 255, 15)); + + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(-1, 0, 0))); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(0, -1, 0))); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(0, 0, -1))); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(-1, 0, 0)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(0, -1, 0)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(0, 0, -1)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(16, 255, 15)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(15, 256, 15)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(15, 255, 16)); + + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(0, 0, 0, 0, 0, 0)); + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(30, 125, -7), new Vector3i(1, 0, -1))); + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(30, 125, -7, 1, 0, -1)); + assertTrue(SpongeChunkLayout.INSTANCE.isInChunk(65, 255, -33, 4, 0, -3)); + + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(-17, 0, 0), new Vector3i(-1, 0, 0))); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(0, -257, 0), new Vector3i(0, -1, 0))); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(new Vector3i(0, 0, -17), new Vector3i(0, 0, -1))); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(-17, 0, 0, -1, 0, 0)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(0, -257, 0, 0, -1, 0)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(0, 0, -17, 0, 0, -1)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(32, 255, 31, 1, 0, 1)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(31, 256, 31, 1, 0, 1)); + assertFalse(SpongeChunkLayout.INSTANCE.isInChunk(31, 255, 32, 1, 0, 1)); + } + + @Test + public void testCoordConversion() { + // chunk to world + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.toChunk(Vector3i.ZERO).get()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.toChunk(0, 0, 0).get()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.toChunk(new Vector3i(15, 255, 15)).get()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.toChunk(15, 255, 15).get()); + + assertEquals(new Vector3i(2, 0, 4), SpongeChunkLayout.INSTANCE.toChunk(new Vector3i(34, 121, 72)).get()); + assertEquals(new Vector3i(2, 0, 4), SpongeChunkLayout.INSTANCE.toChunk(34, 121, 72).get()); + + assertEquals(new Vector3i(-6, 0, -13), SpongeChunkLayout.INSTANCE.toChunk(new Vector3i(-83, 62, -203)).get()); + assertEquals(new Vector3i(-6, 0, -13), SpongeChunkLayout.INSTANCE.toChunk(-83, 62, -203).get()); + + assertFalse(SpongeChunkLayout.INSTANCE.toChunk(30000000, 0, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toChunk(-30000001, 0, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toChunk(0, 256, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toChunk(0, -1, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toChunk(0, 0, 30000000).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toChunk(0, 0, -30000001).isPresent()); + + // world to chunk + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.toWorld(Vector3i.ZERO).get()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.toWorld(0, 0, 0).get()); + + assertEquals(new Vector3i(32, 0, 64), SpongeChunkLayout.INSTANCE.toWorld(new Vector3i(2, 0, 4)).get()); + assertEquals(new Vector3i(32, 0, 64), SpongeChunkLayout.INSTANCE.toWorld(2, 0, 4).get()); + + assertEquals(new Vector3i(-96, 0, -208), SpongeChunkLayout.INSTANCE.toWorld(new Vector3i(-6, 0, -13)).get()); + assertEquals(new Vector3i(-96, 0, -208), SpongeChunkLayout.INSTANCE.toWorld(-6, 0, -13).get()); + + assertFalse(SpongeChunkLayout.INSTANCE.toWorld(1875000, 0, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toWorld(-1875001, 0, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toWorld(0, 1, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toWorld(0, -1, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toWorld(0, 0, 1875000).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.toWorld(0, 0, -1875001).isPresent()); + } + + @Test + public void testCoordAdd() { + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.addToChunk(Vector3i.ZERO, Vector3i.ZERO).get()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.addToChunk(0, 0, 0, 0, 0, 0).get()); + + assertEquals(new Vector3i(7, 0, 5), SpongeChunkLayout.INSTANCE.addToChunk(3, 0, 5, 4, 0, 0).get()); + assertEquals(new Vector3i(7, 0, 9), SpongeChunkLayout.INSTANCE.addToChunk(3, 0, 5, 4, 0, 4).get()); + + assertFalse(SpongeChunkLayout.INSTANCE.addToChunk(1874999, 0, 0, 1, 0, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.addToChunk(0, 0, 0, 0, 1, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.addToChunk(0, 0, 1874999, 0, 0, 1).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.addToChunk(-1875000, 0, 0, -1, 0, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.addToChunk(0, 0, 0, 0, -1, 0).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.addToChunk(0, 0, -1875000, 0, 0, -1).isPresent()); + } + + @Test + public void testCoordMove() { + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.moveToChunk(Vector3i.ZERO, Direction.NONE).get()); + assertEquals(Vector3i.ZERO, SpongeChunkLayout.INSTANCE.moveToChunk(0, 0, 0, Direction.NONE).get()); + + assertEquals(new Vector3i(4, 0, 5), SpongeChunkLayout.INSTANCE.moveToChunk(3, 0, 5, Direction.EAST).get()); + assertEquals(new Vector3i(7, 0, 5), SpongeChunkLayout.INSTANCE.moveToChunk(3, 0, 5, Direction.EAST, 4).get()); + assertEquals(new Vector3i(4, 0, 6), SpongeChunkLayout.INSTANCE.moveToChunk(3, 0, 5, Direction.SOUTHEAST).get()); + assertEquals(new Vector3i(7, 0, 9), SpongeChunkLayout.INSTANCE.moveToChunk(3, 0, 5, Direction.SOUTHEAST, 4).get()); + + assertFalse(SpongeChunkLayout.INSTANCE.moveToChunk(1874999, 0, 0, Direction.EAST).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.moveToChunk(0, 0, 0, Direction.UP).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.moveToChunk(0, 0, 1874999, Direction.SOUTH).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.moveToChunk(-1875000, 0, 0, Direction.WEST).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.moveToChunk(0, 0, 0, Direction.DOWN).isPresent()); + assertFalse(SpongeChunkLayout.INSTANCE.moveToChunk(0, 0, -1875000, Direction.NORTH).isPresent()); + + assertThrows(IllegalArgumentException.class, () -> SpongeChunkLayout.INSTANCE.moveToChunk(0, 0, 0, Direction.SOUTH_SOUTHEAST)); + } + +} From 1f3d550c92a59dad60b403174a61f023752f07df Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Thu, 7 Aug 2025 18:14:10 +0200 Subject: [PATCH 07/11] Add code coverage via JaCoCo and a specialized class transformer --- .../bootstrap/dev/DevClasspath.java | 2 +- forge/build.gradle.kts | 17 ++ gradle/libs.versions.toml | 2 + gradle/verification-metadata.xml | 42 +++++ modlauncher-transformers/build.gradle.kts | 9 +- .../jacoco/AgentAccessGenerator.java | 39 +++++ .../modlauncher/jacoco/Instrumenter.java | 72 ++++++++ .../jacoco/JacocoPluginService.java | 155 ++++++++++++++++++ .../PrefixedCondyProbeArrayStrategy.java | 63 +++++++ ...odlauncher.serviceapi.ILaunchPluginService | 1 + neoforge/build.gradle.kts | 17 ++ vanilla/build.gradle.kts | 18 +- 12 files changed, 430 insertions(+), 7 deletions(-) create mode 100644 modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/AgentAccessGenerator.java create mode 100644 modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/Instrumenter.java create mode 100644 modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java create mode 100644 modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/PrefixedCondyProbeArrayStrategy.java create mode 100644 modlauncher-transformers/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService diff --git a/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java b/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java index 5b0d65f20c9..3e1b3c97e1d 100644 --- a/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java +++ b/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java @@ -132,7 +132,7 @@ public static List resolve() { continue; } - if (bootNames.contains(fileName)) { + if (bootNames.contains(fileName) || fileName.startsWith("org.jacoco.core-")) { if (Bootstrap.DEBUG) { System.out.println("Boot: " + path); } diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 2e893adfe95..fea72eeca39 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("implementation-structure") alias(libs.plugins.blossom) alias(libs.plugins.forgeGradle) + jacoco } val commonProject = parent!! @@ -234,6 +235,10 @@ dependencies { testImplementation(libs.mockito.junitJupiter) { exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") } + + testRuntimeOnly(libs.jacoco.core) { + exclude(group = "org.ow2.asm") + } } val awFiles: Set = files(commonMain.get().resources, main.resources).filter { it.name.endsWith(".accesswidener") }.files @@ -437,6 +442,18 @@ tasks { workingDir.mkdirs() workingDir.resolve("eula.txt").writeText("eula=true") } + + extensions.configure(JacocoTaskExtension::class) { + excludeClassLoaders = listOf("cpw.mods.modlauncher.TransformingClassLoader") + } + + finalizedBy(jacocoTestReport) + } + + jacocoTestReport { + sourceSets(commonAppLaunchConf.get(), commonAppLaunch.get(), commonLaunch.get(), commonAccessors.get(), commonMixins.get(), commonMain.get()) + sourceSets(appLaunch, launch, lang, accessors, mixins, main) + dependsOn(test) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d6aefb1ff35..82ea5a9ce16 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,6 +19,7 @@ mockito = "5.11.0" jline = "3.25.1" tinylog = "2.7.0" vineflower = "1.11.1" +jacoco = "0.8.13" [libraries] # common @@ -57,6 +58,7 @@ mixinextras-common = { module = "io.github.llamalad7:mixinextras-common", versio mixinextras-forge = { module = "io.github.llamalad7:mixinextras-forge", version.ref = "mixinextras" } mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } mockito-junitJupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } +jacoco-core = { module = "org.jacoco:org.jacoco.core", version.ref = "jacoco" } # vanilla forgeAutoRenamingTool = { module = "net.minecraftforge:ForgeAutoRenamingTool", version.ref = "forgeAutoRenamingTool" } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index a614c5b28c6..74d474718c2 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -7069,6 +7069,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -8366,6 +8403,11 @@ + + + + + diff --git a/modlauncher-transformers/build.gradle.kts b/modlauncher-transformers/build.gradle.kts index 2f1192b3500..5ddf331a743 100644 --- a/modlauncher-transformers/build.gradle.kts +++ b/modlauncher-transformers/build.gradle.kts @@ -1,10 +1,8 @@ dependencies { - // AccessWidener transformer implementation(libs.accessWidener) { exclude(group="org.apache.logging.log4j") } - // ModLauncher inherited dependencies - strictly should be provided by - // the platform making use of this project + compileOnly(libs.log4j.api) compileOnly(libs.neo.modlauncher) { exclude(group = "org.ow2.asm") @@ -13,9 +11,10 @@ dependencies { compileOnly(libs.joptSimple) compileOnly(libs.asm.commons) - - // And finally, compile only annotations compileOnly(apiLibs.checkerQual) + + // Optional + compileOnly(libs.jacoco.core) } tasks { diff --git a/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/AgentAccessGenerator.java b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/AgentAccessGenerator.java new file mode 100644 index 00000000000..d4b2c8a9698 --- /dev/null +++ b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/AgentAccessGenerator.java @@ -0,0 +1,39 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.transformers.modlauncher.jacoco; + +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.jacoco.core.runtime.RuntimeData; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class AgentAccessGenerator implements IExecutionDataAccessorGenerator { + @Override + public int generateDataAccessor(final long classId, final String className, final int probeCount, final MethodVisitor mv) { + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/$JaCoCo", "data", "Ljava/lang/Object;"); + RuntimeData.generateAccessCall(classId, className, probeCount, mv); + return 6; + } +} diff --git a/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/Instrumenter.java b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/Instrumenter.java new file mode 100644 index 00000000000..3c9457f54bc --- /dev/null +++ b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/Instrumenter.java @@ -0,0 +1,72 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.transformers.modlauncher.jacoco; + +import org.jacoco.core.internal.data.CRC64; +import org.jacoco.core.internal.flow.ClassProbesAdapter; +import org.jacoco.core.internal.instr.ClassInstrumenter; +import org.jacoco.core.internal.instr.IProbeArrayStrategy; +import org.jacoco.core.internal.instr.InstrSupport; +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; + +public class Instrumenter { + // Incompatible with Mixin (ClassMetadataNotFoundException: java.lang.$JaCoCo) + private static final IExecutionDataAccessorGenerator agentAccessGenerator = new AgentAccessGenerator(); + + // Module must read org.jacoco.agent.rt + private static final IExecutionDataAccessorGenerator offlineAccessGenerator = new OfflineInstrumentationAccessGenerator(); + + public static byte[] instrument(final byte[] originalBytes, final boolean mixin) { + final ClassReader reader = InstrSupport.classReaderFor(originalBytes); + final int version = InstrSupport.getMajorVersion(reader); + if (version < Opcodes.V11) { + // not supported + return originalBytes; + } + + final long classId = CRC64.classId(originalBytes); + final String prefix = mixin ? Long.toHexString(classId) : ""; + final String className = reader.getClassName(); + final boolean isInterfaceOrModule = (reader.getAccess() & (Opcodes.ACC_INTERFACE | Opcodes.ACC_MODULE)) != 0; + + final IProbeArrayStrategy strategy = new PrefixedCondyProbeArrayStrategy(className, isInterfaceOrModule, classId, prefix, + mixin ? Instrumenter.offlineAccessGenerator : Instrumenter.agentAccessGenerator); + + final ClassWriter writer = new ClassWriter(reader, 0) { + @Override + protected String getCommonSuperClass(final String type1, final String type2) { + throw new IllegalStateException(); + } + }; + final ClassVisitor visitor = new ClassProbesAdapter(new ClassInstrumenter(strategy, writer), InstrSupport.needsFrames(version)); + reader.accept(visitor, ClassReader.EXPAND_FRAMES); + return writer.toByteArray(); + } +} diff --git a/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java new file mode 100644 index 00000000000..d87aaaeea58 --- /dev/null +++ b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java @@ -0,0 +1,155 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.transformers.modlauncher.jacoco; + +import cpw.mods.modlauncher.TransformingClassLoader; +import cpw.mods.modlauncher.api.ITransformerActivity; +import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public class JacocoPluginService implements ILaunchPluginService { + private static final Logger logger = LogManager.getLogger(); + + private static final String MIXIN_DESC = "Lorg/spongepowered/asm/mixin/Mixin;"; + + private static final EnumSet YAY = EnumSet.of(Phase.BEFORE); + private static final EnumSet NAY = EnumSet.noneOf(Phase.class); + + private boolean disabled; + private ClassLoader loader; + + public JacocoPluginService() { + try { + getClass().getClassLoader().loadClass("org.jacoco.core.JaCoCo"); + } catch (final ClassNotFoundException e) { + this.disabled = true; + } + } + + @Override + public String name() { + return "jacoco"; + } + + @Override + public EnumSet handlesClass(Type classType, boolean isEmpty) { + return this.disabled || isEmpty ? NAY : YAY; + } + + @Override + public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason) { + if (ITransformerActivity.COMPUTING_FRAMES_REASON.equals(reason)) { + return ComputeFlags.NO_REWRITE; + } + + // Capture a reference to the transforming class loader + if (this.loader == null) { + // First transformed class context, aka game entrypoint is supposed to be the transforming class loader + final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); + if (!((Object) contextLoader instanceof TransformingClassLoader)) { // Ignore IDE warning + throw new IllegalStateException("Context class loader of the first transformed class is not a transforming class loader"); + } + // Context class loader may change for next classes, so capture it + this.loader = contextLoader; + } + + // Only apply JaCoCo to our sources + if (!classNode.name.startsWith("org/spongepowered/")) { + return ComputeFlags.NO_REWRITE; + } + + // We need the original bytes for two reasons: + // - JaCoCo computes a checksum from the bytes + // - JaCoCo requires expanded frames, which the current ClassNode doesn't have + byte[] originalBytes; + try (final InputStream in = this.loader.getResourceAsStream(classNode.name + ".class")) { + if (in == null) { + logger.warn("Failed to find original class bytes for class {}", classNode.name); + return ComputeFlags.NO_REWRITE; + } + + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + in.transferTo(buffer); + originalBytes = buffer.toByteArray(); + } catch (IOException e) { + logger.warn("Failed to read original class bytes for class {}", classNode.name, e); + return ComputeFlags.NO_REWRITE; + } + + // Detect the mixin annotation + boolean mixin = false; + if (classNode.invisibleAnnotations != null) { + for (final AnnotationNode annotation : classNode.invisibleAnnotations) { + if (MIXIN_DESC.equals(annotation.desc)) { + mixin = true; + break; + } + } + } + + final byte[] instrumentedBytes = Instrumenter.instrument(originalBytes, mixin); + final ClassReader classReader = new ClassReader(instrumentedBytes); + final ClassNode instrumentedClassNode = new ClassNode(); + classReader.accept(instrumentedClassNode, 0); + + // Completely overwrite any previous transformation, luckily we are in phase BEFORE and all other transformers we use are in phase AFTER + classNode.fields = instrumentedClassNode.fields; + if (mixin) { + // Mixin doesn't like JaCoCo instructions in but mixin constructors are never called anyway + List methods = new ArrayList<>(); + for (final MethodNode method : classNode.methods) { + if (method.name.equals("")) { + methods.add(method); + } + } + for (final MethodNode method : instrumentedClassNode.methods) { + if (!method.name.equals("")) { + methods.add(method); + } + } + classNode.methods = methods; + } else { + classNode.methods = instrumentedClassNode.methods; + } + + // JaCoCo has already updated the frames + return ComputeFlags.SIMPLE_REWRITE; + } + + +} diff --git a/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/PrefixedCondyProbeArrayStrategy.java b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/PrefixedCondyProbeArrayStrategy.java new file mode 100644 index 00000000000..3d38c30951a --- /dev/null +++ b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/PrefixedCondyProbeArrayStrategy.java @@ -0,0 +1,63 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.transformers.modlauncher.jacoco; + +import org.jacoco.core.internal.instr.CondyProbeArrayStrategy; +import org.jacoco.core.internal.instr.IProbeArrayStrategy; +import org.jacoco.core.internal.instr.InstrSupport; +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ConstantDynamic; +import org.objectweb.asm.Handle; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public record PrefixedCondyProbeArrayStrategy( + String className, boolean isInterface, long classId, String prefix, + IExecutionDataAccessorGenerator accessorGenerator +) implements IProbeArrayStrategy { + + @Override + public int storeInstance(final MethodVisitor mv, final boolean clinit, final int variable) { + final Handle bootstrapMethod = new Handle(Opcodes.H_INVOKESTATIC, this.className, this.prefix + InstrSupport.INITMETHOD_NAME, CondyProbeArrayStrategy.B_DESC, this.isInterface); + mv.visitLdcInsn(new ConstantDynamic(this.prefix + InstrSupport.DATAFIELD_NAME, "Ljava/lang/Object;", bootstrapMethod)); + mv.visitTypeInsn(Opcodes.CHECKCAST, "[Z"); + mv.visitVarInsn(Opcodes.ASTORE, variable); + return 1; + } + + @Override + public void addMembers(final ClassVisitor cv, final int probeCount) { + if (probeCount == 0) { + return; + } + + final MethodVisitor mv = cv.visitMethod(InstrSupport.INITMETHOD_ACC, this.prefix + InstrSupport.INITMETHOD_NAME, CondyProbeArrayStrategy.B_DESC, null, null); + final int maxStack = this.accessorGenerator.generateDataAccessor(this.classId, this.className, probeCount, mv); + mv.visitInsn(Opcodes.ARETURN); + mv.visitMaxs(maxStack, 3); + mv.visitEnd(); + } +} diff --git a/modlauncher-transformers/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService b/modlauncher-transformers/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService new file mode 100644 index 00000000000..f95865eabf0 --- /dev/null +++ b/modlauncher-transformers/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService @@ -0,0 +1 @@ +org.spongepowered.transformers.modlauncher.jacoco.JacocoPluginService diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index a78cc276381..a23611351a3 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -19,6 +19,7 @@ plugins { id("implementation-structure") alias(libs.plugins.blossom) alias(libs.plugins.modDevGradle) + jacoco } val commonProject = parent!! @@ -240,6 +241,10 @@ dependencies { testImplementation(libs.mockito.junitJupiter) { exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") } + + testRuntimeOnly(libs.jacoco.core) { + exclude(group = "org.ow2.asm") + } } afterEvaluate { @@ -414,6 +419,18 @@ tasks { } dependsOn(prepareServerRun) + + extensions.configure(JacocoTaskExtension::class) { + excludeClassLoaders = listOf("cpw.mods.modlauncher.TransformingClassLoader") + } + + finalizedBy(jacocoTestReport) + } + + jacocoTestReport { + sourceSets(commonAppLaunchConf.get(), commonAppLaunch.get(), commonLaunch.get(), commonAccessors.get(), commonMixins.get(), commonMain.get()) + sourceSets(appLaunch, launch, lang, accessors, mixins, main) + dependsOn(test) } } diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index 4f5a36bca04..24bdceca781 100644 --- a/vanilla/build.gradle.kts +++ b/vanilla/build.gradle.kts @@ -6,7 +6,7 @@ plugins { alias(libs.plugins.shadow) id("implementation-structure") alias(libs.plugins.blossom) - eclipse + jacoco } val commonProject = parent!! @@ -264,6 +264,10 @@ dependencies { testImplementation(libs.mockito.junitJupiter) { exclude(group = "org.junit.jupiter", module = "junit-jupiter-api") } + + testRuntimeOnly(libs.jacoco.core) { + exclude(group = "org.ow2.asm") + } } minecraft { @@ -515,6 +519,18 @@ tasks { workingDir.mkdirs() workingDir.resolve("eula.txt").writeText("eula=true") } + + extensions.configure(JacocoTaskExtension::class) { + excludeClassLoaders = listOf("cpw.mods.modlauncher.TransformingClassLoader") + } + + finalizedBy(jacocoTestReport) + } + + jacocoTestReport { + sourceSets(commonAppLaunchConf.get(), commonAppLaunch.get(), commonLaunch.get(), commonAccessors.get(), commonMixins.get(), commonMain.get()) + sourceSets(appLaunch, launch, accessors, mixins, main) + dependsOn(test) } } From 457e7b49608c104cccc68dcaaa0554d609ed4350 Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Sat, 9 Aug 2025 16:33:19 +0200 Subject: [PATCH 08/11] Support unit tests via SpongeVanilla production jar --- vanilla/build.gradle.kts | 4 ++ .../vanilla/installer/InstallerMain.java | 20 ++++---- .../installer/test/SpongeSessionListener.java | 50 +++++++++++++++++++ .../installer/test/SpongeTestBoot.java | 40 +++++++++++++++ ....platform.launcher.LauncherSessionListener | 1 + 5 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeSessionListener.java create mode 100644 vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeTestBoot.java create mode 100644 vanilla/src/installer/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index 24bdceca781..8b6659b1ba6 100644 --- a/vanilla/build.gradle.kts +++ b/vanilla/build.gradle.kts @@ -185,6 +185,10 @@ dependencies { installer(project(libraryManagerProject.path)) + // optional at runtime + "installerCompileOnly"(platform(apiLibs.junit.bom)) + "installerCompileOnly"(apiLibs.junit.launcher) + val boot = bootLibrariesConfig.name boot(libs.securemodules) boot(libs.asm.commons) diff --git a/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java index d1ae9561381..4dcb08aa7fb 100644 --- a/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java +++ b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java @@ -81,28 +81,30 @@ public final class InstallerMain { private static final int MAX_TRIES = 2; private final Installer installer; + private final boolean isolated; - public InstallerMain(final String[] args) throws Exception { + public InstallerMain(final String[] args, final boolean isolated) throws Exception { LauncherCommandLine.configure(args); this.installer = new Installer(LauncherCommandLine.installerDirectory); + this.isolated = isolated; } public static void main(final String[] args) throws Exception { - new InstallerMain(args).run(); + new InstallerMain(args, true).run(); } - public void run() { + public void run() throws Exception { try { this.downloadAndRun(); } catch (final Exception ex) { Logger.error(ex, "Failed to download Sponge libraries and/or Minecraft"); - System.exit(2); + throw ex; } finally { this.installer.getLibraryManager().finishedProcessing(); } } - public void downloadAndRun() throws Exception { + private void downloadAndRun() throws Exception { ServerAndLibraries remappedMinecraftJar = null; Version mcVersion = null; try { @@ -188,7 +190,7 @@ public void downloadAndRun() throws Exception { gameArgs.add(launchTarget); Collections.addAll(gameArgs, this.installer.getConfig().args().split(" ")); - InstallerMain.bootstrap(bootLibs, spongeBoot, gameArgs.toArray(new String[0])); + this.bootstrap(bootLibs, spongeBoot, gameArgs.toArray(new String[0])); } private static Path newJarInJar(final Path jar) { @@ -214,7 +216,7 @@ private ServerAndLibraries recoverFromMinecraftDownloadErr } } - private static void bootstrap(final Path[] bootLibs, final Path spongeBoot, final String[] args) throws Exception { + private void bootstrap(final Path[] bootLibs, final Path spongeBoot, final String[] args) throws Exception { final List classpath = new ArrayList<>(); for (final Path lib : bootLibs) { classpath.add(new Path[] { lib }); @@ -222,10 +224,10 @@ private static void bootstrap(final Path[] bootLibs, final Path spongeBoot, fina classpath.add(new Path[] { spongeBoot }); try { - new VanillaBootstrap(args).boot(classpath, true); + new VanillaBootstrap(args).boot(classpath, this.isolated); } catch (final Exception ex) { Logger.error(ex, "Failed to invoke bootstrap due to an error"); - System.exit(1); + throw ex; } } diff --git a/vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeSessionListener.java b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeSessionListener.java new file mode 100644 index 00000000000..1c7252550ab --- /dev/null +++ b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeSessionListener.java @@ -0,0 +1,50 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.vanilla.installer.test; + +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.LauncherSessionListener; +import org.spongepowered.common.applaunch.test.TestGameAccess; + +public class SpongeSessionListener implements LauncherSessionListener { + private ClassLoader previousLoader; + + @Override + public void launcherSessionOpened(final LauncherSession session) { + this.previousLoader = Thread.currentThread().getContextClassLoader(); + + try { + Thread.currentThread().setContextClassLoader(SpongeTestBoot.getGameClassLoader()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void launcherSessionClosed(final LauncherSession session) { + TestGameAccess.shutdownGame(); + Thread.currentThread().setContextClassLoader(this.previousLoader); + } +} diff --git a/vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeTestBoot.java b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeTestBoot.java new file mode 100644 index 00000000000..6260808514e --- /dev/null +++ b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/test/SpongeTestBoot.java @@ -0,0 +1,40 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.vanilla.installer.test; + +import org.spongepowered.common.applaunch.test.TestGameAccess; +import org.spongepowered.vanilla.installer.InstallerMain; + +public class SpongeTestBoot { + + public static ClassLoader getGameClassLoader() throws Exception { + if (TestGameAccess.getGameClassLoader() == null) { + final String[] args = System.getProperty("sponge.test.args", "").split(" "); + System.setProperty("sponge.test.active", "true"); + new InstallerMain(args, false).run(); + } + return TestGameAccess.getGameClassLoader(); + } +} diff --git a/vanilla/src/installer/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener b/vanilla/src/installer/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener new file mode 100644 index 00000000000..b9f17c0d2bb --- /dev/null +++ b/vanilla/src/installer/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener @@ -0,0 +1 @@ +org.spongepowered.vanilla.installer.test.SpongeSessionListener From abf8d23d1b60f04a970e378653c464c1172963da Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Sat, 9 Aug 2025 22:39:58 +0200 Subject: [PATCH 09/11] Support JaCoCo via SpongeVanilla production jar --- forge/build.gradle.kts | 1 + .../jacoco/JacocoPluginService.java | 25 +++++++++++++++++-- neoforge/build.gradle.kts | 1 + vanilla/build.gradle.kts | 1 + .../vanilla/installer/InstallerMain.java | 24 ++++++++++++++---- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index fea72eeca39..5b6369a6709 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -434,6 +434,7 @@ tasks { val runServer = minecraft.runs.getByName("server") jvmArgs(runServer.jvmArgs) jvmArgs("-Dsponge.test.args=" + runServer.args.joinToString(" ")) + jvmArgs("-Dsponge.jacoco.packages=org.spongepowered") workingDir = layout.buildDirectory.dir("test-run").get().asFile doFirst { diff --git a/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java index d87aaaeea58..e8c176b047b 100644 --- a/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java +++ b/modlauncher-transformers/src/main/java/org/spongepowered/transformers/modlauncher/jacoco/JacocoPluginService.java @@ -51,6 +51,7 @@ public class JacocoPluginService implements ILaunchPluginService { private static final EnumSet NAY = EnumSet.noneOf(Phase.class); private boolean disabled; + private String[] packages; private ClassLoader loader; public JacocoPluginService() { @@ -58,6 +59,15 @@ public JacocoPluginService() { getClass().getClassLoader().loadClass("org.jacoco.core.JaCoCo"); } catch (final ClassNotFoundException e) { this.disabled = true; + return; + } + + this.packages = System.getProperty("sponge.jacoco.packages", "").split(","); + for (int i = 0; i < this.packages.length; i++) { + final String pkg = this.packages[i].replace('.', '/'); + if (!pkg.endsWith("/")) { + this.packages[i] = pkg + "/"; + } } } @@ -71,6 +81,15 @@ public EnumSet handlesClass(Type classType, boolean isEmpty) { return this.disabled || isEmpty ? NAY : YAY; } + private boolean testClassName(final String name) { + for (final String pkg : this.packages) { + if (name.startsWith(pkg)) { + return true; + } + } + return false; + } + @Override public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason) { if (ITransformerActivity.COMPUTING_FRAMES_REASON.equals(reason)) { @@ -88,8 +107,10 @@ public int processClassWithFlags(final Phase phase, final ClassNode classNode, f this.loader = contextLoader; } - // Only apply JaCoCo to our sources - if (!classNode.name.startsWith("org/spongepowered/")) { + // Do not instrument every class for two reasons: + // - Performance + // - JaCoCo changes the LVT which can cause mixins targeting the current class to fail + if (!this.testClassName(classNode.name)) { return ComputeFlags.NO_REWRITE; } diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index a23611351a3..7af530fe46b 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -409,6 +409,7 @@ tasks { jvmArgs(runServer.get().jvmArgs) jvmArgs("-Dsponge.test.args=" + runServer.get().args!!.joinToString(" ")) + jvmArgs("-Dsponge.jacoco.packages=org.spongepowered") workingDir = layout.buildDirectory.dir("test-run").get().asFile doFirst { diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index 8b6659b1ba6..86742047026 100644 --- a/vanilla/build.gradle.kts +++ b/vanilla/build.gradle.kts @@ -515,6 +515,7 @@ tasks { val runServer = minecraft.runs.server().get() jvmArgs(runServer.allJvmArguments()) jvmArgs("-Dsponge.test.args=" + runServer.allArguments().joinToString(" ")) + jvmArgs("-Dsponge.jacoco.packages=org.spongepowered") workingDir = layout.buildDirectory.dir("test-run").get().asFile doFirst { diff --git a/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java index 4dcb08aa7fb..3a4cd688cfc 100644 --- a/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java +++ b/vanilla/src/installer/java/org/spongepowered/vanilla/installer/InstallerMain.java @@ -111,7 +111,6 @@ private void downloadAndRun() throws Exception { mcVersion = this.downloadMinecraftManifest(); } catch (final IOException ex) { remappedMinecraftJar = this.recoverFromMinecraftDownloadError(ex); - this.installer.getLibraryManager().validate(); } final LibraryManager libraryManager = this.installer.getLibraryManager(); @@ -128,7 +127,6 @@ private void downloadAndRun() throws Exception { throw new UncheckedIOException(ex); } }, libraryManager.preparationWorker()); - libraryManager.validate(); remappedMinecraftJar = remappedMinecraftJarFuture.get(); } } catch (final ExecutionException ex) { @@ -137,6 +135,8 @@ private void downloadAndRun() throws Exception { } assert remappedMinecraftJar != null; // always assigned or thrown + libraryManager.validate(); + // Minecraft itself is on the main layer libraryManager.addLibrary(InstallerMain.COLLECTION_MAIN, new LibraryManager.Library("minecraft", remappedMinecraftJar.server())); @@ -148,17 +148,31 @@ private void downloadAndRun() throws Exception { libraryManager.addLibrary(InstallerMain.COLLECTION_BOOTSTRAP, new LibraryManager.Library(artifact.toString(), path)); } - this.installer.getLibraryManager().finishedProcessing(); + if (!this.isolated) { + // JaCoCo core is provided by the user because its version must match the version of the JaCoCo agent + Path jacocoJar = null; + try { + final Class jacocoClass = getClass().getClassLoader().loadClass("org.jacoco.core.JaCoCo"); + jacocoJar = Path.of(jacocoClass.getProtectionDomain().getCodeSource().getLocation().toURI()); + } catch (final Exception ignored) {} + + if (jacocoJar != null && jacocoJar.getFileName().toString().endsWith(".jar")) { + Logger.info("JaCoCo core has been detected. Custom instrumentation will be enabled."); + libraryManager.addLibrary(InstallerMain.COLLECTION_BOOTSTRAP, new LibraryManager.Library("jacoco-core", jacocoJar)); + } + } + + libraryManager.finishedProcessing(); Logger.info("Environment has been verified."); final Set seenLibs = new HashSet<>(); - final Path[] bootLibs = this.installer.getLibraryManager().getAll(InstallerMain.COLLECTION_BOOTSTRAP).stream() + final Path[] bootLibs = libraryManager.getAll(InstallerMain.COLLECTION_BOOTSTRAP).stream() .peek(lib -> seenLibs.add(lib.name())) .map(LibraryManager.Library::file) .toArray(Path[]::new); - final Path[] gameLibs = this.installer.getLibraryManager().getAll(InstallerMain.COLLECTION_MAIN).stream() + final Path[] gameLibs = libraryManager.getAll(InstallerMain.COLLECTION_MAIN).stream() .filter(lib -> !seenLibs.contains(lib.name())) .map(LibraryManager.Library::file) .toArray(Path[]::new); From 3810b54d06b0293e16e2f0a728f1b2bde8227417 Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Sun, 10 Aug 2025 21:12:08 +0200 Subject: [PATCH 10/11] Ability to trigger ticks during tests --- .../bootstrap/dev/DevClasspath.java | 2 +- .../bridge/server/MinecraftServerBridge.java | 4 ++ .../server/MinecraftServerMixin_Test.java | 48 ++++++++----- .../DedicatedServerSettingsMixin_Test.java | 1 + .../common/scheduler/SchedulerTest.java | 70 +++++++++++++++++++ src/test/resources/mixins.common.test.json | 11 --- 6 files changed, 108 insertions(+), 28 deletions(-) create mode 100644 src/test/java/org/spongepowered/common/scheduler/SchedulerTest.java delete mode 100644 src/test/resources/mixins.common.test.json diff --git a/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java b/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java index 3e1b3c97e1d..8dfc98cb24e 100644 --- a/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java +++ b/bootstrap/src/main/java/org/spongepowered/bootstrap/dev/DevClasspath.java @@ -125,7 +125,7 @@ public static List resolve() { final String fileName = path.getFileName().toString(); - if (fileName.startsWith("junit-")) { + if (fileName.startsWith("junit-") || fileName.startsWith("mockito-")) { if (Bootstrap.DEBUG) { System.out.println("Ignored: " + path); } diff --git a/src/main/java/org/spongepowered/common/bridge/server/MinecraftServerBridge.java b/src/main/java/org/spongepowered/common/bridge/server/MinecraftServerBridge.java index 9d4e6a54def..a3a3a31a5ac 100644 --- a/src/main/java/org/spongepowered/common/bridge/server/MinecraftServerBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/server/MinecraftServerBridge.java @@ -53,4 +53,8 @@ public interface MinecraftServerBridge { void bridge$reloadedServerRegistries(RegistryHolderLogic holder); RegistryHolderLogic bridge$registryHolder(); + + default void bridge$tickServer(int ticks) { + throw new UnsupportedOperationException("Cannot trigger manual server tick outside test environment"); + } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java index 8d191bdfdd8..8d92a0c9168 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/MinecraftServerMixin_Test.java @@ -35,28 +35,27 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.common.applaunch.test.TestGameAccess; +import org.spongepowered.common.bridge.server.MinecraftServerBridge; import java.io.IOException; +import java.util.function.BooleanSupplier; import java.util.function.Function; @Mixin(MinecraftServer.class) -public abstract class MinecraftServerMixin_Test extends ReentrantBlockableEventLoop { +public abstract class MinecraftServerMixin_Test extends ReentrantBlockableEventLoop implements MinecraftServerBridge { - public MinecraftServerMixin_Test(String name) { - super(name); - } - - @Shadow - protected abstract boolean initServer() throws IOException; - - @Shadow - private volatile boolean running; + // @formatter:off + @Shadow private volatile boolean running; + @Shadow private boolean stopped; - @Shadow - private boolean stopped; + @Shadow protected abstract boolean shadow$initServer() throws IOException; + @Shadow public abstract void shadow$stopServer(); + @Shadow public abstract void shadow$tickServer(BooleanSupplier haveTime); + // @formatter:on - @Shadow - public abstract void stopServer(); + public MinecraftServerMixin_Test(final String name) { + super(name); + } @Inject(method = "", at = @At("RETURN")) private void onInit(final CallbackInfo ci) { @@ -71,7 +70,7 @@ private void onInit(final CallbackInfo ci) { private static void spin(final Function supplier, CallbackInfoReturnable cir) { final MinecraftServer server = supplier.apply(Thread.currentThread()); try { - ((MinecraftServerMixin_Test) (Object) server).initServer(); + ((MinecraftServerMixin_Test) (Object) server).shadow$initServer(); } catch (IOException e) { throw new RuntimeException(e); } @@ -82,7 +81,7 @@ private static void spin(final Function suppl if (this.running) { this.running = false; this.stopped = true; - this.stopServer(); + this.shadow$stopServer(); } } @@ -103,4 +102,21 @@ public void halt(final boolean join) { public void waitUntilNextTick() { this.runAllTasks(); } + + /** + * @author Yeregorix + * @reason We have time to run all optional tasks. + */ + @Overwrite + private boolean haveTime() { + return true; + } + + @Override + public void bridge$tickServer(final int ticks) { + for (int i = 0; i < ticks; i++) { + this.shadow$tickServer(this::haveTime); + this.waitUntilNextTick(); + } + } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java index 47385cbc346..dd95cb3ad80 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java +++ b/src/mixins/java/org/spongepowered/common/mixin/test/server/dedicated/DedicatedServerSettingsMixin_Test.java @@ -43,6 +43,7 @@ public DedicatedServerProperties forceTestProperties(final Path path) { props.setProperty("level-seed", "0"); props.setProperty("level-type", "flat"); props.setProperty("enable-command-block", "true"); + props.setProperty("pause-when-empty-seconds", "0"); return new DedicatedServerProperties(props); } } diff --git a/src/test/java/org/spongepowered/common/scheduler/SchedulerTest.java b/src/test/java/org/spongepowered/common/scheduler/SchedulerTest.java new file mode 100644 index 00000000000..1ac7b72f764 --- /dev/null +++ b/src/test/java/org/spongepowered/common/scheduler/SchedulerTest.java @@ -0,0 +1,70 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.scheduler; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.spongepowered.api.Server; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.scheduler.Task; +import org.spongepowered.api.util.Ticks; +import org.spongepowered.common.bridge.server.MinecraftServerBridge; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.metadata.PluginMetadata; + +import java.util.concurrent.atomic.AtomicBoolean; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class SchedulerTest { + + @Test + public void testScheduleSync() { + final PluginContainer plugin = Mockito.mock(PluginContainer.class); + final PluginMetadata metadata = Mockito.mock(PluginMetadata.class); + when(plugin.metadata()).thenReturn(metadata); + when(metadata.id()).thenReturn("test"); + + final AtomicBoolean done = new AtomicBoolean(false); + final Server server = Sponge.server(); + + server.scheduler().submit(Task.builder().execute(() -> done.set(true)).plugin(plugin).delay(Ticks.of(2)).build()); + assertFalse(done.get()); + + ((MinecraftServerBridge) server).bridge$tickServer(1); + assertFalse(done.get()); + + ((MinecraftServerBridge) server).bridge$tickServer(1); + assertTrue(done.get()); + } +} diff --git a/src/test/resources/mixins.common.test.json b/src/test/resources/mixins.common.test.json deleted file mode 100644 index 5fb635730bb..00000000000 --- a/src/test/resources/mixins.common.test.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "parent": "mixins.sponge.parent.json", - "package": "org.spongepowered.common.launch.mixin", - "mixinPriority": 11111, - "mixins": [ - "ItemMixin_Test", - "SchematicTranslatorMixin_Test", - "SpongeImplHooksMixin_Test" - ] -} From 64d7d46ec930f2e1ef98bb7b6975e9fc0580658e Mon Sep 17 00:00:00 2001 From: Yeregorix Date: Mon, 11 Aug 2025 14:57:27 +0200 Subject: [PATCH 11/11] Cleanup Idea-Ext plugin configuration --- build.gradle.kts | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 19455e530d5..905da3c316d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,6 @@ +import org.jetbrains.gradle.ext.compiler +import org.jetbrains.gradle.ext.delegateActions +import org.jetbrains.gradle.ext.settings import org.spongepowered.gradle.vanilla.task.DecompileJarTask import java.util.Locale @@ -178,6 +181,20 @@ minecraft { accessWideners(main.resources.filter { it.name.endsWith(".accesswidener") }) } +idea { + project.settings { + delegateActions { + delegateBuildRunToGradle = false + testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.GRADLE + } + compiler { + addNotNullAssertions = false + useReleaseOption = true + parallelCompilation = true + } + } +} + allprojects { configurations.configureEach { resolutionStrategy.dependencySubstitution { @@ -188,7 +205,6 @@ allprojects { } } - apply(plugin = "org.jetbrains.gradle.plugin.idea-ext") apply(plugin = "java-library") apply(plugin = "maven-publish") apply(plugin = "net.kyori.indra.licenser.spotless") @@ -212,22 +228,6 @@ allprojects { } } - idea { - if (project != null) { - (project as ExtensionAware).extensions["settings"].run { - (this as ExtensionAware).extensions.getByType(org.jetbrains.gradle.ext.ActionDelegationConfig::class).run { - delegateBuildRunToGradle = false - testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.PLATFORM - } - extensions.getByType(org.jetbrains.gradle.ext.IdeaCompilerConfiguration::class).run { - addNotNullAssertions = false - useReleaseOption = JavaVersion.current().isJava10Compatible - parallelCompilation = true - } - } - } - } - java { val targetJavaVersion = JavaVersion.toVersion(apiJavaTarget.toInt()) sourceCompatibility = targetJavaVersion @@ -272,14 +272,10 @@ allprojects { val spongeSnapshotRepo: String? by project val spongeReleaseRepo: String? by project tasks { - val emptyAnnotationProcessors = objects.fileCollection() withType(JavaCompile::class).configureEach { options.compilerArgs.addAll(listOf("-Xmaxerrs", "1000")) options.encoding = "UTF-8" options.release.set(apiJavaTarget.toInt()) - if (project.name != "testplugins" && System.getProperty("idea.sync.active") != null) { - options.annotationProcessorPath = emptyAnnotationProcessors // hack so IntelliJ doesn't try to run Mixin AP - } } withType(PublishToMavenRepository::class).configureEach {