mirror of
https://github.com/plexusorg/toml4j.git
synced 2025-02-11 11:40:27 +00:00
Initial commit
This commit is contained in:
commit
4ad8a683cc
9 changed files with 724 additions and 0 deletions
25
README.md
Normal file
25
README.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# toml4j
|
||||
|
||||
toml4j is a [TOML](https://github.com/mojombo/toml) parser that uses the [Parboiled](http://www.parboiled.org) PEG parser.
|
||||
|
||||
## Usage
|
||||
|
||||
````java
|
||||
Toml toml = new Toml(getTomlFile()); // throws an Exception if the TOML is incorrect
|
||||
|
||||
String title = toml.getString("title"); // if a key doesn't exist, returns null
|
||||
Boolean enabled = toml.getBoolean("database.enabled"); // gets the key enabled from the key group database
|
||||
Toml servers = toml.getKeyGroup("servers"); // returns a new Toml instance containing only the key group's values
|
||||
````
|
||||
|
||||
### Defaults
|
||||
|
||||
The constructor can be given a set of default values that will be used if necessary.
|
||||
|
||||
````java
|
||||
Toml toml = new Toml("a = 1", new Toml("a = 2\nb = 3");
|
||||
|
||||
Long a = toml.getLong("a"); // returns 1, not 2
|
||||
Long b = toml.getLong("b"); // returns 3
|
||||
Long c = toml.getLong("c"); // returns null
|
||||
````
|
45
pom.xml
Normal file
45
pom.xml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.sonatype.oss</groupId>
|
||||
<artifactId>oss-parent</artifactId>
|
||||
<version>7</version>
|
||||
</parent>
|
||||
<groupId>com.moandjiezana.toml</groupId>
|
||||
<artifactId>toml4j</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>toml4j</name>
|
||||
<description>A parser for TOML</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.parboiled</groupId>
|
||||
<artifactId>parboiled-java</artifactId>
|
||||
<version>1.1.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.0</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
110
src/main/java/com/moandjiezana/toml/Toml.java
Normal file
110
src/main/java/com/moandjiezana/toml/Toml.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.parboiled.Parboiled;
|
||||
import org.parboiled.parserunners.RecoveringParseRunner;
|
||||
import org.parboiled.support.ParsingResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* All getters can fall back to default values if they have been provided and will return null if no matching key exists.
|
||||
*
|
||||
*/
|
||||
public class Toml {
|
||||
|
||||
private final Map<String, Object> values;
|
||||
private final Toml defaults;
|
||||
|
||||
public Toml(File file) throws FileNotFoundException {
|
||||
this(new Scanner(file).useDelimiter("\\Z").next());
|
||||
}
|
||||
|
||||
public Toml(String tomlString) {
|
||||
this(tomlString, null);
|
||||
}
|
||||
|
||||
public Toml(String tomlString, Toml defaults) {
|
||||
TomlParser parser = Parboiled.createParser(TomlParser.class);
|
||||
ParsingResult<Object> result = new RecoveringParseRunner<Object>(parser.Toml()).run(tomlString);
|
||||
// ParsingResult<Object> parsingResult = new ReportingParseRunner<Object>(parser.Toml()).run(tomlString);
|
||||
// System.out.println(ParseTreeUtils.printNodeTree(parsingResult));
|
||||
|
||||
TomlParser.Results results = (TomlParser.Results) result.valueStack.peek(result.valueStack.size() - 1);
|
||||
if (results.errors.length() > 0) {
|
||||
throw new IllegalStateException(results.errors.toString());
|
||||
}
|
||||
|
||||
this.values = results.values;
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
return (String) get(key);
|
||||
}
|
||||
|
||||
public Long getLong(String key) {
|
||||
return (Long) get(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> List<T> getList(String key, Class<T> itemClass) {
|
||||
return (List<T>) get(key);
|
||||
}
|
||||
|
||||
public Boolean getBoolean(String key) {
|
||||
return (Boolean) get(key);
|
||||
}
|
||||
|
||||
public Date getDate(String key) {
|
||||
return (Date) get(key);
|
||||
}
|
||||
|
||||
public Double getDouble(String key) {
|
||||
return (Double) get(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Toml getKeyGroup(String key) {
|
||||
return new Toml((Map<String, Object>) get(key));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object get(String key) {
|
||||
String[] split = key.split("\\.");
|
||||
Object current = new HashMap<String, Object>(values);
|
||||
Object currentDefaults = defaults != null ? defaults.values : null;
|
||||
for (String splitKey : split) {
|
||||
current = ((Map<String, Object>) current).get(splitKey);
|
||||
if (currentDefaults != null) {
|
||||
currentDefaults = ((Map<String, Object>) currentDefaults).get(splitKey);
|
||||
if (current instanceof Map && currentDefaults instanceof Map) {
|
||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) currentDefaults).entrySet()) {
|
||||
if (!((Map<String, Object>) current).containsKey(entry.getKey())) {
|
||||
((Map<String, Object>) current).put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current == null && currentDefaults != null) {
|
||||
current = currentDefaults;
|
||||
}
|
||||
if (current == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
private Toml(Map<String, Object> values) {
|
||||
this.values = values;
|
||||
this.defaults = null;
|
||||
}
|
||||
}
|
209
src/main/java/com/moandjiezana/toml/TomlParser.java
Normal file
209
src/main/java/com/moandjiezana/toml/TomlParser.java
Normal file
|
@ -0,0 +1,209 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.parboiled.BaseParser;
|
||||
import org.parboiled.Rule;
|
||||
import org.parboiled.annotations.BuildParseTree;
|
||||
import org.parboiled.annotations.SuppressNode;
|
||||
|
||||
@BuildParseTree
|
||||
public class TomlParser extends BaseParser<Object> {
|
||||
|
||||
static class Results {
|
||||
public Map<String, Object> values = new HashMap<String, Object>();
|
||||
public StringBuilder errors = new StringBuilder();
|
||||
}
|
||||
|
||||
public Rule Toml() {
|
||||
return Sequence(push(new TomlParser.Results()), push(((TomlParser.Results) peek()).values), OneOrMore(FirstOf(KeyGroup(), Comment(), Key())));
|
||||
}
|
||||
|
||||
Rule KeyGroup() {
|
||||
return Sequence(KeyGroupDelimiter(), KeyGroupName(), addKeyGroup((String) pop()), KeyGroupDelimiter(), Spacing());
|
||||
}
|
||||
|
||||
Rule Key() {
|
||||
return Sequence(Spacing(), KeyName(), EqualsSign(), VariableValues(), Spacing(), swap(), addKey((String) pop(), pop()));
|
||||
}
|
||||
|
||||
Rule KeyGroupName() {
|
||||
return Sequence(OneOrMore(FirstOf(Letter(), Digit(), '.', '_')), push(match()));
|
||||
}
|
||||
|
||||
Rule KeyName() {
|
||||
return Sequence(OneOrMore(FirstOf(Letter(), Digit(), '_', '.')), push(match()));
|
||||
}
|
||||
|
||||
Rule VariableValues() {
|
||||
return FirstOf(ArrayValue(), DateValue(), BooleanValue(), NumberValue(), StringValue());
|
||||
}
|
||||
|
||||
Rule ArrayValue() {
|
||||
return Sequence(push(ArrayList.class), '[', Spacing(), ZeroOrMore(VariableValues(), Optional(ArrayDelimiter())), Spacing(), ']', pushList());
|
||||
}
|
||||
|
||||
Rule DateValue() {
|
||||
return Sequence(Sequence(Year(), '-', Month(), '-', Day(), 'T', Digit(), Digit(), ':', Digit(), Digit(), ':', Digit(), Digit(), 'Z'), pushDate(match()));
|
||||
}
|
||||
|
||||
Rule BooleanValue() {
|
||||
return Sequence(FirstOf("true", "false"), push(Boolean.valueOf(match())));
|
||||
}
|
||||
|
||||
Rule NumberValue() {
|
||||
return Sequence(OneOrMore(FirstOf(Digit(), '.')), pushNumber(match()));
|
||||
}
|
||||
|
||||
Rule StringValue() {
|
||||
return Sequence('"', OneOrMore(TestNot('"'), ANY), pushString(match()), '"');
|
||||
}
|
||||
|
||||
Rule Year() {
|
||||
return Sequence(Digit(), Digit(), Digit(), Digit());
|
||||
}
|
||||
|
||||
Rule Month() {
|
||||
return Sequence(CharRange('0', '1'), Digit());
|
||||
}
|
||||
|
||||
Rule Day() {
|
||||
return Sequence(CharRange('0', '3'), Digit());
|
||||
}
|
||||
|
||||
Rule Digit() {
|
||||
return CharRange('0', '9');
|
||||
}
|
||||
|
||||
Rule Letter() {
|
||||
return CharRange('a', 'z');
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule KeyGroupDelimiter() {
|
||||
return AnyOf("[]");
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule EqualsSign() {
|
||||
return Sequence(Spacing(), '=', Spacing());
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule Spacing() {
|
||||
return ZeroOrMore(FirstOf(Comment(), AnyOf(" \t\r\n\f")));
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule ArrayDelimiter() {
|
||||
return Sequence(Spacing(), ',', Spacing());
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule Comment() {
|
||||
return Sequence('#', ZeroOrMore(TestNot(AnyOf("\r\n")), ANY), FirstOf("\r\n", '\r', '\n', EOI));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
boolean addKeyGroup(String name) {
|
||||
String[] split = name.split("\\.");
|
||||
name = split[split.length - 1];
|
||||
|
||||
while (getContext().getValueStack().size() > 2) {
|
||||
drop();
|
||||
}
|
||||
|
||||
Map<String, Object> newKeyGroup = (Map<String, Object>) getContext().getValueStack().peek();
|
||||
for (String splitKey : split) {
|
||||
if (!newKeyGroup.containsKey(splitKey)) {
|
||||
newKeyGroup.put(splitKey, new HashMap<String, Object>());
|
||||
}
|
||||
Object currentValue = newKeyGroup.get(splitKey);
|
||||
if (!(currentValue instanceof Map)) {
|
||||
results().errors.append("Could not create key group ").append(name).append(": key already exists!");
|
||||
|
||||
return true;
|
||||
}
|
||||
newKeyGroup = (Map<String, Object>) currentValue;
|
||||
}
|
||||
|
||||
push(newKeyGroup);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean addKey(String key, Object value) {
|
||||
if (key.contains(".")) {
|
||||
results().errors.append(key).append(" is invalid: key names may not contain a dot!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
putValue(key, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean pushList() {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
while (peek() != ArrayList.class) {
|
||||
list.add(0, pop());
|
||||
}
|
||||
|
||||
poke(list);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean pushDate(String dateString) {
|
||||
String s = dateString.replace("Z", "+00:00");
|
||||
try {
|
||||
s = s.substring(0, 22) + s.substring(23);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
||||
dateFormat.setLenient(false);
|
||||
Date date = dateFormat.parse(s);
|
||||
push(date);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
results().errors.append("Invalid date: ").append(dateString);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean pushNumber(String number) {
|
||||
if (number.contains(".")) {
|
||||
push(Double.valueOf(number));
|
||||
} else {
|
||||
push(Long.valueOf(number));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean pushString(String line) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String[] split = line.split("\\\\n");
|
||||
for (String string : split) {
|
||||
builder.append(string).append('\n');
|
||||
}
|
||||
builder.deleteCharAt(builder.length() - 1);
|
||||
push(builder.toString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void putValue(String name, Object value) {
|
||||
Map<String, Object> values = (Map<String, Object>) peek();
|
||||
if (values.containsKey(name)) {
|
||||
results().errors.append("Key ").append(name).append(" already exists!");
|
||||
return;
|
||||
}
|
||||
values.put(name, value);
|
||||
}
|
||||
|
||||
TomlParser.Results results() {
|
||||
return (Results) peek(getContext().getValueStack().size() - 1);
|
||||
}
|
||||
}
|
82
src/test/java/com/moandjiezana/toml/RealWorldTest.java
Normal file
82
src/test/java/com/moandjiezana/toml/RealWorldTest.java
Normal file
|
@ -0,0 +1,82 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.parboiled.Parboiled;
|
||||
import org.parboiled.parserunners.RecoveringParseRunner;
|
||||
import org.parboiled.support.ParsingResult;
|
||||
|
||||
public class RealWorldTest {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void should_parse_example() throws Exception {
|
||||
TomlParser parser = Parboiled.createParser(TomlParser.class);
|
||||
|
||||
String toml = new Scanner(new File(getClass().getResource("/example.toml").getFile())).useDelimiter("\\Z").next();
|
||||
ParsingResult<Object> result = new RecoveringParseRunner<Object>(parser.Toml()).run(toml);
|
||||
|
||||
Map<String, Object> root = (Map<String, Object>) result.valueStack.peek(result.valueStack.size() - 2);
|
||||
|
||||
printMap(root);
|
||||
|
||||
assertEquals("TOML Example", root.get("title"));
|
||||
|
||||
Map<String, Object> owner = get(root, "owner");
|
||||
assertEquals("Tom Preston-Werner", owner.get("name"));
|
||||
assertEquals("GitHub", owner.get("organization"));
|
||||
assertEquals("GitHub Cofounder & CEO\nLikes tater tots and beer.", owner.get("bio"));
|
||||
|
||||
Calendar dob = Calendar.getInstance();
|
||||
dob.set(1979, Calendar.MAY, 27, 7, 32, 0);
|
||||
dob.set(Calendar.MILLISECOND, 0);
|
||||
dob.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
assertEquals(dob.getTime(), owner.get("dob"));
|
||||
|
||||
Map<String, Object> database = get(root, "database");
|
||||
assertEquals("192.168.1.1", database.get("server"));
|
||||
assertEquals(5000L, database.get("connection_max"));
|
||||
assertTrue((Boolean) database.get("enabled"));
|
||||
assertEquals(Arrays.asList(8001L, 8001L, 8002L), database.get("ports"));
|
||||
|
||||
Map<String, Object> servers = get(root, "servers");
|
||||
Map<String, Object> alphaServers = get(servers, "alpha");
|
||||
assertEquals("10.0.0.1", alphaServers.get("ip"));
|
||||
assertEquals("eqdc10", alphaServers.get("dc"));
|
||||
Map<String, Object> betaServers = get(servers, "beta");
|
||||
assertEquals("10.0.0.2", betaServers.get("ip"));
|
||||
assertEquals("eqdc10", betaServers.get("dc"));
|
||||
|
||||
Map<String, Object> clients = get(root, "clients");
|
||||
assertEquals(asList(asList("gamma", "delta"), asList(1L, 2L)), clients.get("data"));
|
||||
assertEquals(asList("alpha", "omega"), clients.get("hosts"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void printMap(Map<String, Object> map) {
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
if (entry.getValue() instanceof Map) {
|
||||
System.out.println("[" + entry.getKey() + "]");
|
||||
printMap((Map<String, Object>) entry.getValue());
|
||||
System.out.println("[/" + entry.getKey() + "]");
|
||||
} else {
|
||||
System.out.println(entry.getKey() + " = " + entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> get(Map<String, Object> map, String key) {
|
||||
return (Map<String, Object>) map.get(key);
|
||||
}
|
||||
}
|
61
src/test/java/com/moandjiezana/toml/TomlDefaultsTest.java
Normal file
61
src/test/java/com/moandjiezana/toml/TomlDefaultsTest.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class TomlDefaultsTest {
|
||||
|
||||
private Toml defaultToml;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
defaultToml = new Toml("a = \"a\"\n[group]\na=\"a\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_fall_back_to_default_value() {
|
||||
Toml toml = new Toml("", defaultToml);
|
||||
|
||||
assertEquals("a", toml.getString("a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_use_value_when_present_in_values_and_defaults() {
|
||||
Toml toml = new Toml("a = \"b\"", defaultToml);
|
||||
|
||||
assertEquals("b", toml.getString("a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_return_null_when_no_defaults_for_key() throws Exception {
|
||||
Toml toml = new Toml("", defaultToml);
|
||||
|
||||
assertNull(toml.getString("b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_fall_back_to_default_with_multi_key() throws Exception {
|
||||
Toml toml = new Toml("", defaultToml);
|
||||
|
||||
assertEquals("a", toml.getString("group.a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_fall_back_to_key_group() throws Exception {
|
||||
Toml toml = new Toml("", defaultToml);
|
||||
|
||||
assertEquals("a", toml.getKeyGroup("group").getString("a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_fall_back_to_key_within_key_group() throws Exception {
|
||||
Toml toml = new Toml("[group]\nb=1", defaultToml);
|
||||
|
||||
assertEquals(1, toml.getKeyGroup("group").getLong("b").intValue());
|
||||
assertEquals("a", toml.getKeyGroup("group").getString("a"));
|
||||
}
|
||||
}
|
156
src/test/java/com/moandjiezana/toml/TomlTest.java
Normal file
156
src/test/java/com/moandjiezana/toml/TomlTest.java
Normal file
|
@ -0,0 +1,156 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TomlTest {
|
||||
|
||||
@Test
|
||||
public void should_get_string() throws Exception {
|
||||
Toml toml = new Toml("a = \"a\"");
|
||||
|
||||
assertEquals("a", toml.getString("a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_number() throws Exception {
|
||||
Toml toml = new Toml("b = 1001");
|
||||
|
||||
assertEquals(1001, toml.getLong("b").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_list() throws Exception {
|
||||
Toml toml = new Toml("list = [\"a\", \"b\", \"c\"]");
|
||||
|
||||
assertEquals(asList("a", "b", "c"), toml.getList("list", String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_boolean() throws Exception {
|
||||
Toml toml = new Toml("bool_false = false\nbool_true = true");
|
||||
|
||||
assertFalse(toml.getBoolean("bool_false"));
|
||||
assertTrue(toml.getBoolean("bool_true"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_date() throws Exception {
|
||||
Toml toml = new Toml("a_date = 2011-11-10T13:12:00Z");
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(2011, Calendar.NOVEMBER, 10, 13, 12, 00);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
assertEquals(calendar.getTime(), toml.getDate("a_date"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_double() throws Exception {
|
||||
Toml toml = new Toml("double = 5.25");
|
||||
|
||||
assertEquals(5.25D, toml.getDouble("double").doubleValue(), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_key_group() throws Exception {
|
||||
Toml toml = new Toml("[group]\nkey = \"value\"");
|
||||
|
||||
Toml group = toml.getKeyGroup("group");
|
||||
|
||||
assertEquals("value", group.getString("key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_value_for_multi_key() throws Exception {
|
||||
Toml toml = new Toml("[group]\nkey = \"value\"");
|
||||
|
||||
assertEquals("value", toml.getString("group.key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_get_value_for_multi_key_with_no_parent_keygroup() throws Exception {
|
||||
Toml toml = new Toml("[group.sub]\nkey = \"value\"");
|
||||
|
||||
assertEquals("value", toml.getString("group.sub.key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_return_null_if_no_value_for_key() throws Exception {
|
||||
Toml toml = new Toml("");
|
||||
|
||||
assertNull(toml.getString("a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_return_null_when_no_value_for_multi_key() throws Exception {
|
||||
Toml toml = new Toml("");
|
||||
|
||||
assertNull(toml.getString("group.key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_load_from_file() throws Exception {
|
||||
Toml toml = new Toml(new File(getClass().getResource("should_load_from_file.toml").getFile()));
|
||||
|
||||
assertEquals("value", toml.getString("key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_support_numbers_in_key_names() throws Exception {
|
||||
Toml toml = new Toml("a1 = 1");
|
||||
|
||||
assertEquals(1, toml.getLong("a1").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_support_numbers_in_key_group_names() throws Exception {
|
||||
Toml toml = new Toml("[group1]\na = 1");
|
||||
|
||||
assertEquals(1, toml.getLong("group1.a").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_support_underscores_in_key_names() throws Exception {
|
||||
Toml toml = new Toml("a_a = 1");
|
||||
|
||||
assertEquals(1, toml.getLong("a_a").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_support_underscores_in_key_group_names() throws Exception {
|
||||
Toml toml = new Toml("[group_a]\na = 1");
|
||||
|
||||
assertEquals(1, toml.getLong("group_a.a").intValue());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void should_fail_when_dot_in_key_name() throws Exception {
|
||||
new Toml("a.a = 1");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void should_fail_on_invalid_date() throws Exception {
|
||||
new Toml("d = 2012-13-01T15:00:00Z");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void should_fail_when_key_is_overwritten_by_key_group() {
|
||||
new Toml("[fruit]\ntype=\"apple\"\n[fruit.type]\napple=\"yes\"");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void should_fail_when_key_is_overwritten_by_another_key() {
|
||||
new Toml("[fruit]\ntype=\"apple\"\ntype=\"orange\"");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
key = "value"
|
35
src/test/resources/example.toml
Normal file
35
src/test/resources/example.toml
Normal file
|
@ -0,0 +1,35 @@
|
|||
# This is a TOML document. Boom.
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
organization = "GitHub"
|
||||
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
||||
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
||||
|
||||
[database]
|
||||
server = "192.168.1.1"
|
||||
ports = [ 8001, 8001, 8002 ]
|
||||
connection_max = 5000
|
||||
enabled = true
|
||||
|
||||
[servers]
|
||||
|
||||
# You can indent as you please. Tabs or spaces. TOML don't care.
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
dc = "eqdc10"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
dc = "eqdc10"
|
||||
|
||||
[clients]
|
||||
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
|
||||
|
||||
# Line breaks are OK when inside arrays
|
||||
hosts = [
|
||||
"alpha",
|
||||
"omega"
|
||||
]
|
Loading…
Reference in a new issue