From 6c63b47e5ed2fb4748d120abf72380f99b64afdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 18 Oct 2020 21:36:58 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20multiple=20chained=20optio?= =?UTF-8?q?nals=20not=20working=20correctly=20(#73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :bug: Fix multiple chained optionals not working correctly There is a problem where the child arguments never forwarded their commands correctly. This will now fix itself when necessary. * :books: Add CHANGELOG entry for change --- CHANGELOG.md | 2 ++ .../java/cloud/commandframework/CommandTree.java | 15 ++++++++++++++- .../cloud/commandframework/CommandTreeTest.java | 12 ++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b9e3385..d71fe7b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixes + - Fixes chained optionals not allowing the command to be executed when more than one optional is omitted ## [1.0.1] - 2020-10-14 diff --git a/cloud-core/src/main/java/cloud/commandframework/CommandTree.java b/cloud-core/src/main/java/cloud/commandframework/CommandTree.java index 21b6f161..7e8bb5fb 100644 --- a/cloud-core/src/main/java/cloud/commandframework/CommandTree.java +++ b/cloud-core/src/main/java/cloud/commandframework/CommandTree.java @@ -287,7 +287,20 @@ public final class CommandTree { if (child.getValue().hasDefaultValue()) { commandQueue.add(child.getValue().getDefaultValue()); } else if (!child.getValue().isRequired()) { - return Pair.of(this.cast(child.getValue().getOwningCommand()), null); + if (child.getValue().getOwningCommand() == null) { + /* + * If there are multiple children with different owning commands then it's ambiguous and + * not allowed, therefore we're able to pick any child command, as long as we can find it + */ + Node> node = child; + while (!node.isLeaf()) { + node = node.getChildren().get(0); + if (node.getValue() != null && node.getValue().getOwningCommand() != null) { + child.getValue().setOwningCommand(node.getValue().getOwningCommand()); + } + } + } + return Pair.of(child.getValue().getOwningCommand(), null); } else if (child.isLeaf()) { if (root.getValue() != null && root.getValue().getOwningCommand() != null) { final Command command = root.getValue().getOwningCommand(); diff --git a/cloud-core/src/test/java/cloud/commandframework/CommandTreeTest.java b/cloud-core/src/test/java/cloud/commandframework/CommandTreeTest.java index 6f3adc02..1f6acfa2 100644 --- a/cloud-core/src/test/java/cloud/commandframework/CommandTreeTest.java +++ b/cloud-core/src/test/java/cloud/commandframework/CommandTreeTest.java @@ -143,6 +143,13 @@ class CommandTreeTest { .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")) + ); } @Test @@ -301,6 +308,11 @@ class CommandTreeTest { ); } + @Test + void testOptionals() { + manager.executeCommand(new TestCommandSender(), "optionals").join(); + } + public static final class SpecificCommandSender extends TestCommandSender {