[serde-gson,serde-hjson,serde-jackson] Unify JSON reader tests
This commit is contained in:
@@ -1,14 +1,146 @@
|
|||||||
package de.siphalor.tweed5.testutils.serde.json;
|
package de.siphalor.tweed5.testutils.serde.json;
|
||||||
|
|
||||||
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
|
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
|
||||||
|
import de.siphalor.tweed5.dataapi.api.TweedDataToken;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import org.assertj.core.data.Offset;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public interface JsonReaderTest {
|
public interface JsonReaderTest {
|
||||||
|
default Offset<Double> getDoublePrecision() {
|
||||||
|
return Offset.offset(0.000000001D);
|
||||||
|
}
|
||||||
|
|
||||||
TweedDataReader createJsonReader(String text);
|
TweedDataReader createJsonReader(String text);
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"127,127",
|
||||||
|
"-128,-128",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonByte(String input, byte expected) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsByte()).as("%s should be a valid byte", input).isTrue();
|
||||||
|
assertThat(token.readAsByte()).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"1.23e2,123",
|
||||||
|
"120e-1,12",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonByteFloaty(String input, byte expected) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsByte()).as("%s should be a valid byte", input).isTrue();
|
||||||
|
assertThat(token.readAsByte()).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"128",
|
||||||
|
"1.23",
|
||||||
|
"-129",
|
||||||
|
"1.23e3",
|
||||||
|
"123E-1",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonByteIllegal(String input) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsByte()).as("%s should not be a valid byte", input).isFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource(value = {
|
||||||
|
"123,123",
|
||||||
|
"-132893892,-132893892",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonInt(String input, int expected) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsInt()).as("%s should be a valid int", input).isTrue();
|
||||||
|
assertThat(token.readAsInt()).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource(value = {
|
||||||
|
"123e4,1230000",
|
||||||
|
"9.87e3,9870",
|
||||||
|
"45670E-1,4567",
|
||||||
|
"-123.56E+5,-12356000",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonIntFloaty(String input, int expected) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsInt()).as("%s should be a valid int", input).isTrue();
|
||||||
|
assertThat(token.readAsInt()).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"123,123",
|
||||||
|
"12.34,12.34",
|
||||||
|
"123456789.123456789,123456789.123456789",
|
||||||
|
"1234.057e8,123405700000",
|
||||||
|
"987.654E-5,0.00987654",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonDouble(String input, double expected) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsDouble()).as("%s should be a valid double", input).isTrue();
|
||||||
|
assertThat(token.readAsDouble()).isEqualTo(expected, getDoublePrecision());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"123,123",
|
||||||
|
"98765,98765"
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonIntAsDouble(String input, double expected) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
var token = reader.readToken();
|
||||||
|
assertThat(token.canReadAsDouble()).as("%s should be a valid double", input).isTrue();
|
||||||
|
assertThat(token.readAsDouble()).isEqualTo(expected, getDoublePrecision());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {
|
||||||
|
"[]",
|
||||||
|
"[\n\n]",
|
||||||
|
"[ ]",
|
||||||
|
"[\n\t\t]",
|
||||||
|
})
|
||||||
|
@SneakyThrows
|
||||||
|
default void jsonEmptyArray(String input) {
|
||||||
|
try (var reader = createJsonReader(input)) {
|
||||||
|
TweedDataToken token;
|
||||||
|
token = reader.readToken();
|
||||||
|
assertThat(token.isListStart()).isTrue();
|
||||||
|
token = reader.readToken();
|
||||||
|
assertThat(token.isListEnd()).isTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
default void complexJsonReadTest() {
|
default void complexJsonReadTest() {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package de.siphalor.tweed5.data.hjson;
|
package de.siphalor.tweed5.data.hjson;
|
||||||
|
|
||||||
import de.siphalor.tweed5.dataapi.api.TweedDataReadException;
|
|
||||||
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
|
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
|
||||||
import de.siphalor.tweed5.dataapi.api.TweedDataToken;
|
import de.siphalor.tweed5.dataapi.api.TweedDataToken;
|
||||||
import de.siphalor.tweed5.testutils.serde.json.JsonReaderTest;
|
import de.siphalor.tweed5.testutils.serde.json.JsonReaderTest;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.CsvSource;
|
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
@@ -13,116 +12,54 @@ import java.io.StringReader;
|
|||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class HjsonReaderTest implements JsonReaderTest {
|
class HjsonReaderTest implements JsonReaderTest {
|
||||||
private static final double DOUBLE_PRECISION = 0.000000001D;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TweedDataReader createJsonReader(String text) {
|
public TweedDataReader createJsonReader(String text) {
|
||||||
return new HjsonReader(new HjsonLexer(new StringReader(text)));
|
return new HjsonReader(new HjsonLexer(new StringReader(text)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@CsvSource({
|
|
||||||
"127,127",
|
|
||||||
"-128,-128",
|
|
||||||
"1.23e2,123",
|
|
||||||
"1230E-1,123",
|
|
||||||
})
|
|
||||||
void testByte(String input, byte expected) {
|
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
|
||||||
TweedDataToken token = assertDoesNotThrow(hjsonReader::readToken);
|
|
||||||
assertEquals(expected, assertDoesNotThrow(token::readAsByte));
|
|
||||||
assertTrue(token.canReadAsByte());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@ValueSource(strings = {
|
|
||||||
"128",
|
|
||||||
"1.23",
|
|
||||||
"-129",
|
|
||||||
"1.23e3",
|
|
||||||
"123E-1",
|
|
||||||
})
|
|
||||||
void testByteIllegal(String input) {
|
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
|
||||||
TweedDataToken token = assertDoesNotThrow(hjsonReader::readToken);
|
|
||||||
assertThrows(TweedDataReadException.class, token::readAsByte);
|
|
||||||
assertFalse(token.canReadAsByte());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@CsvSource(value = {
|
|
||||||
"123,123",
|
|
||||||
"123e4,1230000",
|
|
||||||
"9.87e3,9870",
|
|
||||||
"45670E-1,4567",
|
|
||||||
"-123.56E+5,-12356000",
|
|
||||||
})
|
|
||||||
void testInteger(String input, int expected) {
|
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
|
||||||
TweedDataToken token = assertDoesNotThrow(hjsonReader::readToken);
|
|
||||||
assertEquals(expected, assertDoesNotThrow(token::readAsInt));
|
|
||||||
assertTrue(token.canReadAsInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@CsvSource(
|
|
||||||
ignoreLeadingAndTrailingWhitespace = false,
|
|
||||||
value = {
|
|
||||||
"123,123",
|
|
||||||
"12.34,12.34",
|
|
||||||
"123456789.123456789,123456789.123456789",
|
|
||||||
"1234.057e8,123405700000",
|
|
||||||
"987.654E-5,0.00987654",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
void testDouble(String input, double expected) {
|
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
|
||||||
TweedDataToken token = assertDoesNotThrow(hjsonReader::readToken);
|
|
||||||
assertEquals(expected, assertDoesNotThrow(token::readAsDouble), DOUBLE_PRECISION);
|
|
||||||
assertTrue(token.canReadAsDouble());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {
|
@ValueSource(strings = {
|
||||||
"{test:abc\ncdef:123\na:true}",
|
"{test:abc\ncdef:123\na:true}",
|
||||||
"\n{test: abc \ncdef:123,a\n:\ntrue\n}",
|
"\n{test: abc \ncdef:123,a\n:\ntrue\n}",
|
||||||
"// \n{\n\ttest:abc\ncdef:123e0,a: true ,}",
|
"// \n{\n\ttest:abc\ncdef:123e0,a: true ,}",
|
||||||
})
|
})
|
||||||
|
@SneakyThrows
|
||||||
void testObject(String input) {
|
void testObject(String input) {
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
try (var reader = createJsonReader(input)) {
|
||||||
TweedDataToken token;
|
TweedDataToken token;
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapStart());
|
assertTrue(token.isMapStart());
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEntryKey());
|
assertTrue(token.isMapEntryKey());
|
||||||
assertTrue(token.canReadAsString());
|
assertTrue(token.canReadAsString());
|
||||||
assertEquals("test", assertDoesNotThrow(token::readAsString));
|
assertEquals("test", assertDoesNotThrow(token::readAsString));
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEntryValue());
|
assertTrue(token.isMapEntryValue());
|
||||||
assertTrue(token.canReadAsString());
|
assertTrue(token.canReadAsString());
|
||||||
assertEquals("abc", assertDoesNotThrow(token::readAsString));
|
assertEquals("abc", assertDoesNotThrow(token::readAsString));
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEntryKey());
|
assertTrue(token.isMapEntryKey());
|
||||||
assertTrue(token.canReadAsString());
|
assertTrue(token.canReadAsString());
|
||||||
assertEquals("cdef", assertDoesNotThrow(token::readAsString));
|
assertEquals("cdef", assertDoesNotThrow(token::readAsString));
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEntryValue());
|
assertTrue(token.isMapEntryValue());
|
||||||
assertTrue(token.canReadAsInt());
|
assertTrue(token.canReadAsInt());
|
||||||
assertEquals(123, assertDoesNotThrow(token::readAsInt));
|
assertEquals(123, assertDoesNotThrow(token::readAsInt));
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEntryKey());
|
assertTrue(token.isMapEntryKey());
|
||||||
assertTrue(token.canReadAsString());
|
assertTrue(token.canReadAsString());
|
||||||
assertEquals("a", assertDoesNotThrow(token::readAsString));
|
assertEquals("a", assertDoesNotThrow(token::readAsString));
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEntryValue());
|
assertTrue(token.isMapEntryValue());
|
||||||
assertTrue(token.canReadAsBoolean());
|
assertTrue(token.canReadAsBoolean());
|
||||||
assertEquals(true, assertDoesNotThrow(token::readAsBoolean));
|
assertEquals(true, assertDoesNotThrow(token::readAsBoolean));
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isMapEnd());
|
assertTrue(token.isMapEnd());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@@ -132,49 +69,30 @@ class HjsonReaderTest implements JsonReaderTest {
|
|||||||
"[\n12\n\t\t34\n\t56\n]",
|
"[\n12\n\t\t34\n\t56\n]",
|
||||||
"[\n12,34\n\t56\n]",
|
"[\n12,34\n\t56\n]",
|
||||||
})
|
})
|
||||||
|
@SneakyThrows
|
||||||
void testArray(String input) {
|
void testArray(String input) {
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
try (var reader = createJsonReader(input)) {
|
||||||
TweedDataToken token;
|
TweedDataToken token;
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isListStart());
|
assertTrue(token.isListStart());
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isListValue());
|
assertTrue(token.isListValue());
|
||||||
assertTrue(token.canReadAsInt());
|
assertTrue(token.canReadAsInt());
|
||||||
assertEquals(12, assertDoesNotThrow(token::readAsInt));
|
assertEquals(12, assertDoesNotThrow(token::readAsInt));
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isListValue());
|
assertTrue(token.isListValue());
|
||||||
assertTrue(token.canReadAsInt());
|
assertTrue(token.canReadAsInt());
|
||||||
assertEquals(34, assertDoesNotThrow(token::readAsInt));
|
assertEquals(34, assertDoesNotThrow(token::readAsInt));
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isListValue());
|
assertTrue(token.isListValue());
|
||||||
assertTrue(token.canReadAsInt());
|
assertTrue(token.canReadAsInt());
|
||||||
assertEquals(56, assertDoesNotThrow(token::readAsInt));
|
assertEquals(56, assertDoesNotThrow(token::readAsInt));
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
token = assertDoesNotThrow(reader::readToken);
|
||||||
assertTrue(token.isListEnd());
|
assertTrue(token.isListEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@ValueSource(strings = {
|
|
||||||
"[]",
|
|
||||||
"[\n\n]",
|
|
||||||
"[ ]",
|
|
||||||
"[\n\t\t]",
|
|
||||||
})
|
|
||||||
void testEmptyArray(String input) {
|
|
||||||
HjsonReader hjsonReader = setupReaderWithLexer(input);
|
|
||||||
TweedDataToken token;
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
|
||||||
assertTrue(token.isListStart());
|
|
||||||
|
|
||||||
token = assertDoesNotThrow(hjsonReader::readToken);
|
|
||||||
assertTrue(token.isListEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
private HjsonReader setupReaderWithLexer(String input) {
|
|
||||||
return new HjsonReader(new HjsonLexer(new StringReader(input)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,26 @@ public class JacksonReader implements TweedDataReader {
|
|||||||
public long readAsLong() {
|
public long readAsLong() {
|
||||||
return longValue;
|
return longValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canReadAsFloat() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float readAsFloat() {
|
||||||
|
return (float) longValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canReadAsDouble() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double readAsDouble() {
|
||||||
|
return (double) longValue;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
afterValueRead();
|
afterValueRead();
|
||||||
return token;
|
return token;
|
||||||
|
|||||||
@@ -5,11 +5,30 @@ import com.fasterxml.jackson.core.StreamReadFeature;
|
|||||||
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
|
import de.siphalor.tweed5.dataapi.api.TweedDataReader;
|
||||||
import de.siphalor.tweed5.testutils.serde.json.JsonReaderTest;
|
import de.siphalor.tweed5.testutils.serde.json.JsonReaderTest;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
class JacksonReaderTest implements JsonReaderTest {
|
class JacksonReaderTest implements JsonReaderTest {
|
||||||
|
@Disabled("Jackson does not support integer values with floating point syntax elements")
|
||||||
|
@Override
|
||||||
|
public void jsonByteFloaty(String input, byte expected) {
|
||||||
|
JsonReaderTest.super.jsonByteFloaty(input, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled("Jackson does not support integer values with floating point syntax elements")
|
||||||
|
@Override
|
||||||
|
public void jsonIntFloaty(String input, int expected) {
|
||||||
|
JsonReaderTest.super.jsonIntFloaty(input, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled("Jackson's double precision is abysmal in comparison with everyone else's even with fast double parsing turned off")
|
||||||
|
@Override
|
||||||
|
public void jsonDouble(String input, double expected) {
|
||||||
|
JsonReaderTest.super.jsonDouble(input, expected);
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public TweedDataReader createJsonReader(String text) {
|
public TweedDataReader createJsonReader(String text) {
|
||||||
|
|||||||
Reference in New Issue
Block a user