diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java index c30cc8d..e4732e8 100644 --- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java +++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java @@ -93,6 +93,8 @@ public class CommandDispatcher { * @return the node added to this tree */ public LiteralCommandNode register(final LiteralArgumentBuilder command) { + if(command.isDefaultNode()) throw new IllegalArgumentException("Cannot add a default node to root"); + final LiteralCommandNode build = command.build(); root.addChild(build); return build; diff --git a/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java b/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java index 420bd90..9509390 100644 --- a/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java +++ b/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java @@ -21,8 +21,7 @@ import java.util.function.Predicate; public class LiteralCommandNode extends CommandNode { private final String literal; - - + public LiteralCommandNode(final String literal, final Command command, final Predicate requirement, final CommandNode redirect, final RedirectModifier modifier, final boolean forks) { this(literal, command, requirement, redirect, modifier, forks, null, false); } diff --git a/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java b/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java index ff8127f..dcd3fcc 100644 --- a/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java +++ b/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java @@ -53,6 +53,11 @@ public class CommandDispatcherTest { return result; } + @Test(expected = IllegalArgumentException.class) + public void testRegisterDefaultNode() throws Exception { + subject.register(defaultLiteral("foo")); + } + @SuppressWarnings("unchecked") @Test public void testCreateAndExecuteCommand() throws Exception { diff --git a/src/test/java/com/mojang/brigadier/CommandDispatcherUsagesTest.java b/src/test/java/com/mojang/brigadier/CommandDispatcherUsagesTest.java index 62e13c6..0cf3ad9 100644 --- a/src/test/java/com/mojang/brigadier/CommandDispatcherUsagesTest.java +++ b/src/test/java/com/mojang/brigadier/CommandDispatcherUsagesTest.java @@ -13,7 +13,9 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.util.Map; +import java.util.stream.Collectors; +import static com.mojang.brigadier.builder.LiteralArgumentBuilder.defaultLiteral; import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.emptyArray; @@ -97,14 +99,28 @@ public class CommandDispatcherUsagesTest { literal("k") .redirect(get("h")) ); + //default node tests + subject.register( + literal("l") + //basic + .then(defaultLiteral("1").executes(command)) + //two choices + .then(literal("2") + .then(defaultLiteral("i").executes(command)) + .then(literal("ii").executes(command))) + //chained + .then(literal("3").then(defaultLiteral("i").then(defaultLiteral("ii").executes(command)))) + //unexecutable default node + .then(literal("4").then(defaultLiteral("i").then(literal("ii").executes(command)))) + ); } private CommandNode get(final String command) { - return Iterables.getLast(subject.parse(command, source).getContext().getNodes()).getNode(); + return Iterables.getLast(subject.parse(command, source).getContext().getNodes().stream().filter(n -> !n.getRange().isEmpty()).collect(Collectors.toList())).getNode(); } private CommandNode get(final StringReader command) { - return Iterables.getLast(subject.parse(command, source).getContext().getNodes()).getNode(); + return Iterables.getLast(subject.parse(command, source).getContext().getNodes().stream().filter(n -> !n.getRange().isEmpty()).collect(Collectors.toList())).getNode(); } @Test @@ -148,6 +164,15 @@ public class CommandDispatcherUsagesTest { "i 2", "j ...", "k -> h", + "l", + "l 1", + "l 2", + "l 2 i", + "l 2 ii", + "l 3", + "l 3 i", + "l 3 i ii", + "l 4 i ii", })); } @@ -165,6 +190,7 @@ public class CommandDispatcherUsagesTest { .put(get("i"), "i [1|2]") .put(get("j"), "j ...") .put(get("k"), "k -> h") + .put(get("l"), "l [1|2|3|4]") .build() )); } @@ -193,4 +219,16 @@ public class CommandDispatcherUsagesTest { .build() )); } + + @Test + public void testSmartUsage_l() throws Exception { + final Map, String> results = subject.getSmartUsage(get("l"), source); + assertThat(results, equalTo(ImmutableMap.builder() + .put(get("l 1"), "1") + .put(get("l 2"), "2 [i|ii]") + .put(get("l 3"), "3 [i]") + .put(get("l 4"), "4 i ii") + .build() + )); + } } \ No newline at end of file diff --git a/src/test/java/com/mojang/brigadier/builder/ArgumentBuilderTest.java b/src/test/java/com/mojang/brigadier/builder/ArgumentBuilderTest.java index 57eb623..94181af 100644 --- a/src/test/java/com/mojang/brigadier/builder/ArgumentBuilderTest.java +++ b/src/test/java/com/mojang/brigadier/builder/ArgumentBuilderTest.java @@ -4,10 +4,12 @@ package com.mojang.brigadier.builder; import com.mojang.brigadier.tree.CommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; import org.junit.Before; import org.junit.Test; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; +import static com.mojang.brigadier.builder.LiteralArgumentBuilder.defaultLiteral; import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument; import static org.hamcrest.Matchers.hasSize; @@ -55,6 +57,20 @@ public class ArgumentBuilderTest { builder.then(literal("foo")); } + @Test + public void testThen_withDefaultNode() throws Exception { + final LiteralCommandNode child = defaultLiteral("foo").build(); + builder.then(child); + + assertThat(builder.getDefaultNode(), is(child)); + } + + @Test(expected = IllegalStateException.class) + public void testThen_withTwoDefaultNodes() throws Exception { + builder.then(defaultLiteral("foo")); + builder.then(defaultLiteral("bar")); + } + private static class TestableArgumentBuilder extends ArgumentBuilder> { public TestableArgumentBuilder() { super(false); diff --git a/src/test/java/com/mojang/brigadier/builder/RequiredArgumentBuilderTest.java b/src/test/java/com/mojang/brigadier/builder/RequiredArgumentBuilderTest.java index d57ca55..a9a026c 100644 --- a/src/test/java/com/mojang/brigadier/builder/RequiredArgumentBuilderTest.java +++ b/src/test/java/com/mojang/brigadier/builder/RequiredArgumentBuilderTest.java @@ -17,6 +17,7 @@ import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument; import static com.mojang.brigadier.builder.RequiredArgumentBuilder.defaultArgument; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; @RunWith(MockitoJUnitRunner.class) @@ -40,6 +41,7 @@ public class RequiredArgumentBuilderTest { assertThat(node.getName(), is("foo")); assertThat(node.getType(), is(type)); assertThat(node.isDefaultNode(), is(false)); + assertThat(node.getDefaultValue(), is(nullValue())); } @Test