1
0
Fork 0

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:
Edward d'Auvergne 2018-06-14 09:32:02 +02:00
parent 8d0db45c51
commit fff923d2f4
8 changed files with 173 additions and 72 deletions

View file

@ -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)

View file

@ -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();

View file

@ -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)

View file

@ -3,6 +3,7 @@ foreach( unit_test_category
Add-ons
general
FDM
Input
Main
Navaids
Scripting

View 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
)

View 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

View file

@ -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);
}

View 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