215 lines
7.6 KiB
Java
215 lines
7.6 KiB
Java
/*
|
|
* Copyright (C) 2022 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.google.gson.functional;
|
|
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static org.junit.Assert.fail;
|
|
|
|
import com.google.gson.FormattingStyle;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.GsonBuilder;
|
|
import com.google.gson.reflect.TypeToken;
|
|
import java.util.Arrays;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.junit.runners.JUnit4;
|
|
|
|
/**
|
|
* Functional tests for formatting styles.
|
|
*
|
|
* @author Mihai Nita
|
|
*/
|
|
@RunWith(JUnit4.class)
|
|
public class FormattingStyleTest {
|
|
|
|
// Create new input object every time to protect against tests accidentally modifying input
|
|
private static Map<String, List<Integer>> createInput() {
|
|
Map<String, List<Integer>> map = new LinkedHashMap<>();
|
|
map.put("a", Arrays.asList(1, 2));
|
|
return map;
|
|
}
|
|
|
|
private static String buildExpected(String newline, String indent, boolean spaceAfterSeparators) {
|
|
String expected =
|
|
"{<EOL><INDENT>\"a\":<COLON_SPACE>[<EOL><INDENT><INDENT>1,<COMMA_SPACE><EOL><INDENT><INDENT>2<EOL><INDENT>]<EOL>}";
|
|
String commaSpace = spaceAfterSeparators && newline.isEmpty() ? " " : "";
|
|
return expected
|
|
.replace("<EOL>", newline)
|
|
.replace("<INDENT>", indent)
|
|
.replace("<COLON_SPACE>", spaceAfterSeparators ? " " : "")
|
|
.replace("<COMMA_SPACE>", commaSpace);
|
|
}
|
|
|
|
// Various valid strings that can be used for newline and indent
|
|
private static final String[] TEST_NEWLINES = {
|
|
"", "\r", "\n", "\r\n", "\n\r\r\n", System.lineSeparator()
|
|
};
|
|
private static final String[] TEST_INDENTS = {"", " ", " ", "\t", " \t \t"};
|
|
|
|
@Test
|
|
public void testDefault() {
|
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
|
String json = gson.toJson(createInput());
|
|
assertThat(json).isEqualTo(buildExpected("\n", " ", true));
|
|
}
|
|
|
|
@Test
|
|
public void testVariousCombinationsParse() {
|
|
// Mixing various indent and newline styles in the same string, to be parsed.
|
|
String jsonStringMix = "{\r\t'a':\r\n[ 1,2\t]\n}";
|
|
TypeToken<Map<String, List<Integer>>> inputType =
|
|
new TypeToken<Map<String, List<Integer>>>() {};
|
|
|
|
Map<String, List<Integer>> actualParsed;
|
|
// Test all that all combinations of newline can be parsed and generate the same INPUT.
|
|
for (String indent : TEST_INDENTS) {
|
|
for (String newline : TEST_NEWLINES) {
|
|
FormattingStyle style = FormattingStyle.PRETTY.withNewline(newline).withIndent(indent);
|
|
Gson gson = new GsonBuilder().setFormattingStyle(style).create();
|
|
|
|
String toParse = buildExpected(newline, indent, true);
|
|
actualParsed = gson.fromJson(toParse, inputType);
|
|
assertThat(actualParsed).isEqualTo(createInput());
|
|
|
|
// Parse the mixed string with the gson parsers configured with various newline / indents.
|
|
actualParsed = gson.fromJson(jsonStringMix, inputType);
|
|
assertThat(actualParsed).isEqualTo(createInput());
|
|
}
|
|
}
|
|
}
|
|
|
|
private static String toJson(Object obj, FormattingStyle style) {
|
|
return new GsonBuilder().setFormattingStyle(style).create().toJson(obj);
|
|
}
|
|
|
|
@Test
|
|
public void testFormatCompact() {
|
|
String json = toJson(createInput(), FormattingStyle.COMPACT);
|
|
String expectedJson = buildExpected("", "", false);
|
|
assertThat(json).isEqualTo(expectedJson);
|
|
// Sanity check to verify that `buildExpected` works correctly
|
|
assertThat(json).isEqualTo("{\"a\":[1,2]}");
|
|
}
|
|
|
|
@Test
|
|
public void testFormatPretty() {
|
|
String json = toJson(createInput(), FormattingStyle.PRETTY);
|
|
String expectedJson = buildExpected("\n", " ", true);
|
|
assertThat(json).isEqualTo(expectedJson);
|
|
// Sanity check to verify that `buildExpected` works correctly
|
|
assertThat(json)
|
|
.isEqualTo(
|
|
"{\n" //
|
|
+ " \"a\": [\n" //
|
|
+ " 1,\n" //
|
|
+ " 2\n" //
|
|
+ " ]\n" //
|
|
+ "}");
|
|
}
|
|
|
|
@Test
|
|
public void testFormatPrettySingleLine() {
|
|
FormattingStyle style = FormattingStyle.COMPACT.withSpaceAfterSeparators(true);
|
|
String json = toJson(createInput(), style);
|
|
String expectedJson = buildExpected("", "", true);
|
|
assertThat(json).isEqualTo(expectedJson);
|
|
// Sanity check to verify that `buildExpected` works correctly
|
|
assertThat(json).isEqualTo("{\"a\": [1, 2]}");
|
|
}
|
|
|
|
@Test
|
|
public void testFormat() {
|
|
for (String newline : TEST_NEWLINES) {
|
|
for (String indent : TEST_INDENTS) {
|
|
for (boolean spaceAfterSeparators : new boolean[] {true, false}) {
|
|
FormattingStyle style =
|
|
FormattingStyle.COMPACT
|
|
.withNewline(newline)
|
|
.withIndent(indent)
|
|
.withSpaceAfterSeparators(spaceAfterSeparators);
|
|
|
|
String json = toJson(createInput(), style);
|
|
String expectedJson = buildExpected(newline, indent, spaceAfterSeparators);
|
|
assertThat(json).isEqualTo(expectedJson);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Should be able to convert {@link FormattingStyle#COMPACT} to {@link FormattingStyle#PRETTY}
|
|
* using the {@code withX} methods.
|
|
*/
|
|
@Test
|
|
public void testCompactToPretty() {
|
|
FormattingStyle style =
|
|
FormattingStyle.COMPACT.withNewline("\n").withIndent(" ").withSpaceAfterSeparators(true);
|
|
|
|
String json = toJson(createInput(), style);
|
|
String expectedJson = toJson(createInput(), FormattingStyle.PRETTY);
|
|
assertThat(json).isEqualTo(expectedJson);
|
|
}
|
|
|
|
/**
|
|
* Should be able to convert {@link FormattingStyle#PRETTY} to {@link FormattingStyle#COMPACT}
|
|
* using the {@code withX} methods.
|
|
*/
|
|
@Test
|
|
public void testPrettyToCompact() {
|
|
FormattingStyle style =
|
|
FormattingStyle.PRETTY.withNewline("").withIndent("").withSpaceAfterSeparators(false);
|
|
|
|
String json = toJson(createInput(), style);
|
|
String expectedJson = toJson(createInput(), FormattingStyle.COMPACT);
|
|
assertThat(json).isEqualTo(expectedJson);
|
|
}
|
|
|
|
@Test
|
|
public void testStyleValidations() {
|
|
try {
|
|
// TBD if we want to accept \u2028 and \u2029. For now we don't because JSON specification
|
|
// does not consider them to be newlines
|
|
FormattingStyle.PRETTY.withNewline("\u2028");
|
|
fail("Gson should not accept anything but \\r and \\n for newline");
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected)
|
|
.hasMessageThat()
|
|
.isEqualTo("Only combinations of \\n and \\r are allowed in newline.");
|
|
}
|
|
|
|
try {
|
|
FormattingStyle.PRETTY.withNewline("NL");
|
|
fail("Gson should not accept anything but \\r and \\n for newline");
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected)
|
|
.hasMessageThat()
|
|
.isEqualTo("Only combinations of \\n and \\r are allowed in newline.");
|
|
}
|
|
|
|
try {
|
|
FormattingStyle.PRETTY.withIndent("\f");
|
|
fail("Gson should not accept anything but space and tab for indent");
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected)
|
|
.hasMessageThat()
|
|
.isEqualTo("Only combinations of spaces and tabs are allowed in indent.");
|
|
}
|
|
}
|
|
}
|