#include "dynamictypes/DataValueSchema.h" #include "serialization/TestDeserializationContext.h" #include "serialization/TestSerializationContext.h" #include "unittest/TestSuite.h" #include "utilities/IOUtilities.h" static void testCreate(void) { DataValueSchema * schema = DataValueSchema_create(0, NULL); TestCase_assertPointerNonNULL(schema); TestCase_assertUIntEqual(schema->fieldCount, 0); TestCase_assertPointerNULL(schema->fields); DataValueSchema_dispose(schema); DataValueSchemaField field = {DATA_TYPE_BOOLEAN, "a", valueCreateBoolean(false), 0, NULL, NULL}; schema = DataValueSchema_create(1, &field); TestCase_assertPointerNonNULL(schema); TestCase_assertUIntEqual(schema->fieldCount, 1); TestCase_assertPointerNonNULL(schema->fields); TestCase_assertIntEqual(schema->fields[0].type, DATA_TYPE_BOOLEAN); TestCase_assertPointerUnequal(schema->fields[0].name, field.name); TestCase_assertStringEqual(schema->fields[0].name, "a"); TestCase_assertSizeEqual(schema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(schema->fields[0].metadata); TestCase_assertPointerNULL(schema->fields[0].subitemSchema); uint32_t metadata = 0x11223344; DataValueSchemaField fields[2] = { {DATA_TYPE_INT8, "b", valueCreateInt8(0), 4, &metadata, NULL}, {DATA_TYPE_ARRAY, "c", valueCreateBoolean(false), 0, NULL, schema} }; DataValueSchema * schema2 = DataValueSchema_create(2, fields); TestCase_assertPointerNonNULL(schema2); TestCase_assertUIntEqual(schema2->fieldCount, 2); TestCase_assertPointerNonNULL(schema2->fields); TestCase_assertIntEqual(schema2->fields[0].type, DATA_TYPE_INT8); TestCase_assertPointerUnequal(schema2->fields[0].name, fields[0].name); TestCase_assertStringEqual(schema2->fields[0].name, "b"); TestCase_assertSizeEqual(schema2->fields[0].metadataSize, 4); TestCase_assertPointerNonNULL(schema2->fields[0].metadata); TestCase_assertPointerUnequal(schema2->fields[0].metadata, fields[0].metadata); TestCase_assertUIntEqual(*(uint32_t *) schema2->fields[0].metadata, 0x11223344); TestCase_assertPointerNULL(schema2->fields[0].subitemSchema); TestCase_assertIntEqual(schema2->fields[1].type, DATA_TYPE_ARRAY); TestCase_assertPointerUnequal(schema2->fields[1].name, fields[1].name); TestCase_assertStringEqual(schema2->fields[1].name, "c"); TestCase_assertSizeEqual(schema2->fields[1].metadataSize, 0); TestCase_assertPointerNULL(schema2->fields[1].metadata); TestCase_assertPointerNonNULL(schema2->fields[1].subitemSchema); TestCase_assertPointerUnequal(schema2->fields[1].subitemSchema, schema); TestCase_assertUIntEqual(schema2->fields[1].subitemSchema->fieldCount, 1); TestCase_assertPointerNonNULL(schema2->fields[1].subitemSchema->fields); TestCase_assertIntEqual(schema2->fields[1].subitemSchema->fields[0].type, DATA_TYPE_BOOLEAN); TestCase_assertPointerUnequal(schema2->fields[1].subitemSchema->fields[0].name, schema->fields[0].name); TestCase_assertStringEqual(schema2->fields[1].subitemSchema->fields[0].name, "a"); TestCase_assertSizeEqual(schema2->fields[1].subitemSchema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(schema2->fields[1].subitemSchema->fields[0].metadata); TestCase_assertPointerNULL(schema2->fields[1].subitemSchema->fields[0].subitemSchema); DataValueSchema_dispose(schema2); DataValueSchema_dispose(schema); } static void testCopy(void) { DataValueSchema * schema = DataValueSchema_create(0, NULL); DataValueSchema * copy = DataValueSchema_copy(schema); DataValueSchema_dispose(schema); TestCase_assertPointerNonNULL(copy); TestCase_assertUIntEqual(copy->fieldCount, 0); TestCase_assertPointerNULL(copy->fields); DataValueSchema_dispose(copy); DataValueSchemaField field = {DATA_TYPE_BOOLEAN, "a", valueCreateBoolean(false), 0, NULL, NULL}; schema = DataValueSchema_create(1, &field); copy = DataValueSchema_copy(schema); DataValueSchema_dispose(schema); TestCase_assertPointerNonNULL(copy); TestCase_assertUIntEqual(copy->fieldCount, 1); TestCase_assertPointerNonNULL(copy->fields); TestCase_assertIntEqual(copy->fields[0].type, DATA_TYPE_BOOLEAN); TestCase_assertPointerUnequal(copy->fields[0].name, field.name); TestCase_assertStringEqual(copy->fields[0].name, "a"); TestCase_assertSizeEqual(copy->fields[0].metadataSize, 0); TestCase_assertPointerNULL(copy->fields[0].metadata); TestCase_assertPointerNULL(copy->fields[0].subitemSchema); uint32_t metadata = 0x11223344; DataValueSchemaField fields[2] = { {DATA_TYPE_INT8, "b", valueCreateInt8(0), 4, &metadata, NULL}, {DATA_TYPE_ARRAY, "c", valueCreateBoolean(false), 0, NULL, copy} }; DataValueSchema * schema2 = DataValueSchema_create(2, fields); DataValueSchema * copy2 = DataValueSchema_copy(schema2); DataValueSchema_dispose(schema2); TestCase_assertPointerNonNULL(copy2); TestCase_assertUIntEqual(copy2->fieldCount, 2); TestCase_assertPointerNonNULL(copy2->fields); TestCase_assertIntEqual(copy2->fields[0].type, DATA_TYPE_INT8); TestCase_assertPointerUnequal(copy2->fields[0].name, fields[0].name); TestCase_assertStringEqual(copy2->fields[0].name, "b"); TestCase_assertSizeEqual(copy2->fields[0].metadataSize, 4); TestCase_assertPointerNonNULL(copy2->fields[0].metadata); TestCase_assertPointerUnequal(copy2->fields[0].metadata, fields[0].metadata); TestCase_assertUIntEqual(*(uint32_t *) copy2->fields[0].metadata, 0x11223344); TestCase_assertPointerNULL(copy2->fields[0].subitemSchema); TestCase_assertIntEqual(copy2->fields[1].type, DATA_TYPE_ARRAY); TestCase_assertPointerUnequal(copy2->fields[1].name, fields[1].name); TestCase_assertStringEqual(copy2->fields[1].name, "c"); TestCase_assertSizeEqual(copy2->fields[1].metadataSize, 0); TestCase_assertPointerNULL(copy2->fields[1].metadata); TestCase_assertPointerNonNULL(copy2->fields[1].subitemSchema); TestCase_assertPointerUnequal(copy2->fields[1].subitemSchema, copy); TestCase_assertUIntEqual(copy2->fields[1].subitemSchema->fieldCount, 1); TestCase_assertPointerNonNULL(copy2->fields[1].subitemSchema->fields); TestCase_assertIntEqual(copy2->fields[1].subitemSchema->fields[0].type, DATA_TYPE_BOOLEAN); TestCase_assertPointerUnequal(copy2->fields[1].subitemSchema->fields[0].name, copy->fields[0].name); TestCase_assertStringEqual(copy2->fields[1].subitemSchema->fields[0].name, "a"); TestCase_assertSizeEqual(copy2->fields[1].subitemSchema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(copy2->fields[1].subitemSchema->fields[0].metadata); TestCase_assertPointerNULL(copy2->fields[1].subitemSchema->fields[0].subitemSchema); DataValueSchema_dispose(copy2); DataValueSchema_dispose(copy); } static void testMutate(void) { DataValueSchema * schema = DataValueSchema_create(0, NULL); DataValueSchemaField field1 = {DATA_TYPE_BOOLEAN, strdup("a"), valueCreateBoolean(false), 0, NULL, NULL}; DataValueSchema_addField(schema, field1); TestCase_assertUIntEqual(schema->fieldCount, 1); TestCase_assertPointerNonNULL(schema->fields); TestCase_assertIntEqual(schema->fields[0].type, field1.type); TestCase_assertStringPointerEqual(schema->fields[0].name, field1.name); TestCase_assertSizeEqual(schema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(schema->fields[0].metadata); TestCase_assertPointerNULL(schema->fields[0].subitemSchema); int8_t metadata = 0x12; DataValueSchemaField field2 = {DATA_TYPE_ARRAY, strdup("b"), valueCreateBoolean(false), 1, memdup(&metadata, 1), NULL}; DataValueSchema_insertField(schema, field2, 0); TestCase_assertUIntEqual(schema->fieldCount, 2); TestCase_assertIntEqual(schema->fields[0].type, field2.type); TestCase_assertStringPointerEqual(schema->fields[0].name, field2.name); TestCase_assertSizeEqual(schema->fields[0].metadataSize, 1); TestCase_assertPointerEqual(schema->fields[0].metadata, field2.metadata); TestCase_assertPointerNULL(schema->fields[0].subitemSchema); TestCase_assertIntEqual(schema->fields[1].type, field1.type); TestCase_assertStringPointerEqual(schema->fields[1].name, field1.name); TestCase_assertSizeEqual(schema->fields[1].metadataSize, 0); TestCase_assertPointerNULL(schema->fields[1].metadata); TestCase_assertPointerNULL(schema->fields[1].subitemSchema); DataValueSchema_removeFieldAtIndex(schema, 0); TestCase_assertUIntEqual(schema->fieldCount, 1); TestCase_assertIntEqual(schema->fields[0].type, field1.type); TestCase_assertStringPointerEqual(schema->fields[0].name, field1.name); TestCase_assertSizeEqual(schema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(schema->fields[0].metadata); TestCase_assertPointerNULL(schema->fields[0].subitemSchema); DataValueSchema_dispose(schema); } static Serialization_enumKeyValue dataTypeEnumValues[] = { {"boolean", DATA_TYPE_BOOLEAN}, {"int8", DATA_TYPE_INT8}, {"uint8", DATA_TYPE_UINT8}, {"int16", DATA_TYPE_INT16}, {"uint16", DATA_TYPE_UINT16}, {"int32", DATA_TYPE_INT32}, {"uint32", DATA_TYPE_UINT32}, {"int64", DATA_TYPE_INT64}, {"uint64", DATA_TYPE_UINT64}, {"float", DATA_TYPE_FLOAT}, {"double", DATA_TYPE_DOUBLE}, {"pointer", DATA_TYPE_POINTER}, {"string", DATA_TYPE_STRING}, {"blob", DATA_TYPE_BLOB}, {"hash_table", DATA_TYPE_HASH_TABLE}, {"array", DATA_TYPE_ARRAY}, {"associative_array", DATA_TYPE_ASSOCIATIVE_ARRAY}, {"fixed16_16", DATA_TYPE_FIXED_16_16} }; static void testSerialize(void) { jmp_buf jmpEnv; TestSerializationContext * context = TestSerializationContext_create(&jmpEnv); if (setjmp(jmpEnv) != 0) { TestCase_assert(false, "%s", context->error); } DataValueSchemaField subitemField = {DATA_TYPE_INT8, "c", valueCreateInt8(0), 0, NULL, NULL}; DataValueSchema * subitemSchema = DataValueSchema_create(1, &subitemField); int8_t metadata = 0x34; DataValueSchemaField fields[2] = { {DATA_TYPE_ARRAY, "a", valueCreateBoolean(false), 0, NULL, subitemSchema}, {DATA_TYPE_STRING, "b", valueCreateString("", 0, false, false), 1, &metadata, NULL} }; DataValueSchema * schema = DataValueSchema_create(2, fields); DataValueSchema_dispose(subitemSchema); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, DATA_VALUE_SCHEMA_FORMAT_TYPE); call_virtual(expectCall, context, __LINE__, context->vtable->writeString, "format_type", DATA_VALUE_SCHEMA_FORMAT_TYPE); call_virtual(expectCall, context, __LINE__, context->vtable->writeUInt16, "format_version", DATA_VALUE_SCHEMA_FORMAT_VERSION); call_virtual(expectCall, context, __LINE__, context->vtable->beginArray, "fields"); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, NULL); call_virtual(expectCall, context, __LINE__, context->vtable->writeEnumeration, "type", DATA_TYPE_ARRAY, sizeof(dataTypeEnumValues) / sizeof(dataTypeEnumValues[0]), dataTypeEnumValues); call_virtual(expectCall, context, __LINE__, context->vtable->writeString, "name", "a"); call_virtual(expectCall, context, __LINE__, context->vtable->writeBlob, "metadata", NULL, 0); call_virtual(expectCall, context, __LINE__, context->vtable->beginArray, "fields"); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, NULL); call_virtual(expectCall, context, __LINE__, context->vtable->writeEnumeration, "type", DATA_TYPE_INT8, sizeof(dataTypeEnumValues) / sizeof(dataTypeEnumValues[0]), dataTypeEnumValues); call_virtual(expectCall, context, __LINE__, context->vtable->writeString, "name", "c"); call_virtual(expectCall, context, __LINE__, context->vtable->writeBlob, "metadata", NULL, 0); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); call_virtual(expectCall, context, __LINE__, context->vtable->endArray, "fields"); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, NULL); call_virtual(expectCall, context, __LINE__, context->vtable->writeEnumeration, "type", DATA_TYPE_STRING, sizeof(dataTypeEnumValues) / sizeof(dataTypeEnumValues[0]), dataTypeEnumValues); call_virtual(expectCall, context, __LINE__, context->vtable->writeString, "name", "b"); call_virtual(expectCall, context, __LINE__, context->vtable->writeBlob, "metadata", &metadata, 1); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); call_virtual(expectCall, context, __LINE__, context->vtable->endArray); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); DataValueSchema_dispose(schema); TestSerializationContext_dispose(context); } static void testDeserialize(void) { jmp_buf jmpEnv; TestDeserializationContext * context = TestDeserializationContext_create(&jmpEnv); if (setjmp(jmpEnv) != 0) { TestCase_assert(false, "%s", context->error); } int8_t metadata = 0x34; call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, DATA_VALUE_SCHEMA_FORMAT_TYPE); call_virtual(expectCall, context, __LINE__, context->vtable->readString, "format_type", DATA_VALUE_SCHEMA_FORMAT_TYPE); call_virtual(expectCall, context, __LINE__, context->vtable->readUInt16, "format_version", DATA_VALUE_SCHEMA_FORMAT_VERSION); call_virtual(expectCall, context, __LINE__, context->vtable->beginArray, "fields", 2); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, NULL); call_virtual(expectCall, context, __LINE__, context->vtable->readEnumeration, "type", DATA_TYPE_ARRAY, sizeof(dataTypeEnumValues) / sizeof(dataTypeEnumValues[0]), dataTypeEnumValues); call_virtual(expectCall, context, __LINE__, context->vtable->readString, "name", "a"); call_virtual(expectCall, context, __LINE__, context->vtable->readBlob, "metadata", NULL, 0); call_virtual(expectCall, context, __LINE__, context->vtable->beginArray, "fields", 1); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, NULL); call_virtual(expectCall, context, __LINE__, context->vtable->readEnumeration, "type", DATA_TYPE_INT8, sizeof(dataTypeEnumValues) / sizeof(dataTypeEnumValues[0]), dataTypeEnumValues); call_virtual(expectCall, context, __LINE__, context->vtable->readString, "name", "c"); call_virtual(expectCall, context, __LINE__, context->vtable->readInt8, "default", 0); call_virtual(expectCall, context, __LINE__, context->vtable->readBlob, "metadata", NULL, 0); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); call_virtual(expectCall, context, __LINE__, context->vtable->endArray, "fields"); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); call_virtual(expectCall, context, __LINE__, context->vtable->beginStructure, NULL); call_virtual(expectCall, context, __LINE__, context->vtable->readEnumeration, "type", DATA_TYPE_STRING, sizeof(dataTypeEnumValues) / sizeof(dataTypeEnumValues[0]), dataTypeEnumValues); call_virtual(expectCall, context, __LINE__, context->vtable->readString, "name", "b"); call_virtual(expectCall, context, __LINE__, context->vtable->readString, "default", ""); call_virtual(expectCall, context, __LINE__, context->vtable->readBlob, "metadata", &metadata, 1); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); call_virtual(expectCall, context, __LINE__, context->vtable->endArray); call_virtual(expectCall, context, __LINE__, context->vtable->endStructure); DataValueSchema * schema = DataValueSchema_deserialize(context); TestDeserializationContext_dispose(context); TestCase_assertPointerNonNULL(schema); TestCase_assertUIntEqual(schema->fieldCount, 2); TestCase_assertPointerNonNULL(schema->fields); TestCase_assertIntEqual(schema->fields[0].type, DATA_TYPE_ARRAY); TestCase_assertStringEqual(schema->fields[0].name, "a"); TestCase_assertSizeEqual(schema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(schema->fields[0].metadata); TestCase_assertPointerNonNULL(schema->fields[0].subitemSchema); TestCase_assertUIntEqual(schema->fields[0].subitemSchema->fieldCount, 1); TestCase_assertPointerNonNULL(schema->fields[0].subitemSchema->fields); TestCase_assertIntEqual(schema->fields[0].subitemSchema->fields[0].type, DATA_TYPE_INT8); TestCase_assertStringEqual(schema->fields[0].subitemSchema->fields[0].name, "c"); TestCase_assertIntEqual(schema->fields[0].subitemSchema->fields[0].defaultValue.type, DATA_TYPE_INT8); TestCase_assertIntEqual(schema->fields[0].subitemSchema->fields[0].defaultValue.value.int8, 0); TestCase_assertSizeEqual(schema->fields[0].subitemSchema->fields[0].metadataSize, 0); TestCase_assertPointerNULL(schema->fields[0].subitemSchema->fields[0].metadata); TestCase_assertPointerNULL(schema->fields[0].subitemSchema->fields[0].subitemSchema); TestCase_assertIntEqual(schema->fields[1].type, DATA_TYPE_STRING); TestCase_assertStringEqual(schema->fields[1].name, "b"); TestCase_assertIntEqual(schema->fields[1].defaultValue.type, DATA_TYPE_STRING); TestCase_assertStringEqual(schema->fields[1].defaultValue.value.string, ""); TestCase_assertSizeEqual(schema->fields[1].metadataSize, 1); TestCase_assertPointerNonNULL(schema->fields[1].metadata); TestCase_assertIntEqual(*(int8_t *) schema->fields[1].metadata, 0x34); TestCase_assertPointerNULL(schema->fields[1].subitemSchema); DataValueSchema_dispose(schema); } TEST_SUITE(DataValueSchemaTest, testCreate, testCopy, testMutate, testSerialize, testDeserialize)