update parser (#5)

This commit is contained in:
tompzf
2026-01-16 11:40:02 +01:00
committed by GitHub
parent 5039a37131
commit 234be8917f
115 changed files with 14038 additions and 5380 deletions

View File

@@ -58,7 +58,7 @@ add_subdirectory(unit_tests/smart_ifc)
add_subdirectory(unit_tests/toml_parser)
add_subdirectory(unit_tests/module_control)
add_subdirectory(unit_tests/repository)
# add_subdirectory(unit_tests/shared_mem)
add_subdirectory(unit_tests/shared_mem)
add_subdirectory(unit_tests/memory_manager)
add_subdirectory(unit_tests/core_loader)
add_subdirectory(unit_tests/named_mutex)

View File

@@ -11,7 +11,7 @@ or
# SDV TEST MACRO
## Overview
There is set of macros in "export/support/sdv_test_macro.h" which are designed to extend the Google Test (GTEST) framework by incorporating a warning level mechanism. These macros allow developers to specify a warning level for each test assertion, providing more control over test outcomes and enabling better handling of test result conditions based on their warning level.
There is set of macros in "tests/include/sdv_test_macro.h" which are designed to extend the Google Test (GTEST) framework by incorporating a warning level mechanism. These macros allow developers to specify a warning level for each test assertion, providing more control over test outcomes and enabling better handling of test result conditions based on their warning level.
## Purpose
The primary purpose of these macros is to enhance the flexibility and robustness of test assertions in the GTEST framework. By integrating a warning level, developers can decide whether to report failed tests as warning or error and handle them accordingly. This is particularly useful in where different test failures may have varying impacts on the overall build system.
@@ -62,19 +62,19 @@ The WarningLevel enum defines three levels of warnings:
Additionally SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD is implemented to check if tests are running with CMake build or any other way. It returns true if they are running with CMake build.
## Usage
To use these macros, include the header file '#include <support/sdv_test_macro.h>" in your test files. When writing test cases, use the SDV macros instead of the standard GTEST macros, and specify the appropriate warning level for each assertion.
To use these macros, include the header file '#include "tests/include/sdv_test_macro.h"' in your test files. When writing test cases, use the SDV macros instead of the standard GTEST macros, and specify the appropriate warning level for each assertion.
```cpp
#include <support/sdv_test_macro.h>
#include "tests/include/sdv_test_macro.h"
TEST(SDVTestMacros, TestExpectEq)
{
int val1 = 5;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_EQ(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_EQ(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectStreq)
@@ -82,9 +82,9 @@ TEST(SDVTestMacros, TestExpectStreq)
std::string str1 = "test";
std::string str2 = "test";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_STREQ(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_STREQ(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_STREQ(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_STREQ(str1, str2, sdv_test::WARNING_ENABLED);
}
```
In this example, the SDV_EXPECT_EQ macro checks if val1 and val2 are equal, while the SDV_EXPECT_STREQ macro checks if str1 and str2 are equal. In both test cases, it is checked whether it is running

View File

@@ -163,11 +163,11 @@ ViewFilter = "Fatal"
auto table1 = config.GetDirect("newTableArray[0]");
EXPECT_EQ(table1.GetType(), sdv::toml::ENodeType::node_table);
EXPECT_TRUE(table1.GetName().empty());
EXPECT_EQ(table1.GetName(), "newTableArray");
auto table2 = config.GetDirect("newTableArray[1]");
EXPECT_EQ(table2.GetType(), sdv::toml::ENodeType::node_table);
EXPECT_TRUE(table2.GetName().empty());
EXPECT_EQ(table2.GetName(), "newTableArray");
config.Clear();
appcontrol.Shutdown();
@@ -770,6 +770,11 @@ ViewFilter = "Fatal"
[j."ʞ".'l']
)"));
EXPECT_FALSE(sdv::toml::CTOMLParser(u8R"(
[ j . "ʞ" . 'l' ]
["j".'ʞ'."l"]
)"));
EXPECT_FALSE(sdv::toml::CTOMLParser(R"(
[fruit]
apple = "red"

View File

@@ -929,13 +929,13 @@ TEST(DataDispatchServiceTest, DirectRxTxSignalConcurrency)
while (!bShutdown)
{
signalPubA.Write(std::rand());
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
signalPubB.Write(std::rand());
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
signalPubC.Write(std::rand());
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
signalPubD.Write(std::rand());
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
}
}
catch (...)

View File

@@ -1,4 +1,5 @@
#include <gtest/gtest.h>
#include <cstring>
#include "../../../global/process_watchdog.h"
#if defined(_WIN32) && defined(_UNICODE)
@@ -7,8 +8,30 @@ extern "C" int wmain(int argc, wchar_t* argv[])
extern "C" int main(int argc, char* argv[])
#endif
{
CProcessWatchdog watchdog;
// Check for the --gtest_repeat option.
bool bRepeatEnabled = false;
for (int iIndex = 0; iIndex < argc; iIndex++)
{
if (!argv[iIndex])
continue;
#if defined(_WIN32) && defined(_UNICODE)
bRepeatEnabled |= std::wcsncmp(argv[iIndex], L"--gtest_repeat", 14) == 0;
#else
bRepeatEnabled |= std::strncmp(argv[iIndex], "--gtest_repeat", 14) == 0;
#endif
}
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
// When repeat is enabled, do not enable the watchdog.
if (bRepeatEnabled)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
else
{
CProcessWatchdog watchdog;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
}

View File

@@ -1446,7 +1446,7 @@ TEST(DataDispatchServiceTest, TransactionalRxTxSignalConcurrency)
std::atomic_uint64_t uiValueCnt = 1000;
bool bShutdown = false;
bool bShutdownPublisher = false, bShutdownConsumer = false;
std::srand(static_cast<unsigned>(std::time(0)));
// Thread sync
@@ -1471,18 +1471,18 @@ TEST(DataDispatchServiceTest, TransactionalRxTxSignalConcurrency)
uiInitCnt++;
std::shared_lock<std::shared_mutex> lock(mtxStart);
while (!bShutdown)
while (!bShutdownPublisher)
{
sdv::core::CTransaction transaction = dispatch.CreateTransaction();
uint64_t uiValue = std::rand();
signalPubA.Write(uiValue, transaction);
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
signalPubB.Write(uiValue + 10, transaction);
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
signalPubC.Write(uiValue + 20, transaction);
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
signalPubD.Write(uiValue + 30, transaction);
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10));
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 10));
transaction.Finish();
}
}
@@ -1513,7 +1513,7 @@ TEST(DataDispatchServiceTest, TransactionalRxTxSignalConcurrency)
uiInitCnt++;
std::shared_lock<std::shared_mutex> lock(mtxStart);
while (!bShutdown)
while (!bShutdownConsumer)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
@@ -1616,9 +1616,11 @@ TEST(DataDispatchServiceTest, TransactionalRxTxSignalConcurrency)
// Wait for all threads to finalize
appcontrol.SetConfigMode();
bShutdown = true;
bShutdownPublisher = true;
for (std::thread& rThread : rgPublishThreads)
if (rThread.joinable()) rThread.join();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
bShutdownConsumer = true;
for (std::thread& rThread : rgConsumeThreads)
if (rThread.joinable()) rThread.join();

View File

@@ -12,7 +12,7 @@
#include <interfaces/dispatch.h>
#include <support/app_control.h>
#include <support/timer.h>
#include <support/sdv_test_macro.h>
#include "../../include/sdv_test_macro.h"
#include "../../../global/process_watchdog.h"
#include "../global/ascformat/ascreader.cpp"
#include "../global/ascformat/ascwriter.cpp"
@@ -2713,38 +2713,38 @@ TEST(DbcUtilCanDLTest, CyclicTransmit)
if (iCnt < 4)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_ENABLED);
}
for (n = 0; n < 5; n++)
{
if (n != 0)
{
if (vecStat[n] > 6) // In the unlucky case, 6 triggers might have occurred (during startup, there might be many more...).
if (vecStat[n] > 6u) // In the unlucky case, 6 triggers might have occurred (during startup, there might be many more...).
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(vecStat[n], 6, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(vecStat[n], 6u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(vecStat[n], 6, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(vecStat[n], 6u, sdv_test::WARNING_ENABLED);
}
double dPeriod = std::round((vecTime[n] - vecTime[n - 1]) * 1000.0) / 1000.0;
if (dPeriod > 0.051) // Max 51ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_ENABLED);
}
if (n == 4)
{
if (dPeriod < 0.019) // Min 19ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_ENABLED);
}
}
else
@@ -2752,18 +2752,18 @@ TEST(DbcUtilCanDLTest, CyclicTransmit)
if (dPeriod < 0.039) // Min 39ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_ENABLED);
}
}
}
if (vecStat[n] < 4u) // At least 4 triggers.
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(vecStat[n], 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(vecStat[n], 4u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(vecStat[n], 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(vecStat[n], 4u, sdv_test::WARNING_ENABLED);
}
}
}
@@ -2857,9 +2857,9 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveTransmit)
if (iCnt != 0 && iCnt != 2)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(iCnt, 0, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(iCnt, 0, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(iCnt, 0, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(iCnt, 0, sdv_test::WARNING_ENABLED);
}
bInit = true;
@@ -2874,9 +2874,9 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveTransmit)
if (iCnt < 4)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_ENABLED);
}
for (n = 0; n < 5; n++)
@@ -2885,40 +2885,40 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveTransmit)
{
if (n == 2)
{
if (vecStat[n] != 1) // One trigger should have occurred due to default value
if (vecStat[n] != 1u) // One trigger should have occurred due to default value
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(vecStat[n], 1, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(vecStat[n], 1u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(vecStat[n], 1, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(vecStat[n], 1u, sdv_test::WARNING_ENABLED);
}
}
else
{
if (vecStat[n] > 6) // In the unlucky case, 6 triggers might have occurred (during startup, there might be many more...).
if (vecStat[n] > 6u) // In the unlucky case, 6 triggers might have occurred (during startup, there might be many more...).
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(vecStat[n], 6, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(vecStat[n], 6u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(vecStat[n], 6, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(vecStat[n], 6u, sdv_test::WARNING_ENABLED);
}
}
double dPeriod = std::round((vecTime[n] - vecTime[n - 1]) * 1000.0) / 1000.0;
if (dPeriod > 0.051) // Max 51ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_ENABLED);
}
if (n == 4)
{
if (dPeriod < 0.019) // Min 19ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_ENABLED);
}
}
else
@@ -2926,9 +2926,9 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveTransmit)
if (dPeriod < 0.039) // Min 39ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_ENABLED);
}
}
}
@@ -3028,38 +3028,38 @@ TEST(DbcUtilCanDLTest, CyclicAndSpontaneousTransmit)
if (iCnt < 4)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_ENABLED);
}
for (n = 0; n < 5; n++)
{
if (n != 0)
{
if (vecStat[n] != 2) // One trigger and one cycle.
if (vecStat[n] != 2u) // One trigger and one cycle.
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(vecStat[n], 2, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(vecStat[n], 2u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(vecStat[n], 2, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(vecStat[n], 2u, sdv_test::WARNING_ENABLED);
}
double dPeriod = std::round((vecTime[n] - vecTime[n - 1]) * 1000.0) / 1000.0;
if (dPeriod > 0.051) // Max 51ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_ENABLED);
}
if (n == 4)
{
if (dPeriod < 0.019) // Min 19ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_ENABLED);
}
}
else
@@ -3067,9 +3067,9 @@ TEST(DbcUtilCanDLTest, CyclicAndSpontaneousTransmit)
if (dPeriod < 0.039) // Min 39ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_ENABLED);
}
}
}
@@ -3172,43 +3172,43 @@ TEST(DbcUtilCanDLTest, SpontaneousDelayTransmit)
if (iCnt < 4)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_ENABLED);
}
for (n = 0; n < 5; n++)
{
if (n != 0)
{
if (vecStat[n] > 4) // Max 4 times
if (vecStat[n] > 4u) // Max 4 times
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(vecStat[n], 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(vecStat[n], 4u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(vecStat[n], 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(vecStat[n], 4u, sdv_test::WARNING_ENABLED);
}
if (vecStat[n] < 3) // Min 3 times
if (vecStat[n] < 3u) // Min 3 times
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(vecStat[n], 3, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(vecStat[n], 3u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(vecStat[n], 3, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(vecStat[n], 3u, sdv_test::WARNING_ENABLED);
}
double dPeriod = std::round((vecLastTime[n] - vecFirstTime[n]) * 1000.0) / 1000.0;
if (dPeriod > 0.061) // Max 61ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dPeriod, 0.061, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dPeriod, 0.061, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dPeriod, 0.061, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dPeriod, 0.061, sdv_test::WARNING_ENABLED);
}
if (dPeriod < 0.039) // Min 39ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_ENABLED);
}
}
}
@@ -3310,38 +3310,38 @@ TEST(DbcUtilCanDLTest, CyclicAndSpontaneousDelayTransmit)
if (iCnt < 4)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_ENABLED);
}
for (n = 0; n < 5; n++)
{
if (n != 0)
{
if (vecStat[n] != 2) // Two trigger and/or cycle.
if (vecStat[n] != 2u) // Two trigger and/or cycle.
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(vecStat[n], 2, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(vecStat[n], 2u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(vecStat[n], 2, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(vecStat[n], 2u, sdv_test::WARNING_ENABLED);
}
double dPeriod = std::round((vecTime[n] - vecTime[n - 1]) * 1000.0) / 1000.0;
if (dPeriod > 0.051) // Max 51ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_ENABLED);
}
if (n == 4)
{
if (dPeriod < 0.019) // Min 19ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_ENABLED);
}
}
else
@@ -3349,9 +3349,9 @@ TEST(DbcUtilCanDLTest, CyclicAndSpontaneousDelayTransmit)
if (dPeriod < 0.049) // Min 49ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.049, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.049, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.049, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.049, sdv_test::WARNING_ENABLED);
}
}
}
@@ -3446,9 +3446,9 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveAndSpontaneousTransmit)
if (iCnt != 0 && iCnt != 2)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(iCnt, 0, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(iCnt, 0, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(iCnt, 0, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(iCnt, 0, sdv_test::WARNING_ENABLED);
}
bInit = true;
@@ -3463,9 +3463,9 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveAndSpontaneousTransmit)
if (iCnt < 4)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(iCnt, 4, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(iCnt, 4, sdv_test::WARNING_ENABLED);
}
for (n = 0; n < 5; n++)
{
@@ -3473,40 +3473,40 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveAndSpontaneousTransmit)
{
if (n == 2)
{
if (vecStat[n] != 1) // One trigger no cycle.
if (vecStat[n] != 1u) // One trigger no cycle.
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(vecStat[n], 1, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(vecStat[n], 1u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(vecStat[n], 1, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(vecStat[n], 1u, sdv_test::WARNING_ENABLED);
}
}
else
{
if (vecStat[n] != 2) // One trigger and one cycle.
if (vecStat[n] != 2u) // One trigger and one cycle.
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(vecStat[n], 2, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(vecStat[n], 2u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(vecStat[n], 2, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(vecStat[n], 2u, sdv_test::WARNING_ENABLED);
}
}
double dPeriod = std::round((vecTime[n] - vecTime[n - 1]) * 1000.0) / 1000.0;
if (dPeriod > 0.051) // Max 51ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dPeriod, 0.051, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dPeriod, 0.051, sdv_test::WARNING_ENABLED);
}
if (n == 4)
{
if (dPeriod < 0.019) // Min 19ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.019, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.019, sdv_test::WARNING_ENABLED);
}
}
else
@@ -3514,9 +3514,9 @@ TEST(DbcUtilCanDLTest, CyclicIfActiveAndSpontaneousTransmit)
if (dPeriod < 0.039) // Min 39ms
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dPeriod, 0.039, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dPeriod, 0.039, sdv_test::WARNING_ENABLED);
}
}
}

View File

@@ -0,0 +1,273 @@
#ifndef SDV_TEST_MACRO_H
#define SDV_TEST_MACRO_H
#include <sstream>
#include <iostream>
#include <gtest/gtest.h>
/**
* @brief Namespace sdv_test
*/
namespace sdv_test
{
/**
* @brief Enum for warning levels.
*/
enum EWarningLevel
{
WARNING_ENABLED, //<! With this level Failed tests are reported as error as it is in GTEST normally.
WARNING_REDUCED, //<! With this level Failed tests are reported as warning.
WARNING_DISABLED //<! With this level no action is implemented at this moment.
};
/**
* @brief Function to report a warning when the expected condition is not met.
* @param[in] condition The condition that is being checked (should be true if valid).
* @param[in] warningLevel The level of warning to display.
* @param[in] message The warning message to display.
* @param[in] file The name of the file where the warning occurred.
* @param[in] line The line number where the warning occurred.
*/
inline void ReportWarning(bool condition, EWarningLevel warningLevel, const std::string& message, const char* file, int line)
{
if (!condition)
{
switch (warningLevel)
{
case WARNING_ENABLED:
FAIL() << "[ FAILED ]: " << message << " in file " << file << " on line " << line << std::endl;
break;
case WARNING_DISABLED:
// No action
break;
case WARNING_REDUCED:
std::clog << "[[ WARNING ]] TEST FAILURE NOT EVALUATED: " << message << " in file " << file <<
" on line " << line << std::endl;
break;
default:
break;
}
}
}
/**
* @brief Function to detect whether tests are running with CMAKE build or locally manually.
* @return Returns true if it is running with CMAKE build, otherwise false.
*/
inline bool IsRunningTestsWithCmakeBuild()
{
auto envVar = std::getenv("TEST_EXECUTION_MODE");
if (envVar && std::string(envVar) == "CMake") return true;
else return false;
}
} // namespace sdv_test
/**
* @brief Macro for checking whether tests are running with CMAKE build or locally manually.
* Returns true if it is running with CMAKE build, otherwise false.
*/
#define SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD sdv_test::IsRunningTestsWithCmakeBuild()
/**
* @brief Helper macro to handle warning levels.
* @param[in] level The warning level.
* @param[in] statement The statement to execute.
* @param[in] val1 The first value for comparison.
* @param[in] val2 The second value for comparison.
* @param[in] condition The condition to check.
*/
#define HANDLE_WARNING_LEVEL(level, statement, val1, val2, condition) \
do \
{ \
switch (level) \
{ \
case sdv_test::EWarningLevel::WARNING_ENABLED: \
statement; \
break; \
case sdv_test::EWarningLevel::WARNING_REDUCED: \
if (val1 condition val2) statement; \
else \
{ \
std::ostringstream oss; \
oss << "[[ WARNING ]] TEST FAILURE NOT EVALUATED: Condition did not match for [" \
<< #val1 "] and [" #val2 << "] in file " << __FILE__ << " on line " << __LINE__; \
std::clog << oss.str() << std::endl; \
} \
break; \
case sdv_test::EWarningLevel::WARNING_DISABLED: /* No action */ \
break; \
default: \
break; \
} \
} while (0)
/**
* @brief Redefine GTEST macros with warning level.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] level The warning level.
*/
#define SDV_EXPECT_EQ(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_EQ(val1, val2), val1, val2, ==)
#define SDV_ASSERT_EQ(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_EQ(val1, val2), val1, val2, ==)
#define SDV_EXPECT_NE(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_NE(val1, val2), val1, val2, !=)
#define SDV_ASSERT_NE(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_NE(val1, val2), val1, val2, !=)
#define SDV_EXPECT_TRUE(condition, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_TRUE(condition), condition, true, ==)
#define SDV_ASSERT_TRUE(condition, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_TRUE(condition), condition, true, ==)
#define SDV_EXPECT_FALSE(condition, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_FALSE(condition), condition, false, ==)
#define SDV_ASSERT_FALSE(condition, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_FALSE(condition), condition, false, ==)
#define SDV_EXPECT_LT(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_LT(val1, val2), val1, val2, <)
#define SDV_ASSERT_LT(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_LT(val1, val2), val1, val2, <)
#define SDV_EXPECT_LE(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_LE(val1, val2), val1, val2, <=)
#define SDV_ASSERT_LE(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_LE(val1, val2), val1, val2, <=)
#define SDV_EXPECT_GT(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_GT(val1, val2), val1, val2, >)
#define SDV_ASSERT_GT(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_GT(val1, val2), val1, val2, >)
#define SDV_EXPECT_GE(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_GE(val1, val2), val1, val2, >=)
#define SDV_ASSERT_GE(val1, val2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_GE(val1, val2), val1, val2, >=)
#define SDV_EXPECT_STREQ(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_STREQ((str1).c_str(), (str2).c_str()), str1, str2, ==)
#define SDV_ASSERT_STREQ(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_STREQ((str1).c_str(), (str2).c_str()), str1, str2, ==)
#define SDV_EXPECT_STRNE(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_STRNE(str1.c_str(), str2.c_str()), str1, str2, !=)
#define SDV_ASSERT_STRNE(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_STRNE(str1.c_str(), str2.c_str()), str1, str2, !=)
#define SDV_EXPECT_STRCASEEQ(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_STRCASEEQ((str1).c_str(), (str2).c_str()), str1, str2, ==)
#define SDV_ASSERT_STRCASEEQ(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_STRCASEEQ((str1).c_str(), (str2).c_str()), str1, str2, ==)
#define SDV_EXPECT_STRCASENE(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, EXPECT_STRCASENE((str1).c_str(), (str2).c_str()), str1, str2, !=)
#define SDV_ASSERT_STRCASENE(str1, str2, level) \
HANDLE_WARNING_LEVEL(level, ASSERT_STRCASENE((str1).c_str(), (str2).c_str()), str1, str2, !=)
/**
* @brief Macro for equality check (==) with warning reporting for time critical tests.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] warningLevel The level of warning to display.
*/
#define SDV_EXPECT_EQ_WARN(val1, val2, warningLevel) \
do { \
auto expr1 = val1; \
auto expr2 = val2; \
sdv_test::ReportWarning((expr1) == (expr2), warningLevel, \
"Expected " #val1 " == " #val2 " (" #val1 "=" + std::to_string(expr1) + ", " #val2 "=" + std::to_string(expr2) + ")", \
__FILE__, __LINE__); \
} while (0)
/**
* @brief Macro for inequality check (!=) with warning reporting for time critical tests.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] warningLevel The level of warning to display.
*/
#define SDV_EXPECT_NE_WARN(val1, val2, warningLevel) \
do { \
auto expr1 = val1; \
auto expr2 = val2; \
sdv_test::ReportWarning((expr1) != (expr2), warningLevel, \
"Expected " #val1 " != " #val2 " (" #val1 "=" + std::to_string(expr1) + ", " #val2 "=" + std::to_string(expr2) + ")", \
__FILE__, __LINE__); \
} while (0)
/**
* @brief Macro for greater-than check (>) with warning reporting for time critical tests.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] warningLevel The level of warning to display.
*/
#define SDV_EXPECT_GT_WARN(val1, val2, warningLevel) \
do { \
auto expr1 = val1; \
auto expr2 = val2; \
sdv_test::ReportWarning((expr1) > (expr2), warningLevel, \
"Expected " #val1 " > " #val2 " (" #val1 "=" + std::to_string(expr1) + ", " #val2 "=" + std::to_string(expr2) + ")", \
__FILE__, __LINE__); \
} while (0)
/**
* @brief Macro for less-than check (<) with warning reporting for time critical tests.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] warningLevel The level of warning to display.
*/
#define SDV_EXPECT_LT_WARN(val1, val2, warningLevel) \
do { \
auto expr1 = val1; \
auto expr2 = val2; \
sdv_test::ReportWarning((expr1) < (expr2), warningLevel, \
"Expected " #val1 " < " #val2 " (" #val1 "=" + std::to_string(expr1) + ", " #val2 "=" + std::to_string(expr2) + ")", \
__FILE__, __LINE__); \
} while (0)
/**
* @brief Macro for greater-than-or-equal-to check (>=) with warning reporting for time critical tests.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] warningLevel The level of warning to display.
*/
#define SDV_EXPECT_GE_WARN(val1, val2, warningLevel) \
do { \
auto expr1 = val1; \
auto expr2 = val2; \
sdv_test::ReportWarning((expr1) >= (expr2), warningLevel, \
"Expected " #val1 " >= " #val2 " (" #val1 "=" + std::to_string(expr1) + ", " #val2 "=" + std::to_string(expr2) + ")", \
__FILE__, __LINE__); \
} while (0)
/**
* @brief Macro for less-than-or-equal-to check (<=) with warning reporting for time critical tests.
* @param[in] val1 The first value.
* @param[in] val2 The second value.
* @param[in] warningLevel The level of warning to display.
*/
#define SDV_EXPECT_LE_WARN(val1, val2, warningLevel) \
do { \
auto expr1 = val1; \
auto expr2 = val2; \
sdv_test::ReportWarning((expr1) <= (expr2), warningLevel, \
"Expected " #val1 " <= " #val2 " (" #val1 "=" + std::to_string(expr1) + ", " #val2 "=" + std::to_string(expr2) + ")", \
__FILE__, __LINE__); \
} while (0)
#endif // SDV_TEST_MACRO_H

