Added float argument

This commit is contained in:
Nathan Adams 2017-08-01 09:38:14 +02:00
parent 4b9170fd7f
commit a67b4b51b0
2 changed files with 253 additions and 0 deletions

View file

@ -0,0 +1,103 @@
package com.mojang.brigadier.arguments;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandException;
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
import java.util.Objects;
public class FloatArgumentType implements ArgumentType<Float> {
public static final ParameterizedCommandExceptionType ERROR_WRONG_SUFFIX = new ParameterizedCommandExceptionType("argument.float.wrongsuffix", "Expected suffix '${suffix}'", "suffix");
public static final ParameterizedCommandExceptionType ERROR_TOO_SMALL = new ParameterizedCommandExceptionType("argument.float.low", "Float must not be less than ${minimum}, found ${found}", "found", "minimum");
public static final ParameterizedCommandExceptionType ERROR_TOO_BIG = new ParameterizedCommandExceptionType("argument.float.big", "Float must not be more than ${maximum}, found ${found}", "found", "maximum");
private final float minimum;
private final float maximum;
private final String suffix;
private FloatArgumentType(final float minimum, final float maximum, final String suffix) {
this.minimum = minimum;
this.maximum = maximum;
this.suffix = suffix;
}
public static FloatArgumentType floatArg() {
return floatArg(-Float.MAX_VALUE);
}
public static FloatArgumentType floatArg(final float min) {
return floatArg(min, Float.MAX_VALUE);
}
public static FloatArgumentType floatArg(final float min, final float max) {
return floatArg(min, max, "");
}
public static FloatArgumentType floatArg(final float min, final float max, final String suffix) {
return new FloatArgumentType(min, max, suffix);
}
public static int getInteger(final CommandContext<?> context, final String name) {
return context.getArgument(name, int.class);
}
@Override
public <S> Float parse(final StringReader reader, final CommandContextBuilder<S> contextBuilder) throws CommandException {
final int start = reader.getCursor();
final float result = (float) reader.readDouble();
for (int i = 0; i < suffix.length(); i++) {
if (reader.canRead() && reader.peek() == suffix.charAt(i)) {
reader.skip();
} else {
reader.setCursor(start);
throw ERROR_WRONG_SUFFIX.createWithContext(reader, suffix);
}
}
if (result < minimum) {
reader.setCursor(start);
throw ERROR_TOO_SMALL.createWithContext(reader, result, minimum);
}
if (result > maximum) {
reader.setCursor(start);
throw ERROR_TOO_BIG.createWithContext(reader, result, maximum);
}
return result;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof FloatArgumentType)) return false;
final FloatArgumentType that = (FloatArgumentType) o;
return maximum == that.maximum && minimum == that.minimum && Objects.equals(suffix, that.suffix);
}
@Override
public int hashCode() {
return (int) (31 * minimum + maximum);
}
@Override
public String toString() {
if (minimum == -Float.MAX_VALUE && maximum == Float.MAX_VALUE) {
return "float()";
} else if (maximum == Float.MAX_VALUE) {
return "float(" + minimum + ")";
} else {
return "float(" + minimum + ", " + maximum + ")";
}
}
@Override
public String getUsageSuffix() {
return suffix.length() == 0 ? null : suffix;
}
@Override
public String getUsageText() {
return "float";
}
}

View file

