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
Fortern committed Aug 12, 2024
1 parent 4c8d2ab commit 27dcafd
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 13 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 @@ -330,6 +330,7 @@ private ParseResults<S> parseNodes(final CommandNode<S> node, final StringReader
} while (reader.canRead() && reader.peek() == ARGUMENT_SEPARATOR_CHAR);
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
31 changes: 19 additions & 12 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 All @@ -27,23 +28,13 @@
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class CommandDispatcherTest {
Expand Down Expand Up @@ -409,6 +400,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
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
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 +53,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 27dcafd

Please sign in to comment.