2015-06-01 04:08:42 +00:00
|
|
|
package com.moandjiezana.toml;
|
|
|
|
|
2015-06-27 21:19:40 +00:00
|
|
|
import org.junit.Rule;
|
2015-06-01 04:08:42 +00:00
|
|
|
import org.junit.Test;
|
2015-06-27 21:19:40 +00:00
|
|
|
import org.junit.rules.TemporaryFolder;
|
2015-06-01 04:08:42 +00:00
|
|
|
|
2015-06-27 21:19:40 +00:00
|
|
|
import java.io.*;
|
2015-06-25 14:56:04 +00:00
|
|
|
import java.text.SimpleDateFormat;
|
2015-06-01 04:08:42 +00:00
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
|
2015-06-27 19:50:15 +00:00
|
|
|
public class ValueWriterTest {
|
2015-06-27 21:19:40 +00:00
|
|
|
|
|
|
|
@Rule
|
|
|
|
public TemporaryFolder testDirectory = new TemporaryFolder();
|
|
|
|
|
2015-06-01 04:08:42 +00:00
|
|
|
@Test
|
2015-06-27 19:50:15 +00:00
|
|
|
public void should_write_primitive_types() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class TestClass {
|
|
|
|
public String aString;
|
|
|
|
int anInt;
|
|
|
|
protected float aFloat;
|
|
|
|
private double aDouble;
|
|
|
|
boolean aBoolean;
|
|
|
|
final int aFinalInt = 1; // Should be skipped
|
|
|
|
Date aDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
TestClass o = new TestClass();
|
|
|
|
o.aString = "hello";
|
|
|
|
o.anInt = 4;
|
|
|
|
o.aFloat = 1.23f;
|
|
|
|
o.aDouble = -5.43;
|
|
|
|
o.aBoolean = false;
|
|
|
|
|
2015-06-25 14:56:04 +00:00
|
|
|
o.aDate = new Date();
|
|
|
|
String theDate = formatDate(o.aDate);
|
2015-06-01 04:08:42 +00:00
|
|
|
|
2015-06-27 21:19:40 +00:00
|
|
|
String output = new TomlWriter().write(o);
|
2015-06-01 04:08:42 +00:00
|
|
|
String expected = "aString = \"hello\"\n" +
|
|
|
|
"anInt = 4\n" +
|
|
|
|
"aFloat = 1.23\n" +
|
|
|
|
"aDouble = -5.43\n" +
|
|
|
|
"aBoolean = false\n" +
|
|
|
|
"aDate = " + theDate + "\n";
|
|
|
|
|
2015-06-27 19:50:15 +00:00
|
|
|
assertEquals(expected, output);
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
2015-06-25 14:56:04 +00:00
|
|
|
private String formatDate(Date date) {
|
2015-06-27 19:50:15 +00:00
|
|
|
// Copying the date formatting code from DateValueWriter isn't optimal, but
|
|
|
|
// I can't see any other way to check date formatting - the test gets
|
2015-06-25 14:56:04 +00:00
|
|
|
// run in multiple time zones, so we can't just hard-code a time zone.
|
|
|
|
String dateString = new SimpleDateFormat("yyyy-MM-dd'T'HH:m:ss").format(date);
|
|
|
|
Calendar calendar = new GregorianCalendar();
|
|
|
|
int tzOffset = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000);
|
|
|
|
dateString += String.format("%+03d:%02d", tzOffset / 60, tzOffset % 60);
|
|
|
|
|
|
|
|
return dateString;
|
|
|
|
}
|
|
|
|
|
2015-06-28 17:30:35 +00:00
|
|
|
class SubChild {
|
|
|
|
int anInt;
|
|
|
|
}
|
|
|
|
class Child {
|
|
|
|
SubChild subChild;
|
|
|
|
int anInt;
|
|
|
|
}
|
|
|
|
class Parent {
|
|
|
|
Map<String, Object> aMap;
|
|
|
|
Child child;
|
|
|
|
boolean aBoolean;
|
|
|
|
}
|
2015-06-01 04:08:42 +00:00
|
|
|
|
2015-06-28 17:30:35 +00:00
|
|
|
private Parent buildNestedMap() {
|
2015-06-01 04:08:42 +00:00
|
|
|
Parent parent = new Parent();
|
|
|
|
parent.aMap = new LinkedHashMap<String, Object>();
|
|
|
|
parent.aMap.put("foo", 1);
|
|
|
|
parent.aMap.put("bar", "value1");
|
|
|
|
parent.aMap.put("baz.x", true);
|
|
|
|
parent.child = new Child();
|
|
|
|
parent.child.anInt = 2;
|
|
|
|
parent.child.subChild = new SubChild();
|
|
|
|
parent.child.subChild.anInt = 4;
|
|
|
|
parent.aBoolean = true;
|
|
|
|
|
2015-06-28 17:30:35 +00:00
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-28 21:09:20 +00:00
|
|
|
public void should_write_nested_map_with_default_indentation_policy() {
|
2015-06-28 17:30:35 +00:00
|
|
|
String output = new TomlWriter().write(buildNestedMap());
|
|
|
|
String expected = "aBoolean = true\n\n" +
|
|
|
|
"[aMap]\n" +
|
|
|
|
"foo = 1\n" +
|
|
|
|
"bar = \"value1\"\n" +
|
|
|
|
"\"baz.x\" = true\n\n" +
|
|
|
|
"[child]\n" +
|
|
|
|
"anInt = 2\n\n" +
|
|
|
|
"[child.subChild]\n" +
|
|
|
|
"anInt = 4\n";
|
|
|
|
assertEquals(expected, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void should_follow_indentation_policy_of_indented_values() {
|
|
|
|
String output = new TomlWriter().
|
|
|
|
setIndentationPolicy(new WriterIndentationPolicy().setKeyValueIndent(2)).
|
|
|
|
write(buildNestedMap());
|
2015-06-01 04:08:42 +00:00
|
|
|
String expected = "aBoolean = true\n\n" +
|
|
|
|
"[aMap]\n" +
|
|
|
|
" foo = 1\n" +
|
|
|
|
" bar = \"value1\"\n" +
|
|
|
|
" \"baz.x\" = true\n\n" +
|
|
|
|
"[child]\n" +
|
|
|
|
" anInt = 2\n\n" +
|
|
|
|
"[child.subChild]\n" +
|
|
|
|
" anInt = 4\n";
|
2015-06-27 19:50:15 +00:00
|
|
|
assertEquals(expected, output);
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
2015-06-28 17:30:35 +00:00
|
|
|
@Test
|
|
|
|
public void should_follow_indentation_policy_of_indented_tables() {
|
|
|
|
String output = new TomlWriter().
|
|
|
|
setIndentationPolicy(new WriterIndentationPolicy().setTableIndent(2)).
|
|
|
|
write(buildNestedMap());
|
|
|
|
String expected = "aBoolean = true\n\n" +
|
|
|
|
"[aMap]\n" +
|
|
|
|
"foo = 1\n" +
|
|
|
|
"bar = \"value1\"\n" +
|
|
|
|
"\"baz.x\" = true\n\n" +
|
|
|
|
"[child]\n" +
|
|
|
|
"anInt = 2\n\n" +
|
|
|
|
" [child.subChild]\n" +
|
|
|
|
" anInt = 4\n";
|
|
|
|
assertEquals(expected, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void should_follow_indentation_policy_of_indented_tables_and_values() {
|
|
|
|
String output = new TomlWriter().
|
|
|
|
setIndentationPolicy(new WriterIndentationPolicy().setTableIndent(2).setKeyValueIndent(2)).
|
|
|
|
write(buildNestedMap());
|
|
|
|
String expected = "aBoolean = true\n\n" +
|
|
|
|
"[aMap]\n" +
|
|
|
|
" foo = 1\n" +
|
|
|
|
" bar = \"value1\"\n" +
|
|
|
|
" \"baz.x\" = true\n\n" +
|
|
|
|
"[child]\n" +
|
|
|
|
" anInt = 2\n\n" +
|
|
|
|
" [child.subChild]\n" +
|
|
|
|
" anInt = 4\n";
|
|
|
|
assertEquals(expected, output);
|
|
|
|
}
|
|
|
|
|
2015-06-01 04:08:42 +00:00
|
|
|
@Test
|
2015-06-27 19:50:15 +00:00
|
|
|
public void should_write_array_of_tables() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class Table {
|
|
|
|
int anInt;
|
|
|
|
|
|
|
|
Table(int anInt) {
|
|
|
|
this.anInt = anInt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class Config {
|
|
|
|
Table[] table;
|
|
|
|
}
|
|
|
|
Config config = new Config();
|
|
|
|
config.table = new Table[]{new Table(1), new Table(2)};
|
|
|
|
|
2015-06-27 21:19:40 +00:00
|
|
|
String output = new TomlWriter().write(config);
|
2015-06-01 04:08:42 +00:00
|
|
|
String expected = "[[table]]\n" +
|
2015-06-28 17:30:35 +00:00
|
|
|
"anInt = 1\n\n" +
|
2015-06-01 04:08:42 +00:00
|
|
|
"[[table]]\n" +
|
2015-06-28 17:30:35 +00:00
|
|
|
"anInt = 2\n";
|
2015-06-27 19:50:15 +00:00
|
|
|
assertEquals(expected, output);
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-27 19:50:15 +00:00
|
|
|
public void should_write_array_of_array() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class ArrayTest {
|
|
|
|
int[][] array = {{1, 2, 3}, {4, 5, 6}};
|
|
|
|
}
|
|
|
|
ArrayTest arrayTest = new ArrayTest();
|
|
|
|
|
2015-06-27 21:19:40 +00:00
|
|
|
String output = new TomlWriter().write(arrayTest);
|
2015-06-01 04:08:42 +00:00
|
|
|
String expected = "array = [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]\n";
|
2015-06-27 19:50:15 +00:00
|
|
|
assertEquals(expected, output);
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-27 19:50:15 +00:00
|
|
|
public void should_write_list() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class ListTest {
|
|
|
|
List<Integer> aList = new LinkedList<Integer>();
|
|
|
|
}
|
|
|
|
ListTest o = new ListTest();
|
|
|
|
o.aList.add(1);
|
|
|
|
o.aList.add(2);
|
|
|
|
|
2015-06-27 21:19:40 +00:00
|
|
|
assertEquals("aList = [ 1, 2 ]\n", new TomlWriter().write(o));
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-25 16:31:36 +00:00
|
|
|
public void should_handle_zero_length_arrays_and_lists() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class TestClass {
|
|
|
|
List<Integer> aList = new LinkedList<Integer>();
|
|
|
|
Float[] anArray = new Float[0];
|
|
|
|
}
|
2015-06-27 21:19:40 +00:00
|
|
|
assertEquals("", new TomlWriter().write(new TestClass()));
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
2015-06-28 21:35:39 +00:00
|
|
|
@Test(expected = IllegalStateException.class)
|
|
|
|
public void should_reject_heterogeneous_arrays() {
|
|
|
|
class BadArray {
|
|
|
|
Object[] array = new Object[2];
|
|
|
|
}
|
|
|
|
BadArray badArray = new BadArray();
|
|
|
|
badArray.array[0] = new Integer(1);
|
|
|
|
badArray.array[1] = "oops";
|
|
|
|
|
|
|
|
new TomlWriter().write(badArray);
|
|
|
|
}
|
|
|
|
|
2015-06-01 04:08:42 +00:00
|
|
|
@Test
|
2015-06-25 16:31:36 +00:00
|
|
|
public void should_elide_empty_intermediate_tables() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class C {
|
|
|
|
int anInt = 1;
|
|
|
|
}
|
|
|
|
class B {
|
|
|
|
C c = new C();
|
|
|
|
}
|
|
|
|
class A {
|
|
|
|
B b = new B();
|
|
|
|
}
|
|
|
|
|
2015-06-28 17:30:35 +00:00
|
|
|
assertEquals("[b.c]\nanInt = 1\n", new TomlWriter().write(new A()));
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-27 19:50:15 +00:00
|
|
|
public void should_write_classes_with_inheritance() {
|
2015-06-01 04:08:42 +00:00
|
|
|
class Parent {
|
|
|
|
protected int anInt = 2;
|
|
|
|
}
|
|
|
|
class Child extends Parent {
|
|
|
|
boolean aBoolean = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Child child = new Child();
|
|
|
|
String expected = "aBoolean = true\nanInt = 2\n";
|
2015-06-27 21:19:40 +00:00
|
|
|
assertEquals(expected, new TomlWriter().write(child));
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-27 19:50:15 +00:00
|
|
|
public void should_write_strings_to_toml_utf8() throws UnsupportedEncodingException {
|
2015-06-01 04:08:42 +00:00
|
|
|
String input = " é foo € \b \t \n \f \r \" \\ ";
|
2015-06-28 20:54:29 +00:00
|
|
|
assertEquals("\" \\u00E9 foo \\u20AC \\b \\t \\n \\f \\r \\\" \\\\ \"", new TomlWriter().write(input));
|
2015-06-01 04:08:42 +00:00
|
|
|
|
|
|
|
// Check unicode code points greater than 0XFFFF
|
|
|
|
input = " \uD801\uDC28 \uD840\uDC0B ";
|
2015-06-27 21:19:40 +00:00
|
|
|
assertEquals("\" \\U00010428 \\U0002000B \"", new TomlWriter().write(input));
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2015-06-25 16:31:36 +00:00
|
|
|
public void should_quote_keys() {
|
2015-06-01 04:08:42 +00:00
|
|
|
Map<String, Integer> aMap = new LinkedHashMap<String, Integer>();
|
|
|
|
aMap.put("a.b", 1);
|
|
|
|
aMap.put("5€", 2);
|
|
|
|
aMap.put("c$d", 3);
|
|
|
|
aMap.put("e/f", 4);
|
|
|
|
|
|
|
|
String expected = "\"a.b\" = 1\n" +
|
|
|
|
"\"5€\" = 2\n" +
|
|
|
|
"\"c$d\" = 3\n" +
|
|
|
|
"\"e/f\" = 4\n";
|
2015-06-27 21:19:40 +00:00
|
|
|
assertEquals(expected, new TomlWriter().write(aMap));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class SimpleTestClass {
|
|
|
|
int a = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void should_write_to_writer() throws IOException {
|
|
|
|
StringWriter output = new StringWriter();
|
|
|
|
new TomlWriter().write(new SimpleTestClass(), output);
|
|
|
|
|
|
|
|
assertEquals("a = 1\n", output.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void should_write_to_outputstream() throws IOException {
|
|
|
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
|
|
new TomlWriter().write(new SimpleTestClass(), output);
|
|
|
|
|
|
|
|
assertEquals("a = 1\n", output.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void should_write_to_file() throws IOException {
|
|
|
|
File output = testDirectory.newFile();
|
|
|
|
new TomlWriter().write(new SimpleTestClass(), output);
|
|
|
|
|
|
|
|
assertEquals("a = 1\n", readFile(output));
|
|
|
|
}
|
|
|
|
|
|
|
|
private String readFile(File input) throws IOException {
|
|
|
|
BufferedReader bufferedReader = new BufferedReader(new FileReader(input));
|
|
|
|
|
|
|
|
StringBuilder w = new StringBuilder();
|
|
|
|
String line = bufferedReader.readLine();
|
|
|
|
while (line != null) {
|
|
|
|
w.append(line).append('\n');
|
|
|
|
line = bufferedReader.readLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
return w.toString();
|
2015-06-01 04:08:42 +00:00
|
|
|
}
|
|
|
|
}
|