diff --git a/gson/src/main/java/com/google/gson/FormattingStyle.java b/gson/src/main/java/com/google/gson/FormattingStyle.java
new file mode 100644
index 0000000000..19b307aa74
--- /dev/null
+++ b/gson/src/main/java/com/google/gson/FormattingStyle.java
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+import java.util.Objects;
+
+/**
+ * A class used to control what the serialization looks like.
+ *
+ *
It currently defines the kind of newline to use, and the indent, but
+ * might add more in the future.
+ *
+ * @see Wikipedia Newline article
+ *
+ * @since $next-version$
+ */
+public class FormattingStyle {
+ private final String newline;
+ private final String indent;
+
+ static public final FormattingStyle DEFAULT =
+ new FormattingStyle("\n", " ");
+
+ private FormattingStyle(String newline, String indent) {
+ Objects.requireNonNull(newline, "newline == null");
+ Objects.requireNonNull(indent, "indent == null");
+ if (!newline.matches("[\r\n]*")) {
+ throw new IllegalArgumentException(
+ "Only combinations of \\n and \\r are allowed in newline.");
+ }
+ if (!indent.matches("[ \t]*")) {
+ throw new IllegalArgumentException(
+ "Only combinations of spaces and tabs allowed in indent.");
+ }
+ this.newline = newline;
+ this.indent = indent;
+ }
+
+ /**
+ * Creates a {@link FormattingStyle} with the specified newline setting.
+ *
+ * It can be used to accommodate certain OS convention, for example
+ * hardcode {@code "\r"} for Linux and macos, {@code "\r\n"} for Windows, or
+ * call {@link java.lang.System#lineSeparator()} to match the current OS.
+ *
+ * Only combinations of {@code \n} and {@code \r} are allowed.
+ *
+ * @param newline the string value that will be used as newline.
+ * @return a newly created {@link FormattingStyle}
+ */
+ public FormattingStyle withNewline(String newline) {
+ return new FormattingStyle(newline, this.indent);
+ }
+
+ /**
+ * Creates a {@link FormattingStyle} with the specified indent string.
+ *
+ * Only combinations of spaces and tabs allowed in indent.
+ *
+ * @param indent the string value that will be used as indent.
+ * @return a newly created {@link FormattingStyle}
+ */
+ public FormattingStyle withIndent(String indent) {
+ return new FormattingStyle(this.newline, indent);
+ }
+
+ /**
+ * The string value that will be used as a newline.
+ *
+ * @return the newline value.
+ */
+ public String getNewline() {
+ return this.newline;
+ }
+
+ /**
+ * The string value that will be used as indent.
+ *
+ * @return the indent value.
+ */
+ public String getIndent() {
+ return this.indent;
+ }
+}
diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java
index 0339d56920..34f92fab3d 100644
--- a/gson/src/main/java/com/google/gson/Gson.java
+++ b/gson/src/main/java/com/google/gson/Gson.java
@@ -69,8 +69,8 @@
*
* You can create a Gson instance by invoking {@code new Gson()} if the default configuration
* is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various
- * configuration options such as versioning support, pretty printing, custom
- * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.
+ * configuration options such as versioning support, pretty printing, custom newline, custom indent,
+ * custom {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.
*
* Here is an example of how Gson is used for a simple Class:
*
@@ -141,7 +141,7 @@
public final class Gson {
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
static final boolean DEFAULT_LENIENT = false;
- static final boolean DEFAULT_PRETTY_PRINT = false;
+ static final FormattingStyle DEFAULT_FORMATTING_STYLE = null;
static final boolean DEFAULT_ESCAPE_HTML = true;
static final boolean DEFAULT_SERIALIZE_NULLS = false;
static final boolean DEFAULT_COMPLEX_MAP_KEYS = false;
@@ -182,7 +182,7 @@ public final class Gson {
final boolean complexMapKeySerialization;
final boolean generateNonExecutableJson;
final boolean htmlSafe;
- final boolean prettyPrinting;
+ final FormattingStyle formattingStyle;
final boolean lenient;
final boolean serializeSpecialFloatingPointValues;
final boolean useJdkUnsafe;
@@ -202,7 +202,9 @@ public final class Gson {
*
* - The JSON generated by
toJson
methods is in compact representation. This
* means that all the unneeded white-space is removed. You can change this behavior with
- * {@link GsonBuilder#setPrettyPrinting()}.
+ * {@link GsonBuilder#setPrettyPrinting()}.
+ * - When the JSON generated contains more than one line, the kind of newline and indent to
+ * use can be configured with {@link GsonBuilder#setPrettyPrinting(FormattingStyle)}.
* - The generated JSON omits all the fields that are null. Note that nulls in arrays are
* kept as is since an array is an ordered list. Moreover, if a field is not null, but its
* generated JSON is empty, the field is kept. You can configure Gson to serialize null values
@@ -234,7 +236,7 @@ public Gson() {
this(Excluder.DEFAULT, DEFAULT_FIELD_NAMING_STRATEGY,
Collections.>emptyMap(), DEFAULT_SERIALIZE_NULLS,
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
- DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
+ DEFAULT_FORMATTING_STYLE, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
DEFAULT_USE_JDK_UNSAFE,
LongSerializationPolicy.DEFAULT, DEFAULT_DATE_PATTERN, DateFormat.DEFAULT, DateFormat.DEFAULT,
Collections.emptyList(), Collections.emptyList(),
@@ -245,7 +247,7 @@ public Gson() {
Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy,
Map> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
- boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
+ FormattingStyle formattingStyle, boolean lenient, boolean serializeSpecialFloatingPointValues,
boolean useJdkUnsafe,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List builderFactories,
@@ -261,7 +263,7 @@ public Gson() {
this.complexMapKeySerialization = complexMapKeySerialization;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
- this.prettyPrinting = prettyPrinting;
+ this.formattingStyle = formattingStyle;
this.lenient = lenient;
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
this.useJdkUnsafe = useJdkUnsafe;
@@ -702,7 +704,7 @@ public JsonElement toJsonTree(Object src) {
*
* Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
*
- * @return Json representation of {@code src}
+ * @return JSON representation of {@code src}.
* @since 1.4
*
* @see #toJsonTree(Object)
@@ -724,7 +726,7 @@ public JsonElement toJsonTree(Object src, Type typeOfSrc) {
* {@link Writer}, use {@link #toJson(Object, Appendable)} instead.
*
* @param src the object for which JSON representation is to be created
- * @return Json representation of {@code src}.
+ * @return JSON representation of {@code src}.
*
* @see #toJson(Object, Appendable)
* @see #toJson(Object, Type)
@@ -749,7 +751,7 @@ public String toJson(Object src) {
*
* Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
*
- * @return JSON representation of {@code src}
+ * @return JSON representation of {@code src}.
*
* @see #toJson(Object, Type, Appendable)
* @see #toJson(Object)
@@ -855,7 +857,7 @@ public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOE
* Converts a tree of {@link JsonElement}s into its equivalent JSON representation.
*
* @param jsonElement root of a tree of {@link JsonElement}s
- * @return JSON String representation of the tree
+ * @return JSON String representation of the tree.
* @since 1.4
*/
public String toJson(JsonElement jsonElement) {
@@ -891,6 +893,7 @@ public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOExce
* - {@link GsonBuilder#serializeNulls()}
* - {@link GsonBuilder#setLenient()}
* - {@link GsonBuilder#setPrettyPrinting()}
+ * - {@link GsonBuilder#setPrettyPrinting(FormattingStyle)}
*
*/
public JsonWriter newJsonWriter(Writer writer) throws IOException {
@@ -898,9 +901,7 @@ public JsonWriter newJsonWriter(Writer writer) throws IOException {
writer.write(JSON_NON_EXECUTABLE_PREFIX);
}
JsonWriter jsonWriter = new JsonWriter(writer);
- if (prettyPrinting) {
- jsonWriter.setIndent(" ");
- }
+ jsonWriter.setFormattingStyle(formattingStyle);
jsonWriter.setHtmlSafe(htmlSafe);
jsonWriter.setLenient(lenient);
jsonWriter.setSerializeNulls(serializeNulls);
diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java
index 8b04430f7f..63c7f04749 100644
--- a/gson/src/main/java/com/google/gson/GsonBuilder.java
+++ b/gson/src/main/java/com/google/gson/GsonBuilder.java
@@ -23,7 +23,7 @@
import static com.google.gson.Gson.DEFAULT_LENIENT;
import static com.google.gson.Gson.DEFAULT_NUMBER_TO_NUMBER_STRATEGY;
import static com.google.gson.Gson.DEFAULT_OBJECT_TO_NUMBER_STRATEGY;
-import static com.google.gson.Gson.DEFAULT_PRETTY_PRINT;
+import static com.google.gson.Gson.DEFAULT_FORMATTING_STYLE;
import static com.google.gson.Gson.DEFAULT_SERIALIZE_NULLS;
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
import static com.google.gson.Gson.DEFAULT_USE_JDK_UNSAFE;
@@ -98,7 +98,7 @@ public final class GsonBuilder {
private boolean complexMapKeySerialization = DEFAULT_COMPLEX_MAP_KEYS;
private boolean serializeSpecialFloatingPointValues = DEFAULT_SPECIALIZE_FLOAT_VALUES;
private boolean escapeHtmlChars = DEFAULT_ESCAPE_HTML;
- private boolean prettyPrinting = DEFAULT_PRETTY_PRINT;
+ private FormattingStyle formattingStyle = DEFAULT_FORMATTING_STYLE;
private boolean generateNonExecutableJson = DEFAULT_JSON_NON_EXECUTABLE;
private boolean lenient = DEFAULT_LENIENT;
private boolean useJdkUnsafe = DEFAULT_USE_JDK_UNSAFE;
@@ -129,7 +129,7 @@ public GsonBuilder() {
this.complexMapKeySerialization = gson.complexMapKeySerialization;
this.generateNonExecutableJson = gson.generateNonExecutableJson;
this.escapeHtmlChars = gson.htmlSafe;
- this.prettyPrinting = gson.prettyPrinting;
+ this.formattingStyle = gson.formattingStyle;
this.lenient = gson.lenient;
this.serializeSpecialFloatingPointValues = gson.serializeSpecialFloatingPointValues;
this.longSerializationPolicy = gson.longSerializationPolicy;
@@ -478,13 +478,26 @@ public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strateg
}
/**
- * Configures Gson to output Json that fits in a page for pretty printing. This option only
- * affects Json serialization.
+ * Configures Gson to output JSON that fits in a page for pretty printing. This option only
+ * affects JSON serialization.
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
*/
public GsonBuilder setPrettyPrinting() {
- prettyPrinting = true;
+ return setPrettyPrinting(FormattingStyle.DEFAULT);
+ }
+
+ /**
+ * Configures Gson to output JSON that uses a certain kind of formatting stile (for example newline and indent).
+ * This option only affects JSON serialization.
+ *
+ * Has no effect if the serialized format is a single line.
+ *
+ * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+ * @since $next-version$
+ */
+ public GsonBuilder setPrettyPrinting(FormattingStyle formattingStyle) {
+ this.formattingStyle = formattingStyle;
return this;
}
@@ -761,7 +774,7 @@ public Gson create() {
return new Gson(excluder, fieldNamingPolicy, new HashMap<>(instanceCreators),
serializeNulls, complexMapKeySerialization,
- generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
+ generateNonExecutableJson, escapeHtmlChars, formattingStyle, lenient,
serializeSpecialFloatingPointValues, useJdkUnsafe, longSerializationPolicy,
datePattern, dateStyle, timeStyle, new ArrayList<>(this.factories),
new ArrayList<>(this.hierarchyFactories), factories,
diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java
index fce9093fb6..827de959b9 100644
--- a/gson/src/main/java/com/google/gson/JsonPrimitive.java
+++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java
@@ -106,7 +106,7 @@ public boolean getAsBoolean() {
if (isBoolean()) {
return (Boolean) value;
}
- // Check to see if the value as a String is "true" in any case.
+ // Check to see if the value as a String is "true" in any case.
return Boolean.parseBoolean(getAsString());
}
diff --git a/gson/src/main/java/com/google/gson/stream/JsonWriter.java b/gson/src/main/java/com/google/gson/stream/JsonWriter.java
index 90e3529c5c..5afa228eaf 100644
--- a/gson/src/main/java/com/google/gson/stream/JsonWriter.java
+++ b/gson/src/main/java/com/google/gson/stream/JsonWriter.java
@@ -36,6 +36,8 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
+import com.google.gson.FormattingStyle;
+
/**
* Writes a JSON (RFC 7159)
* encoded value to a stream, one token at a time. The stream includes both
@@ -180,10 +182,9 @@ public class JsonWriter implements Closeable, Flushable {
}
/**
- * A string containing a full set of spaces for a single level of
- * indentation, or null for no pretty printing.
+ * The settings used for pretty printing, or null for no pretty printing.
*/
- private String indent;
+ private FormattingStyle formattingStyle;
/**
* The name/value separator; either ":" or ": ".
@@ -217,14 +218,44 @@ public JsonWriter(Writer out) {
*/
public final void setIndent(String indent) {
if (indent.length() == 0) {
- this.indent = null;
+ setFormattingStyle(null);
+ } else {
+ setFormattingStyle(FormattingStyle.DEFAULT.withIndent(indent));
+ }
+ }
+
+ /**
+ * Sets the pretty printing style to be used in the encoded document.
+ * No pretty printing if null.
+ *
+ * Sets the various attributes to be used in the encoded document.
+ * For example the indentation string to be repeated for each level of indentation.
+ * Or the newline style, to accommodate various OS styles.
+ *
+ * Has no effect if the serialized format is a single line.
+ *
+ * @param formattingStyle the style used for pretty printing, no pretty printing if null.
+ * @since $next-version$
+ */
+ public final void setFormattingStyle(FormattingStyle formattingStyle) {
+ this.formattingStyle = formattingStyle;
+ if (formattingStyle == null) {
this.separator = ":";
} else {
- this.indent = indent;
this.separator = ": ";
}
}
+ /**
+ * Returns the pretty printing style used by this writer.
+ *
+ * @return the FormattingStyle that will be used.
+ * @since $next-version$
+ */
+ public final FormattingStyle getFormattingStyle() {
+ return formattingStyle;
+ }
+
/**
* Configure this writer to relax its syntax rules. By default, this writer
* only emits well-formed JSON as specified by >(), true, false, true, false,
- true, true, false, true, LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
+ FormattingStyle.DEFAULT, true, false, true,
+ LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
DateFormat.DEFAULT, new ArrayList(),
new ArrayList(), new ArrayList(),
CUSTOM_OBJECT_TO_NUMBER_STRATEGY, CUSTOM_NUMBER_TO_NUMBER_STRATEGY,
@@ -79,7 +80,8 @@ public void testOverridesDefaultExcluder() {
public void testClonedTypeAdapterFactoryListsAreIndependent() {
Gson original = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
new HashMap>(), true, false, true, false,
- true, true, false, true, LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
+ FormattingStyle.DEFAULT, true, false, true,
+ LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
DateFormat.DEFAULT, new ArrayList(),
new ArrayList(), new ArrayList(),
CUSTOM_OBJECT_TO_NUMBER_STRATEGY, CUSTOM_NUMBER_TO_NUMBER_STRATEGY,
diff --git a/gson/src/test/java/com/google/gson/functional/FormattingStyleTest.java b/gson/src/test/java/com/google/gson/functional/FormattingStyleTest.java
new file mode 100644
index 0000000000..4bdbb95f86
--- /dev/null
+++ b/gson/src/test/java/com/google/gson/functional/FormattingStyleTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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 org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.google.gson.FormattingStyle;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+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 {
+
+ private static final String[] INPUT = {"v1", "v2"};
+ private static final String EXPECTED = "[\"v1\",\"v2\"]";
+ private static final String EXPECTED_OS = buildExpected(System.lineSeparator(), " ");
+ private static final String EXPECTED_CR = buildExpected("\r", " ");
+ private static final String EXPECTED_LF = buildExpected("\n", " ");
+ private static final String EXPECTED_CRLF = buildExpected("\r\n", " ");
+
+ // 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(INPUT);
+ // Make sure the default uses LF, like before.
+ assertEquals(EXPECTED_LF, json);
+ }
+
+ @Test
+ public void testNewlineCrLf() {
+ FormattingStyle style = FormattingStyle.DEFAULT.withNewline("\r\n");
+ Gson gson = new GsonBuilder().setPrettyPrinting(style).create();
+ String json = gson.toJson(INPUT);
+ assertEquals(EXPECTED_CRLF, json);
+ }
+
+ @Test
+ public void testNewlineLf() {
+ FormattingStyle style = FormattingStyle.DEFAULT.withNewline("\n");
+ Gson gson = new GsonBuilder().setPrettyPrinting(style).create();
+ String json = gson.toJson(INPUT);
+ assertEquals(EXPECTED_LF, json);
+ }
+
+ @Test
+ public void testNewlineCr() {
+ FormattingStyle style = FormattingStyle.DEFAULT.withNewline("\r");
+ Gson gson = new GsonBuilder().setPrettyPrinting(style).create();
+ String json = gson.toJson(INPUT);
+ assertEquals(EXPECTED_CR, json);
+ }
+
+ @Test
+ public void testNewlineOs() {
+ FormattingStyle style = FormattingStyle.DEFAULT.withNewline(System.lineSeparator());
+ Gson gson = new GsonBuilder().setPrettyPrinting(style).create();
+ String json = gson.toJson(INPUT);
+ assertEquals(EXPECTED_OS, json);
+ }
+
+ @Test
+ public void testVariousCombinationsToString() {
+ for (String indent : TEST_INDENTS) {
+ for (String newline : TEST_NEWLINES) {
+ FormattingStyle style = FormattingStyle.DEFAULT.withNewline(newline).withIndent(indent);
+ Gson gson = new GsonBuilder().setPrettyPrinting(style).create();
+ String json = gson.toJson(INPUT);
+ assertEquals(buildExpected(newline, indent), json);
+ }
+ }
+ }
+
+ @Test
+ public void testVariousCombinationsParse() {
+ // Mixing various indent and newline styles in the same string, to be parsed.
+ String jsonStringMix = "[\r\t'v1',\r\n 'v2'\n]";
+
+ String[] 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.DEFAULT.withNewline(newline).withIndent(indent);
+ Gson gson = new GsonBuilder().setPrettyPrinting(style).create();
+
+ String toParse = buildExpected(newline, indent);
+ actualParsed = gson.fromJson(toParse, INPUT.getClass());
+ assertArrayEquals(INPUT, actualParsed);
+
+ // Parse the mixed string with the gson parsers configured with various newline / indents.
+ actualParsed = gson.fromJson(jsonStringMix, INPUT.getClass());
+ assertArrayEquals(INPUT, actualParsed);
+ }
+ }
+ }
+
+ @Test
+ public void testStyleValidations() {
+ try {
+ // TBD if we want to accept \u2028 and \u2029. For now we don't.
+ FormattingStyle.DEFAULT.withNewline("\u2028");
+ fail("Gson should not accept anything but \\r and \\n for newline");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ FormattingStyle.DEFAULT.withNewline("NL");
+ fail("Gson should not accept anything but \\r and \\n for newline");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ FormattingStyle.DEFAULT.withIndent("\f");
+ fail("Gson should not accept anything but space and tab for indent");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ private static String buildExpected(String newline, String indent) {
+ return EXPECTED.replace("", newline).replace("", indent);
+ }
+}
diff --git a/gson/src/test/java/com/google/gson/internal/bind/JsonTreeWriterTest.java b/gson/src/test/java/com/google/gson/internal/bind/JsonTreeWriterTest.java
index 3801033a36..116d275c0d 100644
--- a/gson/src/test/java/com/google/gson/internal/bind/JsonTreeWriterTest.java
+++ b/gson/src/test/java/com/google/gson/internal/bind/JsonTreeWriterTest.java
@@ -278,8 +278,12 @@ public void testJsonValue() throws IOException {
*/
@Test
public void testOverrides() {
- List ignoredMethods = Arrays.asList("setLenient(boolean)", "isLenient()", "setIndent(java.lang.String)",
- "setHtmlSafe(boolean)", "isHtmlSafe()", "setSerializeNulls(boolean)", "getSerializeNulls()");
+ List ignoredMethods = Arrays.asList(
+ "setLenient(boolean)", "isLenient()",
+ "setIndent(java.lang.String)",
+ "setHtmlSafe(boolean)", "isHtmlSafe()",
+ "setFormattingStyle(com.google.gson.FormattingStyle)", "getFormattingStyle()",
+ "setSerializeNulls(boolean)", "getSerializeNulls()");
MoreAsserts.assertOverridesMethods(JsonWriter.class, JsonTreeWriter.class, ignoredMethods);
}
}
diff --git a/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java b/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
index a0896676c5..70470a166b 100644
--- a/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
+++ b/gson/src/test/java/com/google/gson/stream/JsonWriterTest.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
+import com.google.gson.FormattingStyle;
import com.google.gson.internal.LazilyParsedNumber;
import java.io.IOException;
import java.io.StringWriter;
@@ -844,4 +845,30 @@ public void testWriterCloseIsIdempotent() throws IOException {
writer.close();
writer.close();
}
+
+ @Test
+ public void testSetGetFormattingStyle() throws IOException {
+ String lineSeparator = "\r\n";
+
+ StringWriter stringWriter = new StringWriter();
+ JsonWriter jsonWriter = new JsonWriter(stringWriter);
+ jsonWriter.setFormattingStyle(FormattingStyle.DEFAULT.withIndent(" \t ").withNewline(lineSeparator));
+
+ jsonWriter.beginArray();
+ jsonWriter.value(true);
+ jsonWriter.value("text");
+ jsonWriter.value(5.0);
+ jsonWriter.nullValue();
+ jsonWriter.endArray();
+
+ String expected = "[\r\n"
+ + " \t true,\r\n"
+ + " \t \"text\",\r\n"
+ + " \t 5.0,\r\n"
+ + " \t null\r\n"
+ + "]";
+ assertThat(stringWriter.toString()).isEqualTo(expected);
+
+ assertThat(jsonWriter.getFormattingStyle().getNewline()).isEqualTo(lineSeparator);
+ }
}