Skip to content

Commit

Permalink
Make sure arguments are preserved after redirects
Browse files Browse the repository at this point in the history
  • Loading branch information
willkroboth committed Nov 14, 2023
1 parent b92c420 commit 11036b6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/mojang/brigadier/CommandDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ private ParseResults<S> parseNodes(final CommandNode<S> node, final StringReader
reader.skip();
if (child.getRedirect() != null) {
final CommandContextBuilder<S> childContext = new CommandContextBuilder<>(this, source, child.getRedirect(), reader.getCursor());
childContext.withArguments(context.getArguments());
final ParseResults<S> parse = parseNodes(child.getRedirect(), reader, childContext);
context.withChild(parse.getContext());
return new ParseResults<>(context, parse.getReader(), parse.getExceptions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public CommandContextBuilder<S> withArgument(final String name, final ParsedArgu
return this;
}

public CommandContextBuilder<S> withArguments(Map<String, ParsedArgument<S, ?>> arguments) {
this.arguments.putAll(arguments);
return this;
}

public Map<String, ParsedArgument<S, ?>> getArguments() {
return arguments;
}
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/com/mojang/brigadier/CommandDispatcherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.tree.ArgumentCommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import org.hamcrest.CustomMatcher;
Expand Down Expand Up @@ -409,6 +410,22 @@ public void testRedirectModifierEmptyResult() throws CommandSyntaxException {
assertThat(result, is(0)); // No commands executed, so result is 0
}

@Test
public void testRedirectPreservesPreviousArguments() throws CommandSyntaxException {
final LiteralCommandNode<Object> ending = literal("ending")
.executes(context -> context.getArgument("number", int.class)).build();
final ArgumentCommandNode<Object, Integer> lowNumber = argument("number", integer(1, 10))
.then(ending).build();
final ArgumentCommandNode<Object, Integer> highNumber = argument("number", integer(11, 20))
.redirect(lowNumber).build();
subject.register(literal("base")
.then(literal("low").then(lowNumber))
.then(literal("high").then(highNumber)));

assertThat(subject.execute("base low 5 ending", source), is(5));
assertThat(subject.execute("base high 15 ending", source), is(15));
}

@Test
public void testExecuteOrphanedSubcommand() {
subject.register(literal("foo").then(
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/com/mojang/brigadier/CommandSuggestionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,26 @@ public void getCompletionSuggestions_redirect_lots() throws Exception {
assertThat(result.getList(), equalTo(Lists.newArrayList(new Suggestion(StringRange.at(33), "loop"))));
}

@Test
public void getCompletionSuggestions_redirectPreservesArguments() throws Exception {
subject.register(literal("command")
.then(
argument("first", integer())
.then(
argument("second", integer())
.suggests((context, builder) -> {
builder.suggest(String.valueOf(context.getLastChild().getArgument("first", int.class) + 1));
return builder.buildFuture();
})
)
));
subject.register(literal("redirect").redirect(subject.getRoot()));

testSuggestions("command 1 ", 10, StringRange.at(10), "2");
testSuggestions("redirect command 1 ", 19, StringRange.at(19), "2");
testSuggestions("redirect redirect command 1 ", 28, StringRange.at(28), "2");
}

@Test
public void getCompletionSuggestions_execute_simulation() throws Exception {
final LiteralCommandNode<Object> execute = subject.register(literal("execute"));
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/com/mojang/brigadier/context/CommandContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -51,6 +54,16 @@ public void testGetArgument() throws Exception {
assertThat(context.getArgument("foo", int.class), is(123));
}

@Test
public void testGetArguments() throws Exception {
Map<String, ParsedArgument<Object, ?>> arguments = new HashMap<>();
arguments.put("foo", new ParsedArgument<>(0, 1, 123));
arguments.put("bar", new ParsedArgument<>(0, 1, "123"));
final CommandContext<Object> context = builder.withArguments(arguments).build("123");
assertThat(context.getArgument("foo", int.class), is(123));
assertThat(context.getArgument("bar", String.class), is("123"));
}

@Test
public void testSource() throws Exception {
assertThat(builder.build("").getSource(), is(source));
Expand Down

0 comments on commit 11036b6

Please sign in to comment.