Several breaking changes

This commit is contained in:
Johannes Frohnmeyer 2022-05-17 21:20:10 +02:00
parent ccf30b23e8
commit dc4e61ac7b
Signed by: Johannes
GPG Key ID: E76429612C2929F4
47 changed files with 472 additions and 310 deletions

1
.gitignore vendored
View File

@ -20,3 +20,4 @@ build
.DS_Store
examples/android-proguard-example/gen
.attach_pid*

View File

@ -1,7 +1,17 @@
# About this fork
This fork of Gson adds support for writing comments in JsonWriter.
To do this, JsonWriter and CommentsTest were adjusted.
This fork of Gson adds several features which were originally denied due to Gson's maintenance status.
Among them are:
- support for writing comments
- collections with single entries without array syntax (`"single entry"` can become a `List` or array)
- stricter leniency enforcement from the main Gson class (`toJson`, `fromJson` will respect the choice)
- slightly better error messages
- skipping empty entries in arrays (`["one",, "two",]`)
- optionally omitting quotes around entry names like in Json5
- support for hexadecimal integers
This means the only thing lacking for Json5 support is trailing commas in objects
Please be aware that I also increased the minimum java version to 11
To use this, add the following:
```groovy

View File

@ -35,12 +35,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.Excluder;
import com.google.gson.internal.GsonBuildConfig;
import com.google.gson.internal.LazilyParsedNumber;
import com.google.gson.internal.Primitives;
import com.google.gson.internal.Streams;
import com.google.gson.internal.*;
import com.google.gson.internal.bind.ArrayTypeAdapter;
import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
import com.google.gson.internal.bind.DateTypeAdapter;
@ -104,23 +99,6 @@ import com.google.gson.stream.MalformedJsonException;
* @author Jesse Wilson
*/
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 boolean DEFAULT_ESCAPE_HTML = true;
static final boolean DEFAULT_SERIALIZE_NULLS = false;
static final boolean DEFAULT_COMPLEX_MAP_KEYS = false;
static final boolean DEFAULT_DUPLICATE_MAP_KEYS = false;
static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false;
static final boolean DEFAULT_USE_JDK_UNSAFE = true;
static final String DEFAULT_DATE_PATTERN = null;
static final FieldNamingStrategy DEFAULT_FIELD_NAMING_STRATEGY = FieldNamingPolicy.IDENTITY;
static final ToNumberStrategy DEFAULT_OBJECT_TO_NUMBER_STRATEGY = ToNumberPolicy.DOUBLE;
static final ToNumberStrategy DEFAULT_NUMBER_TO_NUMBER_STRATEGY = ToNumberPolicy.LAZILY_PARSED_NUMBER;
private static final TypeToken<?> NULL_KEY_SURROGATE = TypeToken.get(Object.class);
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
/**
* This thread local guards against reentrant calls to getAdapter(). In
* certain object graphs, creating an adapter for a type may recursively
@ -148,6 +126,7 @@ public final class Gson {
final boolean htmlSafe;
final boolean prettyPrinting;
final boolean lenient;
final boolean omitQuotes;
final boolean serializeSpecialFloatingPointValues;
final boolean useJdkUnsafe;
final String datePattern;
@ -195,21 +174,21 @@ public final class Gson {
* </ul>
*/
public Gson() {
this(Excluder.DEFAULT, DEFAULT_FIELD_NAMING_STRATEGY,
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_DUPLICATE_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
DEFAULT_USE_JDK_UNSAFE,
LongSerializationPolicy.DEFAULT, DEFAULT_DATE_PATTERN, DateFormat.DEFAULT, DateFormat.DEFAULT,
this(Excluder.DEFAULT, DefaultConfig.DEFAULT_FIELD_NAMING_STRATEGY,
Collections.<Type, InstanceCreator<?>>emptyMap(), DefaultConfig.DEFAULT_SERIALIZE_NULLS,
DefaultConfig.DEFAULT_COMPLEX_MAP_KEYS, DefaultConfig.DEFAULT_DUPLICATE_MAP_KEYS, DefaultConfig.DEFAULT_JSON_NON_EXECUTABLE, DefaultConfig.DEFAULT_ESCAPE_HTML,
DefaultConfig.DEFAULT_PRETTY_PRINT, true, DefaultConfig.DEFAULT_OMIT_QUOTES, DefaultConfig.DEFAULT_SPECIALIZE_FLOAT_VALUES,
DefaultConfig.DEFAULT_USE_JDK_UNSAFE,
LongSerializationPolicy.DEFAULT, DefaultConfig.DEFAULT_DATE_PATTERN, DateFormat.DEFAULT, DateFormat.DEFAULT,
Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
Collections.<TypeAdapterFactory>emptyList(), DEFAULT_OBJECT_TO_NUMBER_STRATEGY, DEFAULT_NUMBER_TO_NUMBER_STRATEGY,
Collections.<TypeAdapterFactory>emptyList(), DefaultConfig.DEFAULT_OBJECT_TO_NUMBER_STRATEGY, DefaultConfig.DEFAULT_NUMBER_TO_NUMBER_STRATEGY,
Collections.<ReflectionAccessFilter>emptyList());
}
Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy,
Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean duplicateMapKeyDeserialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
boolean prettyPrinting, boolean lenient, boolean omitQuotes, boolean serializeSpecialFloatingPointValues,
boolean useJdkUnsafe,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List<TypeAdapterFactory> builderFactories,
@ -228,6 +207,7 @@ public final class Gson {
this.htmlSafe = htmlSafe;
this.prettyPrinting = prettyPrinting;
this.lenient = lenient;
this.omitQuotes = omitQuotes;
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
this.useJdkUnsafe = useJdkUnsafe;
this.longSerializationPolicy = longSerializationPolicy;
@ -481,7 +461,7 @@ public final class Gson {
*/
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
TypeAdapter<?> cached = typeTokenCache.get(type == null ? DefaultConfig.NULL_KEY_SURROGATE : type);
if (cached != null) {
return (TypeAdapter<T>) cached;
}
@ -745,7 +725,9 @@ public final class Gson {
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
writer.setLenient(lenient);
boolean oldOmitQuotes = writer.getOmitQuotes();
writer.setOmitQuotes(omitQuotes);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
@ -760,6 +742,7 @@ public final class Gson {
throw error;
} finally {
writer.setLenient(oldLenient);
writer.setOmitQuotes(oldOmitQuotes);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
@ -804,12 +787,13 @@ public final class Gson {
* <li>{@link GsonBuilder#generateNonExecutableJson()}</li>
* <li>{@link GsonBuilder#serializeNulls()}</li>
* <li>{@link GsonBuilder#setLenient()}</li>
* <li>{@link GsonBuilder#setOmitQuotes()}</li>
* <li>{@link GsonBuilder#setPrettyPrinting()}</li>
* </ul>
*/
public JsonWriter newJsonWriter(Writer writer) throws IOException {
if (generateNonExecutableJson) {
writer.write(JSON_NON_EXECUTABLE_PREFIX);
writer.write(DefaultConfig.JSON_NON_EXECUTABLE_PREFIX);
}
JsonWriter jsonWriter = new JsonWriter(writer);
if (prettyPrinting) {
@ -817,6 +801,7 @@ public final class Gson {
}
jsonWriter.setHtmlSafe(htmlSafe);
jsonWriter.setLenient(lenient);
jsonWriter.setOmitQuotes(omitQuotes);
jsonWriter.setSerializeNulls(serializeNulls);
return jsonWriter;
}
@ -841,7 +826,9 @@ public final class Gson {
*/
public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
writer.setLenient(lenient);
boolean oldOmitQuotes = writer.getOmitQuotes();
writer.setOmitQuotes(omitQuotes);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
@ -856,6 +843,7 @@ public final class Gson {
throw error;
} finally {
writer.setLenient(oldLenient);
writer.setOmitQuotes(oldOmitQuotes);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
@ -989,7 +977,7 @@ public final class Gson {
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
reader.setLenient(lenient);
try {
reader.peek();
isEmpty = false;

View File

@ -35,18 +35,7 @@ import com.google.gson.internal.sql.SqlTypesSupport;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import static com.google.gson.Gson.DEFAULT_COMPLEX_MAP_KEYS;
import static com.google.gson.Gson.DEFAULT_DATE_PATTERN;
import static com.google.gson.Gson.DEFAULT_DUPLICATE_MAP_KEYS;
import static com.google.gson.Gson.DEFAULT_ESCAPE_HTML;
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_SERIALIZE_NULLS;
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
import static com.google.gson.Gson.DEFAULT_USE_JDK_UNSAFE;
import static com.google.gson.internal.DefaultConfig.*;
/**
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
@ -100,6 +89,7 @@ public final class GsonBuilder {
private boolean prettyPrinting = DEFAULT_PRETTY_PRINT;
private boolean generateNonExecutableJson = DEFAULT_JSON_NON_EXECUTABLE;
private boolean lenient = DEFAULT_LENIENT;
private boolean omitQuotes = DEFAULT_OMIT_QUOTES;
private boolean useJdkUnsafe = DEFAULT_USE_JDK_UNSAFE;
private ToNumberStrategy objectToNumberStrategy = DEFAULT_OBJECT_TO_NUMBER_STRATEGY;
private ToNumberStrategy numberToNumberStrategy = DEFAULT_NUMBER_TO_NUMBER_STRATEGY;
@ -131,6 +121,7 @@ public final class GsonBuilder {
this.escapeHtmlChars = gson.htmlSafe;
this.prettyPrinting = gson.prettyPrinting;
this.lenient = gson.lenient;
this.omitQuotes = gson.omitQuotes;
this.serializeSpecialFloatingPointValues = gson.serializeSpecialFloatingPointValues;
this.longSerializationPolicy = gson.longSerializationPolicy;
this.datePattern = gson.datePattern;
@ -456,6 +447,15 @@ public final class GsonBuilder {
return this;
}
/**
* By default, Gson always writes quotes around entry names.
* This option allows omitting quotes if the name is alphanumeric.
*/
public GsonBuilder setOmitQuotes() {
omitQuotes = true;
return this;
}
/**
* By default, Gson escapes HTML characters such as &lt; &gt; etc. Use this option to configure
* Gson to pass-through HTML characters as is.
@ -694,7 +694,7 @@ public final class GsonBuilder {
return new Gson(excluder, fieldNamingPolicy, new HashMap<>(instanceCreators),
serializeNulls, complexMapKeySerialization, duplicateMapKeyDeserialization,
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient, omitQuotes,
serializeSpecialFloatingPointValues, useJdkUnsafe, longSerializationPolicy,
datePattern, dateStyle, timeStyle, new ArrayList<>(this.factories),
new ArrayList<>(this.hierarchyFactories), factories,

View File

@ -0,0 +1,23 @@
package com.google.gson.internal;
import com.google.gson.*;
import com.google.gson.reflect.*;
public class DefaultConfig {
public static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
public static final boolean DEFAULT_LENIENT = false;
public static final boolean DEFAULT_OMIT_QUOTES = false;
public static final boolean DEFAULT_PRETTY_PRINT = false;
public static final boolean DEFAULT_ESCAPE_HTML = true;
public static final boolean DEFAULT_SERIALIZE_NULLS = false;
public static final boolean DEFAULT_COMPLEX_MAP_KEYS = false;
public static final boolean DEFAULT_DUPLICATE_MAP_KEYS = false;
public static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false;
public static final boolean DEFAULT_USE_JDK_UNSAFE = true;
public static final String DEFAULT_DATE_PATTERN = null;
public static final FieldNamingStrategy DEFAULT_FIELD_NAMING_STRATEGY = FieldNamingPolicy.IDENTITY;
public static final ToNumberStrategy DEFAULT_OBJECT_TO_NUMBER_STRATEGY = ToNumberPolicy.DOUBLE;
public static final ToNumberStrategy DEFAULT_NUMBER_TO_NUMBER_STRATEGY = ToNumberPolicy.LAZILY_PARSED_NUMBER;
public static final TypeToken<?> NULL_KEY_SURROGATE = TypeToken.get(Object.class);
public static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
}

View File

@ -65,6 +65,13 @@ public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
in.nextNull();
return null;
}
Object array;
if (in.isLenient() && in.peek() != JsonToken.BEGIN_ARRAY) {
// Coerce
array = Array.newInstance(componentType, 1);
Array.set(array, 0, componentTypeAdapter.read(in));
return array;
}
List<E> list = new ArrayList<>();
in.beginArray();
@ -75,7 +82,7 @@ public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
in.endArray();
int size = list.size();
Object array = Array.newInstance(componentType, size);
array = Array.newInstance(componentType, size);
for (int i = 0; i < size; i++) {
Array.set(array, i, list.get(i));
}

View File

@ -77,12 +77,17 @@ public final class CollectionTypeAdapterFactory implements TypeAdapterFactory {
}
Collection<E> collection = constructor.construct();
in.beginArray();
while (in.hasNext()) {
E instance = elementTypeAdapter.read(in);
collection.add(instance);
if (!in.isLenient() || in.peek() == JsonToken.BEGIN_ARRAY) {
in.beginArray();
while (in.hasNext()) {
E instance = elementTypeAdapter.read(in);
collection.add(instance);
}
in.endArray();
} else {
// Coerce
collection.add(elementTypeAdapter.read(in));
}
in.endArray();
return collection;
}

View File

@ -16,7 +16,7 @@
package com.google.gson.stream;
import com.google.gson.internal.JsonReaderInternalAccess;
import com.google.gson.internal.*;
import com.google.gson.internal.bind.JsonTreeReader;
import java.io.Closeable;
import java.io.EOFException;
@ -226,7 +226,7 @@ public class JsonReader implements Closeable {
private final Reader in;
/** True to accept non-spec compliant JSON */
private boolean lenient = false;
private boolean lenient = DefaultConfig.DEFAULT_LENIENT;
static final int BUFFER_SIZE = 1024;
/**
@ -315,8 +315,7 @@ public class JsonReader implements Closeable {
* <li>Names that are unquoted or {@code 'single quoted'}.
* <li>Strings that are unquoted or {@code 'single quoted'}.
* <li>Array elements separated by {@code ;} instead of {@code ,}.
* <li>Unnecessary array separators. These are interpreted as if null
* was the omitted value.
* <li>Unnecessary array separators. These are ignored.
* <li>Names and values separated by {@code =} or {@code =>} instead of
* {@code :}.
* <li>Name/value pairs separated by {@code ;} instead of {@code ,}.
@ -473,7 +472,7 @@ public class JsonReader implements Closeable {
case ',':
break;
default:
throw syntaxError("Unterminated array");
throw syntaxError("Unterminated array at " + (char)c);
}
} else if (peekStack == JsonScope.EMPTY_OBJECT || peekStack == JsonScope.NONEMPTY_OBJECT) {
stack[stackSize - 1] = JsonScope.DANGLING_NAME;
@ -488,7 +487,7 @@ public class JsonReader implements Closeable {
case ',':
break;
default:
throw syntaxError("Unterminated object");
throw syntaxError("Unterminated object at " + (char)c);
}
}
int c = nextNonWhitespace(true);
@ -546,35 +545,8 @@ public class JsonReader implements Closeable {
throw new IllegalStateException("JsonReader is closed");
}
int c = nextNonWhitespace(true);
switch (c) {
case ']':
if (peekStack == JsonScope.EMPTY_ARRAY) {
return peeked = PEEKED_END_ARRAY;
}
// fall-through to handle ",]"
case ';':
case ',':
// In lenient mode, a 0-length literal in an array means 'null'.
if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) {
checkLenient();
pos--;
return peeked = PEEKED_NULL;
} else {
throw syntaxError("Unexpected value");
}
case '\'':
checkLenient();
return peeked = PEEKED_SINGLE_QUOTED;
case '"':
return peeked = PEEKED_DOUBLE_QUOTED;
case '[':
return peeked = PEEKED_BEGIN_ARRAY;
case '{':
return peeked = PEEKED_BEGIN_OBJECT;
default:
pos--; // Don't consume the first character in a literal value.
}
if (checkNextNonWhitespace(peekStack))
return peeked;
int result = peekKeyword();
if (result != PEEKED_NONE) {
@ -594,6 +566,45 @@ public class JsonReader implements Closeable {
return peeked = PEEKED_UNQUOTED;
}
private boolean checkNextNonWhitespace(int peekStack) throws IOException {
int c = nextNonWhitespace(true);
switch (c) {
case ']':
if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) {
peeked = PEEKED_END_ARRAY;
return true;
}
throw syntaxError("Unexpected value");
case ';':
case ',':
// In lenient mode, a 0-length literal in an array should be skipped.
if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) {
checkLenient();
//pos--;
//peeked = PEEKED_NULL;
return checkNextNonWhitespace(peekStack);
} else {
throw syntaxError("Unexpected value");
}
case '\'':
checkLenient();
peeked = PEEKED_SINGLE_QUOTED;
return true;
case '"':
peeked = PEEKED_DOUBLE_QUOTED;
return true;
case '[':
peeked = PEEKED_BEGIN_ARRAY;
return true;
case '{':
peeked = PEEKED_BEGIN_OBJECT;
return true;
default:
pos--; // Don't consume the first character in a literal value.
}
return false;
}
private int peekKeyword() throws IOException {
// Figure out which keyword we're matching against by its first character.
char c = buffer[pos];
@ -1198,10 +1209,14 @@ public class JsonReader implements Closeable {
}
peeked = PEEKED_BUFFERED;
double asDouble = Double.parseDouble(peekedString); // don't catch this NumberFormatException.
result = (int) asDouble;
if (result != asDouble) { // Make sure no precision was lost casting to 'int'.
throw new NumberFormatException("Expected an int but was " + peekedString + locationString());
if (peekedString.startsWith("0x")) {
result = Integer.decode(peekedString);
} else {
double asDouble = Double.parseDouble(peekedString); // don't catch this NumberFormatException.
result = (int) asDouble;
if (result != asDouble) { // Make sure no precision was lost casting to 'int'.
throw new NumberFormatException("Expected an int but was " + peekedString + locationString());
}
}
peekedString = null;
peeked = PEEKED_NONE;
@ -1254,7 +1269,8 @@ public class JsonReader implements Closeable {
pos += peekedNumberLength;
}
peeked = PEEKED_NONE;
} while (count != 0);
} while (count > 0);
if (count < 0) throw new IllegalStateException("Attempt to skip led outside its parent");
pathIndices[stackSize - 1]++;
pathNames[stackSize - 1] = "null";
@ -1452,7 +1468,8 @@ public class JsonReader implements Closeable {
String locationString() {
int line = lineNumber + 1;
int column = pos - lineStart + 1;
return " at line " + line + " column " + column + " path " + getPath();
String charInterjection = pos < buffer.length ? " (char '" + buffer[pos] + "')" : "";
return " at line " + line + " column " + column + charInterjection + " path " + getPath();
}
private String getPath(boolean usePreviousPath) {

View File

@ -16,6 +16,8 @@
package com.google.gson.stream;
import com.google.gson.internal.*;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
@ -190,7 +192,9 @@ public class JsonWriter implements Closeable, Flushable {
*/
private String separator = ":";
private boolean lenient;
private boolean lenient = DefaultConfig.DEFAULT_LENIENT;
private boolean omitQuotes = DefaultConfig.DEFAULT_OMIT_QUOTES;
private boolean htmlSafe;
@ -286,11 +290,25 @@ public class JsonWriter implements Closeable, Flushable {
return serializeNulls;
}
/**
* Sets whether serialized entry names may omit quotes (like in json5)
* The default is false
*/
public final void setOmitQuotes(boolean omitQuotes) {
this.omitQuotes = omitQuotes;
}
public final boolean getOmitQuotes() {
return omitQuotes;
}
/**
* Insert a comment at the current location.
* May create a new line.
* This writer MUST be lenient to use this
*/
public JsonWriter comment(String comment) throws IOException {
if (!lenient) throw new MalformedJsonException("Cannot write comment in non-lenient JsonWriter.");
if (comment == null || comment.isBlank()) return this;
String[] parts = comment.split("\n");
if (indent == null) {
@ -424,7 +442,12 @@ public class JsonWriter implements Closeable, Flushable {
private void writeDeferredName() throws IOException {
if (deferredName != null) {
beforeName();
string(deferredName);
if (omitQuotes && deferredName.matches("[a-zA-Z_$][\\w$]*")) {
out.write(deferredName);
}
else {
string(deferredName);
}
deferredName = null;
}
}

View File

@ -54,7 +54,7 @@ public final class GsonTest extends TestCase {
public void testOverridesDefaultExcluder() {
Gson gson = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
new HashMap<Type, InstanceCreator<?>>(), true, false, false, true, false,
true, true, false, true, LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
true, true, false, 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,
@ -69,7 +69,7 @@ public final class GsonTest extends TestCase {
public void testClonedTypeAdapterFactoryListsAreIndependent() {
Gson original = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
new HashMap<Type, InstanceCreator<?>>(), true, false, false, true, false,
true, true, false, true, LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
true, true, false, 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,
@ -91,7 +91,7 @@ public final class GsonTest extends TestCase {
public void testNewJsonWriter_Default() throws IOException {
StringWriter writer = new StringWriter();
JsonWriter jsonWriter = new Gson().newJsonWriter(writer);
JsonWriter jsonWriter = new GsonBuilder().create().newJsonWriter(writer);
jsonWriter.beginObject();
jsonWriter.name("test");
jsonWriter.nullValue();
@ -137,7 +137,7 @@ public final class GsonTest extends TestCase {
public void testNewJsonReader_Default() throws IOException {
String json = "test"; // String without quotes
JsonReader jsonReader = new Gson().newJsonReader(new StringReader(json));
JsonReader jsonReader = new GsonBuilder().create().newJsonReader(new StringReader(json));
try {
jsonReader.nextString();
fail();

View File

@ -203,7 +203,7 @@ public final class MixedStreamTest extends TestCase {
StringWriter writer = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(writer);
new GsonBuilder().serializeSpecialFloatingPointValues().create()
new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create()
.toJson(doubles, type, jsonWriter);
assertEquals("[NaN,-Infinity,Infinity,-0.0,0.5,0.0]", writer.toString());

View File

@ -33,7 +33,7 @@ public class ToNumberPolicyTest extends TestCase {
strategy.readNumber(fromString("1e400"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("JSON forbids NaN and infinities: Infinity at line 1 column 6 path $", expected.getMessage());
assertEquals("JSON forbids NaN and infinities: Infinity at line 1 column 6 (char '\0') path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("\"not-a-number\""));
@ -74,19 +74,19 @@ public class ToNumberPolicyTest extends TestCase {
strategy.readNumber(fromString("NaN"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 (char 'N') path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("Infinity"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 (char 'I') path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("-Infinity"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 (char '-') path $", expected.getMessage());
}
}

View File

@ -186,7 +186,7 @@ public class ArrayTest extends TestCase {
}
public void testArrayOfPrimitivesAsObjectsDeserialization() throws Exception {
String json = "[1,'abc',0.3,1.1,5]";
String json = "[1,\"abc\",0.3,1.1,5]";
Object[] objs = gson.fromJson(json, Object[].class);
assertEquals(1, ((Number)objs[0]).intValue());
assertEquals("abc", objs[1]);
@ -249,8 +249,8 @@ public class ArrayTest extends TestCase {
* Regression tests for Issue 272
*/
public void testMultidimenstionalArraysDeserialization() {
String json = "[['3m Co','71.72','0.02','0.03','4/2 12:00am','Manufacturing'],"
+ "['Alcoa Inc','29.01','0.42','1.47','4/1 12:00am','Manufacturing']]";
String json = "[[\"3m Co\",\"71.72\",\"0.02\",\"0.03\",\"4/2 12:00am\",\"Manufacturing\"],"
+ "[\"Alcoa Inc\",\"29.01\",\"0.42\",\"1.47\",\"4/1 12:00am\",\"Manufacturing\"]]";
String[][] items = gson.fromJson(json, String[][].class);
assertEquals("3m Co", items[0][0]);
assertEquals("Manufacturing", items[1][5]);

View File

@ -101,7 +101,7 @@ public class CollectionTest extends TestCase {
}
public void testLinkedListDeserialization() {
String json = "['a1','a2']";
String json = "[\"a1\",\"a2\"]";
Type linkedListType = new TypeToken<LinkedList<String>>() {}.getType();
List<String> list = gson.fromJson(json, linkedListType);
assertEquals("a1", list.get(0));
@ -119,7 +119,7 @@ public class CollectionTest extends TestCase {
}
public void testQueueDeserialization() {
String json = "['a1','a2']";
String json = "[\"a1\",\"a2\"]";
Type queueType = new TypeToken<Queue<String>>() {}.getType();
Queue<String> queue = gson.fromJson(json, queueType);
assertEquals("a1", queue.element());
@ -385,7 +385,7 @@ public class CollectionTest extends TestCase {
assertTrue(json.contains("2"));
}
public void testSetDeserialization() {
String json = "[{value:1},{value:2}]";
String json = "[{\"value\":1},{\"value\":2}]";
Type type = new TypeToken<Set<Entry>>() {}.getType();
Set<Entry> set = gson.fromJson(json, type);
assertEquals(2, set.size());

View File

@ -56,7 +56,7 @@ public class ConcurrencyTest extends TestCase {
*/
public void testSingleThreadDeserialization() {
for (int i = 0; i < 10; i++) {
gson.fromJson("{'a':'hello','b':'world','i':1}", MyObject.class);
gson.fromJson("{\"a\":\"hello\",\"b\":\"world\",\"i\":1}", MyObject.class);
}
}
@ -106,7 +106,7 @@ public class ConcurrencyTest extends TestCase {
try {
startLatch.await();
for (int i = 0; i < 10; i++) {
gson.fromJson("{'a':'hello','b':'world','i':1}", MyObject.class);
gson.fromJson("{\"a\":\"hello\",\"b\":\"world\",\"i\":1}", MyObject.class);
}
} catch (Throwable t) {
failed.set(true);

View File

@ -112,12 +112,11 @@ public class CustomDeserializerTest extends TestCase {
public void testJsonTypeFieldBasedDeserialization() {
String json = "{field1:'abc',field2:'def',__type__:'SUB_TYPE1'}";
Gson gson = new GsonBuilder().registerTypeAdapter(MyBase.class, new JsonDeserializer<MyBase>() {
@Override public MyBase deserialize(JsonElement json, Type pojoType,
JsonDeserializationContext context) throws JsonParseException {
String type = json.getAsJsonObject().get(MyBase.TYPE_ACCESS).getAsString();
return context.deserialize(json, SubTypes.valueOf(type).getSubclass());
}
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(MyBase.class, (JsonDeserializer<MyBase>) (json1, pojoType, context) -> {
String type = json1.getAsJsonObject().get(MyBase.TYPE_ACCESS).getAsString();
return context.deserialize(json1, SubTypes.valueOf(type).getSubclass());
}).create();
SubType1 target = (SubType1) gson.fromJson(json, MyBase.class);
assertEquals("abc", target.field1);
@ -150,13 +149,8 @@ public class CustomDeserializerTest extends TestCase {
public void testCustomDeserializerReturnsNullForTopLevelObject() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
@Override
public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return null;
}
}).create();
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "{baseName:'Base',subName:'SubRevised'}";
Base target = gson.fromJson(json, Base.class);
assertNull(target);
@ -164,13 +158,8 @@ public class CustomDeserializerTest extends TestCase {
public void testCustomDeserializerReturnsNull() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
@Override
public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return null;
}
}).create();
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "{base:{baseName:'Base',subName:'SubRevised'}}";
ClassWithBaseField target = gson.fromJson(json, ClassWithBaseField.class);
assertNull(target.base);
@ -178,13 +167,8 @@ public class CustomDeserializerTest extends TestCase {
public void testCustomDeserializerReturnsNullForArrayElements() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
@Override
public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return null;
}
}).create();
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "[{baseName:'Base'},{baseName:'Base'}]";
Base[] target = gson.fromJson(json, Base[].class);
assertNull(target[0]);
@ -193,13 +177,8 @@ public class CustomDeserializerTest extends TestCase {
public void testCustomDeserializerReturnsNullForArrayElementsForArrayField() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
@Override
public Base deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return null;
}
}).create();
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "{bases:[{baseName:'Base'},{baseName:'Base'}]}";
ClassWithBaseArray target = gson.fromJson(json, ClassWithBaseArray.class);
assertNull(target.bases[0]);

View File

@ -264,7 +264,7 @@ public class CustomTypeAdaptersTest extends TestCase {
}
});
Gson gson = gsonBuilder.create();
String json = "'0123456789'";
String json = "\"0123456789\"";
byte[] actual = gson.fromJson(json, byte[].class);
byte[] expected = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = 0; i < actual.length; ++i) {
@ -338,7 +338,7 @@ public class CustomTypeAdaptersTest extends TestCase {
.registerTypeAdapter(StringHolder.class, new StringHolderTypeAdapter())
.create();
Type setType = new TypeToken<Set<StringHolder>>() {}.getType();
Set<StringHolder> setOfHolders = gson.fromJson("['Jacob:Tomaw']", setType);
Set<StringHolder> setOfHolders = gson.fromJson("[\"Jacob:Tomaw\"]", setType);
assertEquals(1, setOfHolders.size());
StringHolder foo = setOfHolders.iterator().next();
assertEquals("Jacob", foo.part1);
@ -376,7 +376,7 @@ public class CustomTypeAdaptersTest extends TestCase {
.registerTypeAdapter(StringHolder.class, new StringHolderTypeAdapter())
.create();
Type mapType = new TypeToken<Map<String, StringHolder>>() {}.getType();
Map<String, StringHolder> mapOfFoo = gson.fromJson("{'foo':'Jacob:Tomaw'}", mapType);
Map<String, StringHolder> mapOfFoo = gson.fromJson("{\"foo\":\"Jacob:Tomaw\"}", mapType);
assertEquals(1, mapOfFoo.size());
StringHolder foo = mapOfFoo.get("foo");
assertEquals("Jacob", foo.part1);
@ -394,8 +394,9 @@ public class CustomTypeAdaptersTest extends TestCase {
public void testEnsureCustomDeserializerNotInvokedForNullValues() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(DataHolder.class, new DataHolderDeserializer())
.create();
.setLenient()
.registerTypeAdapter(DataHolder.class, new DataHolderDeserializer())
.create();
String json = "{wrappedData:null}";
DataHolderWrapper actual = gson.fromJson(json, DataHolderWrapper.class);
assertNull(actual.wrappedData);
@ -404,8 +405,8 @@ public class CustomTypeAdaptersTest extends TestCase {
// Test created from Issue 352
public void testRegisterHierarchyAdapterForDate() {
Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(Date.class, new DateTypeAdapter())
.create();
.registerTypeHierarchyAdapter(Date.class, new DateTypeAdapter())
.create();
assertEquals("0", gson.toJson(new Date(0)));
assertEquals("0", gson.toJson(new java.sql.Date(0)));
assertEquals(new Date(0), gson.fromJson("0", Date.class));

View File

@ -104,7 +104,7 @@ public class DefaultTypeAdaptersTest extends TestCase {
} catch (UnsupportedOperationException expected) {
}
// Override with a custom type adapter for class.
gson = new GsonBuilder().registerTypeAdapter(Class.class, new MyClassTypeAdapter()).create();
gson = new GsonBuilder().setLenient().registerTypeAdapter(Class.class, new MyClassTypeAdapter()).create();
assertEquals(String.class, gson.fromJson("java.lang.String", Class.class));
}
@ -410,7 +410,7 @@ public class DefaultTypeAdaptersTest extends TestCase {
}
public void testDefaultCalendarDeserialization() throws Exception {
Gson gson = new GsonBuilder().create();
Gson gson = new Gson();
String json = "{year:2009,month:2,dayOfMonth:11,hourOfDay:14,minute:29,second:23}";
Calendar cal = gson.fromJson(json, Calendar.class);
assertEquals(2009, cal.get(Calendar.YEAR));
@ -434,7 +434,7 @@ public class DefaultTypeAdaptersTest extends TestCase {
}
public void testDefaultGregorianCalendarDeserialization() throws Exception {
Gson gson = new GsonBuilder().create();
Gson gson = new Gson();
String json = "{year:2009,month:2,dayOfMonth:11,hourOfDay:14,minute:29,second:23}";
GregorianCalendar cal = gson.fromJson(json, GregorianCalendar.class);
assertEquals(2009, cal.get(Calendar.YEAR));

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2008 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 com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import junit.framework.TestCase;
/**
* Functional tests for enums with Proguard.
*
* @author Young Cha
*/
public class EnumWithObfuscatedTest extends TestCase {
private Gson gson;
@Override
protected void setUp() throws Exception {
super.setUp();
gson = new Gson();
}
public enum Gender {
@SerializedName("MAIL")
MALE,
@SerializedName("FEMAIL")
FEMALE
}
public void testEnumClassWithObfuscated() {
for (Gender enumConstant: Gender.class.getEnumConstants()) {
try {
Gender.class.getField(enumConstant.name());
fail("Enum is not obfuscated");
} catch (NoSuchFieldException ignore) {
}
}
assertEquals(Gender.MALE, gson.fromJson("\"MAIL\"", Gender.class));
assertEquals("\"MAIL\"", gson.toJson(Gender.MALE, Gender.class));
}
}

View File

@ -38,6 +38,7 @@ public class ExposeFieldsTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
gson = new GsonBuilder()
.setLenient()
.excludeFieldsWithoutExposeAnnotation()
.registerTypeAdapter(SomeInterface.class, new SomeInterfaceInstanceCreator())
.create();

View File

@ -42,12 +42,9 @@ public class InstanceCreatorTest extends TestCase {
public void testInstanceCreatorReturnsBaseType() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new InstanceCreator<Base>() {
@Override public Base createInstance(Type type) {
return new Base();
}
})
.create();
.setLenient()
.registerTypeAdapter(Base.class, (InstanceCreator<Base>) type -> new Base())
.create();
String json = "{baseName:'BaseRevised',subName:'Sub'}";
Base base = gson.fromJson(json, Base.class);
assertEquals("BaseRevised", base.baseName);
@ -55,12 +52,9 @@ public class InstanceCreatorTest extends TestCase {
public void testInstanceCreatorReturnsSubTypeForTopLevelObject() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new InstanceCreator<Base>() {
@Override public Base createInstance(Type type) {
return new Sub();
}
})
.create();
.setLenient()
.registerTypeAdapter(Base.class, (InstanceCreator<Base>) type -> new Sub())
.create();
String json = "{baseName:'Base',subName:'SubRevised'}";
Base base = gson.fromJson(json, Base.class);
@ -73,12 +67,9 @@ public class InstanceCreatorTest extends TestCase {
public void testInstanceCreatorReturnsSubTypeForField() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new InstanceCreator<Base>() {
@Override public Base createInstance(Type type) {
return new Sub();
}
})
.create();
.setLenient()
.registerTypeAdapter(Base.class, (InstanceCreator<Base>) type -> new Sub())
.create();
String json = "{base:{baseName:'Base',subName:'SubRevised'}}";
ClassWithBaseField target = gson.fromJson(json, ClassWithBaseField.class);
assertTrue(target.base instanceof Sub);

View File

@ -65,7 +65,7 @@ public class InternationalizationTest extends TestCase {
}
public void testStringsWithUnicodeChineseCharactersEscapedDeserialization() throws Exception {
String actual = gson.fromJson("'\\u597d\\u597d\\u597d'", String.class);
String actual = gson.fromJson("\"\\u597d\\u597d\\u597d\"", String.class);
assertEquals("\u597d\u597d\u597d", actual);
}
}

View File

@ -65,7 +65,7 @@ public class JavaUtilConcurrentAtomicTest extends TestCase {
Gson gson = new GsonBuilder()
.setLongSerializationPolicy(LongSerializationPolicy.STRING)
.create();
AtomicLongHolder target = gson.fromJson("{'value':'10'}", AtomicLongHolder.class);
AtomicLongHolder target = gson.fromJson("{\"value\":\"10\"}", AtomicLongHolder.class);
assertEquals(10, target.value.get());
String json = gson.toJson(target);
assertEquals("{\"value\":\"10\"}", json);
@ -95,7 +95,7 @@ public class JavaUtilConcurrentAtomicTest extends TestCase {
Gson gson = new GsonBuilder()
.setLongSerializationPolicy(LongSerializationPolicy.STRING)
.create();
AtomicLongArray target = gson.fromJson("['10', '13', '14']", AtomicLongArray.class);
AtomicLongArray target = gson.fromJson("[\"10\", \"13\", \"14\"]", AtomicLongArray.class);
assertEquals(3, target.length());
assertEquals(10, target.get(0));
assertEquals(13, target.get(1));

View File

@ -36,7 +36,7 @@ public class JavaUtilTest extends TestCase {
}
public void testCurrency() throws Exception {
CurrencyHolder target = gson.fromJson("{'value':'USD'}", CurrencyHolder.class);
CurrencyHolder target = gson.fromJson("{\"value\":\"USD\"}", CurrencyHolder.class);
assertEquals("USD", target.value.getCurrencyCode());
String json = gson.toJson(target);
assertEquals("{\"value\":\"USD\"}", json);
@ -52,7 +52,7 @@ public class JavaUtilTest extends TestCase {
}
public void testProperties() {
Properties props = gson.fromJson("{'a':'v1','b':'v2'}", Properties.class);
Properties props = gson.fromJson("{\"a\":\"v1\",\"b\":\"v2\"}", Properties.class);
assertEquals("v1", props.getProperty("a"));
assertEquals("v2", props.getProperty("b"));
String json = gson.toJson(props);

View File

@ -49,7 +49,7 @@ public final class JsonAdapterAnnotationOnClassesTest extends TestCase {
// Also invoke the JsonAdapter javadoc sample
json = gson.toJson(new User("Inderjeet", "Singh"));
assertEquals("{\"name\":\"Inderjeet Singh\"}", json);
User user = gson.fromJson("{'name':'Joel Leitch'}", User.class);
User user = gson.fromJson("{\"name\":\"Joel Leitch\"}", User.class);
assertEquals("Joel", user.firstName);
assertEquals("Leitch", user.lastName);
@ -94,6 +94,7 @@ public final class JsonAdapterAnnotationOnClassesTest extends TestCase {
}
};
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(A.class, serializer)
.create();
String json = gson.toJson(new A("abcd"));
@ -113,6 +114,7 @@ public final class JsonAdapterAnnotationOnClassesTest extends TestCase {
}
};
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(A.class, deserializer)
.create();
String json = gson.toJson(new A("abcd"));

View File

@ -57,12 +57,13 @@ public final class JsonAdapterAnnotationOnFieldsTest extends TestCase {
.create();
String json = gson.toJson(new Computer(new User("Inderjeet Singh")));
assertEquals("{\"user\":\"RegisteredUserAdapter\"}", json);
Computer computer = gson.fromJson("{'user':'Inderjeet Singh'}", Computer.class);
Computer computer = gson.fromJson("{\"user\":\"Inderjeet Singh\"}", Computer.class);
assertEquals("RegisteredUserAdapter", computer.user.name);
}
public void testFieldAnnotationTakesPrecedenceOverRegisteredTypeAdapter() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Part.class, new TypeAdapter<Part>() {
@Override public void write(JsonWriter out, Part part) throws IOException {
throw new AssertionError();

View File

@ -16,13 +16,7 @@
package com.google.gson.functional;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.*;
import com.google.gson.common.TestTypes.BagOfPrimitives;
import com.google.gson.common.TestTypes.Nested;
import com.google.gson.reflect.TypeToken;
@ -123,9 +117,9 @@ public class JsonParserTest extends TestCase {
public void testExtraCommasInArrays() {
Type type = new TypeToken<List<String>>() {}.getType();
assertEquals(Arrays.asList("a", null, "b", null, null), gson.fromJson("[a,,b,,]", type));
assertEquals(Arrays.asList(null, null), gson.fromJson("[,]", type));
assertEquals(Arrays.asList("a", null), gson.fromJson("[a,]", type));
assertEquals(Arrays.asList("a", "b"), gson.fromJson("[a,,b,,]", type));
assertEquals(Arrays.asList(), gson.fromJson("[,]", type));
assertEquals(Arrays.asList("a"), gson.fromJson("[a,]", type));
}
public void testExtraCommasInMaps() {

View File

@ -33,7 +33,7 @@ public class LeniencyTest extends TestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
gson = new GsonBuilder().setLenient().create();
gson = new Gson();
}
public void testLenientFromJson() {

View File

@ -106,7 +106,7 @@ public class MapAsArrayTypeAdapterTest extends TestCase {
}
public void testMapWithTypeVariableDeserialization() {
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
Gson gson = new GsonBuilder().setLenient().enableComplexMapKeySerialization().create();
String json = "{map:[[{x:2,y:3},{x:4,y:5}]]}";
Type type = new TypeToken<PointWithProperty<Point>>(){}.getType();
PointWithProperty<Point> map = gson.fromJson(json, type);

View File

@ -155,7 +155,7 @@ public class MapTest extends TestCase {
assertEquals(123, map.get("null").intValue());
assertNull(map.get(null));
map = gson.fromJson("{null:123}", typeOfMap);
map = gson.fromJson("{'null':123}", typeOfMap);
assertEquals(1, map.size());
assertEquals(123, map.get("null").intValue());
assertNull(map.get(null));

View File

@ -99,7 +99,7 @@ public class NullObjectAndFieldTest extends TestCase {
*/
public void testNullWrappedPrimitiveMemberDeserialization() {
Gson gson = gsonBuilder.create();
String json = "{'value':null}";
String json = "{\"value\":null}";
ClassWithNullWrappedPrimitive target = gson.fromJson(json, ClassWithNullWrappedPrimitive.class);
assertNull(target.value);
}
@ -223,12 +223,8 @@ public class NullObjectAndFieldTest extends TestCase {
public void testCustomTypeAdapterPassesNullDesrialization() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(ObjectWithField.class, new JsonDeserializer<ObjectWithField>() {
@Override public ObjectWithField deserialize(JsonElement json, Type type,
JsonDeserializationContext context) {
return context.deserialize(null, type);
}
}).create();
.setLenient()
.registerTypeAdapter(ObjectWithField.class, (JsonDeserializer<ObjectWithField>) (json, type, context) -> context.deserialize(null, type)).create();
String json = "{value:'value1'}";
ObjectWithField target = gson.fromJson(json, ObjectWithField.class);
assertNull(target);

View File

@ -346,7 +346,7 @@ public class ObjectTest extends TestCase {
return p.new Child();
}
}).create();
String json = "{'value2':3}";
String json = "{\"value2\":3}";
Parent.Child c = gson.fromJson(json, Parent.Child.class);
assertEquals(3, c.value2);
}

View File

@ -16,10 +16,9 @@
package com.google.gson.functional;
import com.google.gson.*;
import junit.framework.TestCase;
import com.google.gson.Gson;
/**
* Functional tests for Java Character values.
*

View File

@ -18,11 +18,7 @@ package com.google.gson.functional;
import static org.junit.Assert.assertArrayEquals;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.LongSerializationPolicy;
import com.google.gson.*;
import com.google.gson.internal.LazilyParsedNumber;
import com.google.gson.reflect.TypeToken;
import java.io.Serializable;
@ -95,7 +91,7 @@ public class PrimitiveTest extends TestCase {
gson.fromJson("2147483648", byte.class);
fail();
} catch (JsonSyntaxException e) {
assertEquals("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 path $", e.getMessage());
assertEquals("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 (char '\0') path $", e.getMessage());
}
}
@ -133,7 +129,7 @@ public class PrimitiveTest extends TestCase {
gson.fromJson("2147483648", short.class);
fail();
} catch (JsonSyntaxException e) {
assertEquals("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 path $", e.getMessage());
assertEquals("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 (char '\0') path $", e.getMessage());
}
}
@ -435,7 +431,7 @@ public class PrimitiveTest extends TestCase {
}
public void testDoubleNaNSerialization() {
Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();
Gson gson = new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create();
double nan = Double.NaN;
assertEquals("NaN", gson.toJson(nan));
assertEquals("NaN", gson.toJson(Double.NaN));
@ -461,7 +457,7 @@ public class PrimitiveTest extends TestCase {
}
public void testFloatNaNSerialization() {
Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();
Gson gson = new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create();
float nan = Float.NaN;
assertEquals("NaN", gson.toJson(nan));
assertEquals("NaN", gson.toJson(Float.NaN));
@ -495,7 +491,7 @@ public class PrimitiveTest extends TestCase {
}
public void testDoubleInfinitySerialization() {
Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();
Gson gson = new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create();
double infinity = Double.POSITIVE_INFINITY;
assertEquals("Infinity", gson.toJson(infinity));
assertEquals("Infinity", gson.toJson(Double.POSITIVE_INFINITY));
@ -521,7 +517,7 @@ public class PrimitiveTest extends TestCase {
}
public void testFloatInfinitySerialization() {
Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();
Gson gson = new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create();
float infinity = Float.POSITIVE_INFINITY;
assertEquals("Infinity", gson.toJson(infinity));
assertEquals("Infinity", gson.toJson(Float.POSITIVE_INFINITY));
@ -555,7 +551,7 @@ public class PrimitiveTest extends TestCase {
}
public void testNegativeInfinitySerialization() {
Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();
Gson gson = new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create();
double negativeInfinity = Double.NEGATIVE_INFINITY;
assertEquals("-Infinity", gson.toJson(negativeInfinity));
assertEquals("-Infinity", gson.toJson(Double.NEGATIVE_INFINITY));
@ -581,7 +577,7 @@ public class PrimitiveTest extends TestCase {
}
public void testNegativeInfinityFloatSerialization() {
Gson gson = new GsonBuilder().serializeSpecialFloatingPointValues().create();
Gson gson = new GsonBuilder().setLenient().serializeSpecialFloatingPointValues().create();
float negativeInfinity = Float.NEGATIVE_INFINITY;
assertEquals("-Infinity", gson.toJson(negativeInfinity));
assertEquals("-Infinity", gson.toJson(Float.NEGATIVE_INFINITY));
@ -633,9 +629,9 @@ public class PrimitiveTest extends TestCase {
String value = "String Blah Blah Blah...1, 2, 3";
try {
gson.fromJson(value, String.class);
new Gson().fromJson(value, String.class);
fail();
} catch (JsonSyntaxException expected) { }
} catch (JsonIOException expected) { }
}
public void testHtmlCharacterSerialization() throws Exception {

View File

@ -38,7 +38,7 @@ public class SecurityTest extends TestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
gsonBuilder = new GsonBuilder();
gsonBuilder = new GsonBuilder().setLenient();
}
public void testNonExecutableJsonSerialization() {

View File

@ -159,7 +159,7 @@ public final class StreamingTypeAdaptersTest extends TestCase {
out.value(person.name + "," + person.age);
}
};
Gson gson = new GsonBuilder().registerTypeAdapter(
Gson gson = new GsonBuilder().setLenient().registerTypeAdapter(
Person.class, typeAdapter).create();
Truck truck = new Truck();
truck.horsePower = 1.0D;
@ -175,7 +175,7 @@ public final class StreamingTypeAdaptersTest extends TestCase {
gson.fromJson(json, Truck.class);
fail();
} catch (JsonSyntaxException expected) {}
gson = new GsonBuilder().registerTypeAdapter(Person.class, typeAdapter.nullSafe()).create();
gson = new GsonBuilder().setLenient().registerTypeAdapter(Person.class, typeAdapter.nullSafe()).create();
assertEquals("{\"horsePower\":1.0,\"passengers\":[null,\"jesse,30\"]}",
gson.toJson(truck, Truck.class));
truck = gson.fromJson(json, Truck.class);

View File

@ -54,6 +54,7 @@ public class TreeTypeAdaptersTest extends TestCase {
@Override
protected void setUp() {
gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Id.class, new IdTreeTypeAdapter())
.create();
course = new Course<>(COURSE_ID, 4,

View File

@ -34,6 +34,7 @@ import junit.framework.TestCase;
public final class TypeAdapterPrecedenceTest extends TestCase {
public void testNonstreamingFollowedByNonstreaming() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Foo.class, newSerializer("serializer 1"))
.registerTypeAdapter(Foo.class, newSerializer("serializer 2"))
.registerTypeAdapter(Foo.class, newDeserializer("deserializer 1"))
@ -45,6 +46,7 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
public void testStreamingFollowedByStreaming() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Foo.class, newTypeAdapter("type adapter 1"))
.registerTypeAdapter(Foo.class, newTypeAdapter("type adapter 2"))
.create();
@ -54,6 +56,7 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
public void testSerializeNonstreamingTypeAdapterFollowedByStreamingTypeAdapter() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Foo.class, newSerializer("serializer"))
.registerTypeAdapter(Foo.class, newDeserializer("deserializer"))
.registerTypeAdapter(Foo.class, newTypeAdapter("type adapter"))
@ -64,6 +67,7 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
public void testStreamingFollowedByNonstreaming() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Foo.class, newTypeAdapter("type adapter"))
.registerTypeAdapter(Foo.class, newSerializer("serializer"))
.registerTypeAdapter(Foo.class, newDeserializer("deserializer"))
@ -74,6 +78,7 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
public void testStreamingHierarchicalFollowedByNonstreaming() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeHierarchyAdapter(Foo.class, newTypeAdapter("type adapter"))
.registerTypeAdapter(Foo.class, newSerializer("serializer"))
.registerTypeAdapter(Foo.class, newDeserializer("deserializer"))
@ -89,11 +94,12 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
.registerTypeHierarchyAdapter(Foo.class, newDeserializer("deserializer"))
.create();
assertEquals("\"foo via type adapter\"", gson.toJson(new Foo("foo")));
assertEquals("foo via type adapter", gson.fromJson("foo", Foo.class).name);
assertEquals("foo via type adapter", gson.fromJson("\"foo\"", Foo.class).name);
}
public void testStreamingHierarchicalFollowedByNonstreamingHierarchical() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeHierarchyAdapter(Foo.class, newSerializer("serializer"))
.registerTypeHierarchyAdapter(Foo.class, newDeserializer("deserializer"))
.registerTypeHierarchyAdapter(Foo.class, newTypeAdapter("type adapter"))
@ -104,6 +110,7 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
public void testNonstreamingHierarchicalFollowedByNonstreaming() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeHierarchyAdapter(Foo.class, newSerializer("hierarchical"))
.registerTypeHierarchyAdapter(Foo.class, newDeserializer("hierarchical"))
.registerTypeAdapter(Foo.class, newSerializer("non hierarchical"))

View File

@ -52,7 +52,7 @@ public class SqlTypesGsonTest extends TestCase {
}
public void testDefaultSqlDateDeserialization() {
String json = "'Dec 3, 2009'";
String json = "\"Dec 3, 2009\"";
java.sql.Date extracted = gson.fromJson(json, java.sql.Date.class);
DefaultTypeAdaptersTest.assertEqualsDate(extracted, 2009, 11, 3);
}
@ -82,7 +82,7 @@ public class SqlTypesGsonTest extends TestCase {
}
public void testDefaultSqlTimeDeserialization() {
String json = "'1:18:02 PM'";
String json = "\"1:18:02 PM\"";
Time extracted = gson.fromJson(json, Time.class);
DefaultTypeAdaptersTest.assertEqualsTime(extracted, 13, 18, 2);
}
@ -98,7 +98,7 @@ public class SqlTypesGsonTest extends TestCase {
}
public void testDefaultSqlTimestampDeserialization() {
String json = "'Dec 3, 2009 1:18:02 PM'";
String json = "\"Dec 3, 2009 1:18:02 PM\"";
Timestamp extracted = gson.fromJson(json, Timestamp.class);
DefaultTypeAdaptersTest.assertEqualsDate(extracted, 2009, 11, 3);
DefaultTypeAdaptersTest.assertEqualsTime(extracted, 13, 18, 2);

View File

@ -14,8 +14,9 @@
* limitations under the License.
*/
package com.google.gson;
package com.google.gson.jf;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import java.util.Arrays;
import java.util.List;
@ -39,7 +40,7 @@ public final class CommentsTest extends TestCase {
+ " \"c\"\n"
+ "]";
List<String> abc = new Gson().fromJson(json, new TypeToken<List<String>>() {}.getType());
List<String> abc = new GsonBuilder().setLenient().create().fromJson(json, new TypeToken<List<String>>() {}.getType());
assertEquals(Arrays.asList("a", "b", "c"), abc);
}
}

View File

@ -0,0 +1,28 @@
package com.google.gson.jf;
import junit.framework.*;
import java.util.*;
public class ExtraAssert {
public static <T> void assertListEquals(List<T> expecteds, List<T> actuals) {
TestCase.assertNotNull(expecteds);
TestCase.assertNotNull(actuals);
TestCase.assertEquals(expecteds.size(), actuals.size());
for (int i = 0; i < expecteds.size(); i++) {
TestCase.assertEquals(expecteds.get(i), actuals.get(i));
}
}
public static class StringArrayBox {
public String[] collection;
}
public static class StringListBox {
public List<String> collection;
}
public static class IntListBox {
public List<Integer> collection;
}
}

View File

@ -0,0 +1,49 @@
package com.google.gson.jf;
import com.google.gson.*;
import junit.framework.*;
public class Json5Test extends TestCase {
public void testShortExample() {
// Taken from the official example
assertTrue(new Gson().fromJson("{\n" +
" // comments\n" +
" unquoted: 'and you can quote me on that',\n" +
" singleQuotes: 'I can use \"double quotes\" here',\n" +
" lineBreaks: \"Look, Mom! \\\n" +
"No \\\\n's!\",\n" +
" hexadecimal: 0xdecaf,\n" +
" leadingDecimalPoint: .8675309, andTrailing: 8675309.,\n" +
" positiveSign: +1,\n" +
" trailingComma: 'in objects', andIn: ['arrays',],\n" +
" \"backwardsCompatible\": \"with JSON\",\n" +
"}", ExampleModel.class).isDefault());
}
public static class ExampleModel {
public String unquoted;
public String singleQuotes;
public String lineBreaks;
public Integer hexadecimal;
public Double leadingDecimalPoint;
public Double andTrailing;
public Integer positiveSign;
public String trailingComma;
public String[] andIn;
public String backwardsCompatible;
public boolean isDefault() {
return unquoted.equals("and you can quote me on that")
&& singleQuotes.equals("I can use \"double quotes\" here")
&& lineBreaks.equals("Look, Mom!\nNo \\n's!")
&& hexadecimal.equals(0xdecaf)
&& leadingDecimalPoint.equals(.8675309)
&& andTrailing.equals(8675309.)
&& positiveSign.equals(1)
&& trailingComma.equals("in objects")
&& andIn.length == 1 && andIn[0].equals("arrays")
&& backwardsCompatible.equals("with JSON");
}
}
}

View File

@ -0,0 +1,22 @@
package com.google.gson.jf;
import com.google.gson.*;
import junit.framework.TestCase;
import java.util.*;
import static com.google.gson.jf.ExtraAssert.*;
public class LenientCollectionCommaTest extends TestCase {
private Gson lenient;
private static final String json = "{\"collection\": [1, 2,, 3, , , 4, 5,]}";
@Override
protected void setUp() throws Exception {
super.setUp();
lenient = new GsonBuilder().setLenient().create();
}
public void testElementSkipping() {
assertListEquals(List.of(1, 2, 3, 4, 5), lenient.fromJson(json, IntListBox.class).collection);
}
}

View File

@ -0,0 +1,45 @@
package com.google.gson.jf;
import com.google.gson.*;
import junit.framework.TestCase;
import java.util.*;
import static org.junit.Assert.*;
import static com.google.gson.jf.ExtraAssert.*;
public class LenientCollectionTest extends TestCase {
private Gson lenient;
private Gson strict;
private static final String json = "{\"collection\": \"example\"}";
@Override
protected void setUp() throws Exception {
super.setUp();
lenient = new GsonBuilder().setLenient().create();
strict = new GsonBuilder().create();
}
public void testLenientArray() {
assertArrayEquals(new String[] {"example"}, lenient.fromJson(json, StringArrayBox.class).collection);
}
public void testLenientList() {
assertListEquals(List.of("example"), lenient.fromJson(json, StringListBox.class).collection);
}
public void testStrictArray() {
try {
strict.fromJson(json, StringArrayBox.class);
fail("Strict Gson should not deserialize array without brackets");
} catch (JsonParseException expected) {
}
}
public void testStrictList() {
try {
strict.fromJson(json, StringListBox.class);
fail("Strict Gson should not deserialize list without brackets");
} catch (JsonParseException expected) {
}
}
}

View File

@ -0,0 +1,33 @@
package com.google.gson.jf;
import com.google.gson.*;
import junit.framework.*;
import java.util.*;
import static com.google.gson.jf.ExtraAssert.*;
public class OmitQuotesTest extends TestCase {
private Gson lenient;
private Gson strict;
private static final String lenientJson = "{collection:[\"example\"]}";
private static final String strictJson = "{\"collection\":[\"example\"]}";
private StringListBox slb;
@Override
protected void setUp() throws Exception {
super.setUp();
lenient = new GsonBuilder().setOmitQuotes().create();
strict = new GsonBuilder().create();
slb = new StringListBox();
slb.collection = List.of("example");
}
public void testLenient() {
assertEquals(lenientJson, lenient.toJson(slb));
}
public void testStrict() {
assertEquals(strictJson, strict.toJson(slb));
}
}

View File

@ -32,7 +32,7 @@ public class JsonAdapterNullSafeTest extends TestCase {
}
public void testNullSafeBugDeserialize() throws Exception {
Device device = gson.fromJson("{'id':'ec57803e2'}", Device.class);
Device device = gson.fromJson("{\"id\":\"ec57803e2\"}", Device.class);
assertEquals("ec57803e2", device.id);
}

View File

@ -1172,7 +1172,7 @@ public final class JsonReaderTest extends TestCase {
try {
reader.nextNull();
fail();
} catch (IOException expected) {
} catch (IllegalStateException expected) {
}
reader = new JsonReader(reader("[,]"));
@ -1189,14 +1189,14 @@ public final class JsonReaderTest extends TestCase {
reader.setLenient(true);
reader.beginArray();
assertEquals(true, reader.nextBoolean());
reader.nextNull();
//reader.nextNull();
assertEquals(true, reader.nextBoolean());
reader.endArray();
reader = new JsonReader(reader("[,true]"));
reader.setLenient(true);
reader.beginArray();
reader.nextNull();
//reader.nextNull();
assertEquals(true, reader.nextBoolean());
reader.endArray();
@ -1204,14 +1204,14 @@ public final class JsonReaderTest extends TestCase {
reader.setLenient(true);
reader.beginArray();
assertEquals(true, reader.nextBoolean());
reader.nextNull();
//reader.nextNull();
reader.endArray();
reader = new JsonReader(reader("[,]"));
reader.setLenient(true);
reader.beginArray();
reader.nextNull();
reader.nextNull();
//reader.nextNull();
//reader.nextNull();
reader.endArray();
}
@ -1239,7 +1239,7 @@ public final class JsonReaderTest extends TestCase {
try {
reader.skipValue();
fail();
} catch (IOException expected) {
} catch (IllegalStateException expected) {
}
reader = new JsonReader(reader("[,]"));
@ -1379,46 +1379,46 @@ public final class JsonReaderTest extends TestCase {
}
public void testFailWithPosition() throws IOException {
testFailWithPosition("Expected value at line 6 column 5 path $[1]",
testFailWithPosition("Expected value at line 6 column 5 (char '}') path $[1]",
"[\n\n\n\n\n\"a\",}]");
}
public void testFailWithPositionGreaterThanBufferSize() throws IOException {
String spaces = repeat(' ', 8192);
testFailWithPosition("Expected value at line 6 column 5 path $[1]",
testFailWithPosition("Expected value at line 6 column 5 (char '}') path $[1]",
"[\n\n" + spaces + "\n\n\n\"a\",}]");
}
public void testFailWithPositionOverSlashSlashEndOfLineComment() throws IOException {
testFailWithPosition("Expected value at line 5 column 6 path $[1]",
testFailWithPosition("Expected value at line 5 column 6 (char '}') path $[1]",
"\n// foo\n\n//bar\r\n[\"a\",}");
}
public void testFailWithPositionOverHashEndOfLineComment() throws IOException {
testFailWithPosition("Expected value at line 5 column 6 path $[1]",
testFailWithPosition("Expected value at line 5 column 6 (char '}') path $[1]",
"\n# foo\n\n#bar\r\n[\"a\",}");
}
public void testFailWithPositionOverCStyleComment() throws IOException {
testFailWithPosition("Expected value at line 6 column 12 path $[1]",
testFailWithPosition("Expected value at line 6 column 12 (char '}') path $[1]",
"\n\n/* foo\n*\n*\r\nbar */[\"a\",}");
}
public void testFailWithPositionOverQuotedString() throws IOException {
testFailWithPosition("Expected value at line 5 column 3 path $[1]",
testFailWithPosition("Expected value at line 5 column 3 (char '}') path $[1]",
"[\"foo\nbar\r\nbaz\n\",\n }");
}
public void testFailWithPositionOverUnquotedString() throws IOException {
testFailWithPosition("Expected value at line 5 column 2 path $[1]", "[\n\nabcd\n\n,}");
testFailWithPosition("Expected value at line 5 column 2 (char '}') path $[1]", "[\n\nabcd\n\n,}");
}
public void testFailWithEscapedNewlineCharacter() throws IOException {
testFailWithPosition("Expected value at line 5 column 3 path $[1]", "[\n\n\"\\\n\n\",}");
testFailWithPosition("Expected value at line 5 column 3 (char '}') path $[1]", "[\n\n\"\\\n\n\",}");
}
public void testFailWithPositionIsOffsetByBom() throws IOException {
testFailWithPosition("Expected value at line 1 column 6 path $[1]",
testFailWithPosition("Expected value at line 1 column 6 (char '}') path $[1]",
"\ufeff[\"a\",}]");
}
@ -1461,7 +1461,7 @@ public final class JsonReaderTest extends TestCase {
reader.peek();
fail();
} catch (IOException expected) {
assertEquals("Expected value at line 1 column 14 path $[1].a[2]", expected.getMessage());
assertEquals("Expected value at line 1 column 14 (char '}') path $[1].a[2]", expected.getMessage());
}
}
@ -1728,7 +1728,7 @@ public final class JsonReaderTest extends TestCase {
assertDocument("{\"name\"=>\"string\",", BEGIN_OBJECT, NAME, STRING, IOException.class);
assertDocument("{\"name\"=>\"string\",\"name\"", BEGIN_OBJECT, NAME, STRING, NAME);
assertDocument("[}", BEGIN_ARRAY, IOException.class);
assertDocument("[,]", BEGIN_ARRAY, NULL, NULL, END_ARRAY);
assertDocument("[,]", BEGIN_ARRAY, END_ARRAY);
assertDocument("{", BEGIN_OBJECT, IOException.class);
assertDocument("{\"name\"", BEGIN_OBJECT, NAME, IOException.class);
assertDocument("{\"name\",", BEGIN_OBJECT, NAME, IOException.class);