From fff923d2f4db066371d6995c0778f6347017c060 Mon Sep 17 00:00:00 2001 From: Edward d'Auvergne Date: Thu, 14 Jun 2018 09:32:02 +0200 Subject: [PATCH] TestSuite: Migration of the HIDInput tests to the CppUnit framework. The extractBits(), signExtend(), and writeBits() functions of the anonymous namespace in Input/FGHIDEventInput.cxx have been shifted out of the namespace and are now exposed via the header. This is needed as cannot be imported within the CppUnit infrastructure, as it is already built into the run_test_suite binary. --- src/Input/FGHIDEventInput.cxx | 87 ++++++++++--------- src/Input/FGHIDEventInput.hxx | 6 ++ test_suite/CMakeLists.txt | 3 + test_suite/unit_tests/CMakeLists.txt | 1 + test_suite/unit_tests/Input/CMakeLists.txt | 17 ++++ test_suite/unit_tests/Input/TestSuite.cxx | 28 ++++++ .../unit_tests}/Input/test_hidinput.cxx | 51 +++++------ test_suite/unit_tests/Input/test_hidinput.hxx | 52 +++++++++++ 8 files changed, 173 insertions(+), 72 deletions(-) create mode 100644 test_suite/unit_tests/Input/CMakeLists.txt create mode 100644 test_suite/unit_tests/Input/TestSuite.cxx rename {src => test_suite/unit_tests}/Input/test_hidinput.cxx (56%) create mode 100644 test_suite/unit_tests/Input/test_hidinput.hxx diff --git a/src/Input/FGHIDEventInput.cxx b/src/Input/FGHIDEventInput.cxx index 929ad1541..0e8d088a9 100644 --- a/src/Input/FGHIDEventInput.cxx +++ b/src/Input/FGHIDEventInput.cxx @@ -538,22 +538,6 @@ void FGHIDDevice::update(double dt) _dirtyReports.clear(); } -void writeBits(uint8_t* bytes, size_t bitOffset, size_t bitSize, int value) -{ - size_t wholeBytesToSkip = bitOffset >> 3; - uint8_t* dataByte = bytes + wholeBytesToSkip; - size_t offsetInByte = bitOffset & 0x7; - size_t bitsInByte = std::min(bitSize, 8 - offsetInByte); - uint8_t mask = 0xff >> (8 - bitsInByte); - - *dataByte |= ((value & mask) << offsetInByte); - - if (bitsInByte < bitSize) { - // if we have more bits to write, recurse - writeBits(bytes, bitOffset + bitsInByte, bitSize - bitsInByte, value >> bitsInByte); - } -} - void FGHIDDevice::sendReport(Report* report) const { if (!_device) { @@ -585,33 +569,6 @@ void FGHIDDevice::sendReport(Report* report) const } } -int extractBits(uint8_t* bytes, size_t lengthInBytes, size_t bitOffset, size_t bitSize) -{ - const size_t wholeBytesToSkip = bitOffset >> 3; - const size_t offsetInByte = bitOffset & 0x7; - - // work out how many whole bytes to copy - const size_t bytesToCopy = std::min(sizeof(uint32_t), (offsetInByte + bitSize + 7) / 8); - uint32_t v = 0; - // this goes from byte alignment to word alignment safely - memcpy((void*) &v, bytes + wholeBytesToSkip, bytesToCopy); - - // shift down so lowest bit is aligned - v = v >> offsetInByte; - - // mask off any extraneous top bits - const uint32_t mask = ~(0xffffffff << bitSize); - v &= mask; - - return v; -} - -int signExtend(int inValue, size_t bitSize) -{ - const int m = 1U << (bitSize - 1); - return (inValue ^ m) - m; -} - int FGHIDDevice::maybeSignExtend(Item* item, int inValue) { return item->doSignExtend ? signExtend(inValue, item->bitSize) : inValue; @@ -701,6 +658,50 @@ void FGHIDDevice::Send(const char *eventName, double value) } // of anonymous namespace + +int extractBits(uint8_t* bytes, size_t lengthInBytes, size_t bitOffset, size_t bitSize) +{ + const size_t wholeBytesToSkip = bitOffset >> 3; + const size_t offsetInByte = bitOffset & 0x7; + + // work out how many whole bytes to copy + const size_t bytesToCopy = std::min(sizeof(uint32_t), (offsetInByte + bitSize + 7) / 8); + uint32_t v = 0; + // this goes from byte alignment to word alignment safely + memcpy((void*) &v, bytes + wholeBytesToSkip, bytesToCopy); + + // shift down so lowest bit is aligned + v = v >> offsetInByte; + + // mask off any extraneous top bits + const uint32_t mask = ~(0xffffffff << bitSize); + v &= mask; + + return v; +} + +int signExtend(int inValue, size_t bitSize) +{ + const int m = 1U << (bitSize - 1); + return (inValue ^ m) - m; +} + +void writeBits(uint8_t* bytes, size_t bitOffset, size_t bitSize, int value) +{ + size_t wholeBytesToSkip = bitOffset >> 3; + uint8_t* dataByte = bytes + wholeBytesToSkip; + size_t offsetInByte = bitOffset & 0x7; + size_t bitsInByte = std::min(bitSize, 8 - offsetInByte); + uint8_t mask = 0xff >> (8 - bitsInByte); + + *dataByte |= ((value & mask) << offsetInByte); + + if (bitsInByte < bitSize) { + // if we have more bits to write, recurse + writeBits(bytes, bitOffset + bitsInByte, bitSize - bitsInByte, value >> bitsInByte); + } +} + FGHIDEventInput::FGHIDEventInput() : FGEventInput(), d(new FGHIDEventInputPrivate) diff --git a/src/Input/FGHIDEventInput.hxx b/src/Input/FGHIDEventInput.hxx index 8d755619e..182e648f2 100644 --- a/src/Input/FGHIDEventInput.hxx +++ b/src/Input/FGHIDEventInput.hxx @@ -27,6 +27,12 @@ #include "FGEventInput.hxx" + +int extractBits(uint8_t* bytes, size_t lengthInBytes, size_t bitOffset, size_t bitSize); +int signExtend(int inValue, size_t bitSize); +void writeBits(uint8_t* bytes, size_t bitOffset, size_t bitSize, int value); + + class FGHIDEventInput : public FGEventInput { public: FGHIDEventInput(); diff --git a/test_suite/CMakeLists.txt b/test_suite/CMakeLists.txt index e9b73b336..2a936f298 100644 --- a/test_suite/CMakeLists.txt +++ b/test_suite/CMakeLists.txt @@ -71,6 +71,9 @@ add_test(AddonManagementUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest add_test(AeroElementUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u AeroElementTests) add_test(AutosaveMigrationUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u AutosaveMigrationTests) add_test(FlightplanUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u FlightplanTests) +if(ENABLE_HID_INPUT) + add_test(HIDInputUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u HIDInputTests) +endif() add_test(LaRCSimMatrixUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u LaRCSimMatrixTests) add_test(MktimeUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u MktimeTests) add_test(NasalSysUnitTests ${TESTSUITE_OUTPUT_DIR}/run_test_suite --ctest -u NasalSysTests) diff --git a/test_suite/unit_tests/CMakeLists.txt b/test_suite/unit_tests/CMakeLists.txt index f418a519b..8d2958847 100644 --- a/test_suite/unit_tests/CMakeLists.txt +++ b/test_suite/unit_tests/CMakeLists.txt @@ -3,6 +3,7 @@ foreach( unit_test_category Add-ons general FDM + Input Main Navaids Scripting diff --git a/test_suite/unit_tests/Input/CMakeLists.txt b/test_suite/unit_tests/Input/CMakeLists.txt new file mode 100644 index 000000000..68b79a534 --- /dev/null +++ b/test_suite/unit_tests/Input/CMakeLists.txt @@ -0,0 +1,17 @@ +if(ENABLE_HID_INPUT) + set(HID_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/test_hidinput.cxx) + set(HID_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/test_hidinput.hxx) +endif() + +set(TESTSUITE_SOURCES + ${TESTSUITE_SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/TestSuite.cxx + ${HID_SOURCE} + PARENT_SCOPE +) + +set(TESTSUITE_HEADERS + ${TESTSUITE_HEADERS} + ${HID_HEADER} + PARENT_SCOPE +) diff --git a/test_suite/unit_tests/Input/TestSuite.cxx b/test_suite/unit_tests/Input/TestSuite.cxx new file mode 100644 index 000000000..611326ec6 --- /dev/null +++ b/test_suite/unit_tests/Input/TestSuite.cxx @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2018 Edward d'Auvergne + * + * This file is part of the program FlightGear. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "test_hidinput.hxx" + + +// Set up the unit tests. +#ifdef ENABLE_HID_INPUT + CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(HIDInputTests, "Unit tests"); +#endif diff --git a/src/Input/test_hidinput.cxx b/test_suite/unit_tests/Input/test_hidinput.cxx similarity index 56% rename from src/Input/test_hidinput.cxx rename to test_suite/unit_tests/Input/test_hidinput.cxx index 978157f63..2a586844e 100644 --- a/src/Input/test_hidinput.cxx +++ b/test_suite/unit_tests/Input/test_hidinput.cxx @@ -18,33 +18,35 @@ #include "config.h" +#include "test_hidinput.hxx" + #include "test_suite/helpers/globals.hxx" #include -#include "FGHIDEventInput.cxx" +#include -void testValueExtract() +void HIDInputTests::testValueExtract() { uint8_t testDataFromSpec[4] = {0, 0xf4, 0x1 | (0x7 << 2), 0x03}; - SG_VERIFY(extractBits(testDataFromSpec, 4, 8, 10) == 500); - SG_VERIFY(extractBits(testDataFromSpec, 4, 18, 10) == 199); + CPPUNIT_ASSERT(extractBits(testDataFromSpec, 4, 8, 10) == 500); + CPPUNIT_ASSERT(extractBits(testDataFromSpec, 4, 18, 10) == 199); uint8_t testData2[4] = {0x01 << 6 | 0x0f, 0x17 | (1 << 6), 0x3 | (0x11 << 2), 0x3d | (1 << 6) }; - SG_VERIFY(extractBits(testData2, 4, 0, 6) == 15); - SG_VERIFY(extractBits(testData2, 4, 6, 12) == 3421); - SG_VERIFY(extractBits(testData2, 4, 18, 12) == 3921); - SG_VERIFY(extractBits(testData2, 4, 30, 1) == 1); - SG_VERIFY(extractBits(testData2, 4, 31, 1) == 0); + CPPUNIT_ASSERT(extractBits(testData2, 4, 0, 6) == 15); + CPPUNIT_ASSERT(extractBits(testData2, 4, 6, 12) == 3421); + CPPUNIT_ASSERT(extractBits(testData2, 4, 18, 12) == 3921); + CPPUNIT_ASSERT(extractBits(testData2, 4, 30, 1) == 1); + CPPUNIT_ASSERT(extractBits(testData2, 4, 31, 1) == 0); } // void writeBits(uint8_t* bytes, size_t bitOffset, size_t bitSize, int value) -void testValueInsert() +void HIDInputTests::testValueInsert() { uint8_t buf[8]; memset(buf, 0, 8); @@ -54,27 +56,18 @@ void testValueInsert() writeBits(buf, 6, 12, a); writeBits(buf, 18, 12, b); - SG_VERIFY(buf[0] == 0x40); - SG_VERIFY(buf[1] == 0x57); - SG_VERIFY(buf[2] == (0x03 | 0x44)); - SG_VERIFY(buf[3] == 0x3d); + CPPUNIT_ASSERT(buf[0] == 0x40); + CPPUNIT_ASSERT(buf[1] == 0x57); + CPPUNIT_ASSERT(buf[2] == (0x03 | 0x44)); + CPPUNIT_ASSERT(buf[3] == 0x3d); } -void testSignExtension() +void HIDInputTests::testSignExtension() { - SG_VERIFY(signExtend(0x80, 8) == -128); - SG_VERIFY(signExtend(0xff, 8) == -1); - SG_VERIFY(signExtend(0x7f, 8) == 127); + CPPUNIT_ASSERT(signExtend(0x80, 8) == -128); + CPPUNIT_ASSERT(signExtend(0xff, 8) == -1); + CPPUNIT_ASSERT(signExtend(0x7f, 8) == 127); - SG_VERIFY(signExtend(0x831, 12) == -1999); - SG_VERIFY(signExtend(0x7dd, 12) == 2013); -} - -int main(int argc, char* argv[]) -{ - testValueExtract(); - testValueInsert(); - testSignExtension(); - - return EXIT_SUCCESS; + CPPUNIT_ASSERT(signExtend(0x831, 12) == -1999); + CPPUNIT_ASSERT(signExtend(0x7dd, 12) == 2013); } diff --git a/test_suite/unit_tests/Input/test_hidinput.hxx b/test_suite/unit_tests/Input/test_hidinput.hxx new file mode 100644 index 000000000..4e60f5b20 --- /dev/null +++ b/test_suite/unit_tests/Input/test_hidinput.hxx @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Edward d'Auvergne + * + * This file is part of the program FlightGear. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef _FG_HIDINPUT_UNIT_TESTS_HXX +#define _FG_HIDINPUT_UNIT_TESTS_HXX + + +#include +#include + + +// The unit tests. +class HIDInputTests : public CppUnit::TestFixture +{ + // Set up the test suite. + CPPUNIT_TEST_SUITE(HIDInputTests); + CPPUNIT_TEST(testValueExtract); + CPPUNIT_TEST(testValueInsert); + CPPUNIT_TEST(testSignExtension); + CPPUNIT_TEST_SUITE_END(); + +public: + // Set up function for each test. + void setUp() {} + + // Clean up after each test. + void tearDown() {} + + // The tests. + void testValueExtract(); + void testValueInsert(); + void testSignExtension(); +}; + +#endif // _FG_HIDINPUT_UNIT_TESTS_HXX