/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.datamodel.internal; import static org.junit.Assert.assertEquals; import java.util.Date; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import de.rcenvironment.core.datamodel.api.DataType; import de.rcenvironment.core.datamodel.api.TypedDatum; import de.rcenvironment.core.datamodel.types.api.BooleanTD; import de.rcenvironment.core.datamodel.types.api.DateTimeTD; import de.rcenvironment.core.datamodel.types.api.DirectoryReferenceTD; import de.rcenvironment.core.datamodel.types.api.EmptyTD; import de.rcenvironment.core.datamodel.types.api.FileReferenceTD; import de.rcenvironment.core.datamodel.types.api.FloatTD; import de.rcenvironment.core.datamodel.types.api.IntegerTD; import de.rcenvironment.core.datamodel.types.api.MatrixTD; import de.rcenvironment.core.datamodel.types.api.NotAValueTD; import de.rcenvironment.core.datamodel.types.api.ShortTextTD; import de.rcenvironment.core.datamodel.types.api.SmallTableTD; import de.rcenvironment.core.datamodel.types.api.VectorTD; import de.rcenvironment.core.utils.common.StringUtils; /** * Test class for data serializer. * * @author Jan Flink */ @RunWith(JUnit4.class) public class DefaultTypedDatumSerializerTest { private static final String CLOSE_BRACKET = "]"; private static final String OPEN_BRACKET = "["; private static final String ESCAPED_QUOTE = "\""; private static final int SIZE_1024 = 1024; private static final String COMMA_STRING = ","; private static final String SHORT_TEXT_TEST_VALUE = "test"; private static final String JSON_STRING = "{\"t\":\"%s\",\"v\":%s}"; private static final String JSON_STRING_TEXT = "{\"t\":\"%s\",\"v\":\"%s\"}"; private static final String JSON_STRING_ARRAY = "{\"t\":\"%s\",\"v\":[%s]}"; private static final String JSON_STRING_DIMENSION_ARRAY = "{\"t\":\"%s\",\"r\":%s,\"c\":%s,\"v\":[%s]}"; private static DefaultTypedDatumFactory factory; private static DefaultTypedDatumSerializer serializer; /** * JUnit rule declaration for checking exceptions. Must be public. */ @Rule public ExpectedException exception = ExpectedException.none(); /** * Initialization method. */ @BeforeClass public static void setUpBeforeClass() { factory = new DefaultTypedDatumFactory(); serializer = new DefaultTypedDatumSerializer(); } /** * Test. */ @Test public void testNullPointerException() { exception.expect(NullPointerException.class); serializer.serialize(null); TypedDatum dummy = new TypedDatum() { @Override public DataType getDataType() { return null; } }; serializer.serialize(dummy); } /** * Test. */ @Test public void testIllegalArgumentException() { exception.expect(IllegalArgumentException.class); TypedDatum dummy = new TypedDatum() { @Override public DataType getDataType() { return DataType.StructuredData; } }; serializer.serialize(dummy); serializer.deserialize(""); serializer.deserialize("no-json-string"); } /** * Test. */ @Test public void testSerialize() { // Serialization of BooleanTD BooleanTD boolFalse = factory.createBoolean(false); assertEquals(StringUtils.format(JSON_STRING, DataType.Boolean.getShortName(), Boolean.FALSE.toString()), serializer.serialize(boolFalse)); // Serialization of BooleanTD BooleanTD boolTrue = factory.createBoolean(true); assertEquals(StringUtils.format(JSON_STRING, DataType.Boolean.getShortName(), Boolean.TRUE.toString()), serializer.serialize(boolTrue)); // Serialization of ShortTextTD ShortTextTD shortText = factory.createShortText(SHORT_TEXT_TEST_VALUE); assertEquals(StringUtils.format(JSON_STRING_TEXT, DataType.ShortText.getShortName(), SHORT_TEXT_TEST_VALUE), serializer.serialize(shortText)); // Serialization of IntegerTD IntegerTD integer = factory.createInteger(0); assertEquals(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), 0), serializer.serialize(integer)); integer = factory.createInteger(1); assertEquals(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), 1), serializer.serialize(integer)); integer = factory.createInteger(Long.MAX_VALUE); assertEquals(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), Long.MAX_VALUE), serializer.serialize(integer)); long anyLong = Integer.MAX_VALUE + Integer.MAX_VALUE/2; integer = factory.createInteger(anyLong); assertEquals(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), anyLong), serializer.serialize(integer)); integer = factory.createInteger(Long.MIN_VALUE); assertEquals(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), Long.MIN_VALUE), serializer.serialize(integer)); // Serialization of FloatTD FloatTD floatData = factory.createFloat(0.0); assertEquals(StringUtils.format(JSON_STRING, DataType.Float.getShortName(), 0.0), serializer.serialize(floatData)); floatData = factory.createFloat(1.0); assertEquals(StringUtils.format(JSON_STRING, DataType.Float.getShortName(), 1.0), serializer.serialize(floatData)); floatData = factory.createFloat(Double.MAX_VALUE); assertEquals(StringUtils.format(JSON_STRING, DataType.Float.getShortName(), Double.MAX_VALUE), serializer.serialize(floatData)); floatData = factory.createFloat(Double.MIN_VALUE); assertEquals(StringUtils.format(JSON_STRING, DataType.Float.getShortName(), Double.MIN_VALUE), serializer.serialize(floatData)); floatData = factory.createFloat(Double.NaN); assertEquals(StringUtils.format(JSON_STRING, DataType.Float.getShortName(), ESCAPED_QUOTE + Double.NaN + ESCAPED_QUOTE), serializer.serialize(floatData)); floatData = factory.createFloat(Double.POSITIVE_INFINITY); assertEquals( StringUtils.format(JSON_STRING, DataType.Float.getShortName(), ESCAPED_QUOTE + Double.POSITIVE_INFINITY + ESCAPED_QUOTE), serializer.serialize(floatData)); floatData = factory.createFloat(Double.NEGATIVE_INFINITY); assertEquals( StringUtils.format(JSON_STRING, DataType.Float.getShortName(), ESCAPED_QUOTE + Double.NEGATIVE_INFINITY + ESCAPED_QUOTE), serializer.serialize(floatData)); // Serialization of DateTimeTD Long currentMillis = System.currentTimeMillis(); DateTimeTD dateTime = factory.createDateTime(currentMillis); assertEquals(StringUtils.format(JSON_STRING, DataType.DateTime.getShortName(), String.valueOf(currentMillis)), serializer.serialize(dateTime)); // Serialization of VectorTD FloatTD[] vectorEntries = { factory.createFloat(1.0), factory.createFloat(2.0), factory.createFloat(3.0) }; VectorTD vector = factory.createVector(vectorEntries); assertEquals(getVectorString(vectorEntries), serializer.serialize(vector)); FloatTD[] vectorEntries2 = { factory.createFloat(2.0), factory.createFloat(3.0), factory.createFloat(4.0) }; vector = factory.createVector(vectorEntries2); assertEquals(getVectorString(vectorEntries2), serializer.serialize(vector)); FloatTD[] vectorEntries3 = { factory.createFloat(Double.MAX_VALUE), factory.createFloat(0.0), factory.createFloat(Double.MIN_VALUE) }; vector = factory.createVector(vectorEntries3); assertEquals(getVectorString(vectorEntries3), serializer.serialize(vector)); // Serialization of MatrixTD FloatTD[][] matrixEntries = { vectorEntries, vectorEntries2, vectorEntries3 }; MatrixTD matrix = factory.createMatrix(matrixEntries); assertEquals(getMatrixString(matrixEntries), serializer.serialize(matrix)); // Serialization of SmallTableTD TypedDatum[][] tableEntries = { vectorEntries, vectorEntries2, vectorEntries3 }; SmallTableTD smallTable = factory.createSmallTable(matrix.toArray()); assertEquals(getExpectedSmallTableString(tableEntries), serializer.serialize(smallTable)); TypedDatum[][] tableEntries2 = { { boolFalse, integer, floatData }, { dateTime, shortText, integer }, { floatData, floatData, floatData } }; smallTable = factory.createSmallTable(3, 3); smallTable.setTypedDatumForCell(boolFalse, 0, 0); smallTable.setTypedDatumForCell(integer, 0, 1); smallTable.setTypedDatumForCell(floatData, 0, 2); smallTable.setTypedDatumForCell(dateTime, 1, 0); smallTable.setTypedDatumForCell(shortText, 1, 1); smallTable.setTypedDatumForCell(integer, 1, 2); smallTable.setTypedDatumForCell(floatData, 2, 0); smallTable.setTypedDatumForCell(floatData, 2, 1); smallTable.setTypedDatumForCell(floatData, 2, 2); assertEquals(getExpectedSmallTableString(tableEntries2), serializer.serialize(smallTable)); // Serialization of EmptyTD EmptyTD empty = factory.createEmpty(); assertEquals("{\"t\":\"" + DataType.Empty.getShortName() + "\"}", serializer.serialize(empty)); // Serialization of FileReferenceTD FileReferenceTD fileReference = factory.createFileReference("example reference", "example filename"); assertEquals(getFileReferenceString(), serializer.serialize(fileReference)); fileReference.setLastModified(new Date(0)); fileReference.setFileSize(SIZE_1024); assertEquals(getFileReferenceWithModifiedString(), serializer.serialize(fileReference)); } /** * Tests de-/serialization of values of type {@link NotAValueTD}. */ @Test public void testDeSerializeNotAValue() { String identifier = "some-id"; NotAValueTD.Cause cause = NotAValueTD.Cause.InvalidInputs; NotAValueTD notAValue = factory.createNotAValue(identifier, cause); String serializedNotAValue = serializer.serialize(notAValue); assertEquals(getNotAValueString(identifier, cause), serializedNotAValue); NotAValueTD deserializedNotAValue = (NotAValueTD) serializer.deserialize(serializedNotAValue); assertEquals(notAValue.getIdentifier(), deserializedNotAValue.getIdentifier()); assertEquals(notAValue.getCause(), deserializedNotAValue.getCause()); } /** * Tests deserialization of values of type {@link NotAValueTD} serialized before version 8.0.0. */ @Test public void testDeserializeNotAValueSerializedBefore800() { String identifierFailure = "some-id_flr"; String identifierInvalidInputs = "some-id"; NotAValueTD deserializedNotAValueFailure = (NotAValueTD) serializer.deserialize( StringUtils.format(JSON_STRING, DataType.NotAValue.getShortName(), ESCAPED_QUOTE + identifierFailure + ESCAPED_QUOTE)); assertEquals(deserializedNotAValueFailure.getIdentifier(), identifierFailure); assertEquals(deserializedNotAValueFailure.getCause(), NotAValueTD.Cause.Failure); NotAValueTD deserializedNotAValueInvalidInputs = (NotAValueTD) serializer.deserialize( StringUtils.format(JSON_STRING, DataType.NotAValue.getShortName(), ESCAPED_QUOTE + identifierInvalidInputs + ESCAPED_QUOTE)); assertEquals(deserializedNotAValueInvalidInputs.getIdentifier(), identifierInvalidInputs); assertEquals(deserializedNotAValueInvalidInputs.getCause(), NotAValueTD.Cause.InvalidInputs); } /** * Test. */ @Test public void testDeserialize() { // Deserialization of BooleanTD BooleanTD boolFalse = factory.createBoolean(false); assertEquals(boolFalse, serializer.deserialize(serializer.serialize(boolFalse))); String oldSerialization = StringUtils.format(JSON_STRING_TEXT, DataType.Boolean.getShortName(), Boolean.FALSE.toString()); assertEquals(boolFalse, serializer.deserialize(oldSerialization)); BooleanTD boolTrue = factory.createBoolean(true); assertEquals(boolTrue, serializer.deserialize(serializer.serialize(boolTrue))); oldSerialization = StringUtils.format(JSON_STRING_TEXT, DataType.Boolean.getShortName(), Boolean.TRUE.toString()); assertEquals(boolTrue, serializer.deserialize(oldSerialization)); // Deserialization of ShortTextTD ShortTextTD shortText = factory.createShortText(SHORT_TEXT_TEST_VALUE); assertEquals(shortText, serializer.deserialize(serializer.serialize(shortText))); // Deserialization of IntegerTD IntegerTD integer = factory.createInteger(5); assertEquals(integer, serializer.deserialize(serializer.serialize(integer))); integer = factory.createInteger(Long.MAX_VALUE); assertEquals(integer, serializer.deserialize(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), Long.MAX_VALUE))); long anyLong = Integer.MAX_VALUE + Integer.MAX_VALUE/2; integer = factory.createInteger(anyLong); assertEquals(integer, serializer.deserialize(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), anyLong))); integer = factory.createInteger(Long.MIN_VALUE); assertEquals(integer, serializer.deserialize(StringUtils.format(JSON_STRING, DataType.Integer.getShortName(), Long.MIN_VALUE))); // Deserialization of FloatTD FloatTD floatData = factory.createFloat(5.0); assertEquals(floatData, serializer.deserialize(serializer.serialize(floatData))); floatData = factory.createFloat(Double.MAX_VALUE); assertEquals(floatData, serializer.deserialize(serializer.serialize(floatData))); floatData = factory.createFloat(Double.MIN_VALUE); assertEquals(floatData, serializer.deserialize(serializer.serialize(floatData))); floatData = factory.createFloat(Double.NEGATIVE_INFINITY); assertEquals(floatData, serializer.deserialize(StringUtils.format(serializer.serialize(floatData)))); // Deserialization of DateTimeTD Long currentMillis = System.currentTimeMillis(); DateTimeTD dateTime = factory.createDateTime(currentMillis); assertEquals(dateTime, serializer.deserialize(serializer.serialize(dateTime))); // Deserialization of VectorTD FloatTD[] vectorEntries = { factory.createFloat(1.0), factory.createFloat(2.0), factory.createFloat(3.0) }; FloatTD[] vectorEntries2 = { factory.createFloat(2.0), factory.createFloat(3.0), factory.createFloat(4.0) }; FloatTD[] vectorEntries3 = { factory.createFloat(Double.MAX_VALUE), factory.createFloat(0.0), factory.createFloat(Double.POSITIVE_INFINITY) }; VectorTD vector = factory.createVector(vectorEntries); assertEquals(vector, serializer.deserialize(serializer.serialize(vector))); // Deserialization of MatrixTD FloatTD[][] matrixEntries = { vectorEntries, vectorEntries2, vectorEntries3 }; MatrixTD matrix = factory.createMatrix(matrixEntries); assertEquals(matrix, serializer.deserialize(serializer.serialize(matrix))); // Deserialization of SmallTableTD SmallTableTD smallTable = factory.createSmallTable(matrix.toArray()); assertEquals(smallTable, serializer.deserialize(serializer.serialize(smallTable))); smallTable = factory.createSmallTable(3, 3); smallTable.setTypedDatumForCell(boolFalse, 0, 0); smallTable.setTypedDatumForCell(integer, 0, 1); smallTable.setTypedDatumForCell(floatData, 0, 2); smallTable.setTypedDatumForCell(dateTime, 1, 0); smallTable.setTypedDatumForCell(shortText, 1, 1); smallTable.setTypedDatumForCell(integer, 1, 2); smallTable.setTypedDatumForCell(floatData, 2, 0); smallTable.setTypedDatumForCell(floatData, 2, 1); smallTable.setTypedDatumForCell(floatData, 2, 2); assertEquals(smallTable, serializer.deserialize(serializer.serialize(smallTable))); TypedDatum[][] tableEntries = { { boolFalse, integer, floatData }, { dateTime, shortText, integer }, { floatData, floatData, floatData } }; String oldSmalltableSerialization = getOldSerializationExpectedSmallTableString(tableEntries); assertEquals(smallTable, serializer.deserialize(oldSmalltableSerialization)); // Deserialization of EmptyTD EmptyTD empty = factory.createEmpty(); assertEquals(empty.toString(), serializer.deserialize(serializer.serialize(empty)).toString()); // Deserialization of FileReferenceTD FileReferenceTD fileReference = factory.createFileReference("example reference", "example filename"); FileReferenceTD deserializedFileReference = (FileReferenceTD) serializer .deserialize(serializer.serialize(fileReference)); assertEquals(fileReference.getFileName(), deserializedFileReference.getFileName()); assertEquals(fileReference.getFileReference(), deserializedFileReference.getFileReference()); assertEquals(fileReference.getFileSizeInBytes(), deserializedFileReference.getFileSizeInBytes()); assertEquals(fileReference.getLastModified(), deserializedFileReference.getLastModified()); fileReference.setLastModified(new Date(0)); fileReference.setFileSize(SIZE_1024); deserializedFileReference = (FileReferenceTD) serializer .deserialize(getFileReferenceWithModifiedString()); assertEquals(fileReference.getFileName(), deserializedFileReference.getFileName()); assertEquals(fileReference.getFileReference(), deserializedFileReference.getFileReference()); assertEquals(fileReference.getFileSizeInBytes(), deserializedFileReference.getFileSizeInBytes()); assertEquals(fileReference.getLastModified(), deserializedFileReference.getLastModified()); // Deserialization of DirectoryReferenceTD DirectoryReferenceTD dirRef = factory.createDirectoryReference("reference", "dirname"); dirRef.setDirectorySize(SIZE_1024); DirectoryReferenceTD otherDirRef = (DirectoryReferenceTD) serializer.deserialize(serializer.serialize(dirRef)); assertEquals(dirRef.getDirectoryReference(), otherDirRef.getDirectoryReference()); assertEquals(dirRef.getDirectoryName(), otherDirRef.getDirectoryName()); assertEquals(dirRef.getDirectorySizeInBytes(), otherDirRef.getDirectorySizeInBytes()); } private String getNotAValueString(String identifier, NotAValueTD.Cause cause) { return StringUtils.format(JSON_STRING, DataType.NotAValue.getShortName(), StringUtils.format( "{\"id\":\"%s\",\"t\"" + ":\"%s\"}", identifier, cause.name())); } private String getFileReferenceString() { return StringUtils.format(JSON_STRING, DataType.FileReference.getShortName(), "{\"fileReference\":\"example reference\",\"fileName\"" + ":\"example filename\",\"fileSize\":0}"); } private String getFileReferenceWithModifiedString() { return StringUtils.format(JSON_STRING, DataType.FileReference.getShortName(), "{\"fileReference\":\"example reference\",\"fileName\"" + ":\"example filename\",\"fileSize\":1024,\"lastModified\":0}"); } private String getVectorString(FloatTD[] vectorEntries) { String value = ""; for (int i = 0; i < vectorEntries.length; i++) { value += vectorEntries[i]; if (i < vectorEntries.length - 1) { value += COMMA_STRING; } } return StringUtils.format(JSON_STRING_ARRAY, DataType.Vector.getShortName(), value); } private String getMatrixString(FloatTD[][] matrixEntries) { String value = ""; int rows = matrixEntries.length; int cols = 0; for (int i = 0; i < rows; i++) { if (matrixEntries[i].length > cols) { cols = matrixEntries[i].length; } value += OPEN_BRACKET; for (int j = 0; j < cols; j++) { value += matrixEntries[i][j]; if (j < matrixEntries[i].length - 1) { value += COMMA_STRING; } } value += CLOSE_BRACKET; if (i < matrixEntries.length - 1) { value += COMMA_STRING; } } return StringUtils.format(JSON_STRING_DIMENSION_ARRAY, DataType.Matrix.getShortName(), rows, cols, value); } private String getExpectedSmallTableString(TypedDatum[][] tableEntries) { String value = ""; int rows = tableEntries.length; int cols = 0; for (int i = 0; i < rows; i++) { if (tableEntries[i].length > cols) { cols = tableEntries[i].length; } value += OPEN_BRACKET; for (int j = 0; j < cols; j++) { value += ESCAPED_QUOTE + serializer.serialize(tableEntries[i][j]).replaceAll(ESCAPED_QUOTE, "\\\\\"") + ESCAPED_QUOTE; if (j < tableEntries[i].length - 1) { value += COMMA_STRING; } } value += CLOSE_BRACKET; if (i < tableEntries.length - 1) { value += COMMA_STRING; } } return StringUtils.format(JSON_STRING_DIMENSION_ARRAY, DataType.SmallTable.getShortName(), rows, cols, value); } private String getOldSerializationExpectedSmallTableString(TypedDatum[][] tableEntries) { String value = ""; int rows = tableEntries.length; int cols = 0; for (int i = 0; i < rows; i++) { if (tableEntries[i].length > cols) { cols = tableEntries[i].length; } value += OPEN_BRACKET; for (int j = 0; j < cols; j++) { value += serializer.serialize(tableEntries[i][j]); if (j < tableEntries[i].length - 1) { value += COMMA_STRING; } } value += CLOSE_BRACKET; if (i < tableEntries.length - 1) { value += COMMA_STRING; } } return StringUtils.format(JSON_STRING_DIMENSION_ARRAY, DataType.SmallTable.getShortName(), rows, cols, value); } }