Add basic api for event integration, + basic held tests

This commit is contained in:
themode 2022-01-27 13:08:42 +01:00
parent 5e0340c9d8
commit dbcb21d1aa
5 changed files with 101 additions and 5 deletions

View File

@ -18,4 +18,10 @@ public interface Collector<T> {
assertInstanceOf(type, element, "Expected type " + type.getSimpleName() + ", got " + element.getClass().getSimpleName());
consumer.accept((P) element);
}
default void assertSingle(@NotNull Consumer<T> consumer) {
List<T> elements = collect();
assertEquals(1, elements.size(), "Expected 1 element, got " + elements);
consumer.accept(elements.get(0));
}
}

View File

@ -3,6 +3,8 @@ package net.minestom.server.api;
import net.minestom.server.ServerProcess;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventFilter;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.ChunkGenerator;
import net.minestom.server.instance.ChunkPopulator;
@ -20,6 +22,8 @@ public interface Env {
@NotNull TestConnection createConnection();
<E extends Event, H> @NotNull Collector<E> trackEvent(@NotNull Class<E> eventType, @NotNull EventFilter<? super E, H> filter, @NotNull H actor);
default void tick() {
process().ticker().tick(System.nanoTime());
}

View File

@ -1,8 +1,14 @@
package net.minestom.server.api;
import net.minestom.server.ServerProcess;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventFilter;
import net.minestom.server.event.EventNode;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
final class EnvImpl implements Env {
private final ServerProcess process;
@ -19,4 +25,27 @@ final class EnvImpl implements Env {
public @NotNull TestConnection createConnection() {
return new TestConnectionImpl(this);
}
@Override
public @NotNull <E extends Event, H> Collector<E> trackEvent(@NotNull Class<E> eventType, @NotNull EventFilter<? super E, H> filter, @NotNull H actor) {
var tracker = new EventCollector<E>(actor);
var node = EventNode.type("tracker", filter).addListener(eventType, tracker.events::add);
process.eventHandler().map(node, actor);
return tracker;
}
final class EventCollector<E extends Event> implements Collector<E> {
private final Object handler;
private final List<E> events = new CopyOnWriteArrayList<>();
public EventCollector(Object handler) {
this.handler = handler;
}
@Override
public @NotNull List<E> collect() {
process.eventHandler().unmap(handler);
return List.copyOf(events);
}
}
}

View File

@ -25,7 +25,7 @@ final class TestConnectionImpl implements TestConnection {
private final ServerProcess process;
private final PlayerConnectionImpl playerConnection = new PlayerConnectionImpl();
private final List<TrackerImpl<ServerPacket>> incomingTrackers = new CopyOnWriteArrayList<>();
private final List<IncomingCollector<ServerPacket>> incomingTrackers = new CopyOnWriteArrayList<>();
public TestConnectionImpl(Env env) {
this.env = env;
@ -57,8 +57,8 @@ final class TestConnectionImpl implements TestConnection {
@Override
public @NotNull <T extends ServerPacket> Collector<T> trackIncoming(@NotNull Class<T> type) {
var tracker = new TrackerImpl<>(type);
this.incomingTrackers.add(TrackerImpl.class.cast(tracker));
var tracker = new IncomingCollector<>(type);
this.incomingTrackers.add(IncomingCollector.class.cast(tracker));
return tracker;
}
@ -82,11 +82,11 @@ final class TestConnectionImpl implements TestConnection {
}
}
final class TrackerImpl<T extends ServerPacket> implements Collector<T> {
final class IncomingCollector<T extends ServerPacket> implements Collector<T> {
private final Class<T> type;
private final List<T> packets = new CopyOnWriteArrayList<>();
public TrackerImpl(Class<T> type) {
public IncomingCollector(Class<T> type) {
this.type = type;
}

View File

@ -0,0 +1,57 @@
package net.minestom.server.entity;
import net.minestom.server.api.Env;
import net.minestom.server.api.EnvTest;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.event.EventFilter;
import net.minestom.server.event.player.PlayerChangeHeldSlotEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.client.play.ClientHeldItemChangePacket;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@EnvTest
public class PlayerHeldIntegrationTest {
@Test
public void playerHeld(Env env) {
var instance = env.createFlatInstance();
var connection = env.createConnection();
var player = connection.connect(instance, new Pos(0, 40, 0)).join();
player.getInventory().setItemStack(1, ItemStack.of(Material.STONE));
assertEquals(ItemStack.AIR, player.getItemInMainHand());
assertEquals(0, player.getHeldSlot());
player.addPacketToQueue(new ClientHeldItemChangePacket((short) 1));
env.tick();
assertEquals(ItemStack.of(Material.STONE), player.getItemInMainHand());
assertEquals(1, player.getHeldSlot());
}
@Test
public void playerHeldEvent(Env env) {
var instance = env.createFlatInstance();
var connection = env.createConnection();
var player = connection.connect(instance, new Pos(0, 40, 0)).join();
player.getInventory().setItemStack(1, ItemStack.of(Material.STONE));
assertEquals(ItemStack.AIR, player.getItemInMainHand());
assertEquals(0, player.getHeldSlot());
player.addPacketToQueue(new ClientHeldItemChangePacket((short) 1));
var tracker = env.trackEvent(PlayerChangeHeldSlotEvent.class, EventFilter.PLAYER, player);
env.tick();
tracker.assertSingle(event -> {
assertEquals(player, event.getPlayer());
assertEquals(1, event.getSlot());
});
assertEquals(ItemStack.of(Material.STONE), player.getItemInMainHand());
assertEquals(1, player.getHeldSlot());
}
}