#include "jsonio/JSONParser.h" #include "jsonserialization/JSONDeserializationContext.h" #include "unittest/TestSuite.h" #include "utilities/printfFormats.h" #include "utilities/IOUtilities.h" #include #include #include #define stringAndLength(str) str, strlen(str) static void verifyInit(JSONDeserializationContext * context) { TestCase_assert(context->jmpBuf == NULL, "Expected NULL but got %p", context->jmpBuf); TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); TestCase_assert(context->vtable == &JSONDeserializationContext_class, "Expected %p but got %p", &JSONDeserializationContext_class, context->vtable); } static void testInit(void) { JSONDeserializationContext context, * contextPtr; struct JSONNode node; const char * tempFilePath; int fd; node.type = JSON_TYPE_ARRAY; node.key = NULL; node.value.count = 0; node.subitems = NULL; memset(&context, 0, sizeof(context)); stemobject_assign_vtable(context, JSONDeserializationContext); JSONDeserializationContext_initWithString(&context, stringAndLength("[]")); verifyInit(&context); JSONDeserializationContext_dispose(&context); memset(&context, 0, sizeof(context)); tempFilePath = temporaryFilePath("tmpXXXXXX", &fd); writeFileSimple(tempFilePath, stringAndLength("[]")); stemobject_assign_vtable(context, JSONDeserializationContext); JSONDeserializationContext_initWithFile(&context, tempFilePath); close(fd); unlink(tempFilePath); verifyInit(&context); JSONDeserializationContext_dispose(&context); memset(&context, 0, sizeof(context)); stemobject_assign_vtable(context, JSONDeserializationContext); JSONDeserializationContext_initWithJSONNode(&context, &node); verifyInit(&context); JSONDeserializationContext_dispose(&context); contextPtr = JSONDeserializationContext_createWithString(stringAndLength("[]")); TestCase_assert(contextPtr != NULL, "Expected non-NULL but got NULL"); if (contextPtr == NULL) {return;} // Suppress clang warning verifyInit(contextPtr); JSONDeserializationContext_dispose(contextPtr); tempFilePath = temporaryFilePath("tmpXXXXXX", &fd); writeFileSimple(tempFilePath, stringAndLength("[]")); contextPtr = JSONDeserializationContext_createWithFile(tempFilePath); close(fd); unlink(tempFilePath); TestCase_assert(contextPtr != NULL, "Expected non-NULL but got NULL"); if (contextPtr == NULL) {return;} // Suppress clang warning verifyInit(contextPtr); JSONDeserializationContext_dispose(contextPtr); contextPtr = JSONDeserializationContext_createWithJSONNode(&node); TestCase_assert(contextPtr != NULL, "Expected non-NULL but got NULL"); if (contextPtr == NULL) {return;} // Suppress clang warning verifyInit(contextPtr); JSONDeserializationContext_dispose(contextPtr); } static unsigned int vaArgsToEnumKeyValues(Serialization_enumKeyValue * outValues, ...) { va_list args; va_start(args, outValues); unsigned int valueCount = 0; for (;;) { const char * name = va_arg(args, const char *); if (name == NULL) { break; } outValues[valueCount].key = name; outValues[valueCount].value = va_arg(args, int); valueCount++; } va_end(args); return valueCount; } static unsigned int vaArgsToBitNames(Serialization_bitName * outBitNames, ...) { va_list args; va_start(args, outBitNames); unsigned int bitCount = 0; for (;;) { const char * name = va_arg(args, const char *); if (name == NULL) { break; } outBitNames[bitCount].name = name; outBitNames[bitCount].index = bitCount; bitCount++; } va_end(args); return bitCount; } #define enumKV(value) #value, value #define beginAndVerifyContainer(CONTAINER_TYPE, KEY, EXPECTED_SIZE) { \ size_t size; \ size = call_virtual(begin##CONTAINER_TYPE, context, KEY); \ TestCase_assert(size == (EXPECTED_SIZE), "Expected " SIZE_T_FORMAT " but got " SIZE_T_FORMAT, (size_t) (EXPECTED_SIZE), size); \ } #define beginAndVerifyArray(KEY, EXPECTED_SIZE) beginAndVerifyContainer(Array, KEY, EXPECTED_SIZE) #define beginAndVerifyDictionary(KEY, EXPECTED_SIZE) beginAndVerifyContainer(Dictionary, KEY, EXPECTED_SIZE) #define readFunction_int8_t readInt8 #define readFunction_uint8_t readUInt8 #define readFunction_int16_t readInt16 #define readFunction_uint16_t readUInt16 #define readFunction_int32_t readInt32 #define readFunction_uint32_t readUInt32 #define readFunction_int64_t readInt64 #define readFunction_uint64_t readUInt64 #define readFunction_float readFloat #define readFunction_double readDouble #define readFunction_fixed16_16 readFixed16_16 #define readFunction_bool readBoolean #define printfSpecifier_int8_t "%d" #define printfSpecifier_uint8_t "%u" #define printfSpecifier_int16_t "%d" #define printfSpecifier_uint16_t "%u" #define printfSpecifier_int32_t "%d" #define printfSpecifier_uint32_t "%u" #define printfSpecifier_int64_t INT64_FORMAT #define printfSpecifier_uint64_t UINT64_FORMAT #define printfSpecifier_float "%f" #define printfSpecifier_double "%f" #define printfSpecifier_fixed16_16 "0x%05X" #define printfSpecifier_bool "%d" #define readAndVerifyNumber(TYPE, KEY, EXPECTED_VALUE) { \ TYPE value; \ value = call_virtual(readFunction_##TYPE, context, KEY); \ TestCase_assert(value == (EXPECTED_VALUE), "Expected " printfSpecifier_##TYPE " but got " printfSpecifier_##TYPE, (TYPE) (EXPECTED_VALUE), value); \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); \ } #define readAndVerifyString(KEY, EXPECTED_VALUE) { \ const char * value; \ value = call_virtual(readString, context, KEY); \ TestCase_assert(!strcmp(value, (EXPECTED_VALUE)), "Expected \"%s\" but got \"%s\"", (EXPECTED_VALUE), value); \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); \ } #define readAndVerifyStringNullable(KEY, EXPECTED_VALUE) { \ const char * value; \ value = call_virtual(readStringNullable, context, KEY); \ if ((EXPECTED_VALUE) == NULL) { \ TestCase_assert(value == NULL, "Expected NULL but got \"%s\"", value); \ } else { \ const char * expectedValue = (EXPECTED_VALUE); \ TestCase_assert(value != NULL, "Expected non-NULL but got NULL"); \ TestCase_assert(!strcmp(value, expectedValue), "Expected \"%s\" but got \"%s\"", expectedValue, value); \ } \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); \ } #define readAndVerifyBlob(KEY, EXPECTED_VALUE, EXPECTED_LENGTH) { \ const void * value; \ size_t length; \ value = call_virtual(readBlob, context, KEY, &length); \ if ((EXPECTED_VALUE) == NULL) { \ TestCase_assert(value == NULL, "Expected NULL but got %p", value); \ } else { \ const void * expectedValue = (EXPECTED_VALUE); \ TestCase_assert(value != NULL, "Expected non-NULL but got NULL"); \ TestCase_assert(length == EXPECTED_LENGTH, "Expected " SIZE_T_FORMAT " but got " SIZE_T_FORMAT, (size_t) EXPECTED_LENGTH, length); \ TestCase_assert(!memcmp(value, expectedValue, EXPECTED_LENGTH), "Expected \"%s\" but got \"%s\"", (char *) expectedValue, (char *) value); \ } \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); \ } #define enumReadFunction_int readEnumeration #define enumReadFunction_int8_t readEnumeration8 #define enumReadFunction_int16_t readEnumeration16 #define enumReadFunction_int32_t readEnumeration32 #define printfSpecifier_int "%d" #define readAndVerifyEnumeration(TYPE, KEY, EXPECTED_VALUE, ...) { \ TYPE value; \ Serialization_enumKeyValue values[3]; \ unsigned int valueCount = vaArgsToEnumKeyValues(values, __VA_ARGS__); \ value = call_virtual(enumReadFunction_##TYPE, context, KEY, valueCount, values); \ TestCase_assert(value == (EXPECTED_VALUE), "Expected " printfSpecifier_##TYPE " but got " printfSpecifier_##TYPE, (TYPE) (EXPECTED_VALUE), value); \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); \ } #define printfSpecifier_bitfield8 "0x%02X" #define printfSpecifier_bitfield16 "0x%04X" #define printfSpecifier_bitfield32 "0x%08X" #if defined(WIN32) #define printfSpecifier_bitfield64 "0x%016I64X" #elif defined(linux) && defined(_LP64) #define printfSpecifier_bitfield64 "0x%016lX" #else #define printfSpecifier_bitfield64 "0x%016llX" #endif #define readAndVerifyBitfield(NBITS, KEY, EXPECTED_VALUE, ...) { \ uint##NBITS##_t value; \ Serialization_bitName bitNames[64]; \ unsigned int bitCount = vaArgsToBitNames(bitNames, __VA_ARGS__); \ value = call_virtual(readBitfield##NBITS, context, KEY, bitCount, bitNames); \ TestCase_assert(value == (EXPECTED_VALUE), "Expected " printfSpecifier_bitfield##NBITS " but got " printfSpecifier_bitfield##NBITS, (EXPECTED_VALUE), value); \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); \ } #define verifyReadNextDictionaryKey(KEY) \ key = call_virtual(readNextDictionaryKey, context); \ TestCase_assert(key != NULL, "Expected non-NULL but got NULL"); \ TestCase_assert(!strcmp(key, (KEY)), "Expected \"%s\" but got \"%s\"", (KEY), key); \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); #define verifyHasDictionaryKey(KEY, HAS_KEY) \ TestCase_assert(call_virtual(hasDictionaryKey, context, (KEY)) == (HAS_KEY), "Expected %s but got %s", (HAS_KEY) ? "true" : "false", (HAS_KEY) ? "false" : "true"); \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Got error from operation that should have succeeded: %d", context->status); static void testNumberValues(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \"0xA0000\"]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 11) readAndVerifyNumber(int8_t, "", 0) readAndVerifyNumber(uint8_t, "", 1) readAndVerifyNumber(int16_t, "", 2) readAndVerifyNumber(uint16_t, "", 3) readAndVerifyNumber(int32_t, "", 4) readAndVerifyNumber(uint32_t, "", 5) readAndVerifyNumber(int64_t, "", 6) readAndVerifyNumber(uint64_t, "", 7) readAndVerifyNumber(float, "", 8) readAndVerifyNumber(double, "", 9) readAndVerifyNumber(fixed16_16, "", 0xA0000) call_virtual(endArray, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength("[-128, 255, -32768, 65535, -2147483648, 4294967295, -9007199254740992, 9007199254740992, 9223372036854775808, 9223372036854775808, \"0x80000002\"]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 11) readAndVerifyNumber(int8_t, "", INT8_MIN) readAndVerifyNumber(uint8_t, "", UINT8_MAX) readAndVerifyNumber(int16_t, "", INT16_MIN) readAndVerifyNumber(uint16_t, "", UINT16_MAX) readAndVerifyNumber(int32_t, "", INT32_MIN) readAndVerifyNumber(uint32_t, "", UINT32_MAX) readAndVerifyNumber(int64_t, "", -(1ll << DBL_MANT_DIG)) readAndVerifyNumber(uint64_t, "", 1ull << DBL_MANT_DIG) readAndVerifyNumber(float, "", INT64_MAX) readAndVerifyNumber(double, "", INT64_MAX) readAndVerifyNumber(fixed16_16, "", FIXED_16_16_MIN) call_virtual(endArray, context); call_virtual(dispose, context); } static void testLargeIntegerRepresentations(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[\"-9007199254740993\", \"9007199254740993\", -9007199254740992, 9007199254740992, -9223372036854775808, \"-9223372036854775807\", \"18446744073709551615\"]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 7) readAndVerifyNumber(int64_t, "", -((1ll << DBL_MANT_DIG) + 1)) readAndVerifyNumber(uint64_t, "", (1ull << DBL_MANT_DIG) + 1) readAndVerifyNumber(int64_t, "", -(1ll << DBL_MANT_DIG)) readAndVerifyNumber(uint64_t, "", 1ull << DBL_MANT_DIG) // INT64_MIN is exactly representable as a double, so it must be serialized as a number readAndVerifyNumber(int64_t, "", INT64_MIN) // INT64_MIN + 1 is not representable as a double, so it must be serialized as a string readAndVerifyNumber(int64_t, "", INT64_MIN + 1) readAndVerifyNumber(uint64_t, "", UINT64_MAX) call_virtual(endArray, context); call_virtual(dispose, context); } static void testStringValues(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[\"foo\", \"Hello, world!\", \"null\", null]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 4) readAndVerifyString("", "foo") readAndVerifyString("", "Hello, world!") readAndVerifyStringNullable("", "null") readAndVerifyStringNullable("", NULL) call_virtual(endArray, context); call_virtual(dispose, context); } static void testBlobValues(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[\"Zm9v\", \"SGVsbG8sIHdvcmxkIQ==\", null]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 3) readAndVerifyBlob("", "foo", 3) readAndVerifyBlob("", "Hello, world!", 13) readAndVerifyBlob("", NULL, 0) call_virtual(endArray, context); call_virtual(dispose, context); } static void testBooleanValues(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[false, true]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 2) readAndVerifyNumber(bool, "", false) readAndVerifyNumber(bool, "", true) call_virtual(endArray, context); call_virtual(dispose, context); } #define ENUM_TEST_0 0 #define ENUM_TEST_1 1 #define ENUM_TEST_zero 0 #define ENUM_TEST_one 1 #define ENUM_TEST_two 2 static void testEnumerations(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[\"ENUM_TEST_0\", \"ENUM_TEST_1\", \"ENUM_TEST_zero\", \"ENUM_TEST_one\", \"ENUM_TEST_two\"]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 5) readAndVerifyEnumeration(int, "", ENUM_TEST_0, enumKV(ENUM_TEST_0), enumKV(ENUM_TEST_1), NULL) readAndVerifyEnumeration(int, "", ENUM_TEST_1, enumKV(ENUM_TEST_0), enumKV(ENUM_TEST_1), NULL) readAndVerifyEnumeration(int, "", ENUM_TEST_zero, enumKV(ENUM_TEST_zero), enumKV(ENUM_TEST_one), enumKV(ENUM_TEST_two), NULL) readAndVerifyEnumeration(int, "", ENUM_TEST_one, enumKV(ENUM_TEST_zero), enumKV(ENUM_TEST_one), enumKV(ENUM_TEST_two), NULL) readAndVerifyEnumeration(int, "", ENUM_TEST_two, enumKV(ENUM_TEST_zero), enumKV(ENUM_TEST_one), enumKV(ENUM_TEST_two), NULL) call_virtual(endArray, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength("[\"ENUM_TEST_0\", \"ENUM_TEST_1\", \"ENUM_TEST_zero\", \"ENUM_TEST_one\", \"ENUM_TEST_two\"]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 5) readAndVerifyEnumeration(int8_t, "", ENUM_TEST_0, enumKV(ENUM_TEST_0), enumKV(ENUM_TEST_1), NULL) readAndVerifyEnumeration(int16_t, "", ENUM_TEST_1, enumKV(ENUM_TEST_0), enumKV(ENUM_TEST_1), NULL) readAndVerifyEnumeration(int32_t, "", ENUM_TEST_zero, enumKV(ENUM_TEST_zero), enumKV(ENUM_TEST_one), enumKV(ENUM_TEST_two), NULL) readAndVerifyEnumeration(int8_t, "", ENUM_TEST_one, enumKV(ENUM_TEST_zero), enumKV(ENUM_TEST_one), enumKV(ENUM_TEST_two), NULL) readAndVerifyEnumeration(int16_t, "", ENUM_TEST_two, enumKV(ENUM_TEST_zero), enumKV(ENUM_TEST_one), enumKV(ENUM_TEST_two), NULL) call_virtual(endArray, context); call_virtual(dispose, context); } static void testBitfields(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength( "[" "[\"bit_1\", \"bit_3\", \"bit_5\", \"bit_7\"]," "[\"bit0\", \"bit1\", \"bit2\", \"bit4\", \"bit6\"]," "[\"0\", \"C\", \"D\", \"E\", \"F\"]," "[\"b0\", \"b1\", \"b2\", \"b3\"]," "[\"0\", \"1C\", \"1D\", \"1E\", \"1F\"]," "[\"b1\", \"b2\", \"b3\", \"b4\"]," "[\"0\", \"3C\", \"3D\", \"3E\", \"3F\"]," "[\"b2\", \"b3\", \"b4\", \"b5\"]," "[]," "[]," "[]," "[]" "]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 12) readAndVerifyBitfield(8, "", 0xAA, "bit_0", "bit_1", "bit_2", "bit_3", "bit_4", "bit_5", "bit_6", "bit_7", NULL); readAndVerifyBitfield(8, "", 0x57, "bit0", "bit1", "bit2", "bit3", "bit4", "bit5", "bit6", NULL); readAndVerifyBitfield(16, "", 0xF001, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", NULL); readAndVerifyBitfield(16, "", 0x000F, "b0", "b1", "b2", "b3", "b4", "b5", NULL); readAndVerifyBitfield(32, "", 0xF0000001, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", NULL); readAndVerifyBitfield(32, "", 0x0000001E, "b0", "b1", "b2", "b3", "b4", "b5", NULL); readAndVerifyBitfield(64, "", (uint64_t) 0xF000000000000001ull, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", NULL); readAndVerifyBitfield(64, "", (uint64_t) 0x000000000000003Cull, "b0", "b1", "b2", "b3", "b4", "b5", NULL); readAndVerifyBitfield(8, "", 0x00, NULL); readAndVerifyBitfield(16, "", 0x0000, NULL); readAndVerifyBitfield(32, "", 0x00000000, NULL); readAndVerifyBitfield(64, "", (uint64_t) 0x0000000000000000ull, NULL); call_virtual(endArray, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength( "[" "[\"bit_7\", \"bit_5\", \"bit_3\", \"bit_1\"]," "[\"bit6\", \"bit4\", \"bit2\", \"bit1\", \"bit0\"]," "[\"F\", \"E\", \"D\", \"C\", \"0\"]," "[\"b3\", \"b2\", \"b1\", \"b0\"]," "[\"1F\", \"1E\", \"1D\", \"1C\", \"0\"]," "[\"b4\", \"b3\", \"b2\", \"b1\"]," "[\"3F\", \"3E\", \"3D\", \"3C\", \"0\"]," "[\"b5\", \"b4\", \"b3\", \"b2\"]" "]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 8) readAndVerifyBitfield(8, "", 0xAA, "bit_0", "bit_1", "bit_2", "bit_3", "bit_4", "bit_5", "bit_6", "bit_7", NULL); readAndVerifyBitfield(8, "", 0x57, "bit0", "bit1", "bit2", "bit3", "bit4", "bit5", "bit6", NULL); readAndVerifyBitfield(16, "", 0xF001, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", NULL); readAndVerifyBitfield(16, "", 0x000F, "b0", "b1", "b2", "b3", "b4", "b5", NULL); readAndVerifyBitfield(32, "", 0xF0000001, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", NULL); readAndVerifyBitfield(32, "", 0x0000001E, "b0", "b1", "b2", "b3", "b4", "b5", NULL); readAndVerifyBitfield(64, "", (uint64_t) 0xF000000000000001ull, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", NULL); readAndVerifyBitfield(64, "", (uint64_t) 0x000000000000003Cull, "b0", "b1", "b2", "b3", "b4", "b5", NULL); call_virtual(endArray, context); call_virtual(dispose, context); } static void testArrays(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[[-1], [0, 1, [2, 3, 4, 5, 6, 7], 8, 9, \"0xA0000\", \"10\", null, true, \"enum\", [\"13\"], [\"14\"], [\"15\"], [\"16\"]]]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("", 2) beginAndVerifyArray("", 1) readAndVerifyNumber(int8_t, "", -1) call_virtual(endArray, context); beginAndVerifyArray("", 14) readAndVerifyNumber(int8_t, "", 0) readAndVerifyNumber(uint8_t, "", 1) beginAndVerifyArray("", 6) readAndVerifyNumber(int16_t, "", 2) readAndVerifyNumber(uint16_t, "", 3) readAndVerifyNumber(int32_t, "", 4) readAndVerifyNumber(uint32_t, "", 5) readAndVerifyNumber(int64_t, "", 6) readAndVerifyNumber(uint64_t, "", 7) call_virtual(endArray, context); readAndVerifyNumber(float, "", 8) readAndVerifyNumber(double, "", 9) readAndVerifyNumber(fixed16_16, "", 0xA0000) readAndVerifyString("", "10") readAndVerifyStringNullable("", NULL) readAndVerifyNumber(bool, "", true) readAndVerifyEnumeration(int, "", 12, "enum", 12, NULL) readAndVerifyBitfield(8, "", 0x01, "13", NULL) readAndVerifyBitfield(16, "", 0x0001, "14", NULL) readAndVerifyBitfield(32, "", 0x00000001, "15", NULL) readAndVerifyBitfield(64, "", (uint64_t) 0x0000000000000001ull, "16", NULL) call_virtual(endArray, context); call_virtual(endArray, context); call_virtual(dispose, context); } static void testStructures(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("{\"a\": {\"b\": -1}, \"c\": {\"d\": 0, \"e\": 1, \"f\": {\"g\": 2, \"h\": 3, \"i\": 4, \"j\": 5, \"k\": 6, \"l\": 7}, \"m\": 8, \"n\": 9, \"v\": 655360, \"o\": \"10\", \"w\": null, \"p\": true, \"q\": \"enum\", \"r\": [\"13\"], \"s\": [\"14\"], \"t\": [\"15\"], \"u\": [\"16\"]}}")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "a"); readAndVerifyNumber(int8_t, "b", -1) call_virtual(endStructure, context); call_virtual(beginStructure, context, "c"); readAndVerifyNumber(int8_t, "d", 0) readAndVerifyNumber(uint8_t, "e", 1) call_virtual(beginStructure, context, "f"); readAndVerifyNumber(int16_t, "g", 2) readAndVerifyNumber(uint16_t, "h", 3) readAndVerifyNumber(int32_t, "i", 4) readAndVerifyNumber(uint32_t, "j", 5) readAndVerifyNumber(int64_t, "k", 6) readAndVerifyNumber(uint64_t, "l", 7) call_virtual(endStructure, context); readAndVerifyNumber(float, "m", 8) readAndVerifyNumber(double, "n", 9) readAndVerifyNumber(fixed16_16, "v", 0xA0000) readAndVerifyString("o", "10") readAndVerifyStringNullable("w", NULL) readAndVerifyNumber(bool, "p", true) readAndVerifyEnumeration(int, "q", 12, "enum", 12, NULL) readAndVerifyBitfield(8, "r", 0x01, "13", NULL) readAndVerifyBitfield(16, "s", 0x0001, "14", NULL) readAndVerifyBitfield(32, "t", 0x00000001, "15", NULL) readAndVerifyBitfield(64, "u", (uint64_t) 0x0000000000000001ull, "16", NULL) call_virtual(endStructure, context); call_virtual(endStructure, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength("{\"c\": {\"u\": [\"16\"], \"t\": [\"15\"], \"s\": [\"14\"], \"r\": [\"13\"], \"q\": \"enum\", \"p\": true, \"w\": null, \"o\": \"10\", \"v\": \"0xA0000\", \"n\": 9, \"m\": 8, \"f\": {\"l\": 7, \"k\": 6, \"j\": 5, \"i\": 4, \"h\": 3, \"g\": 2}, \"e\": 1, \"d\": 0}, \"a\": {\"b2\": -10, \"b\": -1}}")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "a"); readAndVerifyNumber(int8_t, "b", -1) readAndVerifyNumber(int8_t, "b2", -10) call_virtual(endStructure, context); call_virtual(beginStructure, context, "c"); readAndVerifyNumber(int8_t, "d", 0) readAndVerifyNumber(uint8_t, "e", 1) call_virtual(beginStructure, context, "f"); readAndVerifyNumber(int16_t, "g", 2) readAndVerifyNumber(uint16_t, "h", 3) readAndVerifyNumber(int32_t, "i", 4) readAndVerifyNumber(uint32_t, "j", 5) readAndVerifyNumber(int64_t, "k", 6) readAndVerifyNumber(uint64_t, "l", 7) call_virtual(endStructure, context); readAndVerifyNumber(float, "m", 8) readAndVerifyNumber(double, "n", 9) readAndVerifyNumber(fixed16_16, "v", 0xA0000) readAndVerifyString("o", "10") readAndVerifyStringNullable("w", NULL) readAndVerifyNumber(bool, "p", true) readAndVerifyEnumeration(int, "q", 12, "enum", 12, NULL) readAndVerifyBitfield(8, "r", 0x01, "13", NULL) readAndVerifyBitfield(16, "s", 0x0001, "14", NULL) readAndVerifyBitfield(32, "t", 0x00000001, "15", NULL) readAndVerifyBitfield(64, "u", (uint64_t) 0x0000000000000001ull, "16", NULL) call_virtual(endStructure, context); call_virtual(endStructure, context); call_virtual(dispose, context); } static void testDictionaries(void) { JSONDeserializationContext * context; const char * key; context = JSONDeserializationContext_createWithString(stringAndLength("{\"a\": {\"b\": -1}, \"c\": {\"d\": 0, \"e\": 1, \"f\": {\"g\": 2, \"h\": 3, \"i\": 4, \"j\": 5, \"k\": 6, \"l\": 7}, \"m\": 8, \"n\": 9, \"v\": 655360, \"o\": \"10\", \"w\": null, \"p\": true, \"q\": \"enum\", \"r\": [\"13\"], \"s\": [\"14\"], \"t\": [\"15\"], \"u\": [\"16\"]}}")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyDictionary("", 2) beginAndVerifyDictionary("a", 1) readAndVerifyNumber(int8_t, "b", -1) call_virtual(endDictionary, context); beginAndVerifyDictionary("c", 14) readAndVerifyNumber(int8_t, "d", 0) readAndVerifyNumber(uint8_t, "e", 1) beginAndVerifyDictionary("f", 6) readAndVerifyNumber(int16_t, "g", 2) readAndVerifyNumber(uint16_t, "h", 3) readAndVerifyNumber(int32_t, "i", 4) readAndVerifyNumber(uint32_t, "j", 5) readAndVerifyNumber(int64_t, "k", 6) readAndVerifyNumber(uint64_t, "l", 7) call_virtual(endDictionary, context); readAndVerifyNumber(float, "m", 8) readAndVerifyNumber(double, "n", 9) readAndVerifyNumber(fixed16_16, "v", 0xA0000) readAndVerifyString("o", "10") readAndVerifyStringNullable("w", NULL) readAndVerifyNumber(bool, "p", true) readAndVerifyEnumeration(int, "q", 12, "enum", 12, NULL) readAndVerifyBitfield(8, "r", 0x01, "13", NULL) readAndVerifyBitfield(16, "s", 0x0001, "14", NULL) readAndVerifyBitfield(32, "t", 0x00000001, "15", NULL) readAndVerifyBitfield(64, "u", (uint64_t) 0x0000000000000001ull, "16", NULL) call_virtual(endDictionary, context); call_virtual(endDictionary, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength("{\"c\": {\"u\": [\"16\"], \"t\": [\"15\"], \"s\": [\"14\"], \"r\": [\"13\"], \"q\": \"enum\", \"p\": true, \"w\": null, \"o\": \"10\", \"v\": \"0xA0000\", \"n\": 9, \"m\": 8, \"f\": {\"l\": 7, \"k\": 6, \"j\": 5, \"i\": 4, \"h\": 3, \"g\": 2}, \"e\": 1, \"d\": 0}, \"a\": {\"b2\": -10, \"b\": -1}}")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyDictionary("", 2) beginAndVerifyDictionary("a", 2) readAndVerifyNumber(int8_t, "b", -1) readAndVerifyNumber(int8_t, "b2", -10) call_virtual(endDictionary, context); beginAndVerifyDictionary("c", 14) readAndVerifyNumber(int8_t, "d", 0) readAndVerifyNumber(uint8_t, "e", 1) beginAndVerifyDictionary("f", 6) readAndVerifyNumber(int16_t, "g", 2) readAndVerifyNumber(uint16_t, "h", 3) readAndVerifyNumber(int32_t, "i", 4) readAndVerifyNumber(uint32_t, "j", 5) readAndVerifyNumber(int64_t, "k", 6) readAndVerifyNumber(uint64_t, "l", 7) call_virtual(endDictionary, context); readAndVerifyNumber(float, "m", 8) readAndVerifyNumber(double, "n", 9) readAndVerifyNumber(fixed16_16, "v", 0xA0000) readAndVerifyString("o", "10") readAndVerifyStringNullable("w", NULL) readAndVerifyNumber(bool, "p", true) readAndVerifyEnumeration(int, "q", 12, "enum", 12, NULL) readAndVerifyBitfield(8, "r", 0x01, "13", NULL) readAndVerifyBitfield(16, "s", 0x0001, "14", NULL) readAndVerifyBitfield(32, "t", 0x00000001, "15", NULL) readAndVerifyBitfield(64, "u", (uint64_t) 0x0000000000000001ull, "16", NULL) call_virtual(endDictionary, context); call_virtual(endDictionary, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength("{\"foo\": {\"bar\": 0, \"baz\": 1, \"bar\": 2}, \"foo\": 3, \"bar\": {\"foo\": 4, \"baz\": 5, \"baz\": 6}}")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyDictionary("", 3) verifyHasDictionaryKey("foo", true) verifyHasDictionaryKey("bar", true) verifyHasDictionaryKey("baz", false) verifyReadNextDictionaryKey("foo") beginAndVerifyDictionary(key, 3) verifyHasDictionaryKey("foo", false) verifyHasDictionaryKey("bar", true) verifyHasDictionaryKey("baz", true) verifyReadNextDictionaryKey("bar") readAndVerifyNumber(double, key, 0) verifyReadNextDictionaryKey("baz") readAndVerifyNumber(double, key, 1) verifyReadNextDictionaryKey("bar") readAndVerifyNumber(double, key, 2) call_virtual(endDictionary, context); verifyReadNextDictionaryKey("foo") readAndVerifyNumber(double, key, 3) verifyReadNextDictionaryKey("bar") beginAndVerifyDictionary(key, 3) verifyHasDictionaryKey("foo", true) verifyHasDictionaryKey("bar", false) verifyHasDictionaryKey("baz", true) verifyReadNextDictionaryKey("foo") readAndVerifyNumber(double, key, 4) verifyReadNextDictionaryKey("baz") readAndVerifyNumber(double, key, 5) verifyReadNextDictionaryKey("baz") readAndVerifyNumber(double, key, 6) call_virtual(endDictionary, context); call_virtual(endDictionary, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithString(stringAndLength("{\"\": -1, \"\": 0, \"\": 1, \"\": 2, \"\": 3, \"\": 4, \"\": 5, \"\": 6, \"\": 7, \"\": 8, \"\": 9, \"\": \"0xA0000\", \"\": \"10\", \"\": null, \"\": true, \"\": \"enum\", \"\": [\"13\"], \"\": [\"14\"], \"\": [\"15\"], \"\": [\"16\"], \"\": [], \"\": {}, \"\": {\"\": 0, \"\": 0}}")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyDictionary("", 23) verifyHasDictionaryKey("", true) verifyHasDictionaryKey(" ", false) verifyReadNextDictionaryKey("") readAndVerifyNumber(int8_t, key, -1) verifyReadNextDictionaryKey("") readAndVerifyNumber(int8_t, key, 0) verifyReadNextDictionaryKey("") readAndVerifyNumber(uint8_t, key, 1) verifyReadNextDictionaryKey("") readAndVerifyNumber(int16_t, key, 2) verifyReadNextDictionaryKey("") readAndVerifyNumber(uint16_t, key, 3) verifyReadNextDictionaryKey("") readAndVerifyNumber(int32_t, key, 4) verifyReadNextDictionaryKey("") readAndVerifyNumber(uint32_t, key, 5) verifyReadNextDictionaryKey("") readAndVerifyNumber(int64_t, key, 6) verifyReadNextDictionaryKey("") readAndVerifyNumber(uint64_t, key, 7) verifyReadNextDictionaryKey("") readAndVerifyNumber(float, key, 8) verifyReadNextDictionaryKey("") readAndVerifyNumber(double, key, 9) verifyReadNextDictionaryKey("") readAndVerifyNumber(fixed16_16, key, 0xA0000) verifyReadNextDictionaryKey("") readAndVerifyString(key, "10") verifyReadNextDictionaryKey("") readAndVerifyStringNullable(key, NULL) verifyReadNextDictionaryKey("") readAndVerifyNumber(bool, key, true) verifyReadNextDictionaryKey("") readAndVerifyEnumeration(int, key, 12, "enum", 12, NULL) verifyReadNextDictionaryKey("") readAndVerifyBitfield(8, key, 0x01, "13", NULL) verifyReadNextDictionaryKey("") readAndVerifyBitfield(16, key, 0x0001, "14", NULL) verifyReadNextDictionaryKey("") readAndVerifyBitfield(32, key, 0x00000001, "15", NULL) verifyReadNextDictionaryKey("") readAndVerifyBitfield(64, key, (uint64_t) 0x0000000000000001ull, "16", NULL) verifyReadNextDictionaryKey("") beginAndVerifyArray(key, 0) call_virtual(endArray, context); verifyReadNextDictionaryKey("") call_virtual(beginStructure, context, key); call_virtual(endStructure, context); verifyReadNextDictionaryKey("") beginAndVerifyDictionary(key, 2) call_virtual(endDictionary, context); call_virtual(endDictionary, context); call_virtual(dispose, context); } static void testMixedContainers(void) { JSONDeserializationContext * context; context = JSONDeserializationContext_createWithString(stringAndLength("[{\"innerArray\": [], \"innerDict\": {}}, {\"innerArray2\": [], \"innerStruct\": {}}]")); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning beginAndVerifyArray("outerArray", 2) call_virtual(beginStructure, context, "outerStruct"); beginAndVerifyArray("innerArray", 0) call_virtual(endArray, context); beginAndVerifyDictionary("innerDict", 0) call_virtual(endDictionary, context); call_virtual(endStructure, context); beginAndVerifyDictionary("outerDict", 2) beginAndVerifyArray("innerArray2", 0) call_virtual(endArray, context); call_virtual(beginStructure, context, "innerStruct"); call_virtual(endStructure, context); call_virtual(endDictionary, context); call_virtual(endArray, context); call_virtual(dispose, context); } #define performActionWithTemporaryFile(STRING, ACTION) { \ const char * tempFilePath; \ int fd; \ \ tempFilePath = temporaryFilePath("tmpXXXXXX", &fd); \ writeFileSimple(tempFilePath, (STRING), strlen(STRING)); \ ACTION(tempFilePath) \ close(fd); \ unlink(tempFilePath); \ } #define initContextWithFile(FILE_PATH) \ stemobject_assign_vtable(context2, JSONDeserializationContext); \ JSONDeserializationContext_initWithFile(&context2, FILE_PATH); \ context = &context2; #define initContextFromTemporaryFile(STRING) performActionWithTemporaryFile(STRING, initContextWithFile) #define createContextWithFile(FILE_PATH) context = JSONDeserializationContext_createWithFile(tempFilePath); #define createContextFromTemporaryFile(STRING) performActionWithTemporaryFile(STRING, initContextWithFile) static void testInitWithFile(void) { JSONDeserializationContext * context, context2; initContextFromTemporaryFile("[\"foo\"]") TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); beginAndVerifyArray("", 1) readAndVerifyString("", "foo") call_virtual(endArray, context); call_virtual(dispose, context); initContextFromTemporaryFile("[\"bar\"]") TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); beginAndVerifyArray("", 1) readAndVerifyString("", "bar") call_virtual(endArray, context); call_virtual(dispose, context); createContextFromTemporaryFile("[\"foo\"]") TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); beginAndVerifyArray("", 1) readAndVerifyString("", "foo") call_virtual(endArray, context); call_virtual(dispose, context); createContextFromTemporaryFile("[\"bar\"]") TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); beginAndVerifyArray("", 1) readAndVerifyString("", "bar") call_virtual(endArray, context); call_virtual(dispose, context); } static void testInitWithJSONNode(void) { JSONDeserializationContext * context, context2; struct JSONNode * node; node = JSONParser_loadString(stringAndLength("[\"foo\"]"), NULL); TestCase_assert(node != NULL, "Expected non-NULL but got NULL"); if (node == NULL) {return;} // Suppress clang warning stemobject_assign_vtable(context2, JSONDeserializationContext); JSONDeserializationContext_initWithJSONNode(&context2, node); context = &context2; TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); TestCase_assert(context->rootNode != node, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems != node->subitems, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems[0].value.string != node->subitems[0].value.string, "Pointers expected to differ, but didn't"); beginAndVerifyArray("", 1) readAndVerifyString("", "foo") call_virtual(endArray, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithJSONNode(node); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); TestCase_assert(context->rootNode != node, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems != node->subitems, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems[0].value.string != node->subitems[0].value.string, "Pointers expected to differ, but didn't"); beginAndVerifyArray("", 1) readAndVerifyString("", "foo") call_virtual(endArray, context); call_virtual(dispose, context); JSONNode_dispose(node); node = JSONParser_loadString(stringAndLength("[\"bar\"]"), NULL); TestCase_assert(node != NULL, "Expected non-NULL but got NULL"); if (node == NULL) {return;} // Suppress clang warning stemobject_assign_vtable(context2, JSONDeserializationContext); JSONDeserializationContext_initWithJSONNode(&context2, node); context = &context2; TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); TestCase_assert(context->rootNode != node, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems != node->subitems, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems[0].value.string != node->subitems[0].value.string, "Pointers expected to differ, but didn't"); beginAndVerifyArray("", 1) readAndVerifyString("", "bar") call_virtual(endArray, context); call_virtual(dispose, context); context = JSONDeserializationContext_createWithJSONNode(node); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d", SERIALIZATION_ERROR_OK, context->status); TestCase_assert(context->rootNode != node, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems != node->subitems, "Pointers expected to differ, but didn't"); TestCase_assert(context->rootNode->subitems[0].value.string != node->subitems[0].value.string, "Pointers expected to differ, but didn't"); beginAndVerifyArray("", 1) readAndVerifyString("", "bar") call_virtual(endArray, context); call_virtual(dispose, context); JSONNode_dispose(node); } static void testErrorReporting(void) { JSONDeserializationContext * context, context2; jmp_buf jmpBuf; int status; context = JSONDeserializationContext_createWithJSONNode(NULL); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context->status); call_virtual(dispose, context); stemobject_assign_vtable(context2, JSONDeserializationContext); JSONDeserializationContext_initWithJSONNode(&context2, NULL); TestCase_assert(context2.status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context2.status); JSONDeserializationContext_dispose(&context2); context = JSONDeserializationContext_createWithFile("If this file exists, unit tests will fail"); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context->status); call_virtual(dispose, context); stemobject_assign_vtable(context2, JSONDeserializationContext); JSONDeserializationContext_initWithFile(&context2, "If this file exists, unit tests will fail"); TestCase_assert(context2.status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context2.status); JSONDeserializationContext_dispose(&context2); context = JSONDeserializationContext_createWithString(NULL, 0); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context->status); call_virtual(dispose, context); stemobject_assign_vtable(context2, JSONDeserializationContext); JSONDeserializationContext_initWithString(&context2, NULL, 0); TestCase_assert(context2.status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context2.status); JSONDeserializationContext_dispose(&context2); context = JSONDeserializationContext_createWithString("", 0); TestCase_assert(context != NULL, "Expected non-NULL but got NULL"); if (context == NULL) {return;} // Suppress clang warning TestCase_assert(context->status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context->status); call_virtual(dispose, context); stemobject_assign_vtable(context2, JSONDeserializationContext); JSONDeserializationContext_initWithString(&context2, "", 0); TestCase_assert(context2.status == JSON_SERIALIZATION_ERROR_INVALID_JSON, "Expected %d but got %d", JSON_SERIALIZATION_ERROR_INVALID_JSON, context2.status); JSONDeserializationContext_dispose(&context2); #define _testFailure(STRING, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ context = JSONDeserializationContext_createWithString(STRING, strlen(STRING)); \ PREAMBLE_CODE \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d (OK)", SERIALIZATION_ERROR_OK, context->status); \ FAIL_CODE \ TestCase_assert(context->status == ERROR_STATUS, "Expected %d but got %d (context->status)", ERROR_STATUS, context->status); \ call_virtual(dispose, context); \ \ context = JSONDeserializationContext_createWithString(STRING, strlen(STRING)); \ context->jmpBuf = &jmpBuf; \ status = setjmp(jmpBuf); \ if (!status) { \ PREAMBLE_CODE \ TestCase_assert(context->status == SERIALIZATION_ERROR_OK, "Expected %d but got %d (OK setjmp)", SERIALIZATION_ERROR_OK, context->status); \ FAIL_CODE \ } \ TestCase_assert(status == ERROR_STATUS, "Expected %d but got %d (status setjmp)", ERROR_STATUS, status); \ TestCase_assert(context->status == ERROR_STATUS, "Expected %d but got %d (context->status setjmp)", ERROR_STATUS, context->status); \ call_virtual(dispose, context); _testFailure("[\"a\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) _testFailure("[\"a\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) _testFailure("[\"-9007199254740992\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) _testFailure("[\"9007199254740992\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) _testFailure("[\"-9007199254740993 foo\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) _testFailure("[\"bar -9007199254740993\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) _testFailure("[\"9007199254740993 bar\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) _testFailure("[\"foo 9007199254740993\"]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) _testFailure("[-129]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt8, context, "");) _testFailure("[128]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt8, context, "");) _testFailure("[-1]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt8, context, "");) _testFailure("[256]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt8, context, "");) _testFailure("[-32769]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt16, context, "");) _testFailure("[32768]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt16, context, "");) _testFailure("[-1]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt16, context, "");) _testFailure("[65536]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt16, context, "");) _testFailure("[-2147483649]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt32, context, "");) _testFailure("[2147483648]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt32, context, "");) _testFailure("[-1]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt32, context, "");) _testFailure("[4294967296]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt32, context, "");) /* _testFailure("[-18446744073709551616]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) _testFailure("[18446744073709551616]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) */ _testFailure("[-1]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) /* _testFailure("[36893488147419103232]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) _testFailure("[-680564733841876926926749214863536422912]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readFloat, context, "");) _testFailure("[680564733841876926926749214863536422912]", SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE, call_virtual(beginArray, context, "");, call_virtual(readFloat, context, "");) */ #define _testFiveFailures(STRING_1, STRING_2, STRING_3, STRING_4, STRING_5, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_1, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_2, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_3, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_4, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_5, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) #define _testFourFailures(STRING_1, STRING_2, STRING_3, STRING_4, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_1, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_2, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_3, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) \ _testFailure(STRING_4, ERROR_STATUS, PREAMBLE_CODE, FAIL_CODE) _testFailure("{}", SERIALIZATION_ERROR_INCORRECT_TYPE, , call_virtual(beginArray, context, "");) _testFiveFailures("[{}]", "[\"\"]", "[0]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(beginArray, context, "");) _testFailure("[]", SERIALIZATION_ERROR_INCORRECT_TYPE, , call_virtual(beginStructure, context, "");) _testFiveFailures("[[]]", "[\"\"]", "[0]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(beginStructure, context, "");) _testFailure("[]", SERIALIZATION_ERROR_INCORRECT_TYPE, , call_virtual(beginDictionary, context, "");) _testFiveFailures("[[]]", "[\"\"]", "[0]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(beginDictionary, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt8, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt8, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt16, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt16, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt32, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt32, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readInt64, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readUInt64, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readFloat, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readDouble, context, "");) _testFiveFailures("[{}]", "[[]]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readFixed16_16, context, "");) _testFiveFailures("[{}]", "[[]]", "[0]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readString, context, "");) _testFourFailures("[{}]", "[[]]", "[0]", "[false]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readStringNullable, context, "");) _testFiveFailures("[{}]", "[[]]", "[0]", "[\"\"]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readBoolean, context, "");) _testFiveFailures("[{}]", "[[]]", "[0]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readEnumeration, context, "", 0, NULL);) _testFiveFailures("[{}]", "[0]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readBitfield8, context, "", 0, NULL);) _testFiveFailures("[{}]", "[0]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readBitfield16, context, "", 0, NULL);) _testFiveFailures("[{}]", "[0]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readBitfield32, context, "", 0, NULL);) _testFiveFailures("[{}]", "[0]", "[\"\"]", "[false]", "[null]", SERIALIZATION_ERROR_INCORRECT_TYPE, call_virtual(beginArray, context, "");, call_virtual(readBitfield64, context, "", 0, NULL);) #undef _testFiveFailures static Serialization_enumKeyValue testEnumValue = {"enum", 0}; static Serialization_bitName testBitName = {"", 0}; #define _testEndOfArray(READ_CODE) \ _testFailure("[]", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginArray, context, "");, READ_CODE) \ _testFailure("[0]", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginArray, context, ""); call_virtual(readInt8, context, "");, READ_CODE) \ _testFailure("[[], 0]", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, "");, READ_CODE) \ _testFailure("[[0], 0]", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, ""); call_virtual(readInt8, context, "");, READ_CODE) _testEndOfArray(call_virtual(beginArray, context, "");) _testEndOfArray(call_virtual(beginStructure, context, "");) _testEndOfArray(call_virtual(beginDictionary, context, "");) _testEndOfArray(call_virtual(readInt8, context, "");) _testEndOfArray(call_virtual(readUInt8, context, "");) _testEndOfArray(call_virtual(readInt16, context, "");) _testEndOfArray(call_virtual(readUInt16, context, "");) _testEndOfArray(call_virtual(readInt32, context, "");) _testEndOfArray(call_virtual(readUInt32, context, "");) _testEndOfArray(call_virtual(readInt64, context, "");) _testEndOfArray(call_virtual(readUInt64, context, "");) _testEndOfArray(call_virtual(readFloat, context, "");) _testEndOfArray(call_virtual(readDouble, context, "");) _testEndOfArray(call_virtual(readFixed16_16, context, "");) _testEndOfArray(call_virtual(readString, context, "");) _testEndOfArray(call_virtual(readStringNullable, context, "");) _testEndOfArray(call_virtual(readBoolean, context, "");) _testEndOfArray(call_virtual(readEnumeration, context, "", 1, &testEnumValue);) _testEndOfArray(call_virtual(readBitfield8, context, "", 1, &testBitName);) _testEndOfArray(call_virtual(readBitfield16, context, "", 1, &testBitName);) _testEndOfArray(call_virtual(readBitfield32, context, "", 1, &testBitName);) _testEndOfArray(call_virtual(readBitfield64, context, "", 1, &testBitName);) #undef _testEndOfArray _testFailure("{}", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginDictionary, context, "");, call_virtual(readNextDictionaryKey, context);) _testFailure("{\"\": 0}", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginDictionary, context, ""); call_virtual(readNextDictionaryKey, context);, call_virtual(readNextDictionaryKey, context);) _testFailure("{\"\": {}, \"a\": 0}", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginDictionary, context, ""); call_virtual(beginDictionary, context, "");, call_virtual(readNextDictionaryKey, context);) _testFailure("{\"\": {\"\": 0}, \"a\": 0}", SERIALIZATION_ERROR_END_OF_CONTAINER, call_virtual(beginDictionary, context, ""); call_virtual(beginDictionary, context, ""); call_virtual(readNextDictionaryKey, context);, call_virtual(readNextDictionaryKey, context);) #define _testNoSuchKey(READ_CODE) \ _testFailure("{}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginStructure, context, "");, READ_CODE) \ _testFailure("{\"a\": 0}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginStructure, context, "");, READ_CODE) \ _testFailure("{\"\": {}, \"a\": 0}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "");, READ_CODE) \ _testFailure("{\"\": {\"a\": 0}, \"a\": 0}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "");, READ_CODE) \ _testFailure("{}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginDictionary, context, "");, READ_CODE) \ _testFailure("{\"a\": 0}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginDictionary, context, "");, READ_CODE) \ _testFailure("{\"\": {}, \"a\": 0}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginDictionary, context, ""); call_virtual(beginDictionary, context, "");, READ_CODE) \ _testFailure("{\"\": {\"a\": 0}, \"a\": 0}", SERIALIZATION_ERROR_KEY_NOT_FOUND, call_virtual(beginDictionary, context, ""); call_virtual(beginDictionary, context, "");, READ_CODE) _testNoSuchKey(call_virtual(beginArray, context, "");) _testNoSuchKey(call_virtual(beginStructure, context, "");) _testNoSuchKey(call_virtual(beginDictionary, context, "");) _testNoSuchKey(call_virtual(readInt8, context, "");) _testNoSuchKey(call_virtual(readUInt8, context, "");) _testNoSuchKey(call_virtual(readInt16, context, "");) _testNoSuchKey(call_virtual(readUInt16, context, "");) _testNoSuchKey(call_virtual(readInt32, context, "");) _testNoSuchKey(call_virtual(readUInt32, context, "");) _testNoSuchKey(call_virtual(readInt64, context, "");) _testNoSuchKey(call_virtual(readUInt64, context, "");) _testNoSuchKey(call_virtual(readFloat, context, "");) _testNoSuchKey(call_virtual(readDouble, context, "");) _testNoSuchKey(call_virtual(readFixed16_16, context, "");) _testNoSuchKey(call_virtual(readString, context, "");) _testNoSuchKey(call_virtual(readStringNullable, context, "");) _testNoSuchKey(call_virtual(readBoolean, context, "");) _testNoSuchKey(call_virtual(readEnumeration, context, "", 1, &testEnumValue);) _testNoSuchKey(call_virtual(readBitfield8, context, "", 1, &testBitName);) _testNoSuchKey(call_virtual(readBitfield16, context, "", 1, &testBitName);) _testNoSuchKey(call_virtual(readBitfield32, context, "", 1, &testBitName);) _testNoSuchKey(call_virtual(readBitfield64, context, "", 1, &testBitName);) #undef _testNoSuchKey _testFailure("{\"foo\": 0, \"foo\": 1, \"bar\": 2}", JSON_SERIALIZATION_ERROR_DUPLICATE_STRUCTURE_KEY, , call_virtual(beginStructure, context, "");) _testFailure("{\"\": {\"bar\": 0, \"foo\": 1, \"bar\": 2}}", JSON_SERIALIZATION_ERROR_DUPLICATE_STRUCTURE_KEY, call_virtual(beginStructure, context, "");, call_virtual(beginStructure, context, "");) _testFailure("{\"bar\": 0, \"foo\": 1, \"foo\": 2}", JSON_SERIALIZATION_ERROR_DUPLICATE_STRUCTURE_KEY, , call_virtual(beginStructure, context, "");) _testFailure("[[\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"]]", JSON_SERIALIZATION_ERROR_TOO_MANY_BITS, call_virtual(beginArray, context, "");, call_virtual(readBitfield8, context, "", 0, NULL);) _testFailure("[[\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\"]]", JSON_SERIALIZATION_ERROR_TOO_MANY_BITS, call_virtual(beginArray, context, "");, call_virtual(readBitfield16, context, "", 0, NULL);) _testFailure("[[\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\", \"20\", \"21\", \"22\", \"23\", \"24\", \"25\", \"26\", \"27\", \"28\", \"29\", \"30\", \"31\", \"32\"]]", JSON_SERIALIZATION_ERROR_TOO_MANY_BITS, call_virtual(beginArray, context, "");, call_virtual(readBitfield32, context, "", 0, NULL);) _testFailure("[[\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\", \"20\", \"21\", \"22\", \"23\", \"24\", \"25\", \"26\", \"27\", \"28\", \"29\", \"30\", \"31\", \"32\", \"33\", \"34\", \"35\", \"36\", \"37\", \"38\", \"39\", \"40\", \"41\", \"42\", \"43\", \"44\", \"45\", \"46\", \"47\", \"48\", \"49\", \"50\", \"51\", \"52\", \"53\", \"54\", \"55\", \"56\", \"57\", \"58\", \"59\", \"60\", \"61\", \"62\", \"63\", \"64\"]]", JSON_SERIALIZATION_ERROR_TOO_MANY_BITS, call_virtual(beginArray, context, "");, call_virtual(readBitfield64, context, "", 0, NULL);) #define _testReadBitfieldFailure(STRING, ERROR, ...) { \ Serialization_bitName bitNames[2]; \ unsigned int bitNameCount = vaArgsToBitNames(bitNames, __VA_ARGS__); \ _testFailure(STRING, ERROR, call_virtual(beginArray, context, "");, call_virtual(readBitfield8, context, "", bitNameCount, bitNames);) \ _testFailure(STRING, ERROR, call_virtual(beginArray, context, "");, call_virtual(readBitfield16, context, "", bitNameCount, bitNames);) \ _testFailure(STRING, ERROR, call_virtual(beginArray, context, "");, call_virtual(readBitfield32, context, "", bitNameCount, bitNames);) \ _testFailure(STRING, ERROR, call_virtual(beginArray, context, "");, call_virtual(readBitfield64, context, "", bitNameCount, bitNames);) \ } _testReadBitfieldFailure("[[\"not_a_bit\"]]", SERIALIZATION_ERROR_UNNAMED_BIT, NULL) _testReadBitfieldFailure("[[\"not_a_bit\"]]", SERIALIZATION_ERROR_UNNAMED_BIT, "a_bit", NULL) _testReadBitfieldFailure("[[{}]]", SERIALIZATION_ERROR_INCORRECT_TYPE, NULL) _testReadBitfieldFailure("[[[]]]", SERIALIZATION_ERROR_INCORRECT_TYPE, NULL) _testReadBitfieldFailure("[[0]]", SERIALIZATION_ERROR_INCORRECT_TYPE, NULL) _testReadBitfieldFailure("[[false]]", SERIALIZATION_ERROR_INCORRECT_TYPE, NULL) _testReadBitfieldFailure("[[null]]", SERIALIZATION_ERROR_INCORRECT_TYPE, NULL) _testReadBitfieldFailure("[[\"a_bit\", \"a_bit\"]]", JSON_SERIALIZATION_ERROR_DUPLICATE_BIT_NAME, "a_bit", NULL); _testReadBitfieldFailure("[[\"not_a_bit\", \"not_a_bit\"]]", JSON_SERIALIZATION_ERROR_DUPLICATE_BIT_NAME, "a_bit", NULL); _testReadBitfieldFailure("[[\"not_a_bit\", \"not_a_bit\", \"a_bit\"]]", JSON_SERIALIZATION_ERROR_DUPLICATE_BIT_NAME, "a_bit", NULL); _testReadBitfieldFailure("[[\"not_a_bit\", \"a_bit\", \"not_a_bit\"]]", JSON_SERIALIZATION_ERROR_DUPLICATE_BIT_NAME, "a_bit", NULL); _testReadBitfieldFailure("[[\"a_bit\", \"not_a_bit\", \"not_a_bit\"]]", JSON_SERIALIZATION_ERROR_DUPLICATE_BIT_NAME, "a_bit", NULL); _testReadBitfieldFailure("[[\"a_bit\", \"a_bit\", null]]", JSON_SERIALIZATION_ERROR_DUPLICATE_BIT_NAME, "a_bit", NULL); _testReadBitfieldFailure("[[\"a_bit\", null, \"a_bit\"]]", SERIALIZATION_ERROR_INCORRECT_TYPE, "a_bit", NULL); _testReadBitfieldFailure("[[null, \"a_bit\", \"a_bit\"]]", SERIALIZATION_ERROR_INCORRECT_TYPE, "a_bit", NULL); #undef _testReadBitfieldFailure _testFailure("[\"a\"]", SERIALIZATION_ERROR_ENUM_NOT_NAMED, call_virtual(beginArray, context, "");, call_virtual(readEnumeration, context, "", 0, NULL);) _testFailure("[\"a\"]", SERIALIZATION_ERROR_ENUM_NOT_NAMED, call_virtual(beginArray, context, "");, call_virtual(readEnumeration, context, "", 1, &testEnumValue);) Serialization_enumKeyValue duplicateEnumValues[] = {{"enum0", 0}, {"enum1", 0}}; _testFailure("[\"enum0\"]", SERIALIZATION_ERROR_DUPLICATE_ENUM_VALUE, call_virtual(beginArray, context, "");, call_virtual(readEnumeration, context, "", 2, duplicateEnumValues);) Serialization_enumKeyValue duplicateEnumNames[] = {{"enum0", 0}, {"enum0", 1}}; _testFailure("[\"enum0\"]", SERIALIZATION_ERROR_DUPLICATE_ENUM_NAME, call_virtual(beginArray, context, "");, call_virtual(readEnumeration, context, "", 2, duplicateEnumNames);) _testFailure("[]", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginArray, context, "");, call_virtual(hasDictionaryKey, context, "");) _testFailure("[]", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginArray, context, "");, call_virtual(readNextDictionaryKey, context);) _testFailure("[[]]", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, "");, call_virtual(hasDictionaryKey, context, "");) _testFailure("[[]]", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, "");, call_virtual(readNextDictionaryKey, context);) _testFailure("{}", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginStructure, context, "");, call_virtual(hasDictionaryKey, context, "");) _testFailure("{}", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginStructure, context, "");, call_virtual(readNextDictionaryKey, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "");, call_virtual(hasDictionaryKey, context, "");) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_INVALID_OPERATION, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "");, call_virtual(readNextDictionaryKey, context);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readInt8, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readUInt8, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readInt16, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readUInt16, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readInt32, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readUInt32, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readInt64, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readUInt64, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readFloat, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readDouble, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readFixed16_16, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readString, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readStringNullable, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readBoolean, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readEnumeration, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readBitfield8, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readBitfield16, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readBitfield32, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginStructure, context, "");, call_virtual(readBitfield64, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readInt8, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readUInt8, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readInt16, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readUInt16, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readInt32, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readUInt32, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readInt64, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readUInt64, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readFloat, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readDouble, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readFixed16_16, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readString, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readStringNullable, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readBoolean, context, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readEnumeration, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readBitfield8, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readBitfield16, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readBitfield32, context, NULL, 0, NULL);) _testFailure("{}", SERIALIZATION_ERROR_NULL_KEY, call_virtual(beginDictionary, context, "");, call_virtual(readBitfield64, context, NULL, 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(beginArray, context, "");) _testFailure("[]", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(beginDictionary, context, "");) _testFailure("[]", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(beginStructure, context, "");) _testFailure("{}", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginStructure, context, ""); call_virtual(endStructure, context);, call_virtual(beginArray, context, "");) _testFailure("{}", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginStructure, context, ""); call_virtual(endStructure, context);, call_virtual(beginDictionary, context, "");) _testFailure("{}", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginStructure, context, ""); call_virtual(endStructure, context);, call_virtual(beginStructure, context, "");) _testFailure("{}", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginDictionary, context, ""); call_virtual(endDictionary, context);, call_virtual(beginArray, context, "");) _testFailure("{}", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginDictionary, context, ""); call_virtual(endDictionary, context);, call_virtual(beginDictionary, context, "");) _testFailure("{}", SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS, call_virtual(beginDictionary, context, ""); call_virtual(endDictionary, context);, call_virtual(beginStructure, context, "");) _testFailure("[]", SERIALIZATION_ERROR_CONTAINER_UNDERFLOW, ;, call_virtual(endArray, context);) _testFailure("[[]]", SERIALIZATION_ERROR_CONTAINER_UNDERFLOW, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, ""); call_virtual(endArray, context); call_virtual(endArray, context);, call_virtual(endArray, context);) _testFailure("{}", SERIALIZATION_ERROR_CONTAINER_UNDERFLOW, ;, call_virtual(endStructure, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_CONTAINER_UNDERFLOW, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, ""); call_virtual(endStructure, context); call_virtual(endStructure, context);, call_virtual(endStructure, context);) _testFailure("{}", SERIALIZATION_ERROR_CONTAINER_UNDERFLOW, ;, call_virtual(endDictionary, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_CONTAINER_UNDERFLOW, call_virtual(beginDictionary, context, ""); call_virtual(endDictionary, context);, call_virtual(endDictionary, context);) _testFailure("[]", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginArray, context, "");, call_virtual(endStructure, context);) _testFailure("[[]]", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, "");, call_virtual(endStructure, context);) _testFailure("[]", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginArray, context, "");, call_virtual(endDictionary, context);) _testFailure("[[]]", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginArray, context, ""); call_virtual(beginArray, context, "");, call_virtual(endDictionary, context);) _testFailure("{}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginStructure, context, "");, call_virtual(endArray, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "");, call_virtual(endArray, context);) _testFailure("{}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginStructure, context, "");, call_virtual(endDictionary, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginStructure, context, ""); call_virtual(beginStructure, context, "");, call_virtual(endDictionary, context);) _testFailure("{}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginDictionary, context, "");, call_virtual(endArray, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginDictionary, context, ""); call_virtual(beginDictionary, context, "");, call_virtual(endArray, context);) _testFailure("{}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginDictionary, context, "");, call_virtual(endStructure, context);) _testFailure("{\"\": {}}", SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH, call_virtual(beginDictionary, context, ""); call_virtual(beginDictionary, context, "");, call_virtual(endStructure, context);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readInt8, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readUInt8, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readInt16, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readUInt16, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readInt32, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readUInt32, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readInt64, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readUInt64, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readFloat, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readDouble, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readFixed16_16, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readString, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readStringNullable, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readBoolean, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readEnumeration, context, "key", 1, &testEnumValue);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readBitfield8, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readBitfield16, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readBitfield32, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, , call_virtual(readBitfield64, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readInt8, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readUInt8, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readInt16, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readUInt16, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readInt32, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readUInt32, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readInt64, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readUInt64, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readFloat, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readDouble, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readFixed16_16, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readString, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readStringNullable, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readBoolean, context, "key");) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readEnumeration, context, "key", 1, &testEnumValue);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readBitfield8, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readBitfield16, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readBitfield32, context, "key", 0, NULL);) _testFailure("[]", SERIALIZATION_ERROR_NO_CONTAINER_STARTED, call_virtual(beginArray, context, ""); call_virtual(endArray, context);, call_virtual(readBitfield64, context, "key", 0, NULL);) _testFailure("[0]", JSON_SERIALIZATION_ERROR_CONTAINER_NOT_FULLY_READ, call_virtual(beginArray, context, "");, call_virtual(endArray, context);) #undef _testFailure } TEST_SUITE(JSONDeserializationContextTest, testInit, testNumberValues, testLargeIntegerRepresentations, testStringValues, testBlobValues, testBooleanValues, testEnumerations, testBitfields, testArrays, testStructures, testDictionaries, testMixedContainers, testInitWithFile, testInitWithJSONNode, testErrorReporting)