Implement JSON Path for JsonTreeReader.
This commit is contained in:
parent
ecaa57114f
commit
c2fae85a9f
@ -25,9 +25,7 @@ import com.google.gson.stream.JsonReader;
|
|||||||
import com.google.gson.stream.JsonToken;
|
import com.google.gson.stream.JsonToken;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,35 +45,57 @@ public final class JsonTreeReader extends JsonReader {
|
|||||||
};
|
};
|
||||||
private static final Object SENTINEL_CLOSED = new Object();
|
private static final Object SENTINEL_CLOSED = new Object();
|
||||||
|
|
||||||
private final List<Object> stack = new ArrayList<Object>();
|
/*
|
||||||
|
* The nesting stack. Using a manual array rather than an ArrayList saves 20%.
|
||||||
|
*/
|
||||||
|
private Object[] stack = new Object[32];
|
||||||
|
private int stackSize = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The path members. It corresponds directly to stack: At indices where the
|
||||||
|
* stack contains an object (EMPTY_OBJECT, DANGLING_NAME or NONEMPTY_OBJECT),
|
||||||
|
* pathNames contains the name at this scope. Where it contains an array
|
||||||
|
* (EMPTY_ARRAY, NONEMPTY_ARRAY) pathIndices contains the current index in
|
||||||
|
* that array. Otherwise the value is undefined, and we take advantage of that
|
||||||
|
* by incrementing pathIndices when doing so isn't useful.
|
||||||
|
*/
|
||||||
|
private String[] pathNames = new String[32];
|
||||||
|
private int[] pathIndices = new int[32];
|
||||||
|
|
||||||
public JsonTreeReader(JsonElement element) {
|
public JsonTreeReader(JsonElement element) {
|
||||||
super(UNREADABLE_READER);
|
super(UNREADABLE_READER);
|
||||||
stack.add(element);
|
push(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void beginArray() throws IOException {
|
@Override public void beginArray() throws IOException {
|
||||||
expect(JsonToken.BEGIN_ARRAY);
|
expect(JsonToken.BEGIN_ARRAY);
|
||||||
JsonArray array = (JsonArray) peekStack();
|
JsonArray array = (JsonArray) peekStack();
|
||||||
stack.add(array.iterator());
|
push(array.iterator());
|
||||||
|
pathIndices[stackSize - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void endArray() throws IOException {
|
@Override public void endArray() throws IOException {
|
||||||
expect(JsonToken.END_ARRAY);
|
expect(JsonToken.END_ARRAY);
|
||||||
popStack(); // empty iterator
|
popStack(); // empty iterator
|
||||||
popStack(); // array
|
popStack(); // array
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void beginObject() throws IOException {
|
@Override public void beginObject() throws IOException {
|
||||||
expect(JsonToken.BEGIN_OBJECT);
|
expect(JsonToken.BEGIN_OBJECT);
|
||||||
JsonObject object = (JsonObject) peekStack();
|
JsonObject object = (JsonObject) peekStack();
|
||||||
stack.add(object.entrySet().iterator());
|
push(object.entrySet().iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void endObject() throws IOException {
|
@Override public void endObject() throws IOException {
|
||||||
expect(JsonToken.END_OBJECT);
|
expect(JsonToken.END_OBJECT);
|
||||||
popStack(); // empty iterator
|
popStack(); // empty iterator
|
||||||
popStack(); // object
|
popStack(); // object
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean hasNext() throws IOException {
|
@Override public boolean hasNext() throws IOException {
|
||||||
@ -84,19 +104,19 @@ public final class JsonTreeReader extends JsonReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public JsonToken peek() throws IOException {
|
@Override public JsonToken peek() throws IOException {
|
||||||
if (stack.isEmpty()) {
|
if (stackSize == 0) {
|
||||||
return JsonToken.END_DOCUMENT;
|
return JsonToken.END_DOCUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object o = peekStack();
|
Object o = peekStack();
|
||||||
if (o instanceof Iterator) {
|
if (o instanceof Iterator) {
|
||||||
boolean isObject = stack.get(stack.size() - 2) instanceof JsonObject;
|
boolean isObject = stack[stackSize - 2] instanceof JsonObject;
|
||||||
Iterator<?> iterator = (Iterator<?>) o;
|
Iterator<?> iterator = (Iterator<?>) o;
|
||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
if (isObject) {
|
if (isObject) {
|
||||||
return JsonToken.NAME;
|
return JsonToken.NAME;
|
||||||
} else {
|
} else {
|
||||||
stack.add(iterator.next());
|
push(iterator.next());
|
||||||
return peek();
|
return peek();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -127,16 +147,19 @@ public final class JsonTreeReader extends JsonReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object peekStack() {
|
private Object peekStack() {
|
||||||
return stack.get(stack.size() - 1);
|
return stack[stackSize - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object popStack() {
|
private Object popStack() {
|
||||||
return stack.remove(stack.size() - 1);
|
Object result = stack[--stackSize];
|
||||||
|
stack[stackSize] = null;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expect(JsonToken expected) throws IOException {
|
private void expect(JsonToken expected) throws IOException {
|
||||||
if (peek() != expected) {
|
if (peek() != expected) {
|
||||||
throw new IllegalStateException("Expected " + expected + " but was " + peek());
|
throw new IllegalStateException(
|
||||||
|
"Expected " + expected + " but was " + peek() + locationString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,72 +167,101 @@ public final class JsonTreeReader extends JsonReader {
|
|||||||
expect(JsonToken.NAME);
|
expect(JsonToken.NAME);
|
||||||
Iterator<?> i = (Iterator<?>) peekStack();
|
Iterator<?> i = (Iterator<?>) peekStack();
|
||||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
|
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
|
||||||
stack.add(entry.getValue());
|
String result = (String) entry.getKey();
|
||||||
return (String) entry.getKey();
|
pathNames[stackSize - 1] = result;
|
||||||
|
push(entry.getValue());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String nextString() throws IOException {
|
@Override public String nextString() throws IOException {
|
||||||
JsonToken token = peek();
|
JsonToken token = peek();
|
||||||
if (token != JsonToken.STRING && token != JsonToken.NUMBER) {
|
if (token != JsonToken.STRING && token != JsonToken.NUMBER) {
|
||||||
throw new IllegalStateException("Expected " + JsonToken.STRING + " but was " + token);
|
throw new IllegalStateException(
|
||||||
|
"Expected " + JsonToken.STRING + " but was " + token + locationString());
|
||||||
}
|
}
|
||||||
return ((JsonPrimitive) popStack()).getAsString();
|
String result = ((JsonPrimitive) popStack()).getAsString();
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean nextBoolean() throws IOException {
|
@Override public boolean nextBoolean() throws IOException {
|
||||||
expect(JsonToken.BOOLEAN);
|
expect(JsonToken.BOOLEAN);
|
||||||
return ((JsonPrimitive) popStack()).getAsBoolean();
|
boolean result = ((JsonPrimitive) popStack()).getAsBoolean();
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void nextNull() throws IOException {
|
@Override public void nextNull() throws IOException {
|
||||||
expect(JsonToken.NULL);
|
expect(JsonToken.NULL);
|
||||||
popStack();
|
popStack();
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public double nextDouble() throws IOException {
|
@Override public double nextDouble() throws IOException {
|
||||||
JsonToken token = peek();
|
JsonToken token = peek();
|
||||||
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
|
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
|
||||||
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
|
throw new IllegalStateException(
|
||||||
|
"Expected " + JsonToken.NUMBER + " but was " + token + locationString());
|
||||||
}
|
}
|
||||||
double result = ((JsonPrimitive) peekStack()).getAsDouble();
|
double result = ((JsonPrimitive) peekStack()).getAsDouble();
|
||||||
if (!isLenient() && (Double.isNaN(result) || Double.isInfinite(result))) {
|
if (!isLenient() && (Double.isNaN(result) || Double.isInfinite(result))) {
|
||||||
throw new NumberFormatException("JSON forbids NaN and infinities: " + result);
|
throw new NumberFormatException("JSON forbids NaN and infinities: " + result);
|
||||||
}
|
}
|
||||||
popStack();
|
popStack();
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public long nextLong() throws IOException {
|
@Override public long nextLong() throws IOException {
|
||||||
JsonToken token = peek();
|
JsonToken token = peek();
|
||||||
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
|
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
|
||||||
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
|
throw new IllegalStateException(
|
||||||
|
"Expected " + JsonToken.NUMBER + " but was " + token + locationString());
|
||||||
}
|
}
|
||||||
long result = ((JsonPrimitive) peekStack()).getAsLong();
|
long result = ((JsonPrimitive) peekStack()).getAsLong();
|
||||||
popStack();
|
popStack();
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int nextInt() throws IOException {
|
@Override public int nextInt() throws IOException {
|
||||||
JsonToken token = peek();
|
JsonToken token = peek();
|
||||||
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
|
if (token != JsonToken.NUMBER && token != JsonToken.STRING) {
|
||||||
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
|
throw new IllegalStateException(
|
||||||
|
"Expected " + JsonToken.NUMBER + " but was " + token + locationString());
|
||||||
}
|
}
|
||||||
int result = ((JsonPrimitive) peekStack()).getAsInt();
|
int result = ((JsonPrimitive) peekStack()).getAsInt();
|
||||||
popStack();
|
popStack();
|
||||||
|
if (stackSize > 0) {
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void close() throws IOException {
|
@Override public void close() throws IOException {
|
||||||
stack.clear();
|
stack = new Object[] { SENTINEL_CLOSED };
|
||||||
stack.add(SENTINEL_CLOSED);
|
stackSize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void skipValue() throws IOException {
|
@Override public void skipValue() throws IOException {
|
||||||
if (peek() == JsonToken.NAME) {
|
if (peek() == JsonToken.NAME) {
|
||||||
nextName();
|
nextName();
|
||||||
|
pathNames[stackSize - 2] = "null";
|
||||||
} else {
|
} else {
|
||||||
popStack();
|
popStack();
|
||||||
|
pathNames[stackSize - 1] = "null";
|
||||||
}
|
}
|
||||||
|
pathIndices[stackSize - 1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String toString() {
|
@Override public String toString() {
|
||||||
@ -220,7 +272,45 @@ public final class JsonTreeReader extends JsonReader {
|
|||||||
expect(JsonToken.NAME);
|
expect(JsonToken.NAME);
|
||||||
Iterator<?> i = (Iterator<?>) peekStack();
|
Iterator<?> i = (Iterator<?>) peekStack();
|
||||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
|
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
|
||||||
stack.add(entry.getValue());
|
push(entry.getValue());
|
||||||
stack.add(new JsonPrimitive((String)entry.getKey()));
|
push(new JsonPrimitive((String) entry.getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void push(Object newTop) {
|
||||||
|
if (stackSize == stack.length) {
|
||||||
|
Object[] newStack = new Object[stackSize * 2];
|
||||||
|
int[] newPathIndices = new int[stackSize * 2];
|
||||||
|
String[] newPathNames = new String[stackSize * 2];
|
||||||
|
System.arraycopy(stack, 0, newStack, 0, stackSize);
|
||||||
|
System.arraycopy(pathIndices, 0, newPathIndices, 0, stackSize);
|
||||||
|
System.arraycopy(pathNames, 0, newPathNames, 0, stackSize);
|
||||||
|
stack = newStack;
|
||||||
|
pathIndices = newPathIndices;
|
||||||
|
pathNames = newPathNames;
|
||||||
|
}
|
||||||
|
stack[stackSize++] = newTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String getPath() {
|
||||||
|
StringBuilder result = new StringBuilder().append('$');
|
||||||
|
for (int i = 0; i < stackSize; i++) {
|
||||||
|
if (stack[i] instanceof JsonArray) {
|
||||||
|
if (stack[++i] instanceof Iterator) {
|
||||||
|
result.append('[').append(pathIndices[i]).append(']');
|
||||||
|
}
|
||||||
|
} else if (stack[i] instanceof JsonObject) {
|
||||||
|
if (stack[++i] instanceof Iterator) {
|
||||||
|
result.append('.');
|
||||||
|
if (pathNames[i] != null) {
|
||||||
|
result.append(pathNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String locationString() {
|
||||||
|
return " at path " + getPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,35 @@
|
|||||||
|
|
||||||
package com.google.gson.stream;
|
package com.google.gson.stream;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.internal.Streams;
|
||||||
|
import com.google.gson.internal.bind.JsonTreeReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import junit.framework.TestCase;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
import static junit.framework.Assert.assertEquals;
|
||||||
public class JsonReaderPathTest extends TestCase {
|
import static org.junit.Assume.assumeTrue;
|
||||||
public void testPath() throws IOException {
|
|
||||||
JsonReader reader = new JsonReader(
|
@RunWith(Parameterized.class)
|
||||||
new StringReader("{\"a\":[2,true,false,null,\"b\",{\"c\":\"d\"},[3]]}"));
|
public class JsonReaderPathTest {
|
||||||
|
@Parameterized.Parameters(name = "{0}")
|
||||||
|
public static List<Object[]> parameters() {
|
||||||
|
return Arrays.asList(
|
||||||
|
new Object[] { Factory.STRING_READER },
|
||||||
|
new Object[] { Factory.OBJECT_READER }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameterized.Parameter
|
||||||
|
public Factory factory;
|
||||||
|
|
||||||
|
@Test public void path() throws IOException {
|
||||||
|
JsonReader reader = factory.create("{\"a\":[2,true,false,null,\"b\",{\"c\":\"d\"},[3]]}");
|
||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
reader.beginObject();
|
reader.beginObject();
|
||||||
assertEquals("$.", reader.getPath());
|
assertEquals("$.", reader.getPath());
|
||||||
@ -62,8 +82,8 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testObjectPath() throws IOException {
|
@Test public void objectPath() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("{\"a\":1,\"b\":2}"));
|
JsonReader reader = factory.create("{\"a\":1,\"b\":2}");
|
||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
|
|
||||||
reader.peek();
|
reader.peek();
|
||||||
@ -102,8 +122,8 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testArrayPath() throws IOException {
|
@Test public void arrayPath() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("[1,2]"));
|
JsonReader reader = factory.create("[1,2]");
|
||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
|
|
||||||
reader.peek();
|
reader.peek();
|
||||||
@ -132,8 +152,10 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMultipleTopLevelValuesInOneDocument() throws IOException {
|
@Test public void multipleTopLevelValuesInOneDocument() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("[][]"));
|
assumeTrue(factory == Factory.STRING_READER);
|
||||||
|
|
||||||
|
JsonReader reader = factory.create("[][]");
|
||||||
reader.setLenient(true);
|
reader.setLenient(true);
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
reader.endArray();
|
reader.endArray();
|
||||||
@ -143,24 +165,25 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSkipArrayElements() throws IOException {
|
@Test public void skipArrayElements() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("[1,2,3]"));
|
JsonReader reader = factory.create("[1,2,3]");
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
assertEquals("$[2]", reader.getPath());
|
assertEquals("$[2]", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSkipObjectNames() throws IOException {
|
@Test public void skipObjectNames() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("{\"a\":1}"));
|
JsonReader reader = factory.create("{\"a\":1}");
|
||||||
reader.beginObject();
|
reader.beginObject();
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
assertEquals("$.null", reader.getPath());
|
assertEquals("$.null", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSkipObjectValues() throws IOException {
|
@Test public void skipObjectValues() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("{\"a\":1,\"b\":2}"));
|
JsonReader reader = factory.create("{\"a\":1,\"b\":2}");
|
||||||
reader.beginObject();
|
reader.beginObject();
|
||||||
|
assertEquals("$.", reader.getPath());
|
||||||
reader.nextName();
|
reader.nextName();
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
assertEquals("$.null", reader.getPath());
|
assertEquals("$.null", reader.getPath());
|
||||||
@ -168,15 +191,15 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
assertEquals("$.b", reader.getPath());
|
assertEquals("$.b", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSkipNestedStructures() throws IOException {
|
@Test public void skipNestedStructures() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("[[1,2,3],4]"));
|
JsonReader reader = factory.create("[[1,2,3],4]");
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
assertEquals("$[1]", reader.getPath());
|
assertEquals("$[1]", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testArrayOfObjects() throws IOException {
|
@Test public void arrayOfObjects() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("[{},{},{}]"));
|
JsonReader reader = factory.create("[{},{},{}]");
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
assertEquals("$[0]", reader.getPath());
|
assertEquals("$[0]", reader.getPath());
|
||||||
reader.beginObject();
|
reader.beginObject();
|
||||||
@ -195,8 +218,8 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testArrayOfArrays() throws IOException {
|
@Test public void arrayOfArrays() throws IOException {
|
||||||
JsonReader reader = new JsonReader(new StringReader("[[],[],[]]"));
|
JsonReader reader = factory.create("[[],[],[]]");
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
assertEquals("$[0]", reader.getPath());
|
assertEquals("$[0]", reader.getPath());
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
@ -214,4 +237,20 @@ public class JsonReaderPathTest extends TestCase {
|
|||||||
reader.endArray();
|
reader.endArray();
|
||||||
assertEquals("$", reader.getPath());
|
assertEquals("$", reader.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Factory {
|
||||||
|
STRING_READER {
|
||||||
|
@Override public JsonReader create(String data) {
|
||||||
|
return new JsonReader(new StringReader(data));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
OBJECT_READER {
|
||||||
|
@Override public JsonReader create(String data) {
|
||||||
|
JsonElement element = Streams.parse(new JsonReader(new StringReader(data)));
|
||||||
|
return new JsonTreeReader(element);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract JsonReader create(String data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
pom.xml
2
pom.xml
@ -51,7 +51,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.2</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
Loading…
Reference in New Issue
Block a user