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 <Input/FGHIDEventInput.cxx> cannot be imported within the CppUnit infrastructure, as it is already built into the run_test_suite binary.
This commit is contained in:
parent
8d0db45c51
commit
fff923d2f4
8 changed files with 173 additions and 72 deletions
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3,6 +3,7 @@ foreach( unit_test_category
|
|||
Add-ons
|
||||
general
|
||||
FDM
|
||||
Input
|
||||
Main
|
||||
Navaids
|
||||
Scripting
|
||||
|
|
17
test_suite/unit_tests/Input/CMakeLists.txt
Normal file
17
test_suite/unit_tests/Input/CMakeLists.txt
Normal file
|
@ -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
|
||||
)
|
28
test_suite/unit_tests/Input/TestSuite.cxx
Normal file
28
test_suite/unit_tests/Input/TestSuite.cxx
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "test_hidinput.hxx"
|
||||
|
||||
|
||||
// Set up the unit tests.
|
||||
#ifdef ENABLE_HID_INPUT
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(HIDInputTests, "Unit tests");
|
||||
#endif
|
|
@ -18,33 +18,35 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "test_hidinput.hxx"
|
||||
|
||||
#include "test_suite/helpers/globals.hxx"
|
||||
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
|
||||
#include "FGHIDEventInput.cxx"
|
||||
#include <Input/FGHIDEventInput.hxx>
|
||||
|
||||
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);
|
||||
}
|
52
test_suite/unit_tests/Input/test_hidinput.hxx
Normal file
52
test_suite/unit_tests/Input/test_hidinput.hxx
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FG_HIDINPUT_UNIT_TESTS_HXX
|
||||
#define _FG_HIDINPUT_UNIT_TESTS_HXX
|
||||
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <cppunit/TestFixture.h>
|
||||
|
||||
|
||||
// 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
|
Loading…
Add table
Reference in a new issue