diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/SuggestionsProvider.java b/proxy/src/main/java/com/velocitypowered/proxy/command/SuggestionsProvider.java
index 2de0503d4..e6af2d62b 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/command/SuggestionsProvider.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/command/SuggestionsProvider.java
@@ -30,6 +30,8 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.command.Command;
+import com.velocitypowered.api.command.CommandMeta;
+import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.proxy.command.brigadier.VelocityArgumentCommandNode;
import java.util.ArrayList;
import java.util.Collection;
@@ -283,12 +285,17 @@ final class SuggestionsProvider {
* Parses the hint nodes under the given node, which is either an alias node of
* a {@link Command} or another hint node.
*
+ * The caller must check the requirements
+ * are satisfied by a given source prior to calling this method.
+ *
*
The reader and context are not mutated by this method.
*
* @param node the node to parse
* @param originalReader the input reader
* @param contextSoFar the context, containing the alias node of the command
* @return the parse results containing the parsed hint nodes
+ * @see VelocityCommandMeta#copyHints(CommandMeta) for the conditions under which the returned
+ * hints can be suggested to a {@link CommandSource}.
*/
private ParseResults parseHints(final CommandNode node, final StringReader originalReader,
final CommandContextBuilder contextSoFar) {
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/BrigadierCommandTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/BrigadierCommandTests.java
index 3038ce766..b1fec4155 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/BrigadierCommandTests.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/BrigadierCommandTests.java
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
package com.velocitypowered.proxy.command;
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
@@ -41,6 +58,57 @@ public class BrigadierCommandTests extends CommandTestSuite {
assertEquals(1, callCount.get());
}
+ @Test
+ void testExecuteIgnoresAliasCase() {
+ final var callCount = new AtomicInteger();
+
+ final var node = LiteralArgumentBuilder
+ .literal("hello")
+ .executes(context -> {
+ assertEquals("hello", context.getInput());
+ callCount.incrementAndGet();
+ return 1;
+ })
+ .build();
+ manager.register(new BrigadierCommand(node));
+
+ assertHandled("Hello");
+ assertEquals(1, callCount.get());
+ }
+
+ @Test
+ void testExecuteInputIsTrimmed() {
+ final var callCount = new AtomicInteger();
+
+ final var node = LiteralArgumentBuilder
+ .literal("hello")
+ .executes(context -> {
+ assertEquals("hello", context.getInput());
+ callCount.incrementAndGet();
+ return 1;
+ })
+ .build();
+ manager.register(new BrigadierCommand(node));
+
+ assertHandled(" hello");
+ assertHandled(" hello");
+ assertHandled("hello ");
+ assertHandled("hello ");
+ assertEquals(4, callCount.get());
+ }
+
+ @Test
+ void testExecuteAfterUnregisterForwards() {
+ final var node = LiteralArgumentBuilder
+ .literal("hello")
+ .executes(context -> fail())
+ .build();
+ manager.register(new BrigadierCommand(node));
+ manager.unregister("hello");
+
+ assertForwarded("hello");
+ }
+
@Test
void testForwardsAndDoesNotExecuteImpermissibleAlias() {
final var callCount = new AtomicInteger();
@@ -162,6 +230,17 @@ public class BrigadierCommandTests extends CommandTestSuite {
// Suggestions
+ @Test
+ void testDoesNotSuggestAliasAfterUnregister() {
+ final var node = LiteralArgumentBuilder
+ .literal("hello")
+ .build();
+ manager.register(new BrigadierCommand(node));
+ manager.unregister("hello");
+
+ assertSuggestions("");
+ }
+
@Test
void testArgumentSuggestions() {
final var node = LiteralArgumentBuilder
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/CommandGraphInjectorTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/CommandGraphInjectorTests.java
index d0c3a9414..92a5b8b19 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/CommandGraphInjectorTests.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/CommandGraphInjectorTests.java
@@ -22,7 +22,6 @@ import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -36,16 +35,13 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-public class CommandGraphInjectorTests {
+public class CommandGraphInjectorTests extends CommandTestSuite {
- private static final CommandSource SOURCE = MockCommandSource.INSTANCE;
-
- private VelocityCommandManager manager;
private RootCommandNode dest;
@BeforeEach
void setUp() {
- this.manager = CommandManagerTests.newManager();
+ super.setUp();
this.dest = new RootCommandNode<>();
}
@@ -53,7 +49,7 @@ public class CommandGraphInjectorTests {
void testInjectInvocableCommand() {
final var meta = manager.metaBuilder("hello").build();
manager.register(meta, (SimpleCommand) invocation -> fail());
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
// Preserves alias and arguments node
final var expected = manager.getRoot();
@@ -73,14 +69,14 @@ public class CommandGraphInjectorTests {
@Override
public boolean hasPermission(final Invocation invocation) {
- assertEquals(SOURCE, invocation.source());
+ assertEquals(source, invocation.source());
assertEquals("hello", invocation.alias());
assertArrayEquals(new String[0], invocation.arguments());
callCount.incrementAndGet();
return false;
}
});
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
assertTrue(dest.getChildren().isEmpty());
assertEquals(1, callCount.get());
@@ -94,7 +90,7 @@ public class CommandGraphInjectorTests {
.then(argument("count", integer()))
.build();
manager.register(new BrigadierCommand(node));
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
assertEquals(node, dest.getChild("hello"));
}
@@ -113,7 +109,7 @@ public class CommandGraphInjectorTests {
}))
.build();
manager.register(new BrigadierCommand(registered));
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
final var expected = LiteralArgumentBuilder
.literal("greet")
@@ -131,7 +127,7 @@ public class CommandGraphInjectorTests {
.build())
.build();
manager.register(new BrigadierCommand(registered));
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
final var expected = LiteralArgumentBuilder
.literal("origin")
@@ -158,7 +154,7 @@ public class CommandGraphInjectorTests {
)
.build();
manager.register(new BrigadierCommand(registered));
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
final var expected = LiteralArgumentBuilder
.literal("hello")
@@ -181,7 +177,7 @@ public class CommandGraphInjectorTests {
.then(literal("baz"))
.build();
dest.addChild(original);
- manager.getInjector().inject(dest, SOURCE);
+ manager.getInjector().inject(dest, source);
assertEquals(registered, dest.getChild("foo"));
}
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/CommandManagerTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/CommandManagerTests.java
index 8bd9236f9..c93392379 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/CommandManagerTests.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/CommandManagerTests.java
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
package com.velocitypowered.proxy.command;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -10,37 +27,11 @@ import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.RawCommand;
import com.velocitypowered.api.command.SimpleCommand;
-import com.velocitypowered.proxy.event.MockEventManager;
-import com.velocitypowered.proxy.event.VelocityEventManager;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-public class CommandManagerTests {
-
- static final VelocityEventManager EVENT_MANAGER = new MockEventManager();
-
- static {
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- try {
- EVENT_MANAGER.shutdown();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }));
- }
-
- static VelocityCommandManager newManager() {
- return new VelocityCommandManager(EVENT_MANAGER);
- }
-
- private VelocityCommandManager manager;
-
- @BeforeEach
- void setUp() {
- this.manager = newManager();
- }
+public class CommandManagerTests extends CommandTestSuite {
// Registration
@@ -156,6 +147,21 @@ public class CommandManagerTests {
assertTrue(manager.hasCommand("foo"));
}
+ // Execution
+
+ @Test
+ void testExecuteUnknownAliasIsForwarded() {
+ assertForwarded("");
+ assertForwarded("hello");
+ }
+
+ // Suggestions
+
+ @Test
+ void testEmptyManagerSuggestNoAliases() {
+ assertSuggestions("");
+ }
+
static final class DummyCommand implements SimpleCommand {
static final DummyCommand INSTANCE = new DummyCommand();
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/CommandTestSuite.java b/proxy/src/test/java/com/velocitypowered/proxy/command/CommandTestSuite.java
index ff7748905..62ee06a8c 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/CommandTestSuite.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/CommandTestSuite.java
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
package com.velocitypowered.proxy.command;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -5,17 +22,38 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.velocitypowered.api.command.CommandSource;
+import com.velocitypowered.proxy.event.MockEventManager;
+import com.velocitypowered.proxy.event.VelocityEventManager;
import java.util.Arrays;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
abstract class CommandTestSuite {
+ private static VelocityEventManager eventManager;
+
protected VelocityCommandManager manager;
protected final CommandSource source = MockCommandSource.INSTANCE;
+ @BeforeAll
+ static void beforeAll() {
+ eventManager = new MockEventManager();
+ }
+
+ @AfterAll
+ static void afterAll() {
+ try {
+ eventManager.shutdown();
+ eventManager = null;
+ } catch (final InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
@BeforeEach
void setUp() {
- this.manager = CommandManagerTests.newManager();
+ this.manager = new VelocityCommandManager(eventManager);
}
final void assertHandled(final String input) {
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/OldCommandManagerTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/OldCommandManagerTests.java
deleted file mode 100644
index 76202c833..000000000
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/OldCommandManagerTests.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (C) 2018 Velocity Contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.velocitypowered.proxy.command;
-
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-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.junit.jupiter.api.Assertions.fail;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.mojang.brigadier.arguments.IntegerArgumentType;
-import com.mojang.brigadier.arguments.StringArgumentType;
-import com.mojang.brigadier.builder.LiteralArgumentBuilder;
-import com.mojang.brigadier.builder.RequiredArgumentBuilder;
-import com.mojang.brigadier.tree.ArgumentCommandNode;
-import com.mojang.brigadier.tree.CommandNode;
-import com.mojang.brigadier.tree.LiteralCommandNode;
-import com.velocitypowered.api.command.BrigadierCommand;
-import com.velocitypowered.api.command.CommandMeta;
-import com.velocitypowered.api.command.CommandSource;
-import com.velocitypowered.api.command.RawCommand;
-import com.velocitypowered.api.command.SimpleCommand;
-import com.velocitypowered.proxy.event.VelocityEventManager;
-import com.velocitypowered.proxy.plugin.MockEventManager;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-@Disabled
-public class OldCommandManagerTests {
-
- static VelocityCommandManager createManager() {
- return new VelocityCommandManager(CommandManagerTests.EVENT_MANAGER);
- }
-
- @Test
- void testConstruction() {
- VelocityCommandManager manager = createManager();
- assertFalse(manager.hasCommand("foo"));
- assertTrue(manager.getRoot().getChildren().isEmpty());
- assertFalse(manager.executeAsync(MockCommandSource.INSTANCE, "foo").join());
- assertFalse(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "bar").join());
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "").join().isEmpty());
- }
-
- @Test
- void testBrigadierRegister() {
- VelocityCommandManager manager = createManager();
- LiteralCommandNode node = LiteralArgumentBuilder
- .literal("foo")
- .build();
- BrigadierCommand command = new BrigadierCommand(node);
- manager.register(command);
-
- assertEquals(node, command.getNode());
- assertTrue(manager.hasCommand("fOo"));
-
- LiteralCommandNode barNode = LiteralArgumentBuilder
- .literal("bar")
- .build();
- BrigadierCommand aliasesCommand = new BrigadierCommand(barNode);
- CommandMeta meta = manager.metaBuilder(aliasesCommand)
- .aliases("baZ")
- .build();
-
- assertEquals(ImmutableSet.of("bar", "baz"), meta.getAliases());
- assertTrue(meta.getHints().isEmpty());
- manager.register(meta, aliasesCommand);
- assertTrue(manager.hasCommand("bAr"));
- assertTrue(manager.hasCommand("Baz"));
- }
-
- @Test
- void testSimpleRegister() {
- VelocityCommandManager manager = createManager();
- SimpleCommand command = new NoopSimpleCommand();
-
- manager.register("Foo", command);
- assertTrue(manager.hasCommand("foO"));
- manager.unregister("fOo");
- assertFalse(manager.hasCommand("foo"));
- assertFalse(manager.executeAsync(MockCommandSource.INSTANCE, "foo").join());
-
- manager.register("foo", command, "bAr", "BAZ");
- assertTrue(manager.hasCommand("bar"));
- assertTrue(manager.hasCommand("bAz"));
- }
-
- @Test
- void testRawRegister() {
- VelocityCommandManager manager = createManager();
- RawCommand command = new NoopRawCommand();
-
- manager.register("foO", command, "BAR");
- assertTrue(manager.hasCommand("fOo"));
- assertTrue(manager.hasCommand("bar"));
- }
-
- @Test
- void testBrigadierExecute() {
- VelocityCommandManager manager = createManager();
- AtomicBoolean executed = new AtomicBoolean(false);
- AtomicBoolean checkedRequires = new AtomicBoolean(false);
- LiteralCommandNode node = LiteralArgumentBuilder
- .literal("buy")
- .executes(context -> {
- assertEquals(MockCommandSource.INSTANCE, context.getSource());
- assertEquals("buy", context.getInput());
- executed.set(true);
- return 1;
- })
- .build();
- CommandNode quantityNode = RequiredArgumentBuilder
- .argument("quantity", IntegerArgumentType.integer(12, 16))
- .requires(source -> {
- assertEquals(MockCommandSource.INSTANCE, source);
- checkedRequires.set(true);
- return true;
- })
- .executes(context -> {
- int argument = IntegerArgumentType.getInteger(context, "quantity");
- assertEquals(14, argument);
- executed.set(true);
- return 1;
- })
- .build();
- CommandNode productNode = RequiredArgumentBuilder
- .argument("product", StringArgumentType.string())
- .requires(source -> {
- checkedRequires.set(true);
- return false;
- })
- .executes(context -> fail("was executed"))
- .build();
- quantityNode.addChild(productNode);
- node.addChild(quantityNode);
- manager.register(new BrigadierCommand(node));
-
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "buy ").join());
- assertTrue(executed.compareAndSet(true, false), "was executed");
- assertTrue(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "buy 14").join());
- assertTrue(checkedRequires.compareAndSet(true, false));
- assertTrue(executed.get());
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "buy 9").join(),
- "Invalid arg returns false");
- assertTrue(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "buy 12 bananas")
- .join());
- assertTrue(checkedRequires.get());
- }
-
- @Test
- void testSimpleExecute() {
- VelocityCommandManager manager = createManager();
- AtomicBoolean executed = new AtomicBoolean(false);
- SimpleCommand command = invocation -> {
- assertEquals(MockCommandSource.INSTANCE, invocation.source());
- assertArrayEquals(new String[] {"bar", "254"}, invocation.arguments());
- executed.set(true);
- };
- manager.register("foo", command);
-
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "foo bar 254").join());
- assertTrue(executed.get());
-
- SimpleCommand noPermsCommand = new SimpleCommand() {
- @Override
- public void execute(final Invocation invocation) {
- fail("was executed");
- }
-
- @Override
- public boolean hasPermission(final Invocation invocation) {
- return false;
- }
- };
-
- manager.register("dangerous", noPermsCommand, "veryDangerous");
- assertFalse(manager.executeAsync(MockCommandSource.INSTANCE, "dangerous").join());
- assertFalse(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "verydangerous 123")
- .join());
- }
-
- @Test
- void testRawExecute() {
- VelocityCommandManager manager = createManager();
- AtomicBoolean executed = new AtomicBoolean(false);
- RawCommand command = new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- assertEquals(MockCommandSource.INSTANCE, invocation.source());
- assertEquals("lobby 23", invocation.arguments());
- executed.set(true);
- }
- };
- manager.register("sendMe", command);
-
- assertTrue(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "sendMe lobby 23")
- .join());
- assertTrue(executed.compareAndSet(true, false));
-
- RawCommand noArgsCommand = new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- assertEquals("", invocation.arguments());
- executed.set(true);
- }
- };
- manager.register("noargs", noArgsCommand);
-
- assertTrue(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "noargs").join());
- assertTrue(executed.get());
- assertTrue(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "noargs ").join());
-
- RawCommand noPermsCommand = new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- fail("was executed");
- }
-
- @Override
- public boolean hasPermission(final Invocation invocation) {
- return false;
- }
- };
-
- manager.register("sendThem", noPermsCommand);
- assertFalse(manager.executeImmediatelyAsync(MockCommandSource.INSTANCE, "sendThem foo")
- .join());
- }
-
- @Test
- void testSuggestions() {
- VelocityCommandManager manager = createManager();
-
- LiteralCommandNode brigadierNode = LiteralArgumentBuilder
- .literal("brigadier")
- .build();
- CommandNode nameNode = RequiredArgumentBuilder
- .argument("name", StringArgumentType.string())
- .build();
- CommandNode numberNode = RequiredArgumentBuilder
- .argument("quantity", IntegerArgumentType.integer())
- .suggests((context, builder) -> builder.suggest(2).suggest(3).buildFuture())
- .build();
- nameNode.addChild(numberNode);
- brigadierNode.addChild(nameNode);
- manager.register(new BrigadierCommand(brigadierNode));
-
- SimpleCommand simpleCommand = new SimpleCommand() {
- @Override
- public void execute(final Invocation invocation) {
- fail();
- }
-
- @Override
- public List suggest(final Invocation invocation) {
- switch (invocation.arguments().length) {
- case 0:
- return ImmutableList.of("foo", "bar");
- case 1:
- return ImmutableList.of("123");
- default:
- return ImmutableList.of();
- }
- }
- };
- manager.register("simple", simpleCommand);
-
- RawCommand rawCommand = new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- fail();
- }
-
- @Override
- public List suggest(final Invocation invocation) {
- switch (invocation.arguments()) {
- case "":
- return ImmutableList.of("foo", "baz");
- case "foo ":
- return ImmutableList.of("2", "3", "5", "7");
- case "bar ":
- return ImmutableList.of("11", "13", "17");
- default:
- return ImmutableList.of();
- }
- }
- };
- manager.register("raw", rawCommand);
-
- assertEquals(
- ImmutableList.of("brigadier", "raw", "simple"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "").join(),
- "literals are in alphabetical order");
- assertEquals(
- ImmutableList.of("brigadier"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "briga").join());
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "brigadier")
- .join().isEmpty());
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "brigadier ")
- .join().isEmpty());
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "brigadier foo")
- .join().isEmpty());
- assertEquals(
- ImmutableList.of("2", "3"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "brigadier foo ").join());
- assertEquals(
- ImmutableList.of("bar", "foo"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "simple ").join());
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "simple")
- .join().isEmpty());
- assertEquals(
- ImmutableList.of("123"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "simPle foo").join());
- assertEquals(
- ImmutableList.of("baz", "foo"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "raw ").join());
- assertEquals(
- ImmutableList.of("2", "3", "5", "7"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "raw foo ").join());
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "raw foo")
- .join().isEmpty());
- assertEquals(
- ImmutableList.of("11", "13", "17"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "rAW bar ").join());
- }
-
- @Test
- void testBrigadierSuggestionPermissions() {
- VelocityCommandManager manager = createManager();
- LiteralCommandNode manageNode = LiteralArgumentBuilder
- .literal("manage")
- .requires(source -> false)
- .build();
- CommandNode idNode = RequiredArgumentBuilder
- .argument("id", IntegerArgumentType.integer(0))
- .suggests((context, builder) -> fail("called suggestion builder"))
- .build();
- manageNode.addChild(idNode);
- manager.register(new BrigadierCommand(manageNode));
-
- // Brigadier doesn't call the children predicate when requesting suggestions.
- // However, it won't query children if the source doesn't pass the parent
- // #requires predicate.
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "manage ")
- .join().isEmpty());
- }
-
- @Test
- @Disabled
- void testHinting() {
- VelocityCommandManager manager = createManager();
- AtomicBoolean executed = new AtomicBoolean(false);
- AtomicBoolean calledSuggestionProvider = new AtomicBoolean(false);
- AtomicReference expectedArgs = new AtomicReference<>();
- RawCommand command = new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- assertEquals(expectedArgs.get(), invocation.arguments());
- executed.set(true);
- }
-
- @Override
- public List suggest(final Invocation invocation) {
- return ImmutableList.of("raw");
- }
- };
-
- CommandNode barHint = LiteralArgumentBuilder
- .literal("bar")
- .executes(context -> fail("hints don't get executed"))
- .build();
- ArgumentCommandNode numberArg = RequiredArgumentBuilder
- .argument("number", IntegerArgumentType.integer())
- .suggests((context, builder) -> {
- calledSuggestionProvider.set(true);
- return builder.suggest("456").buildFuture();
- })
- .build();
- barHint.addChild(numberArg);
- CommandNode bazHint = LiteralArgumentBuilder
- .literal("baz")
- .build();
- CommandMeta meta = manager.metaBuilder("foo")
- .aliases("foo2")
- .hint(barHint)
- .hint(bazHint)
- .build();
- manager.register(meta, command);
-
- expectedArgs.set("notBarOrBaz");
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "foo notBarOrBaz").join());
- assertTrue(executed.compareAndSet(true, false));
- expectedArgs.set("anotherArg 123");
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "Foo2 anotherArg 123").join());
- assertTrue(executed.compareAndSet(true, false));
- expectedArgs.set("bar");
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "foo bar").join());
- assertTrue(executed.compareAndSet(true, false));
- expectedArgs.set("bar 123");
- assertTrue(manager.executeAsync(MockCommandSource.INSTANCE, "foo2 bar 123").join());
- assertTrue(executed.compareAndSet(true, false));
-
- assertEquals(ImmutableList.of("bar", "baz", "raw"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "foo ").join());
- assertFalse(calledSuggestionProvider.get());
- assertEquals(ImmutableList.of("456"),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "foo bar ").join());
- assertTrue(calledSuggestionProvider.compareAndSet(true, false));
- assertEquals(ImmutableList.of(),
- manager.offerSuggestions(MockCommandSource.INSTANCE, "foo2 baz ").join());
- }
-
- @Test
- void testSuggestionPermissions() throws ExecutionException, InterruptedException {
- VelocityCommandManager manager = createManager();
- RawCommand rawCommand = new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- fail("The Command should not be executed while testing suggestions");
- }
-
- @Override
- public boolean hasPermission(Invocation invocation) {
- return invocation.arguments().length() > 0;
- }
-
- @Override
- public List suggest(final Invocation invocation) {
- return ImmutableList.of("suggestion");
- }
- };
-
- manager.register("foo", rawCommand);
-
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "foo").get().isEmpty());
- assertFalse(manager.offerSuggestions(MockCommandSource.INSTANCE, "foo bar").get().isEmpty());
-
- SimpleCommand oldCommand = new SimpleCommand() {
- @Override
- public void execute(Invocation invocation) {
- fail("The Command should not be executed while testing suggestions");
- }
-
- @Override
- public boolean hasPermission(Invocation invocation) {
- return invocation.arguments().length > 0;
- }
-
- @Override
- public List suggest(Invocation invocation) {
- return ImmutableList.of("suggestion");
- }
- };
-
- manager.register("bar", oldCommand);
-
- assertTrue(manager.offerSuggestions(MockCommandSource.INSTANCE, "bar").get().isEmpty());
- assertFalse(manager.offerSuggestions(MockCommandSource.INSTANCE, "bar foo").get().isEmpty());
- }
-
- static class NoopSimpleCommand implements SimpleCommand {
- @Override
- public void execute(final Invocation invocation) {
-
- }
- }
-
- static class NoopRawCommand implements RawCommand {
- @Override
- public void execute(final Invocation invocation) {
-
- }
- }
-}
\ No newline at end of file
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/RawCommandTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/RawCommandTests.java
index 3f8ff1bfe..2b03ace8d 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/RawCommandTests.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/RawCommandTests.java
@@ -1,12 +1,33 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
package com.velocitypowered.proxy.command;
+import static com.mojang.brigadier.arguments.StringArgumentType.word;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import com.google.common.collect.ImmutableList;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.spotify.futures.CompletableFutures;
+import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.RawCommand;
import com.velocitypowered.api.command.SimpleCommand;
import java.util.Collections;
@@ -36,6 +57,47 @@ public class RawCommandTests extends CommandTestSuite {
assertEquals(1, callCount.get());
}
+ @Test
+ void testExecuteIgnoresAliasCase() {
+ final var callCount = new AtomicInteger();
+
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, (RawCommand) invocation -> {
+ assertEquals("hello", invocation.alias());
+ callCount.incrementAndGet();
+ });
+
+ assertHandled("Hello");
+ assertEquals(1, callCount.get());
+ }
+
+ @Test
+ void testExecuteInputIsTrimmed() {
+ final var callCount = new AtomicInteger();
+
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, (RawCommand) invocation -> {
+ assertEquals("hello", invocation.alias());
+ assertEquals("", invocation.arguments());
+ callCount.incrementAndGet();
+ });
+
+ assertHandled(" hello");
+ assertHandled(" hello");
+ assertHandled("hello ");
+ assertHandled("hello ");
+ assertEquals(4, callCount.get());
+ }
+
+ @Test
+ void testExecuteAfterUnregisterForwards() {
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, (RawCommand) invocation -> fail());
+ manager.unregister("hello");
+
+ assertForwarded("hello");
+ }
+
@Test
void testForwardsAndDoesNotExecuteImpermissibleAlias() {
final var callCount = new AtomicInteger();
@@ -125,6 +187,25 @@ public class RawCommandTests extends CommandTestSuite {
});
}
+ @Test
+ void testDoesNotSuggestAliasAfterUnregister() {
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, new RawCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public List suggest(final Invocation invocation) {
+ return fail();
+ }
+ });
+ manager.unregister("hello");
+
+ assertSuggestions("");
+ }
+
@Test
void testSuggestsArgumentsAfterAlias() {
final var meta = manager.metaBuilder("hello").build();
@@ -301,4 +382,105 @@ public class RawCommandTests extends CommandTestSuite {
assertThrows(CompletionException.class, () ->
manager.offerSuggestions(source, "hello ").join());
}
+
+ // Hinting
+
+ // Even if the following 2 cases look really similar, they test
+ // different parts of SuggestionsProvider.
+ @Test
+ void testDoesNotSuggestHintIfImpermissibleAlias() {
+ final var hint = LiteralArgumentBuilder
+ .literal("hint")
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new RawCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public boolean hasPermission(final Invocation invocation) {
+ return false;
+ }
+ });
+
+ assertSuggestions("hello ");
+ }
+
+ @Test
+ void testDoesNotSuggestHintIfImpermissibleArguments() {
+ final var hint = LiteralArgumentBuilder
+ .literal("hint")
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new RawCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public boolean hasPermission(final Invocation invocation) {
+ return false;
+ }
+ });
+
+ assertSuggestions("hello hin");
+ }
+
+ @Test
+ void testSuggestsMergesIgnoringHintsWhoseCustomSuggestionProviderFutureCompletesExceptionally() {
+ final var hint = RequiredArgumentBuilder
+ .argument("hint", word())
+ .suggests((context, builder) ->
+ CompletableFutures.exceptionallyCompletedFuture(new RuntimeException()))
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new RawCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public List suggest(final Invocation invocation) {
+ return ImmutableList.of("world");
+ }
+ });
+
+ assertSuggestions("hello ", "world");
+ }
+
+ @Test
+ void testSuggestsMergesIgnoringHintsWhoseCustomSuggestionProviderThrows() {
+ final var hint = RequiredArgumentBuilder
+ .argument("hint", word())
+ .suggests((context, builder) -> {
+ throw new RuntimeException();
+ })
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new RawCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public List suggest(final Invocation invocation) {
+ return ImmutableList.of("world");
+ }
+ });
+
+ assertSuggestions("hello ", "world");
+ }
}
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/SimpleCommandTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/SimpleCommandTests.java
index e4ccec57d..644b6a31e 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/SimpleCommandTests.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/SimpleCommandTests.java
@@ -1,12 +1,33 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
package com.velocitypowered.proxy.command;
+import static com.mojang.brigadier.arguments.StringArgumentType.word;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import com.google.common.collect.ImmutableList;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.spotify.futures.CompletableFutures;
+import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import java.util.Collections;
import java.util.List;
@@ -35,6 +56,47 @@ public class SimpleCommandTests extends CommandTestSuite {
assertEquals(1, callCount.get());
}
+ @Test
+ void testExecuteIgnoresAliasCase() {
+ final var callCount = new AtomicInteger();
+
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, (SimpleCommand) invocation -> {
+ assertEquals("hello", invocation.alias());
+ callCount.incrementAndGet();
+ });
+
+ assertHandled("Hello");
+ assertEquals(1, callCount.get());
+ }
+
+ @Test
+ void testExecuteInputIsTrimmed() {
+ final var callCount = new AtomicInteger();
+
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, (SimpleCommand) invocation -> {
+ assertEquals("hello", invocation.alias());
+ assertArrayEquals(new String[0], invocation.arguments());
+ callCount.incrementAndGet();
+ });
+
+ assertHandled(" hello");
+ assertHandled(" hello");
+ assertHandled("hello ");
+ assertHandled("hello ");
+ assertEquals(4, callCount.get());
+ }
+
+ @Test
+ void testExecuteAfterUnregisterForwards() {
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, (SimpleCommand) invocation -> fail());
+ manager.unregister("hello");
+
+ assertForwarded("hello");
+ }
+
@Test
void testForwardsAndDoesNotExecuteImpermissibleAlias() {
final var callCount = new AtomicInteger();
@@ -124,6 +186,25 @@ public class SimpleCommandTests extends CommandTestSuite {
});
}
+ @Test
+ void testDoesNotSuggestAliasAfterUnregister() {
+ final var meta = manager.metaBuilder("hello").build();
+ manager.register(meta, new SimpleCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public List suggest(final Invocation invocation) {
+ return fail();
+ }
+ });
+ manager.unregister("hello");
+
+ assertSuggestions("");
+ }
+
@Test
void testSuggestsArgumentsAfterAlias() {
final var meta = manager.metaBuilder("hello").build();
@@ -300,4 +381,105 @@ public class SimpleCommandTests extends CommandTestSuite {
assertThrows(CompletionException.class, () ->
manager.offerSuggestions(source, "hello ").join());
}
+
+ // Hinting
+
+ // Even if the following 2 cases look really similar, they test
+ // different parts of SuggestionsProvider.
+ @Test
+ void testDoesNotSuggestHintIfImpermissibleAlias() {
+ final var hint = LiteralArgumentBuilder
+ .literal("hint")
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new SimpleCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public boolean hasPermission(final Invocation invocation) {
+ return false;
+ }
+ });
+
+ assertSuggestions("hello ");
+ }
+
+ @Test
+ void testDoesNotSuggestHintIfImpermissibleArguments() {
+ final var hint = LiteralArgumentBuilder
+ .literal("hint")
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new SimpleCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public boolean hasPermission(final Invocation invocation) {
+ return false;
+ }
+ });
+
+ assertSuggestions("hello hin");
+ }
+
+ @Test
+ void testSuggestsMergesIgnoringHintsWhoseCustomSuggestionProviderFutureCompletesExceptionally() {
+ final var hint = RequiredArgumentBuilder
+ .argument("hint", word())
+ .suggests((context, builder) ->
+ CompletableFutures.exceptionallyCompletedFuture(new RuntimeException()))
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new SimpleCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public List suggest(final Invocation invocation) {
+ return ImmutableList.of("world");
+ }
+ });
+
+ assertSuggestions("hello ", "world");
+ }
+
+ @Test
+ void testSuggestsMergesIgnoringHintsWhoseCustomSuggestionProviderThrows() {
+ final var hint = RequiredArgumentBuilder
+ .argument("hint", word())
+ .suggests((context, builder) -> {
+ throw new RuntimeException();
+ })
+ .build();
+ final var meta = manager.metaBuilder("hello")
+ .hint(hint)
+ .build();
+ manager.register(meta, new SimpleCommand() {
+ @Override
+ public void execute(final Invocation invocation) {
+ fail();
+ }
+
+ @Override
+ public List suggest(final Invocation invocation) {
+ return ImmutableList.of("world");
+ }
+ });
+
+ assertSuggestions("hello ", "world");
+ }
}
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/command/SuggestionsProviderTests.java b/proxy/src/test/java/com/velocitypowered/proxy/command/SuggestionsProviderTests.java
index dd61069bc..37a582362 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/command/SuggestionsProviderTests.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/command/SuggestionsProviderTests.java
@@ -18,22 +18,16 @@
package com.velocitypowered.proxy.command;
import static com.mojang.brigadier.arguments.StringArgumentType.word;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.spotify.futures.CompletableFutures;
-import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.Command;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.RawCommand;
-import com.velocitypowered.api.command.SimpleCommand;
import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
import org.junit.jupiter.api.Test;
/**
@@ -196,22 +190,24 @@ public class SuggestionsProviderTests extends CommandTestSuite {
assertSuggestions("foo ", "bar", "baz", "qux");
assertSuggestions("foo bar", "baz", "qux");
- assertSuggestions("foo baz", "bar", "qux");
+ assertSuggestions("foo baz", "qux");
}
+ // Hints are suggested iff the source can use the given arguments; see
+ // VelocityCommandMeta#copyHints.
@Test
- // This doesn't make much sense, but emulates Brigadier behavior
- void testSuggestsImpermissibleHint() {
- final var hint = LiteralArgumentBuilder
- .literal("hint")
- .requires(source1 -> false)
+ void testSuggestIgnoresHintRequirementPredicateResults() {
+ final var hint = RequiredArgumentBuilder
+ .argument("hint", word())
+ .requires(source1 -> fail())
+ .suggests((context, builder) -> builder.suggest("suggestion").buildFuture())
.build();
final var meta = manager.metaBuilder("hello")
.hint(hint)
.build();
manager.register(meta, NoSuggestionsCommand.INSTANCE);
- assertSuggestions("hello ", "hint");
+ assertSuggestions("hello ", "suggestion");
}
@Test
@@ -245,51 +241,6 @@ public class SuggestionsProviderTests extends CommandTestSuite {
assertSuggestions("hello ");
}
- @Test
- void testSuggestCompletesExceptionallyIfHintRequirementPredicateThrows() {
- final var hint = RequiredArgumentBuilder
- .argument("hint", word())
- .requires(source1 -> {
- throw new RuntimeException();
- })
- .suggests((context, builder) -> fail())
- .build();
- final var meta = manager.metaBuilder("hello")
- .hint(hint)
- .build();
- manager.register(meta, NoSuggestionsCommand.INSTANCE);
-
- assertThrows(CompletionException.class, () ->
- manager.offerSuggestions(source, "hello ").join());
- }
-
- /*
-
- @Test
- void testSuggestionMergingIgnoresExceptionallyCompletedSuggestionFutures() {
- final var hint = RequiredArgumentBuilder
- .argument("hint", word())
- .suggests((context, builder) ->
- CompletableFutures.exceptionallyCompletedFuture(new RuntimeException()))
- .build();
- final var meta = manager.metaBuilder("hello")
- .hint(hint)
- .build();
- manager.register(meta, new RawCommand() {
- @Override
- public void execute(final Invocation invocation) {
- fail();
- }
-
- @Override
- public List suggest(final Invocation invocation) {
- return ImmutableList.of("world");
- }
- });
-
- assertSuggestions("hello ", "world");
- }*/
-
static final class NoSuggestionsCommand implements RawCommand {
static final NoSuggestionsCommand INSTANCE = new NoSuggestionsCommand();