mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 07:59:21 +08:00
Merge pull request #226 from square/jwilson.0121.more_object_reader
Fix some bugs and increase tests for ObjectJsonReader.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
package com.squareup.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -86,16 +87,14 @@ final class ObjectJsonReader extends JsonReader {
|
||||
|
||||
// If the iterator isn't empty push its first value onto the stack.
|
||||
if (iterator.hasNext()) {
|
||||
stack[stackSize] = iterator.next();
|
||||
stackSize++;
|
||||
push(iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void endArray() throws IOException {
|
||||
ListIterator<?> peeked = require(ListIterator.class, Token.END_ARRAY);
|
||||
if (peeked.hasNext()) {
|
||||
throw new JsonDataException(
|
||||
"Expected " + Token.END_ARRAY + " but was " + peek() + " at path " + getPath());
|
||||
throw typeMismatch(peeked, Token.END_ARRAY);
|
||||
}
|
||||
remove();
|
||||
}
|
||||
@@ -109,16 +108,14 @@ final class ObjectJsonReader extends JsonReader {
|
||||
|
||||
// If the iterator isn't empty push its first value onto the stack.
|
||||
if (iterator.hasNext()) {
|
||||
stack[stackSize] = iterator.next();
|
||||
stackSize++;
|
||||
push(iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void endObject() throws IOException {
|
||||
Iterator<?> peeked = require(Iterator.class, Token.END_OBJECT);
|
||||
if (peeked instanceof ListIterator || peeked.hasNext()) {
|
||||
throw new JsonDataException(
|
||||
"Expected " + Token.END_OBJECT + " but was " + peek() + " at path " + getPath());
|
||||
throw typeMismatch(peeked, Token.END_OBJECT);
|
||||
}
|
||||
pathNames[stackSize - 1] = null;
|
||||
remove();
|
||||
@@ -148,22 +145,31 @@ final class ObjectJsonReader extends JsonReader {
|
||||
if (peeked == null) return Token.NULL;
|
||||
if (peeked == JSON_READER_CLOSED) throw new IllegalStateException("JsonReader is closed");
|
||||
|
||||
throw new JsonDataException("Expected a JSON value but was a " + peeked.getClass().getName()
|
||||
+ " at path " + getPath());
|
||||
throw typeMismatch(peeked, "a JSON value");
|
||||
}
|
||||
|
||||
@Override public String nextName() throws IOException {
|
||||
Object peeked = require(Map.Entry.class, Token.NAME);
|
||||
Map.Entry<?, ?> peeked = require(Map.Entry.class, Token.NAME);
|
||||
|
||||
// Swap the Map.Entry for its value on the stack and return its key.
|
||||
String result = (String) ((Map.Entry<?, ?>) peeked).getKey();
|
||||
stack[stackSize - 1] = ((Map.Entry<?, ?>) peeked).getValue();
|
||||
String result = stringKey(peeked);
|
||||
stack[stackSize - 1] = peeked.getValue();
|
||||
pathNames[stackSize - 2] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override int selectName(Options options) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
Map.Entry<?, ?> peeked = require(Map.Entry.class, Token.NAME);
|
||||
String name = stringKey(peeked);
|
||||
for (int i = 0, length = options.strings.length; i < length; i++) {
|
||||
// Swap the Map.Entry for its value on the stack and return its key.
|
||||
if (options.strings[i].equals(name)) {
|
||||
stack[stackSize - 1] = peeked.getValue();
|
||||
pathNames[stackSize - 2] = name;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override public String nextString() throws IOException {
|
||||
@@ -173,7 +179,14 @@ final class ObjectJsonReader extends JsonReader {
|
||||
}
|
||||
|
||||
@Override int selectString(Options options) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
String peeked = require(String.class, Token.STRING);
|
||||
for (int i = 0, length = options.strings.length; i < length; i++) {
|
||||
if (options.strings[i].equals(peeked)) {
|
||||
remove();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override public boolean nextBoolean() throws IOException {
|
||||
@@ -189,21 +202,74 @@ final class ObjectJsonReader extends JsonReader {
|
||||
}
|
||||
|
||||
@Override public double nextDouble() throws IOException {
|
||||
Number peeked = require(Number.class, Token.NUMBER);
|
||||
Object peeked = require(Object.class, Token.NUMBER);
|
||||
|
||||
double result;
|
||||
if (peeked instanceof Number) {
|
||||
result = ((Number) peeked).doubleValue();
|
||||
} else if (peeked instanceof String) {
|
||||
try {
|
||||
result = Double.parseDouble((String) peeked);
|
||||
} catch (NumberFormatException e) {
|
||||
throw typeMismatch(peeked, Token.NUMBER);
|
||||
}
|
||||
} else {
|
||||
throw typeMismatch(peeked, Token.NUMBER);
|
||||
}
|
||||
if (!lenient && (Double.isNaN(result) || Double.isInfinite(result))) {
|
||||
throw new JsonEncodingException("JSON forbids NaN and infinities: " + result
|
||||
+ " at path " + getPath());
|
||||
}
|
||||
remove();
|
||||
return peeked.doubleValue(); // TODO(jwilson): precision check?
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public long nextLong() throws IOException {
|
||||
Number peeked = require(Number.class, Token.NUMBER);
|
||||
Object peeked = require(Object.class, Token.NUMBER);
|
||||
|
||||
long result;
|
||||
if (peeked instanceof Number) {
|
||||
result = ((Number) peeked).longValue();
|
||||
} else if (peeked instanceof String) {
|
||||
try {
|
||||
result = Long.parseLong((String) peeked);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
BigDecimal asDecimal = new BigDecimal((String) peeked);
|
||||
result = asDecimal.longValueExact();
|
||||
} catch (NumberFormatException e2) {
|
||||
throw typeMismatch(peeked, Token.NUMBER);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw typeMismatch(peeked, Token.NUMBER);
|
||||
}
|
||||
remove();
|
||||
return peeked.longValue(); // TODO(jwilson): precision check?
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public int nextInt() throws IOException {
|
||||
Number peeked = require(Number.class, Token.NUMBER);
|
||||
Object peeked = require(Object.class, Token.NUMBER);
|
||||
|
||||
int result;
|
||||
if (peeked instanceof Number) {
|
||||
result = ((Number) peeked).intValue();
|
||||
} else if (peeked instanceof String) {
|
||||
try {
|
||||
result = Integer.parseInt((String) peeked);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
BigDecimal asDecimal = new BigDecimal((String) peeked);
|
||||
result = asDecimal.intValueExact();
|
||||
} catch (NumberFormatException e2) {
|
||||
throw typeMismatch(peeked, Token.NUMBER);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw typeMismatch(peeked, Token.NUMBER);
|
||||
}
|
||||
remove();
|
||||
return peeked.intValue(); // TODO(jwilson): precision check?
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public void skipValue() throws IOException {
|
||||
@@ -233,11 +299,10 @@ final class ObjectJsonReader extends JsonReader {
|
||||
}
|
||||
|
||||
@Override void promoteNameToValue() throws IOException {
|
||||
Object peeked = require(Map.Entry.class, Token.NAME);
|
||||
Map.Entry<?, ?> peeked = require(Map.Entry.class, Token.NAME);
|
||||
|
||||
stackSize++;
|
||||
stack[stackSize - 2] = ((Map.Entry<?, ?>) peeked).getValue();
|
||||
stack[stackSize - 1] = ((Map.Entry<?, ?>) peeked).getKey();
|
||||
push(peeked.getKey());
|
||||
stack[stackSize - 2] = peeked.getValue();
|
||||
}
|
||||
|
||||
@Override public void close() throws IOException {
|
||||
@@ -247,6 +312,13 @@ final class ObjectJsonReader extends JsonReader {
|
||||
stackSize = 1;
|
||||
}
|
||||
|
||||
private void push(Object newTop) {
|
||||
if (stackSize == stack.length) {
|
||||
throw new JsonDataException("Nesting too deep at " + getPath());
|
||||
}
|
||||
stack[stackSize++] = newTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the top of the stack which is required to be a {@code type}. Throws if this reader is
|
||||
* closed, or if the type isn't what was expected.
|
||||
@@ -263,8 +335,23 @@ final class ObjectJsonReader extends JsonReader {
|
||||
if (peeked == JSON_READER_CLOSED) {
|
||||
throw new IllegalStateException("JsonReader is closed");
|
||||
}
|
||||
throw new JsonDataException(
|
||||
"Expected " + expected + " but was " + peek() + " at path " + getPath());
|
||||
throw typeMismatch(peeked, expected);
|
||||
}
|
||||
|
||||
private String stringKey(Map.Entry<?, ?> entry) {
|
||||
Object name = entry.getKey();
|
||||
if (name instanceof String) return (String) name;
|
||||
throw typeMismatch(name, Token.NAME);
|
||||
}
|
||||
|
||||
private JsonDataException typeMismatch(Object value, Object expected) {
|
||||
if (value == null) {
|
||||
throw new JsonDataException(
|
||||
"Expected " + expected + " but was null at path " + getPath());
|
||||
} else {
|
||||
throw new JsonDataException("Expected " + expected + " but was " + value + ", a "
|
||||
+ value.getClass().getName() + ", at path " + getPath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,8 +369,7 @@ final class ObjectJsonReader extends JsonReader {
|
||||
|
||||
Object parent = stack[stackSize - 1];
|
||||
if (parent instanceof Iterator && ((Iterator<?>) parent).hasNext()) {
|
||||
stack[stackSize] = ((Iterator<?>) parent).next();
|
||||
stackSize++;
|
||||
push(((Iterator<?>) parent).next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,8 @@ import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import okio.Buffer;
|
||||
import okio.ForwardingSource;
|
||||
import okio.Okio;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -32,6 +34,7 @@ import static com.squareup.moshi.JsonReader.Token.NULL;
|
||||
import static com.squareup.moshi.JsonReader.Token.NUMBER;
|
||||
import static com.squareup.moshi.JsonReader.Token.STRING;
|
||||
import static com.squareup.moshi.TestUtil.newReader;
|
||||
import static com.squareup.moshi.TestUtil.repeat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -51,34 +54,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
assertThat(buffer.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test public void readArray() throws IOException {
|
||||
JsonReader reader = newReader("[true, true]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readEmptyArray() throws IOException {
|
||||
JsonReader reader = newReader("[]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.hasNext()).isFalse();
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readObject() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\": \"android\", \"b\": \"banana\"}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
assertThat(reader.nextString()).isEqualTo("android");
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
assertThat(reader.nextString()).isEqualTo("banana");
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readObjectBuffer() throws IOException {
|
||||
Buffer buffer = new Buffer().writeUtf8("{\"a\": \"android\", \"b\": \"banana\"}");
|
||||
JsonReader reader = JsonReader.of(buffer);
|
||||
@@ -93,7 +68,7 @@ public final class BufferedSourceJsonReaderTest {
|
||||
|
||||
@Test public void readObjectSource() throws IOException {
|
||||
Buffer buffer = new Buffer().writeUtf8("{\"a\": \"android\", \"b\": \"banana\"}");
|
||||
JsonReader reader = JsonReader.of(buffer);
|
||||
JsonReader reader = JsonReader.of(Okio.buffer(new ForwardingSource(buffer) {}));
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
assertThat(reader.nextString()).isEqualTo("android");
|
||||
@@ -103,147 +78,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readEmptyObject() throws IOException {
|
||||
JsonReader reader = newReader("{}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.hasNext()).isFalse();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipArray() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\": [\"one\", \"two\", \"three\"], \"b\": 123}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipArrayAfterPeek() throws Exception {
|
||||
JsonReader reader = newReader("{\"a\": [\"one\", \"two\", \"three\"], \"b\": 123}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_ARRAY);
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipTopLevelObject() throws Exception {
|
||||
JsonReader reader = newReader("{\"a\": [\"one\", \"two\", \"three\"], \"b\": 123}");
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipObject() throws IOException {
|
||||
JsonReader reader = newReader(
|
||||
"{\"a\": { \"c\": [], \"d\": [true, true, {}] }, \"b\": \"banana\"}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipObjectAfterPeek() throws Exception {
|
||||
String json = "{" + " \"one\": { \"num\": 1 }"
|
||||
+ ", \"two\": { \"num\": 2 }" + ", \"three\": { \"num\": 3 }" + "}";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("one");
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_OBJECT);
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("two");
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_OBJECT);
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("three");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipInteger() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":123456789,\"b\":-123456789}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipDouble() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":-123.456e-789,\"b\":123456789.0}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void failOnUnknownFailsOnUnknownObjectValue() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\": 123}");
|
||||
reader.setFailOnUnknown(true);
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
try {
|
||||
reader.skipValue();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Cannot skip unexpected NUMBER at $.a");
|
||||
}
|
||||
// Confirm that the reader is left in a consistent state after the exception.
|
||||
reader.setFailOnUnknown(false);
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void failOnUnknownFailsOnUnknownArrayElement() throws IOException {
|
||||
JsonReader reader = newReader("[\"a\", 123]");
|
||||
reader.setFailOnUnknown(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
try {
|
||||
reader.skipValue();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Cannot skip unexpected NUMBER at $[1]");
|
||||
}
|
||||
// Confirm that the reader is left in a consistent state after the exception.
|
||||
reader.setFailOnUnknown(false);
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void helloWorld() throws IOException {
|
||||
String json = "{\n" +
|
||||
" \"hello\": true,\n" +
|
||||
" \"foo\": [\"world\"]\n" +
|
||||
"}";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("hello");
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.nextName()).isEqualTo("foo");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("world");
|
||||
reader.endArray();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void nullSource() {
|
||||
try {
|
||||
JsonReader.of(null);
|
||||
@@ -252,65 +86,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void emptyString() throws Exception {
|
||||
try {
|
||||
newReader("").beginArray();
|
||||
fail();
|
||||
} catch (EOFException expected) {
|
||||
}
|
||||
try {
|
||||
newReader("").beginObject();
|
||||
fail();
|
||||
} catch (EOFException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void characterUnescaping() throws IOException {
|
||||
String json = "[\"a\","
|
||||
+ "\"a\\\"\","
|
||||
+ "\"\\\"\","
|
||||
+ "\":\","
|
||||
+ "\",\","
|
||||
+ "\"\\b\","
|
||||
+ "\"\\f\","
|
||||
+ "\"\\n\","
|
||||
+ "\"\\r\","
|
||||
+ "\"\\t\","
|
||||
+ "\" \","
|
||||
+ "\"\\\\\","
|
||||
+ "\"{\","
|
||||
+ "\"}\","
|
||||
+ "\"[\","
|
||||
+ "\"]\","
|
||||
+ "\"\\u0000\","
|
||||
+ "\"\\u0019\","
|
||||
+ "\"\\u20AC\""
|
||||
+ "]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
assertThat(reader.nextString()).isEqualTo("a\"");
|
||||
assertThat(reader.nextString()).isEqualTo("\"");
|
||||
assertThat(reader.nextString()).isEqualTo(":");
|
||||
assertThat(reader.nextString()).isEqualTo(",");
|
||||
assertThat(reader.nextString()).isEqualTo("\b");
|
||||
assertThat(reader.nextString()).isEqualTo("\f");
|
||||
assertThat(reader.nextString()).isEqualTo("\n");
|
||||
assertThat(reader.nextString()).isEqualTo("\r");
|
||||
assertThat(reader.nextString()).isEqualTo("\t");
|
||||
assertThat(reader.nextString()).isEqualTo(" ");
|
||||
assertThat(reader.nextString()).isEqualTo("\\");
|
||||
assertThat(reader.nextString()).isEqualTo("{");
|
||||
assertThat(reader.nextString()).isEqualTo("}");
|
||||
assertThat(reader.nextString()).isEqualTo("[");
|
||||
assertThat(reader.nextString()).isEqualTo("]");
|
||||
assertThat(reader.nextString()).isEqualTo("\0");
|
||||
assertThat(reader.nextString()).isEqualTo("\u0019");
|
||||
assertThat(reader.nextString()).isEqualTo("\u20AC");
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void unescapingInvalidCharacters() throws IOException {
|
||||
String json = "[\"\\u000g\"]";
|
||||
JsonReader reader = newReader(json);
|
||||
@@ -344,84 +119,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void integersWithFractionalPartSpecified() throws IOException {
|
||||
JsonReader reader = newReader("[1.0,1.0,1.0]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.0);
|
||||
assertThat(reader.nextInt()).isEqualTo(1);
|
||||
assertThat(reader.nextLong()).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test public void doubles() throws IOException {
|
||||
String json = "[-0.0,"
|
||||
+ "1.0,"
|
||||
+ "1.7976931348623157E308,"
|
||||
+ "4.9E-324,"
|
||||
+ "0.0,"
|
||||
+ "-0.5,"
|
||||
+ "2.2250738585072014E-308,"
|
||||
+ "3.141592653589793,"
|
||||
+ "2.718281828459045]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextDouble()).isEqualTo(-0.0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.7976931348623157E308);
|
||||
assertThat(reader.nextDouble()).isEqualTo(4.9E-324);
|
||||
assertThat(reader.nextDouble()).isEqualTo(0.0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(-0.5);
|
||||
assertThat(reader.nextDouble()).isEqualTo(2.2250738585072014E-308);
|
||||
assertThat(reader.nextDouble()).isEqualTo(3.141592653589793);
|
||||
assertThat(reader.nextDouble()).isEqualTo(2.718281828459045);
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void strictNonFiniteDoubles() throws IOException {
|
||||
String json = "[NaN]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextDouble();
|
||||
fail();
|
||||
} catch (JsonEncodingException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void strictQuotedNonFiniteDoubles() throws IOException {
|
||||
String json = "[\"NaN\"]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextDouble();
|
||||
fail();
|
||||
} catch (JsonEncodingException expected) {
|
||||
assertThat(expected).hasMessageContaining("NaN");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void lenientNonFiniteDoubles() throws IOException {
|
||||
String json = "[NaN, -Infinity, Infinity]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(Double.isNaN(reader.nextDouble())).isTrue();
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.NEGATIVE_INFINITY);
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.POSITIVE_INFINITY);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void lenientQuotedNonFiniteDoubles() throws IOException {
|
||||
String json = "[\"NaN\", \"-Infinity\", \"Infinity\"]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextDouble()).isNaN();
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.NEGATIVE_INFINITY);
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.POSITIVE_INFINITY);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void strictNonFiniteDoublesWithSkipValue() throws IOException {
|
||||
String json = "[NaN]";
|
||||
JsonReader reader = newReader(json);
|
||||
@@ -433,39 +130,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void longs() throws IOException {
|
||||
String json = "[0,0,0,"
|
||||
+ "1,1,1,"
|
||||
+ "-1,-1,-1,"
|
||||
+ "-9223372036854775808,"
|
||||
+ "9223372036854775807]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextLong()).isEqualTo(0L);
|
||||
assertThat(reader.nextInt()).isEqualTo(0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(0.0d);
|
||||
assertThat(reader.nextLong()).isEqualTo(1L);
|
||||
assertThat(reader.nextInt()).isEqualTo(1);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.0d);
|
||||
assertThat(reader.nextLong()).isEqualTo(-1L);
|
||||
assertThat(reader.nextInt()).isEqualTo(-1);
|
||||
assertThat(reader.nextDouble()).isEqualTo(-1.0d);
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextLong()).isEqualTo(Long.MIN_VALUE);
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextLong()).isEqualTo(Long.MAX_VALUE);
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test @Ignore public void numberWithOctalPrefix() throws IOException {
|
||||
String json = "[01]";
|
||||
JsonReader reader = newReader(json);
|
||||
@@ -495,15 +159,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void booleans() throws IOException {
|
||||
JsonReader reader = newReader("[true,false]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.nextBoolean()).isFalse();
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void peekingUnquotedStringsPrefixedWithBooleans() throws IOException {
|
||||
JsonReader reader = newReader("[truey]");
|
||||
reader.setLenient(true);
|
||||
@@ -749,122 +404,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void nextFailuresDoNotAdvance() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":true}");
|
||||
reader.beginObject();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.endArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.beginObject();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.endObject();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.endArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
reader.close();
|
||||
}
|
||||
|
||||
@Test public void integerMismatchWithDoubleDoesNotAdvance() throws IOException {
|
||||
JsonReader reader = newReader("[1.5]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.5d);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void integerMismatchWithLongDoesNotAdvance() throws IOException {
|
||||
JsonReader reader = newReader("[9223372036854775807]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextLong()).isEqualTo(9223372036854775807L);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void longMismatchWithDoubleDoesNotAdvance() throws IOException {
|
||||
JsonReader reader = newReader("[1.5]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextLong();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.5d);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void stringNullIsNotNull() throws IOException {
|
||||
JsonReader reader = newReader("[\"null\"]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextNull();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void nullLiteralIsNotAString() throws IOException {
|
||||
JsonReader reader = newReader("[null]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void strictNameValueSeparator() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\"=true}");
|
||||
reader.beginObject();
|
||||
@@ -1334,38 +873,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void topLevelValueTypes() throws IOException {
|
||||
JsonReader reader1 = newReader("true");
|
||||
assertThat(reader1.nextBoolean()).isTrue();
|
||||
assertThat(reader1.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader2 = newReader("false");
|
||||
assertThat(reader2.nextBoolean()).isFalse();
|
||||
assertThat(reader2.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader3 = newReader("null");
|
||||
assertThat(reader3.nextNull()).isNull();
|
||||
assertThat(reader3.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader4 = newReader("123");
|
||||
assertThat(reader4.nextInt()).isEqualTo(123);
|
||||
assertThat(reader4.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader5 = newReader("123.4");
|
||||
assertThat(reader5.nextDouble()).isEqualTo(123.4);
|
||||
assertThat(reader5.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader6 = newReader("\"a\"");
|
||||
assertThat(reader6.nextString()).isEqualTo("a");
|
||||
assertThat(reader6.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void topLevelValueTypeWithSkipValue() throws IOException {
|
||||
JsonReader reader = newReader("true");
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test @Ignore public void bomIgnoredAsFirstCharacterOfDocument() throws IOException {
|
||||
JsonReader reader = newReader("\ufeff[]");
|
||||
reader.beginArray();
|
||||
@@ -1497,19 +1004,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void deeplyNestedArrays() throws IOException {
|
||||
JsonReader reader = newReader("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.beginArray();
|
||||
}
|
||||
assertThat(reader.getPath()).isEqualTo("$[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]"
|
||||
+ "[0][0][0][0][0][0][0][0][0][0][0][0][0]");
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.endArray();
|
||||
}
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void tooDeeplyNestedArrays() throws IOException {
|
||||
JsonReader reader = newReader(
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
|
||||
@@ -1525,28 +1019,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void deeplyNestedObjects() throws IOException {
|
||||
// Build a JSON document structured like {"a":{"a":{"a":{"a":true}}}}, but 31 levels deep.
|
||||
String array = "{\"a\":%s}";
|
||||
String json = "true";
|
||||
for (int i = 0; i < 31; i++) {
|
||||
json = String.format(array, json);
|
||||
}
|
||||
|
||||
JsonReader reader = newReader(json);
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
}
|
||||
assertThat(reader.getPath())
|
||||
.isEqualTo("$.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a");
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.endObject();
|
||||
}
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void tooDeeplyNestedObjects() throws IOException {
|
||||
// Build a JSON document structured like {"a":{"a":{"a":{"a":true}}}}, but 31 levels deep.
|
||||
String array = "{\"a\":%s}";
|
||||
@@ -1652,70 +1124,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void skipVeryLongUnquotedString() throws IOException {
|
||||
JsonReader reader = newReader("[" + repeat('x', 8192) + "]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
reader.skipValue();
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void skipTopLevelUnquotedString() throws IOException {
|
||||
JsonReader reader = newReader(repeat('x', 8192));
|
||||
reader.setLenient(true);
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipVeryLongQuotedString() throws IOException {
|
||||
JsonReader reader = newReader("[\"" + repeat('x', 8192) + "\"]");
|
||||
reader.beginArray();
|
||||
reader.skipValue();
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void skipTopLevelQuotedString() throws IOException {
|
||||
JsonReader reader = newReader("\"" + repeat('x', 8192) + "\"");
|
||||
reader.setLenient(true);
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void stringAsNumberWithTruncatedExponent() throws IOException {
|
||||
JsonReader reader = newReader("[123e]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.peek()).isEqualTo(STRING);
|
||||
}
|
||||
|
||||
@Test public void stringAsNumberWithDigitAndNonDigitExponent() throws IOException {
|
||||
JsonReader reader = newReader("[123e4b]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.peek()).isEqualTo(STRING);
|
||||
}
|
||||
|
||||
@Test public void stringAsNumberWithNonDigitExponent() throws IOException {
|
||||
JsonReader reader = newReader("[123eb]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.peek()).isEqualTo(STRING);
|
||||
}
|
||||
|
||||
@Test public void emptyStringName() throws IOException {
|
||||
JsonReader reader = newReader("{\"\":true}");
|
||||
reader.setLenient(true);
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_OBJECT);
|
||||
reader.beginObject();
|
||||
assertThat(reader.peek()).isEqualTo(NAME);
|
||||
assertThat(reader.nextName()).isEqualTo("");
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.BOOLEAN);
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_OBJECT);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void strictExtraCommasInMaps() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":\"b\",}");
|
||||
reader.beginObject();
|
||||
@@ -1741,12 +1149,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
private String repeat(char c, int count) {
|
||||
char[] array = new char[count];
|
||||
Arrays.fill(array, c);
|
||||
return new String(array);
|
||||
}
|
||||
|
||||
@Test public void malformedDocuments() throws IOException {
|
||||
assertDocument("{]", BEGIN_OBJECT, JsonEncodingException.class);
|
||||
assertDocument("{,", BEGIN_OBJECT, JsonEncodingException.class);
|
||||
@@ -1804,12 +1206,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void validEscapes() throws IOException {
|
||||
JsonReader reader = newReader("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("\"\\/\b\f\n\r\t");
|
||||
}
|
||||
|
||||
@Test public void invalidEscape() throws IOException {
|
||||
JsonReader reader = newReader("[\"str\\ing\"]");
|
||||
reader.beginArray();
|
||||
@@ -1828,68 +1224,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
assertThat(reader.nextString()).isEqualTo("string");
|
||||
}
|
||||
|
||||
@Test public void selectName() throws IOException {
|
||||
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
||||
|
||||
JsonReader reader = newReader("{\"a\": 5, \"b\": 5, \"c\": 5, \"d\": 5}");
|
||||
reader.beginObject();
|
||||
assertEquals("$.", reader.getPath());
|
||||
|
||||
assertEquals(0, reader.selectName(abc));
|
||||
assertEquals("$.a", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.a", reader.getPath());
|
||||
|
||||
assertEquals(1, reader.selectName(abc));
|
||||
assertEquals("$.b", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.b", reader.getPath());
|
||||
|
||||
assertEquals(2, reader.selectName(abc));
|
||||
assertEquals("$.c", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.c", reader.getPath());
|
||||
|
||||
// A missed selectName() doesn't advance anything, not even the path.
|
||||
assertEquals(-1, reader.selectName(abc));
|
||||
assertEquals("$.c", reader.getPath());
|
||||
assertEquals(JsonReader.Token.NAME, reader.peek());
|
||||
|
||||
assertEquals("d", reader.nextName());
|
||||
assertEquals("$.d", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.d", reader.getPath());
|
||||
|
||||
reader.endObject();
|
||||
}
|
||||
|
||||
@Test public void selectString() throws IOException {
|
||||
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
||||
|
||||
JsonReader reader = newReader("[\"a\", \"b\", \"c\", \"d\"]");
|
||||
reader.beginArray();
|
||||
assertEquals("$[0]", reader.getPath());
|
||||
|
||||
assertEquals(0, reader.selectString(abc));
|
||||
assertEquals("$[1]", reader.getPath());
|
||||
|
||||
assertEquals(1, reader.selectString(abc));
|
||||
assertEquals("$[2]", reader.getPath());
|
||||
|
||||
assertEquals(2, reader.selectString(abc));
|
||||
assertEquals("$[3]", reader.getPath());
|
||||
|
||||
// A missed selectName() doesn't advance anything, not even the path.
|
||||
assertEquals(-1, reader.selectString(abc));
|
||||
assertEquals("$[3]", reader.getPath());
|
||||
assertEquals(JsonReader.Token.STRING, reader.peek());
|
||||
|
||||
assertEquals("d", reader.nextString());
|
||||
assertEquals("$[4]", reader.getPath());
|
||||
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
/** Select doesn't match unquoted strings. */
|
||||
@Test public void selectStringUnquoted() throws IOException {
|
||||
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
||||
@@ -1925,24 +1259,6 @@ public final class BufferedSourceJsonReaderTest {
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
/** Select does match necessarily escaping. The decoded value is used in the path. */
|
||||
@Test public void selectNecessaryEscaping() throws IOException {
|
||||
JsonReader.Options options = JsonReader.Options.of("\n", "\u0000", "\"");
|
||||
|
||||
JsonReader reader = newReader("{\"\\n\": 5,\"\\u0000\": 5, \"\\\"\": 5}");
|
||||
reader.beginObject();
|
||||
assertEquals(0, reader.selectName(options));
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.\n", reader.getPath());
|
||||
assertEquals(1, reader.selectName(options));
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.\u0000", reader.getPath());
|
||||
assertEquals(2, reader.selectName(options));
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.\"", reader.getPath());
|
||||
reader.endObject();
|
||||
}
|
||||
|
||||
private void assertDocument(String document, Object... expectations) throws IOException {
|
||||
JsonReader reader = newReader(document);
|
||||
reader.setLenient(true);
|
||||
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Square, 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.squareup.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import okio.Buffer;
|
||||
|
||||
abstract class JsonReaderFactory {
|
||||
public static final JsonReaderFactory BUFFERED_SOURCE = new JsonReaderFactory() {
|
||||
@Override public JsonReader newReader(String json) {
|
||||
Buffer buffer = new Buffer().writeUtf8(json);
|
||||
return JsonReader.of(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
public static final JsonReaderFactory JSON_OBJECT = new JsonReaderFactory() {
|
||||
@Override public JsonReader newReader(String json) throws IOException {
|
||||
Moshi moshi = new Moshi.Builder().build();
|
||||
Object object = moshi.adapter(Object.class).lenient().fromJson(json);
|
||||
return new ObjectJsonReader(object);
|
||||
}
|
||||
};
|
||||
|
||||
static List<Object[]> factories() {
|
||||
return Arrays.asList(
|
||||
new Object[] { BUFFERED_SOURCE },
|
||||
new Object[] { JSON_OBJECT });
|
||||
}
|
||||
|
||||
abstract JsonReader newReader(String json) throws IOException;
|
||||
}
|
@@ -16,9 +16,7 @@
|
||||
package com.squareup.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import okio.Buffer;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@@ -30,34 +28,13 @@ import static org.junit.Assume.assumeTrue;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public final class JsonReaderPathTest {
|
||||
interface Factory {
|
||||
Factory BUFFERED_SOURCE = new Factory() {
|
||||
@Override public JsonReader newReader(String json) {
|
||||
Buffer buffer = new Buffer().writeUtf8(json);
|
||||
return JsonReader.of(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
Factory JSON_OBJECT = new Factory() {
|
||||
@Override public JsonReader newReader(String json) throws IOException {
|
||||
Moshi moshi = new Moshi.Builder().build();
|
||||
Object object = moshi.adapter(Object.class).fromJson(json);
|
||||
return new ObjectJsonReader(object);
|
||||
}
|
||||
};
|
||||
|
||||
JsonReader newReader(String json) throws IOException;
|
||||
}
|
||||
@Parameter public JsonReaderFactory factory;
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static List<Object[]> parameters() {
|
||||
return Arrays.asList(
|
||||
new Object[] { Factory.BUFFERED_SOURCE},
|
||||
new Object[] { Factory.JSON_OBJECT});
|
||||
return JsonReaderFactory.factories();
|
||||
}
|
||||
|
||||
@Parameter public Factory factory;
|
||||
|
||||
@Test public void path() throws IOException {
|
||||
JsonReader reader = factory.newReader("{\"a\":[2,true,false,null,\"b\",{\"c\":\"d\"},[3]]}");
|
||||
assertThat(reader.getPath()).isEqualTo("$");
|
||||
@@ -208,7 +185,7 @@ public final class JsonReaderPathTest {
|
||||
}
|
||||
|
||||
@Test public void multipleTopLevelValuesInOneDocument() throws IOException {
|
||||
assumeTrue(factory != Factory.JSON_OBJECT);
|
||||
assumeTrue(factory != JsonReaderFactory.JSON_OBJECT);
|
||||
|
||||
JsonReader reader = factory.newReader("[][]");
|
||||
reader.setLenient(true);
|
||||
|
800
moshi/src/test/java/com/squareup/moshi/JsonReaderTest.java
Normal file
800
moshi/src/test/java/com/squareup/moshi/JsonReaderTest.java
Normal file
@@ -0,0 +1,800 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.squareup.moshi;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import static com.squareup.moshi.JsonReader.Token.BEGIN_ARRAY;
|
||||
import static com.squareup.moshi.JsonReader.Token.BEGIN_OBJECT;
|
||||
import static com.squareup.moshi.JsonReader.Token.NAME;
|
||||
import static com.squareup.moshi.JsonReader.Token.STRING;
|
||||
import static com.squareup.moshi.TestUtil.repeat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public final class JsonReaderTest {
|
||||
@Parameter public JsonReaderFactory factory;
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static List<Object[]> parameters() {
|
||||
return JsonReaderFactory.factories();
|
||||
}
|
||||
|
||||
JsonReader newReader(String json) throws IOException {
|
||||
return factory.newReader(json);
|
||||
}
|
||||
|
||||
@Test public void readArray() throws IOException {
|
||||
JsonReader reader = newReader("[true, true]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readEmptyArray() throws IOException {
|
||||
JsonReader reader = newReader("[]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.hasNext()).isFalse();
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readObject() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\": \"android\", \"b\": \"banana\"}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
assertThat(reader.nextString()).isEqualTo("android");
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
assertThat(reader.nextString()).isEqualTo("banana");
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void readEmptyObject() throws IOException {
|
||||
JsonReader reader = newReader("{}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.hasNext()).isFalse();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipArray() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\": [\"one\", \"two\", \"three\"], \"b\": 123}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipArrayAfterPeek() throws Exception {
|
||||
JsonReader reader = newReader("{\"a\": [\"one\", \"two\", \"three\"], \"b\": 123}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_ARRAY);
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipTopLevelObject() throws Exception {
|
||||
JsonReader reader = newReader("{\"a\": [\"one\", \"two\", \"three\"], \"b\": 123}");
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipObject() throws IOException {
|
||||
JsonReader reader = newReader(
|
||||
"{\"a\": { \"c\": [], \"d\": [true, true, {}] }, \"b\": \"banana\"}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipObjectAfterPeek() throws Exception {
|
||||
String json = "{" + " \"one\": { \"num\": 1 }"
|
||||
+ ", \"two\": { \"num\": 2 }" + ", \"three\": { \"num\": 3 }" + "}";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("one");
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_OBJECT);
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("two");
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_OBJECT);
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("three");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipInteger() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":123456789,\"b\":-123456789}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipDouble() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":-123.456e-789,\"b\":123456789.0}");
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
reader.skipValue();
|
||||
assertThat(reader.nextName()).isEqualTo("b");
|
||||
reader.skipValue();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void failOnUnknownFailsOnUnknownObjectValue() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\": 123}");
|
||||
reader.setFailOnUnknown(true);
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
try {
|
||||
reader.skipValue();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Cannot skip unexpected NUMBER at $.a");
|
||||
}
|
||||
// Confirm that the reader is left in a consistent state after the exception.
|
||||
reader.setFailOnUnknown(false);
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void failOnUnknownFailsOnUnknownArrayElement() throws IOException {
|
||||
JsonReader reader = newReader("[\"a\", 123]");
|
||||
reader.setFailOnUnknown(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
try {
|
||||
reader.skipValue();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Cannot skip unexpected NUMBER at $[1]");
|
||||
}
|
||||
// Confirm that the reader is left in a consistent state after the exception.
|
||||
reader.setFailOnUnknown(false);
|
||||
assertThat(reader.nextInt()).isEqualTo(123);
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void helloWorld() throws IOException {
|
||||
String json = "{\n" +
|
||||
" \"hello\": true,\n" +
|
||||
" \"foo\": [\"world\"]\n" +
|
||||
"}";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("hello");
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.nextName()).isEqualTo("foo");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("world");
|
||||
reader.endArray();
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void emptyString() throws Exception {
|
||||
try {
|
||||
newReader("").beginArray();
|
||||
fail();
|
||||
} catch (EOFException expected) {
|
||||
}
|
||||
try {
|
||||
newReader("").beginObject();
|
||||
fail();
|
||||
} catch (EOFException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void characterUnescaping() throws IOException {
|
||||
String json = "[\"a\","
|
||||
+ "\"a\\\"\","
|
||||
+ "\"\\\"\","
|
||||
+ "\":\","
|
||||
+ "\",\","
|
||||
+ "\"\\b\","
|
||||
+ "\"\\f\","
|
||||
+ "\"\\n\","
|
||||
+ "\"\\r\","
|
||||
+ "\"\\t\","
|
||||
+ "\" \","
|
||||
+ "\"\\\\\","
|
||||
+ "\"{\","
|
||||
+ "\"}\","
|
||||
+ "\"[\","
|
||||
+ "\"]\","
|
||||
+ "\"\\u0000\","
|
||||
+ "\"\\u0019\","
|
||||
+ "\"\\u20AC\""
|
||||
+ "]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
assertThat(reader.nextString()).isEqualTo("a\"");
|
||||
assertThat(reader.nextString()).isEqualTo("\"");
|
||||
assertThat(reader.nextString()).isEqualTo(":");
|
||||
assertThat(reader.nextString()).isEqualTo(",");
|
||||
assertThat(reader.nextString()).isEqualTo("\b");
|
||||
assertThat(reader.nextString()).isEqualTo("\f");
|
||||
assertThat(reader.nextString()).isEqualTo("\n");
|
||||
assertThat(reader.nextString()).isEqualTo("\r");
|
||||
assertThat(reader.nextString()).isEqualTo("\t");
|
||||
assertThat(reader.nextString()).isEqualTo(" ");
|
||||
assertThat(reader.nextString()).isEqualTo("\\");
|
||||
assertThat(reader.nextString()).isEqualTo("{");
|
||||
assertThat(reader.nextString()).isEqualTo("}");
|
||||
assertThat(reader.nextString()).isEqualTo("[");
|
||||
assertThat(reader.nextString()).isEqualTo("]");
|
||||
assertThat(reader.nextString()).isEqualTo("\0");
|
||||
assertThat(reader.nextString()).isEqualTo("\u0019");
|
||||
assertThat(reader.nextString()).isEqualTo("\u20AC");
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void integersWithFractionalPartSpecified() throws IOException {
|
||||
JsonReader reader = newReader("[1.0,1.0,1.0]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.0);
|
||||
assertThat(reader.nextInt()).isEqualTo(1);
|
||||
assertThat(reader.nextLong()).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test public void doubles() throws IOException {
|
||||
String json = "[-0.0,"
|
||||
+ "1.0,"
|
||||
+ "1.7976931348623157E308,"
|
||||
+ "4.9E-324,"
|
||||
+ "0.0,"
|
||||
+ "-0.5,"
|
||||
+ "2.2250738585072014E-308,"
|
||||
+ "3.141592653589793,"
|
||||
+ "2.718281828459045]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextDouble()).isEqualTo(-0.0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.7976931348623157E308);
|
||||
assertThat(reader.nextDouble()).isEqualTo(4.9E-324);
|
||||
assertThat(reader.nextDouble()).isEqualTo(0.0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(-0.5);
|
||||
assertThat(reader.nextDouble()).isEqualTo(2.2250738585072014E-308);
|
||||
assertThat(reader.nextDouble()).isEqualTo(3.141592653589793);
|
||||
assertThat(reader.nextDouble()).isEqualTo(2.718281828459045);
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void strictNonFiniteDoubles() throws IOException {
|
||||
String json = "[NaN]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextDouble();
|
||||
fail();
|
||||
} catch (JsonEncodingException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void strictQuotedNonFiniteDoubles() throws IOException {
|
||||
String json = "[\"NaN\"]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextDouble();
|
||||
fail();
|
||||
} catch (JsonEncodingException expected) {
|
||||
assertThat(expected).hasMessageContaining("NaN");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void lenientNonFiniteDoubles() throws IOException {
|
||||
String json = "[NaN, -Infinity, Infinity]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(Double.isNaN(reader.nextDouble())).isTrue();
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.NEGATIVE_INFINITY);
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.POSITIVE_INFINITY);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void lenientQuotedNonFiniteDoubles() throws IOException {
|
||||
String json = "[\"NaN\", \"-Infinity\", \"Infinity\"]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextDouble()).isNaN();
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.NEGATIVE_INFINITY);
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.POSITIVE_INFINITY);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void longs() throws IOException {
|
||||
assumeTrue(factory != JsonReaderFactory.JSON_OBJECT); // TODO(jwilson): fix precision checks.
|
||||
String json = "[0,0,0,"
|
||||
+ "1,1,1,"
|
||||
+ "-1,-1,-1,"
|
||||
+ "-9223372036854775808,"
|
||||
+ "9223372036854775807]";
|
||||
JsonReader reader = newReader(json);
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextLong()).isEqualTo(0L);
|
||||
assertThat(reader.nextInt()).isEqualTo(0);
|
||||
assertThat(reader.nextDouble()).isEqualTo(0.0d);
|
||||
assertThat(reader.nextLong()).isEqualTo(1L);
|
||||
assertThat(reader.nextInt()).isEqualTo(1);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.0d);
|
||||
assertThat(reader.nextLong()).isEqualTo(-1L);
|
||||
assertThat(reader.nextInt()).isEqualTo(-1);
|
||||
assertThat(reader.nextDouble()).isEqualTo(-1.0d);
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextLong()).isEqualTo(Long.MIN_VALUE);
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextLong()).isEqualTo(Long.MAX_VALUE);
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void booleans() throws IOException {
|
||||
JsonReader reader = newReader("[true,false]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.nextBoolean()).isFalse();
|
||||
reader.endArray();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void nextFailuresDoNotAdvance() throws IOException {
|
||||
JsonReader reader = newReader("{\"a\":true}");
|
||||
reader.beginObject();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.endArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.beginObject();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.endObject();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
try {
|
||||
reader.endArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
reader.close();
|
||||
}
|
||||
|
||||
@Test public void integerMismatchWithDoubleDoesNotAdvance() throws IOException {
|
||||
assumeTrue(factory != JsonReaderFactory.JSON_OBJECT); // TODO(jwilson): fix precision checks.
|
||||
|
||||
JsonReader reader = newReader("[1.5]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.5d);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void integerMismatchWithLongDoesNotAdvance() throws IOException {
|
||||
assumeTrue(factory != JsonReaderFactory.JSON_OBJECT); // TODO(jwilson): fix precision checks.
|
||||
|
||||
JsonReader reader = newReader("[9223372036854775807]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextLong()).isEqualTo(9223372036854775807L);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void longMismatchWithDoubleDoesNotAdvance() throws IOException {
|
||||
assumeTrue(factory != JsonReaderFactory.JSON_OBJECT); // TODO(jwilson): fix precision checks.
|
||||
|
||||
JsonReader reader = newReader("[1.5]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextLong();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.5d);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void stringNullIsNotNull() throws IOException {
|
||||
JsonReader reader = newReader("[\"null\"]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextNull();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void nullLiteralIsNotAString() throws IOException {
|
||||
JsonReader reader = newReader("[null]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void topLevelValueTypes() throws IOException {
|
||||
JsonReader reader1 = newReader("true");
|
||||
assertThat(reader1.nextBoolean()).isTrue();
|
||||
assertThat(reader1.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader2 = newReader("false");
|
||||
assertThat(reader2.nextBoolean()).isFalse();
|
||||
assertThat(reader2.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader3 = newReader("null");
|
||||
assertThat(reader3.nextNull()).isNull();
|
||||
assertThat(reader3.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader4 = newReader("123");
|
||||
assertThat(reader4.nextInt()).isEqualTo(123);
|
||||
assertThat(reader4.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader5 = newReader("123.4");
|
||||
assertThat(reader5.nextDouble()).isEqualTo(123.4);
|
||||
assertThat(reader5.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
|
||||
JsonReader reader6 = newReader("\"a\"");
|
||||
assertThat(reader6.nextString()).isEqualTo("a");
|
||||
assertThat(reader6.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void topLevelValueTypeWithSkipValue() throws IOException {
|
||||
JsonReader reader = newReader("true");
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void deeplyNestedArrays() throws IOException {
|
||||
JsonReader reader = newReader("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.beginArray();
|
||||
}
|
||||
assertThat(reader.getPath()).isEqualTo("$[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]"
|
||||
+ "[0][0][0][0][0][0][0][0][0][0][0][0][0]");
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.endArray();
|
||||
}
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void deeplyNestedObjects() throws IOException {
|
||||
// Build a JSON document structured like {"a":{"a":{"a":{"a":true}}}}, but 31 levels deep.
|
||||
String array = "{\"a\":%s}";
|
||||
String json = "true";
|
||||
for (int i = 0; i < 31; i++) {
|
||||
json = String.format(array, json);
|
||||
}
|
||||
|
||||
JsonReader reader = newReader(json);
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
}
|
||||
assertThat(reader.getPath())
|
||||
.isEqualTo("$.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a");
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.endObject();
|
||||
}
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipVeryLongUnquotedString() throws IOException {
|
||||
JsonReader reader = newReader("[" + repeat('x', 8192) + "]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
reader.skipValue();
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void skipTopLevelUnquotedString() throws IOException {
|
||||
JsonReader reader = newReader(repeat('x', 8192));
|
||||
reader.setLenient(true);
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void skipVeryLongQuotedString() throws IOException {
|
||||
JsonReader reader = newReader("[\"" + repeat('x', 8192) + "\"]");
|
||||
reader.beginArray();
|
||||
reader.skipValue();
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void skipTopLevelQuotedString() throws IOException {
|
||||
JsonReader reader = newReader("\"" + repeat('x', 8192) + "\"");
|
||||
reader.setLenient(true);
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void stringAsNumberWithTruncatedExponent() throws IOException {
|
||||
JsonReader reader = newReader("[123e]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.peek()).isEqualTo(STRING);
|
||||
}
|
||||
|
||||
@Test public void stringAsNumberWithDigitAndNonDigitExponent() throws IOException {
|
||||
JsonReader reader = newReader("[123e4b]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.peek()).isEqualTo(STRING);
|
||||
}
|
||||
|
||||
@Test public void stringAsNumberWithNonDigitExponent() throws IOException {
|
||||
JsonReader reader = newReader("[123eb]");
|
||||
reader.setLenient(true);
|
||||
reader.beginArray();
|
||||
assertThat(reader.peek()).isEqualTo(STRING);
|
||||
}
|
||||
|
||||
@Test public void emptyStringName() throws IOException {
|
||||
JsonReader reader = newReader("{\"\":true}");
|
||||
reader.setLenient(true);
|
||||
assertThat(reader.peek()).isEqualTo(BEGIN_OBJECT);
|
||||
reader.beginObject();
|
||||
assertThat(reader.peek()).isEqualTo(NAME);
|
||||
assertThat(reader.nextName()).isEqualTo("");
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.BOOLEAN);
|
||||
assertThat(reader.nextBoolean()).isTrue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_OBJECT);
|
||||
reader.endObject();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
|
||||
@Test public void validEscapes() throws IOException {
|
||||
JsonReader reader = newReader("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextString()).isEqualTo("\"\\/\b\f\n\r\t");
|
||||
}
|
||||
|
||||
@Test public void selectName() throws IOException {
|
||||
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
||||
|
||||
JsonReader reader = newReader("{\"a\": 5, \"b\": 5, \"c\": 5, \"d\": 5}");
|
||||
reader.beginObject();
|
||||
assertEquals("$.", reader.getPath());
|
||||
|
||||
assertEquals(0, reader.selectName(abc));
|
||||
assertEquals("$.a", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.a", reader.getPath());
|
||||
|
||||
assertEquals(1, reader.selectName(abc));
|
||||
assertEquals("$.b", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.b", reader.getPath());
|
||||
|
||||
assertEquals(2, reader.selectName(abc));
|
||||
assertEquals("$.c", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.c", reader.getPath());
|
||||
|
||||
// A missed selectName() doesn't advance anything, not even the path.
|
||||
assertEquals(-1, reader.selectName(abc));
|
||||
assertEquals("$.c", reader.getPath());
|
||||
assertEquals(JsonReader.Token.NAME, reader.peek());
|
||||
|
||||
assertEquals("d", reader.nextName());
|
||||
assertEquals("$.d", reader.getPath());
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.d", reader.getPath());
|
||||
|
||||
reader.endObject();
|
||||
}
|
||||
|
||||
@Test public void selectString() throws IOException {
|
||||
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
||||
|
||||
JsonReader reader = newReader("[\"a\", \"b\", \"c\", \"d\"]");
|
||||
reader.beginArray();
|
||||
assertEquals("$[0]", reader.getPath());
|
||||
|
||||
assertEquals(0, reader.selectString(abc));
|
||||
assertEquals("$[1]", reader.getPath());
|
||||
|
||||
assertEquals(1, reader.selectString(abc));
|
||||
assertEquals("$[2]", reader.getPath());
|
||||
|
||||
assertEquals(2, reader.selectString(abc));
|
||||
assertEquals("$[3]", reader.getPath());
|
||||
|
||||
// A missed selectName() doesn't advance anything, not even the path.
|
||||
assertEquals(-1, reader.selectString(abc));
|
||||
assertEquals("$[3]", reader.getPath());
|
||||
assertEquals(JsonReader.Token.STRING, reader.peek());
|
||||
|
||||
assertEquals("d", reader.nextString());
|
||||
assertEquals("$[4]", reader.getPath());
|
||||
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
/** Select does match necessarily escaping. The decoded value is used in the path. */
|
||||
@Test public void selectNecessaryEscaping() throws IOException {
|
||||
JsonReader.Options options = JsonReader.Options.of("\n", "\u0000", "\"");
|
||||
|
||||
JsonReader reader = newReader("{\"\\n\": 5,\"\\u0000\": 5, \"\\\"\": 5}");
|
||||
reader.beginObject();
|
||||
assertEquals(0, reader.selectName(options));
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.\n", reader.getPath());
|
||||
assertEquals(1, reader.selectName(options));
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.\u0000", reader.getPath());
|
||||
assertEquals(2, reader.selectName(options));
|
||||
assertEquals(5, reader.nextInt());
|
||||
assertEquals("$.\"", reader.getPath());
|
||||
reader.endObject();
|
||||
}
|
||||
|
||||
@Test public void stringToNumberCoersion() throws Exception {
|
||||
JsonReader reader = newReader("[\"0\", \"9223372036854775807\", \"1.5\"]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextInt()).isEqualTo(0);
|
||||
assertThat(reader.nextLong()).isEqualTo(9223372036854775807L);
|
||||
assertThat(reader.nextDouble()).isEqualTo(1.5d);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void unnecessaryPrecisionNumberCoersion() throws Exception {
|
||||
JsonReader reader = newReader("[\"0.0\", \"9223372036854775807.0\"]");
|
||||
reader.beginArray();
|
||||
assertThat(reader.nextInt()).isEqualTo(0);
|
||||
assertThat(reader.nextLong()).isEqualTo(9223372036854775807L);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void nanInfinityDoubleCoersion() throws Exception {
|
||||
JsonReader reader = newReader("[\"NaN\", \"Infinity\", \"-Infinity\"]");
|
||||
reader.beginArray();
|
||||
reader.setLenient(true);
|
||||
assertThat(reader.nextDouble()).isNaN();
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.POSITIVE_INFINITY);
|
||||
assertThat(reader.nextDouble()).isEqualTo(Double.NEGATIVE_INFINITY);
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void intMismatchWithStringDoesNotAdvance() throws Exception {
|
||||
JsonReader reader = newReader("[\"a\"]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void longMismatchWithStringDoesNotAdvance() throws Exception {
|
||||
JsonReader reader = newReader("[\"a\"]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextLong();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
reader.endArray();
|
||||
}
|
||||
|
||||
@Test public void doubleMismatchWithStringDoesNotAdvance() throws Exception {
|
||||
JsonReader reader = newReader("[\"a\"]");
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextDouble();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
}
|
||||
assertThat(reader.nextString()).isEqualTo("a");
|
||||
reader.endArray();
|
||||
}
|
||||
}
|
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.squareup.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -22,6 +23,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@@ -106,8 +109,7 @@ public final class ObjectJsonReaderTest {
|
||||
|
||||
@Test public void nesting() throws Exception {
|
||||
List<Map<String, List<Map<String, Double>>>> root
|
||||
= Collections.singletonList(Collections.singletonMap(
|
||||
"a", Collections.singletonList(Collections.singletonMap("b", 1.5d))));
|
||||
= singletonList(singletonMap("a", singletonList(singletonMap("b", 1.5d))));
|
||||
JsonReader reader = new ObjectJsonReader(root);
|
||||
|
||||
assertThat(reader.hasNext()).isTrue();
|
||||
@@ -158,7 +160,7 @@ public final class ObjectJsonReaderTest {
|
||||
}
|
||||
|
||||
@Test public void promoteNameToValue() throws Exception {
|
||||
Map<String, String> root = Collections.singletonMap("a", "b");
|
||||
Map<String, String> root = singletonMap("a", "b");
|
||||
|
||||
JsonReader reader = new ObjectJsonReader(root);
|
||||
reader.beginObject();
|
||||
@@ -174,31 +176,32 @@ public final class ObjectJsonReaderTest {
|
||||
}
|
||||
|
||||
@Test public void endArrayTooEarly() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonList("s"));
|
||||
JsonReader reader = new ObjectJsonReader(singletonList("s"));
|
||||
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.endArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Expected END_ARRAY but was STRING at path $[0]");
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected END_ARRAY but was s, a java.lang.String, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void endObjectTooEarly() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonMap("a", "b"));
|
||||
JsonReader reader = new ObjectJsonReader(singletonMap("a", "b"));
|
||||
|
||||
reader.beginObject();
|
||||
try {
|
||||
reader.endObject();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Expected END_OBJECT but was NAME at path $.");
|
||||
assertThat(expected).hasMessageStartingWith("Expected END_OBJECT but was a=b");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unsupportedType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonList(new StringBuilder("x")));
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("x")));
|
||||
|
||||
reader.beginArray();
|
||||
try {
|
||||
@@ -206,12 +209,109 @@ public final class ObjectJsonReaderTest {
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected a JSON value but was a java.lang.StringBuilder at path $[0]");
|
||||
"Expected a JSON value but was x, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unsupportedKeyType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonMap(new StringBuilder("x"), "y"));
|
||||
|
||||
reader.beginObject();
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected NAME but was x, a java.lang.StringBuilder, at path $.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void nullKey() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonMap(null, "y"));
|
||||
|
||||
reader.beginObject();
|
||||
try {
|
||||
reader.nextName();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Expected NAME but was null at path $.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unexpectedIntType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("1")));
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextInt();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected NUMBER but was 1, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unexpectedLongType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("1")));
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextLong();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected NUMBER but was 1, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unexpectedDoubleType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("1")));
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextDouble();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected NUMBER but was 1, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unexpectedStringType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("s")));
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextString();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected STRING but was s, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unexpectedBooleanType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("true")));
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextBoolean();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected BOOLEAN but was true, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void unexpectedNullType() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("null")));
|
||||
reader.beginArray();
|
||||
try {
|
||||
reader.nextNull();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Expected NULL but was null, a java.lang.StringBuilder, at path $[0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void skipRoot() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonList(new StringBuilder("x")));
|
||||
JsonReader reader = new ObjectJsonReader(singletonList(new StringBuilder("x")));
|
||||
reader.skipValue();
|
||||
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
|
||||
}
|
||||
@@ -292,7 +392,7 @@ public final class ObjectJsonReaderTest {
|
||||
}
|
||||
|
||||
@Test public void failOnUnknown() throws Exception {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonList("a"));
|
||||
JsonReader reader = new ObjectJsonReader(singletonList("a"));
|
||||
reader.setFailOnUnknown(true);
|
||||
|
||||
reader.beginArray();
|
||||
@@ -306,7 +406,7 @@ public final class ObjectJsonReaderTest {
|
||||
|
||||
@Test public void close() throws Exception {
|
||||
try {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonList("a"));
|
||||
JsonReader reader = new ObjectJsonReader(singletonList("a"));
|
||||
reader.beginArray();
|
||||
reader.close();
|
||||
reader.nextString();
|
||||
@@ -315,11 +415,48 @@ public final class ObjectJsonReaderTest {
|
||||
}
|
||||
|
||||
try {
|
||||
JsonReader reader = new ObjectJsonReader(Collections.singletonList("a"));
|
||||
JsonReader reader = new ObjectJsonReader(singletonList("a"));
|
||||
reader.close();
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (IllegalStateException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void tooDeeplyNestedArrays() throws IOException {
|
||||
Object root = Collections.emptyList();
|
||||
for (int i = 0; i < 32; i++) {
|
||||
root = singletonList(root);
|
||||
}
|
||||
JsonReader reader = new ObjectJsonReader(root);
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.beginArray();
|
||||
}
|
||||
try {
|
||||
reader.beginArray();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage("Nesting too deep at $[0][0][0][0][0][0][0][0][0][0][0][0][0]"
|
||||
+ "[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]");
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void tooDeeplyNestedObjects() throws IOException {
|
||||
Object root = Boolean.TRUE;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
root = singletonMap("a", root);
|
||||
}
|
||||
JsonReader reader = new ObjectJsonReader(root);
|
||||
for (int i = 0; i < 31; i++) {
|
||||
reader.beginObject();
|
||||
assertThat(reader.nextName()).isEqualTo("a");
|
||||
}
|
||||
try {
|
||||
reader.beginObject();
|
||||
fail();
|
||||
} catch (JsonDataException expected) {
|
||||
assertThat(expected).hasMessage(
|
||||
"Nesting too deep at $.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.squareup.moshi;
|
||||
|
||||
import java.util.Arrays;
|
||||
import okio.Buffer;
|
||||
|
||||
final class TestUtil {
|
||||
@@ -23,6 +24,12 @@ final class TestUtil {
|
||||
return JsonReader.of(buffer);
|
||||
}
|
||||
|
||||
static String repeat(char c, int count) {
|
||||
char[] array = new char[count];
|
||||
Arrays.fill(array, c);
|
||||
return new String(array);
|
||||
}
|
||||
|
||||
private TestUtil() {
|
||||
throw new AssertionError("No instances.");
|
||||
}
|
||||
|
Reference in New Issue
Block a user