Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure arguments are preserved after redirects #142

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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