From a6db68fa66c44688d3e8d3022056a353b3ad7a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Tue, 22 Sep 2020 18:45:26 +0200 Subject: [PATCH] Fix quoted strings --- .../arguments/standard/StringArgument.java | 47 +++++++-- .../commands/TestCommandManager.java | 5 +- .../standard/StringArgumentTest.java | 95 +++++++++++++++++++ 3 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 cloud-core/src/test/java/com/intellectualsites/commands/arguments/standard/StringArgumentTest.java diff --git a/cloud-core/src/main/java/com/intellectualsites/commands/arguments/standard/StringArgument.java b/cloud-core/src/main/java/com/intellectualsites/commands/arguments/standard/StringArgument.java index 509463b7..ed862a7f 100644 --- a/cloud-core/src/main/java/com/intellectualsites/commands/arguments/standard/StringArgument.java +++ b/cloud-core/src/main/java/com/intellectualsites/commands/arguments/standard/StringArgument.java @@ -63,7 +63,7 @@ public final class StringArgument extends CommandArgument { } /** - * Create a new required command argument + * Create a new required single string command argument * * @param name Argument name * @param Command sender type @@ -71,11 +71,24 @@ public final class StringArgument extends CommandArgument { */ @Nonnull public static CommandArgument required(@Nonnull final String name) { - return StringArgument.newBuilder(name).asRequired().build(); + return StringArgument.newBuilder(name).single().asRequired().build(); } /** - * Create a new optional command argument + * Create a new required command argument + * + * @param name Argument name + * @param stringMode String mode + * @param Command sender type + * @return Created argument + */ + @Nonnull + public static CommandArgument required(@Nonnull final String name, @Nonnull final StringMode stringMode) { + return StringArgument.newBuilder(name).withMode(stringMode).asRequired().build(); + } + + /** + * Create a new optional single string command argument * * @param name Argument name * @param Command sender type @@ -83,7 +96,20 @@ public final class StringArgument extends CommandArgument { */ @Nonnull public static CommandArgument optional(@Nonnull final String name) { - return StringArgument.newBuilder(name).asOptional().build(); + return StringArgument.newBuilder(name).single().asOptional().build(); + } + + /** + * Create a new optional command argument + * + * @param name Argument name + * @param stringMode String mode + * @param Command sender type + * @return Created argument + */ + @Nonnull + public static CommandArgument optional(@Nonnull final String name, @Nonnull final StringMode stringMode) { + return StringArgument.newBuilder(name).withMode(stringMode).asOptional().build(); } /** @@ -127,6 +153,12 @@ public final class StringArgument extends CommandArgument { super(String.class, name); } + @Nonnull + private Builder withMode(@Nonnull final StringMode stringMode) { + this.stringMode = stringMode; + return this; + } + /** * Set the string mode to greedy * @@ -234,7 +266,7 @@ public final class StringArgument extends CommandArgument { boolean finished = false; for (int i = 0; i < size; i++) { - final String string = inputQueue.peek(); + String string = inputQueue.peek(); if (string == null) { break; @@ -243,7 +275,7 @@ public final class StringArgument extends CommandArgument { if (this.stringMode == StringMode.QUOTED) { if (!started) { if (string.startsWith("\"")) { - sj.add(string.substring(1)); + string = string.substring(1); started = true; } else { return ArgumentParseResult.failure(new StringParseException(string, StringMode.QUOTED)); @@ -256,7 +288,8 @@ public final class StringArgument extends CommandArgument { } } - sj.add(inputQueue.remove()); + sj.add(string); + inputQueue.remove(); } if (this.stringMode == StringMode.QUOTED && (!started || !finished)) { diff --git a/cloud-core/src/test/java/com/intellectualsites/commands/TestCommandManager.java b/cloud-core/src/test/java/com/intellectualsites/commands/TestCommandManager.java index 2b9ad31b..4f204603 100644 --- a/cloud-core/src/test/java/com/intellectualsites/commands/TestCommandManager.java +++ b/cloud-core/src/test/java/com/intellectualsites/commands/TestCommandManager.java @@ -31,7 +31,10 @@ import javax.annotation.Nonnull; public class TestCommandManager extends CommandManager { - protected TestCommandManager() { + /** + * Construct a new test command manager + */ + public TestCommandManager() { super(CommandExecutionCoordinator.simpleCoordinator(), CommandRegistrationHandler.nullCommandRegistrationHandler()); } diff --git a/cloud-core/src/test/java/com/intellectualsites/commands/arguments/standard/StringArgumentTest.java b/cloud-core/src/test/java/com/intellectualsites/commands/arguments/standard/StringArgumentTest.java new file mode 100644 index 00000000..d8349b30 --- /dev/null +++ b/cloud-core/src/test/java/com/intellectualsites/commands/arguments/standard/StringArgumentTest.java @@ -0,0 +1,95 @@ +// +// 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.arguments.standard; + +import com.intellectualsites.commands.CommandManager; +import com.intellectualsites.commands.TestCommandManager; +import com.intellectualsites.commands.TestCommandSender; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class StringArgumentTest { + + private static final String[] storage = new String[2]; + private static CommandManager manager; + + @BeforeAll + static void setup() { + manager = new TestCommandManager(); + manager.command(manager.commandBuilder("quoted") + .argument(StringArgument.required("message1", StringArgument.StringMode.QUOTED)) + .argument(StringArgument.required("message2")) + .handler(c -> { + final String message1 = c.getRequired("message1"); + final String message2 = c.getRequired("message2"); + storage[0] = message1; + storage[1] = message2; + }) + .build()); + manager.command(manager.commandBuilder("single") + .argument(StringArgument.required("message")) + .handler(c -> { + final String message = c.getRequired("message"); + storage[0] = message; + }) + .build()); + manager.command(manager.commandBuilder("greedy") + .argument(StringArgument.required("message", StringArgument.StringMode.GREEDY)) + .handler(c -> { + final String message = c.getRequired("message"); + storage[0] = message; + }) + .build()); + } + + private static void clear() { + storage[0] = storage[1] = null; + } + + @Test + void testSingle() { + clear(); + manager.executeCommand(new TestCommandSender(), "single string"); + Assertions.assertEquals("string", storage[0]); + } + + @Test + void testQuotes() { + clear(); + manager.executeCommand(new TestCommandSender(), "quoted \"quoted string\" unquoted").join(); + Assertions.assertEquals("quoted string", storage[0]); + Assertions.assertEquals("unquoted", storage[1]); + } + + @Test + void testGreedy() { + clear(); + manager.executeCommand(new TestCommandSender(), "greedy greedy string content").join(); + Assertions.assertEquals("greedy string content", storage[0]); + } + +}