Write some tests prescribed by missing code coverage. I found a bug where our nonexecute prefix code causes a problem.

This commit is contained in:
Jesse Wilson 2012-02-11 20:15:39 +00:00
parent dd86d63436
commit 7b75efd09e
2 changed files with 175 additions and 11 deletions

View File

@ -401,6 +401,9 @@ public class JsonReader implements Closeable {
* Consumes the non-execute prefix if it exists.
*/
private void consumeNonExecutePrefix() throws IOException {
// TODO: there's a bug here. We're going to call nextNonWhitespace and we have a character that
// we can't necessarily push back (because pos could be 0)
// fast forward through the leading whitespace
nextNonWhitespace(true);
pos--;
@ -1122,7 +1125,8 @@ public class JsonReader implements Closeable {
}
@Override public String toString() {
return getClass().getSimpleName() + " near " + getSnippet();
return getClass().getSimpleName()
+ " at line " + getLineNumber() + " column " + getColumnNumber();
}
/**
@ -1299,15 +1303,6 @@ public class JsonReader implements Closeable {
+ " at line " + getLineNumber() + " column " + getColumnNumber());
}
private CharSequence getSnippet() {
StringBuilder snippet = new StringBuilder();
int beforePos = Math.min(pos, 20);
snippet.append(buffer, pos - beforePos, beforePos);
int afterPos = Math.min(limit - pos, 20);
snippet.append(buffer, pos, afterPos);
return snippet;
}
static {
JsonReaderInternalAccess.INSTANCE = new JsonReaderInternalAccess() {
@Override public void promoteNameToValue(JsonReader reader) throws IOException {

View File

@ -16,6 +16,7 @@
package com.google.gson.stream;
import java.io.EOFException;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
@ -183,6 +184,17 @@ public final class JsonReaderTest extends TestCase {
}
}
public void testUnescapingTruncatedSequence() throws IOException {
String json = "[\"\\";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
try {
reader.nextString();
fail();
} catch (IOException expected) {
}
}
public void testIntegersWithFractionalPartSpecified() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[1.0,1.0,1.0]"));
reader.beginArray();
@ -227,6 +239,17 @@ public final class JsonReaderTest extends TestCase {
}
}
public void testStrictQuotedNonFiniteDoubles() throws IOException {
String json = "[\"NaN\"]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
try {
reader.nextDouble();
fail();
} catch (MalformedJsonException expected) {
}
}
public void testLenientNonFiniteDoubles() throws IOException {
String json = "[NaN, -Infinity, Infinity]";
JsonReader reader = new JsonReader(new StringReader(json));
@ -238,6 +261,17 @@ public final class JsonReaderTest extends TestCase {
reader.endArray();
}
public void testLenientQuotedNonFiniteDoubles() throws IOException {
String json = "[\"NaN\", \"-Infinity\", \"Infinity\"]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(true);
reader.beginArray();
assertTrue(Double.isNaN(reader.nextDouble()));
assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
reader.endArray();
}
public void testStrictNonFiniteDoublesWithSkipValue() throws IOException {
String json = "[NaN]";
JsonReader reader = new JsonReader(new StringReader(json));
@ -1008,7 +1042,7 @@ public final class JsonReaderTest extends TestCase {
testFailWithPosition("Expected literal value at line 1 column 4",
"\ufeff[0,}]");
}
private void testFailWithPosition(String message, String json) throws IOException {
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
@ -1020,6 +1054,141 @@ public final class JsonReaderTest extends TestCase {
assertEquals(message, expected.getMessage());
}
}
public void testDeeplyNestedArrays() throws IOException {
// this is nested 40 levels deep; Gson is tuned for nesting is 30 levels deep or fewer
JsonReader reader = new JsonReader(new StringReader(
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"));
for (int i = 0; i < 40; i++) {
reader.beginArray();
}
for (int i = 0; i < 40; i++) {
reader.endArray();
}
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testDeeplyNestedObjects() throws IOException {
// Build a JSON document structured like {"a":{"a":{"a":{"a":true}}}}, but 40 levels deep
String array = "{\"a\":%s}";
String json = "true";
for (int i = 0; i < 40; i++) {
json = String.format(array, json);
}
JsonReader reader = new JsonReader(new StringReader(json));
for (int i = 0; i < 40; i++) {
reader.beginObject();
assertEquals("a", reader.nextName());
}
assertEquals(true, reader.nextBoolean());
for (int i = 0; i < 40; i++) {
reader.endObject();
}
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
// http://code.google.com/p/google-gson/issues/detail?id=409
public void testStringEndingInSlash() throws IOException {
JsonReader reader = new JsonReader(new StringReader("/"));
reader.setLenient(true);
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testStringWithLeadingSlash() throws IOException {
JsonReader reader = new JsonReader(new StringReader("/x"));
reader.setLenient(true);
try {
reader.peek();
fail();
} catch (MalformedJsonException expected) {
}
}
public void testUnterminatedObject() throws IOException {
JsonReader reader = new JsonReader(new StringReader("{\"a\":\"android\"x"));
reader.setLenient(true);
reader.beginObject();
assertEquals("a", reader.nextName());
assertEquals("android", reader.nextString());
try {
reader.peek();
fail();
} catch (MalformedJsonException expected) {
}
}
public void testVeryLongQuotedString() throws IOException {
char[] stringChars = new char[1024 * 16];
Arrays.fill(stringChars, 'x');
String string = new String(stringChars);
String json = "[\"" + string + "\"]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
assertEquals(string, reader.nextString());
reader.endArray();
}
public void testVeryLongUnquotedString() throws IOException {
char[] stringChars = new char[1024 * 16];
Arrays.fill(stringChars, 'x');
String string = new String(stringChars);
String json = "[" + string + "]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(true);
reader.beginArray();
assertEquals(string, reader.nextString());
reader.endArray();
}
public void testVeryLongUnterminatedString() throws IOException {
char[] stringChars = new char[1024 * 16];
Arrays.fill(stringChars, 'x');
String string = new String(stringChars);
String json = "[" + string;
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(true);
reader.beginArray();
assertEquals(string, reader.nextString());
try {
reader.peek();
fail();
} catch (EOFException expected) {
}
}
public void testSkipVeryLongUnquotedString() throws IOException {
char[] stringChars = new char[1024 * 16];
Arrays.fill(stringChars, 'x');
String string = new String(stringChars);
String json = "[" + string + "]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(true);
reader.beginArray();
reader.skipValue();
reader.endArray();
}
public void testStringAsNumberWithTruncatedExponent() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[123e]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.STRING, reader.peek());
}
public void testStringAsNumberWithDigitAndNonDigitExponent() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[123e4b]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.STRING, reader.peek());
}
public void testStringAsNumberWithNonDigitExponent() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[123eb]"));
reader.setLenient(true);
reader.beginArray();
assertEquals(JsonToken.STRING, reader.peek());
}
private String repeat(char c, int count) {
char[] array = new char[count];