Made all exceptions throw with context
This commit is contained in:
parent
9276feddd4
commit
5181559f46
16 changed files with 275 additions and 61 deletions
|
@ -22,7 +22,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class CommandDispatcher<S> {
|
||||
public static final SimpleCommandExceptionType ERROR_UNKNOWN_COMMAND = new SimpleCommandExceptionType("command.unknown.command", "Unknown command");
|
||||
public static final ParameterizedCommandExceptionType ERROR_UNKNOWN_ARGUMENT = new ParameterizedCommandExceptionType("command.unknown.argument", "Incorrect argument for command, couldn't parse: ${argument}", "argument");
|
||||
public static final SimpleCommandExceptionType ERROR_UNKNOWN_ARGUMENT = new SimpleCommandExceptionType("command.unknown.argument", "Incorrect argument for command");
|
||||
public static final SimpleCommandExceptionType ERROR_EXPECTED_ARGUMENT_SEPARATOR = new SimpleCommandExceptionType("command.expected.separator", "Expected whitespace to end one argument, but found trailing data");
|
||||
|
||||
public static final String ARGUMENT_SEPARATOR = " ";
|
||||
|
@ -52,19 +52,19 @@ public class CommandDispatcher<S> {
|
|||
}
|
||||
|
||||
public int execute(final ParseResults<S> parse) throws CommandException {
|
||||
if (parse.getRemaining().length() > 0) {
|
||||
if (parse.getReader().canRead()) {
|
||||
if (parse.getExceptions().size() == 1) {
|
||||
throw parse.getExceptions().values().iterator().next();
|
||||
} else if (parse.getContext().getInput().isEmpty()) {
|
||||
throw ERROR_UNKNOWN_COMMAND.create();
|
||||
throw ERROR_UNKNOWN_COMMAND.createWithContext(parse.getReader());
|
||||
} else {
|
||||
throw ERROR_UNKNOWN_ARGUMENT.create(parse.getRemaining());
|
||||
throw ERROR_UNKNOWN_ARGUMENT.createWithContext(parse.getReader());
|
||||
}
|
||||
}
|
||||
final CommandContext<S> context = parse.getContext().build();
|
||||
final Command<S> command = context.getCommand();
|
||||
if (command == null) {
|
||||
throw ERROR_UNKNOWN_COMMAND.create();
|
||||
throw ERROR_UNKNOWN_COMMAND.createWithContext(parse.getReader());
|
||||
}
|
||||
return command.run(context);
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class CommandDispatcher<S> {
|
|||
context.withCommand(child.getCommand());
|
||||
if (reader.canRead()) {
|
||||
if (reader.peek() != ARGUMENT_SEPARATOR_CHAR) {
|
||||
throw ERROR_EXPECTED_ARGUMENT_SEPARATOR.create();
|
||||
throw ERROR_EXPECTED_ARGUMENT_SEPARATOR.createWithContext(reader);
|
||||
}
|
||||
reader.skip();
|
||||
return parseNodes(child, reader, context);
|
||||
|
@ -104,7 +104,7 @@ public class CommandDispatcher<S> {
|
|||
}
|
||||
}
|
||||
|
||||
return new ParseResults<>(contextBuilder, reader.getRemaining(), errors);
|
||||
return new ParseResults<>(contextBuilder, reader, errors);
|
||||
}
|
||||
|
||||
public String[] getAllUsage(final CommandNode<S> node, final S source) {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.mojang.brigadier;
|
||||
|
||||
public interface ImmutableStringReader {
|
||||
String getString();
|
||||
|
||||
int getRemainingLength();
|
||||
|
||||
int getTotalLength();
|
||||
|
||||
int getCursor();
|
||||
|
||||
String getRead();
|
||||
|
||||
String getRemaining();
|
||||
|
||||
boolean canRead(int length);
|
||||
|
||||
boolean canRead();
|
||||
|
||||
char peek();
|
||||
|
||||
char peek(int offset);
|
||||
}
|
|
@ -9,25 +9,25 @@ import java.util.Map;
|
|||
|
||||
public class ParseResults<S> {
|
||||
private final CommandContextBuilder<S> context;
|
||||
private final String remaining;
|
||||
private final Map<CommandNode<S>, CommandException> exceptions;
|
||||
private final ImmutableStringReader reader;
|
||||
|
||||
public ParseResults(final CommandContextBuilder<S> context, final String remaining, final Map<CommandNode<S>, CommandException> exceptions) {
|
||||
public ParseResults(final CommandContextBuilder<S> context, final ImmutableStringReader reader, final Map<CommandNode<S>, CommandException> exceptions) {
|
||||
this.context = context;
|
||||
this.remaining = remaining;
|
||||
this.reader = reader;
|
||||
this.exceptions = exceptions;
|
||||
}
|
||||
|
||||
public ParseResults(final CommandContextBuilder<S> context) {
|
||||
this(context, "", Collections.emptyMap());
|
||||
this(context, new StringReader(""), Collections.emptyMap());
|
||||
}
|
||||
|
||||
public CommandContextBuilder<S> getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public String getRemaining() {
|
||||
return remaining;
|
||||
public ImmutableStringReader getReader() {
|
||||
return reader;
|
||||
}
|
||||
|
||||
public Map<CommandNode<S>, CommandException> getExceptions() {
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.mojang.brigadier.exceptions.CommandException;
|
|||
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
|
||||
public class StringReader {
|
||||
public class StringReader implements ImmutableStringReader {
|
||||
private static final char SYNTAX_ESCAPE = '\\';
|
||||
private static final char SYNTAX_QUOTE = '"';
|
||||
|
||||
|
@ -16,6 +16,7 @@ public class StringReader {
|
|||
public static final SimpleCommandExceptionType ERROR_EXPECTED_INT = new SimpleCommandExceptionType("parsing.int.expected", "Expected integer");
|
||||
public static final ParameterizedCommandExceptionType ERROR_INVALID_DOUBLE = new ParameterizedCommandExceptionType("parsing.double.invalid", "Invalid double '${value}'", "value");
|
||||
public static final SimpleCommandExceptionType ERROR_EXPECTED_DOUBLE = new SimpleCommandExceptionType("parsing.double.expected", "Expected double");
|
||||
public static final SimpleCommandExceptionType ERROR_EXPECTED_BOOL = new SimpleCommandExceptionType("parsing.bool.expected", "Expected bool");
|
||||
public static final ParameterizedCommandExceptionType ERROR_EXPECTED_SYMBOL = new ParameterizedCommandExceptionType("parsing.expected", "Expected '${symbol}'", "symbol");
|
||||
|
||||
private final String string;
|
||||
|
@ -25,6 +26,7 @@ public class StringReader {
|
|||
this.string = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
@ -33,38 +35,47 @@ public class StringReader {
|
|||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemainingLength() {
|
||||
return string.length() - cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalLength() {
|
||||
return string.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRead() {
|
||||
return string.substring(0, cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemaining() {
|
||||
return string.substring(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(final int length) {
|
||||
return cursor + length <= string.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead() {
|
||||
return canRead(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char peek() {
|
||||
return string.charAt(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char peek(final int offset) {
|
||||
return string.charAt(cursor + offset);
|
||||
}
|
||||
|
@ -94,12 +105,13 @@ public class StringReader {
|
|||
}
|
||||
final String number = string.substring(start, cursor);
|
||||
if (number.isEmpty()) {
|
||||
throw ERROR_EXPECTED_INT.create();
|
||||
throw ERROR_EXPECTED_INT.createWithContext(this);
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(number);
|
||||
} catch (final NumberFormatException ex) {
|
||||
throw ERROR_INVALID_INT.create(number);
|
||||
cursor = start;
|
||||
throw ERROR_INVALID_INT.createWithContext(this, number);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,12 +122,13 @@ public class StringReader {
|
|||
}
|
||||
final String number = string.substring(start, cursor);
|
||||
if (number.isEmpty()) {
|
||||
throw ERROR_EXPECTED_DOUBLE.create();
|
||||
throw ERROR_EXPECTED_DOUBLE.createWithContext(this);
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(number);
|
||||
} catch (final NumberFormatException ex) {
|
||||
throw ERROR_INVALID_DOUBLE.create(number);
|
||||
cursor = start;
|
||||
throw ERROR_INVALID_DOUBLE.createWithContext(this, number);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +152,7 @@ public class StringReader {
|
|||
if (!canRead()) {
|
||||
return "";
|
||||
} else if (peek() != SYNTAX_QUOTE) {
|
||||
throw ERROR_EXPECTED_START_OF_QUOTE.create();
|
||||
throw ERROR_EXPECTED_START_OF_QUOTE.createWithContext(this);
|
||||
}
|
||||
skip();
|
||||
final StringBuilder result = new StringBuilder();
|
||||
|
@ -151,7 +164,8 @@ public class StringReader {
|
|||
result.append(c);
|
||||
escaped = false;
|
||||
} else {
|
||||
throw ERROR_INVALID_ESCAPE.create(String.valueOf(c));
|
||||
setCursor(getCursor() - 1);
|
||||
throw ERROR_INVALID_ESCAPE.createWithContext(this, String.valueOf(c));
|
||||
}
|
||||
} else if (c == SYNTAX_ESCAPE) {
|
||||
escaped = true;
|
||||
|
@ -162,7 +176,7 @@ public class StringReader {
|
|||
}
|
||||
}
|
||||
|
||||
throw ERROR_EXPECTED_END_OF_QUOTE.create();
|
||||
throw ERROR_EXPECTED_END_OF_QUOTE.createWithContext(this);
|
||||
}
|
||||
|
||||
public String readString() throws CommandException {
|
||||
|
@ -174,19 +188,25 @@ public class StringReader {
|
|||
}
|
||||
|
||||
public boolean readBoolean() throws CommandException {
|
||||
final int start = cursor;
|
||||
final String value = readString();
|
||||
if (value.isEmpty()) {
|
||||
throw ERROR_EXPECTED_BOOL.createWithContext(this);
|
||||
}
|
||||
|
||||
if (value.equals("true")) {
|
||||
return true;
|
||||
} else if (value.equals("false")) {
|
||||
return false;
|
||||
} else {
|
||||
throw ERROR_INVALID_BOOL.create(value);
|
||||
cursor = start;
|
||||
throw ERROR_INVALID_BOOL.createWithContext(this, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void expect(final char c) throws CommandException {
|
||||
if (!canRead() || peek() != c) {
|
||||
throw ERROR_EXPECTED_SYMBOL.create(String.valueOf(c));
|
||||
throw ERROR_EXPECTED_SYMBOL.createWithContext(this, String.valueOf(c));
|
||||
}
|
||||
skip();
|
||||
}
|
||||
|
|
|
@ -45,19 +45,23 @@ public class IntegerArgumentType implements ArgumentType<Integer> {
|
|||
|
||||
@Override
|
||||
public <S> Integer parse(final StringReader reader, final CommandContextBuilder<S> contextBuilder) throws CommandException {
|
||||
final int start = reader.getCursor();
|
||||
final int result = reader.readInt();
|
||||
for (int i = 0; i < suffix.length(); i++) {
|
||||
if (reader.canRead() && reader.peek() == suffix.charAt(i)) {
|
||||
reader.skip();
|
||||
} else {
|
||||
throw ERROR_WRONG_SUFFIX.create(suffix);
|
||||
reader.setCursor(start);
|
||||
throw ERROR_WRONG_SUFFIX.createWithContext(reader, suffix);
|
||||
}
|
||||
}
|
||||
if (result < minimum) {
|
||||
throw ERROR_TOO_SMALL.create(result, minimum);
|
||||
reader.setCursor(start);
|
||||
throw ERROR_TOO_SMALL.createWithContext(reader, result, minimum);
|
||||
}
|
||||
if (result > maximum) {
|
||||
throw ERROR_TOO_BIG.create(result, maximum);
|
||||
reader.setCursor(start);
|
||||
throw ERROR_TOO_BIG.createWithContext(reader, result, maximum);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -3,27 +3,70 @@ package com.mojang.brigadier.exceptions;
|
|||
import java.util.Map;
|
||||
|
||||
public class CommandException extends Exception {
|
||||
public static final int CONTEXT_AMOUNT = 10;
|
||||
public static boolean ENABLE_COMMAND_STACK_TRACES = true;
|
||||
|
||||
private final CommandExceptionType type;
|
||||
private final Map<String, Object> data;
|
||||
private final Map<String, String> data;
|
||||
private final String input;
|
||||
private final int cursor;
|
||||
|
||||
public CommandException(final CommandExceptionType type, final Map<String, Object> data) {
|
||||
public CommandException(final CommandExceptionType type, final Map<String, String> data) {
|
||||
super(type.getTypeName(), null, ENABLE_COMMAND_STACK_TRACES, ENABLE_COMMAND_STACK_TRACES);
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.input = null;
|
||||
this.cursor = -1;
|
||||
}
|
||||
|
||||
public CommandException(final CommandExceptionType type, final Map<String, String> data, final String input, final int cursor) {
|
||||
super(type.getTypeName(), null, ENABLE_COMMAND_STACK_TRACES, ENABLE_COMMAND_STACK_TRACES);
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.input = input;
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return type.getErrorMessage(this);
|
||||
String message = type.getErrorMessage(data);
|
||||
final String context = getContext();
|
||||
if (context != null) {
|
||||
message += " at position " + cursor + ": " + context;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getContext() {
|
||||
if (input == null || cursor < 0) {
|
||||
return null;
|
||||
}
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int cursor = Math.min(input.length(), this.cursor);
|
||||
|
||||
if (cursor > CONTEXT_AMOUNT) {
|
||||
builder.append("...");
|
||||
}
|
||||
|
||||
builder.append(input.substring(Math.max(0, cursor - CONTEXT_AMOUNT), cursor));
|
||||
builder.append("<--[HERE]");
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public CommandExceptionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Map<String, Object> getData() {
|
||||
public Map<String, String> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public int getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.mojang.brigadier.exceptions;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface CommandExceptionType {
|
||||
String getTypeName();
|
||||
|
||||
String getErrorMessage(CommandException exception);
|
||||
String getErrorMessage(Map<String, String> data);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ package com.mojang.brigadier.exceptions;
|
|||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.brigadier.ImmutableStringReader;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -26,28 +29,31 @@ public class ParameterizedCommandExceptionType implements CommandExceptionType {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage(final CommandException exception) {
|
||||
public String getErrorMessage(final Map<String, String> data) {
|
||||
final Matcher matcher = PATTERN.matcher(message);
|
||||
final StringBuffer result = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(result, Matcher.quoteReplacement(exception.getData().get(matcher.group(1)).toString()));
|
||||
matcher.appendReplacement(result, Matcher.quoteReplacement(data.get(matcher.group(1))));
|
||||
}
|
||||
matcher.appendTail(result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public CommandException create(final Object... values) {
|
||||
public CommandException createWithContext(final ImmutableStringReader reader, final Object... values) {
|
||||
return new CommandException(this, createMap(values), reader.getString(), reader.getCursor());
|
||||
}
|
||||
|
||||
public Map<String, String> createMap(final Object... values) {
|
||||
if (values.length != keys.length) {
|
||||
throw new IllegalArgumentException("Invalid values! (Expected: " + JOINER.join(keys) + ")");
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
builder = builder.put(keys[i], values[i]);
|
||||
builder = builder.put(keys[i], String.valueOf(values[i]));
|
||||
}
|
||||
|
||||
return new CommandException(this, builder.build());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package com.mojang.brigadier.exceptions;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.brigadier.ImmutableStringReader;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SimpleCommandExceptionType implements CommandExceptionType {
|
||||
private final String name;
|
||||
|
@ -17,12 +21,12 @@ public class SimpleCommandExceptionType implements CommandExceptionType {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage(final CommandException exception) {
|
||||
public String getErrorMessage(final Map<String, String> data) {
|
||||
return message;
|
||||
}
|
||||
|
||||
public CommandException create() {
|
||||
return new CommandException(this, ImmutableMap.of());
|
||||
public CommandException createWithContext(final ImmutableStringReader reader) {
|
||||
return new CommandException(this, ImmutableMap.of(), reader.getString(), reader.getCursor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,11 +31,13 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
|
|||
|
||||
@Override
|
||||
public void parse(final StringReader reader, final CommandContextBuilder<S> contextBuilder) throws CommandException {
|
||||
final int start = reader.getCursor();
|
||||
for (int i = 0; i < literal.length(); i++) {
|
||||
if (reader.canRead() && reader.peek() == literal.charAt(i)) {
|
||||
reader.skip();
|
||||
} else {
|
||||
throw ERROR_INCORRECT_LITERAL.create(literal);
|
||||
reader.setCursor(start);
|
||||
throw ERROR_INCORRECT_LITERAL.createWithContext(reader, literal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ public class CommandDispatcherTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_UNKNOWN_COMMAND));
|
||||
assertThat(ex.getData(), is(Collections.<String, Object>emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,6 +82,7 @@ public class CommandDispatcherTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_UNKNOWN_COMMAND));
|
||||
assertThat(ex.getData(), is(Collections.<String, Object>emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +96,7 @@ public class CommandDispatcherTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_UNKNOWN_COMMAND));
|
||||
assertThat(ex.getData(), is(Collections.<String, Object>emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +109,8 @@ public class CommandDispatcherTest {
|
|||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_UNKNOWN_ARGUMENT));
|
||||
assertThat(ex.getData(), is(Collections.singletonMap("argument", "bar")));
|
||||
assertThat(ex.getData(), is(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(4));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,6 +124,7 @@ public class CommandDispatcherTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(LiteralCommandNode.ERROR_INCORRECT_LITERAL));
|
||||
assertThat(ex.getData(), is(Collections.singletonMap("expected", "bar")));
|
||||
assertThat(ex.getCursor(), is(4));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +141,8 @@ public class CommandDispatcherTest {
|
|||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_UNKNOWN_ARGUMENT));
|
||||
assertThat(ex.getData(), is(Collections.singletonMap("argument", "unknown")));
|
||||
assertThat(ex.getData(), is(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(4));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,6 +164,36 @@ public class CommandDispatcherTest {
|
|||
verify(subCommand).run(any(CommandContext.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOrphanedSubcommand() throws Exception {
|
||||
subject.register(literal("foo").then(
|
||||
argument("bar", integer())
|
||||
).executes(command));
|
||||
|
||||
try {
|
||||
subject.execute("foo 5", source);
|
||||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_UNKNOWN_COMMAND));
|
||||
assertThat(ex.getData(), is(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parse_noSpaceSeparator() throws Exception {
|
||||
subject.register(literal("foo").then(argument("bar", integer()).executes(command)));
|
||||
|
||||
try {
|
||||
subject.execute("foo5", source);
|
||||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(CommandDispatcher.ERROR_EXPECTED_ARGUMENT_SEPARATOR));
|
||||
assertThat(ex.getData(), is(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteInvalidSubcommand() throws Exception {
|
||||
subject.register(literal("foo").then(
|
||||
|
@ -170,6 +206,7 @@ public class CommandDispatcherTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_INT));
|
||||
assertThat(ex.getData(), is(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(4));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -219,6 +219,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_START_OF_QUOTE));
|
||||
assertThat(ex.getData(), equalTo(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,6 +230,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_END_OF_QUOTE));
|
||||
assertThat(ex.getData(), equalTo(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(12));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +241,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_INVALID_ESCAPE));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.of("character", "n")));
|
||||
assertThat(ex.getCursor(), is(7));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,6 +268,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_INVALID_INT));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.of("value", "12.34")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,6 +279,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_INT));
|
||||
assertThat(ex.getData(), equalTo(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,6 +330,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_INVALID_DOUBLE));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.of("value", "12.34.56")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,6 +341,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_DOUBLE));
|
||||
assertThat(ex.getData(), equalTo(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,6 +377,7 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_SYMBOL));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.of("symbol", "a")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -382,6 +390,40 @@ public class StringReaderTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_SYMBOL));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.of("symbol", "a")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readBoolean_correct() throws Exception {
|
||||
final StringReader reader = new StringReader("true");
|
||||
assertThat(reader.readBoolean(), is(true));
|
||||
assertThat(reader.getRead(), equalTo("true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readBoolean_incorrect() throws Exception {
|
||||
final StringReader reader = new StringReader("tuesday");
|
||||
try {
|
||||
reader.readBoolean();
|
||||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_INVALID_BOOL));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.of("value", "tuesday")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readBoolean_none() throws Exception {
|
||||
final StringReader reader = new StringReader("");
|
||||
try {
|
||||
reader.readBoolean();
|
||||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(StringReader.ERROR_EXPECTED_BOOL));
|
||||
assertThat(ex.getData(), equalTo(Collections.emptyMap()));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@ public class IntegerArgumentTypeTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(IntegerArgumentType.ERROR_WRONG_SUFFIX));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("suffix", "L")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +70,7 @@ public class IntegerArgumentTypeTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(IntegerArgumentType.ERROR_WRONG_SUFFIX));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("suffix", "L")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +82,8 @@ public class IntegerArgumentTypeTest {
|
|||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(IntegerArgumentType.ERROR_TOO_SMALL));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("found", -5, "minimum", 0)));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("found", "-5", "minimum", "0")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +95,8 @@ public class IntegerArgumentTypeTest {
|
|||
fail();
|
||||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(IntegerArgumentType.ERROR_TOO_BIG));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("found", 5, "maximum", 0)));
|
||||
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("found", "5", "maximum", "0")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,12 @@ package com.mojang.brigadier.exceptions;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.testing.EqualsTester;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
|
||||
|
@ -18,21 +20,19 @@ public class ParameterizedCommandExceptionTypeTest {
|
|||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateTooFewArguments() throws Exception {
|
||||
type.create();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCreateTooManyArguments() throws Exception {
|
||||
type.create("World", "Universe");
|
||||
public void createMap_TooManyArguments() throws Exception {
|
||||
type.createMap("World", "Universe");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
final CommandException exception = type.create("World");
|
||||
public void createWithContext() throws Exception {
|
||||
final StringReader reader = new StringReader("Foo bar");
|
||||
reader.setCursor(5);
|
||||
final CommandException exception = type.createWithContext(reader, "World");
|
||||
assertThat(exception.getType(), is(type));
|
||||
assertThat(exception.getData(), is(ImmutableMap.<String, Object>of("name", "World")));
|
||||
assertThat(exception.getMessage(), is("Hello, World!"));
|
||||
assertThat(exception.getInput(), is("Foo bar"));
|
||||
assertThat(exception.getCursor(), is(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
package com.mojang.brigadier.exceptions;
|
||||
|
||||
import com.google.common.testing.EqualsTester;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
|
||||
public class SimpleCommandExceptionTypeTest {
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
public void createWithContext() throws Exception {
|
||||
final SimpleCommandExceptionType type = new SimpleCommandExceptionType("foo", "bar");
|
||||
final CommandException exception = type.create();
|
||||
final StringReader reader = new StringReader("Foo bar");
|
||||
reader.setCursor(5);
|
||||
final CommandException exception = type.createWithContext(reader);
|
||||
assertThat(exception.getType(), is(type));
|
||||
assertThat(exception.getMessage(), is("bar"));
|
||||
assertThat(exception.getData().values(), empty());
|
||||
assertThat(exception.getData(), is(Collections.emptyMap()));
|
||||
assertThat(exception.getInput(), is("Foo bar"));
|
||||
assertThat(exception.getCursor(), is(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -25,4 +33,22 @@ public class SimpleCommandExceptionTypeTest {
|
|||
.addEqualityGroup(new SimpleCommandExceptionType("bar", "Hello, world!"), new SimpleCommandExceptionType("bar", "Hello, universe!"))
|
||||
.testEquals();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContext_none() throws Exception {
|
||||
final CommandException exception = new CommandException(mock(CommandExceptionType.class), Collections.emptyMap());
|
||||
assertThat(exception.getContext(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContext_short() throws Exception {
|
||||
final CommandException exception = new CommandException(mock(CommandExceptionType.class), Collections.emptyMap(), "Hello world!", 5);
|
||||
assertThat(exception.getContext(), equalTo("Hello<--[HERE]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContext_long() throws Exception {
|
||||
final CommandException exception = new CommandException(mock(CommandExceptionType.class), Collections.emptyMap(), "Hello world! This has an error in it. Oh dear!", 20);
|
||||
assertThat(exception.getContext(), equalTo("...d! This ha<--[HERE]"));
|
||||
}
|
||||
}
|
|
@ -69,6 +69,7 @@ public class LiteralCommandNodeTest extends AbstractCommandNodeTest {
|
|||
} catch (final CommandException ex) {
|
||||
assertThat(ex.getType(), is(LiteralCommandNode.ERROR_INCORRECT_LITERAL));
|
||||
assertThat(ex.getData(), is(ImmutableMap.<String, Object>of("expected", "foo")));
|
||||
assertThat(ex.getCursor(), is(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue