feat(commands): add contextual tab completion
Release / release (push) Successful in 2m35s
CI / build (push) Successful in 1m21s

This commit is contained in:
dmg
2026-08-21 22:58:58 -04:00
parent 80810b3ba1
commit 7318d4afa6
11 changed files with 488 additions and 0 deletions
@@ -0,0 +1,55 @@
package games.dmg.spigottyrant;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Set;
import java.util.UUID;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.Test;
final class TyrantAdminTabCompleterTest {
@Test
void permissionGatesAdministrativeSyntaxAndOnlineCandidates() {
UUID alphaId = UUID.fromString("11111111-1111-1111-1111-111111111111");
UUID betaId = UUID.fromString("22222222-2222-2222-2222-222222222222");
Player alpha = player(alphaId, "Alpha");
Player beta = player(betaId, "Beta");
OnlinePlayerDirectory directory = mock(OnlinePlayerDirectory.class);
when(directory.onlinePlayerIds()).thenReturn(Set.of(alphaId, betaId));
when(directory.findById(alphaId)).thenReturn(alpha);
when(directory.findById(betaId)).thenReturn(beta);
TyrantAdminTabCompleter completer = new TyrantAdminTabCompleter(directory);
Command command = mock(Command.class);
CommandSender denied = mock(CommandSender.class);
CommandSender admin = mock(CommandSender.class);
when(admin.hasPermission("spigottyrant.admin")).thenReturn(true);
assertEquals(java.util.List.of(), completer.onTabComplete(
denied, command, "tyrantadmin", new String[] {""}
));
assertTrue(completer.onTabComplete(
admin, command, "tyrantadmin", new String[] {""}
).containsAll(java.util.List.of("status", "start", "pause", "resume", "reset")));
assertEquals(java.util.List.of("Alpha", "Beta"), completer.onTabComplete(
admin, command, "tyrantadmin", new String[] {"start", ""}
));
assertEquals(java.util.List.of("Beta"), completer.onTabComplete(
admin, command, "tyrantadmin", new String[] {"start", "Alpha", ""}
));
assertEquals(java.util.List.of("confirm"), completer.onTabComplete(
admin, command, "tyrantadmin", new String[] {"reset", "c"}
));
}
private static Player player(UUID id, String name) {
Player player = mock(Player.class);
when(player.getUniqueId()).thenReturn(id);
when(player.getName()).thenReturn(name);
return player;
}
}
@@ -0,0 +1,41 @@
package games.dmg.spigottyrant;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.Test;
final class TyrantTabCompleterTest {
@Test
void rootBuyAssignAndConfirmationSuggestionsFollowSyntaxAndPrefix() {
TyrantTabCompleter completer = new TyrantTabCompleter(
mock(TyrantStateManager.class), mock(OnlinePlayerDirectory.class)
);
Player player = mock(Player.class);
Command command = mock(Command.class);
List<String> root = completer.onTabComplete(
player, command, "tyrant", new String[] {""}
);
List<String> buy = completer.onTabComplete(
player, command, "tyrant", new String[] {"buy", "ro"}
);
List<String> assign = completer.onTabComplete(
player, command, "tyrant", new String[] {"assign", "f"}
);
List<String> confirm = completer.onTabComplete(
player, command, "tyrant", new String[] {"relinquish", "c"}
);
assertTrue(root.containsAll(List.of("menu", "status", "buy", "assign", "item")));
assertFalse(root.contains("SomePlayer"));
assertEquals(List.of("roster_intelligence"), buy);
assertEquals(List.of("fixer"), assign);
assertEquals(List.of("confirm"), confirm);
}
}
@@ -0,0 +1,73 @@
package games.dmg.spigottyrant;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.Test;
final class VigilanteTabCompleterTest {
@Test
void rootAndPlayerArgumentsUseMembershipEligibility() {
UUID tyrantId = UUID.fromString("11111111-1111-1111-1111-111111111111");
UUID vigilanteId = UUID.fromString("22222222-2222-2222-2222-222222222222");
UUID eligibleId = UUID.fromString("33333333-3333-3333-3333-333333333333");
UUID followerId = UUID.fromString("44444444-4444-4444-4444-444444444444");
PlayerState eligible = PlayerState.newPlayer(eligibleId, "Eligible");
PlayerState follower = follower(followerId, "Follower", vigilanteId);
TyrantStateManager manager = mock(TyrantStateManager.class);
when(manager.game()).thenReturn(new GameState(
GameLifecycle.RUNNING, Optional.of(tyrantId), Optional.of(vigilanteId),
Optional.empty(), Optional.empty(), Optional.empty(), Duration.ZERO,
0, 0, Set.of()
));
when(manager.players()).thenReturn(Map.of(eligibleId, eligible, followerId, follower));
OnlinePlayerDirectory directory = mock(OnlinePlayerDirectory.class);
when(directory.onlinePlayerIds()).thenReturn(Set.of(eligibleId, followerId, tyrantId));
Player eligiblePlayer = player(eligibleId, "Eligible");
Player followerPlayer = player(followerId, "Follower");
Player tyrantPlayer = player(tyrantId, "Tyrant");
when(directory.findById(eligibleId)).thenReturn(eligiblePlayer);
when(directory.findById(followerId)).thenReturn(followerPlayer);
when(directory.findById(tyrantId)).thenReturn(tyrantPlayer);
VigilanteTabCompleter completer = new VigilanteTabCompleter(
manager, new FollowerService(), directory
);
Player vigilante = player(vigilanteId, "Vigilante");
Command command = mock(Command.class);
assertTrue(completer.onTabComplete(
vigilante, command, "vigilante", new String[] {""}
).containsAll(java.util.List.of("menu", "item", "invite", "dismiss")));
assertEquals(java.util.List.of("Eligible"), completer.onTabComplete(
vigilante, command, "vigilante", new String[] {"invite", ""}
));
assertEquals(java.util.List.of("Follower"), completer.onTabComplete(
vigilante, command, "vigilante", new String[] {"dismiss", ""}
));
}
private static Player player(UUID id, String name) {
Player player = mock(Player.class);
when(player.getUniqueId()).thenReturn(id);
when(player.getName()).thenReturn(name);
return player;
}
private static PlayerState follower(UUID id, String name, UUID vigilanteId) {
PlayerState state = PlayerState.newPlayer(id, name);
return new PlayerState(
id, name, state.lastLogin(), state.optedOutUntil(), state.tyrantClass(),
Optional.of(vigilanteId), state.cooldownEnds(), state.readyAbilityItems(),
state.capturedMobs()
);
}
}