JsonParserTest.java
package zserio.runtime.json;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
public class JsonParserTest
{
@Test
public void empty() throws IOException
{
final Reader reader = new StringReader("");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
assertTrue(jsonParser.parse());
assertEquals(0, observer.getReport().size());
reader.close();
}
@Test
public void oneString() throws IOException
{
final Reader reader = new StringReader("\"text\"");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
assertTrue(jsonParser.parse());
assertEquals(1, observer.getReport().size());
assertEquals("visitValue: text", observer.getReport().get(0));
reader.close();
}
@Test
public void twoStrings() throws IOException
{
final Reader reader = new StringReader("\"text\"\"second\"");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
assertFalse(jsonParser.parse());
assertEquals(1, observer.getReport().size());
assertEquals("visitValue: text", observer.getReport().get(0));
assertEquals(1, jsonParser.getLine());
assertEquals(7, jsonParser.getColumn());
assertTrue(jsonParser.parse());
assertEquals(2, observer.getReport().size());
assertEquals("visitValue: second", observer.getReport().get(1));
assertEquals(1, jsonParser.getLine());
assertEquals(15, jsonParser.getColumn());
reader.close();
}
@Test
public void parse() throws IOException
{
final Reader reader = new StringReader("{\"array\":\n[\n{\"key1\":\n10, \"key2\":\n\"text\"}, {}]}");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
assertTrue(jsonParser.parse());
assertEquals(13, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
assertEquals("visitKey: array", observer.getReport().get(1));
assertEquals("beginArray", observer.getReport().get(2));
assertEquals("beginObject", observer.getReport().get(3));
assertEquals("visitKey: key1", observer.getReport().get(4));
assertEquals("visitValue: 10", observer.getReport().get(5));
assertEquals("visitKey: key2", observer.getReport().get(6));
assertEquals("visitValue: text", observer.getReport().get(7));
assertEquals("endObject", observer.getReport().get(8));
assertEquals("beginObject", observer.getReport().get(9));
assertEquals("endObject", observer.getReport().get(10));
assertEquals("endArray", observer.getReport().get(11));
assertEquals("endObject", observer.getReport().get(12));
reader.close();
}
@Test
public void unexpectedObject() throws IOException
{
final Reader reader = new StringReader("{\n\n{\n\n");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
final JsonParserError exception = assertThrows(JsonParserError.class, () -> jsonParser.parse());
assertEquals("JsonParser:3:1: Unexpected token: BEGIN_OBJECT ('{'), expecting END_OBJECT!",
exception.getMessage());
assertEquals(1, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
reader.close();
}
@Test
public void unexpectedObjectAfterItemSeparator() throws IOException
{
final Reader reader = new StringReader("{\n \"key\": 10,\n {\n");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
final JsonParserError exception = assertThrows(JsonParserError.class, () -> jsonParser.parse());
assertEquals("JsonParser:3:3: Unexpected token: BEGIN_OBJECT ('{'), expecting VALUE!",
exception.getMessage());
assertEquals(3, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
assertEquals("visitKey: key", observer.getReport().get(1));
assertEquals("visitValue: 10", observer.getReport().get(2));
reader.close();
}
@Test
public void missingObjectItemSeparator() throws IOException
{
final Reader reader = new StringReader("{\n\"item1\":\"text\"\n\"item2\":\"text\"\n}");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
final JsonParserError exception = assertThrows(JsonParserError.class, () -> jsonParser.parse());
assertEquals("JsonParser:3:1: Unexpected token: VALUE ('item2'), expecting END_OBJECT!",
exception.getMessage());
assertEquals(3, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
assertEquals("visitKey: item1", observer.getReport().get(1));
assertEquals("visitValue: text", observer.getReport().get(2));
reader.close();
}
@Test
public void wrongKeyType() throws IOException
{
final Reader reader = new StringReader("{\n10:\"text\"\n}");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
final JsonParserError exception = assertThrows(JsonParserError.class, () -> jsonParser.parse());
assertEquals("JsonParser:2:1: Key must be a string value!", exception.getMessage());
assertEquals(1, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
reader.close();
}
@Test
public void unexpectedElementToken() throws IOException
{
final Reader reader = new StringReader("{\n\"item\":}");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
final JsonParserError exception = assertThrows(JsonParserError.class, () -> jsonParser.parse());
assertEquals("JsonParser:2:8: Unexpected token: END_OBJECT ('}'), expecting one of "
+ "[BEGIN_OBJECT, BEGIN_ARRAY, VALUE]!",
exception.getMessage());
assertEquals(2, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
assertEquals("visitKey: item", observer.getReport().get(1));
reader.close();
}
@Test
public void missingArrayElementSeparator() throws IOException
{
final Reader reader = new StringReader("{\n\"array\":\n[10\n20\n]}");
final DummyObserver observer = new DummyObserver();
final JsonParser jsonParser = new JsonParser(reader, observer);
final JsonParserError exception = assertThrows(JsonParserError.class, () -> jsonParser.parse());
assertEquals(
"JsonParser:4:1: Unexpected token: VALUE ('20'), expecting END_ARRAY!", exception.getMessage());
assertEquals(4, observer.getReport().size());
assertEquals("beginObject", observer.getReport().get(0));
assertEquals("visitKey: array", observer.getReport().get(1));
assertEquals("beginArray", observer.getReport().get(2));
assertEquals("visitValue: 10", observer.getReport().get(3));
reader.close();
}
private static class DummyObserver implements JsonParser.Observer
{
public List<String> getReport()
{
return report;
}
@Override
public void beginObject()
{
report.add("beginObject");
}
@Override
public void endObject()
{
report.add("endObject");
}
@Override
public void beginArray()
{
report.add("beginArray");
}
@Override
public void endArray()
{
report.add("endArray");
}
@Override
public void visitKey(String key)
{
report.add("visitKey: " + key);
}
@Override
public void visitValue(Object value)
{
report.add("visitValue: " + value.toString());
}
private final List<String> report = new ArrayList<String>();
};
}