Remove EOFException special casing of JsonStreamParser.next() (#2281)
* Remove EOFException special casing of JsonStreamParser.next() The previous behavior violated the Iterator contract where for `JsonStreamParser("[")` a call to `hasNext()` would return true, but `next()` would throw a NoSuchElementException. * Fix incorrect documented thrown exception type for JsonStreamParser
This commit is contained in:
parent
6c3cf22435
commit
f63a1b85ae
@ -15,18 +15,16 @@
|
||||
*/
|
||||
package com.google.gson;
|
||||
|
||||
import java.io.EOFException;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
|
||||
/**
|
||||
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
|
||||
* asynchronously. The JSON data is parsed in lenient mode, see also
|
||||
@ -61,7 +59,7 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
|
||||
public JsonStreamParser(String json) {
|
||||
this(new StringReader(json));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param reader The data stream containing JSON elements concatenated to each other.
|
||||
* @since 1.4
|
||||
@ -71,13 +69,13 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
|
||||
parser.setLenient(true);
|
||||
lock = new Object();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the next available {@link JsonElement} on the reader. Throws a
|
||||
* {@link NoSuchElementException} if no element is available.
|
||||
*
|
||||
* @return the next available {@code JsonElement} on the reader.
|
||||
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
|
||||
* @throws JsonParseException if the incoming stream is malformed JSON.
|
||||
* @throws NoSuchElementException if no {@code JsonElement} is available.
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -86,22 +84,20 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
return Streams.parse(parser);
|
||||
} catch (StackOverflowError e) {
|
||||
throw new JsonParseException("Failed parsing JSON source to Json", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new JsonParseException("Failed parsing JSON source to Json", e);
|
||||
} catch (JsonParseException e) {
|
||||
throw e.getCause() instanceof EOFException ? new NoSuchElementException() : e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a {@link JsonElement} is available on the input for consumption
|
||||
* @return true if a {@link JsonElement} is available on the input, false otherwise
|
||||
* @throws JsonSyntaxException if the incoming stream is malformed JSON.
|
||||
* @throws JsonParseException if the incoming stream is malformed JSON.
|
||||
* @since 1.4
|
||||
*/
|
||||
@Override
|
||||
|
@ -15,24 +15,30 @@
|
||||
*/
|
||||
package com.google.gson;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.util.NoSuchElementException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JsonStreamParser}
|
||||
*
|
||||
*
|
||||
* @author Inderjeet Singh
|
||||
*/
|
||||
public class JsonStreamParserTest extends TestCase {
|
||||
public class JsonStreamParserTest {
|
||||
private JsonStreamParser parser;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
parser = new JsonStreamParser("'one' 'two'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTwoStrings() {
|
||||
String actualOne = parser.next().getAsString();
|
||||
assertEquals("one", actualOne);
|
||||
@ -40,6 +46,7 @@ public class JsonStreamParserTest extends TestCase {
|
||||
assertEquals("two", actualTwo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() {
|
||||
assertTrue(parser.hasNext());
|
||||
assertEquals("one", parser.next().getAsString());
|
||||
@ -48,20 +55,22 @@ public class JsonStreamParserTest extends TestCase {
|
||||
assertFalse(parser.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSideEffectForHasNext() throws Exception {
|
||||
assertTrue(parser.hasNext());
|
||||
assertTrue(parser.hasNext());
|
||||
assertTrue(parser.hasNext());
|
||||
assertEquals("one", parser.next().getAsString());
|
||||
|
||||
|
||||
assertTrue(parser.hasNext());
|
||||
assertTrue(parser.hasNext());
|
||||
assertEquals("two", parser.next().getAsString());
|
||||
|
||||
|
||||
assertFalse(parser.hasNext());
|
||||
assertFalse(parser.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallingNextBeyondAvailableInput() {
|
||||
parser.next();
|
||||
parser.next();
|
||||
@ -71,4 +80,51 @@ public class JsonStreamParserTest extends TestCase {
|
||||
} catch (NoSuchElementException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyInput() {
|
||||
JsonStreamParser parser = new JsonStreamParser("");
|
||||
try {
|
||||
parser.next();
|
||||
fail();
|
||||
} catch (JsonIOException e) {
|
||||
assertTrue(e.getCause() instanceof EOFException);
|
||||
}
|
||||
|
||||
parser = new JsonStreamParser("");
|
||||
try {
|
||||
parser.hasNext();
|
||||
fail();
|
||||
} catch (JsonIOException e) {
|
||||
assertTrue(e.getCause() instanceof EOFException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncompleteInput() {
|
||||
JsonStreamParser parser = new JsonStreamParser("[");
|
||||
assertTrue(parser.hasNext());
|
||||
try {
|
||||
parser.next();
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedInput() {
|
||||
JsonStreamParser parser = new JsonStreamParser(":");
|
||||
try {
|
||||
parser.hasNext();
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
}
|
||||
|
||||
parser = new JsonStreamParser(":");
|
||||
try {
|
||||
parser.next();
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user