#include "inputcontroller/InputRecorder.h" #include "unittest/TestSuite.h" #include "utilities/IOUtilities.h" #include "utilities/printfFormats.h" #include #include static void verifyInit(InputRecorder * inputRecorder, InputController * inputController, bool fileOutput, unsigned int lineNumber) { TestCase_assert(inputRecorder != NULL, "Expected non-NULL but got NULL (%u)", lineNumber); TestCase_assert(inputRecorder->vtable == &InputRecorder_class, "Expected %p but got %p (%u)", &InputRecorder_class, inputRecorder->vtable, lineNumber); TestCase_assert(inputRecorder->inputController == inputController, "Expected %p but got %p (%u)", inputController, inputRecorder->inputController, lineNumber); TestCase_assert(inputRecorder->frameIndex == 0, "Expected 0 but got %u (%u)", inputRecorder->frameIndex, lineNumber); if (fileOutput) { TestCase_assert(inputRecorder->outputFile != NULL, "Expected non-NULL but got NULL (%u)", lineNumber); } else { TestCase_assert(inputRecorder->outputFile == NULL, "Expected NULL but got %p (%u)", inputRecorder->outputFile, lineNumber); TestCase_assert(inputRecorder->memwriteContext.realloc, "Expected true but got false (%u)", lineNumber); } } static void testInit() { InputRecorder inputRecorder, * inputRecorderPtr; InputController * inputController; const char * tempFilePath; int tempFD; inputController = InputController_create(NULL, NULL, NULL); memset(&inputRecorder, 0x00, sizeof(InputRecorder)); stemobject_assign_vtable(inputRecorder, InputRecorder); InputRecorder_initWithMemwriteOutput(&inputRecorder, NULL, NULL, 0); verifyInit(&inputRecorder, NULL, NULL, __LINE__); InputRecorder_dispose(&inputRecorder); memset(&inputRecorder, 0xFF, sizeof(InputRecorder)); stemobject_assign_vtable(inputRecorder, InputRecorder); InputRecorder_initWithMemwriteOutput(&inputRecorder, inputController, NULL, 0); verifyInit(&inputRecorder, inputController, NULL, __LINE__); InputRecorder_dispose(&inputRecorder); inputRecorderPtr = InputRecorder_createWithMemwriteOutput(NULL, NULL, 0); verifyInit(inputRecorderPtr, NULL, NULL, __LINE__); InputRecorder_dispose(inputRecorderPtr); tempFilePath = temporaryFilePath("tmpXXXXXX", &tempFD); close(tempFD); memset(&inputRecorder, 0x00, sizeof(InputRecorder)); stemobject_assign_vtable(inputRecorder, InputRecorder); InputRecorder_initWithFileOutput(&inputRecorder, NULL, NULL, 0, tempFilePath); verifyInit(&inputRecorder, NULL, tempFilePath, __LINE__); InputRecorder_dispose(&inputRecorder); memset(&inputRecorder, 0xFF, sizeof(InputRecorder)); stemobject_assign_vtable(inputRecorder, InputRecorder); InputRecorder_initWithFileOutput(&inputRecorder, inputController, NULL, 0, tempFilePath); verifyInit(&inputRecorder, inputController, tempFilePath, __LINE__); InputRecorder_dispose(&inputRecorder); inputRecorderPtr = InputRecorder_createWithFileOutput(NULL, NULL, 0, tempFilePath); verifyInit(inputRecorderPtr, NULL, tempFilePath, __LINE__); InputRecorder_dispose(inputRecorderPtr); InputController_dispose(inputController); unlink(tempFilePath); } static void testMemwriteRecording() { InputRecorder * inputRecorder; InputController * inputController; inputController = InputController_create(NULL, NULL, NULL); inputRecorder = InputRecorder_createWithMemwriteOutput(inputController, NULL, 0); TestCase_assert(inputRecorder->memwriteContext.length == 8, "Expected 8 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); unsigned char * data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data, "\x01\x00\x00\x00\x00\x00\x00\x00", 8), "Expected 0100 00000000 0000 but got %02X%02X %02X%02X%02X%02X %02X%02X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); InputRecorder_dispose(inputRecorder); inputRecorder = InputRecorder_createWithMemwriteOutput(inputController, "abcd", 4); TestCase_assert(inputRecorder->memwriteContext.length == 12, "Expected 12 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data, "\x01\x00\x04\x00\x00\x00""abcd\x00\x00", 12), "Expected 0100 04000000 61626364 0000 but got %02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11]); InputRecorder_dispose(inputRecorder); InputController_dispose(inputController); inputController = InputController_create(NULL, NULL, "a", "bc", NULL); inputRecorder = InputRecorder_createWithMemwriteOutput(inputController, NULL, 0); TestCase_assert(inputRecorder->memwriteContext.length == 13, "Expected 13 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data, "\x01\x00\x00\x00\x00\x00\x02\x00""a\x00""bc\x00", 13), "Expected 0100 00000000 0200 6100 626300 but got %02X%02X %02X%02X%02X%02X %02X%02X %02X%02X %02X%02X%02X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12]); call_virtual(startAction, inputController, ATOM("a"), 1.0, false, InputMap_genericUnknownBinding()); TestCase_assert(inputRecorder->memwriteContext.length == 20, "Expected 20 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data + 13, "\x00\x00\x00\x00\x00\x00\x00", 7), "Expected 00000000 0000 00 but got %02X%02X%02X%02X %02X%02X %02X", data[13], data[14], data[15], data[16], data[17], data[18], data[19]); InputRecorder_nextFrame(inputRecorder); call_virtual(startAction, inputController, ATOM("bc"), 2.0, false, InputMap_genericUnknownBinding()); TestCase_assert(inputRecorder->memwriteContext.length == 27, "Expected 27 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data + 20, "\x01\x00\x00\x00\x01\x00\x00", 7), "Expected 01000000 0100 00 but got %02X%02X%02X%02X %02X%02X %02X", data[20], data[21], data[22], data[23], data[24], data[25], data[26]); InputRecorder_nextFrame(inputRecorder); InputRecorder_nextFrame(inputRecorder); InputRecorder_nextFrame(inputRecorder); call_virtual(stopAction, inputController, ATOM("bc"), 3.0, false); TestCase_assert(inputRecorder->memwriteContext.length == 34, "Expected 34 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data + 27, "\x03\x00\x00\x00\x01\x00\x01", 7), "Expected 03000000 0100 01 but got %02X%02X%02X%02X %02X%02X %02X", data[27], data[28], data[29], data[30], data[31], data[32], data[33]); call_virtual(motion, inputController, ATOM("a"), 4.0, 0x10000, 0x20000, 0x30000, 0x40000, false); TestCase_assert(inputRecorder->memwriteContext.length == 57, "Expected 57 but got " SIZE_T_FORMAT, inputRecorder->memwriteContext.length); data = inputRecorder->memwriteContext.data; TestCase_assert(!memcmp(inputRecorder->memwriteContext.data + 34, "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00", 23), "Expected 00000000 0000 02 00000100 00000200 00000300 00000400 but got %02X%02X%02X%02X %02X%02X %02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X", data[34], data[35], data[36], data[37], data[38], data[39], data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], data[56]); InputRecorder_dispose(inputRecorder); InputController_dispose(inputController); } static void testFileRecording() { InputRecorder * inputRecorder; InputController * inputController; const char * tempFilePath; int tempFD; unsigned char * fileContents; size_t fileLength; inputController = InputController_create(NULL, NULL, NULL); tempFilePath = temporaryFilePath("tmpXXXXXX", &tempFD); close(tempFD); inputRecorder = InputRecorder_createWithFileOutput(inputController, NULL, 0, tempFilePath); fileContents = readFileSimple(tempFilePath, &fileLength); TestCase_assert(fileContents != NULL, "Expected non-NULL but got NULL"); TestCase_assert(fileLength == 8, "Expected 8 but got " SIZE_T_FORMAT, fileLength); TestCase_assert(!memcmp(fileContents, "\x01\x00\x00\x00\x00\x00\x00\x00", 8), "Expected 0100 00000000 0000 but got %02X%02X %02X%02X%02X%02X %02X%02X", fileContents[0], fileContents[1], fileContents[2], fileContents[3], fileContents[4], fileContents[5], fileContents[6], fileContents[7]); free(fileContents); InputRecorder_dispose(inputRecorder); inputRecorder = InputRecorder_createWithFileOutput(inputController, "abcd", 4, tempFilePath); fileContents = readFileSimple(tempFilePath, &fileLength); TestCase_assert(fileContents != NULL, "Expected non-NULL but got NULL"); TestCase_assert(fileLength == 12, "Expected 12 but got " SIZE_T_FORMAT, fileLength); TestCase_assert(!memcmp(fileContents, "\x01\x00\x04\x00\x00\x00""abcd\x00\x00", 12), "Expected 0100 04000000 61626364 0000 but got %02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X", fileContents[0], fileContents[1], fileContents[2], fileContents[3], fileContents[4], fileContents[5], fileContents[6], fileContents[7], fileContents[8], fileContents[9], fileContents[10], fileContents[11]); free(fileContents); InputRecorder_dispose(inputRecorder); InputController_dispose(inputController); inputController = InputController_create(NULL, NULL, "a", "bc", NULL); inputRecorder = InputRecorder_createWithFileOutput(inputController, NULL, 0, tempFilePath); fileContents = readFileSimple(tempFilePath, &fileLength); TestCase_assert(fileContents != NULL, "Expected non-NULL but got NULL"); TestCase_assert(fileLength == 13, "Expected 13 but got " SIZE_T_FORMAT, fileLength); TestCase_assert(!memcmp(fileContents, "\x01\x00\x00\x00\x00\x00\x02\x00""a\x00""bc\x00", 13), "Expected 0100 00000000 0200 6100 626300 but got %02X%02X %02X%02X%02X%02X %02X%02X %02X%02X %02X%02X%02X", fileContents[0], fileContents[1], fileContents[2], fileContents[3], fileContents[4], fileContents[5], fileContents[6], fileContents[7], fileContents[8], fileContents[9], fileContents[10], fileContents[11], fileContents[12]); free(fileContents); call_virtual(startAction, inputController, ATOM("a"), 1.0, false, InputMap_genericUnknownBinding()); fileContents = readFileSimple(tempFilePath, &fileLength); TestCase_assert(fileContents != NULL, "Expected non-NULL but got NULL"); TestCase_assert(fileLength == 20, "Expected 20 but got " SIZE_T_FORMAT, fileLength); TestCase_assert(!memcmp(fileContents + 13, "\x00\x00\x00\x00\x00\x00\x00", 7), "Expected 00000000 0000 00 but got %02X%02X%02X%02X %02X%02X %02X", fileContents[13], fileContents[14], fileContents[15], fileContents[16], fileContents[17], fileContents[18], fileContents[19]); free(fileContents); InputRecorder_nextFrame(inputRecorder); call_virtual(startAction, inputController, ATOM("bc"), 2.0, false, InputMap_genericUnknownBinding()); fileContents = readFileSimple(tempFilePath, &fileLength); TestCase_assert(fileContents != NULL, "Expected non-NULL but got NULL"); TestCase_assert(fileLength == 27, "Expected 27 but got " SIZE_T_FORMAT, fileLength); TestCase_assert(!memcmp(fileContents + 20, "\x01\x00\x00\x00\x01\x00\x00", 7), "Expected 01000000 0100 00 but got %02X%02X%02X%02X %02X%02X %02X", fileContents[20], fileContents[21], fileContents[22], fileContents[23], fileContents[24], fileContents[25], fileContents[26]); free(fileContents); InputRecorder_nextFrame(inputRecorder); InputRecorder_nextFrame(inputRecorder); InputRecorder_nextFrame(inputRecorder); call_virtual(stopAction, inputController, ATOM("bc"), 3.0, false); fileContents = readFileSimple(tempFilePath, &fileLength); TestCase_assert(fileContents != NULL, "Expected non-NULL but got NULL"); TestCase_assert(fileLength == 34, "Expected 31 but got " SIZE_T_FORMAT, fileLength); TestCase_assert(!memcmp(fileContents + 27, "\x03\x00\x00\x00\x01\x00\x01", 7), "Expected 03000000 0100 01 but got %02X%02X%02X%02X %02X%02X %02X", fileContents[27], fileContents[28], fileContents[29], fileContents[30], fileContents[31], fileContents[32], fileContents[33]); free(fileContents); InputRecorder_dispose(inputRecorder); InputController_dispose(inputController); unlink(tempFilePath); } TEST_SUITE(InputRecorderTest, testInit, testMemwriteRecording, testFileRecording)