mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-23 08:30:34 +00:00
Command Corrections.
This commit is contained in:
1 parent
1e1eaa96aa
commit
b18681a3e2
43 files changed
+1227
-251
No files matched your search
+178
@@ -0,0 +1,178 @@
|
||||
package art.arcane.iris.command;
|
||||
|
||||
import art.arcane.iris.Iris;
|
||||
import art.arcane.iris.generation.hydrology.HydrologyFeatureType;
|
||||
import art.arcane.iris.generation.runtime.Engine;
|
||||
import art.arcane.iris.generation.runtime.IrisComplex;
|
||||
import art.arcane.iris.localization.IrisLanguage;
|
||||
import art.arcane.iris.platform.bukkit.BukkitPlatform;
|
||||
import art.arcane.iris.platform.bukkit.plugin.VolmitSender;
|
||||
import art.arcane.iris.world.history.GenerationSemanticQueries;
|
||||
import art.arcane.iris.world.task.J;
|
||||
import art.arcane.volmlib.util.director.annotations.Director;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.CALLS_REAL_METHODS;
|
||||
|
||||
public class CommandFindHydrologyTest {
|
||||
@Test
|
||||
public void riverCapturesPlayerStateOnTheOwningThread() throws Exception {
|
||||
assertTrue(CommandFind.class.getMethod("river", String.class, boolean.class)
|
||||
.getAnnotation(Director.class).sync());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void worldChangeDuringSearchDoesNotLoadOrTeleportIntoTheNewWorld() {
|
||||
try (Fixture fixture = new Fixture()) {
|
||||
fixture.command.river("surface", true);
|
||||
when(fixture.player.getWorld()).thenReturn(mock(World.class));
|
||||
fixture.search.get().run();
|
||||
|
||||
fixture.platform.verify(() -> BukkitPlatform.chunkAtAsync(any(World.class), anyInt(), anyInt(), eq(true)), never());
|
||||
fixture.platform.verify(() -> BukkitPlatform.teleportAsync(any(Player.class), any(Location.class)), never());
|
||||
verify(fixture.sender).sendMessage(contains("world changed"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disconnectDuringSearchDoesNotLoadTheDestination() {
|
||||
try (Fixture fixture = new Fixture()) {
|
||||
fixture.command.river("surface", true);
|
||||
when(fixture.player.isOnline()).thenReturn(false);
|
||||
fixture.search.get().run();
|
||||
|
||||
fixture.platform.verify(() -> BukkitPlatform.chunkAtAsync(any(World.class), anyInt(), anyInt(), eq(true)), never());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void worldChangeWhileLoadingTheDestinationCancelsTeleport() {
|
||||
try (Fixture fixture = new Fixture()) {
|
||||
fixture.command.river("surface", true);
|
||||
fixture.search.get().run();
|
||||
when(fixture.player.getWorld()).thenReturn(mock(World.class));
|
||||
fixture.chunk.complete(mock(Chunk.class));
|
||||
|
||||
fixture.platform.verify(() -> BukkitPlatform.teleportAsync(any(Player.class), any(Location.class)), never());
|
||||
verify(fixture.sender).sendMessage(contains("world changed"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successIsReportedOnlyAfterTeleportCompletes() {
|
||||
try (Fixture fixture = new Fixture()) {
|
||||
fixture.command.river("surface", true);
|
||||
fixture.search.get().run();
|
||||
fixture.chunk.complete(mock(Chunk.class));
|
||||
|
||||
verify(fixture.sender, never()).sendMessage("teleported");
|
||||
fixture.teleport.complete(true);
|
||||
verify(fixture.sender).sendMessage("teleported");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectedTeleportReportsFailureWithoutSuccess() {
|
||||
try (Fixture fixture = new Fixture()) {
|
||||
fixture.command.river("surface", true);
|
||||
fixture.search.get().run();
|
||||
fixture.chunk.complete(mock(Chunk.class));
|
||||
fixture.teleport.complete(false);
|
||||
|
||||
verify(fixture.sender, never()).sendMessage("teleported");
|
||||
verify(fixture.sender).sendMessage(contains("Could not teleport"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedTeleportReportsTheFullCauseWithoutSuccess() {
|
||||
try (Fixture fixture = new Fixture()) {
|
||||
IllegalStateException failure = new IllegalStateException("destination unloaded");
|
||||
fixture.command.river("surface", true);
|
||||
fixture.search.get().run();
|
||||
fixture.chunk.complete(mock(Chunk.class));
|
||||
fixture.teleport.completeExceptionally(failure);
|
||||
|
||||
verify(fixture.sender, never()).sendMessage("teleported");
|
||||
verify(fixture.sender).sendMessage(contains("Could not teleport"));
|
||||
fixture.logging.verify(() -> Iris.reportError(any(String.class), eq(failure)));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Fixture implements AutoCloseable {
|
||||
private final CommandFind command = mock(CommandFind.class, CALLS_REAL_METHODS);
|
||||
private final Engine engine = mock(Engine.class);
|
||||
private final IrisComplex complex = mock(IrisComplex.class);
|
||||
private final Player player = mock(Player.class);
|
||||
private final World world = mock(World.class);
|
||||
private final VolmitSender sender = mock(VolmitSender.class);
|
||||
private final AtomicReference<Runnable> search = new AtomicReference<>();
|
||||
private final CompletableFuture<Chunk> chunk = new CompletableFuture<>();
|
||||
private final CompletableFuture<Boolean> teleport = new CompletableFuture<>();
|
||||
private final MockedStatic<J> scheduler = mockStatic(J.class);
|
||||
private final MockedStatic<BukkitPlatform> platform = mockStatic(BukkitPlatform.class);
|
||||
private final MockedStatic<GenerationSemanticQueries> queries = mockStatic(GenerationSemanticQueries.class);
|
||||
private final MockedStatic<IrisLanguage> language = mockStatic(IrisLanguage.class, invocation -> "teleported");
|
||||
private final MockedStatic<Iris> logging = mockStatic(Iris.class);
|
||||
|
||||
private Fixture() {
|
||||
doReturn(engine).when(command).engine();
|
||||
doReturn(player).when(command).player();
|
||||
doReturn(sender).when(command).sender();
|
||||
when(engine.getComplex()).thenReturn(complex);
|
||||
when(player.getWorld()).thenReturn(world);
|
||||
when(player.getLocation()).thenReturn(new Location(world, 0, 70, 0));
|
||||
when(player.isOnline()).thenReturn(true);
|
||||
when(world.getMinHeight()).thenReturn(-64);
|
||||
when(world.getMaxHeight()).thenReturn(320);
|
||||
scheduler.when(() -> J.a(any(Runnable.class))).thenAnswer(invocation -> {
|
||||
search.set(invocation.getArgument(0));
|
||||
return null;
|
||||
});
|
||||
scheduler.when(() -> J.runEntity(eq(player), any(Runnable.class))).thenAnswer(invocation -> {
|
||||
invocation.<Runnable>getArgument(1).run();
|
||||
return true;
|
||||
});
|
||||
scheduler.when(() -> J.runRegion(any(World.class), anyInt(), anyInt(), any(Runnable.class))).thenAnswer(invocation -> {
|
||||
invocation.<Runnable>getArgument(3).run();
|
||||
return true;
|
||||
});
|
||||
platform.when(() -> BukkitPlatform.chunkAtAsync(any(World.class), anyInt(), anyInt(), eq(true))).thenReturn(chunk);
|
||||
platform.when(() -> BukkitPlatform.teleportAsync(eq(player), any(Location.class))).thenReturn(teleport);
|
||||
queries.when(() -> GenerationSemanticQueries.nearestRiver(eq(engine), any(), eq(0), eq(0), anyInt(), any()))
|
||||
.thenReturn(Optional.of(new GenerationSemanticQueries.RiverResult(
|
||||
GenerationSemanticQueries.RiverSource.ACTIVE_PREDICTION,
|
||||
HydrologyFeatureType.RIFFLE, Optional.empty(), 1L, 32, 63, 32, OptionalLong.empty())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
logging.close();
|
||||
language.close();
|
||||
queries.close();
|
||||
platform.close();
|
||||
scheduler.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package art.arcane.iris.command;
|
||||
|
||||
import art.arcane.iris.configuration.IrisSettings;
|
||||
import art.arcane.iris.platform.bukkit.plugin.VolmitSender;
|
||||
import art.arcane.iris.studio.view.GuiHost;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class CommandStudioDesktopTest {
|
||||
private IrisSettings previousSettings;
|
||||
private boolean previousSuppressed;
|
||||
private RecordingSender sender;
|
||||
private CommandStudio command;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
previousSettings = IrisSettings.settings;
|
||||
previousSuppressed = GuiHost.isDesktopSuppressed();
|
||||
IrisSettings.settings = new IrisSettings();
|
||||
IrisSettings.settings.getGui().setUseServerLaunchedGuis(true);
|
||||
GuiHost.suppressDesktop(true);
|
||||
sender = new RecordingSender();
|
||||
command = new TestCommand(sender);
|
||||
}
|
||||
|
||||
@After
|
||||
public void restore() {
|
||||
IrisSettings.settings = previousSettings;
|
||||
GuiHost.suppressDesktop(previousSuppressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapReportsMissingDisplayBeforeAccessingWorld() {
|
||||
command.map(null);
|
||||
|
||||
assertDisplayMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void imageMapReportsMissingDisplayInsteadOfDisabledSetting() {
|
||||
command.imagemap(null);
|
||||
|
||||
assertDisplayMessage();
|
||||
}
|
||||
|
||||
private void assertDisplayMessage() {
|
||||
assertEquals(1, sender.messages.size());
|
||||
assertTrue(sender.messages.getFirst(), sender.messages.getFirst().contains("display"));
|
||||
}
|
||||
|
||||
private static final class TestCommand extends CommandStudio {
|
||||
private final VolmitSender sender;
|
||||
|
||||
private TestCommand(VolmitSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolmitSender sender() {
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RecordingSender extends VolmitSender {
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
|
||||
private RecordingSender() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
messages.add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user