chore(core): improve (some) tests
This commit is contained in:
parent
db17fb5d10
commit
ebb25e9d41
3 changed files with 643 additions and 371 deletions
|
|
@ -0,0 +1,178 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2021 Alexander Söderberg & Contributors
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package cloud.commandframework;
|
||||
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.standard.IntegerArgument;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||
import cloud.commandframework.internal.CommandRegistrationHandler;
|
||||
import cloud.commandframework.meta.CommandMeta;
|
||||
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link CommandManager} integration tests.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class CommandManagerTest {
|
||||
|
||||
private CommandManager<TestCommandSender> commandManager;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.commandManager = new CommandManager<TestCommandSender>(
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
CommandRegistrationHandler.nullCommandRegistrationHandler()
|
||||
) {
|
||||
@Override
|
||||
public boolean hasPermission(
|
||||
final @NonNull TestCommandSender sender,
|
||||
final @NonNull String permission
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CommandMeta createDefaultCommandMeta() {
|
||||
return SimpleCommandMeta.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultiLiteralRouting() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> handlerA = mock(CommandExecutionHandler.class);
|
||||
when(handlerA.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
final CommandExecutionHandler<TestCommandSender> handlerB = mock(CommandExecutionHandler.class);
|
||||
when(handlerB.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
final CommandExecutionHandler<TestCommandSender> handlerC = mock(CommandExecutionHandler.class);
|
||||
when(handlerC.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
final Command<TestCommandSender> commandA = this.commandManager.commandBuilder("test")
|
||||
.literal("a")
|
||||
.handler(handlerA)
|
||||
.build();
|
||||
final Command<TestCommandSender> commandB = this.commandManager.commandBuilder("test")
|
||||
.literal("b")
|
||||
.handler(handlerB)
|
||||
.build();
|
||||
final Command<TestCommandSender> commandC = this.commandManager.commandBuilder("test")
|
||||
.literal("c")
|
||||
.argument(IntegerArgument.optional("opt"))
|
||||
.handler(handlerC)
|
||||
.build();
|
||||
|
||||
this.commandManager.command(commandA);
|
||||
this.commandManager.command(commandB);
|
||||
this.commandManager.command(commandC);
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "test a").join();
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "test b").join();
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "test c").join();
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "test c 123").join();
|
||||
|
||||
// Assert
|
||||
ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
|
||||
verify(handlerA).executeFuture(contextArgumentCaptor.capture());
|
||||
final CommandContext<TestCommandSender> contextA = contextArgumentCaptor.getValue();
|
||||
assertThat(contextA.getRawInputJoined()).isEqualTo("test a");
|
||||
|
||||
verify(handlerB).executeFuture(contextArgumentCaptor.capture());
|
||||
final CommandContext<TestCommandSender> contextB = contextArgumentCaptor.getValue();
|
||||
assertThat(contextB.getRawInputJoined()).isEqualTo("test b");
|
||||
|
||||
// Reset captor to reset the list of values.
|
||||
contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(handlerC, times(2)).executeFuture(contextArgumentCaptor.capture());
|
||||
final CommandContext<TestCommandSender> contextC1 = contextArgumentCaptor.getAllValues().get(0);
|
||||
assertThat(contextC1.getRawInputJoined()).isEqualTo("test c");
|
||||
final CommandContext<TestCommandSender> contextC2 = contextArgumentCaptor.getAllValues().get(1);
|
||||
assertThat(contextC2.getRawInputJoined()).isEqualTo("test c 123");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCommandBuilder() {
|
||||
// Create and register a command
|
||||
Command<TestCommandSender> command = this.commandManager.commandBuilder("component")
|
||||
.literal("literal", "literalalias")
|
||||
.literal("detail", ArgumentDescription.of("detaildescription"))
|
||||
.argument(
|
||||
CommandArgument.ofType(int.class, "argument"),
|
||||
ArgumentDescription.of("argumentdescription")
|
||||
)
|
||||
.build();
|
||||
this.commandManager.command(command);
|
||||
|
||||
// Verify all the details we have configured are present
|
||||
List<CommandArgument<TestCommandSender, ?>> arguments = command.getArguments();
|
||||
List<CommandComponent<TestCommandSender>> components = command.getComponents();
|
||||
assertThat(arguments.size()).isEqualTo(components.size());
|
||||
assertThat(components.size()).isEqualTo(4);;
|
||||
|
||||
// Arguments should exactly match the component getArgument() result, in same order
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
assertThat(components.get(i).getArgument()).isEqualTo(arguments.get(i));
|
||||
}
|
||||
|
||||
// Argument configuration, we know component has the same argument so no need to test those
|
||||
// TODO: Aliases
|
||||
assertThat(arguments.get(0).getName()).isEqualTo("component");;
|
||||
assertThat(arguments.get(1).getName()).isEqualTo("literal");;
|
||||
assertThat(arguments.get(2).getName()).isEqualTo("detail");;
|
||||
assertThat(arguments.get(3).getName()).isEqualTo("argument");;
|
||||
|
||||
// Check argument is indeed a command argument
|
||||
assertThat(TypeToken.get(int.class)).isEqualTo(arguments.get(3).getValueType());
|
||||
|
||||
// Check description is set for all components, is empty when not specified
|
||||
assertThat(components.get(0).getArgumentDescription().getDescription()).isEmpty();
|
||||
assertThat(components.get(1).getArgumentDescription().getDescription()).isEmpty();
|
||||
assertThat(components.get(2).getArgumentDescription().getDescription()).isEqualTo("detaildescription");;
|
||||
assertThat(components.get(3).getArgumentDescription().getDescription()).isEqualTo("argumentdescription");;
|
||||
}
|
||||
}
|
||||
|
|
@ -23,44 +23,62 @@
|
|||
//
|
||||
package cloud.commandframework;
|
||||
|
||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||
import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext;
|
||||
import cloud.commandframework.execution.postprocessor.CommandPostprocessor;
|
||||
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||
import cloud.commandframework.services.types.ConsumerService;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static cloud.commandframework.util.TestUtils.createManager;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.notNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class CommandPostProcessorTest {
|
||||
@SuppressWarnings("unchecked")
|
||||
class CommandPostProcessorTest {
|
||||
|
||||
private static final boolean[] state = new boolean[]{false};
|
||||
private static CommandManager<TestCommandSender> manager;
|
||||
private CommandManager<TestCommandSender> commandManager;
|
||||
|
||||
@BeforeAll
|
||||
static void newTree() {
|
||||
manager = createManager();
|
||||
manager.command(manager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.handler(c -> state[0] = true)
|
||||
.build());
|
||||
manager.registerCommandPostProcessor(new SamplePostprocessor());
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.commandManager = createManager();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPreprocessing() {
|
||||
manager.executeCommand(new TestCommandSender(), "test").join();
|
||||
Assertions.assertFalse(state[0]);
|
||||
void testPostProcessing() {
|
||||
// Arrange
|
||||
final CommandPostprocessor<TestCommandSender> postprocessor = spy(new SamplePostprocessor());
|
||||
this.commandManager.registerCommandPostProcessor(postprocessor);
|
||||
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = mock(CommandExecutionHandler.class);
|
||||
when(executionHandler.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("test")
|
||||
.handler(executionHandler)
|
||||
.build()
|
||||
);
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "test").join();
|
||||
|
||||
// Assert
|
||||
verify(executionHandler, never()).executeFuture(notNull());
|
||||
verify(postprocessor).accept(notNull());
|
||||
}
|
||||
|
||||
static final class SamplePostprocessor implements CommandPostprocessor<TestCommandSender> {
|
||||
static class SamplePostprocessor implements CommandPostprocessor<TestCommandSender> {
|
||||
|
||||
@Override
|
||||
public void accept(final @NonNull CommandPostprocessingContext<TestCommandSender> context) {
|
||||
ConsumerService.interrupt();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
package cloud.commandframework;
|
||||
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.compound.ArgumentPair;
|
||||
import cloud.commandframework.arguments.flags.CommandFlag;
|
||||
import cloud.commandframework.arguments.preprocessor.RegexPreprocessor;
|
||||
import cloud.commandframework.arguments.standard.EnumArgument;
|
||||
import cloud.commandframework.arguments.standard.FloatArgument;
|
||||
import cloud.commandframework.arguments.standard.IntegerArgument;
|
||||
|
|
@ -34,6 +32,8 @@ import cloud.commandframework.arguments.standard.StringArgument;
|
|||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.exceptions.AmbiguousNodeException;
|
||||
import cloud.commandframework.exceptions.NoPermissionException;
|
||||
import cloud.commandframework.execution.CommandExecutionHandler;
|
||||
import cloud.commandframework.keys.SimpleCloudKey;
|
||||
import cloud.commandframework.meta.SimpleCommandMeta;
|
||||
import cloud.commandframework.types.tuples.Pair;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
|
|
@ -41,344 +41,412 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import static cloud.commandframework.util.TestUtils.createManager;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.notNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link CommandTree} integration tests.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class CommandTreeTest {
|
||||
|
||||
private static final int EXPECTED_INPUT_NUMBER = 15;
|
||||
private static CommandManager<TestCommandSender> manager;
|
||||
private CommandManager<TestCommandSender> commandManager;
|
||||
|
||||
@BeforeAll
|
||||
static void newTree() {
|
||||
manager = createManager();
|
||||
|
||||
/* Build general test commands */
|
||||
manager.command(manager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.literal("one").build())
|
||||
.command(manager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.literal("two").permission("no").build())
|
||||
.command(manager.commandBuilder("test", Collections.singleton("other"),
|
||||
SimpleCommandMeta.empty()
|
||||
)
|
||||
.literal("opt", "öpt")
|
||||
.argument(IntegerArgument
|
||||
.optional("num", EXPECTED_INPUT_NUMBER))
|
||||
.build())
|
||||
.command(manager.commandBuilder("req").senderType(SpecificCommandSender.class).build());
|
||||
|
||||
/* Build command to test command proxying */
|
||||
final Command<TestCommandSender> toProxy = manager.commandBuilder("test")
|
||||
.literal("unproxied")
|
||||
.argument(StringArgument.of("string"))
|
||||
.argument(IntegerArgument.of("int"))
|
||||
.literal("anotherliteral")
|
||||
.handler(c -> {
|
||||
})
|
||||
.build();
|
||||
manager.command(toProxy);
|
||||
manager.command(manager.commandBuilder("proxy").proxies(toProxy).build());
|
||||
|
||||
/* Build command for testing intermediary and final executors */
|
||||
manager.command(manager.commandBuilder("command")
|
||||
.permission("command.inner")
|
||||
.literal("inner")
|
||||
.handler(c -> System.out.println("Using inner command")));
|
||||
manager.command(manager.commandBuilder("command")
|
||||
.permission("command.outer")
|
||||
.handler(c -> System.out.println("Using outer command")));
|
||||
|
||||
/* Build command for testing compound types */
|
||||
manager.command(manager.commandBuilder("pos")
|
||||
.argument(ArgumentPair.of(manager, "pos", Pair.of("x", "y"),
|
||||
Pair.of(Integer.class, Integer.class)
|
||||
)
|
||||
.simple())
|
||||
.handler(c -> {
|
||||
final Pair<Integer, Integer> pair = c.get("pos");
|
||||
System.out.printf("X: %d | Y: %d\n", pair.getFirst(), pair.getSecond());
|
||||
}));
|
||||
manager.command(manager.commandBuilder("vec")
|
||||
.argument(ArgumentPair.of(manager, "vec", Pair.of("x", "y"),
|
||||
Pair.of(Double.class, Double.class)
|
||||
)
|
||||
.withMapper(
|
||||
Vector2.class,
|
||||
(sender, pair) -> new Vector2(pair.getFirst(), pair.getSecond())
|
||||
)
|
||||
)
|
||||
.handler(c -> {
|
||||
final Vector2 vector2 = c.get("vec");
|
||||
System.out.printf("X: %f | Y: %f\n", vector2.getX(), vector2.getY());
|
||||
}));
|
||||
|
||||
/* Build command for testing flags */
|
||||
final CommandFlag<Void> test = manager.flagBuilder("test")
|
||||
.withAliases("t")
|
||||
.build();
|
||||
|
||||
final CommandFlag<Integer> num = manager.flagBuilder("num")
|
||||
.withArgument(IntegerArgument.of("num"))
|
||||
.build();
|
||||
|
||||
manager.command(manager.commandBuilder("flags")
|
||||
.flag(manager.flagBuilder("test")
|
||||
.withAliases("t")
|
||||
.build())
|
||||
.flag(manager.flagBuilder("test2")
|
||||
.withAliases("f")
|
||||
.build())
|
||||
.flag(num)
|
||||
.flag(manager.flagBuilder("enum")
|
||||
.withArgument(EnumArgument.of(FlagEnum.class, "enum")))
|
||||
.handler(c -> {
|
||||
System.out.println("Flag present? " + c.flags().isPresent(test));
|
||||
System.out.println("Second flag present? " + c.flags().isPresent("test2"));
|
||||
System.out.println("Numerical flag: " + c.flags().getValue(num, -10));
|
||||
System.out.println("Enum: " + c.flags().getValue("enum", FlagEnum.PROXI));
|
||||
})
|
||||
.build());
|
||||
|
||||
/* Build command for testing float */
|
||||
manager.command(manager.commandBuilder("float")
|
||||
.argument(FloatArgument.of("num"))
|
||||
.handler(c -> System.out.printf("%f\n", c.<Float>get("num"))));
|
||||
|
||||
/* Build command for testing preprocessing */
|
||||
manager.command(manager.commandBuilder("preprocess")
|
||||
.argument(
|
||||
StringArgument.<TestCommandSender>of("argument")
|
||||
.addPreprocessor(RegexPreprocessor.of("[A-Za-z]{3,5}"))
|
||||
)
|
||||
);
|
||||
|
||||
/* Build command for testing multiple optionals */
|
||||
manager.command(
|
||||
manager.commandBuilder("optionals")
|
||||
.argument(StringArgument.optional("opt1"))
|
||||
.argument(StringArgument.optional("opt2"))
|
||||
);
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.commandManager = createManager();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parse() {
|
||||
final Pair<Command<TestCommandSender>, Exception> command = manager.getCommandTree()
|
||||
.parse(
|
||||
new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager
|
||||
),
|
||||
new LinkedList<>(
|
||||
Arrays.asList(
|
||||
"test",
|
||||
"one"
|
||||
))
|
||||
void testMultiLiteralParsing() {
|
||||
// Arrange
|
||||
final int defaultInputNumber = ThreadLocalRandom.current().nextInt();
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.literal("one")
|
||||
.build()
|
||||
).command(
|
||||
this.commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.literal("two")
|
||||
.permission("no")
|
||||
.build()
|
||||
).command(
|
||||
this.commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.literal("opt")
|
||||
.argument(IntegerArgument.optional("num", defaultInputNumber))
|
||||
.build()
|
||||
);
|
||||
Assertions.assertNotNull(command.getFirst());
|
||||
Assertions.assertEquals(NoPermissionException.class, manager.getCommandTree()
|
||||
.parse(
|
||||
new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager
|
||||
),
|
||||
new LinkedList<>(
|
||||
Arrays.asList("test", "two"))
|
||||
)
|
||||
.getSecond().getClass());
|
||||
manager.getCommandTree()
|
||||
.parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager),
|
||||
|
||||
// Act
|
||||
final Pair<Command<TestCommandSender>, Exception> command1 = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("test", "one"))
|
||||
);
|
||||
final Pair<Command<TestCommandSender>, Exception> command2 = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("test", "two"))
|
||||
);
|
||||
final Pair<Command<TestCommandSender>, Exception> command3 = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("test", "opt"))
|
||||
)
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager
|
||||
));
|
||||
manager.getCommandTree()
|
||||
.parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager),
|
||||
);
|
||||
final Pair<Command<TestCommandSender>, Exception> command4 = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("test", "opt", "12"))
|
||||
)
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager
|
||||
));
|
||||
);
|
||||
|
||||
// Assert
|
||||
assertThat(command1.getFirst()).isNotNull();
|
||||
assertThat(command1.getSecond()).isNull();
|
||||
|
||||
assertThat(command2.getFirst()).isNull();
|
||||
assertThat(command2.getSecond()).isInstanceOf(NoPermissionException.class);
|
||||
|
||||
assertThat(command3.getFirst()).isNotNull();
|
||||
assertThat(command3.getFirst().toString()).isEqualTo("test opt num");
|
||||
assertThat(command3.getSecond()).isNull();
|
||||
|
||||
assertThat(command4.getFirst()).isNotNull();
|
||||
assertThat(command4.getFirst().toString()).isEqualTo("test opt num");
|
||||
assertThat(command4.getSecond()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlias() {
|
||||
manager.getCommandTree()
|
||||
.parse(
|
||||
new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager
|
||||
),
|
||||
new LinkedList<>(Arrays.asList(
|
||||
"other",
|
||||
"öpt",
|
||||
"12"
|
||||
))
|
||||
)
|
||||
.getFirst().getCommandExecutionHandler().execute(new CommandContext<>(
|
||||
new TestCommandSender(),
|
||||
manager
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArgumentsAndComponents() {
|
||||
// Create and register a command
|
||||
Command<TestCommandSender> command = manager.commandBuilder("component")
|
||||
.literal("literal", "literalalias")
|
||||
.literal("detail", ArgumentDescription.of("detaildescription"))
|
||||
.argument(CommandArgument.ofType(int.class, "argument"),
|
||||
ArgumentDescription.of("argumentdescription"))
|
||||
void testAliasedRouting() {
|
||||
// Arrange
|
||||
final int defaultInputNumber = ThreadLocalRandom.current().nextInt();
|
||||
final Command<TestCommandSender> command = this.commandManager.commandBuilder(
|
||||
"test", Collections.singleton("other"), SimpleCommandMeta.empty()
|
||||
).literal("opt", "öpt")
|
||||
.argument(IntegerArgument.optional("num", defaultInputNumber))
|
||||
.build();
|
||||
manager.command(command);
|
||||
this.commandManager.command(command);
|
||||
|
||||
// Verify all the details we have configured are present
|
||||
List<CommandArgument<TestCommandSender, ?>> arguments = command.getArguments();
|
||||
List<CommandComponent<TestCommandSender>> components = command.getComponents();
|
||||
Assertions.assertEquals(arguments.size(), components.size());
|
||||
Assertions.assertEquals(4, components.size());
|
||||
// Act
|
||||
final Command<TestCommandSender> result = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("other", "öpt", "12"))
|
||||
).getFirst();
|
||||
|
||||
// Arguments should exactly match the component getArgument() result, in same order
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
Assertions.assertEquals(components.get(i).getArgument(), arguments.get(i));
|
||||
}
|
||||
|
||||
// Argument configuration, we know component has the same argument so no need to test those
|
||||
// TODO: Aliases
|
||||
Assertions.assertEquals("component", arguments.get(0).getName());
|
||||
Assertions.assertEquals("literal", arguments.get(1).getName());
|
||||
Assertions.assertEquals("detail", arguments.get(2).getName());
|
||||
Assertions.assertEquals("argument", arguments.get(3).getName());
|
||||
|
||||
// Check argument is indeed a command argument
|
||||
Assertions.assertEquals(TypeToken.get(int.class), arguments.get(3).getValueType());
|
||||
|
||||
// Check description is set for all components, is empty when not specified
|
||||
Assertions.assertEquals("", components.get(0).getArgumentDescription().getDescription());
|
||||
Assertions.assertEquals("", components.get(1).getArgumentDescription().getDescription());
|
||||
Assertions.assertEquals("detaildescription", components.get(2).getArgumentDescription().getDescription());
|
||||
Assertions.assertEquals("argumentdescription", components.get(3).getArgumentDescription().getDescription());
|
||||
// Assert
|
||||
assertThat(result).isEqualTo(command);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSuggestions() {
|
||||
Assertions.assertFalse(
|
||||
manager.getCommandTree().getSuggestions(
|
||||
new CommandContext<>(new TestCommandSender(), manager),
|
||||
new LinkedList<>(Arrays.asList("test", ""))
|
||||
).isEmpty());
|
||||
}
|
||||
// Arrange
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("test")
|
||||
.literal("a")
|
||||
);
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("test")
|
||||
.literal("b")
|
||||
);
|
||||
|
||||
@Test
|
||||
void testRequiredSender() {
|
||||
Assertions.assertThrows(CompletionException.class, () ->
|
||||
manager.executeCommand(new TestCommandSender(), "req").join());
|
||||
// Act
|
||||
final List<String> results = this.commandManager.getCommandTree().getSuggestions(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("test", ""))
|
||||
);
|
||||
|
||||
// Assert
|
||||
assertThat(results).containsExactly("a", "b");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultParser() {
|
||||
manager.command(
|
||||
manager.commandBuilder("default")
|
||||
.argument(manager.argumentBuilder(Integer.class, "int"))
|
||||
.handler(context -> {
|
||||
final int number = context.get("int");
|
||||
System.out.printf("Supplied number is: %d\n", number);
|
||||
})
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = mock(CommandExecutionHandler.class);
|
||||
when(executionHandler.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("default")
|
||||
.argument(this.commandManager.argumentBuilder(Integer.class, "int"))
|
||||
.handler(executionHandler)
|
||||
.build()
|
||||
);
|
||||
manager.executeCommand(new TestCommandSender(), "default 5").join();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "default 5").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.get(SimpleCloudKey.of("int", TypeToken.get(Integer.class)))).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidCommand() {
|
||||
Assertions.assertThrows(CompletionException.class, () -> manager
|
||||
assertThrows(CompletionException.class, () -> this.commandManager
|
||||
.executeCommand(new TestCommandSender(), "invalid test").join());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProxy() {
|
||||
manager.executeCommand(new TestCommandSender(), "test unproxied foo 10 anotherliteral").join();
|
||||
manager.executeCommand(new TestCommandSender(), "proxy foo 10").join();
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = mock(CommandExecutionHandler.class);
|
||||
when(executionHandler.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
final Command<TestCommandSender> toProxy = this.commandManager.commandBuilder("test")
|
||||
.literal("unproxied")
|
||||
.argument(StringArgument.of("string"))
|
||||
.argument(IntegerArgument.of("int"))
|
||||
.literal("anotherliteral")
|
||||
.handler(executionHandler)
|
||||
.build();
|
||||
this.commandManager.command(toProxy);
|
||||
this.commandManager.command(this.commandManager.commandBuilder("proxy").proxies(toProxy).build());
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "test unproxied foo 10 anotherliteral").join();
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "proxy foo 10").join();
|
||||
|
||||
// Assert
|
||||
verify(executionHandler, times(2)).executeFuture(notNull());
|
||||
}
|
||||
|
||||
private CommandExecutionHandler<TestCommandSender> setupFlags() {
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = mock(CommandExecutionHandler.class);
|
||||
when(executionHandler.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
final CommandFlag<Integer> num = this.commandManager.flagBuilder("num")
|
||||
.withArgument(IntegerArgument.of("num"))
|
||||
.build();
|
||||
|
||||
this.commandManager.command(this.commandManager.commandBuilder("flags")
|
||||
.flag(this.commandManager.flagBuilder("test")
|
||||
.withAliases("t")
|
||||
.build())
|
||||
.flag(this.commandManager.flagBuilder("test2")
|
||||
.withAliases("f")
|
||||
.build())
|
||||
.flag(num)
|
||||
.flag(this.commandManager.flagBuilder("enum")
|
||||
.withArgument(EnumArgument.of(FlagEnum.class, "enum")))
|
||||
.handler(executionHandler)
|
||||
.build());
|
||||
|
||||
return executionHandler;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIntermediary() {
|
||||
manager.executeCommand(new TestCommandSender(), "command inner").join();
|
||||
manager.executeCommand(new TestCommandSender(), "command").join();
|
||||
void testFlags_NoFlags() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().contains("test")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompound() {
|
||||
manager.executeCommand(new TestCommandSender(), "pos -3 2").join();
|
||||
manager.executeCommand(new TestCommandSender(), "vec 1 1").join();
|
||||
void testFlags_PresenceFlag() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags --test").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().contains("test")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags() {
|
||||
manager.executeCommand(new TestCommandSender(), "flags").join();
|
||||
manager.executeCommand(new TestCommandSender(), "flags --test").join();
|
||||
manager.executeCommand(new TestCommandSender(), "flags -t").join();
|
||||
Assertions.assertThrows(CompletionException.class, () ->
|
||||
manager.executeCommand(new TestCommandSender(), "flags --test --nonexistant").join());
|
||||
Assertions.assertThrows(CompletionException.class, () ->
|
||||
manager.executeCommand(new TestCommandSender(), "flags --test --duplicate").join());
|
||||
manager.executeCommand(new TestCommandSender(), "flags --test --test2").join();
|
||||
Assertions.assertThrows(CompletionException.class, () ->
|
||||
manager.executeCommand(new TestCommandSender(), "flags --test test2").join());
|
||||
manager.executeCommand(new TestCommandSender(), "flags --num 500").join();
|
||||
manager.executeCommand(new TestCommandSender(), "flags --num 63 --enum potato --test").join();
|
||||
manager.executeCommand(new TestCommandSender(), "flags -tf --num 63 --enum potato").join();
|
||||
void testFlags_PresenceFlagShortForm() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags -t").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().contains("test")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags_NonexistentFlag() {
|
||||
// Arrange
|
||||
this.setupFlags();
|
||||
|
||||
// Act & Assert
|
||||
assertThrows(
|
||||
CompletionException.class, () ->
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags --test --nonexistent").join()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags_MultiplePresenceFlags() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags --test --test2").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().contains("test")).isTrue();
|
||||
assertThat(context.flags().contains("test2")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags_NonPrefixedPresenceFlag() {
|
||||
// Arrange
|
||||
this.setupFlags();
|
||||
|
||||
// Act
|
||||
assertThrows(
|
||||
CompletionException.class, () ->
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags --test test2").join()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags_ValueFlag() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags --num 500").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().<Integer>getValue("num")).hasValue(500);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags_MultipleValueFlagsFollowedByPresence() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags --num 63 --enum potato --test").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().<Integer>getValue("num")).hasValue(63);
|
||||
assertThat(context.flags().<FlagEnum>getValue("enum")).hasValue(FlagEnum.POTATO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFlags_ShortFormPresenceFlagsFollowedByMultipleValueFlags() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = this.setupFlags();
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "flags -tf --num 63 --enum potato").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.flags().contains("test")).isTrue();
|
||||
assertThat(context.flags().contains("test2")).isTrue();
|
||||
assertThat(context.flags().<Integer>getValue("num")).hasValue(63);
|
||||
assertThat(context.flags().<FlagEnum>getValue("enum")).hasValue(FlagEnum.POTATO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAmbiguousNodes() {
|
||||
// Call newTree(); after each time we leave the Tree in an invalid state
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
// Call setup(); after each time we leave the Tree in an invalid state
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.argument(StringArgument.of("string"))
|
||||
);
|
||||
Assertions.assertThrows(AmbiguousNodeException.class, () ->
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
assertThrows(AmbiguousNodeException.class, () ->
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.argument(IntegerArgument.of("integer"))));
|
||||
newTree();
|
||||
this.setup();
|
||||
|
||||
// Literal and argument can co-exist, not ambiguous
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.argument(StringArgument.of("string"))
|
||||
);
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.literal("literal"));
|
||||
newTree();
|
||||
this.setup();
|
||||
|
||||
// Two literals (different names) and argument can co-exist, not ambiguous
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.literal("literal"));
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.literal("literal2"));
|
||||
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.argument(IntegerArgument.of("integer")));
|
||||
newTree();
|
||||
this.setup();
|
||||
|
||||
// Two literals with the same name can not co-exist, causes 'duplicate command chains' error
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.literal("literal"));
|
||||
Assertions.assertThrows(IllegalStateException.class, () ->
|
||||
manager.command(manager.commandBuilder("ambiguous")
|
||||
assertThrows(IllegalStateException.class, () ->
|
||||
this.commandManager.command(this.commandManager.commandBuilder("ambiguous")
|
||||
.literal("literal")));
|
||||
newTree();
|
||||
this.setup();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLiteralRepeatingArgument() {
|
||||
// Build a command with a literal repeating
|
||||
Command<TestCommandSender> command = manager.commandBuilder("repeatingargscommand")
|
||||
Command<TestCommandSender> command = this.commandManager.commandBuilder("repeatingargscommand")
|
||||
.literal("repeat")
|
||||
.literal("middle")
|
||||
.literal("repeat")
|
||||
|
|
@ -386,20 +454,20 @@ class CommandTreeTest {
|
|||
|
||||
// Verify built command has the repeat argument twice
|
||||
List<CommandArgument<TestCommandSender, ?>> args = command.getArguments();
|
||||
Assertions.assertEquals(4, args.size());
|
||||
Assertions.assertEquals("repeatingargscommand", args.get(0).getName());
|
||||
Assertions.assertEquals("repeat", args.get(1).getName());
|
||||
Assertions.assertEquals("middle", args.get(2).getName());
|
||||
Assertions.assertEquals("repeat", args.get(3).getName());
|
||||
assertThat(args.size()).isEqualTo(4);;
|
||||
assertThat(args.get(0).getName()).isEqualTo("repeatingargscommand");;
|
||||
assertThat(args.get(1).getName()).isEqualTo("repeat");;
|
||||
assertThat(args.get(2).getName()).isEqualTo("middle");;
|
||||
assertThat(args.get(3).getName()).isEqualTo("repeat");;
|
||||
|
||||
// Register
|
||||
manager.command(command);
|
||||
this.commandManager.command(command);
|
||||
|
||||
// If internally it drops repeating arguments, then it would register:
|
||||
// > /repeatingargscommand repeat middle
|
||||
// So check that we can register that exact command without an ambiguity exception
|
||||
manager.command(
|
||||
manager.commandBuilder("repeatingargscommand")
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("repeatingargscommand")
|
||||
.literal("repeat")
|
||||
.literal("middle")
|
||||
);
|
||||
|
|
@ -408,110 +476,118 @@ class CommandTreeTest {
|
|||
@Test
|
||||
void testAmbiguousLiteralOverridingArgument() {
|
||||
/* Build two commands for testing literals overriding variable arguments */
|
||||
manager.command(
|
||||
manager.commandBuilder("literalwithvariable")
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("literalwithvariable")
|
||||
.argument(StringArgument.of("variable"))
|
||||
);
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("literalwithvariable")
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("literalwithvariable")
|
||||
.literal("literal", "literalalias")
|
||||
);
|
||||
|
||||
/* Try parsing as a variable, which should match the variable command */
|
||||
final Pair<Command<TestCommandSender>, Exception> variableResult = manager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager),
|
||||
final Pair<Command<TestCommandSender>, Exception> variableResult = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("literalwithvariable", "argthatdoesnotmatch"))
|
||||
);
|
||||
Assertions.assertNull(variableResult.getSecond());
|
||||
Assertions.assertEquals("literalwithvariable",
|
||||
variableResult.getFirst().getArguments().get(0).getName());
|
||||
Assertions.assertEquals("variable",
|
||||
variableResult.getFirst().getArguments().get(1).getName());
|
||||
assertThat(variableResult.getSecond()).isNull();
|
||||
assertThat(variableResult.getFirst().getArguments().get(0).getName()).isEqualTo("literalwithvariable");;
|
||||
assertThat(variableResult.getFirst().getArguments().get(1).getName()).isEqualTo("variable");;
|
||||
|
||||
/* Try parsing with the main name literal, which should match the literal command */
|
||||
final Pair<Command<TestCommandSender>, Exception> literalResult = manager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager),
|
||||
final Pair<Command<TestCommandSender>, Exception> literalResult = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("literalwithvariable", "literal"))
|
||||
);
|
||||
Assertions.assertNull(literalResult.getSecond());
|
||||
Assertions.assertEquals("literalwithvariable",
|
||||
literalResult.getFirst().getArguments().get(0).getName());
|
||||
Assertions.assertEquals("literal",
|
||||
literalResult.getFirst().getArguments().get(1).getName());
|
||||
assertThat(literalResult.getSecond()).isNull();
|
||||
assertThat(literalResult.getFirst().getArguments().get(0).getName()).isEqualTo("literalwithvariable");;
|
||||
assertThat(literalResult.getFirst().getArguments().get(1).getName()).isEqualTo("literal");;
|
||||
|
||||
/* Try parsing with the alias of the literal, which should match the literal command */
|
||||
final Pair<Command<TestCommandSender>, Exception> literalAliasResult = manager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), manager),
|
||||
final Pair<Command<TestCommandSender>, Exception> literalAliasResult = this.commandManager.getCommandTree().parse(
|
||||
new CommandContext<>(new TestCommandSender(), this.commandManager),
|
||||
new LinkedList<>(Arrays.asList("literalwithvariable", "literalalias"))
|
||||
);
|
||||
Assertions.assertNull(literalAliasResult.getSecond());
|
||||
Assertions.assertEquals("literalwithvariable",
|
||||
literalAliasResult.getFirst().getArguments().get(0).getName());
|
||||
Assertions.assertEquals("literal",
|
||||
literalAliasResult.getFirst().getArguments().get(1).getName());
|
||||
assertThat(literalAliasResult.getSecond()).isNull();
|
||||
assertThat(literalAliasResult.getFirst().getArguments().get(0).getName()).isEqualTo("literalwithvariable");;
|
||||
assertThat(literalAliasResult.getFirst().getArguments().get(1).getName()).isEqualTo("literal");;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDuplicateArgument() {
|
||||
// Arrange
|
||||
final CommandArgument<TestCommandSender, String> argument = StringArgument.of("test");
|
||||
manager.command(manager.commandBuilder("one").argument(argument));
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () ->
|
||||
manager.command(manager.commandBuilder("two").argument(argument)));
|
||||
}
|
||||
this.commandManager.command(this.commandManager.commandBuilder("one").argument(argument));
|
||||
|
||||
@Test
|
||||
void testFloats() {
|
||||
manager.executeCommand(new TestCommandSender(), "float 0.0").join();
|
||||
manager.executeCommand(new TestCommandSender(), "float 100").join();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPreprocessors() {
|
||||
manager.executeCommand(new TestCommandSender(), "preprocess abc").join();
|
||||
Assertions.assertThrows(
|
||||
CompletionException.class,
|
||||
() -> manager.executeCommand(new TestCommandSender(), "preprocess ab").join()
|
||||
// Act & Assert
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> this.commandManager.command(this.commandManager.commandBuilder("two").argument(argument))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFloats() {
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = mock(CommandExecutionHandler.class);
|
||||
when(executionHandler.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("float")
|
||||
.argument(FloatArgument.of("num"))
|
||||
.handler(executionHandler)
|
||||
.build()
|
||||
);
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "float 0.0").join();
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "float 100").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler, times(2)).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final Stream<Float> values = contextArgumentCaptor.getAllValues()
|
||||
.stream()
|
||||
.map(context -> context.<Float>get("num"));
|
||||
assertThat(values).containsExactly(0.0f, 100f);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOptionals() {
|
||||
manager.executeCommand(new TestCommandSender(), "optionals").join();
|
||||
// Arrange
|
||||
final CommandExecutionHandler<TestCommandSender> executionHandler = mock(CommandExecutionHandler.class);
|
||||
when(executionHandler.executeFuture(any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
this.commandManager.command(
|
||||
this.commandManager.commandBuilder("optionals")
|
||||
.argument(StringArgument.optional("opt1"))
|
||||
.argument(StringArgument.optional("opt2"))
|
||||
.handler(executionHandler)
|
||||
.build()
|
||||
);
|
||||
|
||||
// Act
|
||||
this.commandManager.executeCommand(new TestCommandSender(), "optionals").join();
|
||||
|
||||
// Assert
|
||||
final ArgumentCaptor<CommandContext<TestCommandSender>> contextArgumentCaptor = ArgumentCaptor.forClass(
|
||||
CommandContext.class
|
||||
);
|
||||
verify(executionHandler).executeFuture(contextArgumentCaptor.capture());
|
||||
|
||||
final CommandContext<TestCommandSender> context = contextArgumentCaptor.getValue();
|
||||
assertThat(context.getOrDefault(SimpleCloudKey.of("opt1", TypeToken.get(String.class)), null)).isNull();
|
||||
assertThat(context.getOrDefault(SimpleCloudKey.of("opt2", TypeToken.get(String.class)), null)).isNull();
|
||||
}
|
||||
|
||||
|
||||
public static final class SpecificCommandSender extends TestCommandSender {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static final class Vector2 {
|
||||
|
||||
private final double x;
|
||||
private final double y;
|
||||
|
||||
private Vector2(final double x, final double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
private double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
private double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum FlagEnum {
|
||||
enum FlagEnum {
|
||||
POTATO,
|
||||
CARROT,
|
||||
ONION,
|
||||
PROXI
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue