Skip to content

Commit 1cfa210

Browse files
authored
Merge pull request #9 from Murmele/Tests
use ctest and set path to dbc files with a compile definition
2 parents 44a4a72 + 2a4d059 commit 1cfa210

File tree

7 files changed

+163
-23
lines changed

7 files changed

+163
-23
lines changed

.github/workflows/tests.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ jobs:
1717
- uses: actions/checkout@v3
1818

1919
- name: Configure CMake
20-
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
20+
run: |
21+
mkdir build
22+
cd build
23+
cmake -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ..
2124
2225
- name: Build
23-
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -- -j
26+
run: |
27+
cd build
28+
make
2429
2530
- name: Test
26-
working-directory: ${{github.workspace}}/build
27-
# Didn't configure to use ctest. Opted for a custom target to run instead
28-
run: cmake --build ${{github.workspace}}/build --target test -- -j
31+
run: |
32+
cd build
33+
ctest --output-on-failure
2934

CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
1212
include(CPack)
1313

1414
option(DEBUG "use debug flag" NO)
15+
option(ENABLE_TESTS "Enable Unittests" ON)
1516

1617
# defines variables used in the dbc.pc.in
1718
include(GNUInstallDirs)
@@ -51,7 +52,11 @@ set(HEADER_FILES
5152
include_directories(src)
5253
include_directories(include)
5354

54-
add_subdirectory(test)
55+
if(ENABLE_TESTS)
56+
include(CTest)
57+
add_subdirectory(test)
58+
endif()
59+
5560
add_subdirectory(doc)
5661

5762
add_library(${PROJECT_NAME} STATIC ${SOURCE})

src/dbc.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,56 @@
44

55
#include <regex>
66

7+
namespace {
8+
9+
const auto floatPattern = "(-?\\d+\\.?(\\d+)?)"; // Can be negative
10+
11+
const auto signalIdentifierPattern = "(SG_)";
12+
const auto namePattern = "(\\w+)";
13+
const auto bitStartPattern = "(\\d+)"; // Cannot be negative
14+
const auto lengthPattern = "(\\d+)"; // Cannot be negative
15+
const auto byteOrderPattern = "([0-1])";
16+
const auto signPattern = "(\\+|\\-)";
17+
const auto scalePattern = "(\\d+\\.?(\\d+)?)"; // Non negative float
18+
const auto offsetPattern = floatPattern;
19+
const auto offsetScalePattern = std::string("\\(") + scalePattern + "\\," + offsetPattern + "\\)";
20+
const auto minPattern = floatPattern;
21+
const auto maxPattern = floatPattern;
22+
const auto minMaxPattern = std::string("\\[") + minPattern + "\\|" + maxPattern + "\\]";
23+
const auto unitPattern = "\"(.*)\""; // Random string
24+
const auto receiverPattern = "([\\w\\,]+|Vector__XXX)*";
25+
const auto whiteSpace = "\\s";
26+
27+
} // anonymous namespace
28+
729
namespace libdbc {
830

931
DbcParser::DbcParser() : version(""), nodes(),
1032
version_re("^(VERSION)\\s\"(.*)\""), bit_timing_re("^(BS_:)"),
1133
name_space_re("^(NS_)\\s\\:"), node_re("^(BU_:)\\s((?:[\\w]+?\\s?)*)"),
1234
message_re("^(BO_)\\s(\\d+)\\s(\\w+)\\:\\s(\\d+)\\s(\\w+|Vector__XXX)"),
1335
// NOTE: No multiplex support yet
14-
signal_re("\\s(SG_)\\s(\\w+)\\s\\:\\s(\\d+)\\|(\\d+)\\@(\\d+)(\\+|\\-)\\s\\((\\d+\\.?(\\d+)?)\\,(\\d+\\.?(\\d+)?)\\)\\s\\[(-?\\d+\\.?(\\d+)?)\\|(-?\\d+\\.?(\\d+)?)\\]\\s\"(\\w*)\"\\s([\\w\\,]+|Vector__XXX)*") {
36+
signal_re(std::string(whiteSpace) +
37+
signalIdentifierPattern +
38+
whiteSpace +
39+
namePattern +
40+
whiteSpace +
41+
"\\:" +
42+
whiteSpace +
43+
bitStartPattern +
44+
"\\|" +
45+
lengthPattern +
46+
"\\@" +
47+
byteOrderPattern +
48+
signPattern +
49+
whiteSpace +
50+
offsetScalePattern +
51+
whiteSpace +
52+
minMaxPattern +
53+
whiteSpace +
54+
unitPattern +
55+
whiteSpace +
56+
receiverPattern) {
1557

1658
}
1759

src/signal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace libdbc {
44
Signal::Signal(std::string name, bool is_multiplexed, uint32_t start_bit, uint32_t size, bool is_bigendian, bool is_signed, double factor, double offset, double min, double max, std::string unit, std::vector<std::string> receivers) :
5-
name(name), is_multiplexed(is_multiplexed), start_bit(start_bit), size(size), is_bigendian(is_bigendian), is_signed(is_signed), offset(offset), min(min), max(max), unit(unit), receivers(receivers) {}
5+
name(name), is_multiplexed(is_multiplexed), start_bit(start_bit), size(size), is_bigendian(is_bigendian), is_signed(is_signed), factor(factor), offset(offset), min(min), max(max), unit(unit), receivers(receivers) {}
66

77
bool Signal::operator==(const Signal& rhs) const {
88
return (this->name == rhs.name) && (this->is_multiplexed == rhs.is_multiplexed) &&

test/CMakeLists.txt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
project(tests VERSION 0.1.0)
1+
enable_testing()
22

33
# Download and build Catch2 test framework
44
Include(FetchContent)
@@ -8,15 +8,17 @@ FetchContent_Declare(
88
GIT_TAG v3.2.1
99
)
1010
FetchContent_MakeAvailable(Catch2)
11+
include(Catch)
1112

1213
list(APPEND TEST_SOURCES
1314
test_dbc.cpp
1415
test_utils.cpp)
1516

16-
add_executable(tests ${TEST_SOURCES} ${SOURCE})
17-
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
18-
19-
add_custom_target(test
20-
COMMAND ${PROJECT_NAME}
21-
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
22-
DEPENDS ${PROJECT_NAME})
17+
add_executable(tests ${TEST_SOURCES})
18+
target_compile_definitions(tests PRIVATE TESTDBCFILES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/dbcs")
19+
target_link_libraries(tests PRIVATE dbc Catch2::Catch2WithMain)
20+
target_sources(tests INTERFACE FILE_SET HEADERS
21+
TYPE HEADERS
22+
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
23+
FILES defines.hpp)
24+
catch_discover_tests(tests)

test/defines.hpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
#include <string>
22

33
// Correctly formated files
4-
static const std::string COMPLEX_DBC_FILE = "./dbcs/Complex.dbc";
5-
static const std::string SIMPLE_DBC_FILE = "./dbcs/Simple.dbc";
4+
static const std::string COMPLEX_DBC_FILE = std::string(TESTDBCFILES_PATH) + "/Complex.dbc";
5+
static const std::string SIMPLE_DBC_FILE = std::string(TESTDBCFILES_PATH) + "/Simple.dbc";
66

77
// Files with Errors
8-
static const std::string MISSING_NEW_SYMBOLS_DBC_FILE = "./dbcs/MissingNewSymbols.dbc";
9-
static const std::string MISSING_VERSION_DBC_FILE = "./dbcs/MissingVersion.dbc";
10-
static const std::string MISSING_BIT_TIMING_DBC_FILE = "./dbcs/MissingBitTiming.dbc";
11-
static const std::string TEXT_FILE = "./dbcs/TextFile.txt";
8+
static const std::string MISSING_NEW_SYMBOLS_DBC_FILE = std::string(TESTDBCFILES_PATH) + "/MissingNewSymbols.dbc";
9+
static const std::string MISSING_VERSION_DBC_FILE = std::string(TESTDBCFILES_PATH) + "/MissingVersion.dbc";
10+
static const std::string MISSING_BIT_TIMING_DBC_FILE = std::string(TESTDBCFILES_PATH) + "/MissingBitTiming.dbc";
11+
static const std::string TEXT_FILE = std::string(TESTDBCFILES_PATH) + "/TextFile.txt";
12+
13+
static const std::string PRIMITIVE_DBC =
14+
R"(VERSION "1.0.0"
15+
16+
NS_ :
17+
18+
BS_:
19+
20+
BU_: DBG DRIVER IO MOTOR SENSOR
21+
22+
)";

test/test_dbc.cpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
#include "defines.hpp"
33
#include <libdbc/dbc.hpp>
44

5+
void create_tmp_dbc_with(const char* filename, const char* content)
6+
{
7+
auto* file = std::fopen(filename, "w");
8+
CHECK(file);
9+
10+
std::fputs(PRIMITIVE_DBC.c_str(), file);
11+
std::fputs(content, file);
12+
std::fclose(file);
13+
}
14+
15+
516
TEST_CASE("Testing dbc file loading error issues", "[fileio][error]") {
617
auto parser = std::unique_ptr<libdbc::DbcParser>(new libdbc::DbcParser());
718

@@ -58,4 +69,68 @@ TEST_CASE("Testing dbc file loading", "[fileio]") {
5869
REQUIRE(parser->get_messages().front().signals == msg.signals);
5970
}
6071

61-
}
72+
}
73+
74+
TEST_CASE("Testing negative values") {
75+
const auto* filename = std::tmpnam(NULL);
76+
77+
create_tmp_dbc_with(filename, R"(BO_ 234 MSG1: 8 Vector__XXX
78+
SG_ Sig1 : 55|16@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX
79+
SG_ Sig2 : 39|16@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX
80+
SG_ Sig3 : 23|16@0- (10,0) [-3276.8|-3276.7] "C" Vector__XXX
81+
SG_ Sig4 : 7|16@0- (1,-10) [0|32767] "" Vector__XXX)");
82+
83+
auto parser = libdbc::DbcParser();
84+
parser.parse_file(std::string(filename));
85+
86+
REQUIRE(parser.get_messages().size() == 1);
87+
REQUIRE(parser.get_messages().at(0).signals.size() == 4);
88+
89+
SECTION("Evaluating first message") {
90+
const auto signal = parser.get_messages().at(0).signals.at(0);
91+
REQUIRE(signal.factor == 0.1);
92+
REQUIRE(signal.offset == 0);
93+
REQUIRE(signal.min == -3276.8);
94+
REQUIRE(signal.max == -3276.7);
95+
}
96+
SECTION("Evaluating second message") {
97+
const auto signal = parser.get_messages().at(0).signals.at(1);
98+
REQUIRE(signal.factor == 0.1);
99+
REQUIRE(signal.offset == 0);
100+
REQUIRE(signal.min == -3276.8);
101+
REQUIRE(signal.max == -3276.7);
102+
}
103+
SECTION("Evaluating third message"){
104+
const auto signal = parser.get_messages().at(0).signals.at(2);
105+
REQUIRE(signal.factor == 10);
106+
REQUIRE(signal.offset == 0);
107+
REQUIRE(signal.min == -3276.8);
108+
REQUIRE(signal.max == -3276.7);
109+
}
110+
SECTION("Evaluating fourth message"){
111+
const auto signal = parser.get_messages().at(0).signals.at(3);
112+
REQUIRE(signal.factor == 1);
113+
REQUIRE(signal.offset == -10);
114+
REQUIRE(signal.min == 0);
115+
REQUIRE(signal.max == 32767);
116+
}
117+
}
118+
119+
120+
TEST_CASE("Special characters in unit") {
121+
const auto* filename = std::tmpnam(NULL);
122+
123+
create_tmp_dbc_with(filename, R"(BO_ 234 MSG1: 8 Vector__XXX
124+
SG_ Speed : 0|8@1+ (1,0) [0|204] "Km/h" DEVICE1,DEVICE2,DEVICE3)");
125+
126+
127+
auto parser = libdbc::DbcParser();
128+
parser.parse_file(std::string(filename));
129+
130+
REQUIRE(parser.get_messages().size() == 1);
131+
REQUIRE(parser.get_messages().at(0).signals.size() == 1);
132+
SECTION("Checking that signal with special characters as unit is parsed correctly") {
133+
const auto signal = parser.get_messages().at(0).signals.at(0);
134+
REQUIRE(signal.unit.compare("Km/h") == 0);
135+
}
136+
}

0 commit comments

Comments
 (0)