added support for maps
This commit is contained in:
parent
b72935960f
commit
52def01e5f
21 changed files with 298 additions and 90 deletions
87
pom.xml
Normal file
87
pom.xml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<name>JsonToy2</name>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<groupId>nl.sander</groupId>
|
||||
<artifactId>jsontoy2</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.26.0-GA</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.30</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.10.19</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.10.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -16,7 +16,6 @@ public class IoReader {
|
|||
private boolean encoded = false;
|
||||
private byte current;
|
||||
private int linecount = 0;
|
||||
private long charcount = 0;
|
||||
|
||||
protected IoReader(InputStream inputStream) {
|
||||
this.inputStream = inputStream;
|
||||
|
|
@ -93,11 +92,11 @@ public class IoReader {
|
|||
}
|
||||
|
||||
public List<?> readList() {
|
||||
List<Object> list = new ArrayList<>();
|
||||
|
||||
skipWhitespace();
|
||||
if (current != '[') {
|
||||
throw new JsonReadException("no list found");
|
||||
}
|
||||
List<Object> list = new ArrayList<>();
|
||||
advance();
|
||||
while (current != -1 && current != ']') {
|
||||
Optional<Object> maybeValue = readValue();
|
||||
|
|
@ -105,17 +104,39 @@ public class IoReader {
|
|||
break;
|
||||
} else {
|
||||
list.add(maybeValue.get());
|
||||
eatUntilAny(',');
|
||||
eatUntil(',');
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public Map<?, ?> readMap() {
|
||||
HashMap<Object, Object> map = new HashMap<>();
|
||||
skipWhitespace();
|
||||
if (current != '{') {
|
||||
throw new JsonReadException("no map found");
|
||||
}
|
||||
while (current != -1 && current != '}') {
|
||||
skipWhitespace();
|
||||
if (current == '"') {
|
||||
String key = readString();
|
||||
eatUntil(':');
|
||||
skipWhitespace();
|
||||
Optional<Object> maybeValue = readValue();
|
||||
maybeValue.ifPresent(o -> map.put(key, o));
|
||||
eatUntil(',');
|
||||
} else {
|
||||
advance();
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Optional<Object> readValue() {
|
||||
Object value;
|
||||
skipWhitespace();
|
||||
if (current == ']') {
|
||||
if (current == ']' || current == '}') {
|
||||
return Optional.empty();
|
||||
} else if (current == '[') {
|
||||
value = readList();
|
||||
|
|
@ -137,10 +158,6 @@ public class IoReader {
|
|||
return Optional.of(value);
|
||||
}
|
||||
|
||||
private Map<?, ?> readMap() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public String readString() {
|
||||
eatUntil('\"');
|
||||
|
||||
|
|
@ -158,7 +175,7 @@ public class IoReader {
|
|||
endOfString = true;
|
||||
}
|
||||
} else {
|
||||
// json encoded string
|
||||
// unicode codepoint
|
||||
if (current == 'u') {
|
||||
encoded = true;
|
||||
} else if (current == 'n') {
|
||||
|
|
@ -172,7 +189,7 @@ public class IoReader {
|
|||
throw new JsonReadException("illegal escaped quote in line " + linecount);
|
||||
} else {
|
||||
if (encoded) {
|
||||
// load next 4 characters in special buffer
|
||||
// load next 4 characters in special buffer to convert to int
|
||||
encodedCodePointBuffer.add(current);
|
||||
if (encodedCodePointBuffer.length() == 4) {
|
||||
byte[] bytes = parseCodePoint();
|
||||
|
|
@ -201,7 +218,6 @@ public class IoReader {
|
|||
void advance() {
|
||||
try {
|
||||
current = (byte) inputStream.read();
|
||||
System.out.println((charcount++) + ":" + (char) current);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
|
@ -230,24 +246,4 @@ public class IoReader {
|
|||
advance();
|
||||
return characterBuffer.toString();
|
||||
}
|
||||
|
||||
String eatUntilAny(char... untilOrrChars) {
|
||||
characterBuffer.clear();
|
||||
|
||||
while (current > -1 && (!contains(untilOrrChars, current) | Character.isWhitespace(current))) {
|
||||
characterBuffer.add(current);
|
||||
advance();
|
||||
}
|
||||
advance();
|
||||
return characterBuffer.toString();
|
||||
}
|
||||
|
||||
private boolean contains(char[] chars, byte search) {
|
||||
for (char aChar : chars) {
|
||||
if (search == aChar) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import java.io.InputStream;
|
|||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
|
@ -13,7 +14,7 @@ import java.util.concurrent.ConcurrentMap;
|
|||
* public facade
|
||||
*/
|
||||
public class JsonReader {
|
||||
private static final ConcurrentMap<Class<?>, JsonObjectReader<?>> readers = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<Class<?>, JsonValueReader<?>> readers = new ConcurrentHashMap<>();
|
||||
|
||||
public static <T> T read(Class<T> type, InputStream reader) {
|
||||
return read(type, new IoReader(reader));
|
||||
|
|
@ -29,11 +30,11 @@ public class JsonReader {
|
|||
// class.cast() does not work for primitives;
|
||||
}
|
||||
|
||||
private static <T> JsonObjectReader<?> getReader(Class<T> type) {
|
||||
private static <T> JsonValueReader<?> getReader(Class<T> type) {
|
||||
return readers.get(type);
|
||||
}
|
||||
|
||||
static <T> void register(Class<T> type, JsonObjectReader<T> objectReader) {
|
||||
static <T> void register(Class<T> type, JsonValueReader<T> objectReader) {
|
||||
readers.put(type, objectReader);
|
||||
}
|
||||
|
||||
|
|
@ -58,5 +59,6 @@ public class JsonReader {
|
|||
register(String.class, new StringReader());
|
||||
register(LocalDateTime.class, new LocalDateTimeReader());
|
||||
register(List.class, new ListReader());
|
||||
register(Map.class, new MapReader());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@ package nl.sander.jsontoy2;
|
|||
|
||||
import java.io.Reader;
|
||||
|
||||
public interface JsonObjectReader<T> {
|
||||
public interface JsonValueReader<T> {
|
||||
T read(IoReader ioReader);
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class BooleanReader implements nl.sander.jsontoy2.JsonObjectReader<Boolean> {
|
||||
public class BooleanReader implements JsonValueReader<Boolean> {
|
||||
@Override
|
||||
public Boolean read(IoReader ioReader) {
|
||||
return ioReader.readBoolean();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class ByteReader implements JsonObjectReader<Byte> {
|
||||
public class ByteReader implements JsonValueReader<Byte> {
|
||||
@Override
|
||||
public Byte read(IoReader ioReader) {
|
||||
return ioReader.readByte();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class CharReader implements JsonObjectReader<Character> {
|
||||
public class CharReader implements JsonValueReader<Character> {
|
||||
@Override
|
||||
public Character read(IoReader ioReader) {
|
||||
return ioReader.readCharacter();
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateReader extends AbstractDatesReader<Date> implements JsonObjectReader<Date> {
|
||||
public class DateReader extends AbstractDatesReader<Date> implements JsonValueReader<Date> {
|
||||
|
||||
@Override
|
||||
public Date read(IoReader ioReader) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
import java.io.Reader;
|
||||
|
||||
public class DoubleReader implements JsonObjectReader<Double> {
|
||||
public class DoubleReader implements JsonValueReader<Double> {
|
||||
@Override
|
||||
public Double read(IoReader ioReader) {
|
||||
return ioReader.readDouble();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class FloatReader implements JsonObjectReader<Float> {
|
||||
public class FloatReader implements JsonValueReader<Float> {
|
||||
@Override
|
||||
public Float read(IoReader ioReader) {
|
||||
return ioReader.readFloat();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class IntegerReader implements JsonObjectReader<Integer> {
|
||||
public class IntegerReader implements JsonValueReader<Integer> {
|
||||
@Override
|
||||
public Integer read(IoReader ioReader) {
|
||||
return ioReader.readInteger();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ListReader implements JsonObjectReader<List> {
|
||||
public class ListReader implements JsonValueReader<List> {
|
||||
@Override
|
||||
public List<?> read(IoReader ioReader) {
|
||||
return ioReader.readList();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
public class LocalDateTimeReader extends AbstractDatesReader<LocalDateTime> implements JsonObjectReader<LocalDateTime> {
|
||||
public class LocalDateTimeReader extends AbstractDatesReader<LocalDateTime> implements JsonValueReader<LocalDateTime> {
|
||||
|
||||
@Override
|
||||
public LocalDateTime read(IoReader ioReader) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class LongReader implements JsonObjectReader<Long> {
|
||||
public class LongReader implements JsonValueReader<Long> {
|
||||
@Override
|
||||
public Long read(IoReader ioReader) {
|
||||
return ioReader.readLong();
|
||||
|
|
|
|||
13
src/main/java/nl/sander/jsontoy2/readers/MapReader.java
Normal file
13
src/main/java/nl/sander/jsontoy2/readers/MapReader.java
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MapReader implements JsonValueReader<Map> {
|
||||
@Override
|
||||
public Map read(IoReader ioReader) {
|
||||
return ioReader.readMap();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class ShortReader implements JsonObjectReader<Short> {
|
||||
public class ShortReader implements JsonValueReader<Short> {
|
||||
|
||||
@Override
|
||||
public Short read(IoReader ioReader) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package nl.sander.jsontoy2.readers;
|
||||
|
||||
import nl.sander.jsontoy2.IoReader;
|
||||
import nl.sander.jsontoy2.JsonObjectReader;
|
||||
import nl.sander.jsontoy2.JsonValueReader;
|
||||
|
||||
public class StringReader implements JsonObjectReader<String> {
|
||||
public class StringReader implements JsonValueReader<String> {
|
||||
|
||||
@Override
|
||||
public String read(IoReader ioReader) {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,7 @@ package nl.sander.jsontoy2;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
|
@ -15,54 +12,61 @@ public class Lists {
|
|||
@Test
|
||||
public void emptyList() {
|
||||
List<String> list = JsonReader.read(List.class, "[]");
|
||||
assertEquals(new ArrayList<>(), list);
|
||||
assertEquals(List.of(), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleStringList() {
|
||||
List<String> list = JsonReader.read(List.class, "[\"hello jason\"]");
|
||||
assertEquals(Collections.singletonList("hello jason"), list);
|
||||
assertEquals(List.of("hello jason"), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleStringList() {
|
||||
List<String> list = JsonReader.read(List.class, "[\"hello\" , \"jason\"]");
|
||||
List<String> expected = Arrays.asList("hello", "jason");
|
||||
List<String> expected = List.of("hello", "jason");
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleStrings_noComma_error() {
|
||||
List<String> list = JsonReader.read(List.class, "[\"hello\" \"jason\"]");
|
||||
List<String> expected = Collections.singletonList("hello");
|
||||
List<String> list = JsonReader.read(List.class, " [\"hello\" \"jason\"]");
|
||||
List<String> expected = List.of("hello");
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleInt() {
|
||||
List<Integer> list = JsonReader.read(List.class, "[1]");
|
||||
List<Integer> expected = Collections.singletonList(1);
|
||||
List<Integer> list = JsonReader.read(List.class, " [ 1 ]");
|
||||
List<Integer> expected = List.of(1);
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleInts() {
|
||||
List<Integer> list = JsonReader.read(List.class, "[1,2]");
|
||||
List<Integer> expected = Arrays.asList(1,2);
|
||||
List<Integer> expected = List.of(1, 2);
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intDoubleBooleanString() {
|
||||
List<Integer> list = JsonReader.read(List.class, "[1,2.5,false,\"hello jason\"]");
|
||||
List<?> expected = Arrays.asList(1,2.5,false,"hello jason");
|
||||
List<Integer> list = JsonReader.read(List.class, "[1, 2.5,false, \"hello jason\"]");
|
||||
List<?> expected = List.of(1, 2.5, false, "hello jason");
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nestedList() {
|
||||
List<Integer> list = JsonReader.read(List.class, "[[],[]]");
|
||||
List<?> expected = Arrays.asList(List.of(), List.of());
|
||||
List<?> expected = List.of(List.of(), List.of());
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapInList() {
|
||||
List<Object> list = JsonReader.read(List.class, "[[],{\"list\":[]]}]");
|
||||
List<?> expected = List.of(List.of(), Map.of("list",List.of()));
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
}
|
||||
66
src/test/java/nl/sander/jsontoy2/Maps.java
Normal file
66
src/test/java/nl/sander/jsontoy2/Maps.java
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package nl.sander.jsontoy2;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class Maps {
|
||||
|
||||
@Test
|
||||
public void emptyMap() {
|
||||
Map<Object, Object> map = JsonReader.read(Map.class, "{}");
|
||||
assertEquals(new HashMap<>(), map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleStringKeyValueMap() {
|
||||
Map<String, String> map = JsonReader.read(Map.class, "{\"message\": \"hello jason\"}");
|
||||
assertEquals(Collections.singletonMap("message", "hello jason"), map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleValues() {
|
||||
Map<String, Object> map = JsonReader.read(Map.class, "{\"value1\" : \"jason\" ,\n \"value2\":1}");
|
||||
Map<String, Object> expected = new HashMap<>();
|
||||
expected.put("value1", "jason");
|
||||
expected.put("value2", 1);
|
||||
assertEquals(expected, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleStrings_noColon_error() {
|
||||
assertThrows(JsonReadException.class, () -> JsonReader.read(Map.class, " {\"hello\" \"jason\"}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleInts() {
|
||||
Map<String,Integer> map = JsonReader.read(Map.class, " { \"1\":2 }");
|
||||
Map<String,Integer> expected = Collections.singletonMap("1",2);
|
||||
assertEquals(expected, map);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("raw")
|
||||
public void nestedMap() {
|
||||
Map<String,Map> list = JsonReader.read(Map.class, "{\"map\": {\"map\":{}}}");
|
||||
Map<String,Map> expected = new HashMap<>();
|
||||
HashMap<String,Map> n1 = new HashMap<>();
|
||||
n1.put("map",new HashMap<>());
|
||||
expected.put("map", n1);
|
||||
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listInMap(){
|
||||
Map<String,List> list = JsonReader.read(Map.class, " { \"list\" : [ 1 ] } ");
|
||||
Map<String,List> expected = new HashMap<>();
|
||||
expected.put("list", List.of(1));
|
||||
|
||||
assertEquals(expected, list);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,7 @@ package nl.sander.jsontoy2;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
|
@ -29,7 +24,7 @@ public class Strings {
|
|||
|
||||
@Test
|
||||
public void incompleteSurrogateAndEscapeValid() {
|
||||
String value = JsonReader.read(String.class, "\"\\uD800\n\"");
|
||||
String value = JsonReader.read(String.class, " \"\\uD800\n\"");
|
||||
assertEquals("\u0000\u0000<EFBFBD>\u0000\n", value);
|
||||
}
|
||||
|
||||
|
|
@ -37,18 +32,18 @@ public class Strings {
|
|||
public void firstValidSurrogateSecondInvalid() throws CharacterCodingException {
|
||||
String value = JsonReader.read(String.class, "\"\\uD888\\u1334\"");
|
||||
|
||||
assertEquals("\u0000\u0000؈\u0000\u0000\u00134",value);
|
||||
assertEquals("\u0000\u0000؈\u0000\u0000\u00134", value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void escapedDoubleQuote() {
|
||||
String value = JsonReader.read(String.class, "\"\\\"\"");
|
||||
String value = JsonReader.read(String.class, " \"\\\"\"");
|
||||
assertEquals("\"", value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void escapedSingleQuote() {
|
||||
assertThrows(JsonReadException.class, () -> JsonReader.read(String.class, "\"\\\'\""));
|
||||
assertThrows(JsonReadException.class, () -> JsonReader.read(String.class, "\"\\'\""));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
51
src/test/java/nl/sander/jsontoy2/StringsWithJackson.java
Normal file
51
src/test/java/nl/sander/jsontoy2/StringsWithJackson.java
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package nl.sander.jsontoy2;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class StringsWithJackson {
|
||||
|
||||
ObjectMapper jackson = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
public void regular() throws JsonProcessingException {
|
||||
assertEquals("DADA", jackson.readValue("\"DADA\"", String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstSurrogateButSecondMissing() throws NoSuchFieldException, IllegalAccessException, JsonProcessingException {
|
||||
String value =jackson.readValue("\"\\uDADA\"", String.class);
|
||||
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void incompleteSurrogateAndEscapeValid() throws JsonProcessingException {
|
||||
assertThrows(JsonParseException.class, () -> jackson.readValue("\"\\uD800\n\"", String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstValidSurrogateSecondInvalid() throws JsonProcessingException {
|
||||
String value =jackson.readValue("\"\\uD888\\u1334\"", String.class);
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void escapedDoubleQuote() throws JsonProcessingException {
|
||||
String value =jackson.readValue("\"\\\"\"", String.class);
|
||||
assertEquals("\"", value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void escapedSingleQuote() {
|
||||
assertThrows(JsonParseException.class, () -> jackson.readValue("\"\\'\"", String.class));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue