Merge branch 'underscores_in_numbers' into wip. Fixed version example

test.

Conflicts:
	src/main/java/com/moandjiezana/toml/NumberConverter.java
This commit is contained in:
moandji.ezana 2015-02-17 10:21:17 +02:00
commit a3edb55e9c
3 changed files with 134 additions and 41 deletions

View file

@ -18,11 +18,13 @@ class NumberConverter implements ValueConverter {
boolean dottable = false;
boolean exponentable = false;
boolean terminatable = false;
boolean underscorable = false;
String type = "";
StringBuilder sb = new StringBuilder();
for (int i = index.get(); i < s.length(); i = index.incrementAndGet()) {
char c = s.charAt(i);
boolean notLastChar = s.length() > i + 1;
if (Character.isDigit(c)) {
sb.append(c);
@ -32,26 +34,30 @@ class NumberConverter implements ValueConverter {
type = "integer";
dottable = true;
}
underscorable = notLastChar;
exponentable = !type.equals("exponent");
} else if ((c == '+' || c == '-') && signable && s.length() > i + 1) {
} else if ((c == '+' || c == '-') && signable && notLastChar) {
signable = false;
terminatable = false;
if (c == '-') {
sb.append('-');
}
} else if (c == '.' && dottable && s.length() > i + 1) {
} else if (c == '.' && dottable && notLastChar) {
sb.append('.');
type = "float";
terminatable = false;
dottable = false;
exponentable = false;
} else if ((c == 'E' || c == 'e') && exponentable && s.length() > i + 1) {
} else if ((c == 'E' || c == 'e') && exponentable && notLastChar) {
sb.append('E');
type = "exponent";
terminatable = false;
signable = true;
dottable = false;
exponentable = false;
underscorable = false;
} else if (c == '_' && underscorable && notLastChar && Character.isDigit(s.charAt(i + 1))) {
underscorable = false;
} else {
if (!terminatable) {
type = "";

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");
}
}

View file

@ -75,43 +75,52 @@ public class RealWorldTest {
@SuppressWarnings("unchecked")
@Test
public void should_parse_current_version_example() throws Exception {
Toml toml = new Toml().parse(new File(getClass().getResource("example-v0.3.0.toml").getFile()));
Toml toml = new Toml().parse(new File(getClass().getResource("example-v0.4.0.toml").getFile()));
assertEquals("value", toml.getString("Table.key"));
assertEquals("pug", toml.getString("dog.tater.type"));
assertEquals("value", toml.getString("table.key"));
assertEquals("another value", toml.getString("table.subtable.key"));
assertNotNull(toml.getTable("x.y.z").getTable("w"));
assertEquals("I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF.", toml.getString("String.basic"));
assertEquals("One\nTwo", toml.getString("String.Multiline.key3"));
assertEquals(toml.getString("String.Multiline.key3"), toml.getString("String.Multiline.key1"));
assertEquals(toml.getString("String.Multiline.key3"), toml.getString("String.Multiline.key2"));
assertEquals("The quick brown fox jumps over the lazy dog.", toml.getString("String.Multilined.Singleline.key3"));
assertEquals(toml.getString("String.Multilined.Singleline.key3"), toml.getString("String.Multilined.Singleline.key1"));
assertEquals(toml.getString("String.Multilined.Singleline.key3"), toml.getString("String.Multilined.Singleline.key2"));
assertEquals("C:\\Users\\nodejs\\templates", toml.getString("String.Literal.winpath"));
assertEquals("\\\\ServerX\\admin$\\system32\\", toml.getString("String.Literal.winpath2"));
assertEquals("Tom \"Dubs\" Preston-Werner", toml.getString("String.Literal.quoted"));
assertEquals("<\\i\\c*\\s*>", toml.getString("String.Literal.regex"));
assertEquals("I [dw]on't need \\d{2} apples", toml.getString("String.Literal.Multiline.regex2"));
assertEquals("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", toml.getString("String.Literal.Multiline.lines"));
assertEquals(99, toml.getLong("Integer.key1").intValue());
assertEquals(42, toml.getLong("Integer.key2").intValue());
assertEquals(0, toml.getLong("Integer.key3").intValue());
assertEquals(-17, toml.getLong("Integer.key4").intValue());
assertEquals(1.0, toml.getDouble("Float.fractional.key1").doubleValue(), 0);
assertEquals(3.1415, toml.getDouble("Float.fractional.key2").doubleValue(), 0);
assertEquals(-0.01, toml.getDouble("Float.fractional.key3").doubleValue(), 0);
assertEquals(5e+22, toml.getDouble("Float.exponent.key1").doubleValue(), 0);
assertEquals(1e6, toml.getDouble("Float.exponent.key2").longValue(), 0);
assertEquals(-2E-2, toml.getDouble("Float.exponent.key3").doubleValue(), 0);
assertEquals(6.626e-34, toml.getDouble("Float.both.key").doubleValue(), 0);
assertTrue(toml.getBoolean("Booleans.True"));
assertFalse(toml.getBoolean("Booleans.False"));
assertThat(toml.<Long>getList("Array.key1"), contains(1L, 2L, 3L));
assertThat(toml.<String>getList("Array.key2"), contains("red", "yellow", "green"));
assertEquals(asList(asList(1L, 2L), asList(3L, 4L, 5L)), toml.<List<Long>>getList("Array.key3"));
assertEquals(asList(asList(1L, 2L), asList("a", "b", "c")), toml.<List<Long>>getList("Array.key4"));
assertThat(toml.<Long>getList("Array.key5"), contains(1L, 2L, 3L));
assertThat(toml.<Long>getList("Array.key6"), contains(1L, 2L));
assertEquals("Tom", toml.getString("table.inline.name.first"));
assertEquals("Preston-Werner", toml.getString("table.inline.name.last"));
assertEquals(1, toml.getLong("table.inline.point.x").intValue());
assertEquals(2, toml.getLong("table.inline.point.y").intValue());
// assertEquals("pug", toml.getString("dog.tater.type"));
assertEquals("I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF.", toml.getString("string.basic.basic"));
assertEquals("One\nTwo", toml.getString("string.multiline.key3"));
assertEquals(toml.getString("string.multiline.key3"), toml.getString("string.multiline.key1"));
assertEquals(toml.getString("string.multiline.key3"), toml.getString("string.multiline.key2"));
assertEquals("The quick brown fox jumps over the lazy dog.", toml.getString("string.multiline.continued.key1"));
assertEquals("The quick brown fox jumps over the lazy dog.", toml.getString("string.multiline.continued.key2"));
assertEquals(toml.getString("string.multilined.singleline.key3"), toml.getString("string.multilined.singleline.key1"));
assertEquals(toml.getString("string.multilined.singleline.key3"), toml.getString("string.multilined.singleline.key2"));
assertEquals("C:\\Users\\nodejs\\templates", toml.getString("string.literal.winpath"));
assertEquals("\\\\ServerX\\admin$\\system32\\", toml.getString("string.literal.winpath2"));
assertEquals("Tom \"Dubs\" Preston-Werner", toml.getString("string.literal.quoted"));
assertEquals("<\\i\\c*\\s*>", toml.getString("string.literal.regex"));
assertEquals("I [dw]on't need \\d{2} apples", toml.getString("string.literal.multiline.regex2"));
assertEquals("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", toml.getString("string.literal.multiline.lines"));
assertEquals(99, toml.getLong("integer.key1").intValue());
assertEquals(42, toml.getLong("integer.key2").intValue());
assertEquals(0, toml.getLong("integer.key3").intValue());
assertEquals(-17, toml.getLong("integer.key4").intValue());
assertEquals(1000, toml.getLong("integer.underscores.key1").intValue());
assertEquals(5349221, toml.getLong("integer.underscores.key2").longValue());
assertEquals(12345, toml.getLong("integer.underscores.key3").intValue());
assertEquals(1.0, toml.getDouble("float.fractional.key1").doubleValue(), 0);
assertEquals(3.1415, toml.getDouble("float.fractional.key2").doubleValue(), 0);
assertEquals(-0.01, toml.getDouble("float.fractional.key3").doubleValue(), 0);
assertEquals(5e+22, toml.getDouble("float.exponent.key1").doubleValue(), 0);
assertEquals(1e6, toml.getDouble("float.exponent.key2").longValue(), 0);
assertEquals(-2E-2, toml.getDouble("float.exponent.key3").doubleValue(), 0);
assertEquals(6.626e-34, toml.getDouble("float.both.key").doubleValue(), 0);
assertTrue(toml.getBoolean("boolean.True"));
assertFalse(toml.getBoolean("boolean.False"));
assertThat(toml.<Long>getList("array.key1"), contains(1L, 2L, 3L));
assertThat(toml.<String>getList("array.key2"), contains("red", "yellow", "green"));
assertEquals(asList(asList(1L, 2L), asList(3L, 4L, 5L)), toml.<List<Long>>getList("array.key3"));
assertEquals(asList(asList(1L, 2L), asList("a", "b", "c")), toml.<List<Long>>getList("array.key4"));
assertThat(toml.<Long>getList("array.key5"), contains(1L, 2L, 3L));
assertThat(toml.<Long>getList("array.key6"), contains(1L, 2L));
assertEquals("Hammer", toml.getString("products[0].name"));
assertEquals(738594937, toml.getLong("products[0].sku").intValue());
assertNotNull(toml.getTable("products[1]"));
@ -130,10 +139,10 @@ public class RealWorldTest {
dob.set(1979, Calendar.MAY, 27, 7, 32, 0);
dob.set(Calendar.MILLISECOND, 0);
dob.setTimeZone(TimeZone.getTimeZone("UTC"));
assertEquals(dob.getTime(), toml.getDate("Datetime.key1"));
assertEquals(dob.getTime(), toml.getDate("Datetime.key2"));
assertEquals(dob.getTime(), toml.getDate("datetime.key1"));
assertEquals(dob.getTime(), toml.getDate("datetime.key2"));
dob.set(Calendar.MILLISECOND, 999);
assertEquals(dob.getTime(), toml.getDate("Datetime.key3"));
assertEquals(dob.getTime(), toml.getDate("datetime.key3"));
}
@Test