View File

@@ -4,6 +4,7 @@
#include <thread>
#include <cstdint>
#include <iostream>
#include <atomic>
#ifdef _WIN32
// Prevent reassignment of "interface"
#pragma push_macro("interface")
@@ -96,8 +97,8 @@ private:
}
}
bool m_bTerminateWatchdog = false; ///< When set, allows the thread to terminate.
std::thread m_threadWatchdog; ///< The watchdog thread.
std::atomic_bool m_bTerminateWatchdog = false; ///< When set, allows the thread to terminate.
std::thread m_threadWatchdog; ///< The watchdog thread.
};
#endif // !defined TEST_WATCHDOG_H

View File

@@ -4,6 +4,7 @@
#include <thread>
#include <atomic>
#include <vector>
#include <atomic>
#include <condition_variable>
#include <gtest/gtest.h>
#include <interfaces/can.h>
@@ -121,7 +122,7 @@ public:
bool m_messageSent = false;
private:
bool m_StopThread = false;
std::atomic_bool m_StopThread = false;
std::thread m_thSend2DatalinkThread;
mutable std::mutex m_mtxReceivers;
std::set<sdv::can::IReceive*> m_setReceivers;

View File

@@ -3,7 +3,7 @@
#include <iostream>
#include <fstream>
#include "../../../global/exec_dir_helper.h"
#include <support/sdv_test_macro.h>
#include "../../include/sdv_test_macro.h"
TEST(CAscWriterTest, AddSamplesDirect)
{
@@ -108,16 +108,16 @@ TEST(CAscWriterTest, AddTimedSamples)
if (dDeltaTSGenerated < dDeltaTSGroundThruth - 0.002)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(dDeltaTSGenerated, dDeltaTSGroundThruth - 0.002, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(dDeltaTSGenerated, dDeltaTSGroundThruth - 0.002, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(dDeltaTSGenerated, dDeltaTSGroundThruth - 0.002, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(dDeltaTSGenerated, dDeltaTSGroundThruth - 0.002, sdv_test::WARNING_ENABLED);
}
if (dDeltaTSGenerated > dDeltaTSGroundThruth + 0.002)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(dDeltaTSGenerated, dDeltaTSGroundThruth + 0.002, sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(dDeltaTSGenerated, dDeltaTSGroundThruth + 0.002, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(dDeltaTSGenerated, dDeltaTSGroundThruth + 0.002, sdv::TEST::WarningLevel::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(dDeltaTSGenerated, dDeltaTSGroundThruth + 0.002, sdv_test::WARNING_ENABLED);
}
std::cout << "TIMING: Expected generated timestamp <= ground truth + 2ms (generated=" << dDeltaTSGenerated << "ms, ground truth=" << dDeltaTSGroundThruth << ")..." << std::endl;
EXPECT_EQ(prSampleGroundTruth.first.uiChannel, prSampleGenerated.first.uiChannel);
@@ -136,7 +136,7 @@ TEST(CAscWriterTest, AddTimedSamples)
TEST(CAscWriterTest, ExtendedID)
{
asc::CAscReader readerGroundThruth;
SDV_EXPECT_TRUE(readerGroundThruth.Read(GetExecDirectory() / "asc_reader_ext_id_test.asc"), sdv::TEST::WarningLevel::WARNING_REDUCED);
SDV_EXPECT_TRUE(readerGroundThruth.Read(GetExecDirectory() / "asc_reader_ext_id_test.asc"), sdv_test::WARNING_REDUCED);
// Add all samples
asc::CAscWriter writer;

View File

@@ -80,10 +80,10 @@ TEST_F(CSerdesTest, DeserializeSimpleEndianSwap)
TEST_F(CSerdesTest, SerializeArray)
{
srand((unsigned int)time(0));
std::srand((unsigned int)time(0));
int16_t rguiBuffer[4096];
for (size_t nIndex = 0; nIndex < 4096; nIndex++)
rguiBuffer[nIndex] = static_cast<int16_t>(rand());
rguiBuffer[nIndex] = static_cast<int16_t>(std::rand());
sdv::serializer serializer;
serializer << rguiBuffer;
@@ -95,10 +95,10 @@ TEST_F(CSerdesTest, SerializeArray)
TEST_F(CSerdesTest, DeserializeArray)
{
srand((unsigned int)time(0));
std::srand((unsigned int)time(0));
int16_t rguiBuffer[4096];
for (size_t nIndex = 0; nIndex < 4096; nIndex++)
rguiBuffer[nIndex] = static_cast<int16_t>(rand());
rguiBuffer[nIndex] = static_cast<int16_t>(std::rand());
sdv::serializer serializer;
serializer << rguiBuffer;
@@ -113,10 +113,10 @@ TEST_F(CSerdesTest, DeserializeArray)
TEST_F(CSerdesTest, SerializeArrayEndianSwap)
{
srand((unsigned int)time(0));
std::srand((unsigned int)time(0));
int16_t rguiBuffer[4096];
for (size_t nIndex = 0; nIndex < 4096; nIndex++)
rguiBuffer[nIndex] = static_cast<int16_t>(rand());
rguiBuffer[nIndex] = static_cast<int16_t>(std::rand());
static constexpr sdv::EEndian eEndian =
sdv::GetPlatformEndianess() == sdv::EEndian::little_endian ? sdv::EEndian::big_endian : sdv::EEndian::little_endian;
@@ -139,10 +139,10 @@ TEST_F(CSerdesTest, SerializeArrayEndianSwap)
TEST_F(CSerdesTest, DeserializeArrayEndianSwap)
{
srand((unsigned int)time(0));
std::srand((unsigned int)time(0));
int16_t rguiBuffer[4096];
for (size_t nIndex = 0; nIndex < 4096; nIndex++)
rguiBuffer[nIndex] = static_cast<int16_t>(rand());
rguiBuffer[nIndex] = static_cast<int16_t>(std::rand());
static constexpr sdv::EEndian eEndian =
sdv::GetPlatformEndianess() == sdv::EEndian::little_endian ? sdv::EEndian::big_endian : sdv::EEndian::little_endian;

View File

@@ -5,33 +5,33 @@
#include <support/interface_ptr.h>
/**
* \brief Test class for instantiation tests.
* @brief Test class for instantiation tests.
*/
class CCommandLineParserTest : public testing::Test
{
public:
/**
* \brief Constructor
* @brief Constructor
*/
CCommandLineParserTest() = default;
/**
* \brief Set up the test suite.
* @brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
* @brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
* @brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
* @brief Test teardown.
*/
void TearDown() override;
};

View File

@@ -98,7 +98,7 @@ struct SMakeNoice
rthread.join();
}
bool bShutdown = false; ///< Run threads until shutdown is set.
std::atomic_bool bShutdown = false; ///< Run threads until shutdown is set.
std::atomic_size_t nStarted = 0; ///< Amount of threads that were started. This is to wait for all threads to start.
std::thread rgThreads[nAmount]; ///< The noise generating threads.
};
@@ -383,7 +383,7 @@ TEST(ConcurrencyTest, ConditionVarWaitForPrediction_SeparateMutexForEachThread_I
std::atomic_size_t nCnt = 0;
std::atomic_size_t nThreadCnt = 0;
std::atomic_size_t nViolationCnt = 0;
bool b1 = false, b2 = false, b3 = false, b4 = false;
std::atomic_bool b1 = false, b2 = false, b3 = false, b4 = false;
SMakeNoice noice;
std::thread thread1([&]()
{

View File

@@ -5,33 +5,33 @@
#include <support/interface_ptr.h>
/**
* \brief Test class for instantiation tests.
* @brief Test class for instantiation tests.
*/
class CDbcParserTest : public testing::Test
{
public:
/**
* \brief Constructor
* @brief Constructor
*/
CDbcParserTest() = default;
/**
* \brief Set up the test suite.
* @brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
* @brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
* @brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
* @brief Test teardown.
*/
void TearDown() override;
};

View File

@@ -2,33 +2,33 @@
#define LEXER_TEST_H
/**
* \brief Test class for instantiation tests.
* @brief Test class for instantiation tests.
*/
class CLexerTest : public testing::Test
{
public:
/**
* \brief Constructor
* @brief Constructor
*/
CLexerTest() = default;
/**
* \brief Set up the test suite.
* @brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
* @brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
* @brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
* @brief Test teardown.
*/
void TearDown() override;

View File

@@ -2,33 +2,33 @@
#define PARSER_TEST_H
/**
* \brief Test class for instantiation tests.
* @brief Test class for instantiation tests.
*/
class CParserTest : public testing::Test
{
public:
/**
* \brief Constructor
* @brief Constructor
*/
CParserTest() = default;
/**
* \brief Set up the test suite.
* @brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
* @brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
* @brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
* @brief Test teardown.
*/
void TearDown() override;

View File

@@ -9,8 +9,10 @@
#include "../../../sdv_services/core/installation_composer.cpp"
#include "../../../sdv_services/core/toml_parser/parser_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml_token.cpp"
#include "../../../sdv_services/core/toml_parser/parser_node_toml.cpp"
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
#include <support/app_control.h>
#if defined(_WIN32) && defined(_UNICODE)

View File

@@ -2108,7 +2108,7 @@ TEST_F(CInstallPackageComposerTest, DetectPackageCorruptionContent)
for (size_t n = 0; n < 25; n++)
{
// Corrupt the package at the content (from 100 until the size minus 32)
size_t nPos = static_cast<size_t>(rand()) * (ptrPackage.size() - 132) / RAND_MAX + 100;
size_t nPos = static_cast<size_t>(std::rand()) * (ptrPackage.size() - 132) / RAND_MAX + 100;
uint8_t uiStoredByte = ptrPackage.get()[nPos];
ptrPackage.get()[nPos] = ~uiStoredByte;
@@ -2337,7 +2337,7 @@ TEST_F(CInstallPackageComposerTest, VerifyIntegrityCorruptionContent)
for (size_t n = 0; n < 25; n++)
{
// Corrupt the package at the content (from 100 until the size minus 32)
size_t nPos = static_cast<size_t>(rand()) * (ptrPackage.size() - 132) / RAND_MAX + 100;
size_t nPos = static_cast<size_t>(std::rand()) * (ptrPackage.size() - 132) / RAND_MAX + 100;
uint8_t uiStoredByte = ptrPackage.get()[nPos];
ptrPackage.get()[nPos] = ~uiStoredByte;

View File

@@ -3,6 +3,7 @@
#include "../../../sdv_services/ipc_com/com_ctrl.cpp"
#include "../../../sdv_services/ipc_com/com_channel.cpp"
#include "../../../sdv_services/ipc_com/marshall_object.cpp"
#include <cstring>
/**
* @brief Main function
@@ -13,8 +14,29 @@ extern "C" int wmain(int argc, wchar_t* argv[])
extern "C" int main(int argc, char* argv[])
#endif
{
CProcessWatchdog watchdog;
// Check for the --gtest_repeat option.
bool bRepeatEnabled = false;
for (int iIndex = 0; iIndex < argc; iIndex++)
{
if (!argv[iIndex]) continue;
#if defined(_WIN32) && defined(_UNICODE)
bRepeatEnabled |= std::wcsncmp(argv[iIndex], L"--gtest_repeat", 14) == 0;
#else
bRepeatEnabled |= std::strncmp(argv[iIndex], "--gtest_repeat", 14) == 0;
#endif
}
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
// When repeat is enabled, do not enable the watchdog.
if (bRepeatEnabled)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
else
{
CProcessWatchdog watchdog;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
}

View File

@@ -4,6 +4,7 @@
#include <vector>
#include <list>
#include <deque>
#include <atomic>
TEST(TraceFifoTest, Connect_Disconnect)
{
@@ -190,7 +191,7 @@ TEST(TraceFifoTest, Simple_Publish_Monitor)
EXPECT_TRUE(fifoReader.IsOpened());
std::vector<std::string> vecSent, vecReceived;
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::thread thread([&]()
@@ -238,7 +239,7 @@ TEST(TraceFifoTest, Simple_Publish_Monitor_Multi)
EXPECT_TRUE(fifoReader2.IsOpened());
std::vector<std::string> vecSent, vecReceived1, vecReceived2;
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::thread thread1([&]()
@@ -297,7 +298,7 @@ TEST(TraceFifoTest, Simple_Publish_Beyond_Buffer_With_Reading)
EXPECT_TRUE(fifoReader.IsOpened());
std::vector<std::string> vecSent, vecReceived;
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::thread thread([&]()

View File

@@ -3,8 +3,10 @@
#include "mock.h"
#include "../../../sdv_services/core/toml_parser/parser_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml_token.cpp"
#include "../../../sdv_services/core/toml_parser/parser_node_toml.cpp"
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
#include "../../../sdv_services/core/module_control.cpp"
#include "../../../sdv_services/core/module.cpp"
#include "../../../sdv_services/core/app_config.cpp"

View File

@@ -11,13 +11,7 @@
class CMock
{
public:
CMock() : m_root("root")
{
auto ptrElement = std::make_shared<CNormalTable>("Install");
m_root.AddElement(ptrElement);
auto ptrValue = std::make_shared<CStringNode>("Directory", "install/test");
ptrElement->AddElement(ptrValue);
}
CMock() {}
void DestroyModuleObjects(sdv::core::TModuleID) {}
bool IsStandaloneApplication() { return true; }
bool IsEssentialApplication() { return false; }
@@ -40,9 +34,8 @@ public:
sdv::core::TModuleID ContextLoad(const std::filesystem::path&, const sdv::u8string&) { return 0; }
bool ContextUnload(sdv::core::TModuleID, bool) { return false; }
CNormalTable m_root;
bool m_bIsMain = false;
bool m_bIsIsolated = false;
bool m_bIsMain = false;
bool m_bIsIsolated = false;
};
inline CMock& GetMock()

View File

@@ -3,6 +3,7 @@
#include "../../../global/ipc_named_mutex.h"
#include <chrono>
#include <thread>
#include <atomic>
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain(int argc, wchar_t* argv[])
@@ -28,19 +29,19 @@ TEST(NamedMutexTest, CritSectSyncManualLock)
// The checking is manipulated by the bEnable flag. When disabled, no sync will be done and the check will fail. When enabled,
// sync will be done and the check will succeed.
int32_t iCnt = 0;
bool bSuccess = true;
bool bEnable = false;
std::atomic_bool bSuccess = true;
std::atomic_bool bEnable = false;
auto fn = [&]()
{
ipc::named_mutex mtx("HELLO");
if (bEnable)
mtx.lock();
bSuccess &= (iCnt == 0);
bSuccess = bSuccess && (iCnt == 0);
iCnt++;
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 100));
iCnt--;
bSuccess &= (iCnt == 0);
bSuccess = bSuccess && (iCnt == 0);
if (bEnable)
mtx.unlock();
};
@@ -69,17 +70,17 @@ TEST(NamedMutexTest, CritSectSyncAutoLock)
{
// Counter function check for correct counter value.
int32_t iCnt = 0;
bool bSuccess = true;
std::atomic_bool bSuccess = true;
auto fn = [&]()
{
ipc::named_mutex mtx("HELLO");
std::unique_lock<ipc::named_mutex> lock(mtx);
bSuccess &= (iCnt == 0);
bSuccess = bSuccess && (iCnt == 0);
iCnt++;
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 100));
iCnt--;
bSuccess &= (iCnt == 0);
bSuccess = bSuccess && (iCnt == 0);
};
// Test sync
@@ -94,7 +95,7 @@ TEST(NamedMutexTest, CritSectSyncAutoLock)
TEST(NamedMutexTest, TryLock)
{
bool bRunning = false;
std::atomic_bool bRunning = false;
auto fn = [&]()
{
ipc::named_mutex mtx("HELLO");

View File

@@ -3,8 +3,10 @@
#include "mock.h"
#include "../../../sdv_services/core/toml_parser/parser_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml_token.cpp"
#include "../../../sdv_services/core/toml_parser/parser_node_toml.cpp"
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
#include "../../../sdv_services/core/module_control.cpp"
#include "../../../sdv_services/core/module.cpp"
#include "../../../sdv_services/core/repository.cpp"

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "../../../global/process_watchdog.h"
#include "support/sdv_test_macro.h"
#include "../../include/sdv_test_macro.h"
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain(int argc, wchar_t* argv[])
@@ -19,9 +19,9 @@ TEST(SDVTestMacros, TestExpectEq)
int val1 = 5;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_EQ(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_EQ(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertEq)
@@ -29,9 +29,9 @@ TEST(SDVTestMacros, TestAssertEq)
int val1 = 5;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_EQ(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_EQ(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_EQ(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_EQ(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectNe)
@@ -39,9 +39,9 @@ TEST(SDVTestMacros, TestExpectNe)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_NE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_NE(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_NE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_NE(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertNe)
@@ -49,45 +49,45 @@ TEST(SDVTestMacros, TestAssertNe)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_NE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_NE(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_NE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_NE(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectTrue)
{
bool condition = true;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_TRUE(condition, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_TRUE(condition, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_TRUE(condition, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_TRUE(condition, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertTrue)
{
bool condition = true;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_TRUE(condition, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_TRUE(condition, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_TRUE(condition, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_TRUE(condition, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectFalse)
{
bool condition = false;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_FALSE(condition, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_FALSE(condition, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_FALSE(condition, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_FALSE(condition, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertFalse)
{
bool condition = false;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_FALSE(condition, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_FALSE(condition, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_FALSE(condition, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_FALSE(condition, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectLt)
@@ -95,9 +95,9 @@ TEST(SDVTestMacros, TestExpectLt)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_LT(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_LT(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_LT(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_LT(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertLt)
@@ -105,9 +105,9 @@ TEST(SDVTestMacros, TestAssertLt)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_LT(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_LT(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_LT(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_LT(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectLe)
@@ -115,9 +115,9 @@ TEST(SDVTestMacros, TestExpectLe)
int val1 = 5;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_LE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_LE(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_LE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_LE(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertLe)
@@ -125,9 +125,9 @@ TEST(SDVTestMacros, TestAssertLe)
int val1 = 5;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_LE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_LE(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_LE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_LE(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectGt)
@@ -135,9 +135,9 @@ TEST(SDVTestMacros, TestExpectGt)
int val1 = 6;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_GT(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_GT(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_GT(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_GT(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertGt)
@@ -145,9 +145,9 @@ TEST(SDVTestMacros, TestAssertGt)
int val1 = 6;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_GT(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_GT(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_GT(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_GT(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectGe)
@@ -155,9 +155,9 @@ TEST(SDVTestMacros, TestExpectGe)
int val1 = 6;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_GE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_GE(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_GE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_GE(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertGe)
@@ -165,9 +165,9 @@ TEST(SDVTestMacros, TestAssertGe)
int val1 = 6;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_GE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_GE(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_GE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_GE(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectStreq)
@@ -175,9 +175,9 @@ TEST(SDVTestMacros, TestExpectStreq)
std::string str1 = "test";
std::string str2 = "test";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_STREQ(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_STREQ(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_STREQ(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_STREQ(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertStreq)
@@ -185,9 +185,9 @@ TEST(SDVTestMacros, TestAssertStreq)
std::string str1 = "test";
std::string str2 = "test";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_STREQ(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_STREQ(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_STREQ(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_STREQ(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectStrne)
@@ -195,9 +195,9 @@ TEST(SDVTestMacros, TestExpectStrne)
std::string str1 = "test";
std::string str2 = "test1";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_STRNE(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_STRNE(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_STRNE(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_STRNE(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertStrne)
@@ -205,9 +205,9 @@ TEST(SDVTestMacros, TestAssertStrne)
std::string str1 = "test";
std::string str2 = "test1";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_STRNE(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_STRNE(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_STRNE(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_STRNE(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectStrcaseeq)
@@ -215,9 +215,9 @@ TEST(SDVTestMacros, TestExpectStrcaseeq)
std::string str1 = "test";
std::string str2 = "TEST";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_STRCASEEQ(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_STRCASEEQ(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_STRCASEEQ(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_STRCASEEQ(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertStrcaseeq)
@@ -225,9 +225,9 @@ TEST(SDVTestMacros, TestAssertStrcaseeq)
std::string str1 = "test";
std::string str2 = "TEST";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_STRCASEEQ(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_STRCASEEQ(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_STRCASEEQ(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_STRCASEEQ(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestExpectStrcasene)
@@ -235,9 +235,9 @@ TEST(SDVTestMacros, TestExpectStrcasene)
std::string str1 = "test";
std::string str2 = "TEST1";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_EXPECT_STRCASENE(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_STRCASENE(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_EXPECT_STRCASENE(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_STRCASENE(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestAssertStrcasene)
@@ -245,9 +245,9 @@ TEST(SDVTestMacros, TestAssertStrcasene)
std::string str1 = "test";
std::string str2 = "TEST1";
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_ASSERT_STRCASENE(str1, str2, sdv::TEST::WARNING_REDUCED);
SDV_ASSERT_STRCASENE(str1, str2, sdv_test::WARNING_REDUCED);
else
SDV_ASSERT_STRCASENE(str1, str2, sdv::TEST::WARNING_ENABLED);
SDV_ASSERT_STRCASENE(str1, str2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestTimingExpectEq)
@@ -255,9 +255,9 @@ TEST(SDVTestMacros, TestTimingExpectEq)
int val1 = 5;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestTimingExpectNe)
@@ -265,9 +265,9 @@ TEST(SDVTestMacros, TestTimingExpectNe)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_NE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_NE_WARN(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_NE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_NE_WARN(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestTimingExpectGt)
@@ -275,9 +275,9 @@ TEST(SDVTestMacros, TestTimingExpectGt)
int val1 = 6;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GT(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_GT_WARN(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GT(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_GT_WARN(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestTimingExpectLt)
@@ -285,9 +285,9 @@ TEST(SDVTestMacros, TestTimingExpectLt)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LT(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_LT_WARN(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LT(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_LT_WARN(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestTimingExpectGe)
@@ -295,9 +295,9 @@ TEST(SDVTestMacros, TestTimingExpectGe)
int val1 = 6;
int val2 = 5;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_GE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_GE_WARN(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_GE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_GE_WARN(val1, val2, sdv_test::WARNING_ENABLED);
}
TEST(SDVTestMacros, TestTimingExpectLe)
@@ -305,7 +305,7 @@ TEST(SDVTestMacros, TestTimingExpectLe)
int val1 = 5;
int val2 = 6;
if (SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_LE(val1, val2, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_LE_WARN(val1, val2, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_LE(val1, val2, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_LE_WARN(val1, val2, sdv_test::WARNING_ENABLED);
}

View File

@@ -53,16 +53,11 @@ endif()
# Add the communication unittest
add_test(NAME UnitTest_InprocMemTests COMMAND UnitTest_InprocMemTests)
#TODO Shared memory tests during complete rebuild fail on Windows when compiling with MINGW. This is due to race conditions occuring
# only when the system is under heavy load (like during a complete rebuild). The tests have been disabled for the moment and a
# bug report is filed here: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608134
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
# Execute the test
add_custom_command(TARGET UnitTest_InprocMemTests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_InprocMemTests>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_InprocMemTests.xml
VERBATIM
)
endif()
# Shared mem buffer test
add_executable(UnitTest_SharedMemBufferTests
@@ -85,16 +80,11 @@ endif()
# Add the communication unittest
add_test(NAME UnitTest_SharedMemBufferTests COMMAND UnitTest_SharedMemBufferTests)
#TODO Shared memory tests during complete rebuild fail on Windows when compiling with MINGW. This is due to race conditions occuring
# only when the system is under heavy load (like during a complete rebuild). The tests have been disabled for the moment and a
# bug report is filed here: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608134
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
# Execute the test
add_custom_command(TARGET UnitTest_SharedMemBufferTests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_SharedMemBufferTests>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_SharedMemBufferTests.xml
VERBATIM
)
endif()
# Shared mem connection test
add_executable(UnitTest_SharedMemConnectTests
@@ -115,16 +105,11 @@ endif()
# Add the communication unittest
add_test(NAME UnitTest_SharedMemConnectTests COMMAND UnitTest_SharedMemConnectTests)
#TODO Shared memory tests during complete rebuild fail on Windows when compiling with MINGW. This is due to race conditions occuring
# only when the system is under heavy load (like during a complete rebuild). The tests have been disabled for the moment and a
# bug report is filed here: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608134
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
# Execute the test
add_custom_command(TARGET UnitTest_SharedMemConnectTests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_SharedMemConnectTests>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_SharedMemConnectTests.xml
VERBATIM
)
endif()
# Shared mem large data test
@@ -146,16 +131,11 @@ endif()
# Add the communication unittest
add_test(NAME UnitTest_SharedMemLargeDataTests COMMAND UnitTest_SharedMemLargeDataTests)
#TODO Shared memory tests during complete rebuild fail on Windows when compiling with MINGW. This is due to race conditions occuring
# only when the system is under heavy load (like during a complete rebuild). The tests have been disabled for the moment and a
# bug report is filed here: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/608134
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
# Execute the test
add_custom_command(TARGET UnitTest_SharedMemLargeDataTests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_SharedMemLargeDataTests>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_SharedMemLargeDataTests.xml
VERBATIM
)
endif()
# Build dependencies
add_dependencies(UnitTest_SharedMemTests_App_Repeater core_services)

View File

@@ -4,7 +4,7 @@
#define TIME_TRACKING
#include "../../../sdv_services/ipc_shared_mem/channel_mgnt.cpp"
#include "../../../sdv_services/ipc_shared_mem/connection.cpp"
#include "../../../sdv_services/ipc_shared_mem/connection.cpp" // Tracing is enabled/disabled in the connection.h file
#include "../../../sdv_services/ipc_shared_mem/watchdog.cpp"
#include "../../../sdv_services/ipc_shared_mem/mem_buffer_accessor.cpp"
#include <sstream>
@@ -12,6 +12,7 @@
#include <iostream>
#include <fstream>
#include <queue>
#include <atomic>
#ifdef __GNUC__
#include <unistd.h>
@@ -67,6 +68,8 @@ public:
{
// Send the same data back again (if needed).
std::unique_lock<std::mutex> lock(m_mtxData);
m_nReceiveCallCnt++;
m_nPackageReceiveCnt += seqData.size();
m_queueSendData.push(seqData);
lock.unlock();
@@ -93,7 +96,10 @@ public:
// Send the data back to the sender
if (m_pSend)
{
m_pSend->SendData(seqData);
m_nSendCallCnt++;
}
}
}
@@ -184,6 +190,33 @@ public:
m_threadSender.join();
}
/**
* @brief Get the receive call count.
* @return The amount of receive calls that has been made.
*/
size_t GetReceiveCallCount() const
{
return m_nReceiveCallCnt;
}
/**
* @brief Get the package call count.
* @return The amount of packages that have been received.
*/
size_t GetPackageReceiveCount() const
{
return m_nPackageReceiveCnt;
}
/**
* @brief Get the send call count.
* @return The amount of send calls that has been made.
*/
size_t GetSendCallCount() const
{
return m_nSendCallCnt;
}
private:
sdv::ipc::IDataSend* m_pSend = nullptr; ///< Send interface to implement repeating function.
mutable std::mutex m_mtxData; ///< Protect data access.
@@ -191,9 +224,12 @@ private:
std::condition_variable m_cvDisconnect; ///< Disconnect event.
std::condition_variable m_cvReceived; ///< Receive event.
std::thread m_threadSender; ///< Thread to send data.
bool m_bConnected = false; ///< Set when connected was triggered.
bool m_bDisconnect = false; ///< Set when shutdown was triggered.
bool m_bShutdown = false; ///< Set when shutdown is processed.
std::atomic_bool m_bConnected = false; ///< Set when connected was triggered.
std::atomic_bool m_bDisconnect = false; ///< Set when shutdown was triggered.
std::atomic_bool m_bShutdown = false; ///< Set when shutdown is processed.
std::atomic_size_t m_nReceiveCallCnt = 0; ///< Receive call counter.
std::atomic_size_t m_nPackageReceiveCnt = 0; ///< Package receive counter.
std::atomic_size_t m_nSendCallCnt = 0; ///< Send call counter.
};
@@ -280,15 +316,18 @@ extern "C" int main(int argc, char* argv[])
// Open the control channel endpoint
sdv::TObjectPtr ptrControlConnection;
sdv::ipc::IConnect* pControlConnect = nullptr;
CReceiver receiverControl;
uint64_t uiControlEventCookie = 0;
if (!ssControlConnectString.empty())
{
TRACE(bServer ? "Server" : "Client", ": Start of control channel connection...");
ptrControlConnection = mgntControlMgntChannel.Access(ssControlConnectString);
if (!ptrControlConnection) return -12;
sdv::ipc::IConnect* pControlConnect = ptrControlConnection.GetInterface<sdv::ipc::IConnect>();
pControlConnect = ptrControlConnection.GetInterface<sdv::ipc::IConnect>();
if (!pControlConnect) return -13;
if (!pControlConnect->RegisterStatusEventCallback(&receiverControl)) return -20;
uiControlEventCookie = pControlConnect->RegisterStatusEventCallback(&receiverControl);
if (!uiControlEventCookie) return -20;
if (!pControlConnect->AsyncConnect(&receiverControl)) return -14;
if (!pControlConnect->WaitForConnection(250)) return -5; // Note: Connection should be possible within 250ms.
if (pControlConnect->GetStatus() != sdv::ipc::EConnectStatus::connected) return -15;
@@ -339,8 +378,10 @@ Size = 1024000
// Establish the connection
sdv::ipc::IConnect* pDataConnect = ptrDataConnection.GetInterface<sdv::ipc::IConnect>();
uint64_t uiDataEventCookie = 0;
if (!pDataConnect) return -3;
if (!pDataConnect->RegisterStatusEventCallback(&receiverData)) return -21;
uiDataEventCookie = pDataConnect->RegisterStatusEventCallback(&receiverData);
if (!uiDataEventCookie) return -21;
if (!pDataConnect->AsyncConnect(&receiverData)) return -4;
if (!pDataConnect->WaitForConnection(10000)) return -5; // Note: Connection should be possible within 10000ms.
if (pDataConnect->GetStatus() != sdv::ipc::EConnectStatus::connected) return -5;
@@ -358,12 +399,17 @@ Size = 1024000
// Repeat data until disconnect occurrs (differentiate between forced and not forced to allow two apps to start at the
// same time).
receiverData.WaitUntilDisconnect(bForceTerminate ? 800 : 1600);
std::cout << "App " << (bServer ? "server" : "client") << " connect process disconnecting..." << std::endl;
TRACE("App ", bServer ? "server" : "client", " connect process disconnecting...");
}
// Statistics
TRACE("Receive was called ", receiverData.GetReceiveCallCount(), " times (", receiverData.GetPackageReceiveCount(),
" packages).");
TRACE("Send was called ", receiverData.GetSendCallCount(), " times.");
if (bForceTerminate)
{
std::cout << "Forced termination of app " << (bServer ? "server" : "client") << " connect process..." << std::endl;
TRACE("Forced termination of app ", bServer ? "server" : "client", " connect process...");
#ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
@@ -371,9 +417,11 @@ Size = 1024000
}
// Initiate shutdown
if (pDataConnect && uiDataEventCookie) pDataConnect->UnregisterStatusEventCallback(uiDataEventCookie);
ptrDataConnection.Clear();
mgntDataMgntChannel.Shutdown();
if (mgntDataMgntChannel.GetStatus() != sdv::EObjectStatus::destruction_pending) return -6;
if (pControlConnect && uiControlEventCookie) pControlConnect->UnregisterStatusEventCallback(uiControlEventCookie);
ptrControlConnection.Clear();
mgntControlMgntChannel.Shutdown();
if (mgntControlMgntChannel.GetStatus() != sdv::EObjectStatus::destruction_pending) return -16;

View File

@@ -2,6 +2,7 @@
#include "../../../sdv_services/ipc_shared_mem/in_process_mem_buffer.h"
#include <support/app_control.h>
#include "pattern_gen.h"
#include <atomic>
TEST(InProcessMemoryBufferTest, Instantiate)
{
@@ -26,7 +27,7 @@ TEST(InProcessMemoryBufferTest, TriggerTestRx)
CInProcMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
size_t nCorrectCnt = 0;
std::condition_variable cvStart;
std::mutex mtxStart;
@@ -75,7 +76,7 @@ TEST(InProcessMemoryBufferTest, TriggerTestTx)
CInProcMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
size_t nCorrectCnt = 0;
std::condition_variable cvStart;
std::mutex mtxStart;
@@ -124,7 +125,7 @@ TEST(InProcessMemoryBufferTest, TriggerTestRxTx)
CInProcMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
size_t nCorrectCnt = 0;
std::condition_variable cvSenderStart, cvReceiverStart;
std::mutex mtxReceiverStart;

View File

@@ -5,6 +5,7 @@
#include "../../../sdv_services/ipc_shared_mem/channel_mgnt.cpp"
#include "../../../sdv_services/ipc_shared_mem/watchdog.cpp"
#include "../../../sdv_services/ipc_shared_mem/mem_buffer_accessor.cpp"
#include <cstring>
/**
* @brief Load support modules to publish the needed services.
@@ -28,8 +29,30 @@ extern "C" int wmain(int argc, wchar_t* argv[])
extern "C" int main(int argc, char* argv[])
#endif
{
CProcessWatchdog watchdog;
// Check for the --gtest_repeat option.
bool bRepeatEnabled = false;
for (int iIndex = 0; iIndex < argc; iIndex++)
{
if (!argv[iIndex])
continue;
#if defined(_WIN32) && defined(_UNICODE)
bRepeatEnabled |= std::wcsncmp(argv[iIndex], L"--gtest_repeat", 14) == 0;
#else
bRepeatEnabled |= std::strncmp(argv[iIndex], "--gtest_repeat", 14) == 0;
#endif
}
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
// When repeat is enabled, do not enable the watchdog.
if (bRepeatEnabled)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
else
{
CProcessWatchdog watchdog;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
}

View File

@@ -3,6 +3,7 @@
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include "pattern_gen.h"
#include "../../../sdv_services/ipc_shared_mem/mem_buffer_accessor.h"

View File

@@ -2,6 +2,7 @@
#define PATTERN_GEN_H
#include <thread>
#include <atomic>
#include "../../../sdv_services/ipc_shared_mem/mem_buffer_accessor.h"
/**
@@ -43,8 +44,8 @@ public:
private:
CMemBufferAccessorTx& m_raccessorOut; //!< Reference to the output accessor
std::thread m_thread; //!< Processing thread
bool m_bStarted = false; //!< Set by the thread when started.
bool m_bShutdown = false; //!< When set, shutdown the thread.
std::atomic_bool m_bStarted = false; //!< Set by the thread when started.
std::atomic_bool m_bShutdown = false; //!< When set, shutdown the thread.
uint32_t m_uiDelayMs = 0u; //!< Delay (in ms) to insert while processing.
uint32_t m_uiCycleCnt = 0u; //!< Amount of packets
uint32_t m_uiPacketCnt = 0u; //!< Amount of packets

View File

@@ -1,5 +1,6 @@
#include <filesystem>
#include <fstream>
#include <atomic>
#include "gtest/gtest.h"
#include "pattern_gen.h"
#include "../../../sdv_services/ipc_shared_mem/shared_mem_buffer_posix.h"
@@ -28,10 +29,14 @@ TEST(SharedMemoryBufferTest, CreateBuffer)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
appcontrol.Shutdown();
}
@@ -42,12 +47,16 @@ TEST(SharedMemoryBufferTest, TriggerTestRx)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
size_t nCorrectCnt = 0;
std::condition_variable cvStart;
std::mutex mtxStart;
@@ -91,12 +100,16 @@ TEST(SharedMemoryBufferTest, TriggerTestTx)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
size_t nCorrectCnt = 0;
std::condition_variable cvStart;
std::mutex mtxStart;
@@ -140,16 +153,21 @@ TEST(SharedMemoryBufferTest, TriggerTestRxTx)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
size_t nCorrectCnt = 0;
std::condition_variable cvSenderStart, cvReceiverStart;
std::mutex mtxReceiverStart;
std::mutex mtxSenderStart;
auto fnWaitForTriggerReceiver = [&]()
{
std::unique_lock<std::mutex> lockReceiver(mtxReceiverStart);
@@ -166,9 +184,6 @@ TEST(SharedMemoryBufferTest, TriggerTestRxTx)
std::unique_lock<std::mutex> lockSender(mtxSenderStart);
lockSender.unlock();
cvSenderStart.notify_all();
std::unique_lock<std::mutex> lockReceiver(mtxReceiverStart);
cvReceiverStart.wait(lockReceiver);
lockReceiver.unlock();
while (!bShutdown)
{
bool bResult = sender.WaitForFreeSpace(200);
@@ -179,14 +194,15 @@ TEST(SharedMemoryBufferTest, TriggerTestRxTx)
};
std::unique_lock<std::mutex> lockStartSender(mtxSenderStart);
std::unique_lock<std::mutex> lockStartReceiver(mtxReceiverStart);
std::thread threadSender(fnWaitForTriggerSender);
std::thread threadReceiver(fnWaitForTriggerReceiver);
cvSenderStart.wait(lockStartSender);
lockStartSender.unlock();
std::unique_lock<std::mutex> lockStartReceiver(mtxReceiverStart);
std::thread threadReceiver(fnWaitForTriggerReceiver);
//CHECKPOINT();
cvReceiverStart.wait(lockStartReceiver);
lockStartReceiver.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(25)); // Needed for the threads to enter their loop.
std::this_thread::sleep_for(std::chrono::milliseconds(25)); // Needed for the threads to enter their loop.
for (size_t n = 0; n < 200; n++)
{
std::this_thread::sleep_for(std::chrono::milliseconds(20));
@@ -210,10 +226,14 @@ TEST(SharedMemoryBufferTest, SimpleSynchronousWriteRead)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
EXPECT_TRUE(sender.TryWrite("HELLO", 6));
auto optPacket = receiver.TryRead();
@@ -229,10 +249,14 @@ TEST(SharedMemoryBufferTest, ReadWithoutSending)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
auto optPacket = receiver.TryRead();
EXPECT_FALSE(optPacket);
@@ -246,10 +270,14 @@ TEST(SharedMemoryBufferTest, RequestReadPacketSize)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
EXPECT_TRUE(sender.TryWrite("HELLO", 5));
@@ -266,10 +294,14 @@ TEST(SharedMemoryBufferTest, FragmentRead)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
EXPECT_TRUE(sender.TryWrite("HELLO", 6));
EXPECT_TRUE(sender.TryWrite("HELLO2", 7));
@@ -296,10 +328,14 @@ TEST(SharedMemoryBufferTest, BufferBoundary)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender(256);
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
// The buffer header has 16 bytes
// Each allocation is 8 bytes header, 6 bytes data and 2 bytes alignment
@@ -353,10 +389,14 @@ TEST(SharedMemoryBufferTest, ReserveCommitAccessReleaseNonChronologicalOrder)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender(256);
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
// Reserve buffers for strings
// The buffer header has 16 bytes
@@ -464,10 +504,14 @@ TEST(SharedMemoryBufferTest, SendReceivePattern)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
CPatternReceiver pattern_inspector(receiver);
CPatternSender pattern_generator(sender);
@@ -501,10 +545,14 @@ TEST(SharedMemoryBufferTest, DelayedSendReceivePattern)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
CPatternReceiver pattern_inspector(receiver);
CPatternSender pattern_generator(sender, 10);
@@ -538,10 +586,14 @@ TEST(SharedMemoryBufferTest, SendDelayedReceivePattern)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx sender;
EXPECT_TRUE(sender.IsValid());
if (!sender.IsValid())
std::cout << "ERROR sender: " << sender.GetError() << std::endl;
ASSERT_TRUE(sender.IsValid());
CSharedMemBufferRx receiver(sender.GetConnectionString());
EXPECT_TRUE(receiver.IsValid());
if (!receiver.IsValid())
std::cout << "ERROR receiver: " << receiver.GetError() << std::endl;
ASSERT_TRUE(receiver.IsValid());
CPatternReceiver pattern_inspector(receiver, 10);
CPatternSender pattern_generator(sender);
@@ -575,9 +627,13 @@ TEST(SharedMemoryBufferTest, SendRepeatReceivePattern)
ASSERT_TRUE(appcontrol.Startup(""));
CSharedMemBufferTx bufferTX;
EXPECT_TRUE(bufferTX.IsValid());
if (!bufferTX.IsValid())
std::cout << "ERROR TX: " << bufferTX.GetError() << std::endl;
ASSERT_TRUE(bufferTX.IsValid());
CSharedMemBufferRx bufferRX;
EXPECT_TRUE(bufferRX.IsValid());
if (!bufferTX.IsValid())
std::cout << "ERROR RX: " << bufferTX.GetError() << std::endl;
ASSERT_TRUE(bufferRX.IsValid());
// The connection string containing the RX and TX strings for the repeater
std::string ssConnectionString = bufferTX.GetConnectionString() + "\n" + bufferRX.GetConnectionString();
@@ -630,9 +686,13 @@ Mode = "Essential")code"));
LoadSupportServices();
CSharedMemBufferTx bufferTX;
EXPECT_TRUE(bufferTX.IsValid());
if (!bufferTX.IsValid())
std::cout << "ERROR TX: " << bufferTX.GetError() << std::endl;
ASSERT_TRUE(bufferTX.IsValid());
CSharedMemBufferRx bufferRX;
EXPECT_TRUE(bufferRX.IsValid());
if (!bufferTX.IsValid())
std::cout << "ERROR RX: " << bufferTX.GetError() << std::endl;
ASSERT_TRUE(bufferRX.IsValid());
// Start process
sdv::process::IProcessControl* pProcessControl = sdv::core::GetObject<sdv::process::IProcessControl>("ProcessControlService");

View File

@@ -10,6 +10,7 @@
#include <algorithm>
#include <condition_variable>
#include <queue>
#include <atomic>
/**
* @brief Receiver helper class.
@@ -21,8 +22,7 @@ public:
* @brief Constructor
* @param[in] bEnableEvent When set, enable the connection event callback interface.
*/
CConnectReceiver(bool bEnableEvent = false) : m_bEnableEvent(bEnableEvent),
m_threadDecoupledSend(&CConnectReceiver::DecoupledSendThread, this)
CConnectReceiver(bool bEnableEvent = false) : m_bEnableEvent(bEnableEvent)
{}
/**
@@ -31,6 +31,8 @@ public:
~CConnectReceiver()
{
m_bShutdown = true;
std::unique_lock<std::mutex> lock(m_mtxData);
lock.unlock();
if (m_threadDecoupledSend.joinable())
m_threadDecoupledSend.join();
}
@@ -64,6 +66,10 @@ public:
// Copy the data
m_seqDataCopy = seqData;
// Start the processing thread if needed
if (!m_threadDecoupledSend.joinable()) m_threadDecoupledSend =
std::thread(&CConnectReceiver::DecoupledSendThread, this);
// Store data into the queue for sending.
m_queueDecoupledSend.push(std::move(seqData));
m_cvDecoupledSend.notify_all();
@@ -170,7 +176,7 @@ private:
std::thread m_threadDecoupledSend; ///< Decoupled send thread.
std::queue<sdv::sequence<sdv::pointer<uint8_t>>> m_queueDecoupledSend; ///< Data queue for sending.
std::condition_variable m_cvDecoupledSend; ///< Trigger decoupled sending.
bool m_bShutdown = false; ///< Shutdown send thread.
std::atomic_bool m_bShutdown = false; ///< Shutdown send thread.
};
/**

View File

@@ -7,10 +7,11 @@
#include <../global/base64.h>
#include <support/sdv_core.h>
#include <support/app_control.h>
#include <support/sdv_test_macro.h>
#include "../../include/sdv_test_macro.h"
#include <interfaces/ipc.h>
#include <algorithm>
#include <queue>
#include <atomic>
/**
* @brief Load support modules to publish the needed services.
@@ -27,8 +28,7 @@ public:
* @brief Constructor
* @param[in] bEnableEvent When set, enable the connection event callback interface.
*/
CLargeDataReceiver(bool bEnableEvent = false) : m_bEnableEvent(bEnableEvent),
m_threadDecoupledSend(&CLargeDataReceiver::DecoupledSendThread, this)
CLargeDataReceiver(bool bEnableEvent = false) : m_bEnableEvent(bEnableEvent)
{}
/**
@@ -37,6 +37,8 @@ public:
~CLargeDataReceiver()
{
m_bShutdown = true;
std::unique_lock<std::mutex> lock(m_mtxData);
lock.unlock();
if (m_threadDecoupledSend.joinable())
m_threadDecoupledSend.join();
}
@@ -73,6 +75,10 @@ public:
for (const sdv::pointer<uint8_t>& rptrData : seqData)
m_queueDataCopy.push(rptrData);
// Start the processing thread if needed
if (!m_threadDecoupledSend.joinable())
m_threadDecoupledSend = std::thread(&CLargeDataReceiver::DecoupledSendThread, this);
// Store data into the queue for sending.
m_queueDecoupledSend.push(std::move(seqData));
m_cvDecoupledSend.notify_all();
@@ -87,7 +93,7 @@ public:
/**
* @brief Wait until the caller hasn't sent anything anymore for 1 second.
*/
void WaitForNoActivity(sdv::IInterfaceAccess* pSender, size_t nCount = 1, uint32_t uiTimeoutMs = 20000)
void WaitForNoActivity(sdv::IInterfaceAccess* pSender, [[maybe_unused]] size_t nCount = 1, uint32_t uiTimeoutMs = 1000)
{
CConnection* pConnection = dynamic_cast<CConnection*>(pSender);
double dTimeout = static_cast<double>(uiTimeoutMs) / 1000.0;
@@ -237,16 +243,16 @@ private:
sdv::ipc::IDataSend* m_pSend = nullptr; ///< Send interface to implement repeating function.
mutable std::mutex m_mtxData; ///< Protect data access.
std::queue<sdv::pointer<uint8_t>> m_queueDataCopy; ///< Copy of the data.
sdv::ipc::EConnectStatus m_eStatus = sdv::ipc::EConnectStatus::uninitialized; ///< Current received status.
std::atomic<sdv::ipc::EConnectStatus> m_eStatus = sdv::ipc::EConnectStatus::uninitialized; ///< Current received status.
bool m_bConnectError = false; ///< Connection error ocurred.
bool m_bCommError = false; ///< Communication error occurred.
bool m_bForcedDisconnect = false; ///< Force disconnect.
size_t m_nCount = 0; ///< Receive counter.
std::atomic_size_t m_nCount = 0; ///< Receive counter.
std::condition_variable m_cvReceived; ///< Receive event.
std::thread m_threadDecoupledSend; ///< Decoupled send thread.
std::queue<sdv::sequence<sdv::pointer<uint8_t>>> m_queueDecoupledSend; ///< Data queue for sending.
std::condition_variable m_cvDecoupledSend; ///< Trigger decoupled sending.
bool m_bShutdown = false; ///< Shutdown send thread.
std::atomic_bool m_bShutdown = false; ///< Shutdown send thread.
};
TEST(SharedMemChannelService, CommunicateOneLargeBlock)
@@ -341,6 +347,7 @@ Size = 1024000
EXPECT_NO_THROW(ptrServerConnection.Clear());
EXPECT_NO_THROW(mgntServer.Shutdown());
EXPECT_NO_THROW(mgntClient.Shutdown());
EXPECT_EQ(mgntServer.GetStatus(), sdv::EObjectStatus::destruction_pending);
@@ -371,6 +378,7 @@ Size = 1024000
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
sdv::TObjectPtr ptrServerConnection(sChannelEndpoint.pConnection);
sdv::TObjectPtr ptrClientConnection = mgntClient.Access(sChannelEndpoint.ssConnectString);
EXPECT_TRUE(ptrServerConnection);
@@ -439,7 +447,7 @@ Size = 1024000
}
EXPECT_EQ(nCnt, 30);
nCnt = 0;
nCnt = 0;
bCorrect = true;
EXPECT_EQ(receiverClient.GetReceiveCount(), 30u);
while (bCorrect)
@@ -467,6 +475,7 @@ Size = 1024000
EXPECT_NO_THROW(ptrServerConnection.Clear());
EXPECT_NO_THROW(mgntServer.Shutdown());
EXPECT_NO_THROW(mgntClient.Shutdown());
EXPECT_EQ(mgntServer.GetStatus(), sdv::EObjectStatus::destruction_pending);
@@ -582,6 +591,7 @@ Size = 1024000
EXPECT_NO_THROW(ptrServerConnection.Clear());
EXPECT_NO_THROW(mgntServer.Shutdown());
EXPECT_NO_THROW(mgntClient.Shutdown());
EXPECT_EQ(mgntServer.GetStatus(), sdv::EObjectStatus::destruction_pending);
@@ -650,6 +660,7 @@ Size = 1024000
// Try send; should succeed, since connected
EXPECT_TRUE(pServerSend->SendData(seqPattern));
receiverServer.WaitForNoActivity(ptrServerConnection);
EXPECT_EQ(receiverServer.GetReceiveCount(), 1u);
auto ptrServerPattern = receiverServer.GetData();
ASSERT_EQ(ptrServerPattern.size(), nCount * sizeof(uint32_t));
pData = reinterpret_cast<uint32_t*>(ptrServerPattern.get());
@@ -730,13 +741,15 @@ Size = 1024000
TRACE("Connection estabished...");
appcontrol.SetRunningMode();
EXPECT_EQ(receiverServer.GetReceiveCount(), 0u);
// Try send; should succeed, since connected
for (size_t nCnt = 0; nCnt < 30; nCnt++)
{
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(pServerSend->SendData(seqPattern), true, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(pServerSend->SendData(seqPattern), true, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(pServerSend->SendData(seqPattern), true, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(pServerSend->SendData(seqPattern), true, sdv_test::WARNING_ENABLED);
}
receiverServer.WaitForNoActivity(ptrServerConnection, 30);
@@ -744,9 +757,9 @@ Size = 1024000
size_t nCnt = 0;
bool bCorrect = true;
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(receiverServer.GetReceiveCount(), 30u, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(receiverServer.GetReceiveCount(), 30u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(receiverServer.GetReceiveCount(), 30u, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(receiverServer.GetReceiveCount(), 30u, sdv_test::WARNING_ENABLED);
while (bCorrect)
{
auto ptrServerPattern = receiverServer.GetData();
@@ -765,9 +778,9 @@ Size = 1024000
}
}
if(SDV_IS_RUNNING_TESTS_WITH_CMAKE_BUILD)
SDV_TIMING_EXPECT_EQ(nCnt, 30, sdv::TEST::WARNING_REDUCED);
SDV_EXPECT_EQ_WARN(nCnt, 30u, sdv_test::WARNING_REDUCED);
else
SDV_TIMING_EXPECT_EQ(nCnt, 30, sdv::TEST::WARNING_ENABLED);
SDV_EXPECT_EQ_WARN(nCnt, 30u, sdv_test::WARNING_ENABLED);
appcontrol.SetConfigMode();

View File

@@ -1,5 +1,6 @@
#include "../../../../global/process_watchdog.h"
#include "../include/can_com_test_helper.h"
#include <atomic>
#ifdef __GNUC__
#pragma GCC diagnostic push
@@ -201,7 +202,7 @@ void ShutDownCanComObject(CTestCANSocket& canComObj, MockCANReceiver& mockRcv)
ASSERT_NO_THROW(canComObj.Shutdown());
}
void SendThread(bool& stop, CTestCANSocket& canComObj, sdv::can::SMessage& testData)
void SendThread(std::atomic_bool& stop, CTestCANSocket& canComObj, sdv::can::SMessage& testData)
{
while (!stop)
{
@@ -465,7 +466,7 @@ TEST_F(CANSocketTest, StressTestWith3Objects)
auto testData2 = testHelper.CreateTestData(20, 7); // Testdata to send to vcan3, size = 7
auto testData3 = testHelper.CreateTestData(30, 8); // Testdata to send to vcan1, size = 8
bool stopSendThread = false;
std::atomic_bool stopSendThread = false;
std::cout << "Start thread sending messages..." << std::endl;
std::thread thSendThread1(SendThread, std::ref(stopSendThread), std::ref(canComObj1), std::ref(testData1));
std::this_thread::sleep_for(std::chrono::milliseconds(500));

View File

@@ -4,7 +4,10 @@ add_executable(UnitTest_TOMLParser
"lexer_tests.cpp"
"parser_tests.cpp"
"main.cpp"
"generate_toml_tests.cpp")
"generate_toml_tests.cpp"
"content_modifications.cpp"
"statement_boundary_detection.cpp"
"miscellaneous_tests.cpp")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_link_libraries(UnitTest_TOMLParser GTest::GTest ${CMAKE_THREAD_LIBS_INIT})
if (WIN32)

View File

@@ -183,46 +183,108 @@ TEST(UTF8_CharacterReader, InputValidation)
for (const auto& inv : GetInvalidUTF8Bytes())
{
std::string ssUTF8InputInvalid = "Invalid input: " + inv + " test";
EXPECT_THROW(CCharacterReaderUTF8 reader(ssUTF8InputInvalid), sdv::toml::XTOMLParseException);
EXPECT_THROW(toml_parser::CCharacterReaderUTF8 reader(ssUTF8InputInvalid), sdv::toml::XTOMLParseException);
}
// Test for a variety of invalid sequences
for (const auto& inv : GetInvalidUTF8Sequences())
{
std::string UTF8InputInvalid = "Invalid input: " + inv + "test";
EXPECT_THROW(CCharacterReaderUTF8 reader(UTF8InputInvalid), sdv::toml::XTOMLParseException);
EXPECT_THROW(toml_parser::CCharacterReaderUTF8 reader(UTF8InputInvalid), sdv::toml::XTOMLParseException);
}
// Test for a sample of ASCII, 2-Byte-, 3-Byte- and 4-Byte-Sequences that they will be accepted as valid input
EXPECT_NO_THROW(CCharacterReaderUTF8 reader(UTF8InputValid));
EXPECT_NO_THROW(toml_parser::CCharacterReaderUTF8 reader(UTF8InputValid));
EXPECT_NO_THROW(CCharacterReaderUTF8 reader(TestInputUTF8));
EXPECT_NO_THROW(toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8));
}
TEST(UTF8_CharacterReader, PeekAndConsume_ReadCharacters)
{
// Peek() and Consume() read the next character
// Peek() and Consume() read the next character
{
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
for (int i = 0; i < 12; ++i)
{
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Peek());
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Consume());
}
}
// Read all characters and the an empty string must be read
{
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
std::size_t nSize = TestInputUTF8.size();
size_t nCnt = 0;
while (nCnt < nSize)
{
EXPECT_FALSE(reader.Peek().empty());
std::string ssCharacters = reader.Consume();
size_t nCharCnt = ssCharacters.size();
EXPECT_NE(nCharCnt, 0);
if (!nCharCnt) break;
nCnt += nCharCnt;
}
EXPECT_EQ(nCnt, nSize);
EXPECT_TRUE(reader.Peek().empty());
EXPECT_TRUE(reader.Consume().empty());
}
}
TEST(UTF8_CharacterReader, PeekAndConsume_ReadCharactersSkip)
{
// Peek(n) and Consume(n) read with skip of every two characters
{
CCharacterReaderUTF8 reader(TestInputUTF8);
for (int i = 0; i < 12; ++i)
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
for (int i = 1; i < 12; i += 2)
{
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Peek());
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Consume());
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Peek(1));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Consume(1));
}
}
// Peek(n) and Consume(n) read the next n-th character
{
for (int i = 0; i < 12; ++i)
{
CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Peek(i + 1));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i], reader.Consume(i + 1));
}
}
// PeekUntil(a) and ConsumeUntil(a) read until a given character
// Peek(0)/Consume(0) will return the first character in the string and Peek(n)/Consume(n) return empty string if they read out
// of bounds
{
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Peek(0));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Consume(0));
std::size_t biggerIndex = TestInputUTF8.size(); // Assure this is bigger than the number of characters in TestInputUTF8
EXPECT_EQ("", reader.Peek(biggerIndex));
EXPECT_EQ("", reader.Consume(biggerIndex));
}
}
TEST(UTF8_CharacterReader, PeekAndConsume_ReadCharactersMulti)
{
// Peek() and Consume() read the next character
{
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
for (int i = 0; i < 12; i += 2)
{
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i] + TestInputUTF8_CharacterIndexMap[i + 1], reader.Peek(0, 2));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i] + TestInputUTF8_CharacterIndexMap[i + 1], reader.Consume(0, 2));
}
}
// Peek() and Consume() skip one and then read two read the next character
{
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
for (int i = 0; i < 12; i += 3)
{
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i + 1] + TestInputUTF8_CharacterIndexMap[i + 2], reader.Peek(1, 2));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[i + 1] + TestInputUTF8_CharacterIndexMap[i + 2], reader.Consume(1, 2));
}
}
}
TEST(UTF8_CharacterReader, PeekAndConsume_ReadCharactersUntil)
{
// PeekUntil(a) and ConsumeUntil(a) read until a given character
{
std::size_t byteIndex = 0;
for (int i = 0; i < 12; ++i)
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
std::vector<std::string> Codepoints;
Codepoints.push_back(TestInputUTF8_CharacterIndexMap[i]);
std::string wantedSubstring = TestInputUTF8.substr(0, byteIndex);
@@ -233,28 +295,19 @@ TEST(UTF8_CharacterReader, PeekAndConsume_ReadCharacters)
}
// PeekUntil(a) and ConsumeUntil(a) read only until EOF if they don't find a matching character
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
std::string notInTestString = "g";
EXPECT_EQ(std::string::npos, TestInputUTF8.find(notInTestString));
EXPECT_EQ(TestInputUTF8, reader.PeekUntil({notInTestString}));
EXPECT_EQ(TestInputUTF8, reader.ConsumeUntil({notInTestString}));
}
// Peek(0)/Peek(n) and Consume(0)/Consume(n) return empty string if they would read out of bounds
{
CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ("", reader.Peek(0));
EXPECT_EQ("", reader.Consume(0));
std::size_t biggerIndex = TestInputUTF8.size(); // Assure this is bigger than the number of characters in TestInputUTF8
EXPECT_EQ("", reader.Peek(biggerIndex));
EXPECT_EQ("", reader.Consume(biggerIndex));
}
}
TEST(UTF8_CharacterReader, Peek_NoAdvance)
{
ASSERT_NE(TestInputUTF8_CharacterIndexMap[0], TestInputUTF8_CharacterIndexMap[1]);
ASSERT_NE(TestInputUTF8_CharacterIndexMap[1], TestInputUTF8_CharacterIndexMap[2]);
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
// Peek() does not advance the read location
{
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Peek());
@@ -263,10 +316,10 @@ TEST(UTF8_CharacterReader, Peek_NoAdvance)
}
// Peek(n) does not advance the read location
{
EXPECT_EQ("", reader.Peek(0));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Peek(1));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[1], reader.Peek(2));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[2], reader.Peek(3));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Peek(0)); // Read pos 0
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[1], reader.Peek(1)); // Read pos 1
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[2], reader.Peek(2)); // Read pos 2
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[3], reader.Peek(3)); // Read pos 3
}
// PeekUntil(a) does not advance the read location
{
@@ -286,22 +339,22 @@ TEST(UTF8_CharacterReader, Consume_Advance)
ASSERT_NE(TestInputUTF8_CharacterIndexMap[3], TestInputUTF8_CharacterIndexMap[4]);
// Consume() does advance the read location to the next character
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Consume());
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[1], reader.Consume());
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[2], reader.Consume());
}
// Consume(n) does advance the read location to the next n-th character
{
CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ("", reader.Consume(0));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Consume(1));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[2], reader.Consume(2));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[5], reader.Consume(3));
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.Consume(0)); // Read pos 0; advance to pos 1
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[2], reader.Consume(1)); // Read pos 2; advance to pos 3
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[5], reader.Consume(2)); // Read pos 5; advance to pos 6
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[9], reader.Consume(3)); // Read pos 9; advance to pos 10
}
// ConsumeUntil(a) does advance the read location
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0], reader.ConsumeUntil({TestInputUTF8_CharacterIndexMap[1]}));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[1], reader.ConsumeUntil({TestInputUTF8_CharacterIndexMap[2]}));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[2], reader.ConsumeUntil({TestInputUTF8_CharacterIndexMap[3]}));
@@ -312,7 +365,7 @@ TEST(UTF8_CharacterReader, PeekUntilConsumeUntil_FindAny)
{
// PeekUntil(a) works for a collection of characters
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0],
reader.PeekUntil({TestInputUTF8_CharacterIndexMap[2], TestInputUTF8_CharacterIndexMap[1]}));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0] + TestInputUTF8_CharacterIndexMap[1] + TestInputUTF8_CharacterIndexMap[2],
@@ -320,7 +373,7 @@ TEST(UTF8_CharacterReader, PeekUntilConsumeUntil_FindAny)
}
// ConsumeUntil(a) works for a collection of characters
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[0],
reader.ConsumeUntil({TestInputUTF8_CharacterIndexMap[2], TestInputUTF8_CharacterIndexMap[1]}));
EXPECT_EQ(TestInputUTF8_CharacterIndexMap[1] + TestInputUTF8_CharacterIndexMap[2],
@@ -331,7 +384,7 @@ TEST(UTF8_CharacterReader, PeekUntilConsumeUntil_FindAny)
TEST(UTF8_CharacterReader, PeekAndConsume_SameOutput)
{
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
for (int i = 0; i < 12; ++i)
{
std::string p = reader.Peek();
@@ -342,7 +395,7 @@ TEST(UTF8_CharacterReader, PeekAndConsume_SameOutput)
{
for (int i = 1; i < 13; ++i)
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
std::string p = reader.Peek(i);
std::string c = reader.Consume(i);
EXPECT_EQ(p, c);
@@ -351,7 +404,7 @@ TEST(UTF8_CharacterReader, PeekAndConsume_SameOutput)
{
for (int i = 1; i < 13; ++i)
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
std::vector<std::string> CodePoints;
CodePoints.push_back(reader.Peek(i));
std::string p = reader.PeekUntil(CodePoints);
@@ -365,7 +418,7 @@ TEST(UTF8_CharacterReader, EOFTests)
{
// Check all calls that are not to trigger EOF
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_FALSE(reader.IsEOF());
reader.Peek();
reader.Peek(1);
@@ -379,20 +432,20 @@ TEST(UTF8_CharacterReader, EOFTests)
}
// Check that reading the last character with Consume(n) triggers EOF
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_FALSE(reader.IsEOF());
reader.Consume(TestInputUTF8_CharacterIndexMap.size()); // Last Character
EXPECT_TRUE(reader.IsEOF());
}
// Check that reading out of bounds with Consume(n) triggers EOF
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_FALSE(reader.IsEOF());
reader.Consume(TestInputUTF8_CharacterIndexMap.size() + 1); // Out of bounds
EXPECT_TRUE(reader.IsEOF());
}
{
CCharacterReaderUTF8 reader(TestInputUTF8);
toml_parser::CCharacterReaderUTF8 reader(TestInputUTF8);
EXPECT_FALSE(reader.IsEOF());
reader.ConsumeUntil({TestInputUTF8_CharacterIndexMap[11]}); // Second last character
EXPECT_FALSE(reader.IsEOF());
@@ -400,7 +453,7 @@ TEST(UTF8_CharacterReader, EOFTests)
EXPECT_TRUE(reader.IsEOF());
}
{
CCharacterReaderUTF8 reader("");
toml_parser::CCharacterReaderUTF8 reader("");
EXPECT_TRUE(reader.IsEOF());
}
}

View File

@@ -0,0 +1,449 @@
#include <gtest/gtest.h>
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
// Delete nodes (for all types of nodes, between all types of nodes)
// - beginning
// - middle
// - end
// - Using deleted node info -- error
// - Last node (empty after that)
// - Smart delete (comments/whitespace around)
// Insert nodes (for all types of nodes, between all types of nodes)
// Before and after:
// - beginning
// - middle
// - end
// - Being the first item in a TOML file
// - Inserted and straight away deleted
// - Inserted with false/deleted reference --error
// - Inserted values before (okay) and behind (error) tables
// - Inserted duplicate value -- error
// - Smart insert (comments/whitespace around)
// Shift nodes (for all types of nodes, between root, tables and arrays)
/*
* @brief Delete a key from the TOML string.
* @param[in] rssTOMLInput Reference to the TOML string.
* @param[in] rssKey Reference to the key to delete.
* @param[in] rssOuput Reference to the expected ouput.
* @return Returns 'true' on success.
*/
bool TestDelete(const std::string& rssTOMLInput, const std::string& rssKey, const std::string& rssOutput)
{
toml_parser::CParser parser;
bool bRes = true;
EXPECT_NO_THROW(bRes = parser.Process(rssTOMLInput));
EXPECT_TRUE(bRes);
if (!bRes) return bRes;
auto ptrNode = parser.Root().Direct(rssKey);
EXPECT_TRUE(ptrNode);
if (!ptrNode) return false;
EXPECT_TRUE(bRes = ptrNode->DeleteNode());
if (!bRes) return bRes;
std::string ssTOML = parser.GenerateTOML();
EXPECT_EQ(ssTOML, rssOutput);
if (ssTOML != rssOutput) return false;
return true;
};
TEST(TOMLContentModifications, DISABLED_DeleteValues)
{
// Delete a key from the begin
EXPECT_TRUE(TestDelete(R"toml(
key = 10 # value key
bare_key = "value" # value bare_key
bare-key = false # value bare-key
)toml",
"key",
R"toml(
bare_key = "value" # value bare_key
bare-key = false # value bare-key
)toml"));
// Delete a key from the middle
EXPECT_TRUE(TestDelete(R"toml(
key = 10 # value key
bare_key = "value" # value bare_key
bare-key = false # value bare-key
)toml",
"bare_key",
R"toml(
key = 10 # value key
bare-key = false # value bare-key
)toml"));
// Delete a key from the end
EXPECT_TRUE(TestDelete(R"toml(
key = 10 # value key
bare_key = "value" # value bare_key
bare-key = false # value bare-key
)toml",
"bare-key",
R"toml(
key = 10 # value key
bare_key = "value" # value bare_key
)toml"));
}
TEST(TOMLContentModifications, DISABLED_DeleteInlineTableValues)
{
// Delete key from the inline table
EXPECT_TRUE(TestDelete(R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml",
"1234.y",
R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, z = 2, str = "abc"}
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml",
"1234.x",
R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {y = 1, z = 2, str = "abc"}
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml",
"1234.str",
R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2}
)toml"));
// Delete key from the inline sub-table
EXPECT_TRUE(TestDelete(R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, b=2, c=3}}
)toml",
"1234.tbl.b",
R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, c=3}}
)toml"));
// Delete table
EXPECT_TRUE(TestDelete(R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, b=2, c=3}}
)toml",
"1234.tbl",
R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, b=2, c=3}}
)toml",
"1234",
R"toml(
key = 10
bare_key = "value"
bare-key = false
)toml"));
}
TEST(TOMLContentModifications, DISABLED_DeleteTableValues)
{
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
)toml",
"my_table.key",
R"toml(
[my_table]
bare_key = "value"
bare-key = false
)toml"));
// Delete a key from the middle
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
)toml",
"my_table.bare_key",
R"toml(
[my_table]
key = 10
bare-key = false
)toml"));
// Delete a key from the end
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
)toml",
"my_table.bare-key",
R"toml(
[my_table]
key = 10
bare_key = "value"
)toml"));
// Delete key from the inline table in a table
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml",
"my_table.1234.y",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, z = 2, str = "abc"}
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml",
"my_table.1234.x",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {y = 1, z = 2, str = "abc"}
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml",
"my_table.1234.str",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2}
)toml"));
// Delete key from the inline sub-table
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, b=2, c=3}}
)toml",
"my_table.1234.tbl.b",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, c=3}}
)toml"));
// Delete table
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, b=2, c=3}}
)toml",
"my_table.1234.tbl",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc"}
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
1234 = {x = 0, y = 1, z = 2, str = "abc", tbl={a =1, b=2, c=3}}
)toml",
"my_table.1234",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
)toml"));
// Delete key from the child-table
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
str = "abc"
)toml",
"my_table.1234.y",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
z = 2
str = "abc"
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
str = "abc"
)toml",
"my_table.1234.x",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
y = 1
z = 2
str = "abc"
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
str = "abc"
)toml",
"my_table.1234.str",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
)toml"));
// Delete table
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
str = "abc"
[my_table.1234.tbl]
a =1
b=2
c=3
)toml",
"my_table.1234.tbl",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
str = "abc"
)toml"));
EXPECT_TRUE(TestDelete(R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
[my_table.1234]
x = 0
y = 1
z = 2
str = "abc"
[my_table.1234.tbl]
a =1
b=2
c=3
)toml",
"my_table.1234",
R"toml(
[my_table]
key = 10
bare_key = "value"
bare-key = false
)toml"));
}
TEST(TOMLContentModifications, DISABLED_DeleteArrayValues)
{
EXPECT_TRUE(TestDelete(R"toml(
key = [10, 20, 30]
bare_key = ["value1", "value2", 3030]
bare-key = [{a = false, b = true}, 2020]
)toml",
"key[1]",
R"toml(
key = [10, 30]
bare_key = ["value1", "value2", 3030]
bare-key = [{a = false, b = true}, 2020]
)toml"));
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,10 @@
#include "../../../global/process_watchdog.h"
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml.cpp"
#include "../../../sdv_services/core/toml_parser/lexer_toml_token.cpp"
#include "../../../sdv_services/core/toml_parser/parser_toml.cpp"
#include "../../../sdv_services/core/toml_parser/parser_node_toml.cpp"
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain(int argc, wchar_t* argv[])

View File

@@ -0,0 +1,981 @@
#include <functional>
#include <gtest/gtest.h>
#include <limits>
#include "../../../sdv_services/core/toml_parser/exception.h"
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
TEST(TOMLMiscellaneousTests, Hex2Dec)
{
// No string
std::string ssEmpty;
EXPECT_THROW(toml_parser::HexadecimalToDecimal(ssEmpty), sdv::toml::XTOMLParseException);
// Invalid string
std::string ssNoNumber = "xyz";
EXPECT_THROW(toml_parser::HexadecimalToDecimal(ssNoNumber), sdv::toml::XTOMLParseException);
// Parse value
EXPECT_EQ(toml_parser::HexadecimalToDecimal("10"), 16u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("a"), 10u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("AbCd1234"), 2882343476u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("0"), 0u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("7fffffff"), 2147483647u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("80000000"), 2147483648u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("FFFFFFFF"), 4294967295u);
// Parse up to max value
EXPECT_EQ(toml_parser::HexadecimalToDecimal("0FFFFFFFF"), 4294967295u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("FFFFFFFFA"), 4294967295u);
// Parse until unknown character
EXPECT_EQ(toml_parser::HexadecimalToDecimal("0xyz"), 0u);
EXPECT_EQ(toml_parser::HexadecimalToDecimal("10xyz"), 16u);
}
TEST(TOMLMiscellaneousTests, Dec2Dec)
{
// No string
std::string ssEmpty;
EXPECT_THROW(toml_parser::DecimalToDecimal(ssEmpty), sdv::toml::XTOMLParseException);
// Invalid string
std::string ssNoNumber = "f123";
EXPECT_THROW(toml_parser::DecimalToDecimal(ssNoNumber), sdv::toml::XTOMLParseException);
// Parse value
EXPECT_EQ(toml_parser::DecimalToDecimal("16"), 16u);
EXPECT_EQ(toml_parser::DecimalToDecimal("10"), 10u);
EXPECT_EQ(toml_parser::DecimalToDecimal("2882343476"), 2882343476u);
EXPECT_EQ(toml_parser::DecimalToDecimal("0"), 0u);
EXPECT_EQ(toml_parser::DecimalToDecimal("2147483647"), 2147483647u);
EXPECT_EQ(toml_parser::DecimalToDecimal("2147483648"), 2147483648u);
EXPECT_EQ(toml_parser::DecimalToDecimal("4294967295"), 4294967295u);
// Parse up to max value
EXPECT_EQ(toml_parser::DecimalToDecimal("04294967295"), 4294967295u);
EXPECT_EQ(toml_parser::DecimalToDecimal("42949672950"), 4294967295u);
// Parse until unknown character
EXPECT_EQ(toml_parser::DecimalToDecimal("0xyz"), 0u);
EXPECT_EQ(toml_parser::DecimalToDecimal("10xyz"), 10u);
}
TEST(TOMLMiscellaneousTests, Oct2Dec)
{
// No string
std::string ssEmpty;
EXPECT_THROW(toml_parser::OctalToDecimal(ssEmpty), sdv::toml::XTOMLParseException);
// Invalid string
std::string ssNoNumber = "890";
EXPECT_THROW(toml_parser::OctalToDecimal(ssNoNumber), sdv::toml::XTOMLParseException);
// Parse value
EXPECT_EQ(toml_parser::OctalToDecimal("20"), 16u);
EXPECT_EQ(toml_parser::OctalToDecimal("12"), 10u);
EXPECT_EQ(toml_parser::OctalToDecimal("25363211064"), 2882343476u);
EXPECT_EQ(toml_parser::OctalToDecimal("0"), 0u);
EXPECT_EQ(toml_parser::OctalToDecimal("17777777777"), 2147483647u);
EXPECT_EQ(toml_parser::OctalToDecimal("20000000000"), 2147483648u);
EXPECT_EQ(toml_parser::OctalToDecimal("37777777777"), 4294967295u);
// Parse up to max value
EXPECT_EQ(toml_parser::OctalToDecimal("037777777777"), 4294967295u);
EXPECT_EQ(toml_parser::OctalToDecimal("377777777770"), 4294967295u);
// Parse until unknown character
EXPECT_EQ(toml_parser::OctalToDecimal("0xyz"), 0u);
EXPECT_EQ(toml_parser::OctalToDecimal("12xyz"), 10u);
}
TEST(TOMLMiscellaneousTests, Bin2Dec)
{
// No string
std::string ssEmpty;
EXPECT_THROW(toml_parser::BinaryToDecimal(ssEmpty), sdv::toml::XTOMLParseException);
// Invalid string
std::string ssNoNumber = "234";
EXPECT_THROW(toml_parser::BinaryToDecimal(ssNoNumber), sdv::toml::XTOMLParseException);
// Parse value
EXPECT_EQ(toml_parser::BinaryToDecimal("10000"), 16u);
EXPECT_EQ(toml_parser::BinaryToDecimal("1010"), 10u);
EXPECT_EQ(toml_parser::BinaryToDecimal("10101011110011010001001000110100"), 2882343476u);
EXPECT_EQ(toml_parser::BinaryToDecimal("0"), 0u);
EXPECT_EQ(toml_parser::BinaryToDecimal("1111111111111111111111111111111"), 2147483647u);
EXPECT_EQ(toml_parser::BinaryToDecimal("10000000000000000000000000000000"), 2147483648u);
EXPECT_EQ(toml_parser::BinaryToDecimal("11111111111111111111111111111111"), 4294967295u);
// Parse up to max value
EXPECT_EQ(toml_parser::BinaryToDecimal("011111111111111111111111111111111"), 4294967295u);
EXPECT_EQ(toml_parser::BinaryToDecimal("111111111111111111111111111111110"), 4294967295u);
// Parse until unknown character
EXPECT_EQ(toml_parser::BinaryToDecimal("0xyz"), 0u);
EXPECT_EQ(toml_parser::BinaryToDecimal("1010yz"), 10u);
}
TEST(TOMLMiscellaneousTests, UnicodeCharacter)
{
// No string
std::string ssEmpty;
EXPECT_THROW(toml_parser::EscapedUnicodeCharacterToUTF8(ssEmpty), sdv::toml::XTOMLParseException);
// Invalid string
std::string ssNoNumber = "xyz";
EXPECT_THROW(toml_parser::EscapedUnicodeCharacterToUTF8(ssNoNumber), sdv::toml::XTOMLParseException);
// Conversion
EXPECT_EQ(toml_parser::EscapedUnicodeCharacterToUTF8("042f"), u8"\u042f");
EXPECT_EQ(toml_parser::EscapedUnicodeCharacterToUTF8("0000042f"), u8"\U0000042f");
EXPECT_EQ(toml_parser::EscapedUnicodeCharacterToUTF8("0001F600"), u8"\U0001F600");
}
TEST(TOMLMiscellaneousTests, SplitKeyStringEmpty)
{
std::string ssKeyEmpty;
auto prSplittedKey = toml_parser::SplitNodeKey(ssKeyEmpty);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitKeyFirstPartOnly)
{
std::string ssKey = "abc";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "_abc";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "_abc");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "-abc";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "-abc");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "1234";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1234");
EXPECT_TRUE(prSplittedKey.second.empty());
// Although invalid bare key
ssKey = "abc/";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid bare key
ssKey = "abc\\";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid bare key
ssKey = "abc def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitStandardBareKey)
{
std::string ssKey = "abc.def";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "def");
ssKey = "_abc._def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "_abc");
EXPECT_EQ(prSplittedKey.second, "_def");
ssKey = "-abc.-def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "-abc");
EXPECT_EQ(prSplittedKey.second, "-def");
ssKey = "1234.5678";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1234");
EXPECT_EQ(prSplittedKey.second, "5678");
ssKey = "1234.5678.90";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1234");
EXPECT_EQ(prSplittedKey.second, "5678.90");
// Invalid bare key
ssKey = "/abc./def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid bare key
ssKey = "\\abc.\\def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitBareKeyWithSpace)
{
std::string ssKey = " abc.def";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "def");
ssKey = "abc . def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, " def");
ssKey = "\tabc.\tdef";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "\tdef");
ssKey = "abc\n.\ndef";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "\ndef");
// Invalid key
ssKey = "abc def . ghi jkl";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitLiteralKey)
{
std::string ssKey = "'abc'";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "'abc.def'";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc.def");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "'abc'.'def'";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "'def'");
ssKey = "'\"cool\" key'.'very \"cool\" key'";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "\"cool\" key");
EXPECT_EQ(prSplittedKey.second, "'very \"cool\" key'");
ssKey = "'abc/def'";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc/def");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "'abc\\ndef'";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\\ndef");
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "'abc.def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "cool' 'key";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitQuotedKey)
{
std::string ssKey = "\"abc\"";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc.def\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc.def");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\".\"def\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "\"def\"");
ssKey = "\"'cool' key\".\"very 'cool' key\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "'cool' key");
EXPECT_EQ(prSplittedKey.second, "\"very 'cool' key\"");
ssKey = "\"abc/def\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc/def");
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "\"abc.def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "cool\" \"key";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitEscapedQuotedKey)
{
std::string ssKey = "\"abc\\bdef\"";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\bdef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\tdef\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\tdef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\ndef\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\ndef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\fdef\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\fdef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\rdef\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\rdef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\\"def\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\"def");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\\\def\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc\\def");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\u042fdef\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, u8"abc\u042fdef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\U0000042fdef\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, u8"abc\U0000042fdef");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "\"abc\\U0001F600def\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, u8"abc\U0001F600def");
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "\"abc\\uxyz\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "\"abc\\Uxyz\"";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SplitTableKey)
{
std::string ssKey = "abc.def";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "def");
ssKey = "abc.def.ghi";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "def.ghi");
ssKey = ".abc.def.ghi";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "def.ghi");
}
TEST(TOMLMiscellaneousTests, SplitArrayKey)
{
std::string ssKey = "abc[1]";
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "[1]");
ssKey = "abc[1][2]";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "[1][2]");
ssKey = "[1]";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1");
EXPECT_TRUE(prSplittedKey.second.empty());
ssKey = "[1][2]";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1");
EXPECT_EQ(prSplittedKey.second, "[2]");
ssKey = "[1].abc";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1");
EXPECT_EQ(prSplittedKey.second, "abc");
ssKey = ".[1].abc";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "1");
EXPECT_EQ(prSplittedKey.second, "abc");
ssKey = "abc [ 1 ] [ 2 ] [ 3 ] . def";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_EQ(prSplittedKey.first, "abc");
EXPECT_EQ(prSplittedKey.second, "[ 1 ] [ 2 ] [ 3 ] . def");
// Invalid key
ssKey = "[1]abc";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "[1.2][2]";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "[1";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
// Invalid key
ssKey = "[1[2]]";
prSplittedKey = toml_parser::SplitNodeKey(ssKey);
EXPECT_TRUE(prSplittedKey.first.empty());
EXPECT_TRUE(prSplittedKey.second.empty());
}
TEST(TOMLMiscellaneousTests, SmartQuoteBareKeys)
{
EXPECT_EQ(toml_parser::QuoteText("abc", toml_parser::EQuoteRequest::smart_key), "abc");
EXPECT_EQ(toml_parser::QuoteText("123", toml_parser::EQuoteRequest::smart_key), "123");
EXPECT_EQ(toml_parser::QuoteText("ABC", toml_parser::EQuoteRequest::smart_key), "ABC");
EXPECT_EQ(toml_parser::QuoteText("abc_def", toml_parser::EQuoteRequest::smart_key), "abc_def");
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::smart_key), "ABC-DEF");
}
TEST(TOMLMiscellaneousTests, SmartQuoteSpecialCharsKeys)
{
EXPECT_EQ(toml_parser::QuoteText("", toml_parser::EQuoteRequest::smart_key), "\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc def", toml_parser::EQuoteRequest::smart_key), "\"abc def\"");
EXPECT_EQ(toml_parser::QuoteText(".abc", toml_parser::EQuoteRequest::smart_key), "\".abc\"");
#ifndef __GNUC__
EXPECT_EQ(toml_parser::QuoteText(u8"<EFBFBD>", toml_parser::EQuoteRequest::smart_key),
"\"\\u00B5\""); // Only supported on Windows with MS compiler
#endif
EXPECT_EQ(toml_parser::QuoteText(u8"\u00a1", toml_parser::EQuoteRequest::smart_key), "\"\\u00A1\"");
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::smart_key), "\"abc/\"");
}
TEST(TOMLMiscellaneousTests, SmartQuoteEscapeCharsKeys)
{
EXPECT_EQ(toml_parser::QuoteText("abc\tdef", toml_parser::EQuoteRequest::smart_key), "\"abc\\tdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\\def", toml_parser::EQuoteRequest::smart_key), "\"abc\\\\def\"");
EXPECT_EQ(toml_parser::QuoteText("\"abc\"", toml_parser::EQuoteRequest::smart_key), "\"\\\"abc\\\"\"");
EXPECT_EQ(toml_parser::QuoteText("'abc'", toml_parser::EQuoteRequest::smart_key), "\"'abc'\"");
EXPECT_EQ(toml_parser::QuoteText("abc\bdef", toml_parser::EQuoteRequest::smart_key), "\"abc\\bdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\ndef", toml_parser::EQuoteRequest::smart_key), "\"abc\\ndef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\fdef", toml_parser::EQuoteRequest::smart_key), "\"abc\\fdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::smart_key), "\"abc\\rdef\"");
}
TEST(TOMLMiscellaneousTests, SmartQuoteControlCharsKeys)
{
EXPECT_EQ(toml_parser::QuoteText(std::string(1, '\0'), toml_parser::EQuoteRequest::smart_key), "\"\\u0000\"");
EXPECT_EQ(toml_parser::QuoteText("\u0001", toml_parser::EQuoteRequest::smart_key), "\"\\u0001\"");
EXPECT_EQ(toml_parser::QuoteText("\u0002", toml_parser::EQuoteRequest::smart_key), "\"\\u0002\"");
EXPECT_EQ(toml_parser::QuoteText("\u0003", toml_parser::EQuoteRequest::smart_key), "\"\\u0003\"");
EXPECT_EQ(toml_parser::QuoteText("\u0004", toml_parser::EQuoteRequest::smart_key), "\"\\u0004\"");
EXPECT_EQ(toml_parser::QuoteText("\u0005", toml_parser::EQuoteRequest::smart_key), "\"\\u0005\"");
EXPECT_EQ(toml_parser::QuoteText("\u0006", toml_parser::EQuoteRequest::smart_key), "\"\\u0006\"");
EXPECT_EQ(toml_parser::QuoteText("\u0007", toml_parser::EQuoteRequest::smart_key), "\"\\u0007\"");
// 0008 = backspace (\b), 0009 = tab (\t), 000a = linefeed (\n)
EXPECT_EQ(toml_parser::QuoteText("\u000b", toml_parser::EQuoteRequest::smart_key), "\"\\u000B\"");
// 000c = form feed (\f), 000d = carriage return (\r)
EXPECT_EQ(toml_parser::QuoteText("\u000e", toml_parser::EQuoteRequest::smart_key), "\"\\u000E\"");
EXPECT_EQ(toml_parser::QuoteText("\u000f", toml_parser::EQuoteRequest::smart_key), "\"\\u000F\"");
EXPECT_EQ(toml_parser::QuoteText("\u0010", toml_parser::EQuoteRequest::smart_key), "\"\\u0010\"");
EXPECT_EQ(toml_parser::QuoteText("\u0011", toml_parser::EQuoteRequest::smart_key), "\"\\u0011\"");
EXPECT_EQ(toml_parser::QuoteText("\u0012", toml_parser::EQuoteRequest::smart_key), "\"\\u0012\"");
EXPECT_EQ(toml_parser::QuoteText("\u0013", toml_parser::EQuoteRequest::smart_key), "\"\\u0013\"");
EXPECT_EQ(toml_parser::QuoteText("\u0014", toml_parser::EQuoteRequest::smart_key), "\"\\u0014\"");
EXPECT_EQ(toml_parser::QuoteText("\u0015", toml_parser::EQuoteRequest::smart_key), "\"\\u0015\"");
EXPECT_EQ(toml_parser::QuoteText("\u0016", toml_parser::EQuoteRequest::smart_key), "\"\\u0016\"");
EXPECT_EQ(toml_parser::QuoteText("\u0017", toml_parser::EQuoteRequest::smart_key), "\"\\u0017\"");
EXPECT_EQ(toml_parser::QuoteText("\u0018", toml_parser::EQuoteRequest::smart_key), "\"\\u0018\"");
EXPECT_EQ(toml_parser::QuoteText("\u0019", toml_parser::EQuoteRequest::smart_key), "\"\\u0019\"");
EXPECT_EQ(toml_parser::QuoteText("\u001a", toml_parser::EQuoteRequest::smart_key), "\"\\u001A\"");
EXPECT_EQ(toml_parser::QuoteText("\u001b", toml_parser::EQuoteRequest::smart_key), "\"\\u001B\"");
EXPECT_EQ(toml_parser::QuoteText("\u001c", toml_parser::EQuoteRequest::smart_key), "\"\\u001C\"");
EXPECT_EQ(toml_parser::QuoteText("\u001d", toml_parser::EQuoteRequest::smart_key), "\"\\u001D\"");
EXPECT_EQ(toml_parser::QuoteText("\u001e", toml_parser::EQuoteRequest::smart_key), "\"\\u001E\"");
EXPECT_EQ(toml_parser::QuoteText("\u001f", toml_parser::EQuoteRequest::smart_key), "\"\\u001F\"");
// 0020..0021 are treated as characters (partly quotation needed)
// 0022 = quote (\")
// 0023..005b are treated as characters (partly quotation needed)
// 005c = backslash (\\)
// 005d..007e are treated as characters (partly quotation needed)
EXPECT_EQ(toml_parser::QuoteText("\u007f", toml_parser::EQuoteRequest::smart_key), "\"\\u007F\"");
// 0080... and higher are treated as unicode character (quotation needed)
}
TEST(TOMLMiscellaneousTests, SmartQuoteText)
{
EXPECT_EQ(toml_parser::QuoteText("abc", toml_parser::EQuoteRequest::smart_text), "\"abc\"");
EXPECT_EQ(toml_parser::QuoteText("123", toml_parser::EQuoteRequest::smart_text), "\"123\"");
EXPECT_EQ(toml_parser::QuoteText("ABC", toml_parser::EQuoteRequest::smart_text), "\"ABC\"");
EXPECT_EQ(toml_parser::QuoteText("abc_def", toml_parser::EQuoteRequest::smart_text), "\"abc_def\"");
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::smart_text), "\"ABC-DEF\"");
}
TEST(TOMLMiscellaneousTests, SmartQuoteSpecialCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("", toml_parser::EQuoteRequest::smart_text), "\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc def", toml_parser::EQuoteRequest::smart_text), "\"abc def\"");
EXPECT_EQ(toml_parser::QuoteText(".abc", toml_parser::EQuoteRequest::smart_text), "\".abc\"");
#ifndef __GNUC__
EXPECT_EQ(toml_parser::QuoteText(u8"<EFBFBD>", toml_parser::EQuoteRequest::smart_text),
"\"\\u00B5\""); // Only supported on Windows with MS compiler
#endif
EXPECT_EQ(toml_parser::QuoteText(u8"\u00a1", toml_parser::EQuoteRequest::smart_text), "\"\\u00A1\"");
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::smart_text), "\"abc/\"");
}
TEST(TOMLMiscellaneousTests, SmartQuoteEscapeCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("abc\tdef", toml_parser::EQuoteRequest::smart_text), "\"abc\\tdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\\def", toml_parser::EQuoteRequest::smart_text), "'abc\\def'");
EXPECT_EQ(toml_parser::QuoteText("\"abc\"", toml_parser::EQuoteRequest::smart_text), "'\"abc\"'"); // becomes literal text
EXPECT_EQ(toml_parser::QuoteText("'abc'", toml_parser::EQuoteRequest::smart_text), "\"'abc'\""); // becomes literal text
EXPECT_EQ(toml_parser::QuoteText("abc\bdef", toml_parser::EQuoteRequest::smart_text), "\"abc\\bdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\ndef", toml_parser::EQuoteRequest::smart_text), "\"abc\\ndef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\fdef", toml_parser::EQuoteRequest::smart_text), "\"abc\\fdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::smart_text), "\"abc\\rdef\"");
}
TEST(TOMLMiscellaneousTests, SmartQuoteControlCharsText)
{
EXPECT_EQ(toml_parser::QuoteText(std::string(1, '\0'), toml_parser::EQuoteRequest::smart_text), "\"\\u0000\"");
EXPECT_EQ(toml_parser::QuoteText("\u0001", toml_parser::EQuoteRequest::smart_text), "\"\\u0001\"");
EXPECT_EQ(toml_parser::QuoteText("\u0002", toml_parser::EQuoteRequest::smart_text), "\"\\u0002\"");
EXPECT_EQ(toml_parser::QuoteText("\u0003", toml_parser::EQuoteRequest::smart_text), "\"\\u0003\"");
EXPECT_EQ(toml_parser::QuoteText("\u0004", toml_parser::EQuoteRequest::smart_text), "\"\\u0004\"");
EXPECT_EQ(toml_parser::QuoteText("\u0005", toml_parser::EQuoteRequest::smart_text), "\"\\u0005\"");
EXPECT_EQ(toml_parser::QuoteText("\u0006", toml_parser::EQuoteRequest::smart_text), "\"\\u0006\"");
EXPECT_EQ(toml_parser::QuoteText("\u0007", toml_parser::EQuoteRequest::smart_text), "\"\\u0007\"");
// 0008 = backspace (\b), 0009 = tab (\t), 000a = linefeed (\n)
EXPECT_EQ(toml_parser::QuoteText("\u000b", toml_parser::EQuoteRequest::smart_text), "\"\\u000B\"");
// 000c = form feed (\f), 000d = carriage return (\r)
EXPECT_EQ(toml_parser::QuoteText("\u000e", toml_parser::EQuoteRequest::smart_text), "\"\\u000E\"");
EXPECT_EQ(toml_parser::QuoteText("\u000f", toml_parser::EQuoteRequest::smart_text), "\"\\u000F\"");
EXPECT_EQ(toml_parser::QuoteText("\u0010", toml_parser::EQuoteRequest::smart_text), "\"\\u0010\"");
EXPECT_EQ(toml_parser::QuoteText("\u0011", toml_parser::EQuoteRequest::smart_text), "\"\\u0011\"");
EXPECT_EQ(toml_parser::QuoteText("\u0012", toml_parser::EQuoteRequest::smart_text), "\"\\u0012\"");
EXPECT_EQ(toml_parser::QuoteText("\u0013", toml_parser::EQuoteRequest::smart_text), "\"\\u0013\"");
EXPECT_EQ(toml_parser::QuoteText("\u0014", toml_parser::EQuoteRequest::smart_text), "\"\\u0014\"");
EXPECT_EQ(toml_parser::QuoteText("\u0015", toml_parser::EQuoteRequest::smart_text), "\"\\u0015\"");
EXPECT_EQ(toml_parser::QuoteText("\u0016", toml_parser::EQuoteRequest::smart_text), "\"\\u0016\"");
EXPECT_EQ(toml_parser::QuoteText("\u0017", toml_parser::EQuoteRequest::smart_text), "\"\\u0017\"");
EXPECT_EQ(toml_parser::QuoteText("\u0018", toml_parser::EQuoteRequest::smart_text), "\"\\u0018\"");
EXPECT_EQ(toml_parser::QuoteText("\u0019", toml_parser::EQuoteRequest::smart_text), "\"\\u0019\"");
EXPECT_EQ(toml_parser::QuoteText("\u001a", toml_parser::EQuoteRequest::smart_text), "\"\\u001A\"");
EXPECT_EQ(toml_parser::QuoteText("\u001b", toml_parser::EQuoteRequest::smart_text), "\"\\u001B\"");
EXPECT_EQ(toml_parser::QuoteText("\u001c", toml_parser::EQuoteRequest::smart_text), "\"\\u001C\"");
EXPECT_EQ(toml_parser::QuoteText("\u001d", toml_parser::EQuoteRequest::smart_text), "\"\\u001D\"");
EXPECT_EQ(toml_parser::QuoteText("\u001e", toml_parser::EQuoteRequest::smart_text), "\"\\u001E\"");
EXPECT_EQ(toml_parser::QuoteText("\u001f", toml_parser::EQuoteRequest::smart_text), "\"\\u001F\"");
// 0020..0021 are treated as characters (partly quotation needed)
// 0022 = quote (\")
// 0023..005b are treated as characters (partly quotation needed)
// 005c = backslash (\\)
// 005d..007e are treated as characters (partly quotation needed)
EXPECT_EQ(toml_parser::QuoteText("\u007f", toml_parser::EQuoteRequest::smart_text), "\"\\u007F\"");
// 0080... and higher are treated as unicode character (quotation needed)
}
TEST(TOMLMiscellaneousTests, QuotedText)
{
EXPECT_EQ(toml_parser::QuoteText("abc", toml_parser::EQuoteRequest::quoted_text), "\"abc\"");
EXPECT_EQ(toml_parser::QuoteText("123", toml_parser::EQuoteRequest::quoted_text), "\"123\"");
EXPECT_EQ(toml_parser::QuoteText("ABC", toml_parser::EQuoteRequest::quoted_text), "\"ABC\"");
EXPECT_EQ(toml_parser::QuoteText("abc_def", toml_parser::EQuoteRequest::quoted_text), "\"abc_def\"");
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::quoted_text), "\"ABC-DEF\"");
}
TEST(TOMLMiscellaneousTests, QuotedSpecialCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("", toml_parser::EQuoteRequest::quoted_text), "\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc def", toml_parser::EQuoteRequest::quoted_text), "\"abc def\"");
EXPECT_EQ(toml_parser::QuoteText(".abc", toml_parser::EQuoteRequest::quoted_text), "\".abc\"");
#ifndef __GNUC__
EXPECT_EQ(toml_parser::QuoteText(u8"<EFBFBD>", toml_parser::EQuoteRequest::quoted_text),
"\"\\u00B5\""); // Only supported on Windows with MS compiler
#endif
EXPECT_EQ(toml_parser::QuoteText(u8"\u00a1", toml_parser::EQuoteRequest::quoted_text), "\"\\u00A1\"");
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::quoted_text), "\"abc/\"");
}
TEST(TOMLMiscellaneousTests, QuotedEscapeCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("abc\tdef", toml_parser::EQuoteRequest::quoted_text), "\"abc\\tdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\\def", toml_parser::EQuoteRequest::quoted_text), "\"abc\\\\def\"");
EXPECT_EQ(toml_parser::QuoteText("\"abc\"", toml_parser::EQuoteRequest::quoted_text), "\"\\\"abc\\\"\"");
EXPECT_EQ(toml_parser::QuoteText("'abc'", toml_parser::EQuoteRequest::quoted_text), "\"'abc'\"");
EXPECT_EQ(toml_parser::QuoteText("abc\bdef", toml_parser::EQuoteRequest::quoted_text), "\"abc\\bdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\ndef", toml_parser::EQuoteRequest::quoted_text), "\"abc\\ndef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\fdef", toml_parser::EQuoteRequest::quoted_text), "\"abc\\fdef\"");
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::quoted_text), "\"abc\\rdef\"");
}
TEST(TOMLMiscellaneousTests, QuotedControlCharsText)
{
EXPECT_EQ(toml_parser::QuoteText(std::string(1, '\0'), toml_parser::EQuoteRequest::quoted_text), "\"\\u0000\"");
EXPECT_EQ(toml_parser::QuoteText("\u0001", toml_parser::EQuoteRequest::quoted_text), "\"\\u0001\"");
EXPECT_EQ(toml_parser::QuoteText("\u0002", toml_parser::EQuoteRequest::quoted_text), "\"\\u0002\"");
EXPECT_EQ(toml_parser::QuoteText("\u0003", toml_parser::EQuoteRequest::quoted_text), "\"\\u0003\"");
EXPECT_EQ(toml_parser::QuoteText("\u0004", toml_parser::EQuoteRequest::quoted_text), "\"\\u0004\"");
EXPECT_EQ(toml_parser::QuoteText("\u0005", toml_parser::EQuoteRequest::quoted_text), "\"\\u0005\"");
EXPECT_EQ(toml_parser::QuoteText("\u0006", toml_parser::EQuoteRequest::quoted_text), "\"\\u0006\"");
EXPECT_EQ(toml_parser::QuoteText("\u0007", toml_parser::EQuoteRequest::quoted_text), "\"\\u0007\"");
// 0008 = backspace (\b), 0009 = tab (\t), 000a = linefeed (\n)
EXPECT_EQ(toml_parser::QuoteText("\u000b", toml_parser::EQuoteRequest::quoted_text), "\"\\u000B\"");
// 000c = form feed (\f), 000d = carriage return (\r)
EXPECT_EQ(toml_parser::QuoteText("\u000e", toml_parser::EQuoteRequest::quoted_text), "\"\\u000E\"");
EXPECT_EQ(toml_parser::QuoteText("\u000f", toml_parser::EQuoteRequest::quoted_text), "\"\\u000F\"");
EXPECT_EQ(toml_parser::QuoteText("\u0010", toml_parser::EQuoteRequest::quoted_text), "\"\\u0010\"");
EXPECT_EQ(toml_parser::QuoteText("\u0011", toml_parser::EQuoteRequest::quoted_text), "\"\\u0011\"");
EXPECT_EQ(toml_parser::QuoteText("\u0012", toml_parser::EQuoteRequest::quoted_text), "\"\\u0012\"");
EXPECT_EQ(toml_parser::QuoteText("\u0013", toml_parser::EQuoteRequest::quoted_text), "\"\\u0013\"");
EXPECT_EQ(toml_parser::QuoteText("\u0014", toml_parser::EQuoteRequest::quoted_text), "\"\\u0014\"");
EXPECT_EQ(toml_parser::QuoteText("\u0015", toml_parser::EQuoteRequest::quoted_text), "\"\\u0015\"");
EXPECT_EQ(toml_parser::QuoteText("\u0016", toml_parser::EQuoteRequest::quoted_text), "\"\\u0016\"");
EXPECT_EQ(toml_parser::QuoteText("\u0017", toml_parser::EQuoteRequest::quoted_text), "\"\\u0017\"");
EXPECT_EQ(toml_parser::QuoteText("\u0018", toml_parser::EQuoteRequest::quoted_text), "\"\\u0018\"");
EXPECT_EQ(toml_parser::QuoteText("\u0019", toml_parser::EQuoteRequest::quoted_text), "\"\\u0019\"");
EXPECT_EQ(toml_parser::QuoteText("\u001a", toml_parser::EQuoteRequest::quoted_text), "\"\\u001A\"");
EXPECT_EQ(toml_parser::QuoteText("\u001b", toml_parser::EQuoteRequest::quoted_text), "\"\\u001B\"");
EXPECT_EQ(toml_parser::QuoteText("\u001c", toml_parser::EQuoteRequest::quoted_text), "\"\\u001C\"");
EXPECT_EQ(toml_parser::QuoteText("\u001d", toml_parser::EQuoteRequest::quoted_text), "\"\\u001D\"");
EXPECT_EQ(toml_parser::QuoteText("\u001e", toml_parser::EQuoteRequest::quoted_text), "\"\\u001E\"");
EXPECT_EQ(toml_parser::QuoteText("\u001f", toml_parser::EQuoteRequest::quoted_text), "\"\\u001F\"");
// 0020..0021 are treated as characters (partly quotation needed)
// 0022 = quote (\")
// 0023..005b are treated as characters (partly quotation needed)
// 005c = backslash (\\)
// 005d..007e are treated as characters (partly quotation needed)
EXPECT_EQ(toml_parser::QuoteText("\u007f", toml_parser::EQuoteRequest::quoted_text), "\"\\u007F\"");
// 0080... and higher are treated as unicode character (quotation needed)
}
TEST(TOMLMiscellaneousTests, LiteralText)
{
EXPECT_EQ(toml_parser::QuoteText("abc", toml_parser::EQuoteRequest::literal_text), "'abc'");
EXPECT_EQ(toml_parser::QuoteText("123", toml_parser::EQuoteRequest::literal_text), "'123'");
EXPECT_EQ(toml_parser::QuoteText("ABC", toml_parser::EQuoteRequest::literal_text), "'ABC'");
EXPECT_EQ(toml_parser::QuoteText("abc_def", toml_parser::EQuoteRequest::literal_text), "'abc_def'");
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::literal_text), "'ABC-DEF'");
}
TEST(TOMLMiscellaneousTests, LiteralSpecialCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("", toml_parser::EQuoteRequest::literal_text), "''");
EXPECT_EQ(toml_parser::QuoteText("abc def", toml_parser::EQuoteRequest::literal_text), "'abc def'");
EXPECT_EQ(toml_parser::QuoteText(".abc", toml_parser::EQuoteRequest::literal_text), "'.abc'");
#ifndef __GNUC__
EXPECT_EQ(toml_parser::QuoteText(u8"<EFBFBD>", toml_parser::EQuoteRequest::literal_text),
u8"'\u00B5'"); // Only supported on Windows with MS compiler
#endif
EXPECT_EQ(toml_parser::QuoteText(u8"\u00a1", toml_parser::EQuoteRequest::literal_text), u8"'\u00A1'");
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::literal_text), "'abc/'");
}
TEST(TOMLMiscellaneousTests, LiteralEscapeCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("abc\tdef", toml_parser::EQuoteRequest::literal_text), "\"abc\\tdef\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\\def", toml_parser::EQuoteRequest::literal_text), "'abc\\def'");
EXPECT_EQ(toml_parser::QuoteText("\"abc\"", toml_parser::EQuoteRequest::literal_text), "'\"abc\"'");
EXPECT_EQ(toml_parser::QuoteText("'abc'", toml_parser::EQuoteRequest::literal_text), "\"'abc'\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\bdef", toml_parser::EQuoteRequest::literal_text), "\"abc\\bdef\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\ndef", toml_parser::EQuoteRequest::literal_text), "\"abc\\ndef\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\fdef", toml_parser::EQuoteRequest::literal_text), "\"abc\\fdef\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::literal_text), "\"abc\\rdef\""); // Becomes quoted
}
TEST(TOMLMiscellaneousTests, LiteralControlCharsText)
{
// All become quoted insteda of literal (due to control character).
EXPECT_EQ(toml_parser::QuoteText(std::string(1, '\0'), toml_parser::EQuoteRequest::literal_text), "\"\\u0000\"");
EXPECT_EQ(toml_parser::QuoteText("\u0001", toml_parser::EQuoteRequest::literal_text), "\"\\u0001\"");
EXPECT_EQ(toml_parser::QuoteText("\u0002", toml_parser::EQuoteRequest::literal_text), "\"\\u0002\"");
EXPECT_EQ(toml_parser::QuoteText("\u0003", toml_parser::EQuoteRequest::literal_text), "\"\\u0003\"");
EXPECT_EQ(toml_parser::QuoteText("\u0004", toml_parser::EQuoteRequest::literal_text), "\"\\u0004\"");
EXPECT_EQ(toml_parser::QuoteText("\u0005", toml_parser::EQuoteRequest::literal_text), "\"\\u0005\"");
EXPECT_EQ(toml_parser::QuoteText("\u0006", toml_parser::EQuoteRequest::literal_text), "\"\\u0006\"");
EXPECT_EQ(toml_parser::QuoteText("\u0007", toml_parser::EQuoteRequest::literal_text), "\"\\u0007\"");
// 0008 = backspace (\b), 0009 = tab (\t), 000a = linefeed (\n)
EXPECT_EQ(toml_parser::QuoteText("\u000b", toml_parser::EQuoteRequest::literal_text), "\"\\u000B\"");
// 000c = form feed (\f), 000d = carriage return (\r)
EXPECT_EQ(toml_parser::QuoteText("\u000e", toml_parser::EQuoteRequest::literal_text), "\"\\u000E\"");
EXPECT_EQ(toml_parser::QuoteText("\u000f", toml_parser::EQuoteRequest::literal_text), "\"\\u000F\"");
EXPECT_EQ(toml_parser::QuoteText("\u0010", toml_parser::EQuoteRequest::literal_text), "\"\\u0010\"");
EXPECT_EQ(toml_parser::QuoteText("\u0011", toml_parser::EQuoteRequest::literal_text), "\"\\u0011\"");
EXPECT_EQ(toml_parser::QuoteText("\u0012", toml_parser::EQuoteRequest::literal_text), "\"\\u0012\"");
EXPECT_EQ(toml_parser::QuoteText("\u0013", toml_parser::EQuoteRequest::literal_text), "\"\\u0013\"");
EXPECT_EQ(toml_parser::QuoteText("\u0014", toml_parser::EQuoteRequest::literal_text), "\"\\u0014\"");
EXPECT_EQ(toml_parser::QuoteText("\u0015", toml_parser::EQuoteRequest::literal_text), "\"\\u0015\"");
EXPECT_EQ(toml_parser::QuoteText("\u0016", toml_parser::EQuoteRequest::literal_text), "\"\\u0016\"");
EXPECT_EQ(toml_parser::QuoteText("\u0017", toml_parser::EQuoteRequest::literal_text), "\"\\u0017\"");
EXPECT_EQ(toml_parser::QuoteText("\u0018", toml_parser::EQuoteRequest::literal_text), "\"\\u0018\"");
EXPECT_EQ(toml_parser::QuoteText("\u0019", toml_parser::EQuoteRequest::literal_text), "\"\\u0019\"");
EXPECT_EQ(toml_parser::QuoteText("\u001a", toml_parser::EQuoteRequest::literal_text), "\"\\u001A\"");
EXPECT_EQ(toml_parser::QuoteText("\u001b", toml_parser::EQuoteRequest::literal_text), "\"\\u001B\"");
EXPECT_EQ(toml_parser::QuoteText("\u001c", toml_parser::EQuoteRequest::literal_text), "\"\\u001C\"");
EXPECT_EQ(toml_parser::QuoteText("\u001d", toml_parser::EQuoteRequest::literal_text), "\"\\u001D\"");
EXPECT_EQ(toml_parser::QuoteText("\u001e", toml_parser::EQuoteRequest::literal_text), "\"\\u001E\"");
EXPECT_EQ(toml_parser::QuoteText("\u001f", toml_parser::EQuoteRequest::literal_text), "\"\\u001F\"");
// 0020..0021 are treated as characters (partly quotation needed)
// 0022 = quote (\")
// 0023..005b are treated as characters (partly quotation needed)
// 005c = backslash (\\)
// 005d..007e are treated as characters (partly quotation needed)
EXPECT_EQ(toml_parser::QuoteText("\u007f", toml_parser::EQuoteRequest::literal_text), "\"\\u007F\"");
// 0080... and higher are treated as unicode character (quotation needed)
}
TEST(TOMLMiscellaneousTests, MultiLineQuotedText)
{
EXPECT_EQ(toml_parser::QuoteText("abc", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("123", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"123\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("ABC", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"ABC\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc_def", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc_def\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"ABC-DEF\"\"\"");
}
TEST(TOMLMiscellaneousTests, MultiLineQuotedSpecialCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc def", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc def\"\"\"");
EXPECT_EQ(toml_parser::QuoteText(".abc", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\".abc\"\"\"");
#ifndef __GNUC__
EXPECT_EQ(toml_parser::QuoteText(u8"<EFBFBD>", toml_parser::EQuoteRequest::multi_line_quoted_text),
"\"\"\"\\u00B5\"\"\""); // Only supported on Windows with MS compiler
#endif
EXPECT_EQ(toml_parser::QuoteText(u8"\u00a1", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u00A1\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc/\"\"\"");
}
TEST(TOMLMiscellaneousTests, MultiLineQuotedEscapeCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("abc\tdef", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\\tdef\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc\\def", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\\\\def\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\"abc\"", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\\"abc\\\"\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("'abc'", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"'abc'\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc\bdef", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\\bdef\"\"\"");
// Multi line
EXPECT_EQ(toml_parser::QuoteText("abc\ndef", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\ndef\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("abc\fdef", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\\fdef\"\"\"");
// Multi line
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\rdef\"\"\"");
}
TEST(TOMLMiscellaneousTests, MultiLineQuotedControlCharsText)
{
EXPECT_EQ(toml_parser::QuoteText(std::string(1, '\0'), toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0000\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0001", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0001\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0002", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0002\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0003", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0003\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0004", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0004\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0005", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0005\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0006", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0006\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0007", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0007\"\"\"");
// 0008 = backspace (\b), 0009 = tab (\t), 000a = linefeed (\n)
EXPECT_EQ(toml_parser::QuoteText("\u000b", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u000B\"\"\"");
// 000c = form feed (\f), 000d = carriage return (\r)
EXPECT_EQ(toml_parser::QuoteText("\u000e", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u000E\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u000f", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u000F\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0010", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0010\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0011", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0011\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0012", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0012\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0013", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0013\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0014", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0014\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0015", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0015\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0016", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0016\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0017", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0017\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0018", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0018\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0019", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u0019\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001a", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u001A\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001b", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u001B\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001c", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u001C\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001d", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u001D\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001e", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u001E\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001f", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u001F\"\"\"");
// 0020..0021 are treated as characters (partly quotation needed)
// 0022 = quote (\")
// 0023..005b are treated as characters (partly quotation needed)
// 005c = backslash (\\)
// 005d..007e are treated as characters (partly quotation needed)
EXPECT_EQ(toml_parser::QuoteText("\u007f", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"\\u007F\"\"\"");
// 0080... and higher are treated as unicode character (quotation needed)
}
TEST(TOMLMiscellaneousTests, MultiLineLiteralText)
{
EXPECT_EQ(toml_parser::QuoteText("abc", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc'''");
EXPECT_EQ(toml_parser::QuoteText("123", toml_parser::EQuoteRequest::multi_line_literal_text), "'''123'''");
EXPECT_EQ(toml_parser::QuoteText("ABC", toml_parser::EQuoteRequest::multi_line_literal_text), "'''ABC'''");
EXPECT_EQ(toml_parser::QuoteText("abc_def", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc_def'''");
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::multi_line_literal_text), "'''ABC-DEF'''");
}
TEST(TOMLMiscellaneousTests, MultiLineLiteralSpecialCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("", toml_parser::EQuoteRequest::multi_line_literal_text), "''''''");
EXPECT_EQ(toml_parser::QuoteText("abc def", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc def'''");
EXPECT_EQ(toml_parser::QuoteText(".abc", toml_parser::EQuoteRequest::multi_line_literal_text), "'''.abc'''");
#ifndef __GNUC__
EXPECT_EQ(toml_parser::QuoteText(u8"<EFBFBD>", toml_parser::EQuoteRequest::multi_line_literal_text),
u8"'''\u00B5'''"); // Only supported on Windows with MS compiler
#endif
EXPECT_EQ(toml_parser::QuoteText(u8"\u00a1", toml_parser::EQuoteRequest::multi_line_literal_text), u8"'''\u00A1'''");
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc/'''");
}
TEST(TOMLMiscellaneousTests, MultiLineLiteralEscapeCharsText)
{
EXPECT_EQ(toml_parser::QuoteText("abc\tdef", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"abc\\tdef\"\"\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\\def", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc\\def'''");
EXPECT_EQ(toml_parser::QuoteText("\"abc\"", toml_parser::EQuoteRequest::multi_line_literal_text), "'''\"abc\"'''");
EXPECT_EQ(toml_parser::QuoteText("'abc'", toml_parser::EQuoteRequest::multi_line_literal_text), "''''abc''''");
EXPECT_EQ(
toml_parser::QuoteText("abc\bdef", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"abc\\bdef\"\"\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\ndef", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc\ndef'''");
EXPECT_EQ(toml_parser::QuoteText("abc\fdef", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"abc\\fdef\"\"\""); // Becomes quoted
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc\rdef'''");
}
TEST(TOMLMiscellaneousTests, MultiLineLiteralControlCharsText)
{
// All become quoted insteda of literal (due to control character).
EXPECT_EQ(toml_parser::QuoteText(std::string(1, '\0'), toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0000\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0001", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0001\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0002", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0002\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0003", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0003\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0004", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0004\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0005", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0005\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0006", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0006\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0007", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0007\"\"\"");
// 0008 = backspace (\b), 0009 = tab (\t), 000a = linefeed (\n)
EXPECT_EQ(toml_parser::QuoteText("\u000b", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u000B\"\"\"");
// 000c = form feed (\f), 000d = carriage return (\r)
EXPECT_EQ(toml_parser::QuoteText("\u000e", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u000E\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u000f", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u000F\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0010", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0010\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0011", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0011\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0012", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0012\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0013", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0013\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0014", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0014\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0015", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0015\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0016", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0016\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0017", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0017\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0018", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0018\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u0019", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u0019\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001a", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u001A\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001b", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u001B\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001c", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u001C\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001d", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u001D\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001e", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u001E\"\"\"");
EXPECT_EQ(toml_parser::QuoteText("\u001f", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u001F\"\"\"");
// 0020..0021 are treated as characters (partly quotation needed)
// 0022 = quote (\")
// 0023..005b are treated as characters (partly quotation needed)
// 005c = backslash (\\)
// 005d..007e are treated as characters (partly quotation needed)
EXPECT_EQ(toml_parser::QuoteText("\u007f", toml_parser::EQuoteRequest::multi_line_literal_text), "\"\"\"\\u007F\"\"\"");
// 0080... and higher are treated as unicode character (quotation needed)
}
TEST(TOMLMiscellaneousTests, ExtractBareKeyName)
{
EXPECT_EQ(toml_parser::ExtractKeyName(""), "");
EXPECT_EQ(toml_parser::ExtractKeyName("abc.def"), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("abc"), "abc");
EXPECT_EQ(toml_parser::ExtractKeyName("abc.def.ghi"), "ghi");
EXPECT_EQ(toml_parser::ExtractKeyName("_abc.def"), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("_abc._def"), "_def");
EXPECT_EQ(toml_parser::ExtractKeyName("abc-.def"), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("abc-.def-"), "def-");
EXPECT_EQ(toml_parser::ExtractKeyName("1234"), "1234");
}
TEST(TOMLMiscellaneousTests, ExtractQuotedKeyName)
{
EXPECT_EQ(toml_parser::ExtractKeyName("\"\""), "");
EXPECT_EQ(toml_parser::ExtractKeyName("\"abc\""), "abc");
EXPECT_EQ(toml_parser::ExtractKeyName("abc.\"def\""), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("\"abc.def\""), "abc.def");
EXPECT_EQ(toml_parser::ExtractKeyName("\"abc\\tdef\""), "abc\tdef");
EXPECT_EQ(toml_parser::ExtractKeyName("\"'This' is a \\\"very\\\" quoted key!\""), "'This' is a \"very\" quoted key!");
EXPECT_EQ(toml_parser::ExtractKeyName("\"[1]\""), "[1]");
EXPECT_EQ(toml_parser::ExtractKeyName("\"abc"), ""); // Failure
EXPECT_EQ(toml_parser::ExtractKeyName("abc\"def\""), ""); // Failure
}
TEST(TOMLMiscellaneousTests, ExtractLiteralKeyName)
{
EXPECT_EQ(toml_parser::ExtractKeyName("''"), "");
EXPECT_EQ(toml_parser::ExtractKeyName("'abc'"), "abc");
EXPECT_EQ(toml_parser::ExtractKeyName("abc.'def'"), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("'abc.def'"), "abc.def");
EXPECT_EQ(toml_parser::ExtractKeyName("'abc def'"), "abc def");
EXPECT_EQ(toml_parser::ExtractKeyName("'abc\\tdef'"), "abc\\tdef"); // No escape uences supported
EXPECT_EQ(toml_parser::ExtractKeyName("'This is a \"very\" literal key!'"), "This is a \"very\" literal key!");
EXPECT_EQ(toml_parser::ExtractKeyName("'[1]'"), "[1]");
EXPECT_EQ(toml_parser::ExtractKeyName("'abc"), "");
EXPECT_EQ(toml_parser::ExtractKeyName("abc'def"), ""); // Failure
}
TEST(TOMLMiscellaneousTests, ExtractIndexKeyName)
{
EXPECT_EQ(toml_parser::ExtractKeyName("[0]"), "0");
EXPECT_EQ(toml_parser::ExtractKeyName("[0][1]"), "1");
EXPECT_EQ(toml_parser::ExtractKeyName("abc[0][1]"), "1");
EXPECT_EQ(toml_parser::ExtractKeyName("abc[0].def"), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("abc[0].\"def\""), "def");
EXPECT_EQ(toml_parser::ExtractKeyName("abc[0].def[1]"), "1");
EXPECT_EQ(toml_parser::ExtractKeyName("abc[0].\"def\"[1]"), "1");
EXPECT_EQ(toml_parser::ExtractKeyName("abc[0]def"), ""); // Failure
}

View File

@@ -2,34 +2,42 @@
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
/* Requirements TOML CParserTOML
/* Requirements TOML toml_parser::CParser
* - The output after parsing is a tree structure only if parsing is successful
* - No recovery will be attempted when syntax errors occur
* - all errors and features (except Date-Time) as defined at https://toml.io/en/v1.0.0 have to result in an invalid or valid
* outcome respectively
* outcome respectively
*/
TEST(RecognizeTypes, Root)
{
toml_parser::CParser parser("");
auto& rroot = parser.Root();
EXPECT_EQ(rroot.GetParent(), nullptr);
EXPECT_EQ(rroot.GetIndex(), sdv::toml::npos);
}
TEST(RecognizeTypes, Table)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
[newTable]
[secondTable.nestedTable]
)"s);
auto table1 = parser.GetRoot().GetDirect("newTable");
auto table1 = parser.Root().Direct("newTable");
EXPECT_EQ(table1->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_EQ(table1->GetName(), "newTable");
EXPECT_EQ(table1->GetValue(), sdv::any_t());
EXPECT_NE(static_cast<sdv::IInterfaceAccess*>(table1.get())->GetInterface<sdv::toml::INodeCollection>(), nullptr);
auto table2 = parser.GetRoot().GetDirect("secondTable");
auto table2 = parser.Root().Direct("secondTable");
EXPECT_EQ(table2->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_EQ(table2->GetName(), "secondTable");
EXPECT_EQ(table2->GetValue(), sdv::any_t());
EXPECT_NE(((sdv::IInterfaceAccess*) table2.get())->GetInterface<sdv::toml::INodeCollection>(), nullptr);
auto table3 = parser.GetRoot().GetDirect("secondTable.nestedTable");
auto table3 = parser.Root().Direct("secondTable.nestedTable");
EXPECT_EQ(table3->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_EQ(table3->GetName(), "nestedTable");
EXPECT_EQ(table3->GetValue(), sdv::any_t());
@@ -39,7 +47,7 @@ TEST(RecognizeTypes, Table)
TEST(RecognizeTypes, Key_Value)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
name = "Hammer"
id = 42
pi = 3.1415926
@@ -49,41 +57,47 @@ TEST(RecognizeTypes, Key_Value)
)"s);
auto value_name = parser.GetRoot().GetDirect("name");
auto value_name = parser.Root().Direct("name");
EXPECT_EQ(value_name->GetType(), sdv::toml::ENodeType::node_string);
EXPECT_EQ(value_name->GetValue(), sdv::any_t("Hammer"));
EXPECT_EQ(value_name->GetIndex(), 0u);
auto value_id = parser.GetRoot().GetDirect("id");
auto value_id = parser.Root().Direct("id");
EXPECT_EQ(value_id->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(value_id->GetValue(), 42);
EXPECT_EQ(value_id->GetIndex(), 1u);
auto value_pi = parser.GetRoot().GetDirect("pi");
auto value_pi = parser.Root().Direct("pi");
EXPECT_EQ(value_pi->GetType(), sdv::toml::ENodeType::node_floating_point);
EXPECT_EQ(value_pi->GetValue(), 3.1415926);
EXPECT_EQ(value_pi->GetIndex(), 2u);
auto value_boolean = parser.GetRoot().GetDirect("boolean");
auto value_boolean = parser.Root().Direct("boolean");
EXPECT_EQ(value_boolean->GetType(), sdv::toml::ENodeType::node_boolean);
EXPECT_EQ(value_boolean->GetValue(), true);
EXPECT_EQ(value_boolean->GetIndex(), 3u);
auto value_array = parser.GetRoot().GetDirect("array");
auto value_array = parser.Root().Direct("array");
EXPECT_EQ(value_array->GetType(), sdv::toml::ENodeType::node_array);
EXPECT_EQ(value_array->GetValue(), sdv::any_t());
EXPECT_EQ(value_array->GetIndex(), 4u);
auto value_table = parser.GetRoot().GetDirect("table");
auto value_table = parser.Root().Direct("table");
EXPECT_EQ(value_table->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_EQ(value_table->GetValue(), sdv::any_t());
EXPECT_EQ(value_table->GetIndex(), 5u);
}
TEST(RecognizeTypes, TableArray)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
[[newTableArray]]
[[newTableArray]]
[[table.nestedTableArray]]
)"s);
auto tableArray1 = parser.GetRoot().GetDirect("newTableArray");
auto tableArray1 = parser.Root().Direct("newTableArray");
EXPECT_EQ(tableArray1->GetType(), sdv::toml::ENodeType::node_array);
EXPECT_NE(static_cast<sdv::IInterfaceAccess*>(tableArray1.get())->GetInterface<sdv::toml::INodeCollection>(), nullptr);
EXPECT_EQ(tableArray1->GetName(), "newTableArray");
@@ -97,21 +111,23 @@ TEST(RecognizeTypes, TableArray)
EXPECT_NE(pTableNode1, nullptr);
EXPECT_EQ(pArrayCollection->GetNode(2), nullptr);
auto table1 = parser.GetRoot().GetDirect("newTableArray[0]");
auto table1 = parser.Root().Direct("newTableArray[0]");
ASSERT_TRUE(table1);
EXPECT_EQ(table1->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_EQ(static_cast<sdv::IInterfaceAccess*>(table1.get()), pTableNode0);
EXPECT_TRUE(table1->GetName().empty());
EXPECT_EQ(table1->GetName(), "newTableArray");
auto table2 = parser.GetRoot().GetDirect("newTableArray[1]");
auto table2 = parser.Root().Direct("newTableArray[1]");
ASSERT_TRUE(table2);
EXPECT_EQ(static_cast<sdv::IInterfaceAccess*>(table2.get()), pTableNode1);
EXPECT_EQ(table2->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_TRUE(table2->GetName().empty());
EXPECT_EQ(table2->GetName(), "newTableArray");
}
TEST(NestedContent, Array)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
arr_mixed = [ 1.0, 2, "test string", [ 1, 2 ], { pi = 3.14, e = 2.71828 }, true]
arr_ints = [ 1, 2, 3, 4]
arr_ints_trailing_comma = [ 1, 2, 3, 4, ]
@@ -124,7 +140,7 @@ TEST(NestedContent, Array)
{
auto array_ints = parser.GetRoot().GetDirect("arr_ints");
auto array_ints = parser.Root().Direct("arr_ints");
EXPECT_EQ(array_ints->GetType(), sdv::toml::ENodeType::node_array);
sdv::toml::INodeCollection* pIntArrayCollection =
static_cast<sdv::IInterfaceAccess*>(array_ints.get())->GetInterface<sdv::toml::INodeCollection>();
@@ -135,104 +151,131 @@ TEST(NestedContent, Array)
EXPECT_NE(pIntArrayCollection->GetNode(2), nullptr);
EXPECT_NE(pIntArrayCollection->GetNode(3), nullptr);
EXPECT_EQ(pIntArrayCollection->GetNode(4), nullptr);
auto array_ints_0 = parser.GetRoot().GetDirect("arr_ints[0]");
auto array_ints_0 = parser.Root().Direct("arr_ints[0]");
ASSERT_NE(array_ints_0, nullptr);
EXPECT_EQ(array_ints_0->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_0->GetValue(), 1);
auto array_ints_1 = parser.GetRoot().GetDirect("arr_ints[1]");
EXPECT_EQ(array_ints_0->GetIndex(), 0u);
auto array_ints_1 = parser.Root().Direct("arr_ints[1]");
ASSERT_NE(array_ints_1, nullptr);
EXPECT_EQ(array_ints_1->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_1->GetValue(), 2);
auto array_ints_2 = parser.GetRoot().GetDirect("arr_ints[2]");
EXPECT_EQ(array_ints_1->GetIndex(), 1u);
auto array_ints_2 = parser.Root().Direct("arr_ints[2]");
ASSERT_NE(array_ints_2, nullptr);
EXPECT_EQ(array_ints_2->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_2->GetValue(), 3);
auto array_ints_3 = parser.GetRoot().GetDirect("arr_ints[3]");
EXPECT_EQ(array_ints_2->GetIndex(), 2u);
auto array_ints_3 = parser.Root().Direct("arr_ints[3]");
ASSERT_NE(array_ints_3, nullptr);
EXPECT_EQ(array_ints_3->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_3->GetValue(), 4);
auto array_ints_4 = parser.GetRoot().GetDirect("arr_ints[4]");
EXPECT_EQ(array_ints_3->GetIndex(), 3u);
auto array_ints_4 = parser.Root().Direct("arr_ints[4]");
EXPECT_EQ(array_ints_4, nullptr);
}
{
auto array_ints_trailing_comma = parser.GetRoot().GetDirect("arr_ints_trailing_comma");
auto array_ints_trailing_comma_0 = parser.GetRoot().GetDirect("arr_ints_trailing_comma[0]");
auto array_ints_trailing_comma_1 = parser.GetRoot().GetDirect("arr_ints_trailing_comma[1]");
auto array_ints_trailing_comma_2 = parser.GetRoot().GetDirect("arr_ints_trailing_comma[2]");
auto array_ints_trailing_comma_3 = parser.GetRoot().GetDirect("arr_ints_trailing_comma[3]");
auto array_ints_trailing_comma_4 = parser.GetRoot().GetDirect("arr_ints_trailing_comma[4]");
auto array_ints_trailing_comma = parser.Root().Direct("arr_ints_trailing_comma");
auto array_ints_trailing_comma_0 = parser.Root().Direct("arr_ints_trailing_comma[0]");
auto array_ints_trailing_comma_1 = parser.Root().Direct("arr_ints_trailing_comma[1]");
auto array_ints_trailing_comma_2 = parser.Root().Direct("arr_ints_trailing_comma[2]");
auto array_ints_trailing_comma_3 = parser.Root().Direct("arr_ints_trailing_comma[3]");
auto array_ints_trailing_comma_4 = parser.Root().Direct("arr_ints_trailing_comma[4]");
EXPECT_EQ(array_ints_trailing_comma->GetType(), sdv::toml::ENodeType::node_array);
ASSERT_NE(array_ints_trailing_comma_0, nullptr);
EXPECT_EQ(array_ints_trailing_comma_0->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_trailing_comma_0->GetValue(), 1);
EXPECT_EQ(array_ints_trailing_comma_0->GetIndex(), 0u);
ASSERT_NE(array_ints_trailing_comma_1, nullptr);
EXPECT_EQ(array_ints_trailing_comma_1->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_trailing_comma_1->GetValue(), 2);
EXPECT_EQ(array_ints_trailing_comma_1->GetIndex(), 1u);
ASSERT_NE(array_ints_trailing_comma_2, nullptr);
EXPECT_EQ(array_ints_trailing_comma_2->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_trailing_comma_2->GetValue(), 3);
EXPECT_EQ(array_ints_trailing_comma_2->GetIndex(), 2u);
ASSERT_NE(array_ints_trailing_comma_3, nullptr);
EXPECT_EQ(array_ints_trailing_comma_3->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_ints_trailing_comma_3->GetValue(), 4);
EXPECT_EQ(array_ints_trailing_comma_3->GetIndex(), 3u);
EXPECT_EQ(array_ints_trailing_comma_4, nullptr);
}
{
auto array_mixed = parser.GetRoot().GetDirect("arr_mixed");
auto array_mixed_0 = parser.GetRoot().GetDirect("arr_mixed[0]");
auto array_mixed_1 = parser.GetRoot().GetDirect("arr_mixed[1]");
auto array_mixed_2 = parser.GetRoot().GetDirect("arr_mixed[2]");
auto array_mixed_3 = parser.GetRoot().GetDirect("arr_mixed[3]");
auto array_mixed_3_2 = parser.GetRoot().GetDirect("arr_mixed[3][1]");
auto array_mixed_4 = parser.GetRoot().GetDirect("arr_mixed[4]");
auto array_mixed_4_pi = parser.GetRoot().GetDirect("arr_mixed[4].pi");
auto array_mixed_5 = parser.GetRoot().GetDirect("arr_mixed[5]");
auto array_mixed_6 = parser.GetRoot().GetDirect("arr_mixed[6]");
auto array_mixed = parser.Root().Direct("arr_mixed");
auto array_mixed_0 = parser.Root().Direct("arr_mixed[0]");
auto array_mixed_1 = parser.Root().Direct("arr_mixed[1]");
auto array_mixed_2 = parser.Root().Direct("arr_mixed[2]");
auto array_mixed_3 = parser.Root().Direct("arr_mixed[3]");
auto array_mixed_3_1 = parser.Root().Direct("arr_mixed[3][0]");
auto array_mixed_3_2 = parser.Root().Direct("arr_mixed[3][1]");
auto array_mixed_4 = parser.Root().Direct("arr_mixed[4]");
auto array_mixed_4_pi = parser.Root().Direct("arr_mixed[4].pi");
auto array_mixed_4_e = parser.Root().Direct("arr_mixed[4].e");
auto array_mixed_5 = parser.Root().Direct("arr_mixed[5]");
auto array_mixed_6 = parser.Root().Direct("arr_mixed[6]");
EXPECT_EQ(array_mixed->GetType(), sdv::toml::ENodeType::node_array);
ASSERT_NE(array_mixed_0, nullptr);
EXPECT_EQ(array_mixed_0->GetType(), sdv::toml::ENodeType::node_floating_point);
EXPECT_EQ(array_mixed_0->GetValue(), 1.0);
EXPECT_EQ(array_mixed_0->GetIndex(), 0u);
ASSERT_NE(array_mixed_1, nullptr);
EXPECT_EQ(array_mixed_1->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_mixed_1->GetValue(), 2);
EXPECT_EQ(array_mixed_1->GetIndex(), 1u);
ASSERT_NE(array_mixed_2, nullptr);
EXPECT_EQ(array_mixed_2->GetType(), sdv::toml::ENodeType::node_string);
EXPECT_EQ(static_cast<std::string>(array_mixed_2->GetValue()), "test string");
EXPECT_EQ(array_mixed_2->GetIndex(), 2u);
ASSERT_NE(array_mixed_3, nullptr);
EXPECT_EQ(array_mixed_3->GetType(), sdv::toml::ENodeType::node_array);
EXPECT_EQ(array_mixed_3->GetIndex(), 3u);
EXPECT_EQ(array_mixed_3_1->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_mixed_3_1->GetValue(), 1);
EXPECT_EQ(array_mixed_3_1->GetIndex(), 0u);
EXPECT_EQ(array_mixed_3_2->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(array_mixed_3_2->GetValue(), 2);
EXPECT_EQ(array_mixed_3_2->GetIndex(), 1u);
ASSERT_NE(array_mixed_4, nullptr);
EXPECT_EQ(array_mixed_4->GetType(), sdv::toml::ENodeType::node_table);
EXPECT_EQ(array_mixed_4->GetIndex(), 4u);
EXPECT_EQ(array_mixed_4_pi->GetType(), sdv::toml::ENodeType::node_floating_point);
EXPECT_EQ(array_mixed_4_pi->GetValue(), 3.14);
EXPECT_EQ(array_mixed_4_pi->GetIndex(), 0u);
EXPECT_EQ(array_mixed_4_e->GetType(), sdv::toml::ENodeType::node_floating_point);
EXPECT_EQ(array_mixed_4_e->GetValue(), 2.71828);
EXPECT_EQ(array_mixed_4_e->GetIndex(), 1u);
ASSERT_NE(array_mixed_5, nullptr);
EXPECT_EQ(array_mixed_5->GetType(), sdv::toml::ENodeType::node_boolean);
EXPECT_EQ(array_mixed_5->GetValue(), true);
EXPECT_EQ(array_mixed_5->GetValue(), sdv::any_t());
EXPECT_EQ(array_mixed_5->GetIndex(), 5u);
EXPECT_EQ(array_mixed_6, nullptr);
}
{
auto array_multiline = parser.GetRoot().GetDirect("arr_multiline");
auto array_multiline_0 = parser.GetRoot().GetDirect("arr_multiline[0]");
auto array_multiline_1 = parser.GetRoot().GetDirect("arr_multiline[1]");
auto array_multiline_2 = parser.GetRoot().GetDirect("arr_multiline[2]");
auto array_multiline_3 = parser.GetRoot().GetDirect("arr_multiline[3]");
auto array_multiline = parser.Root().Direct("arr_multiline");
auto array_multiline_0 = parser.Root().Direct("arr_multiline[0]");
auto array_multiline_1 = parser.Root().Direct("arr_multiline[1]");
auto array_multiline_2 = parser.Root().Direct("arr_multiline[2]");
auto array_multiline_3 = parser.Root().Direct("arr_multiline[3]");
EXPECT_EQ(array_multiline->GetType(), sdv::toml::ENodeType::node_array);
ASSERT_NE(array_multiline_0, nullptr);
EXPECT_EQ(array_multiline_0->GetType(), sdv::toml::ENodeType::node_string);
EXPECT_EQ(static_cast<std::string>(array_multiline_0->GetValue()), "first line");
EXPECT_EQ(array_multiline_0->GetIndex(), 0u);
ASSERT_NE(array_multiline_1, nullptr);
EXPECT_EQ(array_multiline_1->GetType(), sdv::toml::ENodeType::node_string);
EXPECT_EQ(static_cast<std::string>(array_multiline_1->GetValue()), "second line");
EXPECT_EQ(array_multiline_1->GetIndex(), 1u);
ASSERT_NE(array_multiline_2, nullptr);
EXPECT_EQ(array_multiline_2->GetType(), sdv::toml::ENodeType::node_string);
EXPECT_EQ(static_cast<std::string>(array_multiline_2->GetValue()), "third_line");
EXPECT_EQ(array_multiline_2->GetIndex(), 2u);
EXPECT_EQ(array_multiline_3, nullptr);
}
}
@@ -240,7 +283,7 @@ TEST(NestedContent, Array)
TEST(NestedContent, Table)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
[table]
a = 2
b = 1.2
@@ -252,12 +295,12 @@ TEST(NestedContent, Table)
d = []
)"s);
auto table_a = parser.GetRoot().GetDirect("table.a");
auto table_b = parser.GetRoot().GetDirect("table.b");
auto anotherTable_a = parser.GetRoot().GetDirect("anotherTable.a");
auto anotherTable_c = parser.GetRoot().GetDirect("anotherTable.c");
auto fourthTable_a = parser.GetRoot().GetDirect("thirdTable.fourthTable.a");
auto fourthTable_d = parser.GetRoot().GetDirect("thirdTable.fourthTable.d");
auto table_a = parser.Root().Direct("table.a");
auto table_b = parser.Root().Direct("table.b");
auto anotherTable_a = parser.Root().Direct("anotherTable.a");
auto anotherTable_c = parser.Root().Direct("anotherTable.c");
auto fourthTable_a = parser.Root().Direct("thirdTable.fourthTable.a");
auto fourthTable_d = parser.Root().Direct("thirdTable.fourthTable.d");
ASSERT_NE(table_a, nullptr);
EXPECT_EQ(table_a->GetType(), sdv::toml::ENodeType::node_integer);
@@ -281,7 +324,7 @@ TEST(NestedContent, Table)
TEST(NestedContent, TableArray)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
[[table.test]]
a = 2
b = 1.2
@@ -293,53 +336,59 @@ TEST(NestedContent, TableArray)
d = []
)"s);
auto table_test_1_a = parser.GetRoot().GetDirect("table.test[0].a");
auto table_test_1_b = parser.GetRoot().GetDirect("table.test[0].b");
auto table_test_2_a = parser.GetRoot().GetDirect("table.test[1].a");
auto table_test_2_c = parser.GetRoot().GetDirect("table.test[1].c");
auto table_test_3_a = parser.GetRoot().GetDirect("table.test[2].a");
auto table_test_3_d = parser.GetRoot().GetDirect("table.test[2].d");
auto table_test_1_a = parser.Root().Direct("table.test[0].a");
auto table_test_1_b = parser.Root().Direct("table.test[0].b");
auto table_test_2_a = parser.Root().Direct("table.test[1].a");
auto table_test_2_c = parser.Root().Direct("table.test[1].c");
auto table_test_3_a = parser.Root().Direct("table.test[2].a");
auto table_test_3_d = parser.Root().Direct("table.test[2].d");
ASSERT_NE(table_test_1_a, nullptr);
EXPECT_EQ(table_test_1_a->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(table_test_1_a->GetValue(), 2);
EXPECT_EQ(table_test_1_a->GetIndex(), 0u);
ASSERT_NE(table_test_1_b, nullptr);
EXPECT_EQ(table_test_1_b->GetType(), sdv::toml::ENodeType::node_floating_point);
EXPECT_EQ(table_test_1_b->GetValue(), 1.2);
EXPECT_EQ(table_test_1_b->GetIndex(), 1u);
ASSERT_NE(table_test_2_a, nullptr);
EXPECT_EQ(table_test_2_a->GetType(), sdv::toml::ENodeType::node_integer);
EXPECT_EQ(table_test_2_a->GetValue(), 4);
EXPECT_EQ(table_test_2_a->GetIndex(), 0u);
ASSERT_NE(table_test_2_c, nullptr);
EXPECT_EQ(table_test_2_c->GetType(), sdv::toml::ENodeType::node_boolean);
EXPECT_EQ(table_test_2_c->GetValue(), false);
EXPECT_EQ(table_test_2_c->GetIndex(), 1u);
ASSERT_NE(table_test_3_a, nullptr);
EXPECT_EQ(table_test_3_a->GetType(), sdv::toml::ENodeType::node_string);
EXPECT_EQ(static_cast<std::string>(table_test_3_a->GetValue()), "five");
EXPECT_EQ(table_test_3_a->GetIndex(), 0u);
ASSERT_NE(table_test_3_d, nullptr);
EXPECT_EQ(table_test_3_d->GetType(), sdv::toml::ENodeType::node_array);
EXPECT_EQ(table_test_3_d->GetIndex(), 1u);
}
TEST(NestedContent, InlineTable)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
table1 = { a = 0, b = 1.2, c = "string" }
table2 = { a = [], b = true, e = 2.71828 }
table3 = { a = { a = "a", b = "A" }, b = {a = "b", b = "B"}, e = {a = "e", b = "E"} }
)"s);
auto table1_a = parser.GetRoot().GetDirect("table1.a");
auto table1_b = parser.GetRoot().GetDirect("table1.b");
auto table1_c = parser.GetRoot().GetDirect("table1.c");
auto table2_a = parser.GetRoot().GetDirect("table2.a");
auto table2_b = parser.GetRoot().GetDirect("table2.b");
auto table2_e = parser.GetRoot().GetDirect("table2.e");
auto table3_a_a = parser.GetRoot().GetDirect("table3.a.a");
auto table3_a_b = parser.GetRoot().GetDirect("table3.a.b");
auto table3_b_a = parser.GetRoot().GetDirect("table3.b.a");
auto table3_b_b = parser.GetRoot().GetDirect("table3.b.b");
auto table3_e_a = parser.GetRoot().GetDirect("table3.e.a");
auto table3_e_b = parser.GetRoot().GetDirect("table3.e.b");
auto table1_a = parser.Root().Direct("table1.a");
auto table1_b = parser.Root().Direct("table1.b");
auto table1_c = parser.Root().Direct("table1.c");
auto table2_a = parser.Root().Direct("table2.a");
auto table2_b = parser.Root().Direct("table2.b");
auto table2_e = parser.Root().Direct("table2.e");
auto table3_a_a = parser.Root().Direct("table3.a.a");
auto table3_a_b = parser.Root().Direct("table3.a.b");
auto table3_b_a = parser.Root().Direct("table3.b.a");
auto table3_b_b = parser.Root().Direct("table3.b.b");
auto table3_e_a = parser.Root().Direct("table3.e.a");
auto table3_e_b = parser.Root().Direct("table3.e.b");
ASSERT_NE(table1_a, nullptr);
EXPECT_EQ(table1_a->GetType(), sdv::toml::ENodeType::node_integer);
@@ -381,7 +430,7 @@ TEST(NestedContent, InlineTable)
TEST(SpecialCases, Keys)
{
using namespace std::string_literals;
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
@@ -389,21 +438,21 @@ TEST(SpecialCases, Keys)
'quoted "value"' = "value"
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
key = "value"
bare_key = "value"
bare-key = "value"
1234 = "value"
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
"" = "blank" # VALID but discouraged
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
'' = 'blank' # VALID but discouraged
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
name = "Orange"
physical.color = "orange"
physical.shape = "round"
@@ -411,20 +460,20 @@ TEST(SpecialCases, Keys)
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
fruit.name = "banana" # this is best practice
fruit. color = "yellow" # same as fruit.color
fruit . flavor = "banana" # same as fruit.flavor
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
# This makes the key "fruit" into a table.
fruit.apple.smooth = true
# So then you can add to the table "fruit" like so:
fruit.orange = 2
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
# VALID BUT DISCOURAGED
apple.type = "fruit"
orange.type = "fruit"
@@ -434,15 +483,15 @@ TEST(SpecialCases, Keys)
orange.color = "orange"
)"s));
EXPECT_NO_THROW(CParserTOML(R"(
EXPECT_NO_THROW(toml_parser::CParser(R"(
3.1415 = 3.1415
)"s));
{
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
3.1415 = 3.1415
)"s);
auto table = parser.GetRoot().GetDirect("3");
auto pi = parser.GetRoot().GetDirect("3.1415");
auto table = parser.Root().Direct("3");
auto pi = parser.Root().Direct("3.1415");
ASSERT_NE(table, nullptr);
EXPECT_EQ(table->GetType(), sdv::toml::ENodeType::node_table);
ASSERT_NE(pi, nullptr);
@@ -454,7 +503,7 @@ TEST(SpecialCases, Keys)
TEST(SpecialCases, Arrays)
{
using namespace std::string_literals;
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
integers = [ 1, 2, 3 ]
colors = [ "red", "yellow", "green" ]
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
@@ -462,7 +511,7 @@ TEST(SpecialCases, Arrays)
string_array = [ "all", 'strings', """are the same""", '''type''' ]
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
contributors = [
"Foo Bar <foo@example.com>",
@@ -470,7 +519,7 @@ TEST(SpecialCases, Arrays)
]
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
integers3 = [
1,
2, # this is ok
@@ -481,7 +530,7 @@ TEST(SpecialCases, Arrays)
TEST(SpecialCases, Tables)
{
using namespace std::string_literals;
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
[table-1]
key1 = "some string"
key2 = 123
@@ -491,19 +540,19 @@ TEST(SpecialCases, Tables)
key2 = 456
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
[dog."tater.man"]
type.name = "pug"
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
[a.b.c] # this is best practice
[ d.e.f ] # same as [d.e.f]
[ g . h . i ] # same as [g.h.i]
[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
# [x] you
# [x.y] don't
# [x.y.z] need these
@@ -511,14 +560,14 @@ TEST(SpecialCases, Tables)
[x] # defining a super-table afterward is ok
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
# VALID BUT DISCOURAGED
[fruit.apple]
[animal]
[fruit.orange]
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
[fruit]
apple.color = "red"
apple.taste.sweet = true
@@ -529,7 +578,7 @@ TEST(SpecialCases, Tables)
TEST(SpecialCases, TableArrays)
{
using namespace std::string_literals;
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
[[products]]
name = "Hammer"
sku = 738594937
@@ -540,7 +589,7 @@ TEST(SpecialCases, TableArrays)
color = "gray"
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
[[fruits]]
name = "apple"
[fruits.physical] # subtable
@@ -556,7 +605,7 @@ TEST(SpecialCases, TableArrays)
name = "plantain"
)"s));
EXPECT_NO_THROW(CParserTOML parser(R"(
EXPECT_NO_THROW(toml_parser::CParser parser(R"(
points = [ { x = 1, y = 2, z = 3 },
{ x = 7, y = 8, z = 9 },
{ x = 2, y = 4, z = 8 } ]
@@ -566,32 +615,32 @@ TEST(SpecialCases, TableArrays)
TEST(ErrorCases, KeyValue)
{
using namespace std::string_literals;
EXPECT_THROW(CParserTOML parser(R"(key = # node_invalid)"s), sdv::toml::XTOMLParseException);
EXPECT_THROW(toml_parser::CParser parser(R"(key = # node_invalid)"s), sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(first = "Tom" last = "Preston-Werner" # node_invalid)"s), sdv::toml::XTOMLParseException);
EXPECT_THROW(toml_parser::CParser parser(R"(first = "Tom" last = "Preston-Werner" # node_invalid)"s), sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(= "no key name" # node_invalid)"s), sdv::toml::XTOMLParseException);
EXPECT_THROW(toml_parser::CParser parser(R"(= "no key name" # node_invalid)"s), sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
name = "Tom"
name = "Pradyun"
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML(R"(
EXPECT_THROW(toml_parser::CParser(R"(
fruit . flavor = "banana" # same as fruit.flavor
fruit.flavor = "banana"
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML(R"(
EXPECT_THROW(toml_parser::CParser(R"(
spelling = "favorite"
"spelling" = "favourite"
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML(R"(
EXPECT_THROW(toml_parser::CParser(R"(
# This defines the value of fruit.apple to be an integer.
fruit.apple = 1
# But then this treats fruit.apple like it's a table.
@@ -604,13 +653,19 @@ TEST(ErrorCases, KeyValue)
TEST(ErrorCases, Tables)
{
using namespace std::string_literals;
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[ j . "ʞ" . 'l' ]
[j."ʞ".'l']
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[ j . "ʞ" . 'l' ]
["j".'ʞ'."l"]
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(toml_parser::CParser parser(R"(
[fruit]
apple = "red"
[fruit]
@@ -618,7 +673,7 @@ TEST(ErrorCases, Tables)
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[fruit]
apple = "red"
[fruit.apple]
@@ -626,14 +681,14 @@ TEST(ErrorCases, Tables)
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[fruit]
apple.color = "red"
apple.taste.sweet = true
[fruit.apple] # INVALID
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[fruit]
apple.color = "red"
apple.taste.sweet = true
@@ -646,12 +701,12 @@ TEST(ErrorCases, InlineTables)
{
using namespace std::string_literals;
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
type = { name = "Nail" }
type.edible = false # INVALID
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[product]
type.name = "Nail"
type = { edible = false } # INVALID
@@ -662,7 +717,7 @@ TEST(ErrorCases, InlineTables)
TEST(ErrorCases, TableArrays)
{
using namespace std::string_literals;
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[fruit.physical] # subtable, but to which parent element should it belong?
color = "red"
shape = "round"
@@ -672,13 +727,13 @@ TEST(ErrorCases, TableArrays)
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
fruits = []
[[fruits]] # Not allowed
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[[fruits]]
name = "apple"
[[fruits.varieties]]
@@ -688,7 +743,7 @@ TEST(ErrorCases, TableArrays)
name = "granny smith"
)"s),
sdv::toml::XTOMLParseException);
EXPECT_THROW(CParserTOML parser(R"(
EXPECT_THROW(toml_parser::CParser parser(R"(
[[fruits]]
name = "apple"
[fruits.physical]
@@ -704,13 +759,13 @@ TEST(ErrorCases, TableArrays)
TEST(Ordering, Array)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
)"s);
auto two = parser.GetRoot().GetDirect("array[2]");
auto eleven = parser.GetRoot().GetDirect("array[11]");
const auto arr = parser.GetRoot().GetDirect("array");
auto two = parser.Root().Direct("array[2]");
auto eleven = parser.Root().Direct("array[11]");
const auto arr = parser.Root().Direct("array");
// with direct access
ASSERT_NE(two, nullptr);
@@ -720,7 +775,7 @@ TEST(Ordering, Array)
// with indirect access through iterating
ASSERT_NE(arr, nullptr);
auto ptrArray = arr->GetArray();
auto ptrArray = arr->Cast<toml_parser::CArray>();
EXPECT_EQ(ptrArray->GetCount(), 12u);
for (uint32_t uiIndex = 0; uiIndex < ptrArray->GetCount(); uiIndex++)
EXPECT_EQ(ptrArray->Get(uiIndex)->GetValue(), (int64_t)uiIndex);
@@ -729,7 +784,7 @@ TEST(Ordering, Array)
TEST(Ordering, TableAray)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
[[tableArray]]
a = 0
[[tableArray]]
@@ -756,19 +811,19 @@ TEST(Ordering, TableAray)
a = 11
)"s);
auto tableArray = parser.GetRoot().GetDirect("tableArray");
auto tableArray = parser.Root().Direct("tableArray");
ASSERT_NE(tableArray, nullptr);
auto ptrArray = tableArray->GetArray();
auto ptrArray = tableArray->Cast<toml_parser::CArray>();
EXPECT_EQ(ptrArray->GetCount(), 12u);
for (uint32_t uiIndex = 0; uiIndex < ptrArray->GetCount(); uiIndex++)
EXPECT_EQ(ptrArray->Get(uiIndex)->GetTable()->Find("a")->GetValue(), (int64_t) uiIndex);
EXPECT_EQ(ptrArray->Get(uiIndex)->Cast<toml_parser::CTable>()->Direct("a")->GetValue(), (int64_t) uiIndex);
}
TEST(Ordering, NodeGetDirect)
{
using namespace std::string_literals;
CParserTOML parser(R"(
toml_parser::CParser parser(R"(
[[table.test]]
a = 2
b = 1.2
@@ -782,18 +837,89 @@ TEST(Ordering, NodeGetDirect)
{ x = 2, y = 4, z = 8 }]
)"s);
auto table_test_1_a = parser.GetRoot().GetDirect("table.test[0].a");
auto table_test_1_b = parser.GetRoot().GetDirect("table.test[0].b");
auto table_test_2_a = parser.GetRoot().GetDirect("table.test[1].a");
auto table_test_2_c = parser.GetRoot().GetDirect("table.test[1].c");
auto table_test_3_a = parser.GetRoot().GetDirect("table.test[2].a");
auto table_test_3_d = parser.GetRoot().GetDirect("table.test[2].d");
auto table_test_1_a = parser.Root().Direct("table.test[0].a");
auto table_test_1_b = parser.Root().Direct("table.test[0].b");
auto table_test_2_a = parser.Root().Direct("table.test[1].a");
auto table_test_2_c = parser.Root().Direct("table.test[1].c");
auto table_test_3_a = parser.Root().Direct("table.test[2].a");
auto table_test_3_d = parser.Root().Direct("table.test[2].d");
EXPECT_TRUE(table_test_1_a);
EXPECT_TRUE(table_test_1_b);
EXPECT_EQ(table_test_3_d->GetType(), sdv::toml::ENodeType::node_array);
auto table_test_3 = parser.GetRoot().GetDirect("table.test[2]");
auto table_test_3_2nd = table_test_3->GetTable()->GetNodeDirect("d[2].x");
auto table_test_3 = parser.Root().Direct("table.test[2]");
auto table_test_3_2nd = table_test_3->Cast<toml_parser::CTable>()->GetNodeDirect("d[2].x");
EXPECT_NE(table_test_3_2nd, nullptr);
}
}
TEST(NodeAccess, Parent)
{
using namespace std::string_literals;
toml_parser::CParser parser(R"(
[[table.test]]
a = 2
b = 1.2
[[table.test]]
a = 4
c = false
[[table.test]]
a = "five"
d = [ { x = 1, y = 2, z = 3 },
{ x = 7, y = 8, z = 9 },
{ x = 2, y = 4, z = 8 }]
)"s);
auto fnGetName = [](sdv::IInterfaceAccess* pNode) -> std::string
{
sdv::toml::INodeInfo* pNodeInfo = sdv::TInterfaceAccessPtr(pNode).GetInterface<sdv::toml::INodeInfo>();
if (!pNodeInfo) return {};
return pNodeInfo->GetPath(true);
};
auto root = &parser.Root();
auto table = parser.Root().Direct("table");
ASSERT_TRUE(table);
EXPECT_EQ(table->GetParent(), root);
EXPECT_EQ(fnGetName(table->GetParent()), "");
auto table_test = parser.Root().Direct("table.test");
ASSERT_TRUE(table_test);
EXPECT_EQ(table_test->GetParent(), table.get());
EXPECT_EQ(fnGetName(table_test->GetParent()), "table");
auto table_test_1 = parser.Root().Direct("table.test[0]");
ASSERT_TRUE(table_test_1);
EXPECT_EQ(table_test_1->GetParent(), table_test.get());
EXPECT_EQ(fnGetName(table_test_1->GetParent()), "table.test");
auto table_test_1_a = parser.Root().Direct("table.test[0].a");
ASSERT_TRUE(table_test_1_a);
EXPECT_EQ(table_test_1_a->GetParent(), table_test_1.get());
EXPECT_EQ(fnGetName(table_test_1_a->GetParent()), "table.test[0]");
auto table_test_1_b = parser.Root().Direct("table.test[0].b");
ASSERT_TRUE(table_test_1_b);
EXPECT_EQ(table_test_1_b->GetParent(), table_test_1.get());
EXPECT_EQ(fnGetName(table_test_1_b->GetParent()), "table.test[0]");
auto table_test_2 = parser.Root().Direct("table.test[1]");
ASSERT_TRUE(table_test_2);
EXPECT_EQ(table_test_2->GetParent(), table_test.get());
EXPECT_EQ(fnGetName(table_test_2->GetParent()), "table.test");
auto table_test_2_a = parser.Root().Direct("table.test[1].a");
ASSERT_TRUE(table_test_2_a);
EXPECT_EQ(table_test_2_a->GetParent(), table_test_2.get());
EXPECT_EQ(fnGetName(table_test_2_a->GetParent()), "table.test[1]");
auto table_test_2_c = parser.Root().Direct("table.test[1].c");
ASSERT_TRUE(table_test_2_c);
EXPECT_EQ(table_test_2_c->GetParent(), table_test_2.get());
EXPECT_EQ(fnGetName(table_test_2_c->GetParent()), "table.test[1]");
auto table_test_3 = parser.Root().Direct("table.test[2]");
ASSERT_TRUE(table_test_3);
EXPECT_EQ(table_test_3->GetParent(), table_test.get());
EXPECT_EQ(fnGetName(table_test_3->GetParent()), "table.test");
auto table_test_3_a = parser.Root().Direct("table.test[2].a");
ASSERT_TRUE(table_test_3_a);
EXPECT_EQ(table_test_3_a->GetParent(), table_test_3.get());
EXPECT_EQ(fnGetName(table_test_3_a->GetParent()), "table.test[2]");
auto table_test_3_d = parser.Root().Direct("table.test[2].d");
ASSERT_TRUE(table_test_3_d);
EXPECT_EQ(table_test_3_d->GetParent(), table_test_3.get());
EXPECT_EQ(fnGetName(table_test_3_d->GetParent()), "table.test[2]");
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
#include <vector>
#include <list>
#include <deque>
#include <atomic>
TEST(TraceFifoTest, Connect_Disconnect)
{
@@ -190,7 +191,7 @@ TEST(TraceFifoTest, Simple_Publish_Monitor)
EXPECT_TRUE(fifoReader.IsOpened());
std::vector<std::string> vecSent, vecReceived;
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::thread thread([&]()
@@ -238,7 +239,7 @@ TEST(TraceFifoTest, Simple_Publish_Monitor_Multi)
EXPECT_TRUE(fifoReader2.IsOpened());
std::vector<std::string> vecSent, vecReceived1, vecReceived2;
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::thread thread1([&]()
@@ -297,7 +298,7 @@ TEST(TraceFifoTest, Simple_Publish_Beyond_Buffer_With_Reading)
EXPECT_TRUE(fifoReader.IsOpened());
std::vector<std::string> vecSent, vecReceived;
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::thread thread([&]()
@@ -410,7 +411,7 @@ TEST(TraceFifoTest, Simple_Stream_Monitor)
EXPECT_TRUE(fifoReader.Open());
EXPECT_TRUE(fifoReader.IsOpened());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::stringstream sstreamReader;
@@ -456,7 +457,7 @@ TEST(TraceFifoTest, Simple_Multi_Stream_Monitor)
EXPECT_TRUE(fifoReader.Open());
EXPECT_TRUE(fifoReader.IsOpened());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::stringstream sstreamReader;
@@ -513,7 +514,7 @@ TEST(TraceFifoTest, Simple_Std_Stream_Monitor)
EXPECT_TRUE(fifoReader.Open());
EXPECT_TRUE(fifoReader.IsOpened());
bool bShutdown = false;
std::atomic_bool bShutdown = false;
// Start receiving thread until shutdown flag is set.
std::stringstream sstreamReader;