Add required sender checking and add more tests
This commit is contained in:
parent
f5e230945d
commit
bc261676e7
7 changed files with 194 additions and 17 deletions
|
|
@ -29,6 +29,7 @@ import com.intellectualsites.commands.components.parser.ComponentParseResult;
|
|||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.exceptions.AmbiguousNodeException;
|
||||
import com.intellectualsites.commands.exceptions.ComponentParseException;
|
||||
import com.intellectualsites.commands.exceptions.InvalidCommandSenderException;
|
||||
import com.intellectualsites.commands.exceptions.InvalidSyntaxException;
|
||||
import com.intellectualsites.commands.exceptions.NoCommandInLeafException;
|
||||
import com.intellectualsites.commands.exceptions.NoPermissionException;
|
||||
|
|
@ -101,7 +102,13 @@ public final class CommandTree<C extends CommandSender, M extends CommandMeta> {
|
|||
public Optional<Command<C, M>> parse(@Nonnull final CommandContext<C> commandContext,
|
||||
@Nonnull final Queue<String> args) throws
|
||||
NoSuchCommandException, NoPermissionException, InvalidSyntaxException {
|
||||
return parseCommand(commandContext, args, this.internalTree);
|
||||
final Optional<Command<C, M>> commandOptional = parseCommand(commandContext, args, this.internalTree);
|
||||
commandOptional.flatMap(Command::getSenderType).ifPresent(requiredType -> {
|
||||
if (!requiredType.isAssignableFrom(commandContext.getSender().getClass())) {
|
||||
throw new InvalidCommandSenderException(commandContext.getSender(), requiredType, Collections.emptyList());
|
||||
}
|
||||
});
|
||||
return commandOptional;
|
||||
}
|
||||
|
||||
private Optional<Command<C, M>> parseCommand(@Nonnull final CommandContext<C> commandContext,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Alexander Söderberg
|
||||
//
|
||||
// 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 com.intellectualsites.commands.exceptions;
|
||||
|
||||
import com.intellectualsites.commands.components.CommandComponent;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Exception thrown when an invalid command sender tries to execute a command
|
||||
*/
|
||||
public final class InvalidCommandSenderException extends CommandParseException {
|
||||
|
||||
private final Class<?> requiredSender;
|
||||
|
||||
/**
|
||||
* Construct a new command parse exception
|
||||
*
|
||||
* @param commandSender Sender who executed the command
|
||||
* @param requiredSender The sender type that is required
|
||||
* @param currentChain Chain leading up to the exception
|
||||
*/
|
||||
public InvalidCommandSenderException(@Nonnull final CommandSender commandSender,
|
||||
@Nonnull final Class<?> requiredSender,
|
||||
@Nonnull final List<CommandComponent<?, ?>> currentChain) {
|
||||
super(commandSender, currentChain);
|
||||
this.requiredSender = requiredSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required sender type
|
||||
*
|
||||
* @return Required sender type
|
||||
*/
|
||||
@Nonnull
|
||||
public Class<?> getRequiredSender() {
|
||||
return this.requiredSender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("%s is not allowed to execute that command. Must be of type %s",
|
||||
getCommandSender().toString(),
|
||||
requiredSender.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 Alexander Söderberg
|
||||
//
|
||||
// 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 com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualsites.commands.components.StaticComponent;
|
||||
import com.intellectualsites.commands.components.standard.EnumComponent;
|
||||
import com.intellectualsites.commands.components.standard.StringComponent;
|
||||
import com.intellectualsites.commands.meta.SimpleCommandMeta;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandSuggestionsTest {
|
||||
|
||||
private static CommandManager<CommandSender, SimpleCommandMeta> manager;
|
||||
|
||||
@BeforeAll
|
||||
static void setupManager() {
|
||||
manager = new TestCommandManager();
|
||||
manager.command(manager.commandBuilder("test").component(StaticComponent.required("one")).build());
|
||||
manager.command(manager.commandBuilder("test").component(StaticComponent.required("two")).build());
|
||||
manager.command(manager.commandBuilder("test")
|
||||
.component(StaticComponent.required("var"))
|
||||
.component(StringComponent.newBuilder("str")
|
||||
.withSuggestionsProvider((c, s) -> Arrays.asList("one", "two"))
|
||||
.build())
|
||||
.component(EnumComponent.required(TestEnum.class, "enum"))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimple() {
|
||||
final String input = "test";
|
||||
final List<String> suggestions = manager.suggest(new TestCommandSender(), input);
|
||||
Assertions.assertEquals(Arrays.asList("one", "two", "var"), suggestions);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVar() {
|
||||
final String input = "test var";
|
||||
final List<String> suggestions = manager.suggest(new TestCommandSender(), input);
|
||||
Assertions.assertEquals(Arrays.asList("one", "two"), suggestions);
|
||||
final String input2 = "test var one";
|
||||
final List<String> suggestions2 = manager.suggest(new TestCommandSender(), input2);
|
||||
Assertions.assertEquals(Arrays.asList("foo", "bar"), suggestions2);
|
||||
final String input3 = "test var one f";
|
||||
final List<String> suggestions3 = manager.suggest(new TestCommandSender(), input3);
|
||||
Assertions.assertEquals(Collections.singletonList("foo"), suggestions3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmpty() {
|
||||
final String input = "kenny";
|
||||
final List<String> suggestions = manager.suggest(new TestCommandSender(), input);
|
||||
Assertions.assertTrue(suggestions.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
public enum TestEnum {
|
||||
FOO, BAR
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
class CommandTreeTest {
|
||||
|
||||
|
|
@ -47,15 +48,16 @@ class CommandTreeTest {
|
|||
static void newTree() {
|
||||
commandManager = new TestCommandManager();
|
||||
commandManager.command(commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("one")).build())
|
||||
.component(StaticComponent.required("one")).build())
|
||||
.command(commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("two")).withPermission("no").build())
|
||||
.component(StaticComponent.required("two")).withPermission("no").build())
|
||||
.command(commandManager.commandBuilder("test", Collections.singleton("other"),
|
||||
SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("opt", "öpt"))
|
||||
.component(IntegerComponent
|
||||
.optional("num", EXPECTED_INPUT_NUMBER))
|
||||
.build());
|
||||
SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("opt", "öpt"))
|
||||
.component(IntegerComponent
|
||||
.optional("num", EXPECTED_INPUT_NUMBER))
|
||||
.build())
|
||||
.command(commandManager.commandBuilder("req").withSenderType(SpecificCommandSender.class).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -94,4 +96,13 @@ class CommandTreeTest {
|
|||
Collections.singletonList("test"))).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRequiredSender() {
|
||||
Assertions.assertThrows(CompletionException.class, () ->
|
||||
commandManager.executeCommand(new TestCommandSender(), "req").join());
|
||||
}
|
||||
|
||||
public static final class SpecificCommandSender extends TestCommandSender {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue