mirror of
https://github.com/plexusorg/toml4j.git
synced 2025-02-11 11:40:27 +00:00
Run burntsushi tests on TomlWriter, where possible.
This commit is contained in:
parent
1a0d38bc72
commit
b550e638c7
6 changed files with 163 additions and 25 deletions
|
@ -22,7 +22,7 @@ class MapValueWriter implements ValueWriter {
|
||||||
public void write(Object value, WriterContext context) {
|
public void write(Object value, WriterContext context) {
|
||||||
Map from = (Map) value;
|
Map from = (Map) value;
|
||||||
|
|
||||||
if (hasPrimitiveValues(from)) {
|
if (hasPrimitiveValues(from, context)) {
|
||||||
context.writeKey();
|
context.writeKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class MapValueWriter implements ValueWriter {
|
||||||
return stringKey;
|
return stringKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasPrimitiveValues(Map values) {
|
private static boolean hasPrimitiveValues(Map values, WriterContext context) {
|
||||||
for (Object key : values.keySet()) {
|
for (Object key : values.keySet()) {
|
||||||
Object fromValue = values.get(key);
|
Object fromValue = values.get(key);
|
||||||
if (fromValue == null) {
|
if (fromValue == null) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import static com.moandjiezana.toml.ValueWriters.WRITERS;
|
||||||
public class TomlWriter {
|
public class TomlWriter {
|
||||||
|
|
||||||
private WriterIndentationPolicy indentationPolicy = new WriterIndentationPolicy();
|
private WriterIndentationPolicy indentationPolicy = new WriterIndentationPolicy();
|
||||||
private boolean wantTerseArraysValue = true;
|
private boolean wantTerseArraysValue = false;
|
||||||
private GregorianCalendar calendar = new GregorianCalendar();
|
private GregorianCalendar calendar = new GregorianCalendar();
|
||||||
private DateFormat customDateFormat = null;
|
private DateFormat customDateFormat = null;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.moandjiezana.toml;
|
package com.moandjiezana.toml;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import com.google.gson.*;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -8,24 +10,11 @@ import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import org.junit.Ignore;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
|
|
||||||
public class BurntSushiValidTest {
|
public class BurntSushiValidTest {
|
||||||
|
|
||||||
|
@ -43,11 +32,13 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void arrays_hetergeneous() throws Exception {
|
public void arrays_hetergeneous() throws Exception {
|
||||||
run("arrays-hetergeneous");
|
run("arrays-hetergeneous");
|
||||||
|
runEncoder("arrays-hetergeneous");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void arrays_nested() throws Exception {
|
public void arrays_nested() throws Exception {
|
||||||
run("arrays-nested");
|
run("arrays-nested");
|
||||||
|
runEncoder("arrays-nested");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -68,21 +59,25 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void datetime() throws Exception {
|
public void datetime() throws Exception {
|
||||||
run("datetime");
|
run("datetime");
|
||||||
|
runEncoder("datetime");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void empty() throws Exception {
|
public void empty() throws Exception {
|
||||||
run("empty");
|
run("empty");
|
||||||
|
runEncoder("empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void example() throws Exception {
|
public void example() throws Exception {
|
||||||
run("example");
|
run("example");
|
||||||
|
runEncoder("example");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void float_() throws Exception {
|
public void float_() throws Exception {
|
||||||
run("float");
|
run("float");
|
||||||
|
runEncoder("float");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -93,16 +88,19 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void implicit_and_explicit_before() throws Exception {
|
public void implicit_and_explicit_before() throws Exception {
|
||||||
run("implicit-and-explicit-before");
|
run("implicit-and-explicit-before");
|
||||||
|
runEncoder("implicit-and-explicit-before");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void implicit_groups() throws Exception {
|
public void implicit_groups() throws Exception {
|
||||||
run("implicit-groups");
|
run("implicit-groups");
|
||||||
|
runEncoder("implicit-groups");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void integer() throws Exception {
|
public void integer() throws Exception {
|
||||||
run("integer");
|
run("integer");
|
||||||
|
runEncoder("integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -128,6 +126,7 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void key_special_chars_modified() throws Exception {
|
public void key_special_chars_modified() throws Exception {
|
||||||
run("key-special-chars-modified");
|
run("key-special-chars-modified");
|
||||||
|
runEncoder("key-special-chars-modified");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Ignore
|
@Test @Ignore
|
||||||
|
@ -143,11 +142,13 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void long_float() throws Exception {
|
public void long_float() throws Exception {
|
||||||
run("long-float");
|
run("long-float");
|
||||||
|
runEncoder("long-float");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void long_integer() throws Exception {
|
public void long_integer() throws Exception {
|
||||||
run("long-integer");
|
run("long-integer");
|
||||||
|
runEncoder("long-integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Ignore
|
@Test @Ignore
|
||||||
|
@ -173,6 +174,7 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void string_empty() throws Exception {
|
public void string_empty() throws Exception {
|
||||||
run("string-empty");
|
run("string-empty");
|
||||||
|
runEncoder("string-empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Ignore
|
@Test @Ignore
|
||||||
|
@ -183,11 +185,13 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void string_escapes_modified() throws Exception {
|
public void string_escapes_modified() throws Exception {
|
||||||
run("string-escapes-modified");
|
run("string-escapes-modified");
|
||||||
|
runEncoder("string-escapes-modified");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void string_simple() throws Exception {
|
public void string_simple() throws Exception {
|
||||||
run("string-simple");
|
run("string-simple");
|
||||||
|
runEncoder("string-simple");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -198,11 +202,13 @@ public class BurntSushiValidTest {
|
||||||
@Test
|
@Test
|
||||||
public void table_array_implicit() throws Exception {
|
public void table_array_implicit() throws Exception {
|
||||||
run("table-array-implicit");
|
run("table-array-implicit");
|
||||||
|
runEncoder("table-array-implicit");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void table_array_many() throws Exception {
|
public void table_array_many() throws Exception {
|
||||||
run("table-array-many");
|
run("table-array-many");
|
||||||
|
runEncoder("table-array-many");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -210,9 +216,17 @@ public class BurntSushiValidTest {
|
||||||
run("table-array-nest");
|
run("table-array-nest");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void table_array_nest_modified() throws Exception {
|
||||||
|
// Same test, but with stray spaces in the expected TOML removed
|
||||||
|
runEncoder("table-array-nest-modified",
|
||||||
|
new TomlWriter().setIndentationPolicy(new WriterIndentationPolicy().setTableIndent(2)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void table_array_one() throws Exception {
|
public void table_array_one() throws Exception {
|
||||||
run("table-array-one");
|
run("table-array-one");
|
||||||
|
runEncoder("table-array-one");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -246,7 +260,9 @@ public class BurntSushiValidTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void run(String testName) {
|
private void run(String testName) {
|
||||||
InputStream inputToml = getClass().getResourceAsStream("burntsushi/valid/" + testName + ".toml");
|
InputStream inputTomlStream = getClass().getResourceAsStream("burntsushi/valid/" + testName + ".toml");
|
||||||
|
// InputStream inputToml = getClass().getResourceAsStream("burntsushi/valid/" + testName + ".toml");
|
||||||
|
String inputToml = convertStreamToString(inputTomlStream);
|
||||||
Reader expectedJsonReader = new InputStreamReader(getClass().getResourceAsStream("burntsushi/valid/" + testName + ".json"));
|
Reader expectedJsonReader = new InputStreamReader(getClass().getResourceAsStream("burntsushi/valid/" + testName + ".json"));
|
||||||
JsonElement expectedJson = GSON.fromJson(expectedJsonReader, JsonElement.class);
|
JsonElement expectedJson = GSON.fromJson(expectedJsonReader, JsonElement.class);
|
||||||
|
|
||||||
|
@ -254,16 +270,103 @@ public class BurntSushiValidTest {
|
||||||
JsonElement actual = TEST_GSON.toJsonTree(toml).getAsJsonObject().get("values");
|
JsonElement actual = TEST_GSON.toJsonTree(toml).getAsJsonObject().get("values");
|
||||||
|
|
||||||
assertEquals(expectedJson, actual);
|
assertEquals(expectedJson, actual);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
inputToml.close();
|
inputTomlStream.close();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expectedJsonReader.close();
|
expectedJsonReader.close();
|
||||||
} catch (IOException e) {}
|
} catch (IOException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String convertStreamToString(java.io.InputStream is) {
|
||||||
|
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
|
||||||
|
return s.hasNext() ? s.next() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runEncoder(String testName) {
|
||||||
|
runEncoder(testName,
|
||||||
|
new TomlWriter().
|
||||||
|
wantTerseArrays(true).
|
||||||
|
setTimeZone(TimeZone.getTimeZone("UTC")).
|
||||||
|
setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runEncoder(String testName, TomlWriter tomlWriter) {
|
||||||
|
InputStream inputTomlStream = getClass().getResourceAsStream("burntsushi/valid/" + testName + ".toml");
|
||||||
|
String expectedToml = convertStreamToString(inputTomlStream);
|
||||||
|
|
||||||
|
Reader inputJsonReader = new InputStreamReader(getClass().getResourceAsStream("burntsushi/valid/" + testName + ".json"));
|
||||||
|
JsonElement jsonInput = GSON.fromJson(inputJsonReader, JsonElement.class);
|
||||||
|
Map<String, Object> enriched = enrichJson(jsonInput.getAsJsonObject());
|
||||||
|
|
||||||
|
String encoded = tomlWriter.write(enriched);
|
||||||
|
assertEquals(expectedToml, encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enrich toml-test JSON trees into native Java types, suiteable
|
||||||
|
// for consumption by TomlWriter.
|
||||||
|
private Map<String, Object> enrichJson(JsonObject jsonObject) {
|
||||||
|
Map<String, Object> enriched = new LinkedHashMap<String, Object>();
|
||||||
|
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
||||||
|
enriched.put(entry.getKey(), enrichJsonElement(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return enriched;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object enrichJsonElement(JsonElement jsonElement) {
|
||||||
|
if (jsonElement.isJsonObject()) {
|
||||||
|
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||||
|
if (jsonObject.has("type") && jsonObject.has("value")) {
|
||||||
|
return enrichPrimitive(jsonObject);
|
||||||
|
}
|
||||||
|
return enrichJson(jsonElement.getAsJsonObject());
|
||||||
|
} else if (jsonElement.isJsonArray()) {
|
||||||
|
List<Object> tables = new LinkedList<Object>();
|
||||||
|
for (JsonElement arrayElement : jsonElement.getAsJsonArray()) {
|
||||||
|
tables.add(enrichJsonElement(arrayElement));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new AssertionError("received unexpected JsonElement: " + jsonElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object enrichPrimitive(JsonObject jsonObject) {
|
||||||
|
String type = jsonObject.getAsJsonPrimitive("type").getAsString();
|
||||||
|
if ("bool".equals(type)) {
|
||||||
|
return jsonObject.getAsJsonPrimitive("value").getAsBoolean();
|
||||||
|
} else if ("integer".equals(type)) {
|
||||||
|
return jsonObject.getAsJsonPrimitive("value").getAsBigInteger();
|
||||||
|
} else if ("float".equals(type)) {
|
||||||
|
return jsonObject.getAsJsonPrimitive("value").getAsDouble();
|
||||||
|
} else if ("string".equals(type)) {
|
||||||
|
return jsonObject.getAsJsonPrimitive("value").getAsString();
|
||||||
|
} else if ("datetime".equals(type)) {
|
||||||
|
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||||
|
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
|
String dateString = jsonObject.getAsJsonPrimitive("value").getAsString();
|
||||||
|
try {
|
||||||
|
return iso8601Format.parse(dateString);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new AssertionError("failed to parse datetime '" + dateString + "': " + e.getMessage());
|
||||||
|
}
|
||||||
|
} else if ("array".equals(type)) {
|
||||||
|
JsonArray jsonArray = jsonObject.getAsJsonArray("value");
|
||||||
|
List<Object> enriched = new LinkedList<Object>();
|
||||||
|
for (JsonElement arrayElement : jsonArray) {
|
||||||
|
enriched.add(enrichJsonElement(arrayElement));
|
||||||
|
}
|
||||||
|
|
||||||
|
return enriched;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new AssertionError("enrichPrimitive: received unknown type " + type);
|
||||||
|
}
|
||||||
|
|
||||||
private static final Gson GSON = new Gson();
|
private static final Gson GSON = new Gson();
|
||||||
private static final Gson TEST_GSON = new GsonBuilder()
|
private static final Gson TEST_GSON = new GsonBuilder()
|
||||||
.registerTypeAdapter(Boolean.class, serialize(Boolean.class))
|
.registerTypeAdapter(Boolean.class, serialize(Boolean.class))
|
||||||
|
|
|
@ -317,7 +317,7 @@ public class ValueWriterTest {
|
||||||
@Test
|
@Test
|
||||||
public void should_write_strings_to_toml_utf8() throws UnsupportedEncodingException {
|
public void should_write_strings_to_toml_utf8() throws UnsupportedEncodingException {
|
||||||
String input = " é foo € \b \t \n \f \r \" \\ ";
|
String input = " é foo € \b \t \n \f \r \" \\ ";
|
||||||
assertEquals("\" \\u00E9 foo \\u20AC \\b \\t \\n \\f \\r \\\" \\ \"", new TomlWriter().write(input));
|
assertEquals("\" \\u00E9 foo \\u20AC \\b \\t \\n \\f \\r \\\" \\\\ \"", new TomlWriter().write(input));
|
||||||
|
|
||||||
// Check unicode code points greater than 0XFFFF
|
// Check unicode code points greater than 0XFFFF
|
||||||
input = " \uD801\uDC28 \uD840\uDC0B ";
|
input = " \uD801\uDC28 \uD840\uDC0B ";
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"albums": [
|
||||||
|
{
|
||||||
|
"name": {"type": "string", "value": "Born to Run"},
|
||||||
|
"songs": [
|
||||||
|
{"name": {"type": "string", "value": "Jungleland"}},
|
||||||
|
{"name": {"type": "string", "value": "Meeting Across the River"}}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": {"type": "string", "value": "Born in the USA"},
|
||||||
|
"songs": [
|
||||||
|
{"name": {"type": "string", "value": "Glory Days"}},
|
||||||
|
{"name": {"type": "string", "value": "Dancing in the Dark"}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
[[albums]]
|
||||||
|
name = "Born to Run"
|
||||||
|
|
||||||
|
[[albums.songs]]
|
||||||
|
name = "Jungleland"
|
||||||
|
|
||||||
|
[[albums.songs]]
|
||||||
|
name = "Meeting Across the River"
|
||||||
|
|
||||||
|
[[albums]]
|
||||||
|
name = "Born in the USA"
|
||||||
|
|
||||||
|
[[albums.songs]]
|
||||||
|
name = "Glory Days"
|
||||||
|
|
||||||
|
[[albums.songs]]
|
||||||
|
name = "Dancing in the Dark"
|
Loading…
Reference in a new issue