Added a redirect option on nodes
This commit is contained in:
@@ -7,7 +7,6 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||||
import com.mojang.brigadier.exceptions.CommandException;
|
import com.mojang.brigadier.exceptions.CommandException;
|
||||||
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
|
|
||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
@@ -98,7 +97,11 @@ public class CommandDispatcher<S> {
|
|||||||
throw ERROR_EXPECTED_ARGUMENT_SEPARATOR.createWithContext(reader);
|
throw ERROR_EXPECTED_ARGUMENT_SEPARATOR.createWithContext(reader);
|
||||||
}
|
}
|
||||||
reader.skip();
|
reader.skip();
|
||||||
|
if (child.getRedirect() != null) {
|
||||||
|
return parseNodes(child.getRedirect(), reader, context.redirect());
|
||||||
|
} else {
|
||||||
return parseNodes(child, reader, context);
|
return parseNodes(child, reader, context);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return new ParseResults<>(context);
|
return new ParseResults<>(context);
|
||||||
}
|
}
|
||||||
@@ -122,7 +125,9 @@ public class CommandDispatcher<S> {
|
|||||||
result.add(prefix);
|
result.add(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node.getChildren().isEmpty()) {
|
if (node.getRedirect() != null) {
|
||||||
|
result.add(prefix.isEmpty() ? node.getUsageText() + ARGUMENT_SEPARATOR + "..." : prefix + ARGUMENT_SEPARATOR + "...");
|
||||||
|
} else if (!node.getChildren().isEmpty()) {
|
||||||
for (final CommandNode<S> child : node.getChildren()) {
|
for (final CommandNode<S> child : node.getChildren()) {
|
||||||
getAllUsage(child, source, result, prefix.isEmpty() ? child.getUsageText() : prefix + ARGUMENT_SEPARATOR + child.getUsageText());
|
getAllUsage(child, source, result, prefix.isEmpty() ? child.getUsageText() : prefix + ARGUMENT_SEPARATOR + child.getUsageText());
|
||||||
}
|
}
|
||||||
@@ -153,6 +158,9 @@ public class CommandDispatcher<S> {
|
|||||||
final String close = childOptional ? USAGE_OPTIONAL_CLOSE : USAGE_REQUIRED_CLOSE;
|
final String close = childOptional ? USAGE_OPTIONAL_CLOSE : USAGE_REQUIRED_CLOSE;
|
||||||
|
|
||||||
if (!deep) {
|
if (!deep) {
|
||||||
|
if (node.getRedirect() != null) {
|
||||||
|
return self + ARGUMENT_SEPARATOR + "...";
|
||||||
|
} else {
|
||||||
final Collection<CommandNode<S>> children = node.getChildren().stream().filter(c -> c.canUse(source)).collect(Collectors.toList());
|
final Collection<CommandNode<S>> children = node.getChildren().stream().filter(c -> c.canUse(source)).collect(Collectors.toList());
|
||||||
if (children.size() == 1) {
|
if (children.size() == 1) {
|
||||||
final String usage = getSmartUsage(children.iterator().next(), source, childOptional, childOptional);
|
final String usage = getSmartUsage(children.iterator().next(), source, childOptional, childOptional);
|
||||||
@@ -187,11 +195,15 @@ public class CommandDispatcher<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> findSuggestions(final CommandNode<S> node, final StringReader reader, final CommandContextBuilder<S> contextBuilder, final Set<String> result) {
|
private Set<String> findSuggestions(final CommandNode<S> node, final StringReader reader, final CommandContextBuilder<S> contextBuilder, final Set<String> result) {
|
||||||
|
if (node.getRedirect() != null) {
|
||||||
|
return findSuggestions(node.getRedirect(), reader, contextBuilder, result);
|
||||||
|
}
|
||||||
final S source = contextBuilder.getSource();
|
final S source = contextBuilder.getSource();
|
||||||
for (final CommandNode<S> child : node.getChildren()) {
|
for (final CommandNode<S> child : node.getChildren()) {
|
||||||
if (!child.canUse(source)) {
|
if (!child.canUse(source)) {
|
||||||
|
|||||||
@@ -11,10 +11,14 @@ public abstract class ArgumentBuilder<S, T extends ArgumentBuilder<S, T>> {
|
|||||||
private final RootCommandNode<S> arguments = new RootCommandNode<>();
|
private final RootCommandNode<S> arguments = new RootCommandNode<>();
|
||||||
private Command<S> command;
|
private Command<S> command;
|
||||||
private Predicate<S> requirement = s -> true;
|
private Predicate<S> requirement = s -> true;
|
||||||
|
private CommandNode<S> target;
|
||||||
|
|
||||||
protected abstract T getThis();
|
protected abstract T getThis();
|
||||||
|
|
||||||
public T then(final ArgumentBuilder<S, ?> argument) {
|
public T then(final ArgumentBuilder<S, ?> argument) {
|
||||||
|
if (target != null) {
|
||||||
|
throw new IllegalStateException("Cannot add children to a redirected node");
|
||||||
|
}
|
||||||
arguments.addChild(argument.build());
|
arguments.addChild(argument.build());
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
@@ -41,5 +45,17 @@ public abstract class ArgumentBuilder<S, T extends ArgumentBuilder<S, T>> {
|
|||||||
return requirement;
|
return requirement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T redirect(final CommandNode<S> target) {
|
||||||
|
if (!arguments.getChildren().isEmpty()) {
|
||||||
|
throw new IllegalStateException("Cannot redirect a node with children");
|
||||||
|
}
|
||||||
|
this.target = target;
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandNode<S> getRedirect() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract CommandNode<S> build();
|
public abstract CommandNode<S> build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class LiteralArgumentBuilder<S> extends ArgumentBuilder<S, LiteralArgumen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LiteralCommandNode<S> build() {
|
public LiteralCommandNode<S> build() {
|
||||||
final LiteralCommandNode<S> result = new LiteralCommandNode<>(getLiteral(), getCommand(), getRequirement());
|
final LiteralCommandNode<S> result = new LiteralCommandNode<>(getLiteral(), getCommand(), getRequirement(), getRedirect());
|
||||||
|
|
||||||
for (final CommandNode<S> argument : getArguments()) {
|
for (final CommandNode<S> argument : getArguments()) {
|
||||||
result.addChild(argument);
|
result.addChild(argument);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class RequiredArgumentBuilder<S, T> extends ArgumentBuilder<S, RequiredAr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ArgumentCommandNode<S, T> build() {
|
public ArgumentCommandNode<S, T> build() {
|
||||||
final ArgumentCommandNode<S, T> result = new ArgumentCommandNode<>(getName(), getType(), getCommand(), getRequirement());
|
final ArgumentCommandNode<S, T> result = new ArgumentCommandNode<>(getName(), getType(), getCommand(), getRequirement(), getRedirect());
|
||||||
|
|
||||||
for (final CommandNode<S> argument : getArguments()) {
|
for (final CommandNode<S> argument : getArguments()) {
|
||||||
result.addChild(argument);
|
result.addChild(argument);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.mojang.brigadier.context;
|
package com.mojang.brigadier.context;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.primitives.Primitives;
|
import com.google.common.primitives.Primitives;
|
||||||
import com.mojang.brigadier.Command;
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
@@ -14,13 +13,19 @@ public class CommandContext<S> {
|
|||||||
private final Map<String, ParsedArgument<S, ?>> arguments;
|
private final Map<String, ParsedArgument<S, ?>> arguments;
|
||||||
private final Map<CommandNode<S>, String> nodes;
|
private final Map<CommandNode<S>, String> nodes;
|
||||||
private final String input;
|
private final String input;
|
||||||
|
private final CommandContext<S> parent;
|
||||||
|
|
||||||
public CommandContext(final S source, final Map<String, ParsedArgument<S, ?>> arguments, final Command<S> command, final Map<CommandNode<S>, String> nodes, final String input) {
|
public CommandContext(final S source, final Map<String, ParsedArgument<S, ?>> arguments, final Command<S> command, final Map<CommandNode<S>, String> nodes, final String input, final CommandContext<S> parent) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.input = input;
|
this.input = input;
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandContext<S> getParent() {
|
||||||
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Command<S> getCommand() {
|
public Command<S> getCommand() {
|
||||||
@@ -58,6 +63,7 @@ public class CommandContext<S> {
|
|||||||
if (!Iterables.elementsEqual(nodes.entrySet(), that.nodes.entrySet())) return false;
|
if (!Iterables.elementsEqual(nodes.entrySet(), that.nodes.entrySet())) return false;
|
||||||
if (command != null ? !command.equals(that.command) : that.command != null) return false;
|
if (command != null ? !command.equals(that.command) : that.command != null) return false;
|
||||||
if (!source.equals(that.source)) return false;
|
if (!source.equals(that.source)) return false;
|
||||||
|
if (parent != null ? !parent.equals(that.parent) : that.parent != null) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -68,6 +74,7 @@ public class CommandContext<S> {
|
|||||||
result = 31 * result + arguments.hashCode();
|
result = 31 * result + arguments.hashCode();
|
||||||
result = 31 * result + (command != null ? command.hashCode() : 0);
|
result = 31 * result + (command != null ? command.hashCode() : 0);
|
||||||
result = 31 * result + nodes.hashCode();
|
result = 31 * result + nodes.hashCode();
|
||||||
|
result = 31 * result + (parent != null ? parent.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class CommandContextBuilder<S> {
|
|||||||
private final StringBuilder input = new StringBuilder();
|
private final StringBuilder input = new StringBuilder();
|
||||||
private S source;
|
private S source;
|
||||||
private Command<S> command;
|
private Command<S> command;
|
||||||
|
private CommandContext<S> parent;
|
||||||
|
|
||||||
public CommandContextBuilder(final CommandDispatcher<S> dispatcher, final S source) {
|
public CommandContextBuilder(final CommandDispatcher<S> dispatcher, final S source) {
|
||||||
this.dispatcher = dispatcher;
|
this.dispatcher = dispatcher;
|
||||||
@@ -54,13 +55,24 @@ public class CommandContextBuilder<S> {
|
|||||||
|
|
||||||
public CommandContextBuilder<S> copy() {
|
public CommandContextBuilder<S> copy() {
|
||||||
final CommandContextBuilder<S> copy = new CommandContextBuilder<>(dispatcher, source);
|
final CommandContextBuilder<S> copy = new CommandContextBuilder<>(dispatcher, source);
|
||||||
copy.command = this.command;
|
copy.command = command;
|
||||||
copy.arguments.putAll(arguments);
|
copy.arguments.putAll(arguments);
|
||||||
copy.nodes.putAll(this.nodes);
|
copy.nodes.putAll(nodes);
|
||||||
copy.input.append(input);
|
copy.input.append(input);
|
||||||
|
copy.parent = parent;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandContextBuilder<S> redirect() {
|
||||||
|
final CommandContextBuilder<S> result = new CommandContextBuilder<>(dispatcher, source);
|
||||||
|
result.parent = build();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandContext<S> getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
public String getInput() {
|
public String getInput() {
|
||||||
return input.toString();
|
return input.toString();
|
||||||
}
|
}
|
||||||
@@ -70,7 +82,7 @@ public class CommandContextBuilder<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CommandContext<S> build() {
|
public CommandContext<S> build() {
|
||||||
return new CommandContext<>(source, arguments, command, nodes, input.toString());
|
return new CommandContext<>(source, arguments, command, nodes, input.toString(), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandDispatcher<S> getDispatcher() {
|
public CommandDispatcher<S> getDispatcher() {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final ArgumentType<T> type;
|
private final ArgumentType<T> type;
|
||||||
|
|
||||||
public ArgumentCommandNode(final String name, final ArgumentType<T> type, final Command<S> command, final Predicate<S> requirement) {
|
public ArgumentCommandNode(final String name, final ArgumentType<T> type, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect) {
|
||||||
super(command, requirement);
|
super(command, requirement, redirect);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
@@ -69,6 +69,7 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
|
|||||||
public RequiredArgumentBuilder<S, T> createBuilder() {
|
public RequiredArgumentBuilder<S, T> createBuilder() {
|
||||||
final RequiredArgumentBuilder<S, T> builder = RequiredArgumentBuilder.argument(name, type);
|
final RequiredArgumentBuilder<S, T> builder = RequiredArgumentBuilder.argument(name, type);
|
||||||
builder.requires(getRequirement());
|
builder.requires(getRequirement());
|
||||||
|
builder.redirect(getRedirect());
|
||||||
if (getCommand() != null) {
|
if (getCommand() != null) {
|
||||||
builder.executes(getCommand());
|
builder.executes(getCommand());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ import java.util.stream.Collectors;
|
|||||||
public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
||||||
private Map<Object, CommandNode<S>> children = Maps.newLinkedHashMap();
|
private Map<Object, CommandNode<S>> children = Maps.newLinkedHashMap();
|
||||||
private final Predicate<S> requirement;
|
private final Predicate<S> requirement;
|
||||||
|
private final CommandNode<S> redirect;
|
||||||
private Command<S> command;
|
private Command<S> command;
|
||||||
|
|
||||||
protected CommandNode(final Command<S> command, final Predicate<S> requirement) {
|
protected CommandNode(final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect) {
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.requirement = requirement;
|
this.requirement = requirement;
|
||||||
|
this.redirect = redirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Command<S> getCommand() {
|
public Command<S> getCommand() {
|
||||||
@@ -33,6 +35,10 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
|||||||
return children.values();
|
return children.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandNode<S> getRedirect() {
|
||||||
|
return redirect;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canUse(final S source) {
|
public boolean canUse(final S source) {
|
||||||
return requirement.test(source);
|
return requirement.test(source);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
|
|||||||
|
|
||||||
private final String literal;
|
private final String literal;
|
||||||
|
|
||||||
public LiteralCommandNode(final String literal, final Command<S> command, final Predicate<S> requirement) {
|
public LiteralCommandNode(final String literal, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect) {
|
||||||
super(command, requirement);
|
super(command, requirement, redirect);
|
||||||
this.literal = literal;
|
this.literal = literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +78,7 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
|
|||||||
public LiteralArgumentBuilder<S> createBuilder() {
|
public LiteralArgumentBuilder<S> createBuilder() {
|
||||||
final LiteralArgumentBuilder<S> builder = LiteralArgumentBuilder.literal(this.literal);
|
final LiteralArgumentBuilder<S> builder = LiteralArgumentBuilder.literal(this.literal);
|
||||||
builder.requires(getRequirement());
|
builder.requires(getRequirement());
|
||||||
|
builder.redirect(getRedirect());
|
||||||
if (getCommand() != null) {
|
if (getCommand() != null) {
|
||||||
builder.executes(getCommand());
|
builder.executes(getCommand());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class RootCommandNode<S> extends CommandNode<S> {
|
public class RootCommandNode<S> extends CommandNode<S> {
|
||||||
public RootCommandNode() {
|
public RootCommandNode() {
|
||||||
super(null, c -> true);
|
super(null, c -> true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ public class CommandDispatcherCompletionsTest {
|
|||||||
assertThat(subject.getCompletionSuggestions("q", source), is(emptyArray()));
|
assertThat(subject.getCompletionSuggestions("q", source), is(emptyArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommand_redirect() throws Exception {
|
||||||
|
subject.register(literal("foo"));
|
||||||
|
subject.register(literal("bar"));
|
||||||
|
subject.register(literal("redirect").redirect(subject.getRoot()));
|
||||||
|
assertThat(subject.getCompletionSuggestions("redirect ", source), equalTo(new String[]{"bar", "foo", "redirect"}));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSubCommand() throws Exception {
|
public void testSubCommand() throws Exception {
|
||||||
subject.register(literal("foo").then(literal("abc")).then(literal("def")).then(literal("ghi").requires(s -> false)));
|
subject.register(literal("foo").then(literal("abc")).then(literal("def")).then(literal("ghi").requires(s -> false)));
|
||||||
|
|||||||
@@ -14,9 +14,12 @@ import java.util.Collections;
|
|||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
||||||
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Matchers.notNull;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
@@ -164,6 +167,30 @@ public class CommandDispatcherTest {
|
|||||||
verify(subCommand).run(any(CommandContext.class));
|
verify(subCommand).run(any(CommandContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testExecuteRedirected() throws Exception {
|
||||||
|
subject.register(literal("actual").executes(command));
|
||||||
|
subject.register(literal("redirected").redirect(subject.getRoot()));
|
||||||
|
|
||||||
|
final ParseResults<Object> parse = subject.parse("redirected redirected actual", source);
|
||||||
|
assertThat(parse.getContext().getInput(), equalTo("actual"));
|
||||||
|
assertThat(parse.getContext().getNodes().size(), is(1));
|
||||||
|
|
||||||
|
final CommandContext<Object> parent1 = parse.getContext().getParent();
|
||||||
|
assertThat(parent1, is(notNullValue()));
|
||||||
|
assertThat(parent1.getInput(), equalTo("redirected"));
|
||||||
|
assertThat(parent1.getNodes().size(), is(1));
|
||||||
|
|
||||||
|
final CommandContext<Object> parent2 = parent1.getParent();
|
||||||
|
assertThat(parent2, is(notNullValue()));
|
||||||
|
assertThat(parent2.getInput(), equalTo("redirected"));
|
||||||
|
assertThat(parent2.getNodes().size(), is(1));
|
||||||
|
|
||||||
|
assertThat(subject.execute(parse), is(42));
|
||||||
|
verify(command).run(any(CommandContext.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecuteOrphanedSubcommand() throws Exception {
|
public void testExecuteOrphanedSubcommand() throws Exception {
|
||||||
subject.register(literal("foo").then(
|
subject.register(literal("foo").then(
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ public class CommandDispatcherUsagesTest {
|
|||||||
.then(literal("1").executes(command))
|
.then(literal("1").executes(command))
|
||||||
.then(literal("2").executes(command))
|
.then(literal("2").executes(command))
|
||||||
);
|
);
|
||||||
|
subject.register(
|
||||||
|
literal("j")
|
||||||
|
.redirect(subject.getRoot())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandNode<Object> get(final String command) {
|
private CommandNode<Object> get(final String command) {
|
||||||
@@ -136,6 +140,7 @@ public class CommandDispatcherUsagesTest {
|
|||||||
"i",
|
"i",
|
||||||
"i 1",
|
"i 1",
|
||||||
"i 2",
|
"i 2",
|
||||||
|
"j ...",
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +156,7 @@ public class CommandDispatcherUsagesTest {
|
|||||||
.put(get("g"), "g [1]")
|
.put(get("g"), "g [1]")
|
||||||
.put(get("h"), "h [1|2|3]")
|
.put(get("h"), "h [1|2|3]")
|
||||||
.put(get("i"), "i [1|2]")
|
.put(get("i"), "i [1|2]")
|
||||||
|
.put(get("j"), "j ...")
|
||||||
.build()
|
.build()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ package com.mojang.brigadier.builder;
|
|||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
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 com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
public class ArgumentBuilderTest {
|
public class ArgumentBuilderTest {
|
||||||
private TestableArgumentBuilder<Object> builder;
|
private TestableArgumentBuilder<Object> builder;
|
||||||
@@ -28,6 +32,27 @@ public class ArgumentBuilderTest {
|
|||||||
assertThat(builder.getArguments(), hasItem((CommandNode<Object>) argument.build()));
|
assertThat(builder.getArguments(), hasItem((CommandNode<Object>) argument.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRedirect() throws Exception {
|
||||||
|
final CommandNode<Object> target = mock(CommandNode.class);
|
||||||
|
builder.redirect(target);
|
||||||
|
assertThat(builder.getRedirect(), is(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void testRedirect_withChild() throws Exception {
|
||||||
|
final CommandNode<Object> target = mock(CommandNode.class);
|
||||||
|
builder.then(literal("foo"));
|
||||||
|
builder.redirect(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void testThen_withRedirect() throws Exception {
|
||||||
|
final CommandNode<Object> target = mock(CommandNode.class);
|
||||||
|
builder.redirect(target);
|
||||||
|
builder.then(literal("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
private static class TestableArgumentBuilder<S> extends ArgumentBuilder<S, TestableArgumentBuilder<S>> {
|
private static class TestableArgumentBuilder<S> extends ArgumentBuilder<S, TestableArgumentBuilder<S>> {
|
||||||
@Override
|
@Override
|
||||||
protected TestableArgumentBuilder<S> getThis() {
|
protected TestableArgumentBuilder<S> getThis() {
|
||||||
|
|||||||
Reference in New Issue
Block a user