@ -0,0 +1,150 @@
package com.mojang.brigadier.arguments;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.testing.EqualsTester;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Set;
import static com.mojang.brigadier.arguments.FloatArgumentType.floatArg;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@RunWith(MockitoJUnitRunner.class)
public class FloatArgumentTypeTest {
private FloatArgumentType type;
@Mock
private CommandContextBuilder<Object> context;
@Before
public void setUp() throws Exception {
type = floatArg(-100, 100);
}
@Test
public void parse_noSuffix() throws Exception {
final StringReader reader = new StringReader("15");
assertThat(floatArg().parse(reader, context), is(15f));
assertThat(reader.canRead(), is(false));
}
@Test
public void parse_suffix() throws Exception {
final StringReader reader = new StringReader("15L");
assertThat(floatArg(0, 100, "L").parse(reader, context), is(15f));
assertThat(reader.canRead(), is(false));
}
@Test
public void parse_suffix_incorrect() throws Exception {
final StringReader reader = new StringReader("15W");
try {
floatArg(0, 100, "L").parse(reader, context);
fail();
} catch (final CommandException ex) {
assertThat(ex.getType(), is(FloatArgumentType.ERROR_WRONG_SUFFIX));
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("suffix", "L")));
assertThat(ex.getCursor(), is(0));
}
}
@Test
public void parse_suffix_missing() throws Exception {
final StringReader reader = new StringReader("15");
try {
floatArg(0, 100, "L").parse(reader, context);
fail();
} catch (final CommandException ex) {
assertThat(ex.getType(), is(FloatArgumentType.ERROR_WRONG_SUFFIX));
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("suffix", "L")));
assertThat(ex.getCursor(), is(0));
}
}
@Test
public void parse_tooSmall() throws Exception {
final StringReader reader = new StringReader("-5");
try {
floatArg(0, 100).parse(reader, context);
fail();
} catch (final CommandException ex) {
assertThat(ex.getType(), is(FloatArgumentType.ERROR_TOO_SMALL));
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("found", "-5.0", "minimum", "0.0")));
assertThat(ex.getCursor(), is(0));
}
}
@Test
public void parse_tooBig() throws Exception {
final StringReader reader = new StringReader("5");
try {
floatArg(-100, 0).parse(reader, context);
fail();
} catch (final CommandException ex) {
assertThat(ex.getType(), is(FloatArgumentType.ERROR_TOO_BIG));
assertThat(ex.getData(), equalTo(ImmutableMap.<String, Object>of("found", "5.0", "maximum", "0.0")));
assertThat(ex.getCursor(), is(0));
}
}
@Test
public void testSuggestions() throws Exception {
final Set<String> set = Sets.newHashSet();
@SuppressWarnings("unchecked") final CommandContextBuilder<Object> context = Mockito.mock(CommandContextBuilder.class);
type.listSuggestions("", set, context);
assertThat(set, is(empty()));
}
@Test
public void testEquals() throws Exception {
new EqualsTester()
.addEqualityGroup(floatArg(), floatArg())
.addEqualityGroup(floatArg(-100, 100), floatArg(-100, 100))
.addEqualityGroup(floatArg(-100, 50), floatArg(-100, 50))
.addEqualityGroup(floatArg(-50, 100), floatArg(-50, 100))
.addEqualityGroup(floatArg(-50, 100, "foo"), floatArg(-50, 100, "foo"))
.addEqualityGroup(floatArg(-50, 100, "bar"), floatArg(-50, 100, "bar"))
.testEquals();
}
@Test
public void testToString() throws Exception {
assertThat(floatArg(), hasToString("float()"));
assertThat(floatArg(-100), hasToString("float(-100.0)"));
assertThat(floatArg(-100, 100), hasToString("float(-100.0, 100.0)"));
assertThat(floatArg(Integer.MIN_VALUE, 100), hasToString("float(-2.14748365E9, 100.0)"));
}
@Test
public void testUsageSuffix() throws Exception {
assertThat(floatArg().getUsageSuffix(), equalTo(null));
}
@Test
public void testUsageSuffix_suffix() throws Exception {
assertThat(floatArg(0, 100, "L").getUsageSuffix(), equalTo("L"));
}
@Test
public void testUsageText() throws Exception {
assertThat(floatArg().getUsageText(), equalTo("float"));
}
@Test
public void testUsageText_suffix() throws Exception {
assertThat(floatArg(0, 100, "L").getUsageText(), equalTo("float"));
}
}