Fixes #776: Add settings for the kind of newline to use (#2231)

* Add settings for kind of newline to use

* Fix amp in javadoc

* Fixing link in javadoc

* Doc: use JSON instead of Json

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* PR Feedback: Objects.requireNonNull

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* PR Feedback: $next-version$, don't hardcode

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* s/testNewlineLF/testNewlineLf/

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* Implement PR feedback

* Round two of review

* Restore copyright year, no reason to update

* Rename OS named enum values to CR and LF

* Add javadoc to NewlineStyle.getValue()

* Implement PR feedback, round 2

* Fix typo

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* No need for line break

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* Shorter, cleaner doc

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>

* Using a FormattingStyle for pretty print

* Fix Junit4 and Truth after merge from master

* Implement review feedback

* Double backslash in message

---------

Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
This commit is contained in:
Mihai Nita 2023-02-12 08:20:02 -08:00 committed by GitHub
parent af21798436
commit 19f54ee6ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 371 additions and 43 deletions

View File

@ -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.
*
* <p>It currently defines the kind of newline to use, and the indent, but
* might add more in the future.</p>
*
* @see <a href="https://en.wikipedia.org/wiki/Newline">Wikipedia Newline article</a>
*
* @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.
*
* <p>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.</p>
*
* <p>Only combinations of {@code \n} and {@code \r} are allowed.</p>
*
* @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.
*
* <p>Only combinations of spaces and tabs allowed in indent.</p>
*
* @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;
}
}

View File

@ -69,8 +69,8 @@ import java.util.concurrent.atomic.AtomicLongArray;
*
* <p>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.</p>
* configuration options such as versioning support, pretty printing, custom newline, custom indent,
* custom {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p>
*
* <p>Here is an example of how Gson is used for a simple Class:
*
@ -141,7 +141,7 @@ import java.util.concurrent.atomic.AtomicLongArray;
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 {
* <ul>
* <li>The JSON generated by <code>toJson</code> methods is in compact representation. This
* means that all the unneeded white-space is removed. You can change this behavior with
* {@link GsonBuilder#setPrettyPrinting()}. </li>
* {@link GsonBuilder#setPrettyPrinting()}.</li>
* <li>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)}.</li>
* <li>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 final class Gson {
this(Excluder.DEFAULT, DEFAULT_FIELD_NAMING_STRATEGY,
Collections.<Type, InstanceCreator<?>>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.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
@ -245,7 +247,7 @@ public final class Gson {
Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy,
Map<Type, InstanceCreator<?>> 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<TypeAdapterFactory> builderFactories,
@ -261,7 +263,7 @@ public final class 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 final class Gson {
* <pre>
* Type typeOfSrc = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
* </pre>
* @return Json representation of {@code src}
* @return JSON representation of {@code src}.
* @since 1.4
*
* @see #toJsonTree(Object)
@ -724,7 +726,7 @@ public final class Gson {
* {@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 final class Gson {
* <pre>
* Type typeOfSrc = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
* </pre>
* @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 final class Gson {
* 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 final class Gson {
* <li>{@link GsonBuilder#serializeNulls()}</li>
* <li>{@link GsonBuilder#setLenient()}</li>
* <li>{@link GsonBuilder#setPrettyPrinting()}</li>
* <li>{@link GsonBuilder#setPrettyPrinting(FormattingStyle)}</li>
* </ul>
*/
public JsonWriter newJsonWriter(Writer writer) throws IOException {
@ -898,9 +901,7 @@ public final class Gson {
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);

View File

@ -23,7 +23,7 @@ import static com.google.gson.Gson.DEFAULT_JSON_NON_EXECUTABLE;
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 final class 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 final class GsonBuilder {
}
/**
* 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.
*
* <p>Has no effect if the serialized format is a single line.</p>
*
* @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 final class GsonBuilder {
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,

View File

@ -106,7 +106,7 @@ public final class JsonPrimitive extends JsonElement {
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());
}

View File

@ -36,6 +36,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import com.google.gson.FormattingStyle;
/**
* Writes a JSON (<a href="http://www.ietf.org/rfc/rfc7159.txt">RFC 7159</a>)
* 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 class JsonWriter implements Closeable, Flushable {
*/
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.
*
* <p>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.</p>
*
* <p>Has no effect if the serialized format is a single line.</p>
*
* @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 <a
@ -645,13 +676,13 @@ public class JsonWriter implements Closeable, Flushable {
}
private void newline() throws IOException {
if (indent == null) {
if (formattingStyle == null) {
return;
}
out.write('\n');
out.write(formattingStyle.getNewline());
for (int i = 1, size = stackSize; i < size; i++) {
out.write(indent);
out.write(formattingStyle.getIndent());
}
}

View File

@ -19,14 +19,14 @@
* @since 2.8.6
*/
module com.google.gson {
exports com.google.gson;
exports com.google.gson.annotations;
exports com.google.gson.reflect;
exports com.google.gson.stream;
exports com.google.gson;
exports com.google.gson.annotations;
exports com.google.gson.reflect;
exports com.google.gson.stream;
// Optional dependency on java.sql
requires static java.sql;
// Optional dependency on java.sql
requires static java.sql;
// Optional dependency on jdk.unsupported for JDK's sun.misc.Unsafe
requires static jdk.unsupported;
// Optional dependency on jdk.unsupported for JDK's sun.misc.Unsafe
requires static jdk.unsupported;
}

View File

@ -63,7 +63,8 @@ public final class GsonTest {
public void testOverridesDefaultExcluder() {
Gson gson = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
new HashMap<Type, InstanceCreator<?>>(), 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<TypeAdapterFactory>(),
new ArrayList<TypeAdapterFactory>(), new ArrayList<TypeAdapterFactory>(),
CUSTOM_OBJECT_TO_NUMBER_STRATEGY, CUSTOM_NUMBER_TO_NUMBER_STRATEGY,
@ -79,7 +80,8 @@ public final class GsonTest {
public void testClonedTypeAdapterFactoryListsAreIndependent() {
Gson original = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
new HashMap<Type, InstanceCreator<?>>(), 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<TypeAdapterFactory>(),
new ArrayList<TypeAdapterFactory>(), new ArrayList<TypeAdapterFactory>(),
CUSTOM_OBJECT_TO_NUMBER_STRATEGY, CUSTOM_NUMBER_TO_NUMBER_STRATEGY,

View File

@ -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 = "[<EOL><INDENT>\"v1\",<EOL><INDENT>\"v2\"<EOL>]";
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("<EOL>", newline).replace("<INDENT>", indent);
}
}

View File

@ -278,8 +278,12 @@ public final class JsonTreeWriterTest {
*/
@Test
public void testOverrides() {
List<String> ignoredMethods = Arrays.asList("setLenient(boolean)", "isLenient()", "setIndent(java.lang.String)",
"setHtmlSafe(boolean)", "isHtmlSafe()", "setSerializeNulls(boolean)", "getSerializeNulls()");
List<String> 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);
}
}

View File

@ -19,6 +19,7 @@ package com.google.gson.stream;
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 final class JsonWriterTest {
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);
}
}