Added support for underscores in numbers

This commit is contained in:
moandji.ezana 2015-02-09 09:41:04 +02:00
parent 1bc8d4bcc5
commit 9093fec59b
2 changed files with 89 additions and 3 deletions

View file

@ -19,11 +19,13 @@ class NumberConverter implements ValueConverter {
boolean signable = true;
boolean dottable = false;
boolean exponentable = false;
boolean underscorable = false;
String type = "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
boolean notLastChar = chars.length > i + 1;
if (Character.isDigit(c)) {
sb.append(c);
@ -32,23 +34,29 @@ class NumberConverter implements ValueConverter {
type = "integer";
dottable = true;
}
underscorable = notLastChar;
exponentable = !type.equals("exponent");
} else if ((c == '+' || c == '-') && signable && chars.length > i + 1) {
} else if ((c == '+' || c == '-') && signable && notLastChar) {
signable = false;
if (c == '-') {
sb.append('-');
}
} else if (c == '.' && dottable && chars.length > i + 1) {
underscorable = false;
} else if (c == '.' && dottable && notLastChar) {
sb.append('.');
type = "float";
dottable = false;
exponentable = false;
} else if ((c == 'E' || c == 'e') && exponentable && chars.length > i + 1) {
underscorable = false;
} else if ((c == 'E' || c == 'e') && exponentable && notLastChar) {
sb.append('E');
type = "exponent";
signable = true;
dottable = false;
exponentable = false;
underscorable = false;
} else if (c == '_' && underscorable && notLastChar && Character.isDigit(chars[i + 1])) {
underscorable = false;
} else if (Character.isWhitespace(c)) {
whitespace = true;
} else if (whitespace && c == '#') {

View file

@ -59,6 +59,34 @@ public class NumberTest {
assertEquals(6.626D * Math.pow(10, -34), toml.getDouble("fractional"), 0.0);
}
@Test
public void should_get_integer_with_underscores() throws Exception {
Toml toml = new Toml().parse("val = 100_000_000");
assertEquals(100000000L, toml.getLong("val").intValue());
}
@Test
public void should_get_float_with_underscores() throws Exception {
Toml toml = new Toml().parse("val = 100_000.123_456");
assertEquals(100000.123456, toml.getDouble("val").doubleValue(), 0);
}
@Test
public void should_get_exponent_with_underscores() throws Exception {
Toml toml = new Toml().parse("val = 1_5e1_00");
assertEquals(15e100, toml.getDouble("val").doubleValue(), 0.0);
}
@Test
public void should_accept_irregular_underscores() throws Exception {
Toml toml = new Toml().parse("val = 1_2_3_4_5");
assertEquals(12345L, toml.getLong("val").longValue());
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_invalid_number() throws Exception {
new Toml().parse("a = 200-");
@ -129,4 +157,54 @@ public class NumberTest {
public void should_fail_on_float_with_two_dots() {
new Toml().parse("answer = 1.1.1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_at_beginning() {
new Toml().parse("answer = _1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_at_end() {
new Toml().parse("answer = 1_");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_two_underscores_in_a_row() {
new Toml().parse("answer = 1__1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_after_minus_sign() {
new Toml().parse("answer = -_1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_after_plus_sign() {
new Toml().parse("answer = +_1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_before_dot() {
new Toml().parse("answer = 1_.1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_after_dot() {
new Toml().parse("answer = 1._1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_before_E() {
new Toml().parse("answer = 1_E1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_after_E() {
new Toml().parse("answer = 1E_1");
}
@Test(expected = IllegalStateException.class)
public void should_fail_on_underscore_followed_by_whitespace() {
new Toml().parse("answer = _ 1");
}
}