test: add @RegistriesTest annotation & enforce naming scheme (#3322)

* test: add @RegistriesTest annotation for vanilla registries snapshot

Adds RegistriesTest/RegistriesTestExt to the testing module providing a shared Registries.vanilla() snapshot, which will become immutable in the future, so tests that only need registry data do not require the server process. Converts the eligible tests and renames init tests to the *IntegrationTest suffix.

Documents the naming scheme in CONTRIBUTING.md.

* fix: SocketRead/Write should be integration tests
This commit is contained in:
Kerman 2026-08-03 15:55:23 -05:00 committed by GitHub
parent a623b29be9
commit 4b4b260314
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 346 additions and 157 deletions

View file

@ -18,6 +18,15 @@
#### **Do you want to contribute to the Minestom documentation?**
* Feel free to do so! Just make sure to conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification when editing the README.md.
#### **Naming Tests**
* Plain unit tests are `*Test`.
* Tests using the `@RegistriesTest` registry snapshot are `*RegistriesTest`.
* Tests using the `@EnvTest` server are `*IntegrationTest`.
* Prefer the lightest fixture that covers the behavior, and make sure your test class passes when run alone. The `testNamingCheck` task enforces the naming as part of `check`.
## General Contribution Rules
* By contributing to the Minestom project your code/contribution will be licensed under the [Apache Version 2.0](../LICENSE) license.

View file

@ -0,0 +1,64 @@
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileType
import org.gradle.api.tasks.*
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
/**
* Enforces the test naming scheme:
*
* - Classes declaring `@EnvTest` are named `*IntegrationTest`.
* - Classes declaring `@RegistriesTest` are named `*RegistriesTest` and never use the `*IntegrationTest` suffix.
* - The `*IntegrationTest` and `*RegistriesTest` suffixes are reserved for classes declaring the matching fixture.
*
* Classes are judged by their own declarations only; an inherited fixture annotation does not constrain the
* subclass name.
*/
abstract class CheckTestNamingTask : DefaultTask() {
private companion object {
val ENV_TEST = Regex("(?m)^@EnvTest\\b")
val REGISTRY_TEST = Regex("(?m)^@RegistriesTest\\b")
}
@get:Incremental
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val sources: ConfigurableFileCollection
init {
// No file output, the check result itself is the outcome
outputs.upToDateWhen { true }
}
@TaskAction
fun run(inputChanges: InputChanges) {
val violations = mutableListOf<String>()
for (change in inputChanges.getFileChanges(sources)) {
if (change.changeType == ChangeType.REMOVED) continue
if (change.fileType != FileType.FILE || !change.file.name.endsWith(".java")) continue
val name = change.file.name.removeSuffix(".java")
val source = change.file.readText()
val env = ENV_TEST.containsMatchIn(source)
val registry = REGISTRY_TEST.containsMatchIn(source)
if (env && !name.endsWith("IntegrationTest"))
violations += "$name: @EnvTest classes must be named *IntegrationTest"
if (registry && name.endsWith("IntegrationTest"))
violations += "$name: *IntegrationTest is reserved for @EnvTest classes"
if (registry && !name.endsWith("RegistriesTest"))
violations += "$name: @RegistriesTest classes must be named *RegistriesTest"
if (!env && name.endsWith("IntegrationTest"))
violations += "$name: *IntegrationTest requires a declared @EnvTest"
if (!registry && name.endsWith("RegistriesTest"))
violations += "$name: *RegistriesTest requires a declared @RegistriesTest"
}
if (violations.isNotEmpty()) {
throw GradleException("Test naming violations:\n" + violations.joinToString("\n"))
}
}
}

View file

@ -140,6 +140,12 @@ tasks.register("errorproneCheck") {
dependsOn(tasks.withType<JavaCompile>())
}
tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) {
dependsOn("errorproneCheck", "forbiddenImportsCheck")
tasks.register<CheckTestNamingTask>("testNamingCheck") {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Checks that test classes are named after their declared fixture."
sources.from(project.extensions.getByType<SourceSetContainer>().named("test").map { it.allJava })
}
tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME) {
dependsOn("errorproneCheck", "forbiddenImportsCheck", "testNamingCheck")
}

View file

