From b5f9284bb571b63fdfe086db1a78c510eac45624 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Thu, 9 Dec 2021 15:23:46 +0100 Subject: [PATCH] Fix CommandPart.generateTabComplete for optional arguments --- .../src/de/steamwar/command/CommandPart.java | 29 +++++++--- .../src/de/steamwar/command/TypeMapper.java | 3 ++ .../command/SimpleCommandPartTest.java | 53 +++++++++++++++++++ 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/SpigotCore_Main/src/de/steamwar/command/CommandPart.java b/SpigotCore_Main/src/de/steamwar/command/CommandPart.java index b7960ed..e6dbf8c 100644 --- a/SpigotCore_Main/src/de/steamwar/command/CommandPart.java +++ b/SpigotCore_Main/src/de/steamwar/command/CommandPart.java @@ -44,17 +44,13 @@ public class CommandPart { private CommandPart next = null; public CommandPart(TypeMapper typeMapper, GuardChecker guard, Class varArgType, String optional, GuardCheckType guardCheckType) { - if (guardCheckType == GuardCheckType.TAB_COMPLETE) { - throw new IllegalArgumentException("Tab complete is not allowed as a guard check type!"); - } this.typeMapper = typeMapper; this.guard = guard; - if (optional != null && varArgType != null) { - throw new IllegalArgumentException("A vararg part can't have an optional part!"); - } this.varArgType = varArgType; this.optional = optional; this.guardCheckType = guardCheckType; + + validatePart(); } public void setNext(CommandPart next) { @@ -64,9 +60,26 @@ public class CommandPart { this.next = next; } + private void validatePart() { + if (guardCheckType == GuardCheckType.TAB_COMPLETE) { + throw new IllegalArgumentException("Tab complete is not allowed as a guard check type!"); + } + if (optional != null && varArgType != null) { + throw new IllegalArgumentException("A vararg part can't have an optional part!"); + } + + if (optional != null) { + try { + typeMapper.map(null, EMPTY_ARRAY, optional); + } catch (Exception e) { + throw new IllegalArgumentException("The optional part is not valid!"); + } + } + } + public void generateArgumentArray(List current, CommandSender commandSender, String[] args, int startIndex) { if (startIndex >= args.length) { - return; + throw new CommandParseException(); } if (varArgType != null) { @@ -86,7 +99,7 @@ public class CommandPart { if (!validArgument.success && optional == null) { throw new CommandParseException(); } - if (optional != null) { + if (!validArgument.success) { current.add(typeMapper.map(commandSender, EMPTY_ARRAY, optional)); if (next != null) { next.generateArgumentArray(current, commandSender, args, startIndex); diff --git a/SpigotCore_Main/src/de/steamwar/command/TypeMapper.java b/SpigotCore_Main/src/de/steamwar/command/TypeMapper.java index dce1882..bc794fb 100644 --- a/SpigotCore_Main/src/de/steamwar/command/TypeMapper.java +++ b/SpigotCore_Main/src/de/steamwar/command/TypeMapper.java @@ -24,6 +24,9 @@ import org.bukkit.command.CommandSender; import java.util.List; public interface TypeMapper { + /** + * The CommandSender can be null! + */ default T map(CommandSender commandSender, String[] previousArguments, String s) { return map(previousArguments, s); } diff --git a/SpigotCore_Main/testsrc/de/steamwar/command/SimpleCommandPartTest.java b/SpigotCore_Main/testsrc/de/steamwar/command/SimpleCommandPartTest.java index 47503d2..a9474a0 100644 --- a/SpigotCore_Main/testsrc/de/steamwar/command/SimpleCommandPartTest.java +++ b/SpigotCore_Main/testsrc/de/steamwar/command/SimpleCommandPartTest.java @@ -38,6 +38,8 @@ public class SimpleCommandPartTest { private CommandPart simpleGuardPart; + private CommandPart optionalCommandPart; + @Before public void setUp() throws Exception { stringCommandPart = new CommandPart(SWCommandUtils.createMapper("hello", "world"), null, null, null, GuardCheckType.COMMAND); @@ -49,6 +51,9 @@ public class SimpleCommandPartTest { varArgCommandPart = new CommandPart(SWCommandUtils.createMapper("hello", "world"), null, String.class, null, GuardCheckType.COMMAND); simpleGuardPart = new CommandPart(SWCommandUtils.createMapper("hello", "world"), (commandSender, guardCheckType, previousArguments, s) -> s.equals("hello") ? GuardResult.DENIED : GuardResult.ALLOWED, null, null, GuardCheckType.COMMAND); + + optionalCommandPart = new CommandPart(SWCommandUtils.createMapper("hello", "world"), null, null, "hello", GuardCheckType.COMMAND); + optionalCommandPart.setNext(new CommandPart(SWCommandUtils.createMapper("hello2", "world2"), null, null, null, GuardCheckType.COMMAND)); } @Test @@ -187,4 +192,52 @@ public class SimpleCommandPartTest { boolean guardResult = simpleGuardPart.guardCheck(new TestCommandSender(), new String[]{"world"}, 0); assertThat(guardResult, is(true)); } + + @Test + public void testOptionalCommandPartTabComplete() { + List tabCompletes = new ArrayList<>(); + optionalCommandPart.generateTabComplete(tabCompletes, new TestCommandSender(), new String[]{""}, 0); + assertThat(tabCompletes.size(), is(4)); + assertThat(tabCompletes.get(0), is("hello")); + assertThat(tabCompletes.get(1), is("world")); + assertThat(tabCompletes.get(2), is("hello2")); + assertThat(tabCompletes.get(3), is("world2")); + } + + @Test + public void testOptionalCommandPartTabCompleteSecond() { + List tabCompletes = new ArrayList<>(); + optionalCommandPart.generateTabComplete(tabCompletes, new TestCommandSender(), new String[]{"hello", ""}, 0); + assertThat(tabCompletes.size(), is(2)); + assertThat(tabCompletes.get(0), is("hello2")); + assertThat(tabCompletes.get(1), is("world2")); + } + + @Test(expected = CommandParseException.class) + public void testOptionalCommandPartExecution() { + optionalCommandPart.generateArgumentArray(new ArrayList<>(), new TestCommandSender(), new String[]{""}, 0); + } + + @Test + public void testOptionalCommandPartExecutionValid() { + List argumentArray = new ArrayList<>(); + optionalCommandPart.generateArgumentArray(argumentArray, new TestCommandSender(), new String[]{"hello2"}, 0); + assertThat(argumentArray.size(), is(2)); + assertThat(argumentArray.get(0), is("hello")); + assertThat(argumentArray.get(1), is("hello2")); + } + + @Test(expected = CommandParseException.class) + public void testOptionalCommandPartExecutionInvalid() { + optionalCommandPart.generateArgumentArray(new ArrayList<>(), new TestCommandSender(), new String[]{"hello"}, 0); + } + + @Test + public void testOptionalCommandPartExecutionFullyValid() { + List argumentArray = new ArrayList<>(); + optionalCommandPart.generateArgumentArray(argumentArray, new TestCommandSender(), new String[]{"world", "hello2"}, 0); + assertThat(argumentArray.size(), is(2)); + assertThat(argumentArray.get(0), is("world")); + assertThat(argumentArray.get(1), is("hello2")); + } }