@ -1,13 +1,11 @@
package net.minestom.server.command;
import net.minestom.server.command.builder.Command;
import net.minestom.testing.EnvTest;
import org.junit.jupiter.api.Test;
import static net.minestom.server.command.builder.arguments.ArgumentType.*;
import static org.junit.jupiter.api.Assertions.*;
@EnvTest
public class CommandSuggestionSubcommandTest {
/**

View file

@ -1,25 +1,24 @@
package net.minestom.server.component;
import net.kyori.adventure.key.Key;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@EnvTest
public class DataComponentTest {
@RegistriesTest
public class DataComponentLookupRegistriesTest {
@Test
public void registry(Env env) { // Tricky registry; so we ensure they are loaded (requires class loading before accessible keys)
public void registry() { // Tricky registry; so we ensure they are loaded (requires class loading before accessible keys)
Assertions.assertNotNull(DataComponent.fromKey(Key.key("lore")), "Registry class was not initialized");
}
@Test
public void stringFromKey(Env env) {
public void stringFromKey() {
Assertions.assertSame(DataComponent.fromKey("lore"), DataComponent.fromKey(Key.key("lore")));
}
@Test
public void testStatic(Env env) {
public void testStatic() {
Assertions.assertSame(DataComponents.LORE, DataComponent.fromKey("lore"));
}
}

View file

@ -20,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest
public class EntityAttributeTest {
public class EntityAttributeIntegrationTest {
@Test
public void testEntityUpdatesAttributes(Env env) {

View file

@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.jupiter.api.Assertions.*;
@EnvTest
public class EntityFireTest
public class EntityFireIntegrationTest
{
@Test
public void duration(Env env) {

View file

@ -2,18 +2,16 @@ package net.minestom.server.entity;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.Registries;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@EnvTest
public class MetadataIntegrationTest {
@RegistriesTest
public class MetadataRegistriesTest {
@Test
public void registeredTypesRoundTripDefaultEntries(Env env) {
final Registries registries = env.process();
public void registeredTypesRoundTripDefaultEntries(Registries registries) {
for (int id = 0; id < Metadata.typeCount(); id++) {
final Metadata.Type<?> type = Metadata.typeById(id);
assertNotNull(type, "Missing metadata type definition for id " + id);

View file

@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@EnvTest
public class PlayerSprintingMetadataTest {
public class PlayerSprintingMetadataIntegrationTest {
@Test
public void sprintingMetadata(Env env) {

View file

@ -12,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@EnvTest
public class ClosestEntityTargetTest {
public class ClosestEntityTargetIntegrationTest {
@Test
public void validFindTarget(Env env) {

View file

@ -6,6 +6,7 @@ import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.PlayerHand;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.BlockKeys;
import net.minestom.server.instance.block.predicate.BlockPredicate;
import net.minestom.server.instance.block.predicate.PropertiesPredicate;
import net.minestom.server.item.ItemStack;
@ -54,7 +55,7 @@ public class PlayerBlockPlacementIntegrationTest {
return Stream.of(
Arguments.of(Block.ACACIA_STAIRS.withProperty("facing", "south"), new BlockPredicates(new BlockPredicate(Block.ACACIA_STAIRS))),
Arguments.of(Block.ACACIA_STAIRS.withProperty("facing", "south"),
new BlockPredicates(new BlockPredicate(RegistryTag.direct(Block.ACACIA_STAIRS.registryKey()),
new BlockPredicates(new BlockPredicate(RegistryTag.direct(BlockKeys.ACACIA_STAIRS),
PropertiesPredicate.exact("facing", "south"), null))),
Arguments.of(Block.AMETHYST_BLOCK, new BlockPredicates(new BlockPredicate(Block.AMETHYST_BLOCK)))
);

View file

@ -12,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@EnvTest
public class WeatherTest {
public class WeatherIntegrationTest {
@Test
public void weatherTest(Env env) {
var instance = env.createFlatInstance();

View file

@ -23,6 +23,7 @@ import net.minestom.server.item.component.*;
import net.minestom.server.item.enchant.Enchantment;
import net.minestom.server.item.predicate.ItemPredicate;
import net.minestom.server.potion.PotionType;
import net.minestom.server.potion.PotionTypeKeys;
import net.minestom.server.registry.RegistryTag;
import net.minestom.server.utils.Range;
import org.jetbrains.annotations.Nullable;
@ -147,9 +148,7 @@ public class DataComponentPredicateTest {
@Test
void testPotionContents() {
var potions = new DataComponentPredicate.Potions(RegistryTag.direct(
PotionType.FIRE_RESISTANCE.registryKey(),
PotionType.HEALING.registryKey(),
PotionType.HARMING.registryKey()));
PotionTypeKeys.FIRE_RESISTANCE, PotionTypeKeys.HEALING, PotionTypeKeys.HARMING));
assertPass(potions, DataComponents.POTION_CONTENTS, new PotionContents(PotionType.HEALING));
assertFail(potions, DataComponents.POTION_CONTENTS, new PotionContents(PotionType.STRENGTH)); // Potion type isn't contained in the predicate's list
assertFail(potions, DataComponents.POTION_CONTENTS, new PotionContents(null, null, List.of(), null));

View file

@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@EnvTest
public class InventoryCloseStateTest {
public class InventoryCloseStateIntegrationTest {
@Test

View file

@ -15,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
@EnvTest
public class PlayerCreativeSlotTest {
public class PlayerCreativeSlotIntegrationTest {
@Test
public void testCreativeSlots(Env env) {

View file

@ -6,11 +6,11 @@ import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.component.DataComponent;
import net.minestom.server.component.DataComponents;
import net.minestom.server.entity.EntityType;
import net.minestom.server.registry.Registries;
import net.minestom.server.instance.block.jukebox.JukeboxSong;
import net.minestom.server.item.component.EnchantmentList;
import net.minestom.server.item.enchant.Enchantment;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Test;
import java.io.IOException;
@ -20,10 +20,10 @@ import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@EnvTest
public class ItemTest {
@RegistriesTest
public class ItemRegistriesTest {
@Test
public void testFields(Env env) {
public void testFields() {
var item = ItemStack.of(Material.DIAMOND_SWORD);
assertEquals(Material.DIAMOND_SWORD, item.material(), "Material must be the same");
assertEquals(1, item.amount(), "Default item amount must be 1");
@ -48,7 +48,7 @@ public class ItemTest {
}
@Test
public void defaultBuilder(Env env) {
public void defaultBuilder() {
var item = ItemStack.builder(Material.DIAMOND_SWORD).build();
assertEquals(Material.DIAMOND_SWORD, item.material(), "Material must be the same");
assertEquals(1, item.amount(), "Default item amount must be 1");
@ -73,7 +73,7 @@ public class ItemTest {
}
@Test
public void testEquality(Env env) {
public void testEquality() {
var item1 = ItemStack.of(Material.DIAMOND_SWORD);
var item2 = ItemStack.of(Material.DIAMOND_SWORD);
assertEquals(item1, item2);
@ -85,7 +85,7 @@ public class ItemTest {
}
@Test
public void testEqualityComponents(Env env) {
public void testEqualityComponents() {
var item1 = ItemStack.of(Material.MUSIC_DISC_STAL);
var item2 = ItemStack.of(Material.MUSIC_DISC_STAL).with(DataComponents.JUKEBOX_PLAYABLE, JukeboxSong.STAL);
assertTrue(item1.isSimilar(item2));
@ -93,17 +93,17 @@ public class ItemTest {
@Test
@SuppressWarnings("deprecation") // deliberately keeps coverage of the deprecated API until its removal
public void testFromNbtLoreSpace(Env env) throws IOException {
public void testFromNbtLoreSpace(Registries registries) throws IOException {
var itemStack = ItemStack.of(Material.LAPIS_BLOCK)
.withLore(Component.text("Hey!", NamedTextColor.RED), Component.empty(), Component.text("hello"))
.with(DataComponents.ITEM_MODEL, "unknown");
var tagOut = MinestomAdventure.tagStringIO().asString(itemStack.toItemNBT());
var tagOut = MinestomAdventure.tagStringIO().asString(itemStack.toItemNBT(registries));
var tagIn = MinestomAdventure.tagStringIO().asCompound(tagOut);
assertEquals(itemStack, ItemStack.fromItemNBT(tagIn));
assertEquals(itemStack, ItemStack.fromItemNBT(tagIn, registries));
}
@Test
public void testImmutableLore(Env env) {
public void testImmutableLore() {
List<Component> lore = new ArrayList<>();
lore.add(Component.text("Hey!"));
var itemStack = ItemStack.of(Material.LAPIS_BLOCK).withLore(lore);
@ -114,7 +114,7 @@ public class ItemTest {
}
@Test
public void testBuilderImmutableLore(Env env) {
public void testBuilderImmutableLore() {
List<Component> lore = new ArrayList<>();
lore.add(Component.text("Hey!"));
var itemStack = ItemStack.builder(Material.LAPIS_BLOCK).lore(lore).build();
@ -126,15 +126,15 @@ public class ItemTest {
@Test
@SuppressWarnings("deprecation") // deliberately keeps coverage of the deprecated API until its removal
public void testFromNbt(Env env) {
var itemNbt = createItem().toItemNBT();
var item = ItemStack.fromItemNBT(itemNbt);
public void testFromNbt(Registries registries) {
var itemNbt = createItem().toItemNBT(registries);
var item = ItemStack.fromItemNBT(itemNbt, registries);
assertEquals(createItem(), item, "Items must be equal if created from the same item nbt");
assertEquals(itemNbt, item.toItemNBT(), "Item nbt must be equal back");
assertEquals(itemNbt, item.toItemNBT(registries), "Item nbt must be equal back");
}
@Test
public void testBuilderReuse(Env env) {
public void testBuilderReuse() {
var builder = ItemStack.builder(Material.DIAMOND);
var item1 = builder.build();
var item2 = builder.set(DataComponents.CUSTOM_NAME, Component.text("Name")).build();
@ -145,7 +145,7 @@ public class ItemTest {
@Test
@SuppressWarnings("deprecation") // deliberately keeps coverage of the deprecated API until its removal
public void materialUpdate(Env env) {
public void materialUpdate(Registries registries) {
var item1 = ItemStack.builder(Material.DIAMOND)
.amount(5).set(DataComponents.CUSTOM_NAME, Component.text("Name"))
.build();
@ -154,8 +154,8 @@ public class ItemTest {
assertEquals(Material.DIAMOND, item1.material());
assertEquals(Material.GOLD_INGOT, item2.material());
var nbt1 = item1.toItemNBT().remove("id");
var nbt2 = item2.toItemNBT().remove("id");
var nbt1 = item1.toItemNBT(registries).remove("id");
var nbt2 = item2.toItemNBT(registries).remove("id");
assertEquals(nbt1, nbt2);
assertEquals(5, item1.amount());
@ -174,9 +174,9 @@ public class ItemTest {
@SuppressWarnings("removal")
public void testEntityType() {
var item1 = ItemStack.of(Material.DIAMOND, 1);
assertNull(item1.material().prototype().get(DataComponents.ENTITY_DATA));
assertNull(item1.get(DataComponents.ENTITY_DATA));
var item2 = ItemStack.of(Material.CAMEL_SPAWN_EGG, 1);
var entityData = item2.material().prototype().get(DataComponents.ENTITY_DATA);
var entityData = item2.get(DataComponents.ENTITY_DATA);
assertNotNull(entityData);
assertEquals(EntityType.CAMEL, entityData.type());
}

View file

@ -1,8 +1,7 @@
package net.minestom.server.item;
import net.minestom.server.component.DataComponents;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -11,11 +10,11 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest
public class ItemStackTest {
@RegistriesTest
public class ItemStackRegistriesTest {
@Test
void resetRevertsToMaterialDefault(Env env) {
void resetRevertsToMaterialDefault() {
ItemStack apple = ItemStack.of(Material.APPLE).without(DataComponents.FOOD);
assertFalse(apple.has(DataComponents.FOOD));
@ -24,7 +23,7 @@ public class ItemStackTest {
}
@Test
void componentsReturnsResolvedView(Env env) {
void componentsReturnsResolvedView() {
ItemStack item = ItemStack.of(Material.APPLE)
.without(DataComponents.FOOD)
.with(DataComponents.REPAIR_COST, 5);

View file

@ -1,16 +1,15 @@
package net.minestom.server.item;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@EnvTest
public class MaterialIntegrationTest {
@RegistriesTest
public class MaterialRegistriesTest {
@Test
void loadAllMaterials(Env env) {
void loadAllMaterials() {
// Materials are lazy loaded now so this is a sanity check that they all load
for (Material material : Material.values()) {
// Just loading the material should be enough to test that it exists

View file

@ -3,9 +3,9 @@ package net.minestom.server.item.component;
import net.minestom.server.codec.Transcoder;
import net.minestom.server.component.DataComponent;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.RegistryTranscoder;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@ -19,9 +19,9 @@ import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@EnvTest
@RegistriesTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class AbstractItemComponentTest<T> {
public abstract class AbstractItemComponentRegistriesTest<T> {
protected abstract DataComponent<T> component();
@ -33,8 +33,8 @@ public abstract class AbstractItemComponentTest<T> {
@ParameterizedTest(name = "{0}")
@MethodSource("directReadWriteMethodSource")
public void directReadWriteTest(String testName, T entry, Env env) {
var coder = new RegistryTranscoder<>(Transcoder.NBT, env.process());
public void directReadWriteTest(String testName, T entry, Registries registries) {
var coder = new RegistryTranscoder<>(Transcoder.NBT, registries);
if (component().isSerialized()) {
var written1 = assertOk(component().encode(coder, entry));
@ -46,13 +46,13 @@ public abstract class AbstractItemComponentTest<T> {
}
if (component().isSynced()) {
var written1 = NetworkBuffer.makeArray(b -> component().write(b, entry), env.process());
var written1 = NetworkBuffer.makeArray(b -> component().write(b, entry), registries);
var buffer = NetworkBuffer.wrap(written1, 0, written1.length, env.process());
var buffer = NetworkBuffer.wrap(written1, 0, written1.length, registries);
var read = component().read(buffer);
assertEquals(entry, read);
var written2 = NetworkBuffer.makeArray(b -> component().write(b, entry), env.process());
var written2 = NetworkBuffer.makeArray(b -> component().write(b, entry), registries);
assertArrayEquals(written1, written2);
}
}

View file

@ -11,7 +11,7 @@ import static java.util.Map.entry;
import net.minestom.server.entity.EntityType;
public class BeesTest extends AbstractItemComponentTest<List<Bee>> {
public class BeesTest extends AbstractItemComponentRegistriesTest<List<Bee>> {
private static final TypedCustomData<EntityType> SOME_DATA = new TypedCustomData<>(
EntityType.BEE, CompoundBinaryTag.empty()
);

View file

@ -8,6 +8,7 @@ import net.minestom.server.component.DataComponent;
import net.minestom.server.component.DataComponentMap;
import net.minestom.server.component.DataComponents;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockKeys;
import net.minestom.server.instance.block.predicate.BlockPredicate;
import net.minestom.server.instance.block.predicate.ComponentPredicateSet;
import net.minestom.server.instance.block.predicate.DataComponentPredicate;
@ -25,7 +26,7 @@ import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class BlockPredicatesTest extends AbstractItemComponentTest<BlockPredicates> {
public class BlockPredicatesTest extends AbstractItemComponentRegistriesTest<BlockPredicates> {
@Override
protected DataComponent<@NotNull BlockPredicates> component() {
@ -53,7 +54,7 @@ public class BlockPredicatesTest extends AbstractItemComponentTest<BlockPredicat
var expected = new BlockPredicates(new BlockPredicate(RegistryTag.direct(RegistryKey.unsafeOf("minecraft:stone"))));
assertEquals(expected, component);
assertEquals(1, component.predicates().getFirst().blocks().size());
assertTrue(component.predicates().getFirst().blocks().contains(Block.STONE.registryKey()));
assertTrue(component.predicates().getFirst().blocks().contains(BlockKeys.STONE));
}
@Test

View file

@ -18,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest
public class BlocksAttacksTest {
public class BlocksAttacksIntegrationTest {
@Test
public void test(Env env) {

View file

@ -8,7 +8,7 @@ import java.util.Map;
import static java.util.Map.entry;
public class BoolTest extends AbstractItemComponentTest<Boolean> {
public class BoolTest extends AbstractItemComponentRegistriesTest<Boolean> {
// This is not a test, but it creates a compile error if the component type is changed away from boolean,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<Boolean>> SHARED_COMPONENTS = List.of(

View file

@ -16,7 +16,7 @@ import static java.util.Map.entry;
import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ColorTest extends AbstractItemComponentTest<RGBLike> {
public class ColorTest extends AbstractItemComponentRegistriesTest<RGBLike> {
// This is not a test, but it creates a compile error if the component type is changed away from Integer,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<RGBLike>> SHARED_COMPONENTS = List.of(

View file

@ -12,7 +12,7 @@ import java.util.Map;
import static net.minestom.server.codec.CodecAssertions.assertOk;
public class ComponentTest extends AbstractItemComponentTest<Component> {
public class ComponentTest extends AbstractItemComponentRegistriesTest<Component> {
// This is not a test, but it creates a compile error if the component type is changed away from Component,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<Component>> SHARED_COMPONENTS = List.of(

View file

@ -18,7 +18,7 @@ import java.util.Map;
import static java.util.Map.entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CustomDataTest extends AbstractItemComponentTest<CustomData> {
public class CustomDataTest extends AbstractItemComponentRegistriesTest<CustomData> {
// This is not a test, but it creates a compile error if the component type is changed away,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<CustomData>> SHARED_COMPONENTS = List.of(

View file

@ -8,7 +8,7 @@ import java.util.Map;
import static java.util.Map.entry;
public class DebugStickStateTest extends AbstractItemComponentTest<DebugStickState> {
public class DebugStickStateTest extends AbstractItemComponentRegistriesTest<DebugStickState> {
@Override
protected DataComponent<DebugStickState> component() {

View file

@ -5,8 +5,8 @@ import net.minestom.server.codec.Transcoder;
import net.minestom.server.component.DataComponent;
import net.minestom.server.component.DataComponents;
import net.minestom.server.item.enchant.Enchantment;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.RegistryTranscoder;
import net.minestom.testing.Env;
import org.junit.jupiter.api.Test;
import java.util.List;
@ -15,7 +15,7 @@ import java.util.Map;
import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class EnchantmentListTest extends AbstractItemComponentTest<EnchantmentList> {
public class EnchantmentListTest extends AbstractItemComponentRegistriesTest<EnchantmentList> {
// This is not a test, but it creates a compile error if the component type is changed away from Unit,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<EnchantmentList>> SHARED_COMPONENTS = List.of(
@ -38,14 +38,14 @@ public class EnchantmentListTest extends AbstractItemComponentTest<EnchantmentLi
}
@Test
void testShorthandNbtSyntax(Env env) throws Exception {
void testShorthandNbtSyntax(Registries registries) throws Exception {
var tag = MinestomAdventure.tagStringIO().asTag("""
{
"sharpness": 1,
"punch": 2,
}
""");
var coder = new RegistryTranscoder<>(Transcoder.NBT, env.process());
var coder = new RegistryTranscoder<>(Transcoder.NBT, registries);
var value = assertOk(component().decode(coder, tag));
assertEquals(new EnchantmentList(Map.of(Enchantment.SHARPNESS, 1, Enchantment.PUNCH, 2)), value);
}

View file

@ -8,7 +8,7 @@ import java.util.Map;
import static java.util.Map.entry;
public class IntTest extends AbstractItemComponentTest<Integer> {
public class IntTest extends AbstractItemComponentRegistriesTest<Integer> {
// This is not a test, but it creates a compile error if the component type is changed away from Integer,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<Integer>> INT_COMPONENTS = List.of(

View file

@ -10,7 +10,7 @@ import net.minestom.server.entity.attribute.AttributeOperation;
import java.util.List;
import java.util.Map;
public class ItemAttributeTest extends AbstractItemComponentTest<AttributeList> {
public class ItemAttributeTest extends AbstractItemComponentRegistriesTest<AttributeList> {
@Override
protected DataComponent<AttributeList> component() {
return DataComponents.ATTRIBUTE_MODIFIERS;

View file

@ -10,8 +10,7 @@ import net.minestom.server.component.DataComponent;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.RegistryTranscoder;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Test;
import java.io.IOException;
@ -25,8 +24,8 @@ import static java.util.Map.entry;
import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.*;
@EnvTest
public class ItemComponentReadWriteIntegrationTest {
@RegistriesTest
public class ItemComponentReadWriteRegistriesTest {
private static final Gson GSON = new Gson();
// This test will go through all of the default components present on vanilla items and make sure that we are
@ -41,7 +40,7 @@ public class ItemComponentReadWriteIntegrationTest {
@Test
@SuppressWarnings("unchecked")
public void testReadWrite(Env env) throws IOException {
public void testReadWrite(Registries registries) throws IOException {
var componentEntries = new ArrayList<>(EXTRA_CASES.entrySet());
try (InputStream is = MinestomData.resource("item.json")) {
Objects.requireNonNull(is, "item.json not found");
@ -57,7 +56,7 @@ public class ItemComponentReadWriteIntegrationTest {
assertAll(componentEntries.stream().map(entry -> () -> {
var component = DataComponent.fromKey(entry.getKey());
assertNotNull(component, "Component not found: " + entry.getKey());
readWriteTestImpl((DataComponent<Object>) component, entry.getValue(), env.process());
readWriteTestImpl((DataComponent<Object>) component, entry.getValue(), registries);
}));
}

View file

@ -12,7 +12,7 @@ import static net.kyori.adventure.nbt.StringBinaryTag.stringBinaryTag;
import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ItemRarityTest extends AbstractItemComponentTest<ItemRarity> {
public class ItemRarityTest extends AbstractItemComponentRegistriesTest<ItemRarity> {
@Override
protected DataComponent<ItemRarity> component() {
return DataComponents.RARITY;

View file

@ -7,7 +7,7 @@ import net.minestom.server.coordinate.Vec;
import java.util.List;
import java.util.Map;
public class LodestoneTrackerTest extends AbstractItemComponentTest<LodestoneTracker> {
public class LodestoneTrackerTest extends AbstractItemComponentRegistriesTest<LodestoneTracker> {
@Override
protected DataComponent<LodestoneTracker> component() {

View file

@ -6,7 +6,7 @@ import net.minestom.server.component.DataComponents;
import java.util.List;
import java.util.Map;
public class MapDecorationsTest extends AbstractItemComponentTest<MapDecorations> {
public class MapDecorationsTest extends AbstractItemComponentRegistriesTest<MapDecorations> {
@Override
protected DataComponent<MapDecorations> component() {

View file

@ -6,7 +6,7 @@ import net.minestom.server.component.DataComponents;
import java.util.List;
import java.util.Map;
public class MapPostProcessingTest extends AbstractItemComponentTest<MapPostProcessing> {
public class MapPostProcessingTest extends AbstractItemComponentRegistriesTest<MapPostProcessing> {
@Override
protected DataComponent<MapPostProcessing> component() {
return DataComponents.MAP_POST_PROCESSING;

View file

@ -7,7 +7,7 @@ import net.minestom.server.item.Material;
import java.util.List;
import java.util.Map;
public class PotDecorationsTest extends AbstractItemComponentTest<PotDecorations> {
public class PotDecorationsTest extends AbstractItemComponentRegistriesTest<PotDecorations> {
@Override
protected DataComponent<PotDecorations> component() {
return DataComponents.POT_DECORATIONS;

View file

@ -16,7 +16,7 @@ import java.util.Map;
import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PotionContentsTest extends AbstractItemComponentTest<PotionContents> {
public class PotionContentsTest extends AbstractItemComponentRegistriesTest<PotionContents> {
@Override
protected DataComponent<PotionContents> component() {

View file

@ -6,7 +6,7 @@ import net.minestom.server.component.DataComponents;
import java.util.List;
import java.util.Map;
public class SeededContainerLootTest extends AbstractItemComponentTest<SeededContainerLoot> {
public class SeededContainerLootTest extends AbstractItemComponentRegistriesTest<SeededContainerLoot> {
@Override
protected DataComponent<SeededContainerLoot> component() {

View file

@ -8,7 +8,7 @@ import java.util.Map;
import static java.util.Map.entry;
public class StringTest extends AbstractItemComponentTest<String> {
public class StringTest extends AbstractItemComponentRegistriesTest<String> {
// This is not a test, but it creates a compile error if the component type is changed away,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<String>> SHARED_COMPONENTS = List.of(

View file

@ -13,7 +13,7 @@ import java.util.Map;
import static net.minestom.server.codec.CodecAssertions.assertOk;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SuspiciousStewEffectsTest extends AbstractItemComponentTest<SuspiciousStewEffects> {
public class SuspiciousStewEffectsTest extends AbstractItemComponentRegistriesTest<SuspiciousStewEffects> {
@Override
protected DataComponent<SuspiciousStewEffects> component() {

View file

@ -3,8 +3,8 @@ package net.minestom.server.item.component;
import net.minestom.server.component.DataComponent;
import net.minestom.server.component.DataComponents;
import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.registry.Registries;
import net.minestom.server.utils.Unit;
import net.minestom.testing.Env;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
@ -14,7 +14,7 @@ import java.util.Map;
import static java.util.Map.entry;
import static org.junit.jupiter.api.Assertions.fail;
public class UnitTest extends AbstractItemComponentTest<Unit> {
public class UnitTest extends AbstractItemComponentRegistriesTest<Unit> {
// This is not a test, but it creates a compile error if the component type is changed away from Unit,
// as a reminder that tests should be added for that new component type.
private static final List<DataComponent<Unit>> UNIT_COMPONENTS = List.of(
@ -38,14 +38,15 @@ public class UnitTest extends AbstractItemComponentTest<Unit> {
@Test
@SuppressWarnings("unchecked")
public void ensureUnitComponentsPresent(Env env) {
public void ensureUnitComponentsPresent(Registries registries) {
var fails = new ArrayList<String>();
for (var component : DataComponent.values()) {
if (!component.isSynced()) continue;
// Try to write as a Unit and if it fails we can ignore that type
try {
((DataComponent<Unit>) component).write(NetworkBuffer.resizableBuffer(env.process()), Unit.INSTANCE);
((DataComponent<Unit>) component).write(
NetworkBuffer.resizableBuffer(registries), Unit.INSTANCE);
} catch (ClassCastException | IllegalArgumentException _) {
continue;
}

View file

@ -13,7 +13,7 @@ import net.minestom.testing.EnvTest;
import org.junit.jupiter.api.Test;
@EnvTest
public class PlayerActionListenerTest {
public class PlayerActionListenerIntegrationTest {
@Test
public void testStabInvalidWeapon(Env env) {

View file

@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest
public class UseEntityListenerTest {
public class UseEntityListenerIntegrationTest {
private Player player;
private Entity targetEntity;

View file

@ -19,7 +19,7 @@ import java.util.function.UnaryOperator;
import static org.junit.jupiter.api.Assertions.assertEquals;
@EnvTest
public class TestUseItemListenerIntegration {
public class UseItemListenerIntegrationTest {
@Test
void useItemNonSpecial(Env env) {

View file

@ -2,13 +2,14 @@ package net.minestom.server.network;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.component.DataComponents;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.registry.Registries;
import net.minestom.testing.RegistriesTest;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
@ -29,7 +30,14 @@ import static net.minestom.server.network.NetworkBuffer.*;
import static net.minestom.testing.TestUtils.waitUntilCleared;
import static org.junit.jupiter.api.Assertions.*;
public class NetworkBufferTest {
@RegistriesTest
public class NetworkBufferRegistriesTest {
private static Registries registries;
@BeforeAll
static void bindRegistries(Registries registries) {
NetworkBufferRegistriesTest.registries = registries;
}
@Test
public void resize() {
@ -440,8 +448,7 @@ public class NetworkBufferTest {
}
@Test
public void sliceRegistries() {
var registries = Registries.vanilla();
public void sliceRegistries(Registries registries) {
var buffer = NetworkBuffer.staticBuffer(16, registries);
var slice = buffer.slice(0, 16, 0, 16);
@ -833,7 +840,7 @@ public class NetworkBufferTest {
}
static <T> void assertBufferType(NetworkBuffer.Type<T> type, @UnknownNullability T value, byte[] expected, Action<T> action) {
var buffer = NetworkBuffer.resizableBuffer(MinecraftServer.getRegistries());
var buffer = NetworkBuffer.resizableBuffer(registries);
action.write(buffer, type, value);
assertEquals(0, buffer.readIndex());
if (expected != null) assertEquals(expected.length, buffer.writeIndex());
@ -902,7 +909,7 @@ public class NetworkBufferTest {
}
static <T> void assertBufferTypeCollection(NetworkBuffer.Type<T> type, List<T> values, byte @Nullable [] expected) {
var buffer = NetworkBuffer.resizableBuffer(MinecraftServer.getRegistries());
var buffer = NetworkBuffer.resizableBuffer(registries);
buffer.write(type.list(), values);
assertEquals(0, buffer.readIndex());
if (expected != null) assertEquals(expected.length, buffer.writeIndex());

View file

@ -66,6 +66,7 @@ import net.minestom.server.recipe.RecipeBookCategory;
import net.minestom.server.recipe.RecipeProperty;
import net.minestom.server.recipe.display.RecipeDisplay;
import net.minestom.server.recipe.display.SlotDisplay;
import net.minestom.server.registry.Registries;
import net.minestom.server.scoreboard.Sidebar;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.statistic.StatisticCategory;
@ -74,8 +75,7 @@ import net.minestom.server.utils.Rotation;
import net.minestom.server.utils.WeightedList;
import net.minestom.server.world.Difficulty;
import net.minestom.server.world.clock.WorldClock;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@ -91,8 +91,8 @@ import static org.junit.jupiter.api.Assertions.*;
/**
* Ensures that packet can be written and read correctly.
*/
@EnvTest // Some packets require registries.
public class PacketWriteReadTest {
@RegistriesTest
public class PacketWriteReadRegistriesTest {
private static final Map<Class<? extends ServerPacket>, Set<ServerPacket>> SERVER_PACKETS = new HashMap<>();
private static final Map<Class<? extends ClientPacket>, Set<ClientPacket>> CLIENT_PACKETS = new HashMap<>();
@ -120,7 +120,7 @@ public class PacketWriteReadTest {
}
@BeforeAll
public static void setupServer(Env env) {
public static void setupServer(Registries registries) {
// Handshake
// Status
addServerPackets(new ResponsePacket(new JsonObject().toString()));
@ -426,7 +426,8 @@ public class PacketWriteReadTest {
addServerPackets(new ChunkDataPacket(0, 0, new ChunkData(Map.of(), new byte[0], Map.of()), new LightData(new BitSet(), new BitSet(), new BitSet(), new BitSet(), List.of(), List.of())));
addServerPackets(new ChunkBiomesPacket(List.of()), new ChunkBiomesPacket(List.of(new ChunkBiomesPacket.ChunkBiomeData(0, 0, new byte[0]))));
addServerPackets(new CustomChatCompletionPacket(CustomChatCompletionPacket.Action.ADD, List.of("entry1", "entry2")));
addServerPackets(new DamageEventPacket(5, env.process().damageType().getId(DamageType.ARROW), 2, 3, VEC), new DamageEventPacket(50, env.process().damageType().getId(DamageType.WITHER), 0, 0, null));
addServerPackets(new DamageEventPacket(5, registries.damageType().getId(DamageType.ARROW), 2, 3, VEC),
new DamageEventPacket(50, registries.damageType().getId(DamageType.WITHER), 0, 0, null));
addServerPackets(new DeclareCommandsPacket(List.of(), 0));
addServerPackets(new BundlePacket());
addServerPackets(new DebugBlockValuePacket(Vec.ONE, new DebugSubscription.Update<>(DebugSubscription.BEE_HIVES, new DebugHiveInfo(Block.BEEHIVE, 1, 0, true))));
@ -447,12 +448,14 @@ public class PacketWriteReadTest {
addServerPackets(new TestInstanceBlockStatus(Component.text("Minestom is cool"), null), new TestInstanceBlockStatus(Component.text("Where is season 5 william?"), BLOCK_VEC));
addServerPackets(new EntityEffectPacket(0, new Potion(PotionEffect.ABSORPTION, 1, 150)));
addServerPackets(new TrackedWaypointPacket(TrackedWaypointPacket.Operation.UNTRACK, new TrackedWaypointPacket.Waypoint(Either.right("test"), TrackedWaypointPacket.Icon.DEFAULT, new TrackedWaypointPacket.Target.Empty())));
addServerPackets(new GameRuleValuesPacket(Map.of()), new GameRuleValuesPacket(Map.of(Objects.requireNonNull(GameRule.staticRegistry().getKey(GameRule.ADVANCE_TIME)), "false", Objects.requireNonNull(GameRule.staticRegistry().getKey(GameRule.KEEP_INVENTORY)), "false")));
addServerPackets(new GameRuleValuesPacket(Map.of()), new GameRuleValuesPacket(Map.of(
Objects.requireNonNull(registries.gameRule().getKey(GameRule.ADVANCE_TIME)), "false",
Objects.requireNonNull(registries.gameRule().getKey(GameRule.KEEP_INVENTORY)), "false")));
addServerPackets(new LowDiskSpaceWarningPacket());
}
@BeforeAll
public static void setupClient(Env ignored) {
public static void setupClient(Registries registries) {
// Handshake
addClientPackets(
new ClientHandshakePacket(755, "localhost", 25565, ClientHandshakePacket.Intent.LOGIN),
@ -635,12 +638,14 @@ public class PacketWriteReadTest {
addClientPackets(new ClientRecipeBookSeenRecipePacket(0), new ClientRecipeBookSeenRecipePacket(100), new ClientRecipeBookSeenRecipePacket(Integer.MAX_VALUE));
addClientPackets(new ClientSetTestBlockPacket(Vec.ZERO, ClientSetTestBlockPacket.TestBlockMode.START, "test started"), new ClientSetTestBlockPacket(Vec.ONE, ClientSetTestBlockPacket.TestBlockMode.FAIL, "test failed"), new ClientSetTestBlockPacket(Vec.ZERO, ClientSetTestBlockPacket.TestBlockMode.ACCEPT, ""));
addClientPackets(new ClientTestInstanceBlockActionPacket(Vec.ZERO, ClientTestInstanceBlockActionPacket.Action.INIT, new ClientTestInstanceBlockActionPacket.Data("mytest", new Vec(10, 10, 10), 0, false, ClientTestInstanceBlockActionPacket.Status.CLEARED, null)), new ClientTestInstanceBlockActionPacket(Vec.ONE, ClientTestInstanceBlockActionPacket.Action.RUN, new ClientTestInstanceBlockActionPacket.Data(null, new Vec(5, 5, 5), 1, true, ClientTestInstanceBlockActionPacket.Status.RUNNING, Component.text("Error!"))));
addClientPackets(new ClientSetGameRulesPacket(List.of()), new ClientSetGameRulesPacket(List.of(new ClientSetGameRulesPacket.Entry(Objects.requireNonNull(GameRule.staticRegistry().getKey(GameRule.MOB_DROPS)), "false"))));
addClientPackets(new ClientSetGameRulesPacket(List.of()), new ClientSetGameRulesPacket(List.of(
new ClientSetGameRulesPacket.Entry(
Objects.requireNonNull(registries.gameRule().getKey(GameRule.MOB_DROPS)), "false"))));
}
private static <T> void testPacket(NetworkBuffer.Type<T> networkType, T packet, Env env) {
byte[] bytes = NetworkBuffer.makeArray(networkType, packet, env.process());
var buffer = NetworkBuffer.wrap(bytes, 0, bytes.length, env.process()); // Requires for serialization of some packets
private static <T> void testPacket(NetworkBuffer.Type<T> networkType, T packet, Registries registries) {
byte[] bytes = NetworkBuffer.makeArray(networkType, packet, registries);
var buffer = NetworkBuffer.wrap(bytes, 0, bytes.length, registries);
var createdPacket = buffer.read(networkType);
assertEquals(packet, createdPacket);
}
@ -679,13 +684,13 @@ public class PacketWriteReadTest {
@ParameterizedTest(name = "Server Packet Test: {1}")
@MethodSource("serverPacketArguments")
void serverPacket(NetworkBuffer.Type<ServerPacket> serializer, ServerPacket packet, Env env) {
testPacket(serializer, packet, env);
void serverPacket(NetworkBuffer.Type<ServerPacket> serializer, ServerPacket packet, Registries registries) {
testPacket(serializer, packet, registries);
}
@ParameterizedTest(name = "Client Packet Test: {1}")
@MethodSource("clientPacketArguments")
void clientPacket(NetworkBuffer.Type<ClientPacket> serializer, ClientPacket packet, Env env) {
testPacket(serializer, packet, env);
void clientPacket(NetworkBuffer.Type<ClientPacket> serializer, ClientPacket packet, Registries registries) {
testPacket(serializer, packet, registries);
}
}

View file

@ -6,6 +6,10 @@ import net.minestom.server.network.packet.PacketWriting;
import net.minestom.server.network.packet.client.ClientPacket;
import net.minestom.server.network.packet.client.common.ClientPluginMessagePacket;
import net.minestom.server.registry.Registries;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@ -15,7 +19,13 @@ import java.util.zip.DataFormatException;
import static org.junit.jupiter.api.Assertions.*;
public class SocketReadTest {
@EnvTest
public class SocketReadIntegrationTest {
@BeforeAll
public static void setup(Env env) { // PACKET_POOL
Assertions.assertNotNull(env.process().registries());
}
@ParameterizedTest
@ValueSource(booleans = {false, true})

View file

@ -3,6 +3,10 @@ package net.minestom.server.network;
import net.minestom.server.network.packet.PacketVanilla;
import net.minestom.server.network.packet.PacketWriting;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
@ -12,7 +16,13 @@ import static net.minestom.server.network.NetworkBuffer.STRING;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
public class SocketWriteTest {
@EnvTest
public class SocketWriteIntegrationTest {
@BeforeAll
public static void setup(Env env) { // PACKET_POOL
Assertions.assertNotNull(env.process().registries());
}
record IntPacket(int value) implements ServerPacket.Play {
public static final NetworkBuffer.Type<IntPacket> SERIALIZER = NetworkBufferTemplate.template(

View file

@ -1,16 +1,15 @@
package net.minestom.server.registry;
import net.minestom.server.component.DataComponentMap;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@EnvTest
public class RegistriesTest {
@RegistriesTest
public class VanillaRegistriesTest {
@Test
void testMaterialPrototypes() {
var registries = Registries.vanilla();
void testMaterialPrototypes(Registries registries) {
for (var entry : registries.material().values()) {
var prototype = entry.prototype();
Assertions.assertNotNull(prototype);

View file

@ -1,12 +1,15 @@
package net.minestom.server.tag;
import net.kyori.adventure.text.Component;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class TagComponentTest {
@EnvTest
public class TagComponentIntegrationTest {
@Test
public void get() {
@ -25,7 +28,7 @@ public class TagComponentTest {
}
@Test
public void invalidTag() {
public void invalidTag(Env env) {
var tag = Tag.Component("entry");
var handler = TagHandler.newHandler();
handler.setTag(Tag.Integer("entry"), 1);
@ -33,7 +36,7 @@ public class TagComponentTest {
}
@Test
public void nbtFallback() {
public void nbtFallback(Env env) {
var component = Component.text("Hey");
var tag = Tag.Component("component");
var handler = TagHandler.newHandler();

View file

@ -2,6 +2,8 @@ package net.minestom.server.tag;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import org.junit.jupiter.api.Test;
import java.lang.ref.WeakReference;
@ -11,7 +13,8 @@ import static net.minestom.testing.TestUtils.waitUntilCleared;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class TagItemTest {
@EnvTest
public class TagItemIntegrationTest {
@Test
public void get() {
@ -74,7 +77,7 @@ public class TagItemTest {
@Test
@SuppressWarnings("deprecation") // deliberately keeps coverage of the deprecated API until its removal
public void differentTagInvalidation() {
public void differentTagInvalidation(Env env) {
var item = ItemStack.of(Material.DIAMOND);
var item2 = ItemStack.of(Material.DIAMOND, 2);
var handler = TagHandler.newHandler();
@ -96,7 +99,7 @@ public class TagItemTest {
}
@Test
public void snbt() {
public void snbt(Env env) {
var handler = TagHandler.newHandler();
var tag = Tag.ItemStack("item");
handler.setTag(tag, ItemStack.of(Material.DIAMOND));

View file

@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@EnvTest
public class EnvTestPlayerProviderTest {
public class EnvPlayerProviderIntegrationTest {
public static class CustomPlayer extends Player {
public CustomPlayer(PlayerConnection playerConnection, GameProfile gameProfile) {

View file

@ -14,7 +14,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@EnvTest
public class BlockBatchTest {
public class BlockBatchIntegrationTest {
@Test
public void inverseConsumerNotNull(Env env) {

View file

@ -18,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest
public class BlockBreakCalculationTest {
public class BlockBreakCalculationIntegrationTest {
private Player player;
private Runnable assertInstabreak;
private Runnable assertNotQuiteInstabreak;

View file

@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest
public class ChunkUpdateLimitCheckerTest {
public class ChunkUpdateLimitCheckerIntegrationTest {
@Test
public void testHistory(Env env) {

View file

@ -1,35 +1,35 @@
package net.minestom.server.world;
import net.minestom.server.registry.Registries;
import net.minestom.server.world.attribute.EnvironmentAttributeMap;
import net.minestom.server.world.biome.Biome;
import net.minestom.testing.Env;
import net.minestom.testing.EnvTest;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@EnvTest
public class BuilderIntegrationTest {
@RegistriesTest
public class BuilderRegistriesTest {
@Test
public void testBiome(Env env) {
Biome existing = env.process().biome().get(Biome.CHERRY_GROVE);
public void testBiome(Registries registries) {
Biome existing = registries.biome().get(Biome.CHERRY_GROVE);
assertNotNull(existing);
Biome.Builder builder = Biome.builder(existing);
assertEquals(existing, builder.build());
}
@Test
public void testDimensionType(Env env) {
DimensionType existing = env.process().dimensionType().get(DimensionType.THE_NETHER);
public void testDimensionType(Registries registries) {
DimensionType existing = registries.dimensionType().get(DimensionType.THE_NETHER);
assertNotNull(existing);
DimensionType.Builder builder = DimensionType.builder(existing);
assertEquals(existing, builder.build());
}
@Test
public void testEnvironmentAttributeMap(Env env) {
DimensionType existing = env.process().dimensionType().get(DimensionType.OVERWORLD);
public void testEnvironmentAttributeMap(Registries registries) {
DimensionType existing = registries.dimensionType().get(DimensionType.OVERWORLD);
assertNotNull(existing);
EnvironmentAttributeMap.Builder builder = EnvironmentAttributeMap.builder(existing.attributes());
assertEquals(existing.attributes(), builder.build());

View file

@ -0,0 +1,21 @@
package net.minestom.testing;
import net.minestom.server.registry.Registries;
import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Provides a shared, detached vanilla {@link Registries} snapshot to a test class.
* Test and lifecycle methods may declare a {@link Registries} parameter to receive the snapshot.
*/
@Inherited
@ExtendWith(RegistriesTestExt.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RegistriesTest {
}

View file

@ -0,0 +1,33 @@
package net.minestom.testing;
import net.minestom.server.registry.Registries;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolver;
final class RegistriesTestExt implements BeforeAllCallback, ParameterResolver {
private static final ExtensionContext.Namespace NAMESPACE =
ExtensionContext.Namespace.create(RegistriesTestExt.class);
private static final String REGISTRIES_KEY = "minestom.registries";
@Override
public void beforeAll(ExtensionContext context) {
registries(context);
}
@Override
public Registries resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
return registries(extensionContext);
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
return parameterContext.getParameter().getType() == Registries.class;
}
private static Registries registries(ExtensionContext context) {
return context.getRoot().getStore(NAMESPACE).computeIfAbsent(
REGISTRIES_KEY, _ -> Registries.vanilla(), Registries.class);
}
}

View file

@ -0,0 +1,25 @@
package net.minestom.testing.test;
import net.minestom.server.registry.Registries;
import net.minestom.testing.RegistriesTest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
@RegistriesTest
class SnapshotInjectionRegistriesTest {
private static Registries lifecycleRegistries;
@BeforeAll
static void captureRegistries(Registries registries) {
lifecycleRegistries = registries;
}
@Test
void injectsRegistries(Registries registries) {
assertNotNull(registries.biome());
assertSame(lifecycleRegistries, registries);
}
}