mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-08-31 04:35:11 +00:00
connection between 2 systems and bug fixes (#14)
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
/**
|
||||
- Default instantiate listener
|
||||
- Instantiate with specific info
|
||||
- Multiple instantiate with identical info (failure)
|
||||
- Multiple instantiate with different info
|
||||
- Default instantiate client and get connection information
|
||||
- */
|
||||
@@ -12,22 +12,22 @@
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project (UnitTest_App_Connect VERSION 1.0 LANGUAGES CXX)
|
||||
project (UnitTest_App_Settings VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Compile the source code
|
||||
add_executable(UnitTest_App_Connect
|
||||
add_executable(UnitTest_App_Settings
|
||||
"main.cpp"
|
||||
"app_connect_local.cpp")
|
||||
target_link_libraries(UnitTest_App_Connect ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
"startup_config.cpp" "settings_config.cpp")
|
||||
target_link_libraries(UnitTest_App_Settings ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the IDL Compiler unittest
|
||||
add_test(NAME UnitTest_App_Connect COMMAND UnitTest_App_Connect)
|
||||
add_test(NAME UnitTest_App_Settings COMMAND UnitTest_App_Settings)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_App_Connect POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_App_Connect>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_App_Connect.xml
|
||||
add_custom_command(TARGET UnitTest_App_Settings POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_App_Settings>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_App_Settings.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(UnitTest_App_Connect dependency_sdv_components)
|
||||
add_dependencies(UnitTest_App_Settings dependency_sdv_components)
|
||||
41
tests/unit_tests/app_settings/main.cpp
Normal file
41
tests/unit_tests/app_settings/main.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/app_settings.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/lexer_toml.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/lexer_toml_token.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/code_snippet.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_indexer.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
*/
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
CLocalMemMgr memmgr;
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
537
tests/unit_tests/app_settings/settings_config.cpp
Normal file
537
tests/unit_tests/app_settings/settings_config.cpp
Normal file
@@ -0,0 +1,537 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "../../../sdv_services/core/app_settings.h"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include <support/toml.h>
|
||||
|
||||
// Load settings
|
||||
// Invalid file
|
||||
// No file
|
||||
// Config paths
|
||||
// Listeners
|
||||
// Connections
|
||||
// Save settings
|
||||
// No file
|
||||
// Config paths
|
||||
// Listeners
|
||||
// Connections
|
||||
|
||||
std::filesystem::path GetSettingsFilePath()
|
||||
{
|
||||
// The settings file is located at the exe directory with sub-directory 2000.
|
||||
return GetExecDirectory() / "2000" / "settings.toml";
|
||||
}
|
||||
|
||||
toml_parser::CParser ReadSettingsFile()
|
||||
{
|
||||
std::ifstream fstream(GetSettingsFilePath());
|
||||
if (!fstream.is_open()) return {};
|
||||
toml_parser::CParser parser(std::string((std::istreambuf_iterator<char>(fstream)), std::istreambuf_iterator<char>()));
|
||||
fstream.close();
|
||||
return parser;
|
||||
}
|
||||
|
||||
bool WriteSettingsFile(const std::string& rssSettings)
|
||||
{
|
||||
std::filesystem::create_directories(GetSettingsFilePath().remove_filename());
|
||||
std::ofstream fstream(GetSettingsFilePath(), std::ios::trunc);
|
||||
if (!fstream.is_open()) return false;
|
||||
fstream << rssSettings;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeleteSettingsFile()
|
||||
{
|
||||
if (std::filesystem::exists(GetSettingsFilePath().remove_filename()))
|
||||
std::filesystem::remove_all(GetSettingsFilePath().remove_filename());
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, LoadInvalidConfig)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
const std::string ssInvalidToml = R"toml([Settings]
|
||||
Version = hundred # Should be valid number)toml";
|
||||
const std::string ssInvalidValue = R"toml([Settings]
|
||||
Version = "hundred" # Invalid value)toml";
|
||||
const std::string ssInvalidVersion = R"toml([Settings]
|
||||
Version = 99)toml";
|
||||
const std::string ssNoVersion = R"toml([Settings])toml";
|
||||
|
||||
WriteSettingsFile(ssInvalidToml);
|
||||
EXPECT_FALSE(settings.LoadSettings());
|
||||
WriteSettingsFile(ssInvalidValue);
|
||||
EXPECT_FALSE(settings.LoadSettings());
|
||||
WriteSettingsFile(ssInvalidVersion);
|
||||
EXPECT_FALSE(settings.LoadSettings());
|
||||
WriteSettingsFile(ssNoVersion);
|
||||
EXPECT_FALSE(settings.LoadSettings());
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, LoadNoConfig)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
// Read empty file - this is not an error
|
||||
EXPECT_TRUE(settings.LoadSettings());
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, SaveConfigWrongMode)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify for a file
|
||||
EXPECT_FALSE(std::filesystem::exists(GetSettingsFilePath()));
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, SaveDefaultConfig)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify for a file
|
||||
EXPECT_TRUE(std::filesystem::exists(GetSettingsFilePath()));
|
||||
|
||||
// Verify settings
|
||||
auto parser = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings(parser.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings);
|
||||
EXPECT_EQ(tableSettings.GetDirect("Version").GetValue(), 100u);
|
||||
sdv::toml::CNode nodePlatformConfig = tableSettings.GetDirect("PlatformConfig");
|
||||
EXPECT_TRUE(nodePlatformConfig);
|
||||
sdv::toml::CNode nodeVehIfcConfig = tableSettings.GetDirect("VehIfcConfig");
|
||||
EXPECT_TRUE(nodeVehIfcConfig);
|
||||
sdv::toml::CNode nodeVehAbstrConfig = tableSettings.GetDirect("VehAbstrConfig");
|
||||
EXPECT_TRUE(nodeVehAbstrConfig);
|
||||
sdv::toml::CNode nodeAppConfig = tableSettings.GetDirect("AppConfig");
|
||||
EXPECT_TRUE(nodeAppConfig);
|
||||
sdv::toml::CNodeCollection arrayListener = tableSettings.GetDirect("Listener");
|
||||
EXPECT_FALSE(arrayListener);
|
||||
sdv::toml::CNodeCollection arrayConnection = tableSettings.GetDirect("Connection");
|
||||
EXPECT_FALSE(arrayConnection);
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, LoadSettings_SystemConfigs)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::platform_config), "platform.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_interface_config), "vehicle_ifc.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_abstraction_config), "vehicle_abstract.toml");
|
||||
|
||||
WriteSettingsFile(R"toml([Settings]
|
||||
Version = 100
|
||||
PlatformConfig = "abc.toml"
|
||||
VehIfcConfig = "def.toml"
|
||||
VehAbstrConfig = "ghi.toml")toml");
|
||||
|
||||
// Read settings file
|
||||
EXPECT_TRUE(settings.LoadSettings());
|
||||
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::platform_config), "abc.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_interface_config), "def.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_abstraction_config), "ghi.toml");
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, SaveSettings_SystemConfigs)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::platform_config), "platform.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_interface_config), "vehicle_ifc.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_abstraction_config), "vehicle_abstract.toml");
|
||||
settings.DisableConfig(CAppSettings::EConfigType::platform_config);
|
||||
settings.DisableConfig(CAppSettings::EConfigType::vehicle_interface_config);
|
||||
settings.DisableConfig(CAppSettings::EConfigType::vehicle_abstraction_config);
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::platform_config), "");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_interface_config), "");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_abstraction_config), "");
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings(parser.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings);
|
||||
EXPECT_TRUE(tableSettings.GetDirect("PlatformConfig").GetValueAsPath().empty());
|
||||
EXPECT_TRUE(tableSettings.GetDirect("VehIfcConfig").GetValueAsPath().empty());
|
||||
EXPECT_TRUE(tableSettings.GetDirect("VehAbstrConfig").GetValueAsPath().empty());
|
||||
|
||||
settings.EnableConfig(CAppSettings::EConfigType::platform_config);
|
||||
settings.EnableConfig(CAppSettings::EConfigType::vehicle_interface_config);
|
||||
settings.EnableConfig(CAppSettings::EConfigType::vehicle_abstraction_config);
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::platform_config), "platform.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_interface_config), "vehicle_ifc.toml");
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::vehicle_abstraction_config), "vehicle_abstract.toml");
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser2 = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings2(parser2.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings2);
|
||||
EXPECT_EQ(tableSettings2.GetDirect("PlatformConfig").GetValueAsPath(), "platform.toml");
|
||||
EXPECT_EQ(tableSettings2.GetDirect("VehIfcConfig").GetValueAsPath(), "vehicle_ifc.toml");
|
||||
EXPECT_EQ(tableSettings2.GetDirect("VehAbstrConfig").GetValueAsPath(), "vehicle_abstract.toml");
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, LoadSettings_UserConfig)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::user_config), "app_config.toml");
|
||||
|
||||
WriteSettingsFile(R"toml([Settings]
|
||||
Version = 100
|
||||
AppConfig = "xyz.toml")toml");
|
||||
|
||||
// Read settings file
|
||||
EXPECT_TRUE(settings.LoadSettings());
|
||||
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::user_config), "xyz.toml");
|
||||
|
||||
settings.Reset();
|
||||
|
||||
// For all configurations except main, isolated and maintenance, the user config is supplied through the app config.
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Standalone"
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string()) + R"toml(
|
||||
Config = "klm.toml")toml"));
|
||||
|
||||
EXPECT_EQ(settings.GetUserConfigPath(), "klm.toml");
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, SaveSettings_UserConfig)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::user_config), "app_config.toml");
|
||||
settings.DisableConfig(CAppSettings::EConfigType::user_config);
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::user_config), "");
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings(parser.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings);
|
||||
EXPECT_TRUE(tableSettings.GetDirect("AppConfig").GetValueAsPath().empty());
|
||||
|
||||
settings.EnableConfig(CAppSettings::EConfigType::user_config);
|
||||
EXPECT_EQ(settings.GetConfigPath(CAppSettings::EConfigType::user_config), "app_config.toml");
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser2 = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings2(parser2.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings2);
|
||||
EXPECT_EQ(tableSettings2.GetDirect("AppConfig").GetValueAsPath(), "app_config.toml");
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, LoadSettings_Listeners)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
// Default listener shoule be available.
|
||||
EXPECT_EQ(settings.GetListeners().size(), 1u);
|
||||
|
||||
WriteSettingsFile(R"toml([Settings]
|
||||
Version = 100
|
||||
|
||||
[[Settings.Listener]]
|
||||
Name = "MyListener1"
|
||||
[Settings.Listener.Provider]
|
||||
Name = "MyListenerProvider1"
|
||||
[Settings.Listener.IpcChannel]
|
||||
abc = "def"
|
||||
|
||||
[[Settings.Listener]]
|
||||
Name = "MyListener2"
|
||||
[Settings.Listener.Provider]
|
||||
Name = "MyListenerProvider2"
|
||||
[Settings.Listener.IpcChannel]
|
||||
xyz = 1234
|
||||
)toml");
|
||||
|
||||
// Read settings file - note: the listeners are part of a listener map. The order is not fixed.
|
||||
// There will be an additional default listener.
|
||||
EXPECT_TRUE(settings.LoadSettings());
|
||||
auto seqListeners = settings.GetListeners();
|
||||
ASSERT_EQ(seqListeners.size(), 3u);
|
||||
EXPECT_TRUE(seqListeners[0] == "MyListener1" || seqListeners[1] == "MyListener1" || seqListeners[2] == "MyListener1");
|
||||
EXPECT_TRUE(seqListeners[0] == "MyListener2" || seqListeners[1] == "MyListener2" || seqListeners[2] == "MyListener2");
|
||||
EXPECT_TRUE(seqListeners[0] == "Default" || seqListeners[1] == "Default" || seqListeners[2] == "Default");
|
||||
EXPECT_TRUE(settings.GetListenerConfig("MyListener0").empty());
|
||||
EXPECT_TRUE(toml_parser::CompareEqual(settings.GetListenerConfig("MyListener1"), R"toml([Provider]
|
||||
Name = "MyListenerProvider1"
|
||||
|
||||
[IpcChannel]
|
||||
abc = "def"
|
||||
)toml"));
|
||||
EXPECT_TRUE(toml_parser::CompareEqual(settings.GetListenerConfig("MyListener2"), R"toml([Provider]
|
||||
Name = "MyListenerProvider2"
|
||||
|
||||
[IpcChannel]
|
||||
xyz = 1234
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, SaveSettings_Listeners)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_EQ(settings.GetListeners().size(), 1u);
|
||||
|
||||
EXPECT_TRUE(settings.AddListenerConfig("MyListener2", R"toml([Provider]
|
||||
Name = "MyListenerProvider2"
|
||||
[IpcChannel]
|
||||
abc = "def")toml"));
|
||||
EXPECT_EQ(settings.GetListeners().size(), 2u);
|
||||
|
||||
EXPECT_TRUE(settings.AddListenerConfig("MyListener1", R"toml([Provider]
|
||||
Name = "MyListenerProvider1"
|
||||
[IpcChannel]
|
||||
xyz = 1234)toml"));
|
||||
EXPECT_EQ(settings.GetListeners().size(), 3u);
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings(parser.Root().GetNodeDirect("Settings"));
|
||||
[[maybe_unused]] std::string ss = parser.GenerateTOML();
|
||||
EXPECT_TRUE(tableSettings);
|
||||
sdv::toml::CNodeCollection tableListener = tableSettings.GetDirect("Listener[0]");
|
||||
if (tableListener.GetDirect("Name").GetValueAsString() != "MyListener1")
|
||||
tableListener = tableSettings.GetDirect("Listener[1]");
|
||||
EXPECT_TRUE(tableListener);
|
||||
EXPECT_EQ(tableListener.GetDirect("Name").GetValueAsString(), "MyListener1");
|
||||
EXPECT_EQ(tableListener.GetDirect("Provider.Name").GetValueAsString(), "MyListenerProvider1");
|
||||
EXPECT_EQ(tableListener.GetDirect("IpcChannel.xyz").GetValue(), 1234);
|
||||
tableListener = tableSettings.GetDirect("Listener[0]");
|
||||
if (tableListener.GetDirect("Name").GetValueAsString() != "MyListener2")
|
||||
tableListener = tableSettings.GetDirect("Listener[1]");
|
||||
EXPECT_TRUE(tableListener);
|
||||
EXPECT_EQ(tableListener.GetDirect("Name").GetValueAsString(), "MyListener2");
|
||||
EXPECT_EQ(tableListener.GetDirect("Provider.Name").GetValueAsString(), "MyListenerProvider2");
|
||||
EXPECT_EQ(tableListener.GetDirect("IpcChannel.abc").GetValueAsString(), "def");
|
||||
|
||||
// Remove one listener
|
||||
settings.RemoveListenerConfig("MyListener1");
|
||||
EXPECT_EQ(settings.GetListeners().size(), 2u);
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser2 = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings2(parser2.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings2);
|
||||
tableListener = tableSettings2.GetDirect("Listener[0]");
|
||||
EXPECT_TRUE(tableListener);
|
||||
EXPECT_EQ(tableListener.GetDirect("Name").GetValueAsString(), "MyListener2");
|
||||
EXPECT_EQ(tableListener.GetDirect("Provider.Name").GetValueAsString(), "MyListenerProvider2");
|
||||
EXPECT_EQ(tableListener.GetDirect("IpcChannel.abc").GetValueAsString(), "def");
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, LoadSettings_Connections)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
// Default connection only
|
||||
EXPECT_EQ(settings.GetConnections().size(), 1);
|
||||
|
||||
WriteSettingsFile(R"toml([Settings]
|
||||
Version = 100
|
||||
|
||||
[[Settings.Connection]]
|
||||
Name = "MyConnection1"
|
||||
[Settings.Connection.Provider]
|
||||
Name = "MyConnectionProvider1"
|
||||
[Settings.Connection.IpcChannel]
|
||||
abc = "def"
|
||||
|
||||
[[Settings.Connection]]
|
||||
Name = "MyConnection2"
|
||||
[Settings.Connection.Provider]
|
||||
Name = "MyConnectionProvider2"
|
||||
[Settings.Connection.IpcChannel]
|
||||
xyz = 1234
|
||||
)toml");
|
||||
|
||||
// Read settings file - note: the order of connections is preserved in the settings file.
|
||||
// There will be an additional default connection.
|
||||
EXPECT_TRUE(settings.LoadSettings());
|
||||
auto seqConnections = settings.GetConnections();
|
||||
ASSERT_EQ(seqConnections.size(), 3u);
|
||||
EXPECT_EQ(seqConnections[0], "Default");
|
||||
EXPECT_EQ(seqConnections[1], "MyConnection1");
|
||||
EXPECT_EQ(seqConnections[2], "MyConnection2");
|
||||
EXPECT_TRUE(settings.GetConnectionConfig("MyConnection0").empty());
|
||||
EXPECT_TRUE(toml_parser::CompareEqual(settings.GetConnectionConfig("MyConnection1"), R"toml([Provider]
|
||||
Name = "MyConnectionProvider1"
|
||||
|
||||
[IpcChannel]
|
||||
abc = "def"
|
||||
)toml"));
|
||||
EXPECT_TRUE(toml_parser::CompareEqual(settings.GetConnectionConfig("MyConnection2"), R"toml([Provider]
|
||||
Name = "MyConnectionProvider2"
|
||||
|
||||
[IpcChannel]
|
||||
xyz = 1234
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_SettingsConfig, SaveSettings_Connections)
|
||||
{
|
||||
// Settings for the main application with a specific instance ID
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
DeleteSettingsFile(); // Needed to prevent settings file parsing during startup.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
|
||||
EXPECT_EQ(settings.GetConnections().size(), 1u);
|
||||
|
||||
EXPECT_TRUE(settings.AddConnectionConfig("MyConnection2", R"toml([Provider]
|
||||
Name = "MyConnectionProvider2"
|
||||
[IpcChannel]
|
||||
abc = "def")toml"));
|
||||
EXPECT_EQ(settings.GetConnections().size(), 2u);
|
||||
|
||||
EXPECT_TRUE(settings.AddConnectionConfig("MyConnection1", R"toml([Provider]
|
||||
Name = "MyConnectionProvider1"
|
||||
[IpcChannel]
|
||||
xyz = 1234)toml"));
|
||||
EXPECT_EQ(settings.GetConnections().size(), 3u);
|
||||
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings(parser.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings);
|
||||
sdv::toml::CNodeCollection tableConnection = tableSettings.GetDirect("Connection[0]");
|
||||
EXPECT_TRUE(tableConnection);
|
||||
EXPECT_EQ(tableConnection.GetDirect("Name").GetValueAsString(), "MyConnection2");
|
||||
EXPECT_EQ(tableConnection.GetDirect("Provider.Name").GetValueAsString(), "MyConnectionProvider2");
|
||||
EXPECT_EQ(tableConnection.GetDirect("IpcChannel.abc").GetValueAsString(), "def");
|
||||
tableConnection = tableSettings.GetDirect("Connection[1]");
|
||||
EXPECT_TRUE(tableConnection);
|
||||
EXPECT_EQ(tableConnection.GetDirect("Name").GetValueAsString(), "MyConnection1");
|
||||
EXPECT_EQ(tableConnection.GetDirect("Provider.Name").GetValueAsString(), "MyConnectionProvider1");
|
||||
EXPECT_EQ(tableConnection.GetDirect("IpcChannel.xyz").GetValue(), 1234);
|
||||
|
||||
// Remove one listener
|
||||
settings.RemoveConnectionConfig("MyConnection1");
|
||||
EXPECT_EQ(settings.GetConnections().size(), 2u);
|
||||
EXPECT_TRUE(settings.SaveSettings());
|
||||
|
||||
// Verify settings
|
||||
auto parser2 = ReadSettingsFile();
|
||||
sdv::toml::CNodeCollection tableSettings2(parser2.Root().GetNodeDirect("Settings"));
|
||||
EXPECT_TRUE(tableSettings2);
|
||||
tableConnection = tableSettings2.GetDirect("Connection[0]");
|
||||
EXPECT_TRUE(tableConnection);
|
||||
EXPECT_EQ(tableConnection.GetDirect("Name").GetValueAsString(), "MyConnection2");
|
||||
EXPECT_EQ(tableConnection.GetDirect("Provider.Name").GetValueAsString(), "MyConnectionProvider2");
|
||||
EXPECT_EQ(tableConnection.GetDirect("IpcChannel.abc").GetValueAsString(), "def");
|
||||
}
|
||||
341
tests/unit_tests/app_settings/startup_config.cpp
Normal file
341
tests/unit_tests/app_settings/startup_config.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../sdv_services/core/app_settings.h"
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
|
||||
|
||||
// Load startup config
|
||||
// Invalid config
|
||||
// Empty config (default config)
|
||||
// Application types
|
||||
// Instance ID
|
||||
// Log handler
|
||||
// Console output
|
||||
// Config path
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, InvalidConfig)
|
||||
{
|
||||
const std::string ssInvalidToml = R"toml([Application]
|
||||
Mode = Standalone # Missing quotes)toml";
|
||||
const std::string ssInvalidValue = R"toml([Application]
|
||||
Mode = "Supadupa" # Invalid value)toml";
|
||||
const std::string ssAdditionalValues = R"toml([Application]
|
||||
Mode = "Standalone"
|
||||
SpecialAction = "Fly to the moon" # Additional value)toml";
|
||||
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
EXPECT_FALSE(settings.ProcessAppStartupConfig(ssInvalidToml));
|
||||
EXPECT_FALSE(settings.ProcessAppStartupConfig(ssInvalidValue));
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(ssAdditionalValues));
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, DefaultConfig)
|
||||
{
|
||||
const std::string ssEmptyToml;
|
||||
|
||||
CAppSettings settings;
|
||||
EXPECT_EQ(settings.GetInstanceID(), 0u);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(ssEmptyToml));
|
||||
EXPECT_TRUE(settings.IsStandaloneApplication());
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::error);
|
||||
EXPECT_EQ(settings.GetConsoleReporting(), CAppSettings::EAppConsoleReporting::normal);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1000u);
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, ApplicationTypes)
|
||||
{
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::no_context);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(""));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_TRUE(settings.IsStandaloneApplication());
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "External")toml"));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::external);
|
||||
EXPECT_TRUE(settings.IsExternalApplication());
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Standalone")toml"));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::standalone);
|
||||
EXPECT_TRUE(settings.IsStandaloneApplication());
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Isolated")toml"));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::isolated);
|
||||
EXPECT_TRUE(settings.IsIsolatedApplication());
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main")toml"));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::main);
|
||||
EXPECT_TRUE(settings.IsMainApplication());
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::essential);
|
||||
EXPECT_TRUE(settings.IsEssentialApplication());
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance")toml"));
|
||||
EXPECT_EQ(settings.GetContextType(), sdv::app::EAppContext::maintenance);
|
||||
EXPECT_TRUE(settings.IsMaintenanceApplication());
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, InstanceID)
|
||||
{
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 0u);
|
||||
|
||||
// Change type to main; no instance ID yet
|
||||
settings.SetContextType(sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 0u);
|
||||
|
||||
// Set instance ID, but no type
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Instance = 1234)toml"));
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
|
||||
// Change types, only main, isolated and maintenance should provide the instance ID.
|
||||
settings.SetContextType(sdv::app::EAppContext::standalone);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
settings.SetContextType(sdv::app::EAppContext::external);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
settings.SetContextType(sdv::app::EAppContext::isolated);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
settings.SetContextType(sdv::app::EAppContext::main);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
settings.SetContextType(sdv::app::EAppContext::essential);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
settings.SetContextType(sdv::app::EAppContext::maintenance);
|
||||
EXPECT_EQ(settings.GetInstanceID(), 1234u);
|
||||
settings.Reset();
|
||||
EXPECT_EQ(settings.GetInstanceID(), 0u);
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, LogHandler)
|
||||
{
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
|
||||
// No config
|
||||
EXPECT_TRUE(settings.GetLoggerClass().empty());
|
||||
EXPECT_TRUE(settings.GetLoggerModulePath().empty());
|
||||
EXPECT_TRUE(settings.GetLoggerProgramTag().empty());
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::error);
|
||||
|
||||
// Default config
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(""));
|
||||
EXPECT_EQ(settings.GetLoggerClass(), "DefaultLoggerService");
|
||||
EXPECT_TRUE(settings.GetLoggerModulePath().empty());
|
||||
EXPECT_TRUE(settings.GetLoggerProgramTag().empty());
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::error);
|
||||
|
||||
// Default logger when main or isolated
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerClass(), "DefaultLoggerService");
|
||||
EXPECT_TRUE(settings.GetLoggerModulePath().empty());
|
||||
EXPECT_TRUE(settings.GetLoggerProgramTag().empty());
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
|
||||
// Default logger when main or isolated
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Isolated")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerClass(), "DefaultLoggerService");
|
||||
EXPECT_TRUE(settings.GetLoggerModulePath().empty());
|
||||
EXPECT_TRUE(settings.GetLoggerProgramTag().empty());
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
|
||||
// Default logger for all others
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Standalone")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerClass(), "DefaultLoggerService");
|
||||
EXPECT_TRUE(settings.GetLoggerModulePath().empty());
|
||||
EXPECT_TRUE(settings.GetLoggerProgramTag().empty());
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::error);
|
||||
|
||||
// Set severity level for logger
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Trace")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::trace);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Debug")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::debug);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Info")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Warning")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::warning);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Error")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::error);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Fatal")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::fatal);
|
||||
EXPECT_FALSE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Filter = "Wrong")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::fatal);
|
||||
|
||||
// Set severity level for console
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Trace")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::trace);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Debug")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::debug);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Info")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::info);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Warning")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::warning);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Error")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::error);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Fatal")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::fatal);
|
||||
EXPECT_FALSE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
ViewFilter = "Wrong")toml"));
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::fatal);
|
||||
|
||||
// Explicit logger
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([LogHandler]
|
||||
Class = "logger_class"
|
||||
Path = "logger.xyz"
|
||||
Tag = "logger_tag"
|
||||
Filter = "Trace"
|
||||
ViewFilter = "Warning"
|
||||
UnkownValue = "hi")toml"));
|
||||
EXPECT_EQ(settings.GetLoggerClass(), "logger_class");
|
||||
EXPECT_EQ(settings.GetLoggerModulePath(), "logger.xyz");
|
||||
EXPECT_EQ(settings.GetLoggerProgramTag(), "logger_tag");
|
||||
EXPECT_EQ(settings.GetLoggerSeverityFilter(), sdv::core::ELogSeverity::trace);
|
||||
EXPECT_EQ(settings.GetConsoleSeverityFilter(), sdv::core::ELogSeverity::warning);
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, ConnectionRetries)
|
||||
{
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
|
||||
// Default is 5 retries
|
||||
EXPECT_EQ(settings.GetConnectRetries(), 5u);
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(""));
|
||||
EXPECT_EQ(settings.GetConnectRetries(), 5u);
|
||||
|
||||
// Set 0 retries - this is not an error and minimizes to 3
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Connections]
|
||||
Retries = 0)toml"));
|
||||
EXPECT_EQ(settings.GetConnectRetries(), 3u);
|
||||
|
||||
// Set 10 retries
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Connections]
|
||||
Retries = 10)toml"));
|
||||
EXPECT_EQ(settings.GetConnectRetries(), 10u);
|
||||
|
||||
// Set 100 retries - this is not an error and maximizes to 30
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Connections]
|
||||
Retries = 100)toml"));
|
||||
EXPECT_EQ(settings.GetConnectRetries(), 30u);
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, InstallDir)
|
||||
{
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
|
||||
// Empty install directory
|
||||
EXPECT_TRUE(settings.GetRootDir().empty());
|
||||
EXPECT_TRUE(settings.GetInstallDir().empty());
|
||||
|
||||
// Install directory has significance with main, isolated and maintenance apps only.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
EXPECT_TRUE(settings.GetRootDir().empty());
|
||||
EXPECT_TRUE(settings.GetInstallDir().empty());
|
||||
|
||||
// Use main and a specific instance ID
|
||||
std::filesystem::remove_all(GetExecDirectory() / "2000"); // Needed to prevent settings file parsing.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Instance = 2000
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
EXPECT_EQ(settings.GetRootDir(), GetExecDirectory());
|
||||
EXPECT_EQ(settings.GetInstallDir(), GetExecDirectory() / "2000");
|
||||
|
||||
// Use isolated and a specific instance ID
|
||||
std::filesystem::remove_all(GetExecDirectory() / "2001"); // Needed to prevent settings file parsing.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Instance = 2001
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
EXPECT_EQ(settings.GetRootDir(), GetExecDirectory());
|
||||
EXPECT_EQ(settings.GetInstallDir(), GetExecDirectory() / "2001");
|
||||
|
||||
// Use maintenance and a specific instance ID
|
||||
std::filesystem::remove_all(GetExecDirectory() / "2002"); // Needed to prevent settings file parsing.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2002
|
||||
InstallDir = )toml" + toml_parser::QuoteText(GetExecDirectory().generic_u8string())));
|
||||
EXPECT_EQ(settings.GetRootDir(), GetExecDirectory());
|
||||
EXPECT_EQ(settings.GetInstallDir(), GetExecDirectory() / "2002");
|
||||
|
||||
// Relative path
|
||||
std::filesystem::remove_all(GetExecDirectory() / "2003"); // Needed to prevent settings file parsing.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Instance = 2003
|
||||
InstallDir = "..")toml"));
|
||||
EXPECT_EQ(settings.GetRootDir(), GetExecDirectory() / "..");
|
||||
EXPECT_EQ(settings.GetInstallDir(), GetExecDirectory() / ".." / "2003");
|
||||
}
|
||||
|
||||
TEST(AppSettingsTest_StartupConfig, CustomConfigFile)
|
||||
{
|
||||
CAppSettings settings;
|
||||
settings.SetConsoleReporting(CAppSettings::EAppConsoleReporting::silent);
|
||||
|
||||
// Default empty
|
||||
EXPECT_TRUE(settings.GetUserConfigPath().empty());
|
||||
|
||||
// Application config path has no significance with main, isolated and maintenance apps only.
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Config = "abc.def")toml"));
|
||||
EXPECT_EQ(settings.GetUserConfigPath(), "abc.def");
|
||||
|
||||
// Use main
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Main"
|
||||
Config = "def.hij")toml"));
|
||||
EXPECT_EQ(settings.GetUserConfigPath(), "abc.def");
|
||||
|
||||
// Use isolated
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Isolated"
|
||||
Config = "hij.klm")toml"));
|
||||
EXPECT_EQ(settings.GetUserConfigPath(), "abc.def");
|
||||
|
||||
// Use maintenance
|
||||
EXPECT_TRUE(settings.ProcessAppStartupConfig(R"toml([Application]
|
||||
Mode = "Maintenance"
|
||||
Config = "klm.nop")toml"));
|
||||
EXPECT_EQ(settings.GetUserConfigPath(), "abc.def");
|
||||
}
|
||||
@@ -283,7 +283,7 @@ TEST(CoreLoaderTest, EnvVarLoading)
|
||||
EXPECT_EQ(executor.Execute(), 1);
|
||||
}
|
||||
|
||||
TEST(CoreLoaderTest, CfgFileLoadingRel)
|
||||
TEST(CoreLoaderTest, CoreRelocFileLoadingRel)
|
||||
{
|
||||
CTestExecute executor;
|
||||
|
||||
@@ -291,14 +291,17 @@ TEST(CoreLoaderTest, CfgFileLoadingRel)
|
||||
fstream << R"cfg(# Some bogus information
|
||||
unknown_var = 2
|
||||
|
||||
[CoreLocation]
|
||||
Version = 100
|
||||
|
||||
# Core library path
|
||||
directory = "../../../bin")cfg";
|
||||
Runtime = "../../../bin")cfg";
|
||||
fstream.close();
|
||||
|
||||
EXPECT_EQ(executor.Execute(), 1);
|
||||
}
|
||||
|
||||
TEST(CoreLoaderTest, CfgFileLoadingAbs)
|
||||
TEST(CoreLoaderTest, CoreRelocFileLoadingAbs)
|
||||
{
|
||||
CTestExecute executor;
|
||||
|
||||
@@ -306,15 +309,18 @@ TEST(CoreLoaderTest, CfgFileLoadingAbs)
|
||||
fstream << R"cfg(# Some bogus information
|
||||
unknown_var = 2
|
||||
|
||||
[CoreLocation]
|
||||
Version = 100
|
||||
|
||||
# Core library path
|
||||
directory = ")cfg" << (executor.GetExeDir() / "../../../bin").lexically_normal().generic_string() << "\"";
|
||||
Runtime = ")cfg" << (executor.GetExeDir() / "../../../bin").lexically_normal().generic_string() << "\"";
|
||||
fstream.close();
|
||||
|
||||
EXPECT_EQ(executor.Execute(), 1);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(CoreLoaderTest, CfgFileLoadingRelWin)
|
||||
TEST(CoreLoaderTest, CoreRelocFileLoadingRelWin)
|
||||
{
|
||||
CTestExecute executor;
|
||||
|
||||
@@ -322,14 +328,17 @@ TEST(CoreLoaderTest, CfgFileLoadingRelWin)
|
||||
fstream << R"cfg(# Some bogus information
|
||||
unknown_var = 2
|
||||
|
||||
[CoreLocation]
|
||||
Version = 100
|
||||
|
||||
# Core library path
|
||||
directory = "..\\..\\..\\bin")cfg";
|
||||
Runtime = "..\\..\\..\\bin")cfg";
|
||||
fstream.close();
|
||||
|
||||
EXPECT_EQ(executor.Execute(), 1);
|
||||
}
|
||||
|
||||
TEST(CoreLoaderTest, CfgFileLoadingAbsWin)
|
||||
TEST(CoreLoaderTest, CoreRelocFileLoadingAbsWin)
|
||||
{
|
||||
CTestExecute executor;
|
||||
|
||||
@@ -352,8 +361,11 @@ TEST(CoreLoaderTest, CfgFileLoadingAbsWin)
|
||||
fstream << R"cfg(# Some bogus information
|
||||
unknown_var = 2
|
||||
|
||||
[CoreLocation]
|
||||
Version = 100
|
||||
|
||||
# Core library path
|
||||
directory = ")cfg" << ssDir << "\"";
|
||||
Runtime = ")cfg" << ssDir << "\"";
|
||||
fstream.close();
|
||||
|
||||
EXPECT_EQ(executor.Execute(), 1);
|
||||
|
||||
@@ -156,7 +156,7 @@ TEST_F(CDbcParserTest, SourceContent)
|
||||
|
||||
TEST_F(CDbcParserTest, SourceLineColumn)
|
||||
{
|
||||
std::string ssSource = R"code(VERSION ""
|
||||
std::string ssSource = R"dbc(VERSION ""
|
||||
|
||||
|
||||
NS_ :
|
||||
@@ -169,7 +169,7 @@ NS_ :
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_)code";
|
||||
EV_DATA_)dbc";
|
||||
|
||||
dbc::CDbcSource src(ssSource);
|
||||
EXPECT_EQ(src.CalcLine(), 1);
|
||||
@@ -370,10 +370,10 @@ TEST_F(CDbcParserTest, NewSymbols)
|
||||
EXPECT_NO_THROW(parser.Parse(srcOneNS));
|
||||
|
||||
// All symbols
|
||||
std::string ssAllNS = R"code(NS_ : NS_DESC_ CM_ BA_DEF_ BA_ VAL_ CAT_DEF_ CAT_ FILTER BA_DEF_DEF_ EV_DATA_
|
||||
std::string ssAllNS = R"dbc(NS_ : NS_DESC_ CM_ BA_DEF_ BA_ VAL_ CAT_DEF_ CAT_ FILTER BA_DEF_DEF_ EV_DATA_
|
||||
ENVVAR_DATA_ SGTYPE_ SGTYPE_VAL_ BA_DEF_SGTYPE_ BA_SGTYPE_ SIG_TYPE_REF_ VAL_TABLE_ SIG_GROUP_
|
||||
SIG_VALTYPE_ SIGTYPE_VALTYPE_ BO_TX_BU_ BA_DEF_REL_ BA_REL_ BA_DEF_DEF_REL_ BU_SG_REL_
|
||||
BU_EV_REL_ BU_BO_REL_ SG_MUL_VAL_)code";
|
||||
BU_EV_REL_ BU_BO_REL_ SG_MUL_VAL_)dbc";
|
||||
dbc::CDbcSource srcAllNS(ssAllNS);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAllNS));
|
||||
|
||||
@@ -628,7 +628,7 @@ TEST_F(CDbcParserTest, SignalDef)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx2"));
|
||||
|
||||
// Message definition
|
||||
std::string ssValidMsgDef1 = R"code(
|
||||
std::string ssValidMsgDef1 = R"dbc(
|
||||
BO_ 1 msg_big_endian: 8 nodeTx
|
||||
SG_ sig1 : 7|4@0+ (1,0) [0|8191] "Nm" nodeRx1
|
||||
SG_ sig2 : 3|8@0+ (1,0) [0|8191] "Nm" nodeRx1, nodeRx2
|
||||
@@ -651,7 +651,7 @@ TEST_F(CDbcParserTest, SignalDef)
|
||||
SG_ sig5a m 1: 24|8@1+ (1,0) [0|8191] "Nm" Vector__XXX
|
||||
SG_ sig2b m 0: 4|32@1+ (1,0) [0|8191] "Nm" nodeRx1, nodeRx2
|
||||
SG_ sig6 : 32|32@1+ (1,0) [0|8191] "Nm" Vector__XXX
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcValidMsgDef1(ssValidMsgDef1);
|
||||
EXPECT_NO_THROW(parser.Parse(srcValidMsgDef1));
|
||||
EXPECT_TRUE(parser.HasSignalDef("msg_big_endian", "sig1"));
|
||||
@@ -725,32 +725,32 @@ TEST_F(CDbcParserTest, SignalDef)
|
||||
EXPECT_TRUE(parser.GetSignalDefExtId(3, "sig6").second);
|
||||
|
||||
// Duplicate signals
|
||||
std::string ssDuplicateSigDef1 = R"code(
|
||||
std::string ssDuplicateSigDef1 = R"dbc(
|
||||
BO_ 4 msg4: 8 nodeTx
|
||||
SG_ sig1 : 52|13@0+ (1,0) [0|8191] "Nm" nodeRx1
|
||||
SG_ sig2 : 36|13@0+ (1,0) [0|8191] "Nm" nodeRx1, nodeRx2
|
||||
SG_ sig1 : 18|13@0+ (1,0) [0|8191] "Nm" Vector__XXX
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcDuplicateSigDef1(ssDuplicateSigDef1);
|
||||
EXPECT_THROW(parser.Parse(srcDuplicateSigDef1), dbc::SDbcParserException);
|
||||
|
||||
// Invalid signals
|
||||
std::string ssInvalidStartBit = R"code(
|
||||
std::string ssInvalidStartBit = R"dbc(
|
||||
BO_ 5 msg5: 8 nodeTx
|
||||
SG_ sig1 : 64|13@0+ (1,0) [0|8191] "Nm" nodeRx1
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcInvalidStartBit(ssInvalidStartBit);
|
||||
EXPECT_THROW(parser.Parse(srcInvalidStartBit), dbc::SDbcParserException);
|
||||
std::string ssInvalidLengthLittleEndian = R"code(
|
||||
std::string ssInvalidLengthLittleEndian = R"dbc(
|
||||
BO_ 6 msg6: 8 nodeTx
|
||||
SG_ sig1 : 33|32@1+ (1,0) [0|8191] "Nm" nodeRx1
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcInvalidLengthLittleEndian(ssInvalidLengthLittleEndian);
|
||||
EXPECT_THROW(parser.Parse(srcInvalidLengthLittleEndian), dbc::SDbcParserException);
|
||||
std::string ssInvalidLengthBigEndian = R"code(
|
||||
std::string ssInvalidLengthBigEndian = R"dbc(
|
||||
BO_ 7 msg7: 8 nodeTx
|
||||
SG_ sig1 : 38|32@0+ (1,0) [0|8191] "Nm" nodeRx1
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcInvalidLengthBigEndian(ssInvalidLengthBigEndian);
|
||||
EXPECT_THROW(parser.Parse(srcInvalidLengthBigEndian), dbc::SDbcParserException);
|
||||
}
|
||||
@@ -767,13 +767,13 @@ TEST_F(CDbcParserTest, SignalTypeDef)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg_float: 8 nodeTx
|
||||
SG_ sig_float : 0|32@1- (1,0) [0|8191] "Nm" nodeRx
|
||||
SG_ sig_int : 32|32@1+ (1,0) [0|8191] "Nm" nodeRx
|
||||
BO_ 2 msg_double: 8 nodeTx
|
||||
SG_ sig_double : 0|64@1- (1,0) [0|8191] "Nm" nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
EXPECT_TRUE(parser.HasMsgDef("msg_float"));
|
||||
@@ -789,11 +789,11 @@ TEST_F(CDbcParserTest, SignalTypeDef)
|
||||
EXPECT_EQ(prSigDouble.first.eValType, dbc::SSignalDef::EValueType::signed_integer);
|
||||
|
||||
// Set the signal value types.
|
||||
std::string ssSigValType = R"code(
|
||||
std::string ssSigValType = R"dbc(
|
||||
SIG_VALTYPE_ 1 sig_float 1;
|
||||
SIG_VALTYPE_ 1 sig_int 0;
|
||||
SIG_VALTYPE_ 2 sig_double 2;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcSigValType(ssSigValType);
|
||||
EXPECT_NO_THROW(parser.Parse(srcSigValType));
|
||||
|
||||
@@ -877,11 +877,11 @@ TEST_F(CDbcParserTest, SignalValueDescriptions)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg_enum: 8 nodeTx
|
||||
SG_ sig_enum : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig_enum_empty : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
EXPECT_TRUE(parser.HasMsgDef("msg_enum"));
|
||||
@@ -933,11 +933,11 @@ TEST_F(CDbcParserTest, EnvironmentVariableDef)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Environment variable definition
|
||||
std::string ssEnvVarDef = R"code(
|
||||
std::string ssEnvVarDef = R"dbc(
|
||||
EV_ var1 : 0 [10|20] "steps" 15 100 DUMMY_NODE_VECTOR3 nodeTx, nodeRx;
|
||||
EV_ var2 : 1 [0.1|0.2] "tenth steps" 0.5 101 DUMMY_NODE_VECTOR2 nodeTx;
|
||||
EV_ var3 : 2 [0.0|0.0] "string val" 0.0 102 DUMMY_NODE_VECTOR8001 nodeRx;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcEnvVarDef(ssEnvVarDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcEnvVarDef));
|
||||
auto vecEnvVars = parser.GetEnvVarNames();
|
||||
@@ -996,18 +996,18 @@ TEST_F(CDbcParserTest, EnvVarData)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Environment variable definition
|
||||
std::string ssEnvVarDef = R"code(
|
||||
std::string ssEnvVarDef = R"dbc(
|
||||
EV_ var1 : 0 [10|20] "steps" 15 100 DUMMY_NODE_VECTOR3 nodeTx, nodeRx;
|
||||
EV_ var2 : 1 [0.1|0.2] "tenth steps" 0.5 101 DUMMY_NODE_VECTOR2 nodeTx;
|
||||
EV_ var3 : 2 [0.0|0.0] "string val" 0.0 102 DUMMY_NODE_VECTOR8001 nodeRx;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcEnvVarDef(ssEnvVarDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcEnvVarDef));
|
||||
|
||||
// Environment variable data definition
|
||||
std::string ssEnvVarDataDef = R"code(
|
||||
std::string ssEnvVarDataDef = R"dbc(
|
||||
ENVVAR_DATA_ var1 : 10;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcEnvVarDataDef(ssEnvVarDataDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcEnvVarDataDef));
|
||||
auto prEnvVar = parser.GetEnvVarDef("var1");
|
||||
@@ -1038,11 +1038,11 @@ TEST_F(CDbcParserTest, EnvVarValueDescriptions)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Environment variable definition
|
||||
std::string ssEnvVarDef = R"code(
|
||||
std::string ssEnvVarDef = R"dbc(
|
||||
EV_ var1 : 0 [10|20] "steps" 15 100 DUMMY_NODE_VECTOR3 nodeTx, nodeRx;
|
||||
EV_ var2 : 1 [0.1|0.2] "tenth steps" 0.5 101 DUMMY_NODE_VECTOR2 nodeTx;
|
||||
EV_ var3 : 2 [0.0|0.0] "string val" 0.0 102 DUMMY_NODE_VECTOR8001 nodeRx;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcEnvVarDef(ssEnvVarDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcEnvVarDef));
|
||||
|
||||
@@ -1079,17 +1079,17 @@ TEST_F(CDbcParserTest, ExtSignalTypeDef)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Value table
|
||||
std::string ssValueTable = R"code(
|
||||
std::string ssValueTable = R"dbc(
|
||||
VAL_TABLE_ table1 10 "ten" 20 "twenty";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcValueTable(ssValueTable);
|
||||
EXPECT_NO_THROW(parser.Parse(srcValueTable));
|
||||
|
||||
// Value table type definition
|
||||
std::string ssValueTableType = R"code(
|
||||
std::string ssValueTableType = R"dbc(
|
||||
SGTYPE_ sgtype1 : 32 @ 1+ (1.0, 0) [0|100] "signal unit" 50, table1;
|
||||
SGTYPE_ sgtype2 : 16 @ 0- (-10.5, 10) [-100|200] "signal unit2" 13, Vector__XXX;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcValueTableType(ssValueTableType);
|
||||
EXPECT_NO_THROW(parser.Parse(srcValueTableType));
|
||||
auto vecSignalTypes = parser.GetSignalTypeDefNames();
|
||||
@@ -1129,17 +1129,17 @@ TEST_F(CDbcParserTest, SignalTypeRef)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Value table
|
||||
std::string ssValueTable = R"code(
|
||||
std::string ssValueTable = R"dbc(
|
||||
VAL_TABLE_ table1 10 "ten" 20 "twenty";
|
||||
VAL_TABLE_ table2 20 "twenty" 30 "thirty";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcValueTable(ssValueTable);
|
||||
EXPECT_NO_THROW(parser.Parse(srcValueTable));
|
||||
|
||||
// Signal type definition
|
||||
std::string ssSignalType = R"code(
|
||||
std::string ssSignalType = R"dbc(
|
||||
SGTYPE_ sgtype1 : 32 @ 1+ (1.0, 0) [0|100] "signal unit" 50, table1;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcSignalType(ssSignalType);
|
||||
EXPECT_NO_THROW(parser.Parse(srcSignalType));
|
||||
|
||||
@@ -1151,11 +1151,11 @@ TEST_F(CDbcParserTest, SignalTypeRef)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg: 8 nodeTx
|
||||
SG_ sig1 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig2 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
@@ -1180,20 +1180,20 @@ TEST_F(CDbcParserTest, SignalGroupDef)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg: 8 nodeTx
|
||||
SG_ sig1 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig2 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig3 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
// Signal group definition
|
||||
std::string ssSignalGroup = R"code(
|
||||
std::string ssSignalGroup = R"dbc(
|
||||
SIG_GROUP_ 1 group1 10 : sig1 sig2;
|
||||
SIG_GROUP_ 1 group2 20 : sig3;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcSignalGroup(ssSignalGroup);
|
||||
EXPECT_NO_THROW(parser.Parse(srcSignalGroup));
|
||||
auto vecGroupNames = parser.GetSignalGroupDefNames(1);
|
||||
@@ -1220,12 +1220,12 @@ TEST_F(CDbcParserTest, GlobalComments)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Global comments
|
||||
std::string ssComments = R"code(
|
||||
std::string ssComments = R"dbc(
|
||||
CM_ "first comment";
|
||||
CM_ "second comment";
|
||||
CM_ "third comment";
|
||||
CM_ "fourth comment";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcComments(ssComments);
|
||||
EXPECT_NO_THROW(parser.Parse(srcComments));
|
||||
auto vecComments = parser.GetComments();
|
||||
@@ -1248,12 +1248,12 @@ TEST_F(CDbcParserTest, NodeComments)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Node comments
|
||||
std::string ssComments = R"code(
|
||||
std::string ssComments = R"dbc(
|
||||
CM_ BU_ nodeTx "first comment";
|
||||
CM_ BU_ nodeTx "second comment \"with quotes\"";
|
||||
CM_ BU_ nodeRx "third comment 'with single quotes'";
|
||||
CM_ BU_ nodeRx "fourth comment";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcComments(ssComments);
|
||||
EXPECT_NO_THROW(parser.Parse(srcComments));
|
||||
auto prNode = parser.GetNodeDef("nodeTx");
|
||||
@@ -1280,22 +1280,22 @@ TEST_F(CDbcParserTest, MessageComments)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg: 8 nodeTx
|
||||
SG_ sig1 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig2 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig3 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
// Message comments
|
||||
std::string ssComments = R"code(
|
||||
std::string ssComments = R"dbc(
|
||||
CM_ BO_ 1 "first comment";
|
||||
CM_ BO_ 1 "second comment";
|
||||
CM_ BO_ 1 "third comment";
|
||||
CM_ BO_ 1 "fourth comment";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcComments(ssComments);
|
||||
EXPECT_NO_THROW(parser.Parse(srcComments));
|
||||
auto prMsgDef = parser.GetMsgDef(1);
|
||||
@@ -1319,22 +1319,22 @@ TEST_F(CDbcParserTest, SignalComments)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Signal definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg: 8 nodeTx
|
||||
SG_ sig1 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig2 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig3 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
// Node comments
|
||||
std::string ssComments = R"code(
|
||||
std::string ssComments = R"dbc(
|
||||
CM_ SG_ 1 sig1 "first comment";
|
||||
CM_ SG_ 1 sig1 "second comment";
|
||||
CM_ SG_ 1 sig2 "third comment";
|
||||
CM_ SG_ 1 sig3 "fourth comment";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcComments(ssComments);
|
||||
EXPECT_NO_THROW(parser.Parse(srcComments));
|
||||
auto prSignal = parser.GetSignalDef(1, "sig1");
|
||||
@@ -1364,21 +1364,21 @@ TEST_F(CDbcParserTest, EnvVarComments)
|
||||
EXPECT_TRUE(parser.HasNodeDef("nodeRx"));
|
||||
|
||||
// Environment variable definition
|
||||
std::string ssEnvVarDef = R"code(
|
||||
std::string ssEnvVarDef = R"dbc(
|
||||
EV_ var1 : 0 [10|20] "steps" 15 100 DUMMY_NODE_VECTOR3 nodeTx, nodeRx;
|
||||
EV_ var2 : 1 [0.1|0.2] "tenth steps" 0.5 101 DUMMY_NODE_VECTOR2 nodeTx;
|
||||
EV_ var3 : 2 [0.0|0.0] "string val" 0.0 102 DUMMY_NODE_VECTOR8001 nodeRx;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcEnvVarDef(ssEnvVarDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcEnvVarDef));
|
||||
|
||||
// Env var comments
|
||||
std::string ssComments = R"code(
|
||||
std::string ssComments = R"dbc(
|
||||
CM_ EV_ var1 "first comment";
|
||||
CM_ EV_ var1 "second comment";
|
||||
CM_ EV_ var2 "third comment";
|
||||
CM_ EV_ var3 "fourth comment";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcComments(ssComments);
|
||||
EXPECT_NO_THROW(parser.Parse(srcComments));
|
||||
auto prEnvVar = parser.GetEnvVarDef("var1");
|
||||
@@ -1402,14 +1402,14 @@ TEST_F(CDbcParserTest, AttributeDef)
|
||||
|
||||
// Global attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ "attr1" INT 10 20;
|
||||
BA_DEF_ "attr2" HEX 10 20;
|
||||
BA_DEF_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ "attr4" STRING;
|
||||
BA_DEF_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
auto vecAttr = parser.GetAttributeDefNames();
|
||||
@@ -1470,27 +1470,27 @@ TEST_F(CDbcParserTest, AttributeDefaultValDef)
|
||||
|
||||
// Global attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ "attr1" INT 10 20;
|
||||
BA_DEF_ "attr2" HEX 10 20;
|
||||
BA_DEF_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ "attr4" STRING;
|
||||
BA_DEF_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
|
||||
// Attribute def default value
|
||||
// The use of an index instead of a value for the enum value is not part of the official standard.
|
||||
std::string ssAttrDefDefaultVal = R"code(
|
||||
std::string ssAttrDefDefaultVal = R"dbc(
|
||||
BA_DEF_DEF_ "attr1" 15;
|
||||
BA_DEF_DEF_ "attr2" 15;
|
||||
BA_DEF_DEF_ "attr3" 5.5;
|
||||
BA_DEF_DEF_ "attr4" "hello";
|
||||
BA_DEF_DEF_ "attr5" "def";
|
||||
BA_DEF_DEF_ "attr6" 6;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttrDefDefaultVal(ssAttrDefDefaultVal);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttrDefDefaultVal));
|
||||
|
||||
@@ -1514,20 +1514,20 @@ TEST_F(CDbcParserTest, GlobalAttributeVal)
|
||||
|
||||
// Global attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ "attr1" INT 10 20;
|
||||
BA_DEF_ "attr2" HEX 10 20;
|
||||
BA_DEF_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ "attr4" STRING;
|
||||
BA_DEF_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
|
||||
// Attribute value
|
||||
// The use of an index instead of a value for the enum value is not part of the official standard.
|
||||
std::string ssAttrVal = R"code(
|
||||
std::string ssAttrVal = R"dbc(
|
||||
BA_ "attr1" 11;
|
||||
BA_ "attr2" 12;
|
||||
BA_ "attr2" 13;
|
||||
@@ -1535,7 +1535,7 @@ TEST_F(CDbcParserTest, GlobalAttributeVal)
|
||||
BA_ "attr4" "hi";
|
||||
BA_ "attr5" "ghi";
|
||||
BA_ "attr6" 6;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttrVal(ssAttrVal);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttrVal));
|
||||
auto vecAttr = parser.GetAttributes();
|
||||
@@ -1562,20 +1562,20 @@ TEST_F(CDbcParserTest, NodeAttributeVal)
|
||||
|
||||
// Node attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ BU_ "attr1" INT 10 20;
|
||||
BA_DEF_ BU_ "attr2" HEX 10 20;
|
||||
BA_DEF_ BU_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ BU_ "attr4" STRING;
|
||||
BA_DEF_ BU_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ BU_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
|
||||
// Attribute value
|
||||
// The use of an index instead of a value for the enum value is not part of the official standard.
|
||||
std::string ssAttrVal = R"code(
|
||||
std::string ssAttrVal = R"dbc(
|
||||
BA_ "attr1" BU_ nodeTx 11;
|
||||
BA_ "attr2" BU_ nodeTx 12;
|
||||
BA_ "attr2" BU_ nodeTx 13;
|
||||
@@ -1583,7 +1583,7 @@ TEST_F(CDbcParserTest, NodeAttributeVal)
|
||||
BA_ "attr4" BU_ nodeRx "hi";
|
||||
BA_ "attr5" BU_ nodeRx "ghi";
|
||||
BA_ "attr6" BU_ nodeRx 6;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttrVal(ssAttrVal);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttrVal));
|
||||
auto prNodeDef = parser.GetNodeDef("nodeTx");
|
||||
@@ -1612,31 +1612,31 @@ TEST_F(CDbcParserTest, MessageAttributeVal)
|
||||
|
||||
// Message attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ BO_ "attr1" INT 10 20;
|
||||
BA_DEF_ BO_ "attr2" HEX 10 20;
|
||||
BA_DEF_ BO_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ BO_ "attr4" STRING;
|
||||
BA_DEF_ BO_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ BO_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg: 8 nodeTx
|
||||
SG_ sig1 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig2 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig3 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
BO_ 2 msg2: 8 nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
// Attribute value
|
||||
// The use of an index instead of a value for the enum value is not part of the official standard.
|
||||
std::string ssAttrVal = R"code(
|
||||
std::string ssAttrVal = R"dbc(
|
||||
BA_ "attr1" BO_ 1 11;
|
||||
BA_ "attr2" BO_ 1 12;
|
||||
BA_ "attr2" BO_ 1 13;
|
||||
@@ -1644,7 +1644,7 @@ TEST_F(CDbcParserTest, MessageAttributeVal)
|
||||
BA_ "attr4" BO_ 2 "hi";
|
||||
BA_ "attr5" BO_ 2 "ghi";
|
||||
BA_ "attr6" BO_ 2 6;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttrVal(ssAttrVal);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttrVal));
|
||||
auto prMsgDef = parser.GetMsgDef(1);
|
||||
@@ -1673,31 +1673,31 @@ TEST_F(CDbcParserTest, SignalAttributeVal)
|
||||
|
||||
// Signal attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ SG_ "attr1" INT 10 20;
|
||||
BA_DEF_ SG_ "attr2" HEX 10 20;
|
||||
BA_DEF_ SG_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ SG_ "attr4" STRING;
|
||||
BA_DEF_ SG_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ SG_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 1 msg: 8 nodeTx
|
||||
SG_ sig1 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig2 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
SG_ sig3 : 0|32@1+ (1,0) [0|0] "" nodeRx
|
||||
BO_ 2 msg2: 8 nodeRx
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
// Attribute value
|
||||
// The use of an index instead of a value for the enum value is not part of the official standard.
|
||||
std::string ssAttrVal = R"code(
|
||||
std::string ssAttrVal = R"dbc(
|
||||
BA_ "attr1" SG_ 1 sig1 11;
|
||||
BA_ "attr2" SG_ 1 sig1 12;
|
||||
BA_ "attr2" SG_ 1 sig2 13;
|
||||
@@ -1705,7 +1705,7 @@ TEST_F(CDbcParserTest, SignalAttributeVal)
|
||||
BA_ "attr4" SG_ 1 sig3 "hi";
|
||||
BA_ "attr5" SG_ 1 sig3 "ghi";
|
||||
BA_ "attr6" SG_ 1 sig3 6;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttrVal(ssAttrVal);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttrVal));
|
||||
auto prSigDef = parser.GetSignalDef(1, "sig1");
|
||||
@@ -1736,29 +1736,29 @@ TEST_F(CDbcParserTest, EnvVarAttributeVal)
|
||||
|
||||
// Environment variable attribute definition
|
||||
// The use of "n/a" and "not-used" is not part of the official standard.
|
||||
std::string ssAttribute = R"code(
|
||||
std::string ssAttribute = R"dbc(
|
||||
BA_DEF_ EV_ "attr1" INT 10 20;
|
||||
BA_DEF_ EV_ "attr2" HEX 10 20;
|
||||
BA_DEF_ EV_ "attr3" FLOAT 1.0 10.9;
|
||||
BA_DEF_ EV_ "attr4" STRING;
|
||||
BA_DEF_ EV_ "attr5" ENUM "abc", "def", "ghi";
|
||||
BA_DEF_ EV_ "attr6" ENUM "abc", "n/a", "not-used", "jkl", "n/a", "not-used", "stu";
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttribute(ssAttribute);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttribute));
|
||||
|
||||
// Environment variable definition
|
||||
std::string ssEnvVarDef = R"code(
|
||||
std::string ssEnvVarDef = R"dbc(
|
||||
EV_ var1 : 0 [10|20] "steps" 15 100 DUMMY_NODE_VECTOR3 nodeTx, nodeRx;
|
||||
EV_ var2 : 1 [0.1|0.2] "tenth steps" 0.5 101 DUMMY_NODE_VECTOR2 nodeTx;
|
||||
EV_ var3 : 2 [0.0|0.0] "string val" 0.0 102 DUMMY_NODE_VECTOR8001 nodeRx;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcEnvVarDef(ssEnvVarDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcEnvVarDef));
|
||||
|
||||
// Attribute value
|
||||
// The use of an index instead of a value for the enum value is not part of the official standard.
|
||||
std::string ssAttrVal = R"code(
|
||||
std::string ssAttrVal = R"dbc(
|
||||
BA_ "attr1" EV_ var1 11;
|
||||
BA_ "attr2" EV_ var1 12;
|
||||
BA_ "attr2" EV_ var2 13;
|
||||
@@ -1766,7 +1766,7 @@ TEST_F(CDbcParserTest, EnvVarAttributeVal)
|
||||
BA_ "attr4" EV_ var3 "hi";
|
||||
BA_ "attr5" EV_ var3 "ghi";
|
||||
BA_ "attr6" EV_ var3 6;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcAttrVal(ssAttrVal);
|
||||
EXPECT_NO_THROW(parser.Parse(srcAttrVal));
|
||||
auto prEnvVarDef = parser.GetEnvVarDef("var1");
|
||||
@@ -1789,7 +1789,7 @@ TEST_F(CDbcParserTest, SignalExtendedMultiplexing)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
BO_ 100 MuxMsg: 1 Vector__XXX
|
||||
SG_ Mux_4 m2 : 6|2@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ Mux_3 m3M : 4|2@1+ (1,0) [0|0] "" Vector__XXX
|
||||
@@ -1799,7 +1799,7 @@ TEST_F(CDbcParserTest, SignalExtendedMultiplexing)
|
||||
SG_MUL_VAL_ 100 Mux_2 Mux_1 3-3, 5-10;
|
||||
SG_MUL_VAL_ 100 Mux_3 Mux_2 3-3;
|
||||
SG_MUL_VAL_ 100 Mux_4 Mux_3 2-2;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
|
||||
@@ -1842,7 +1842,7 @@ TEST_F(CDbcParserTest, ExampleDBC1)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
VERSION ""
|
||||
|
||||
NS_ :
|
||||
@@ -1891,7 +1891,7 @@ CM_ "CAN communication matrix for power train electronics
|
||||
implemented: turn lights, warning lights, windows";
|
||||
|
||||
VAL_ 100 IdleRunning 0 "Running" 1 "Idle" ;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
}
|
||||
@@ -1900,7 +1900,7 @@ TEST_F(CDbcParserTest, ExampleDBC2)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
VERSION ""
|
||||
|
||||
|
||||
@@ -2023,7 +2023,7 @@ VAL_ 1 HMI_Lateral_Long_Ctrl_Req 3 "LONGITUDINAL_CTRL_REQ" 2 "LONGITUDINAL_AND_L
|
||||
VAL_ 1 HMI_Algo_Variant_Request 4 "NONE" 3 "VARIANT_4" 2 "VARIANT_3" 1 "VARIANT_2" 0 "VARIANT_1" ;
|
||||
VAL_ 0 MAB_AI4Motion_Algo_Var_Selected 4 "NONE" 3 "VARIANT_4" 2 "VARIANT_3" 1 "VARIANT_2" 0 "VARIANT_1" ;
|
||||
VAL_ 0 MAB_Activation_AI4Motion 3 "LONGITUDINAL_CTRL_REQ" 2 "LONGITUDINAL_AND_LATERAL" 1 "LATERAL_CTRL_REQ" 0 "NONE" ;
|
||||
SIG_VALTYPE_ 3221225472 New_Signal_25 : 2; )code";
|
||||
SIG_VALTYPE_ 3221225472 New_Signal_25 : 2; )dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
}
|
||||
@@ -2032,7 +2032,7 @@ TEST_F(CDbcParserTest, ExampleDBC3)
|
||||
dbc::CDbcParser parser;
|
||||
|
||||
// Message definition
|
||||
std::string ssMsgDef = R"code(
|
||||
std::string ssMsgDef = R"dbc(
|
||||
VERSION ""
|
||||
|
||||
|
||||
@@ -2135,7 +2135,7 @@ VERSION ""
|
||||
VAL_ 100 DRIVER_HEARTBEAT_cmd 2 "DRIVER_HEARTBEAT_cmd_REBOOT" 1 "DRIVER_HEARTBEAT_cmd_SYNC" 0
|
||||
"DRIVER_HEARTBEAT_cmd_NOOP" ;
|
||||
VAL_ 500 IO_DEBUG_test_enum 2 "IO_DEBUG_test2_enum_two" 1 "IO_DEBUG_test2_enum_one" ;
|
||||
)code";
|
||||
)dbc";
|
||||
dbc::CDbcSource srcMsgDef(ssMsgDef);
|
||||
EXPECT_NO_THROW(parser.Parse(srcMsgDef));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/code_snippet.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_indexer.cpp"
|
||||
#include <support/app_control.h>
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
|
||||
@@ -45,8 +45,10 @@ set_target_properties(UnitTest_IPC_Communication_ps PROPERTIES SUFFIX ".sdv")
|
||||
# Compile the source code
|
||||
add_executable(UnitTest_IPC_Communication
|
||||
"main.cpp"
|
||||
|
||||
"ipc_com.cpp"
|
||||
"ipc_com_sharedmem.cpp"
|
||||
"ipc_com_uds.cpp"
|
||||
"include.h"
|
||||
"ipc_com_uds_tunnel.cpp"
|
||||
)
|
||||
target_link_libraries(UnitTest_IPC_Communication ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
|
||||
1300
tests/unit_tests/ipc_com/include.h
Normal file
1300
tests/unit_tests/ipc_com/include.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
5476
tests/unit_tests/ipc_com/ipc_com_uds.cpp
Normal file
5476
tests/unit_tests/ipc_com/ipc_com_uds.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5534
tests/unit_tests/ipc_com/ipc_com_uds_tunnel.cpp
Normal file
5534
tests/unit_tests/ipc_com/ipc_com_uds_tunnel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,8 @@ extern "C" int main(int argc, char* argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
// Use extended execution time of 10 minutes
|
||||
CProcessWatchdog watchdog(600u);
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
@@ -17,8 +17,10 @@ project (UnitTest_IPC_Connect VERSION 1.0 LANGUAGES CXX)
|
||||
# Compile the source code
|
||||
add_executable(UnitTest_IPC_Connect
|
||||
"main.cpp"
|
||||
|
||||
"ipc_connect.cpp"
|
||||
"ipc_connect_shared_mem.cpp"
|
||||
"ipc_connect_false_positiv.cpp"
|
||||
"ipc_connect_uds.cpp"
|
||||
"ipc_connect_uds_tunnel.cpp"
|
||||
)
|
||||
target_link_libraries(UnitTest_IPC_Connect ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../include/gtest_custom.h"
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/pssup.h>
|
||||
#include "../../../sdv_services/ipc_connect/listener.h"
|
||||
#include "../../../sdv_services/ipc_connect/client.h"
|
||||
|
||||
TEST(IPC_Connect_Test, InstantiateLocalDefaultListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(R"code([Listener]
|
||||
Type = "Local"
|
||||
)code");
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Shutdown
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test, InstantiateLocalDedicatedListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(R"code([Listener]
|
||||
Type = "Local"
|
||||
Instance = 1234
|
||||
)code");
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Shutdown
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test, InstantiateLocalDefaultClientNoListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
|
||||
|
||||
// Start client
|
||||
CClient client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize("");
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
|
||||
Type = "local"
|
||||
)code");
|
||||
EXPECT_FALSE(ptrClient);
|
||||
|
||||
// Shutdown
|
||||
ptrClient.Clear();
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test, InstantiateLocalSpecificClientNoListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
|
||||
|
||||
// Start client
|
||||
CClient client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize("");
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
|
||||
Type = "local"
|
||||
Instance = 1234
|
||||
)code");
|
||||
EXPECT_FALSE(ptrClient);
|
||||
|
||||
// Shutdown
|
||||
ptrClient.Clear();
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
// Disabled the following test due to an unidentified crash/heap corruption occurring with MINGW on the build-server.
|
||||
// Bug-report #610009 describes this issue: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/610009
|
||||
#ifdef _WIN32
|
||||
TEST(IPC_Connect_Test, DISABLED_InstantiateLocalDefaultClientAndListener)
|
||||
#else
|
||||
TEST(IPC_Connect_Test, InstantiateLocalDefaultClientAndListener)
|
||||
#endif
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(R"code([Listener]
|
||||
Type = "Local"
|
||||
)code");
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Start client
|
||||
CClient client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize("");
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
|
||||
Type = "Local"
|
||||
)code");
|
||||
EXPECT_TRUE(ptrClient);
|
||||
|
||||
// The client is a pointer to the repository. Request the module control service
|
||||
sdv::core::IObjectAccess* pObjectAccess = ptrClient.GetInterface<sdv::core::IObjectAccess>();
|
||||
EXPECT_NE(pObjectAccess, nullptr);
|
||||
sdv::core::IModuleInfo* pModuleInfo = nullptr;
|
||||
if (pObjectAccess)
|
||||
pModuleInfo = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService")).GetInterface<sdv::core::IModuleInfo>();
|
||||
EXPECT_NE(pModuleInfo, nullptr);
|
||||
if (pModuleInfo)
|
||||
{
|
||||
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
|
||||
}
|
||||
|
||||
// Shutdown
|
||||
ptrClient.Clear();
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
// Disabled the following test due to an unidentified crash/heap corruption occurring with MINGW on the build-server.
|
||||
// Bug-report #610009 describes this issue: https://dev.azure.com/SW4ZF/AZP-074_DivDI_SofDCarResearch/_workitems/edit/610009
|
||||
#ifdef _WIN32
|
||||
TEST(IPC_Connect_Test, DISABLED_InstantiateLocalSpecificClientAndListener)
|
||||
#else
|
||||
TEST(IPC_Connect_Test, InstantiateLocalSpecificClientAndListener)
|
||||
#endif
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemoryChannelControl", {}, {}), 0);
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(R"code([Listener]
|
||||
Type = "Local"
|
||||
Instance = 1234
|
||||
)code");
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Start client
|
||||
CClient client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize("");
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::TObjectPtr ptrClient = client.Connect(R"code([Client]
|
||||
Type = "Local"
|
||||
Instance = 1234
|
||||
)code");
|
||||
EXPECT_TRUE(ptrClient);
|
||||
|
||||
// The client is a pointer to the repository. Request the module control service
|
||||
sdv::core::IObjectAccess* pObjectAccess = ptrClient.GetInterface<sdv::core::IObjectAccess>();
|
||||
EXPECT_NE(pObjectAccess, nullptr);
|
||||
sdv::core::IModuleInfo* pModuleInfo = nullptr;
|
||||
if (pObjectAccess)
|
||||
pModuleInfo = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService")).GetInterface<sdv::core::IModuleInfo>();
|
||||
EXPECT_NE(pModuleInfo, nullptr);
|
||||
if (pModuleInfo)
|
||||
{
|
||||
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
|
||||
}
|
||||
|
||||
// Shutdown
|
||||
ptrClient.Clear();
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
86
tests/unit_tests/ipc_connect/ipc_connect_false_positiv.cpp
Normal file
86
tests/unit_tests/ipc_connect/ipc_connect_false_positiv.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <support/app_control.h>
|
||||
#include <support/pssup.h>
|
||||
#include <support/sdv_core.h>
|
||||
|
||||
#include "../../../sdv_services/ipc_connect/client.h"
|
||||
#include "../../../sdv_services/ipc_connect/listener.h"
|
||||
#include "../../include/gtest_custom.h"
|
||||
|
||||
TEST(IPC_Connect_Test, InstantiateListenerWithUnknownProvider)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemory", {}, {}), 0);
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_failure);
|
||||
|
||||
// Shutdown
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_Shared_Mem, InstantiateClientWithoutConfiguration)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
|
||||
// Start client without configuration
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize(sdv::SObjectInfo());
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_failure);
|
||||
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
181
tests/unit_tests/ipc_connect/ipc_connect_shared_mem.cpp
Normal file
181
tests/unit_tests/ipc_connect/ipc_connect_shared_mem.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../include/gtest_custom.h"
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/pssup.h>
|
||||
#include <support/interface_ptr.h>
|
||||
#include "../../../sdv_services/ipc_connect/listener.h"
|
||||
#include "../../../sdv_services/ipc_connect/client.h"
|
||||
|
||||
TEST(IPC_Connect_Test_Shared_Mem, InstantiateListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
Instance = 1234
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("DefaultSharedMemory", {}, {}), 0);
|
||||
|
||||
sdv::SObjectInfo sListenerInfo{};
|
||||
sListenerInfo.ssConfig = R"toml(
|
||||
[Provider]
|
||||
Name = "DefaultSharedMemory"
|
||||
|
||||
[IpcChannel]
|
||||
Name = "MyPersonalChannelName"
|
||||
)toml";
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(sListenerInfo);
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
EXPECT_EQ(listener.GetProviderName(), "DefaultSharedMemory");
|
||||
|
||||
// Shutdown
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_Shared_Mem, InstantiateClientNoListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = R"toml(
|
||||
[Provider]
|
||||
Name = "DefaultSharedMemory"
|
||||
|
||||
[IpcChannel]
|
||||
Name = "MyPersonalChannelName"
|
||||
)toml";
|
||||
|
||||
// Start client
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize(sClientInfo);
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_FALSE(client.Connect());
|
||||
|
||||
// Shutdown
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_Shared_Mem, InstantiateClientAndListener)
|
||||
{
|
||||
// Initialize system
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
sdv::core::IModuleControl* pModuleControl = sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("ipc_shared_mem.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
sdv::core::IRepositoryControl* pRepositoryControl = sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
|
||||
sdv::SObjectInfo sListenerInfo{};
|
||||
sListenerInfo.ssConfig = R"toml([Provider]
|
||||
Name = "DefaultSharedMemory"
|
||||
[IpcChannel]
|
||||
Name = "CHANNEL_1234"
|
||||
)toml";
|
||||
|
||||
// Start listener
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
listener.Initialize(sListenerInfo);
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = R"toml([Provider]
|
||||
Name = "DefaultSharedMemory"
|
||||
[IpcChannel]
|
||||
Name = "CHANNEL_1234"
|
||||
)toml";
|
||||
|
||||
// Start client
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize(sClientInfo);
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_TRUE(client.Connect());
|
||||
EXPECT_TRUE(client.IsConnected());
|
||||
|
||||
// The client is a pointer to the repository. Request the module control service
|
||||
sdv::core::IObjectAccess* pObjectAccess =
|
||||
sdv::TInterfaceAccessPtr(client.GetRemoteRepository()).GetInterface<sdv::core::IObjectAccess>();
|
||||
EXPECT_NE(pObjectAccess, nullptr);
|
||||
sdv::core::IModuleInfo* pModuleInfo = nullptr;
|
||||
if (pObjectAccess)
|
||||
pModuleInfo = sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService")).GetInterface<sdv::core::IModuleInfo>();
|
||||
EXPECT_NE(pModuleInfo, nullptr);
|
||||
if (pModuleInfo)
|
||||
{
|
||||
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
|
||||
}
|
||||
EXPECT_TRUE(client.Disconnect());
|
||||
|
||||
// Shutdown
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
233
tests/unit_tests/ipc_connect/ipc_connect_uds.cpp
Normal file
233
tests/unit_tests/ipc_connect/ipc_connect_uds.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Denisa Ros - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../include/gtest_custom.h"
|
||||
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/pssup.h>
|
||||
#include <support/interface_ptr.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include "../../../sdv_services/ipc_connect/listener.h"
|
||||
#include "../../../sdv_services/ipc_connect/client.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const char* GetUdsModuleName()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return "uds_win_sockets.sdv";
|
||||
#else
|
||||
return "uds_unix_sockets.sdv";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* GetUdsChannelControlClassName()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return "WinSocketsChannelControl";
|
||||
#else
|
||||
return "UnixSocketsChannelControl";
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string UniqueSuffix()
|
||||
{
|
||||
const auto now = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||
return std::to_string(static_cast<long long>(now));
|
||||
}
|
||||
|
||||
std::string MakeChannelName(const char* base)
|
||||
{
|
||||
return std::string(base) + "_" + UniqueSuffix();
|
||||
}
|
||||
|
||||
std::string MakeUdsConfigByName(const std::string& channelName)
|
||||
{
|
||||
return std::string("[Provider]\n")
|
||||
+ "Name = \"unix_domain_sockets\"\n\n"
|
||||
+ "[IpcChannel]\n"
|
||||
+ "Name = \"" + channelName + "\"\n";
|
||||
}
|
||||
|
||||
void LoadRequiredModulesAndObjects(bool createUdsChannelControl = true)
|
||||
{
|
||||
auto* pModuleControl =
|
||||
sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load(GetUdsModuleName()), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
|
||||
auto* pRepositoryControl =
|
||||
sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
|
||||
if (createUdsChannelControl)
|
||||
{
|
||||
EXPECT_NE(
|
||||
pRepositoryControl->CreateObject(GetUdsChannelControlClassName(), {}, {}),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(IPC_Connect_Test_UDS, InstantiateListener)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
Instance = 1234
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
const std::string channelName = MakeChannelName("MyPersonalChannelName");
|
||||
|
||||
sdv::SObjectInfo sListenerInfo{};
|
||||
sListenerInfo.ssConfig = MakeUdsConfigByName(channelName);
|
||||
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
listener.Initialize(sListenerInfo);
|
||||
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets");
|
||||
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_UDS, InstantiateClientNoListener)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
const std::string channelName = MakeChannelName("MyPersonalChannelName");
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = MakeUdsConfigByName(channelName);
|
||||
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
client.Initialize(sClientInfo);
|
||||
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
std::cout << "Connecting client..." << std::endl;
|
||||
EXPECT_FALSE(client.Connect());
|
||||
std::cout << "Client failed to connect." << std::endl;
|
||||
EXPECT_FALSE(client.IsConnected());
|
||||
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_UDS, InstantiateClientAndListener)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
const std::string channelName = MakeChannelName("CHANNEL_1234");
|
||||
|
||||
sdv::SObjectInfo sListenerInfo{};
|
||||
sListenerInfo.ssConfig = MakeUdsConfigByName(channelName);
|
||||
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
listener.Initialize(sListenerInfo);
|
||||
|
||||
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets");
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Small delay to avoid startup races between listener init and client connect.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = MakeUdsConfigByName(channelName);
|
||||
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
client.Initialize(sClientInfo);
|
||||
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_TRUE(client.Connect());
|
||||
EXPECT_TRUE(client.IsConnected());
|
||||
|
||||
// The client should expose the remote repository after successful connect.
|
||||
sdv::core::IObjectAccess* pObjectAccess =
|
||||
sdv::TInterfaceAccessPtr(client.GetRemoteRepository())
|
||||
.GetInterface<sdv::core::IObjectAccess>();
|
||||
EXPECT_NE(pObjectAccess, nullptr);
|
||||
|
||||
sdv::core::IModuleInfo* pModuleInfo = nullptr;
|
||||
if (pObjectAccess)
|
||||
{
|
||||
pModuleInfo =
|
||||
sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService"))
|
||||
.GetInterface<sdv::core::IModuleInfo>();
|
||||
}
|
||||
|
||||
EXPECT_NE(pModuleInfo, nullptr);
|
||||
if (pModuleInfo)
|
||||
{
|
||||
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(client.Disconnect());
|
||||
std::cout << "Client Shutdown" << std::endl;
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
std::cout << "Listener Shutdown" << std::endl;
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
278
tests/unit_tests/ipc_connect/ipc_connect_uds_tunnel.cpp
Normal file
278
tests/unit_tests/ipc_connect/ipc_connect_uds_tunnel.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Denisa Ros - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../include/gtest_custom.h"
|
||||
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/pssup.h>
|
||||
#include <support/interface_ptr.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include "../../../sdv_services/ipc_connect/listener.h"
|
||||
#include "../../../sdv_services/ipc_connect/client.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const char* GetTunnelModuleName()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return "uds_win_tunnel.sdv";
|
||||
#else
|
||||
return "uds_unix_tunnel.sdv";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* GetTunnelChannelControlClassName()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return "WinTunnelChannelControl";
|
||||
#else
|
||||
return "UnixTunnelChannelControl";
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string UniqueSuffix()
|
||||
{
|
||||
const auto now = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||
return std::to_string(static_cast<long long>(now));
|
||||
}
|
||||
|
||||
std::string MakeChannelName(const char* base)
|
||||
{
|
||||
return std::string(base) + "_" + UniqueSuffix();
|
||||
}
|
||||
|
||||
std::string MakeTunnelName(const char* base)
|
||||
{
|
||||
return std::string("t_") + base + "_" + UniqueSuffix();
|
||||
}
|
||||
|
||||
std::string MakeTunnelConfigByName(const std::string& channelName,
|
||||
const std::string& tunnelName)
|
||||
{
|
||||
return std::string("[Provider]\n")
|
||||
+ "Name = \"unix_domain_sockets_tunnel\"\n\n"
|
||||
+ "[IpcChannel]\n"
|
||||
+ "Name = \"" + channelName + "\"\n"
|
||||
+ "Tunnel = \"" + tunnelName + "\"\n";
|
||||
}
|
||||
|
||||
void LoadRequiredModulesAndObjects(bool createTunnelChannelControl = true)
|
||||
{
|
||||
auto* pModuleControl =
|
||||
sdv::core::GetObject<sdv::core::IModuleControl>("ModuleControlService");
|
||||
ASSERT_NE(pModuleControl, nullptr);
|
||||
|
||||
EXPECT_NE(pModuleControl->Load("ipc_com.sdv"), 0);
|
||||
EXPECT_NE(pModuleControl->Load(GetTunnelModuleName()), 0);
|
||||
EXPECT_NE(pModuleControl->Load("core_ps.sdv"), 0);
|
||||
|
||||
auto* pRepositoryControl =
|
||||
sdv::core::GetObject<sdv::core::IRepositoryControl>("RepositoryService");
|
||||
ASSERT_NE(pRepositoryControl, nullptr);
|
||||
|
||||
EXPECT_NE(pRepositoryControl->CreateObject("CommunicationControl", {}, {}), 0);
|
||||
|
||||
if (createTunnelChannelControl)
|
||||
{
|
||||
EXPECT_NE(
|
||||
pRepositoryControl->CreateObject(GetTunnelChannelControlClassName(), {}, {}),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(IPC_Connect_Test_UDS_Tunnel, InstantiateListener)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
Instance = 1234
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
const std::string channelName = MakeChannelName("MyPersonalChannelName");
|
||||
const std::string tunnelName = MakeTunnelName("listener");
|
||||
|
||||
sdv::SObjectInfo sListenerInfo{};
|
||||
sListenerInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
|
||||
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
listener.Initialize(sListenerInfo);
|
||||
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets_tunnel");
|
||||
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_UDS_Tunnel, InstantiateClientNoListener)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
const std::string channelName = MakeChannelName("MyPersonalChannelName");
|
||||
const std::string tunnelName = MakeTunnelName("no_listener");
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
|
||||
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
client.Initialize(sClientInfo);
|
||||
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_FALSE(client.Connect());
|
||||
EXPECT_FALSE(client.IsConnected());
|
||||
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_UDS_Tunnel, InstantiateClientAndListener)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
const std::string channelName = MakeChannelName("CHANNEL_1234");
|
||||
const std::string tunnelName = MakeTunnelName("client_listener");
|
||||
|
||||
sdv::SObjectInfo sListenerInfo{};
|
||||
sListenerInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
|
||||
|
||||
CListener listener;
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
listener.Initialize(sListenerInfo);
|
||||
|
||||
EXPECT_EQ(listener.GetProviderName(), "unix_domain_sockets_tunnel");
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Allow listener endpoint publication to complete before client connect.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = MakeTunnelConfigByName(channelName, tunnelName);
|
||||
|
||||
CClientConnect client;
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialization_pending);
|
||||
|
||||
client.Initialize(sClientInfo);
|
||||
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_TRUE(client.Connect());
|
||||
EXPECT_TRUE(client.IsConnected());
|
||||
|
||||
// The client should expose the remote repository after successful connect.
|
||||
sdv::core::IObjectAccess* pObjectAccess =
|
||||
sdv::TInterfaceAccessPtr(client.GetRemoteRepository())
|
||||
.GetInterface<sdv::core::IObjectAccess>();
|
||||
EXPECT_NE(pObjectAccess, nullptr);
|
||||
|
||||
sdv::core::IModuleInfo* pModuleInfo = nullptr;
|
||||
if (pObjectAccess)
|
||||
{
|
||||
pModuleInfo =
|
||||
sdv::TInterfaceAccessPtr(pObjectAccess->GetObject("ModuleControlService"))
|
||||
.GetInterface<sdv::core::IModuleInfo>();
|
||||
}
|
||||
|
||||
EXPECT_NE(pModuleInfo, nullptr);
|
||||
if (pModuleInfo)
|
||||
{
|
||||
EXPECT_FALSE(pModuleInfo->GetModuleList().empty());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(client.Disconnect());
|
||||
|
||||
client.Shutdown();
|
||||
EXPECT_EQ(client.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
|
||||
listener.Shutdown();
|
||||
EXPECT_EQ(listener.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
|
||||
TEST(IPC_Connect_Test_UDS_Tunnel, InvalidProvider_ShouldNotInitializeClient)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"config(
|
||||
[Application]
|
||||
Mode = "Essential"
|
||||
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
)config"));
|
||||
ASSERT_TRUE(appcontrol.IsRunning());
|
||||
|
||||
LoadRequiredModulesAndObjects(true);
|
||||
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = R"toml(
|
||||
[Provider]
|
||||
Name = "invalid_tunnel_provider"
|
||||
|
||||
[IpcChannel]
|
||||
Name = "CHANNEL_1234"
|
||||
Tunnel = "t_invalid_provider"
|
||||
)toml";
|
||||
|
||||
CClientConnect client;
|
||||
client.Initialize(sClientInfo);
|
||||
|
||||
EXPECT_NE(client.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_FALSE(client.Connect());
|
||||
EXPECT_FALSE(client.IsConnected());
|
||||
|
||||
client.Shutdown();
|
||||
appcontrol.Shutdown();
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/code_snippet.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_indexer.cpp"
|
||||
#include "../../../sdv_services/core/module_control.cpp"
|
||||
#include "../../../sdv_services/core/module.cpp"
|
||||
#include "../../../sdv_services/core/app_config.cpp"
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
bool IsConsoleSilent() { return true; }
|
||||
bool IsConsoleVerbose() { return false; }
|
||||
uint32_t GetInstanceID() { return 1234u; }
|
||||
std::filesystem::path GetFrameworkDir() const { return GetExecDirectory(); }
|
||||
std::filesystem::path GetRootDir() const { return GetExecDirectory(); }
|
||||
std::filesystem::path GetInstallDir() const { return GetExecDirectory(); }
|
||||
std::vector<std::filesystem::path> GetSystemConfigPaths() const { return {}; }
|
||||
@@ -117,7 +118,4 @@ inline CRepository& GetRepository()
|
||||
#include "../../../sdv_services/core/app_settings.h"
|
||||
#include "../../../sdv_services/core/app_config.h"
|
||||
|
||||
//inline std::filesystem::path GetCoreDirectoryMock() { return "../../bin"; }
|
||||
//#define GetCoreDirectory GetCoreDirectoryMock
|
||||
|
||||
#endif // !defined MOCK_H
|
||||
@@ -17,6 +17,16 @@
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string MakeUniqueMutexName(const char* suffix)
|
||||
{
|
||||
return std::string("HELLO_") + suffix + "_" +
|
||||
std::to_string(std::chrono::high_resolution_clock::now().time_since_epoch().count());
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
@@ -32,12 +42,14 @@ extern "C" int main(int argc, char* argv[])
|
||||
|
||||
TEST(NamedMutexTest, Construction)
|
||||
{
|
||||
ipc::named_mutex mtx("HELLO");
|
||||
ipc::named_mutex mtx(MakeUniqueMutexName("Construction"));
|
||||
EXPECT_NE(mtx.native_handle(), nullptr);
|
||||
}
|
||||
|
||||
TEST(NamedMutexTest, CritSectSyncManualLock)
|
||||
{
|
||||
const std::string mutexName = MakeUniqueMutexName("CritSectSyncManualLock");
|
||||
|
||||
// Counter function check for correct counter value.
|
||||
// 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.
|
||||
@@ -46,7 +58,7 @@ TEST(NamedMutexTest, CritSectSyncManualLock)
|
||||
std::atomic_bool bEnable = false;
|
||||
auto fn = [&]()
|
||||
{
|
||||
ipc::named_mutex mtx("HELLO");
|
||||
ipc::named_mutex mtx(mutexName);
|
||||
|
||||
if (bEnable)
|
||||
mtx.lock();
|
||||
@@ -81,12 +93,14 @@ TEST(NamedMutexTest, CritSectSyncManualLock)
|
||||
|
||||
TEST(NamedMutexTest, CritSectSyncAutoLock)
|
||||
{
|
||||
const std::string mutexName = MakeUniqueMutexName("CritSectSyncAutoLock");
|
||||
|
||||
// Counter function check for correct counter value.
|
||||
int32_t iCnt = 0;
|
||||
std::atomic_bool bSuccess = true;
|
||||
auto fn = [&]()
|
||||
{
|
||||
ipc::named_mutex mtx("HELLO");
|
||||
ipc::named_mutex mtx(mutexName);
|
||||
|
||||
std::unique_lock<ipc::named_mutex> lock(mtx);
|
||||
bSuccess = bSuccess && (iCnt == 0);
|
||||
@@ -108,10 +122,12 @@ TEST(NamedMutexTest, CritSectSyncAutoLock)
|
||||
|
||||
TEST(NamedMutexTest, TryLock)
|
||||
{
|
||||
const std::string mutexName = MakeUniqueMutexName("TryLock");
|
||||
|
||||
std::atomic_bool bRunning = false;
|
||||
auto fn = [&]()
|
||||
{
|
||||
ipc::named_mutex mtx("HELLO");
|
||||
ipc::named_mutex mtx(mutexName);
|
||||
|
||||
mtx.lock();
|
||||
while (bRunning) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
@@ -123,7 +139,7 @@ TEST(NamedMutexTest, TryLock)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
|
||||
// Try locking; doesn't work since thread still locks.
|
||||
ipc::named_mutex mtx2("HELLO");
|
||||
ipc::named_mutex mtx2(mutexName);
|
||||
EXPECT_FALSE(mtx2.try_lock());
|
||||
|
||||
bRunning = false;
|
||||
@@ -137,7 +153,7 @@ TEST(NamedMutexTest, TryLock)
|
||||
|
||||
TEST(NamedMutexTest, Naming)
|
||||
{
|
||||
ipc::named_mutex mtx1("HELLO");
|
||||
ipc::named_mutex mtx1(MakeUniqueMutexName("Naming"));
|
||||
EXPECT_FALSE(mtx1.name().empty());
|
||||
|
||||
ipc::named_mutex mtx2;
|
||||
|
||||
@@ -834,22 +834,23 @@ public:
|
||||
InitParamMap();
|
||||
}
|
||||
|
||||
|
||||
BEGIN_SDV_PARAM_MAP()
|
||||
SDV_PARAM_SET_READONLY()
|
||||
SDV_PARAM_ENTRY(m_i, "my_integer", 10, "int_unit", "My integer")
|
||||
SDV_PARAM_ENTRY(m_i, "my_integer", 20, "int_unit", "My integer")
|
||||
SDV_PARAM_RESET_READONLY()
|
||||
SDV_PARAM_ENTRY(m_d, "my_double", 1234.5, "double_unit", "My double")
|
||||
SDV_PARAM_SET_READONLY()
|
||||
SDV_PARAM_ENTRY(m_ss, "my_string", "string_value", "string_unit", "My string")
|
||||
SDV_PARAM_ENTRY(m_ss, "my_string", "value_string", "string_unit", "My string")
|
||||
SDV_PARAM_RESET_ATTRIBUTES()
|
||||
SDV_PARAM_ENTRY(m_b, "my_boolean", true, "no_unit", "My boolean")
|
||||
END_SDV_PARAM_MAP()
|
||||
|
||||
private:
|
||||
int m_i;
|
||||
double m_d;
|
||||
std::string m_ss;
|
||||
bool m_b;
|
||||
int m_i = 10; // Read only; will not be overwritten
|
||||
double m_d = 5432.1; // Writable, will be overwritten
|
||||
std::string m_ss = "string_value"; // Read only; will not be overwritten
|
||||
bool m_b = false; // Writable, will be overwritten
|
||||
};
|
||||
|
||||
TEST(ParameterTest, ReadOnlyParamMapStaticInfo)
|
||||
@@ -869,7 +870,7 @@ TEST(ParameterTest, ReadOnlyParamMapStaticInfo)
|
||||
EXPECT_EQ(ptrParamInfo->Name(), "my_integer");
|
||||
EXPECT_EQ(ptrParamInfo->Unit(), "int_unit");
|
||||
EXPECT_EQ(ptrParamInfo->Description(), "My integer");
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), 10);
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), 20);
|
||||
EXPECT_TRUE(ptrParamInfo->ReadOnly());
|
||||
|
||||
// Get parameter #1 global information
|
||||
@@ -889,7 +890,7 @@ TEST(ParameterTest, ReadOnlyParamMapStaticInfo)
|
||||
EXPECT_EQ(ptrParamInfo->Name(), "my_string");
|
||||
EXPECT_EQ(ptrParamInfo->Unit(), "string_unit");
|
||||
EXPECT_EQ(ptrParamInfo->Description(), "My string");
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), "string_value");
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), "value_string");
|
||||
EXPECT_TRUE(ptrParamInfo->ReadOnly());
|
||||
|
||||
// Get parameter #3 global information
|
||||
@@ -922,7 +923,7 @@ TEST(ParameterTest, ReadOnlyParamMapObjectInfo)
|
||||
EXPECT_TRUE(ptrParamInfo->Numeric());
|
||||
EXPECT_EQ(ptrParamInfo->Unit(), "int_unit");
|
||||
EXPECT_EQ(ptrParamInfo->Description(), "My integer");
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), 10);
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), 20);
|
||||
EXPECT_TRUE(ptrParamInfo->ReadOnly());
|
||||
|
||||
// Get parameter #1 global information
|
||||
@@ -940,7 +941,7 @@ TEST(ParameterTest, ReadOnlyParamMapObjectInfo)
|
||||
EXPECT_TRUE(ptrParamInfo->String());
|
||||
EXPECT_EQ(ptrParamInfo->Unit(), "string_unit");
|
||||
EXPECT_EQ(ptrParamInfo->Description(), "My string");
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), "string_value");
|
||||
EXPECT_EQ(ptrParamInfo->DefaultVal(), "value_string");
|
||||
EXPECT_TRUE(ptrParamInfo->ReadOnly());
|
||||
|
||||
// Get parameter #3 global information
|
||||
@@ -971,7 +972,7 @@ TEST(ParameterTest, ReadOnlyParamMapObjectInfoIndirect)
|
||||
EXPECT_TRUE(info.Numeric());
|
||||
EXPECT_EQ(info.Unit(), "int_unit");
|
||||
EXPECT_EQ(info.Description(), "My integer");
|
||||
EXPECT_EQ(info.DefaultVal(), 10);
|
||||
EXPECT_EQ(info.DefaultVal(), 20);
|
||||
EXPECT_TRUE(info.ReadOnly());
|
||||
|
||||
// Get parameter #1 global information
|
||||
@@ -987,7 +988,7 @@ TEST(ParameterTest, ReadOnlyParamMapObjectInfoIndirect)
|
||||
EXPECT_TRUE(info.String());
|
||||
EXPECT_EQ(info.Unit(), "string_unit");
|
||||
EXPECT_EQ(info.Description(), "My string");
|
||||
EXPECT_EQ(info.DefaultVal(), "string_value");
|
||||
EXPECT_EQ(info.DefaultVal(), "value_string");
|
||||
EXPECT_TRUE(info.ReadOnly());
|
||||
|
||||
// Get parameter #2 global information
|
||||
|
||||
33
tests/unit_tests/permission_control/CMakeLists.txt
Normal file
33
tests/unit_tests/permission_control/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Apache License Version 2.0 which is available at
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Erik Verhoeven - initial API and implementation
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project (UnitTest_PermissionControl VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Compile the source code
|
||||
add_executable(UnitTest_PermissionControl
|
||||
"main.cpp"
|
||||
"permission_control_tests.cpp")
|
||||
target_link_libraries(UnitTest_PermissionControl ${CMAKE_DL_LIBS} GTest::GTest)
|
||||
|
||||
# Add the IDL Compiler unittest
|
||||
add_test(NAME UnitTest_PermissionControl COMMAND UnitTest_PermissionControl)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_PermissionControl POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_PermissionControl>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_PermissionControl.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(UnitTest_PermissionControl dependency_sdv_components)
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/permission_control.cpp"
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
@@ -26,7 +26,6 @@ extern "C" int main(int argc, char* argv[])
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
CLocalMemMgr memmgr;
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
264
tests/unit_tests/permission_control/permission_control_tests.cpp
Normal file
264
tests/unit_tests/permission_control/permission_control_tests.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <optional>
|
||||
#include "../../include/gtest_custom.h"
|
||||
#include "../../../sdv_services/core/permission_control.h"
|
||||
|
||||
TEST(PermissionControl, DefaultRestriction)
|
||||
{
|
||||
CPermissionControl control;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
}
|
||||
|
||||
TEST(PermissionControl, SetRestrictionInternal)
|
||||
{
|
||||
CPermissionControl control;
|
||||
std::vector<CAccessPermission> vecPermissions;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Full access
|
||||
vecPermissions.emplace_back(control.CreatePermissionObject(sdv::core::EAccessPermission::full_access));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
|
||||
// Reduce access to local access
|
||||
vecPermissions.emplace_back(control.CreatePermissionObject(sdv::core::EAccessPermission::local_access));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
|
||||
// Reduce access to remote access
|
||||
vecPermissions.emplace_back(control.CreatePermissionObject(sdv::core::EAccessPermission::remote_access));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
|
||||
// Reduce access to restricted access
|
||||
vecPermissions.emplace_back(control.CreatePermissionObject(sdv::core::EAccessPermission::restricted_access));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Try increase access to full access - this should not have any change
|
||||
vecPermissions.emplace_back(control.CreatePermissionObject(sdv::core::EAccessPermission::full_access));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Remove the local access index #1 - this should not have any change
|
||||
EXPECT_EQ(vecPermissions[1].Permission(), sdv::core::EAccessPermission::local_access);
|
||||
vecPermissions.erase(vecPermissions.begin() + 1);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Remove first full access index #0 - this should not have any change
|
||||
EXPECT_EQ(vecPermissions[0].Permission(), sdv::core::EAccessPermission::full_access);
|
||||
vecPermissions.erase(vecPermissions.begin());
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Remove remote access new index #0 - this should not have any change
|
||||
EXPECT_EQ(vecPermissions[0].Permission(), sdv::core::EAccessPermission::remote_access);
|
||||
vecPermissions.erase(vecPermissions.begin());
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Remove restricted access new index #0 - access will change to full access
|
||||
EXPECT_EQ(vecPermissions[0].Permission(), sdv::core::EAccessPermission::restricted_access);
|
||||
vecPermissions.erase(vecPermissions.begin());
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
|
||||
// Remove the remaining access - this would change to (default) restricted access again
|
||||
vecPermissions.clear();
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
}
|
||||
|
||||
TEST(PermissionControl, SetRestrictionExternal)
|
||||
{
|
||||
CPermissionControl control;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Try to set external permission to full access; this will not work
|
||||
EXPECT_EQ(control.RestrictAccessPermission(sdv::core::EAccessPermission::full_access), 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Try to set external permission to local access; this will not work
|
||||
EXPECT_EQ(control.RestrictAccessPermission(sdv::core::EAccessPermission::local_access), 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Try to set external permission to remote access; this will not work
|
||||
EXPECT_EQ(control.RestrictAccessPermission(sdv::core::EAccessPermission::remote_access), 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Try to set external permission to restricted access; this will not work
|
||||
EXPECT_EQ(control.RestrictAccessPermission(sdv::core::EAccessPermission::restricted_access), 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
}
|
||||
|
||||
TEST(PermissionControl, InitializeRestrictionInternal_SetRestrictionExternal)
|
||||
{
|
||||
CPermissionControl control;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Set restriction to full access
|
||||
std::optional<CAccessPermission> optPermission = control.CreatePermissionObject(sdv::core::EAccessPermission::full_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
|
||||
// Set external permission to local access
|
||||
sdv::core::TPermissionID permidLocalAccess = control.RestrictAccessPermission(sdv::core::EAccessPermission::local_access);
|
||||
EXPECT_NE(permidLocalAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
|
||||
// Set external permission to remote access
|
||||
sdv::core::TPermissionID permidRemoteAccess = control.RestrictAccessPermission(sdv::core::EAccessPermission::remote_access);
|
||||
EXPECT_NE(permidRemoteAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
|
||||
// Set external permission to restricted access
|
||||
sdv::core::TPermissionID permidRestrictedAccess =
|
||||
control.RestrictAccessPermission(sdv::core::EAccessPermission::restricted_access);
|
||||
EXPECT_NE(permidRestrictedAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Set external permission to full access - this will not change the access
|
||||
sdv::core::TPermissionID permidFullAccess = control.RestrictAccessPermission(sdv::core::EAccessPermission::full_access);
|
||||
EXPECT_NE(permidFullAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Release not existing access ID - should not work
|
||||
EXPECT_FALSE(control.ReleaseAccessPermission(0));
|
||||
EXPECT_FALSE(control.ReleaseAccessPermission(1));
|
||||
|
||||
// Release local, restricted and full access - this will change access to remote access
|
||||
EXPECT_TRUE(control.ReleaseAccessPermission(permidLocalAccess));
|
||||
EXPECT_TRUE(control.ReleaseAccessPermission(permidRestrictedAccess));
|
||||
EXPECT_TRUE(control.ReleaseAccessPermission(permidFullAccess));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
|
||||
// Release local again - should not work
|
||||
EXPECT_FALSE(control.ReleaseAccessPermission(permidLocalAccess));
|
||||
|
||||
// Terminate internal full access - access should stay with remote access
|
||||
optPermission.reset();
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
|
||||
// Release remote access - the access permission will change to restricted access again
|
||||
EXPECT_TRUE(control.ReleaseAccessPermission(permidRemoteAccess));
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
}
|
||||
|
||||
TEST(PermissionControl, DefaultThreadPermission)
|
||||
{
|
||||
CPermissionControl control;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Set restriction to full access
|
||||
CAccessPermission permission = control.CreatePermissionObject(sdv::core::EAccessPermission::full_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
|
||||
// Start new thread - access should be restricted
|
||||
std::thread thread([&]()
|
||||
{
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
});
|
||||
thread.join();
|
||||
}
|
||||
|
||||
TEST(PermissionControl, InternalSetThreadPermission)
|
||||
{
|
||||
CPermissionControl control;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Set restriction to local access
|
||||
CAccessPermission permission = control.CreatePermissionObject(sdv::core::EAccessPermission::local_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
|
||||
// Start new thread - access should be restricted
|
||||
std::thread thread([&]()
|
||||
{
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Set full access permission
|
||||
CAccessPermission permissionFullAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::full_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
|
||||
// Set local access permission
|
||||
CAccessPermission permissionLocalAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::local_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
|
||||
// Set remote access permission
|
||||
CAccessPermission permissionRemoteAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::remote_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
|
||||
// Set restricted access permission
|
||||
CAccessPermission permissionRestrictedAccess =
|
||||
control.CreatePermissionObject(sdv::core::EAccessPermission::restricted_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
});
|
||||
thread.join();
|
||||
|
||||
// Access permissions on main thread should still be local
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
}
|
||||
|
||||
TEST(PermissionControl, TransferThreadPermission)
|
||||
{
|
||||
CPermissionControl control;
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Set restriction to full access
|
||||
CAccessPermission permissionFullAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::full_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
sdv::core::TPermissionID transferFullAccess = control.TransferCurrentPermission();
|
||||
EXPECT_NE(transferFullAccess, 0u);
|
||||
|
||||
// Set restriction to local access
|
||||
CAccessPermission permissionLocalAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::local_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
sdv::core::TPermissionID transferLocalAccess = control.TransferCurrentPermission();
|
||||
EXPECT_NE(transferLocalAccess, 0u);
|
||||
|
||||
// Set restriction to remote access
|
||||
CAccessPermission permissionRemoteAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::remote_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
sdv::core::TPermissionID transferRemoteAccess = control.TransferCurrentPermission();
|
||||
EXPECT_NE(transferRemoteAccess, 0u);
|
||||
|
||||
// Set restriction to restricted access
|
||||
CAccessPermission permissionRestrictedAccess = control.CreatePermissionObject(sdv::core::EAccessPermission::restricted_access);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
sdv::core::TPermissionID transferRestrictedAccess = control.TransferCurrentPermission();
|
||||
EXPECT_NE(transferRestrictedAccess, 0u);
|
||||
|
||||
// Start new thread - access should be restricted
|
||||
std::thread thread([&]()
|
||||
{
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// Tets bogus transfer IDs
|
||||
EXPECT_FALSE(control.SetAccessPermission(0));
|
||||
EXPECT_FALSE(control.SetAccessPermission(1));
|
||||
|
||||
// Set full access permission from transfer ID
|
||||
sdv::core::TPermissionID permidFullAccess = control.SetAccessPermission(transferFullAccess);
|
||||
EXPECT_NE(permidFullAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::full_access);
|
||||
|
||||
// Set local access permission from transfer ID
|
||||
sdv::core::TPermissionID permidLocalAccess = control.SetAccessPermission(transferLocalAccess);
|
||||
EXPECT_NE(permidLocalAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::local_access);
|
||||
|
||||
// Set remote access permission from transfer ID
|
||||
sdv::core::TPermissionID permidRemoteAccess = control.SetAccessPermission(transferRemoteAccess);
|
||||
EXPECT_NE(permidRemoteAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::remote_access);
|
||||
|
||||
// Set restricted access permission from transfer ID
|
||||
sdv::core::TPermissionID permidRestrictedAccess = control.SetAccessPermission(transferRestrictedAccess);
|
||||
EXPECT_NE(permidRestrictedAccess, 0u);
|
||||
EXPECT_EQ(control.GetCurrentPermission(), sdv::core::EAccessPermission::restricted_access);
|
||||
|
||||
// At the end of the thread, the IDs will be cleaned up automatically.
|
||||
});
|
||||
thread.join();
|
||||
}
|
||||
@@ -44,8 +44,8 @@ extern "C" int main(int argc, char* argv[])
|
||||
EOperatingmode eMode = static_cast<EOperatingmode>(std::atoi(sdv::MakeAnsiString(argv[1]).c_str()));
|
||||
|
||||
sdv::app::CAppControl appcontrol;
|
||||
if (!appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"))
|
||||
if (!appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"))
|
||||
{
|
||||
std::cout << GetTimestamp() << "Failed to start app control..." << std::endl;
|
||||
return -1;
|
||||
@@ -89,7 +89,7 @@ Mode="Maintenance")code"))
|
||||
std::cout << GetTimestamp() << "Waiting for process with PID#" << std::dec << tProcessID << std::endl;
|
||||
CProcessMonitorHelper monitor;
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
uint32_t uiMon = control.RegisterMonitor(tProcessID, &monitor);
|
||||
if (!uiMon)
|
||||
{
|
||||
@@ -134,7 +134,7 @@ Mode="Maintenance")code"))
|
||||
std::cout << GetTimestamp() << "Terminate process with PID#" << std::dec << tProcessID << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Make certain, that the first process is actually running...
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
nResult = control.Terminate(tProcessID) ? 0 : -20;
|
||||
control.Shutdown(); // Needed to prevent clash with core
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
TEST(ProcessControlTest, Instantiate)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessControl control;
|
||||
EXPECT_EQ(control.GetProcessID(), static_cast<sdv::process::TProcessID>(getpid()));
|
||||
@@ -35,11 +35,11 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteProcessNormalShutdown)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -61,11 +61,11 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteProcessEmergencyExit)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -87,13 +87,13 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteProcessNormalShutdownWithMonitor)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -119,13 +119,13 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteProcessEmergencyExitWithMonitor)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -151,14 +151,14 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteMultiProcessNormalShutdown)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -198,14 +198,14 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteMultiEmergencyAccess)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -244,13 +244,13 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteProcessAndTerminate)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -265,7 +265,7 @@ Mode="Maintenance")code"));
|
||||
EXPECT_NE(uiCookie, 0u);
|
||||
|
||||
bool bTerminateResult = false;
|
||||
std::thread thread([&]()
|
||||
sdv::core::secure_thread thread([&]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
bTerminateResult = control.Terminate(tProcessID);
|
||||
@@ -285,14 +285,14 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ParentRightsExecuteMultiTerminate)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -330,11 +330,11 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteProcessNormalShutdown)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -356,11 +356,11 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteProcessEmergencyExit)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -382,13 +382,13 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteProcessNormalShutdownWithMonitor)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -414,13 +414,13 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteProcessEmergencyExitWithMonitor)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -446,14 +446,14 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteMultiProcessNormalShutdown)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -491,14 +491,14 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteMultiEmergencyAccess)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -537,13 +537,13 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteProcessAndTerminate)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -558,7 +558,7 @@ Mode="Maintenance")code"));
|
||||
EXPECT_NE(uiCookie, 0u);
|
||||
|
||||
bool bTerminateResult = false;
|
||||
std::thread thread([&]()
|
||||
sdv::core::secure_thread thread([&]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
bTerminateResult = control.Terminate(tProcessID);
|
||||
@@ -578,14 +578,14 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ReducedRightsExecuteMultiTerminate)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
@@ -623,15 +623,15 @@ Mode="Maintenance")code"));
|
||||
TEST(ProcessControlTest, ExecuteProcessNormalShutdownWithMultipleMonitors)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode="Maintenance")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode="Maintenance")toml"));
|
||||
|
||||
CProcessMonitorHelper monitor1;
|
||||
CProcessMonitorHelper monitor2;
|
||||
CProcessMonitorHelper monitor3;
|
||||
|
||||
CProcessControl control;
|
||||
control.Initialize(""); // Needed since local instantiation
|
||||
control.Initialize(sdv::SObjectInfo()); // Needed since local instantiation
|
||||
#ifdef _WIN32
|
||||
const std::string ssModule = "UnitTest_ProcessControlApp.exe";
|
||||
#else
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/code_snippet.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_indexer.cpp"
|
||||
#include "../../../sdv_services/core/module_control.cpp"
|
||||
#include "../../../sdv_services/core/module.cpp"
|
||||
#include "../../../sdv_services/core/repository.cpp"
|
||||
#include "../../../sdv_services/core/permission_control.cpp"
|
||||
#include "../../../sdv_services/core/iso_monitor.cpp"
|
||||
#include "../../../sdv_services/core/object_lifetime_control.cpp"
|
||||
#include "../../../sdv_services/core/app_config.cpp"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define MOCK_H
|
||||
|
||||
#include <interfaces/app.h>
|
||||
#include <interfaces/permission.h>
|
||||
#include <support/component_impl.h>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "../../../sdv_services/core/installation_manifest.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
#define APP_CONTROL_H
|
||||
#define LOGGER_H
|
||||
#define LOGGER_CONTROL_H
|
||||
//#define PERMISSION_CONTROL_H
|
||||
|
||||
/**
|
||||
* @brief CAppSettings redefined
|
||||
@@ -45,6 +47,7 @@ public:
|
||||
bool IsConsoleSilent() { return true; }
|
||||
bool IsConsoleVerbose() { return false; }
|
||||
uint32_t GetInstanceID() { return 1000u; }
|
||||
std::filesystem::path GetFrameworkDir() const { return GetExecDirectory(); }
|
||||
std::filesystem::path GetRootDir() const { return GetExecDirectory(); }
|
||||
std::filesystem::path GetInstallDir() const { return GetExecDirectory(); }
|
||||
std::vector<std::filesystem::path> GetSystemConfigPaths() const { return {}; }
|
||||
@@ -105,15 +108,36 @@ inline CLoggerControl& GetLoggerControl()
|
||||
return logger_control;
|
||||
}
|
||||
|
||||
///**
|
||||
// * @brief CPermissionControl redefined
|
||||
// */
|
||||
//class CPermissionControl : public sdv::IInterfaceAccess
|
||||
//{
|
||||
//public:
|
||||
// BEGIN_SDV_INTERFACE_MAP()
|
||||
// END_SDV_INTERFACE_MAP()
|
||||
//
|
||||
// // CPermissionControl mocked functions
|
||||
// virtual sdv::core::EAccessPermission GetCurrentPermission() const { return sdv::core::EAccessPermission::full_access; }
|
||||
//};
|
||||
//
|
||||
///**
|
||||
// * @brief Return the permission control.
|
||||
// * @return Reference to the permission control.
|
||||
// */
|
||||
//inline CPermissionControl& GetPermissionControl()
|
||||
//{
|
||||
// static CPermissionControl control;
|
||||
// return control;
|
||||
//}
|
||||
//
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/module_control.h"
|
||||
#include "../../../sdv_services/core/repository.h"
|
||||
#include "../../../sdv_services/core/permission_control.h"
|
||||
#include "../../../sdv_services/core/app_config.h"
|
||||
|
||||
//inline std::filesystem::path GetCoreDirectoryMock() { return "../../bin"; }
|
||||
//#define GetCoreDirectory GetCoreDirectoryMock
|
||||
|
||||
class CHelper
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
virtual void Initialize([[maybe_unused]] const sdv::u8string& ssObjectConfig) override
|
||||
virtual void Initialize([[maybe_unused]] const sdv::SObjectInfo& sObjectInfo) override
|
||||
{
|
||||
FAIL() << "Error: Initialize should not be called by Repo Service!";
|
||||
//m_eObjectState = sdv::EObjectState::initialization_failure;
|
||||
@@ -91,8 +91,8 @@ TEST(RepositoryTest, CreateNonexistentClass)
|
||||
CModuleControl modulectrl;
|
||||
CHelper helper(modulectrl, repository);
|
||||
ASSERT_TRUE(modulectrl.Load((GetExecDirectory() / "UnitTest_Repository_test_module.sdv").generic_u8string()));
|
||||
EXPECT_FALSE(repository.CreateObject2("TestFooBar", nullptr, nullptr));
|
||||
repository.DestroyObject2("TestFooBar");
|
||||
EXPECT_FALSE(repository.CreateObject("TestFooBar", nullptr, nullptr));
|
||||
EXPECT_FALSE(repository.DestroyObject("TestFooBar"));
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, GetNonexistentObject)
|
||||
@@ -100,11 +100,11 @@ TEST(RepositoryTest, GetNonexistentObject)
|
||||
CRepository repository; // Must be created first
|
||||
CModuleControl modulectrl;
|
||||
CHelper helper(modulectrl, repository);
|
||||
auto permission = GetPermissionControl().CreatePermissionObject(sdv::core::EAccessPermission::full_access);
|
||||
ASSERT_TRUE(modulectrl.Load((GetExecDirectory() / "UnitTest_Repository_test_module.sdv").generic_u8string()));
|
||||
bool bRes = repository.CreateObject2("Example_Object", nullptr, nullptr);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_TRUE(repository.CreateObject("Example_Object", nullptr, nullptr));
|
||||
EXPECT_EQ(nullptr, repository.GetObject("TestFooBar"));
|
||||
repository.DestroyObject2("Example_Object");
|
||||
EXPECT_TRUE(repository.DestroyObject("Example_Object"));
|
||||
}
|
||||
|
||||
TEST(RepositoryTest, InstantiateAndGet)
|
||||
@@ -112,11 +112,12 @@ TEST(RepositoryTest, InstantiateAndGet)
|
||||
CRepository repository; // Must be created first
|
||||
CModuleControl modulectrl;
|
||||
CHelper helper(modulectrl, repository);
|
||||
auto permission = GetPermissionControl().CreatePermissionObject(sdv::core::EAccessPermission::full_access);
|
||||
ASSERT_TRUE(modulectrl.Load((GetExecDirectory() / "UnitTest_Repository_test_module.sdv").generic_u8string()));
|
||||
bool bRes = repository.CreateObject2("Example_Object", nullptr, nullptr);
|
||||
bool bRes = repository.CreateObject("Example_Object", nullptr, nullptr);
|
||||
EXPECT_TRUE(bRes);
|
||||
EXPECT_NE(nullptr, repository.GetObject("Example_Object"));
|
||||
repository.DestroyObject2("Example_Object");
|
||||
EXPECT_TRUE(repository.DestroyObject("Example_Object"));
|
||||
EXPECT_EQ(nullptr, repository.GetObject("Example_Object"));
|
||||
}
|
||||
|
||||
@@ -126,8 +127,7 @@ TEST(RepositoryTest, InstantiateInitFail)
|
||||
CModuleControl modulectrl;
|
||||
CHelper helper(modulectrl, repository);
|
||||
ASSERT_TRUE(modulectrl.Load((GetExecDirectory() / "UnitTest_Repository_test_module.sdv").generic_u8string()));
|
||||
bool bRes = repository.CreateObject2("TestObject_IObjectControlFail", nullptr, nullptr);
|
||||
EXPECT_FALSE(bRes);
|
||||
EXPECT_FALSE(repository.CreateObject("TestObject_IObjectControlFail", nullptr, nullptr));
|
||||
EXPECT_EQ(nullptr, repository.GetObject("TestObject_IObjectControlFail"));
|
||||
repository.DestroyObject2("TestObject_IObjectControlFail");
|
||||
EXPECT_FALSE(repository.DestroyObject("TestObject_IObjectControlFail"));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/scheduler/scheduler.cpp"
|
||||
#include "../../../global/scheduler/scheduler.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
@@ -31,7 +31,7 @@ extern "C" int main(int argc, char* argv[])
|
||||
|
||||
TEST(TaskSchedulerTest, Construction)
|
||||
{
|
||||
CTaskScheduler scheduler(2);
|
||||
CTaskScheduler<std::thread, 2> scheduler;
|
||||
EXPECT_EQ(scheduler.GetThreadCount(), 2);
|
||||
EXPECT_EQ(scheduler.GetBusyThreadCount(), 0);
|
||||
EXPECT_EQ(scheduler.GetIdleThreadCount(), 2);
|
||||
@@ -50,7 +50,7 @@ TEST(TaskSchedulerTest, Construction)
|
||||
|
||||
TEST(TaskSchedulerTest, PreallocatedConcurrencyExecution)
|
||||
{
|
||||
CTaskScheduler scheduler(4);
|
||||
CTaskScheduler<std::thread, 4> scheduler;
|
||||
|
||||
// Schedule tasks onto 4 threads
|
||||
std::atomic_size_t nExecuted = 0;
|
||||
@@ -74,7 +74,7 @@ TEST(TaskSchedulerTest, PreallocatedConcurrencyExecution)
|
||||
|
||||
TEST(TaskSchedulerTest, AllocateConcurrency)
|
||||
{
|
||||
CTaskScheduler scheduler(2);
|
||||
CTaskScheduler<std::thread, 2> scheduler;
|
||||
|
||||
// Schedule 4 tasks onto two threads pre-allocated and two just-in-time-allocated threads
|
||||
std::atomic_size_t nExecuted = 0;
|
||||
@@ -98,7 +98,7 @@ TEST(TaskSchedulerTest, AllocateConcurrency)
|
||||
|
||||
TEST(TaskSchedulerTest, ConcurrencyAndTaskQueueing)
|
||||
{
|
||||
CTaskScheduler scheduler(2, 2);
|
||||
CTaskScheduler<std::thread, 2, 2> scheduler;
|
||||
|
||||
// Schedule 4 tasks onto two threads
|
||||
std::atomic_size_t nExecuted = 0;
|
||||
@@ -122,7 +122,7 @@ TEST(TaskSchedulerTest, ConcurrencyAndTaskQueueing)
|
||||
|
||||
TEST(TaskSchedulerTest, ConcurrencyAndDisallowTaskQueueing)
|
||||
{
|
||||
CTaskScheduler scheduler(2, 2);
|
||||
CTaskScheduler<std::thread, 2, 2> scheduler;
|
||||
|
||||
// Schedule 4 tasks onto two threads.. Disallow the second task to be queued and the fourth task to be queued.
|
||||
std::atomic_size_t nExecuted = 0;
|
||||
@@ -133,7 +133,8 @@ TEST(TaskSchedulerTest, ConcurrencyAndDisallowTaskQueueing)
|
||||
while (bWait)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
nExecuted++;
|
||||
}, (n % 2 ? CTaskScheduler::EScheduleFlags::no_queue: CTaskScheduler::EScheduleFlags::normal));
|
||||
},
|
||||
(n % 2 ? EScheduleFlags::no_queue : EScheduleFlags::normal));
|
||||
bWait = false;
|
||||
|
||||
// Wait until all threads are finalized
|
||||
@@ -146,7 +147,7 @@ TEST(TaskSchedulerTest, ConcurrencyAndDisallowTaskQueueing)
|
||||
|
||||
TEST(TaskSchedulerTest, ConcurrencyAndPrioritizedTaskQueueing)
|
||||
{
|
||||
CTaskScheduler scheduler(2, 2);
|
||||
CTaskScheduler<std::thread, 2, 2> scheduler;
|
||||
|
||||
// Schedule 5 tasks onto two threads.. Queue the fifth task with high priority.
|
||||
std::atomic_size_t nExecuted = 0;
|
||||
@@ -169,7 +170,7 @@ TEST(TaskSchedulerTest, ConcurrencyAndPrioritizedTaskQueueing)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
|
||||
nExecuted++;
|
||||
}, (n == 4 ? CTaskScheduler::EScheduleFlags::priority : CTaskScheduler::EScheduleFlags::normal));
|
||||
}, (n == 4 ? EScheduleFlags::priority : EScheduleFlags::normal));
|
||||
bWait = false;
|
||||
|
||||
// Wait until all threads are finalized
|
||||
|
||||
@@ -36,13 +36,13 @@ public:
|
||||
m_uiInstanceID(uiInstanceID)
|
||||
{
|
||||
// Initialize system
|
||||
std::string ssStartup = R"code(
|
||||
std::string ssStartup = R"toml(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Maintenance"
|
||||
)code";
|
||||
)toml";
|
||||
if (uiInstanceID) ssStartup += "Instance = " + std::to_string(uiInstanceID) + "\n";
|
||||
Startup(ssStartup);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
*/
|
||||
CReceiver()
|
||||
{
|
||||
m_threadSender = std::thread(&CReceiver::SendThreadFunc, this);
|
||||
m_threadSender = sdv::core::secure_thread(&CReceiver::SendThreadFunc, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +236,7 @@ private:
|
||||
std::queue<sdv::sequence<sdv::pointer<uint8_t>>> m_queueSendData; ///< Queue for sending data.
|
||||
std::condition_variable m_cvDisconnect; ///< Disconnect event.
|
||||
std::condition_variable m_cvReceived; ///< Receive event.
|
||||
std::thread m_threadSender; ///< Thread to send data.
|
||||
sdv::core::secure_thread m_threadSender; ///< Thread to send data.
|
||||
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.
|
||||
@@ -320,9 +320,9 @@ extern "C" int main(int argc, char* argv[])
|
||||
TRACE("Forced termination of app ", bServer ? "server" : "client", " process is ", bForceTerminate ? "enabled" : "disabled");
|
||||
TRACE("Long life of app ",bServer ? "server" : "client", " process is ", bLongLife ? "enabled" : "disabled");
|
||||
|
||||
// Create an control management channel (if required).
|
||||
// Create a control management channel (if required).
|
||||
CSharedMemChannelMgnt mgntControlMgntChannel;
|
||||
mgntControlMgntChannel.Initialize("");
|
||||
mgntControlMgntChannel.Initialize(sdv::SObjectInfo());
|
||||
if (mgntControlMgntChannel.GetObjectState() != sdv::EObjectState::initialized) return -11;
|
||||
mgntControlMgntChannel.SetOperationMode(sdv::EOperationMode::running);
|
||||
if (mgntControlMgntChannel.GetObjectState() != sdv::EObjectState::running) return -11;
|
||||
@@ -349,7 +349,7 @@ extern "C" int main(int argc, char* argv[])
|
||||
|
||||
// Create the data management channel.
|
||||
CSharedMemChannelMgnt mgntDataMgntChannel;
|
||||
mgntDataMgntChannel.Initialize("");
|
||||
mgntDataMgntChannel.Initialize(sdv::SObjectInfo());
|
||||
if (mgntDataMgntChannel.GetObjectState() != sdv::EObjectState::initialized) return -1;
|
||||
mgntDataMgntChannel.SetOperationMode(sdv::EOperationMode::running);
|
||||
if (mgntDataMgntChannel.GetObjectState() != sdv::EObjectState::running) return -1;
|
||||
@@ -360,10 +360,10 @@ extern "C" int main(int argc, char* argv[])
|
||||
if (bServer)
|
||||
{
|
||||
TRACE("Server: Create data endpoint...");
|
||||
sdv::ipc::SChannelEndpoint sEndpoint = mgntDataMgntChannel.CreateEndpoint(R"code(
|
||||
sdv::ipc::SChannelEndpoint sEndpoint = mgntDataMgntChannel.CreateEndpoint(R"toml(
|
||||
[IpcChannel]
|
||||
Size = 1024000
|
||||
)code");
|
||||
)toml");
|
||||
ptrDataConnection = sEndpoint.pConnection;
|
||||
sdv::pointer<uint8_t> ptrConnectInfoData;
|
||||
ptrConnectInfoData.resize(sEndpoint.ssConnectString.size());
|
||||
|
||||
@@ -59,7 +59,7 @@ TEST(InProcessMemoryBufferTest, TriggerTestRx)
|
||||
};
|
||||
|
||||
std::unique_lock<std::mutex> lockStart(mtxStart);
|
||||
std::thread thread(fnWaitForTrigger);
|
||||
sdv::core::secure_thread thread(fnWaitForTrigger);
|
||||
cvStart.wait(lockStart);
|
||||
|
||||
for (size_t n = 0; n < 20; n++)
|
||||
@@ -108,7 +108,7 @@ TEST(InProcessMemoryBufferTest, TriggerTestTx)
|
||||
};
|
||||
|
||||
std::unique_lock<std::mutex> lockStart(mtxStart);
|
||||
std::thread thread(fnWaitForTrigger);
|
||||
sdv::core::secure_thread thread(fnWaitForTrigger);
|
||||
cvStart.wait(lockStart);
|
||||
|
||||
for (size_t n = 0; n < 20; n++)
|
||||
@@ -170,8 +170,8 @@ TEST(InProcessMemoryBufferTest, TriggerTestRxTx)
|
||||
|
||||
std::unique_lock<std::mutex> lockStartSender(mtxSenderStart);
|
||||
std::unique_lock<std::mutex> lockStartReceiver(mtxReceiverStart);
|
||||
std::thread threadSender(fnWaitForTriggerSender);
|
||||
std::thread threadReceiver(fnWaitForTriggerReceiver);
|
||||
sdv::core::secure_thread threadSender(fnWaitForTriggerSender);
|
||||
sdv::core::secure_thread threadReceiver(fnWaitForTriggerReceiver);
|
||||
cvSenderStart.wait(lockStartSender);
|
||||
lockStartSender.unlock();
|
||||
cvReceiverStart.wait(lockStartReceiver);
|
||||
@@ -340,8 +340,8 @@ TEST(InProcessMemoryBufferTest, ReserveCommitAccessReleaseNonChronologicalOrder)
|
||||
|
||||
// Reserve buffers for strings
|
||||
// The buffer header has 16 bytes
|
||||
// Each allocation is 8 bytes header, 5 bytes data and 3 bytes alignment
|
||||
CAccessorTxPacket rgTxPackets[32] = {};
|
||||
// Each allocation is 8 bytes header, 5 bytes data and 3 bytes alignment
|
||||
CAccessorTxPacket rgTxPackets[32] = {};
|
||||
for (int32_t iIndex = 0; iIndex < 15; iIndex++)
|
||||
{
|
||||
auto optTxPacket = sender.Reserve(5);
|
||||
@@ -373,8 +373,8 @@ TEST(InProcessMemoryBufferTest, ReserveCommitAccessReleaseNonChronologicalOrder)
|
||||
{
|
||||
// The text should contain the number 0
|
||||
EXPECT_TRUE(optRxPacket);
|
||||
EXPECT_NE(optRxPacket->GetData(), nullptr);
|
||||
EXPECT_EQ(std::to_string(0), optRxPacket->GetData<char>());
|
||||
EXPECT_NE(optRxPacket->GetData(), nullptr);
|
||||
EXPECT_EQ(std::to_string(0), optRxPacket->GetData<char>());
|
||||
optRxPacket->Accept();
|
||||
}
|
||||
else
|
||||
@@ -414,7 +414,7 @@ TEST(InProcessMemoryBufferTest, ReserveCommitAccessReleaseNonChronologicalOrder)
|
||||
EXPECT_NE(rgRxPackets[iIndex].GetData(), nullptr);
|
||||
EXPECT_NE(rgRxPackets[iIndex].GetSize(), 0u);
|
||||
}
|
||||
if (rgRxPackets[iIndex])
|
||||
if (rgRxPackets[iIndex])
|
||||
{
|
||||
EXPECT_EQ(std::to_string(iIndex), rgRxPackets[iIndex].GetData<char>());
|
||||
}
|
||||
@@ -442,33 +442,33 @@ TEST(InProcessMemoryBufferTest, SendReceivePattern)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CInProcMemBufferTx sender;
|
||||
EXPECT_TRUE(sender.IsValid());
|
||||
EXPECT_TRUE(sender.IsValid());
|
||||
|
||||
CInProcMemBufferRx receiver(sender.GetConnectionString());
|
||||
EXPECT_TRUE(receiver.IsValid());
|
||||
CInProcMemBufferRx receiver(sender.GetConnectionString());
|
||||
EXPECT_TRUE(receiver.IsValid());
|
||||
|
||||
CPatternReceiver pattern_inspector(receiver);
|
||||
CPatternReceiver pattern_inspector(receiver);
|
||||
CPatternSender pattern_generator(sender);
|
||||
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
|
||||
std::cout << "Pattern generator: " << pattern_generator.GetCycleCnt() << " cyles, " << pattern_generator.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_inspector.GetByteCnt() << " bytes, " << pattern_inspector.GetErrorCnt()
|
||||
<< " errors, " << std::endl;
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
}
|
||||
|
||||
TEST(InProcessMemoryBufferTest, DelayedSendReceivePattern)
|
||||
@@ -477,33 +477,33 @@ TEST(InProcessMemoryBufferTest, DelayedSendReceivePattern)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CInProcMemBufferTx sender;
|
||||
EXPECT_TRUE(sender.IsValid());
|
||||
EXPECT_TRUE(sender.IsValid());
|
||||
|
||||
CInProcMemBufferRx receiver(sender.GetConnectionString());
|
||||
EXPECT_TRUE(receiver.IsValid());
|
||||
CInProcMemBufferRx receiver(sender.GetConnectionString());
|
||||
EXPECT_TRUE(receiver.IsValid());
|
||||
|
||||
CPatternReceiver pattern_inspector(receiver);
|
||||
CPatternSender pattern_generator(sender, 10);
|
||||
CPatternReceiver pattern_inspector(receiver);
|
||||
CPatternSender pattern_generator(sender, 10);
|
||||
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
|
||||
std::cout << "Pattern generator: " << pattern_generator.GetCycleCnt() << " cyles, " << pattern_generator.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_inspector.GetByteCnt() << " bytes, " << pattern_inspector.GetErrorCnt()
|
||||
<< " errors, " << std::endl;
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
}
|
||||
|
||||
TEST(InProcessMemoryBufferTest, SendDelayedReceivePattern)
|
||||
@@ -512,33 +512,33 @@ TEST(InProcessMemoryBufferTest, SendDelayedReceivePattern)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CInProcMemBufferTx sender;
|
||||
EXPECT_TRUE(sender.IsValid());
|
||||
EXPECT_TRUE(sender.IsValid());
|
||||
|
||||
CInProcMemBufferRx receiver(sender.GetConnectionString());
|
||||
EXPECT_TRUE(receiver.IsValid());
|
||||
CInProcMemBufferRx receiver(sender.GetConnectionString());
|
||||
EXPECT_TRUE(receiver.IsValid());
|
||||
|
||||
CPatternReceiver pattern_inspector(receiver, 10);
|
||||
CPatternSender pattern_generator(sender);
|
||||
CPatternReceiver pattern_inspector(receiver, 10);
|
||||
CPatternSender pattern_generator(sender);
|
||||
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
|
||||
std::cout << "Pattern generator: " << pattern_generator.GetCycleCnt() << " cyles, " << pattern_generator.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_inspector.GetByteCnt() << " bytes, " << pattern_inspector.GetErrorCnt()
|
||||
<< " errors, " << std::endl;
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
}
|
||||
|
||||
TEST(InProcessMemoryBufferTest, SendRepeatReceivePattern)
|
||||
@@ -547,50 +547,50 @@ TEST(InProcessMemoryBufferTest, SendRepeatReceivePattern)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
// The first process creates a sender and receiver
|
||||
CInProcMemBufferTx bufferTX;
|
||||
EXPECT_TRUE(bufferTX.IsValid());
|
||||
CInProcMemBufferRx bufferRX;
|
||||
EXPECT_TRUE(bufferRX.IsValid());
|
||||
CInProcMemBufferTx bufferTX;
|
||||
EXPECT_TRUE(bufferTX.IsValid());
|
||||
CInProcMemBufferRx bufferRX;
|
||||
EXPECT_TRUE(bufferRX.IsValid());
|
||||
|
||||
// The connection string containing the RX and TX strings for the repeater
|
||||
std::string ssConnectionString = bufferTX.GetConnectionString() + "\n" + bufferRX.GetConnectionString();
|
||||
|
||||
// The repeater process creates a receiver and sender
|
||||
CInProcMemBufferRx bufferRepeaterRX(ssConnectionString);
|
||||
EXPECT_TRUE(bufferRepeaterRX.IsValid());
|
||||
CInProcMemBufferTx bufferRepeaterTX(ssConnectionString);
|
||||
EXPECT_TRUE(bufferRepeaterTX.IsValid());
|
||||
CInProcMemBufferRx bufferRepeaterRX(ssConnectionString);
|
||||
EXPECT_TRUE(bufferRepeaterRX.IsValid());
|
||||
CInProcMemBufferTx bufferRepeaterTX(ssConnectionString);
|
||||
EXPECT_TRUE(bufferRepeaterTX.IsValid());
|
||||
|
||||
// Connect the pattern generator and inspector
|
||||
CPatternReceiver pattern_inspector(bufferRX);
|
||||
CPatternRepeater pattern_repeater(bufferRepeaterRX, bufferRepeaterTX);
|
||||
CPatternSender pattern_generator(bufferTX);
|
||||
CPatternRepeater pattern_repeater(bufferRepeaterRX, bufferRepeaterTX);
|
||||
CPatternSender pattern_generator(bufferTX);
|
||||
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
// Wait for 2 seconds
|
||||
std::this_thread::sleep_for(std::chrono::seconds(PATTERN_TEST_TIME_S));
|
||||
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_repeater.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
// Shutdown
|
||||
pattern_generator.Shutdown();
|
||||
pattern_repeater.Shutdown();
|
||||
pattern_inspector.Shutdown();
|
||||
|
||||
std::cout << "Pattern generator: " << pattern_generator.GetCycleCnt() << " cyles, " << pattern_generator.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_generator.GetByteCnt() << " bytes" << std::endl;
|
||||
std::cout << "Pattern inspector: " << pattern_inspector.GetCycleCnt() << " cyles, " << pattern_inspector.GetPacketCnt()
|
||||
<< " packets, " << pattern_inspector.GetByteCnt() << " bytes, " << pattern_inspector.GetErrorCnt()
|
||||
<< " errors, " << std::endl;
|
||||
std::cout << "Pattern repeater: " << pattern_repeater.GetCycleCnt() << " cyles, " << pattern_repeater.GetPacketCnt()
|
||||
std::cout << "Pattern repeater: " << pattern_repeater.GetCycleCnt() << " cyles, " << pattern_repeater.GetPacketCnt()
|
||||
<< " packets, " << pattern_repeater.GetByteCnt() << " bytes, " << pattern_repeater.GetErrorCnt()
|
||||
<< " errors, " << std::endl;
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_repeater.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_repeater.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_repeater.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_repeater.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_generator.GetCycleCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_generator.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_inspector.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_inspector.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_inspector.GetByteCnt(), 0ull);
|
||||
EXPECT_NE(pattern_repeater.GetCycleCnt(), 0u);
|
||||
EXPECT_EQ(pattern_repeater.GetErrorCnt(), 0u);
|
||||
EXPECT_NE(pattern_repeater.GetPacketCnt(), 0u);
|
||||
EXPECT_NE(pattern_repeater.GetByteCnt(), 0ull);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ CPatternSender::CPatternSender(CMemBufferAccessorTx& raccessorOut, uint32_t uiDe
|
||||
m_raccessorOut(raccessorOut), m_uiDelayMs(uiDelayMs)
|
||||
{
|
||||
// Start the thread
|
||||
m_thread = std::thread(&CPatternSender::Process, this);
|
||||
m_thread = sdv::core::secure_thread(&CPatternSender::Process, this);
|
||||
|
||||
// Wait for the thread to run
|
||||
while (!m_bStarted) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
@@ -67,7 +67,7 @@ CPatternReceiver::CPatternReceiver(CMemBufferAccessorRx& raccessorIn, uint32_t u
|
||||
m_raccessorIn(raccessorIn),m_uiDelayMs(uiDelayMs)
|
||||
{
|
||||
// Start the thread
|
||||
m_thread = std::thread(& CPatternReceiver::Process, this);
|
||||
m_thread = sdv::core::secure_thread(& CPatternReceiver::Process, this);
|
||||
|
||||
// Wait for the thread to run
|
||||
while (!m_bStarted) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
@@ -123,7 +123,7 @@ CPatternRepeater::CPatternRepeater(CMemBufferAccessorRx& raccessorIn, CMemBuffer
|
||||
m_raccessorIn(raccessorIn), m_raccessorOut(raccessorOut), m_uiDelayMs(uiDelayMs)
|
||||
{
|
||||
// Start the thread
|
||||
m_thread = std::thread(&CPatternRepeater::Process, this);
|
||||
m_thread = sdv::core::secure_thread(&CPatternRepeater::Process, this);
|
||||
|
||||
// Wait for the thread to run
|
||||
while (!m_bStarted) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <support/local_service_access.h>
|
||||
#include "../../../sdv_services/ipc_shared_mem/mem_buffer_accessor.h"
|
||||
|
||||
/**
|
||||
@@ -55,14 +56,14 @@ public:
|
||||
*/
|
||||
|
||||
private:
|
||||
CMemBufferAccessorTx& m_raccessorOut; //!< Reference to the output accessor
|
||||
std::thread m_thread; //!< Processing 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
|
||||
uint64_t m_uiByteCnt = 0ull; //!< Amount of bytes
|
||||
CMemBufferAccessorTx& m_raccessorOut; //!< Reference to the output accessor
|
||||
sdv::core::secure_thread m_thread; //!< Processing 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
|
||||
uint64_t m_uiByteCnt = 0ull; //!< Amount of bytes
|
||||
};
|
||||
|
||||
class CPatternReceiver
|
||||
@@ -98,15 +99,15 @@ public:
|
||||
*/
|
||||
|
||||
private:
|
||||
CMemBufferAccessorRx& m_raccessorIn; //!< Reference to the input accessor
|
||||
std::thread m_thread; //!< Processing thread
|
||||
CMemBufferAccessorRx& m_raccessorIn; //!< Reference to the input accessor
|
||||
sdv::core::secure_thread m_thread; //!< Processing thread
|
||||
bool m_bStarted = false; //!< Set by the thread when started.
|
||||
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_uiErrorCnt = 0u; //!< Amount of counter errors
|
||||
uint32_t m_uiPacketCnt = 0u; //!< Amount of packets
|
||||
uint64_t m_uiByteCnt = 0ull; //!< Amount of bytes
|
||||
uint32_t m_uiDelayMs = 0u; //!< Delay (in ms) to insert while processing.
|
||||
uint32_t m_uiCycleCnt = 0u; //!< Amount of packets
|
||||
uint32_t m_uiErrorCnt = 0u; //!< Amount of counter errors
|
||||
uint32_t m_uiPacketCnt = 0u; //!< Amount of packets
|
||||
uint64_t m_uiByteCnt = 0ull; //!< Amount of bytes
|
||||
};
|
||||
|
||||
class CPatternRepeater
|
||||
@@ -143,16 +144,16 @@ public:
|
||||
*/
|
||||
|
||||
private:
|
||||
CMemBufferAccessorRx& m_raccessorIn; //!< Reference to the input accessor
|
||||
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.
|
||||
uint32_t m_uiDelayMs = 0u; //!< Delay (in ms) to insert while processing.
|
||||
uint32_t m_uiCycleCnt = 0u; //!< Amount of packets
|
||||
uint32_t m_uiErrorCnt = 0u; //!< Amount of counter errors
|
||||
uint32_t m_uiPacketCnt = 0u; //!< Amount of packets
|
||||
uint64_t m_uiByteCnt = 0ull; //!< Amount of bytes
|
||||
CMemBufferAccessorRx& m_raccessorIn; //!< Reference to the input accessor
|
||||
CMemBufferAccessorTx& m_raccessorOut; //!< Reference to the output accessor
|
||||
sdv::core::secure_thread m_thread; //!< Processing thread
|
||||
bool m_bStarted = false; //!< Set by the thread when started.
|
||||
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_uiErrorCnt = 0u; //!< Amount of counter errors
|
||||
uint32_t m_uiPacketCnt = 0u; //!< Amount of packets
|
||||
uint64_t m_uiByteCnt = 0ull; //!< Amount of bytes
|
||||
};
|
||||
|
||||
#endif // !defined(PATTERN_GEN_H)
|
||||
@@ -88,7 +88,7 @@ TEST(SharedMemoryBufferTest, TriggerTestRx)
|
||||
};
|
||||
|
||||
std::unique_lock<std::mutex> lockStart(mtxStart);
|
||||
std::thread thread(fnWaitForTrigger);
|
||||
sdv::core::secure_thread thread(fnWaitForTrigger);
|
||||
cvStart.wait(lockStart);
|
||||
|
||||
for (size_t n = 0; n < 20; n++)
|
||||
@@ -141,7 +141,7 @@ TEST(SharedMemoryBufferTest, TriggerTestTx)
|
||||
};
|
||||
|
||||
std::unique_lock<std::mutex> lockStart(mtxStart);
|
||||
std::thread thread(fnWaitForTrigger);
|
||||
sdv::core::secure_thread thread(fnWaitForTrigger);
|
||||
cvStart.wait(lockStart);
|
||||
|
||||
for (size_t n = 0; n < 20; n++)
|
||||
@@ -208,8 +208,8 @@ 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);
|
||||
sdv::core::secure_thread threadSender(fnWaitForTriggerSender);
|
||||
sdv::core::secure_thread threadReceiver(fnWaitForTriggerReceiver);
|
||||
cvSenderStart.wait(lockStartSender);
|
||||
lockStartSender.unlock();
|
||||
cvReceiverStart.wait(lockStartReceiver);
|
||||
@@ -693,8 +693,8 @@ TEST(SharedMemoryBufferTest, SendRepeatReceivePattern)
|
||||
TEST(SharedMemoryBufferTest, AppProcessSendRepeatReceivePattern)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
CSharedMemBufferTx bufferTX;
|
||||
@@ -747,8 +747,8 @@ Mode = "Essential")code"));
|
||||
TEST(SharedMemoryBufferTest, SendRepeatReceivePatternBetweenTwoAppProcesses)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
// test starts 2 app processes, one should be the sender of the pattern, the other is the repeater
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
|
||||
// Start the processing thread if needed
|
||||
if (!m_threadDecoupledSend.joinable()) m_threadDecoupledSend =
|
||||
std::thread(&CConnectReceiver::DecoupledSendThread, this);
|
||||
sdv::core::secure_thread(&CConnectReceiver::DecoupledSendThread, this);
|
||||
|
||||
// Store data into the queue for sending.
|
||||
m_queueDecoupledSend.push(std::move(seqData));
|
||||
@@ -186,7 +186,7 @@ private:
|
||||
bool m_bConnectError = false; ///< Connection error ocurred.
|
||||
bool m_bCommError = false; ///< Communication error occurred.
|
||||
bool m_bForcedDisconnect = false; ///< Force disconnect.
|
||||
std::thread m_threadDecoupledSend; ///< Decoupled send thread.
|
||||
sdv::core::secure_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.
|
||||
std::atomic_bool m_bShutdown = false; ///< Shutdown send thread.
|
||||
@@ -203,7 +203,7 @@ TEST(SharedMemChannelService, Instantiate)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CSharedMemChannelMgnt mgnt;
|
||||
EXPECT_NO_THROW(mgnt.Initialize(""));
|
||||
EXPECT_NO_THROW(mgnt.Initialize(sdv::SObjectInfo()));
|
||||
|
||||
EXPECT_EQ(mgnt.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
@@ -220,7 +220,7 @@ TEST(SharedMemChannelService, ChannelConfigString)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CSharedMemChannelMgnt mgnt;
|
||||
EXPECT_NO_THROW(mgnt.Initialize(""));
|
||||
EXPECT_NO_THROW(mgnt.Initialize(sdv::SObjectInfo()));
|
||||
|
||||
EXPECT_EQ(mgnt.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
@@ -237,7 +237,7 @@ TEST(SharedMemChannelService, CreateRandomEndpoint)
|
||||
CSharedMemChannelMgnt mgnt;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgnt.Initialize(""));
|
||||
EXPECT_NO_THROW(mgnt.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgnt.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgnt.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -256,12 +256,12 @@ TEST(SharedMemChannelService, CreateExplicitEndpoint)
|
||||
CSharedMemChannelMgnt mgnt;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgnt.Initialize(""));
|
||||
EXPECT_NO_THROW(mgnt.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgnt.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgnt.CreateEndpoint(R"code([IpcChannel]
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgnt.CreateEndpoint(R"toml([IpcChannel]
|
||||
Name = "CHANNEL_1234"
|
||||
Size = 10240
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
if (sChannelEndpoint.pConnection) sdv::TObjectPtr(sChannelEndpoint.pConnection);
|
||||
@@ -278,9 +278,9 @@ TEST(SharedMemChannelService, GetRandomEndpointAccess)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -306,14 +306,14 @@ TEST(SharedMemChannelService, GetExplicitEndpointAccess)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"code([IpcChannel]
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"toml([IpcChannel]
|
||||
Name = "CHANNEL_1234"
|
||||
Size = 10240
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
|
||||
@@ -337,7 +337,7 @@ TEST(SharedMemChannelService, WaitForConnection)
|
||||
CSharedMemChannelMgnt mgnt;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgnt.Initialize(""));
|
||||
EXPECT_NO_THROW(mgnt.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgnt.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgnt.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -359,7 +359,7 @@ TEST(SharedMemChannelService, WaitForConnection)
|
||||
pConnection->GetConnectState() == sdv::ipc::EConnectState::connecting);
|
||||
|
||||
// Wait for connection for infinite period with cancel.
|
||||
std::thread threadCancelWait([&]()
|
||||
sdv::core::secure_thread threadCancelWait([&]()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
pConnection->CancelWait();
|
||||
@@ -384,9 +384,9 @@ TEST(SharedMemChannelService, AsyncConnect)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -481,9 +481,9 @@ TEST(SharedMemChannelService, EstablishConnectionEvents)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -597,11 +597,11 @@ TEST(SharedMemChannelService, EstablishReconnect)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient1, mgntClient2;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient1.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient1.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient1.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient2.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient2.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient2.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -680,11 +680,11 @@ TEST(SharedMemChannelService, EstablishReconnectEvents)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient1, mgntClient2;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient1.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient1.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient1.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgntClient2.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntClient2.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntClient2.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -779,14 +779,14 @@ TEST(SharedMemChannelService, EstablishReconnectEvents)
|
||||
TEST(SharedMemChannelService, AppEstablishConnection)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
CSharedMemChannelMgnt mgntServer;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -860,14 +860,14 @@ Mode = "Essential")code"));
|
||||
TEST(SharedMemChannelService, AppGracefullyShutdown)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
CSharedMemChannelMgnt mgntServer;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -937,14 +937,14 @@ Mode = "Essential")code"));
|
||||
TEST(SharedMemChannelService, AppForcedShutdown_Watchdog)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
CSharedMemChannelMgnt mgntServer;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -1019,8 +1019,8 @@ Mode = "Essential")code"));
|
||||
TEST(SharedMemChannelService, IndirectAppGracefullyShutdown)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
sdv::process::IProcessControl* pProcessControl = sdv::core::GetObject<sdv::process::IProcessControl>("ProcessControlService");
|
||||
@@ -1030,7 +1030,7 @@ Mode = "Essential")code"));
|
||||
|
||||
// Create the first control endpoint.
|
||||
CSharedMemChannelMgnt mgntControl1;
|
||||
EXPECT_NO_THROW(mgntControl1.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntControl1.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntControl1.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sEndpoint1 = mgntControl1.CreateEndpoint("");
|
||||
EXPECT_NE(sEndpoint1.pConnection, nullptr);
|
||||
@@ -1066,7 +1066,7 @@ Mode = "Essential")code"));
|
||||
|
||||
// Create the second control endpoint.
|
||||
CSharedMemChannelMgnt mgntControl2;
|
||||
EXPECT_NO_THROW(mgntControl2.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntControl2.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntControl2.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sEndpoint2 = mgntControl2.CreateEndpoint("");
|
||||
EXPECT_NE(sEndpoint2.pConnection, nullptr);
|
||||
@@ -1100,8 +1100,8 @@ Mode = "Essential")code"));
|
||||
TEST(SharedMemChannelService, IndirectAppServerForceShutdown_Watchdog)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
sdv::process::IProcessControl* pProcessControl = sdv::core::GetObject<sdv::process::IProcessControl>("ProcessControlService");
|
||||
@@ -1113,7 +1113,7 @@ Mode = "Essential")code"));
|
||||
|
||||
// Create the first control endpoint.
|
||||
CSharedMemChannelMgnt mgntControl1;
|
||||
EXPECT_NO_THROW(mgntControl1.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntControl1.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntControl1.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sEndpoint1 = mgntControl1.CreateEndpoint("");
|
||||
EXPECT_NE(sEndpoint1.pConnection, nullptr);
|
||||
@@ -1149,7 +1149,7 @@ Mode = "Essential")code"));
|
||||
|
||||
// Create the second control endpoint.
|
||||
CSharedMemChannelMgnt mgntControl2;
|
||||
EXPECT_NO_THROW(mgntControl2.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntControl2.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntControl2.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sEndpoint2 = mgntControl2.CreateEndpoint("");
|
||||
EXPECT_NE(sEndpoint2.pConnection, nullptr);
|
||||
@@ -1183,8 +1183,8 @@ Mode = "Essential")code"));
|
||||
TEST(SharedMemChannelService, IndirectAppClientForceShutdown_Watchdog)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code([Application]
|
||||
Mode = "Essential")code"));
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml([Application]
|
||||
Mode = "Essential")toml"));
|
||||
LoadSupportServices();
|
||||
|
||||
sdv::process::IProcessControl* pProcessControl = sdv::core::GetObject<sdv::process::IProcessControl>("ProcessControlService");
|
||||
@@ -1194,7 +1194,7 @@ Mode = "Essential")code"));
|
||||
|
||||
// Create the first control endpoint.
|
||||
CSharedMemChannelMgnt mgntControl1;
|
||||
EXPECT_NO_THROW(mgntControl1.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntControl1.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntControl1.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sEndpoint1 = mgntControl1.CreateEndpoint("");
|
||||
EXPECT_NE(sEndpoint1.pConnection, nullptr);
|
||||
@@ -1230,7 +1230,7 @@ Mode = "Essential")code"));
|
||||
|
||||
// Create the second control endpoint.
|
||||
CSharedMemChannelMgnt mgntControl2;
|
||||
EXPECT_NO_THROW(mgntControl2.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntControl2.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntControl2.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sEndpoint2 = mgntControl2.CreateEndpoint("");
|
||||
EXPECT_NE(sEndpoint2.pConnection, nullptr);
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
|
||||
// Start the processing thread if needed
|
||||
if (!m_threadDecoupledSend.joinable())
|
||||
m_threadDecoupledSend = std::thread(&CLargeDataReceiver::DecoupledSendThread, this);
|
||||
m_threadDecoupledSend = sdv::core::secure_thread(&CLargeDataReceiver::DecoupledSendThread, this);
|
||||
|
||||
// Store data into the queue for sending.
|
||||
m_queueDecoupledSend.push(std::move(seqData));
|
||||
@@ -262,7 +262,7 @@ private:
|
||||
bool m_bForcedDisconnect = false; ///< Force disconnect.
|
||||
std::atomic_size_t m_nCount = 0; ///< Receive counter.
|
||||
std::condition_variable m_cvReceived; ///< Receive event.
|
||||
std::thread m_threadDecoupledSend; ///< Decoupled send thread.
|
||||
sdv::core::secure_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.
|
||||
std::atomic_bool m_bShutdown = false; ///< Shutdown send thread.
|
||||
@@ -271,27 +271,29 @@ private:
|
||||
TEST(SharedMemChannelService, CommunicateOneLargeBlock)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code(
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml(
|
||||
[Console]
|
||||
Report = "Silent"
|
||||
)code"));
|
||||
)toml"));
|
||||
appcontrol.SetConfigMode();
|
||||
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntServer.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::running);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize("service = \"client\""));
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = "service = \"client\"";
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sClientInfo));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntClient.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::running);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"code(
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"toml(
|
||||
[IpcChannel]
|
||||
Size = 1024000
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
|
||||
@@ -376,18 +378,20 @@ TEST(SharedMemChannelService, CommunicateMultiLargeBlock)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntServer.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::running);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize("service = \"client\""));
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = "service = \"client\"";
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sClientInfo));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntClient.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::running);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"code(
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"toml(
|
||||
[IpcChannel]
|
||||
Size = 1024000
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
|
||||
@@ -504,18 +508,20 @@ TEST(SharedMemChannelService, CommunicateFragmentedLargeBlock)
|
||||
CSharedMemChannelMgnt mgntServer, mgntClient;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntServer.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::running);
|
||||
EXPECT_NO_THROW(mgntClient.Initialize("service = \"client\""));
|
||||
sdv::SObjectInfo sClientInfo{};
|
||||
sClientInfo.ssConfig = "service = \"client\"";
|
||||
EXPECT_NO_THROW(mgntClient.Initialize(sClientInfo));
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntClient.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntClient.GetObjectState(), sdv::EObjectState::running);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"code(
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"toml(
|
||||
[IpcChannel]
|
||||
Size = 1024000
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
|
||||
@@ -614,23 +620,23 @@ Size = 1024000
|
||||
TEST(SharedMemChannelService, AppCommunicateOneLargeBlock)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code(
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml(
|
||||
[Application]
|
||||
Mode="Essential")code"));
|
||||
Mode="Essential")toml"));
|
||||
LoadSupportServices();
|
||||
appcontrol.SetConfigMode();
|
||||
|
||||
CSharedMemChannelMgnt mgntServer;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntServer.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::running);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"code(
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"toml(
|
||||
[IpcChannel]
|
||||
Size = 1024000
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
|
||||
@@ -698,23 +704,23 @@ Size = 1024000
|
||||
TEST(SharedMemChannelService, AppCommunicateMultiLargeBlock)
|
||||
{
|
||||
sdv::app::CAppControl appcontrol;
|
||||
ASSERT_TRUE(appcontrol.Startup(R"code(
|
||||
ASSERT_TRUE(appcontrol.Startup(R"toml(
|
||||
[Application]
|
||||
Mode="Essential")code"));
|
||||
Mode="Essential")toml"));
|
||||
LoadSupportServices();
|
||||
appcontrol.SetConfigMode();
|
||||
|
||||
CSharedMemChannelMgnt mgntServer;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(""));
|
||||
EXPECT_NO_THROW(mgntServer.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgntServer.SetOperationMode(sdv::EOperationMode::running);
|
||||
EXPECT_EQ(mgntServer.GetObjectState(), sdv::EObjectState::running);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"code(
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgntServer.CreateEndpoint(R"toml(
|
||||
[IpcChannel]
|
||||
Size = 1024000
|
||||
)code");
|
||||
)toml");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
EXPECT_FALSE(sChannelEndpoint.ssConnectString.empty());
|
||||
|
||||
|
||||
46
tests/unit_tests/simple_toml_parser/CMakeLists.txt
Normal file
46
tests/unit_tests/simple_toml_parser/CMakeLists.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Apache License Version 2.0 which is available at
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Martin Stimpfl - initial API and implementation
|
||||
# Erik Verhoeven - writing TOML and whitespace preservation
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project (UnitTest_SimpleTOMLParser VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Character Reader executable
|
||||
add_executable(UnitTest_SimpleTOMLParser
|
||||
"parser_tests.cpp" "main.cpp")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_libraries(UnitTest_SimpleTOMLParser GTest::GTest ${CMAKE_THREAD_LIBS_INIT})
|
||||
if (WIN32)
|
||||
target_link_libraries(UnitTest_SimpleTOMLParser Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(UnitTest_SimpleTOMLParser ${CMAKE_DL_LIBS} rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(UnitTest_SimpleTOMLParser GTest::GTest Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the Reader unittest
|
||||
add_test(NAME UnitTest_SimpleTOMLParser COMMAND UnitTest_SimpleTOMLParser)
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_SimpleTOMLParser POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_SimpleTOMLParser>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_SimpleTOMLParser.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Build dependencies
|
||||
#add_dependencies(UnitTest_SimpleTOMLParser dependency_sdv_components)
|
||||
|
||||
|
||||
|
||||
@@ -8,14 +8,21 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
* Martin Stimpfl - initial API and implementation
|
||||
* Erik Verhoeven - writing TOML and whitespace preservation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
// Test TODO:
|
||||
// Shift nodes up and down within one container
|
||||
// Remove formatting from node
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
868
tests/unit_tests/simple_toml_parser/parser_tests.cpp
Normal file
868
tests/unit_tests/simple_toml_parser/parser_tests.cpp
Normal file
@@ -0,0 +1,868 @@
|
||||
#include <iostream>
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/simple_toml.h>
|
||||
|
||||
TEST(RecognizeTypes, Root)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser("");
|
||||
auto sRoot = parser.Root();
|
||||
EXPECT_EQ(sRoot.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
}
|
||||
|
||||
TEST(RecognizeTypes, Table)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[newTable]
|
||||
[secondTable.nestedTable]
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto table1 = sRoot.GetDirect("newTable");
|
||||
EXPECT_EQ(table1.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(table1.GetName(), "newTable");
|
||||
EXPECT_EQ(table1.GetValue(), "");
|
||||
|
||||
auto table2 = sRoot.GetDirect("secondTable");
|
||||
EXPECT_EQ(table2.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(table2.GetName(), "secondTable");
|
||||
EXPECT_EQ(table2.GetValue(), "");
|
||||
|
||||
auto table3 = sRoot.GetDirect("secondTable.nestedTable");
|
||||
EXPECT_EQ(table3.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(table3.GetName(), "nestedTable");
|
||||
EXPECT_EQ(table3.GetValue(), "");
|
||||
}
|
||||
|
||||
TEST(RecognizeTypes, Key_Value)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
name = "Hammer"
|
||||
id = 42
|
||||
pi = 3.1415926
|
||||
boolean = true
|
||||
array = []
|
||||
table = {}
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto value_name = sRoot.GetDirect("name");
|
||||
EXPECT_EQ(value_name.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(value_name.GetValue(), "Hammer");
|
||||
|
||||
auto value_id = sRoot.GetDirect("id");
|
||||
EXPECT_EQ(value_id.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(value_id.GetValue<int>(), 42);
|
||||
|
||||
auto value_pi = sRoot.GetDirect("pi");
|
||||
EXPECT_EQ(value_pi.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(value_pi.GetValue<double>(), 3.1415926);
|
||||
|
||||
auto value_boolean = sRoot.GetDirect("boolean");
|
||||
EXPECT_EQ(value_boolean.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(value_boolean.GetValue<bool>(), true);
|
||||
|
||||
auto value_array = sRoot.GetDirect("array");
|
||||
EXPECT_EQ(value_array.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
EXPECT_EQ(value_array.GetValue(), "");
|
||||
|
||||
auto value_table = sRoot.GetDirect("table");
|
||||
EXPECT_EQ(value_table.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(value_table.GetValue(), "");
|
||||
}
|
||||
|
||||
TEST(RecognizeTypes, TableArray)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[[newTableArray]]
|
||||
[[newTableArray]]
|
||||
[[table.nestedTableArray]]
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto tableArray1 = sRoot.GetDirect("newTableArray");
|
||||
EXPECT_EQ(tableArray1.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
EXPECT_EQ(tableArray1.GetName(), "newTableArray");
|
||||
|
||||
auto table1 = sRoot.GetDirect("newTableArray[0]");
|
||||
ASSERT_TRUE(table1);
|
||||
EXPECT_EQ(table1.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(table1.GetName(), "newTableArray");
|
||||
|
||||
auto table2 = sRoot.GetDirect("newTableArray[1]");
|
||||
ASSERT_TRUE(table2);
|
||||
EXPECT_EQ(table2.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(table2.GetName(), "newTableArray");
|
||||
}
|
||||
|
||||
TEST(NestedContent, Array)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
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, ]
|
||||
arr_multiline = [
|
||||
"first line",
|
||||
"second line",
|
||||
"third_line",
|
||||
]
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
{
|
||||
auto array_ints = sRoot.GetDirect("arr_ints");
|
||||
EXPECT_EQ(array_ints.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
auto array_ints_0 = sRoot.GetDirect("arr_ints[0]");
|
||||
ASSERT_TRUE(array_ints_0);
|
||||
EXPECT_EQ(array_ints_0.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_0.GetValue<int>(), 1);
|
||||
auto array_ints_1 = sRoot.GetDirect("arr_ints[1]");
|
||||
ASSERT_TRUE(array_ints_1);
|
||||
EXPECT_EQ(array_ints_1.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_1.GetValue<int>(), 2);
|
||||
auto array_ints_2 = sRoot.GetDirect("arr_ints[2]");
|
||||
ASSERT_TRUE(array_ints_2);
|
||||
EXPECT_EQ(array_ints_2.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_2.GetValue<int>(), 3);
|
||||
auto array_ints_3 = sRoot.GetDirect("arr_ints[3]");
|
||||
ASSERT_TRUE(array_ints_3);
|
||||
EXPECT_EQ(array_ints_3.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_3.GetValue<int>(), 4);
|
||||
auto array_ints_4 = sRoot.GetDirect("arr_ints[4]");
|
||||
EXPECT_FALSE(array_ints_4);
|
||||
}
|
||||
|
||||
{
|
||||
auto array_ints_trailing_comma = sRoot.GetDirect("arr_ints_trailing_comma");
|
||||
auto array_ints_trailing_comma_0 = sRoot.GetDirect("arr_ints_trailing_comma[0]");
|
||||
auto array_ints_trailing_comma_1 = sRoot.GetDirect("arr_ints_trailing_comma[1]");
|
||||
auto array_ints_trailing_comma_2 = sRoot.GetDirect("arr_ints_trailing_comma[2]");
|
||||
auto array_ints_trailing_comma_3 = sRoot.GetDirect("arr_ints_trailing_comma[3]");
|
||||
auto array_ints_trailing_comma_4 = sRoot.GetDirect("arr_ints_trailing_comma[4]");
|
||||
|
||||
EXPECT_EQ(array_ints_trailing_comma.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_0);
|
||||
EXPECT_EQ(array_ints_trailing_comma_0.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_trailing_comma_0.GetValue<int>(), 1);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_1);
|
||||
EXPECT_EQ(array_ints_trailing_comma_1.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_trailing_comma_1.GetValue<int>(), 2);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_2);
|
||||
EXPECT_EQ(array_ints_trailing_comma_2.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_trailing_comma_2.GetValue<int>(), 3);
|
||||
ASSERT_TRUE(array_ints_trailing_comma_3);
|
||||
EXPECT_EQ(array_ints_trailing_comma_3.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_ints_trailing_comma_3.GetValue<int>(), 4);
|
||||
EXPECT_FALSE(array_ints_trailing_comma_4);
|
||||
}
|
||||
|
||||
{
|
||||
auto array_mixed = sRoot.GetDirect("arr_mixed");
|
||||
auto array_mixed_0 = sRoot.GetDirect("arr_mixed[0]");
|
||||
auto array_mixed_1 = sRoot.GetDirect("arr_mixed[1]");
|
||||
auto array_mixed_2 = sRoot.GetDirect("arr_mixed[2]");
|
||||
auto array_mixed_3 = sRoot.GetDirect("arr_mixed[3]");
|
||||
auto array_mixed_3_1 = sRoot.GetDirect("arr_mixed[3][0]");
|
||||
auto array_mixed_3_2 = sRoot.GetDirect("arr_mixed[3][1]");
|
||||
auto array_mixed_4 = sRoot.GetDirect("arr_mixed[4]");
|
||||
auto array_mixed_4_pi = sRoot.GetDirect("arr_mixed[4].pi");
|
||||
auto array_mixed_4_e = sRoot.GetDirect("arr_mixed[4].e");
|
||||
auto array_mixed_5 = sRoot.GetDirect("arr_mixed[5]");
|
||||
auto array_mixed_6 = sRoot.GetDirect("arr_mixed[6]");
|
||||
|
||||
EXPECT_EQ(array_mixed.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_mixed_0);
|
||||
EXPECT_EQ(array_mixed_0.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_0.GetValue<double>(), 1.0);
|
||||
ASSERT_TRUE(array_mixed_1);
|
||||
EXPECT_EQ(array_mixed_1.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_1.GetValue<int>(), 2);
|
||||
ASSERT_TRUE(array_mixed_2);
|
||||
EXPECT_EQ(array_mixed_2.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_2.GetValue(), "test string");
|
||||
ASSERT_TRUE(array_mixed_3);
|
||||
EXPECT_EQ(array_mixed_3.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
EXPECT_EQ(array_mixed_3_1.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_3_1.GetValue<int>(), 1);
|
||||
EXPECT_EQ(array_mixed_3_2.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_3_2.GetValue<int>(), 2);
|
||||
ASSERT_TRUE(array_mixed_4);
|
||||
EXPECT_EQ(array_mixed_4.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
EXPECT_EQ(array_mixed_4_pi.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_4_pi.GetValue<double>(), 3.14);
|
||||
EXPECT_EQ(array_mixed_4_e.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_4_e.GetValue<double>(), 2.71828);
|
||||
ASSERT_TRUE(array_mixed_5);
|
||||
EXPECT_EQ(array_mixed_5.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_mixed_5.GetValue<bool>(), true);
|
||||
EXPECT_FALSE(array_mixed_6);
|
||||
}
|
||||
|
||||
{
|
||||
auto array_multiline = sRoot.GetDirect("arr_multiline");
|
||||
auto array_multiline_0 = sRoot.GetDirect("arr_multiline[0]");
|
||||
auto array_multiline_1 = sRoot.GetDirect("arr_multiline[1]");
|
||||
auto array_multiline_2 = sRoot.GetDirect("arr_multiline[2]");
|
||||
auto array_multiline_3 = sRoot.GetDirect("arr_multiline[3]");
|
||||
|
||||
EXPECT_EQ(array_multiline.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
ASSERT_TRUE(array_multiline_0);
|
||||
EXPECT_EQ(array_multiline_0.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_multiline_0.GetValue(), "first line");
|
||||
ASSERT_TRUE(array_multiline_1);
|
||||
EXPECT_EQ(array_multiline_1.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_multiline_1.GetValue(), "second line");
|
||||
ASSERT_TRUE(array_multiline_2);
|
||||
EXPECT_EQ(array_multiline_2.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(array_multiline_2.GetValue(), "third_line");
|
||||
EXPECT_FALSE(array_multiline_3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NestedContent, Table)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[table]
|
||||
a = 2
|
||||
b = 1.2
|
||||
[anotherTable]
|
||||
a = 4
|
||||
c = false
|
||||
[thirdTable.fourthTable]
|
||||
a = "five"
|
||||
d = []
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto table_a = sRoot.GetDirect("table.a");
|
||||
auto table_b = sRoot.GetDirect("table.b");
|
||||
auto anotherTable_a = sRoot.GetDirect("anotherTable.a");
|
||||
auto anotherTable_c = sRoot.GetDirect("anotherTable.c");
|
||||
auto fourthTable_a = sRoot.GetDirect("thirdTable.fourthTable.a");
|
||||
auto fourthTable_d = sRoot.GetDirect("thirdTable.fourthTable.d");
|
||||
|
||||
ASSERT_TRUE(table_a);
|
||||
EXPECT_EQ(table_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_a.GetValue<int>(), 2);
|
||||
ASSERT_TRUE(table_b);
|
||||
EXPECT_EQ(table_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_b.GetValue<double>(), 1.2);
|
||||
ASSERT_TRUE(anotherTable_a);
|
||||
EXPECT_EQ(anotherTable_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(anotherTable_a.GetValue<int>(), 4);
|
||||
ASSERT_TRUE(anotherTable_c);
|
||||
EXPECT_EQ(anotherTable_c.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(anotherTable_c.GetValue<bool>(), false);
|
||||
ASSERT_TRUE(fourthTable_a);
|
||||
EXPECT_EQ(fourthTable_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(fourthTable_a.GetValue(), "five");
|
||||
ASSERT_TRUE(fourthTable_d);
|
||||
EXPECT_EQ(fourthTable_d.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
}
|
||||
|
||||
TEST(NestedContent, TableArray)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[[table.test]]
|
||||
a = 2
|
||||
b = 1.2
|
||||
[[table.test]]
|
||||
a = 4
|
||||
c = false
|
||||
[[table.test]]
|
||||
a = "five"
|
||||
d = []
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto table_test_1_a = sRoot.GetDirect("table.test[0].a");
|
||||
auto table_test_1_b = sRoot.GetDirect("table.test[0].b");
|
||||
auto table_test_2_a = sRoot.GetDirect("table.test[1].a");
|
||||
auto table_test_2_c = sRoot.GetDirect("table.test[1].c");
|
||||
auto table_test_3_a = sRoot.GetDirect("table.test[2].a");
|
||||
auto table_test_3_d = sRoot.GetDirect("table.test[2].d");
|
||||
|
||||
ASSERT_TRUE(table_test_1_a);
|
||||
EXPECT_EQ(table_test_1_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_test_1_a.GetValue<int>(), 2);
|
||||
ASSERT_TRUE(table_test_1_b);
|
||||
EXPECT_EQ(table_test_1_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_test_1_b.GetValue<double>(), 1.2);
|
||||
ASSERT_TRUE(table_test_2_a);
|
||||
EXPECT_EQ(table_test_2_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_test_2_a.GetValue<int>(), 4);
|
||||
ASSERT_TRUE(table_test_2_c);
|
||||
EXPECT_EQ(table_test_2_c.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_test_2_c.GetValue<bool>(), false);
|
||||
ASSERT_TRUE(table_test_3_a);
|
||||
EXPECT_EQ(table_test_3_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table_test_3_a.GetValue(), "five");
|
||||
ASSERT_TRUE(table_test_3_d);
|
||||
EXPECT_EQ(table_test_3_d.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
}
|
||||
|
||||
TEST(NestedContent, InlineTable)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
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"} }
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto table1_a = sRoot.GetDirect("table1.a");
|
||||
auto table1_b = sRoot.GetDirect("table1.b");
|
||||
auto table1_c = sRoot.GetDirect("table1.c");
|
||||
auto table2_a = sRoot.GetDirect("table2.a");
|
||||
auto table2_b = sRoot.GetDirect("table2.b");
|
||||
auto table2_e = sRoot.GetDirect("table2.e");
|
||||
auto table3_a_a = sRoot.GetDirect("table3.a.a");
|
||||
auto table3_a_b = sRoot.GetDirect("table3.a.b");
|
||||
auto table3_b_a = sRoot.GetDirect("table3.b.a");
|
||||
auto table3_b_b = sRoot.GetDirect("table3.b.b");
|
||||
auto table3_e_a = sRoot.GetDirect("table3.e.a");
|
||||
auto table3_e_b = sRoot.GetDirect("table3.e.b");
|
||||
|
||||
ASSERT_TRUE(table1_a);
|
||||
EXPECT_EQ(table1_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table1_a.GetValue<int>(), 0);
|
||||
ASSERT_TRUE(table1_b);
|
||||
EXPECT_EQ(table1_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table1_b.GetValue<double>(), 1.2);
|
||||
ASSERT_TRUE(table1_c);
|
||||
EXPECT_EQ(table1_c.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table1_c.GetValue(), "string");
|
||||
ASSERT_TRUE(table2_a);
|
||||
EXPECT_EQ(table2_a.GetType(), sdv::toml::simple_parser::ENodeType::node_array);
|
||||
ASSERT_TRUE(table2_b);
|
||||
EXPECT_EQ(table2_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table2_b.GetValue<bool>(), true);
|
||||
ASSERT_TRUE(table2_e);
|
||||
EXPECT_EQ(table2_e.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table2_e.GetValue<double>(), 2.71828);
|
||||
ASSERT_TRUE(table3_a_a);
|
||||
EXPECT_EQ(table3_a_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table3_a_a.GetValue(), "a");
|
||||
ASSERT_TRUE(table3_a_b);
|
||||
EXPECT_EQ(table3_a_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table3_a_b.GetValue(), "A");
|
||||
ASSERT_TRUE(table3_b_a);
|
||||
EXPECT_EQ(table3_b_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table3_b_a.GetValue(), "b");
|
||||
ASSERT_TRUE(table3_b_b);
|
||||
EXPECT_EQ(table3_b_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table3_b_b.GetValue(), "B");
|
||||
ASSERT_TRUE(table3_e_a);
|
||||
EXPECT_EQ(table3_e_a.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table3_e_a.GetValue(), "e");
|
||||
ASSERT_TRUE(table3_e_b);
|
||||
EXPECT_EQ(table3_e_b.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(table3_e_b.GetValue(), "E");
|
||||
}
|
||||
|
||||
TEST(NestedContent, InlineTableBreakLine)
|
||||
{
|
||||
// The following is not allowed in version 1.0, but is allowed in version 1.1
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
table = { a = 1, b = 2,
|
||||
c = 3, d = 4 }
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
table = { a = 1, b = 2
|
||||
,c = 3, d = 4 }
|
||||
)toml"));
|
||||
|
||||
// Line breaks are allowed when part of an array or have multi-line strings
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
array = [{ a = 1, b = 2},
|
||||
{c = 3, d = 4}]
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
table = { a = 1, b = [2, 3,
|
||||
4, 5], c = 6, d = 7}
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
table = { x = "abc", y = """def-
|
||||
ghi""", z = "jkl" }
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
table = { x = 'abc', y = '''def-
|
||||
ghi''', z = 'jkl' }
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Keys)
|
||||
{
|
||||
std::string ssUTF8String = u8R"toml(
|
||||
"127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value"
|
||||
)toml";
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(std::string_view(ssUTF8String)));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value"
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
"" = "blank" # VALID but discouraged
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
'' = 'blank' # VALID but discouraged
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true
|
||||
)toml"));
|
||||
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
fruit.name = "banana" # this is best practice
|
||||
fruit. color = "yellow" # same as fruit.color
|
||||
fruit . flavor = "banana" # same as fruit.flavor
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
# 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
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
# VALID BUT DISCOURAGED
|
||||
apple.type = "fruit"
|
||||
orange.type = "fruit"
|
||||
apple.skin = "thin"
|
||||
orange.skin = "thick"
|
||||
apple.color = "red"
|
||||
orange.color = "orange"
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
3.1415 = 3.1415
|
||||
)toml"));
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
3.1415 = 3.1415
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto table = sRoot.GetDirect("3");
|
||||
auto pi = sRoot.GetDirect("3.1415");
|
||||
ASSERT_TRUE(table);
|
||||
EXPECT_EQ(table.GetType(), sdv::toml::simple_parser::ENodeType::node_table);
|
||||
ASSERT_TRUE(pi);
|
||||
EXPECT_EQ(pi.GetType(), sdv::toml::simple_parser::ENodeType::node_value);
|
||||
EXPECT_EQ(pi.GetValue<double>(), 3.1415);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Arrays)
|
||||
{
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
]
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
integers3 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
]
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Tables)
|
||||
{
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[table-1]
|
||||
key1 = "some string"
|
||||
key2 = 123
|
||||
|
||||
[table-2]
|
||||
key1 = "another string"
|
||||
key2 = 456
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[dog."tater.man"]
|
||||
type.name = "pug"
|
||||
)toml"));
|
||||
|
||||
std::string ssUTF8String = u8R"toml(
|
||||
[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']
|
||||
)toml";
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(std::string_view(ssUTF8String)));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
# [x] you
|
||||
# [x.y] don't
|
||||
# [x.y.z] need these
|
||||
[x.y.z.w] # for this to work
|
||||
[x] # defining a super-table afterward is ok
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
# VALID BUT DISCOURAGED
|
||||
[fruit.apple]
|
||||
[animal]
|
||||
[fruit.orange]
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
[fruit.apple.texture] # you can add sub-tables
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(SpecialCases, TableArrays)
|
||||
{
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
[[products]] # empty table within the array
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
color = "gray"
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
[fruits.physical] # subtable
|
||||
color = "red"
|
||||
shape = "round"
|
||||
[[fruits.varieties]] # nested array of tables
|
||||
name = "red delicious"
|
||||
[[fruits.varieties]]
|
||||
name = "granny smith"
|
||||
[[fruits]]
|
||||
name = "banana"
|
||||
[[fruits.varieties]]
|
||||
name = "plantain"
|
||||
)toml"));
|
||||
|
||||
EXPECT_NO_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ]
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(ErrorCases, KeyValue)
|
||||
{
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(key = # node_invalid)toml"), std::exception);
|
||||
|
||||
EXPECT_THROW(
|
||||
sdv::toml::simple_parser::CParser(R"toml(first = "Tom" last = "Preston-Werner" # node_invalid)toml"), std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(= "no key name" # node_invalid)toml"), std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
name = "Tom"
|
||||
name = "Pradyun"
|
||||
)toml"),
|
||||
std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
fruit . flavor = "banana" # same as fruit.flavor
|
||||
fruit.flavor = "banana"
|
||||
)toml"),
|
||||
std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
spelling = "favorite"
|
||||
"spelling" = "favourite"
|
||||
)toml"),
|
||||
std::exception);
|
||||
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
# 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.
|
||||
# You can't turn an integer into a table.
|
||||
fruit.apple.smooth = true
|
||||
)toml"),
|
||||
std::exception);
|
||||
}
|
||||
|
||||
TEST(ErrorCases, Tables)
|
||||
{
|
||||
std::string ssUTF8String(u8R"toml(
|
||||
[ j . "ʞ" . 'l' ]
|
||||
[j."ʞ".'l']
|
||||
)toml");
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(std::string_view(ssUTF8String)), std::exception);
|
||||
|
||||
ssUTF8String = u8R"toml(
|
||||
[ j . "ʞ" . 'l' ]
|
||||
["j".'ʞ'."l"]
|
||||
)toml";
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(std::string_view(ssUTF8String)), std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[fruit]
|
||||
apple = "red"
|
||||
[fruit]
|
||||
orange = "orange"
|
||||
)toml"),
|
||||
std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[fruit]
|
||||
apple = "red"
|
||||
[fruit.apple]
|
||||
texture = "smooth"
|
||||
)toml"),
|
||||
std::exception);
|
||||
|
||||
// These two tests are not covered with current implementation.
|
||||
//EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
// [fruit]
|
||||
// apple.color = "red"
|
||||
// apple.taste.sweet = true
|
||||
// [fruit.apple] # INVALID
|
||||
// )toml"),
|
||||
// std::exception);
|
||||
//EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
// [fruit]
|
||||
// apple.color = "red"
|
||||
// apple.taste.sweet = true
|
||||
// [fruit.apple.taste] # INVALID
|
||||
// )toml"),
|
||||
// std::exception);
|
||||
}
|
||||
|
||||
TEST(ErrorCases, InlineTables)
|
||||
{
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
type = { name = "Nail" }
|
||||
type.edible = false # INVALID
|
||||
)toml"),
|
||||
std::exception);
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[product]
|
||||
type.name = "Nail"
|
||||
type = { edible = false } # INVALID
|
||||
)toml"),
|
||||
std::exception);
|
||||
}
|
||||
|
||||
TEST(ErrorCases, TableArrays)
|
||||
{
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[fruit.physical] # subtable, but to which parent element should it belong?
|
||||
color = "red"
|
||||
shape = "round"
|
||||
[[fruit]] # parser must throw an error upon discovering that "fruit" is
|
||||
# an array rather than a table
|
||||
name = "apple"
|
||||
)toml"),
|
||||
std::exception);
|
||||
|
||||
// The following test is not covered with the current implementation
|
||||
//EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
// fruits = []
|
||||
// [[fruits]] # Not allowed
|
||||
// )toml"),
|
||||
// std::exception);
|
||||
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
[[fruits.varieties]]
|
||||
name = "red delicious"
|
||||
# INVALID: This table conflicts with the previous array of tables
|
||||
[fruits.varieties]
|
||||
name = "granny smith"
|
||||
)toml"),
|
||||
std::exception);
|
||||
EXPECT_THROW(sdv::toml::simple_parser::CParser(R"toml(
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
[fruits.physical]
|
||||
color = "red"
|
||||
shape = "round"
|
||||
# INVALID: This array of tables conflicts with the previous table
|
||||
[[fruits.physical]]
|
||||
color = "green"
|
||||
)toml"),
|
||||
std::exception);
|
||||
}
|
||||
|
||||
TEST(Ordering, Array)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto two = sRoot.GetDirect("array[2]");
|
||||
auto eleven = sRoot.GetDirect("array[11]");
|
||||
const auto arr = sRoot.GetDirect("array");
|
||||
|
||||
// with direct access
|
||||
ASSERT_TRUE(two);
|
||||
EXPECT_EQ(two.GetValue<int>(), 2);
|
||||
ASSERT_TRUE(eleven);
|
||||
EXPECT_EQ(eleven.GetValue<int>(), 11);
|
||||
|
||||
// with indirect access through iterating
|
||||
ASSERT_TRUE(arr);
|
||||
EXPECT_EQ(arr.GetArray().size(), 12u);
|
||||
size_t nIndex = 0;
|
||||
for (const auto& rsNode : arr.GetArray())
|
||||
EXPECT_EQ(rsNode.GetValue<size_t>(), nIndex++);
|
||||
}
|
||||
|
||||
TEST(Ordering, TableAray)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[[tableArray]]
|
||||
a = 0
|
||||
[[tableArray]]
|
||||
a = 1
|
||||
[[tableArray]]
|
||||
a = 2
|
||||
[[tableArray]]
|
||||
a = 3
|
||||
[[tableArray]]
|
||||
a = 4
|
||||
[[tableArray]]
|
||||
a = 5
|
||||
[[tableArray]]
|
||||
a = 6
|
||||
[[tableArray]]
|
||||
a = 7
|
||||
[[tableArray]]
|
||||
a = 8
|
||||
[[tableArray]]
|
||||
a = 9
|
||||
[[tableArray]]
|
||||
a = 10
|
||||
[[tableArray]]
|
||||
a = 11
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto tableArray = sRoot.GetDirect("tableArray");
|
||||
|
||||
ASSERT_TRUE(tableArray);
|
||||
EXPECT_EQ(tableArray.GetArray().size(), 12u);
|
||||
size_t nIndex = 0;
|
||||
for (const auto& rsNode : tableArray.GetArray())
|
||||
EXPECT_EQ(rsNode.GetDirect("a").GetValue<size_t>(), nIndex++);
|
||||
}
|
||||
|
||||
TEST(Ordering, TableArayWithTables)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[topTable]
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 0
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 1
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 2
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 3
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 4
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 5
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 6
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 7
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 8
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 9
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 10
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 11
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto tableArray = sRoot.GetDirect("topTable.tableArray");
|
||||
|
||||
ASSERT_TRUE(tableArray);
|
||||
EXPECT_EQ(tableArray.GetArray().size(), 12u);
|
||||
size_t nIndex = 0;
|
||||
for (const auto& rsNode : tableArray.GetArray())
|
||||
EXPECT_EQ(rsNode.GetDirect("MyTable.a").GetValue<size_t>(), nIndex++);
|
||||
}
|
||||
|
||||
TEST(Ordering, NodeGetDirect)
|
||||
{
|
||||
sdv::toml::simple_parser::CParser parser(R"toml(
|
||||
[[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 }]
|
||||
)toml");
|
||||
auto sRoot = parser.Root();
|
||||
|
||||
auto table_test_1_a = sRoot.GetDirect("table.test[0].a");
|
||||
auto table_test_1_b = sRoot.GetDirect("table.test[0].b");
|
||||
auto table_test_2_a = sRoot.GetDirect("table.test[1].a");
|
||||
auto table_test_2_c = sRoot.GetDirect("table.test[1].c");
|
||||
auto table_test_3_a = sRoot.GetDirect("table.test[2].a");
|
||||
auto table_test_3_d = sRoot.GetDirect("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::simple_parser::ENodeType::node_array);
|
||||
|
||||
auto table_test_3 = sRoot.GetDirect("table.test[2]");
|
||||
auto table_test_3_2nd = table_test_3.GetDirect("d[2].x");
|
||||
ASSERT_TRUE(table_test_3_2nd);
|
||||
}
|
||||
|
||||
@@ -96,15 +96,15 @@ bool CANSocketTest::vcanIsInstalled = false;
|
||||
class CTestCANSocket : public CCANSockets
|
||||
{
|
||||
public:
|
||||
virtual void Initialize(const sdv::u8string& ssObjectConfig) override
|
||||
{
|
||||
CCANSockets::Initialize(ssObjectConfig);
|
||||
}
|
||||
// virtual void OnInitialize(const sdv::ObjectInfo& sObjectInfo) override
|
||||
// {
|
||||
// CCANSockets::OnInitialize(sObjectInfo);
|
||||
// }
|
||||
|
||||
virtual void Shutdown() override
|
||||
{
|
||||
CCANSockets::Shutdown();
|
||||
}
|
||||
// virtual void Shutdown() override
|
||||
// {
|
||||
// CCANSockets::Shutdown();
|
||||
// }
|
||||
|
||||
virtual void Send(const sdv::can::SMessage& sMsg, uint32_t uiIfcIndex) override
|
||||
{
|
||||
@@ -199,7 +199,9 @@ bool InitializeAppControl(sdv::app::CAppControl* appcontrol, const std::string&
|
||||
|
||||
void InitializeCanComObject(CTestCANSocket& canComObj, const std::string config, MockCANReceiver& mockRcv)
|
||||
{
|
||||
ASSERT_NO_THROW(canComObj.Initialize(config.c_str()));
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = config;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialized);
|
||||
ASSERT_NO_THROW(canComObj.SetOperationMode(sdv::EOperationMode::configuring));
|
||||
ASSERT_NO_THROW(canComObj.RegisterReceiver(&mockRcv));
|
||||
@@ -228,9 +230,10 @@ TEST_F(CANSocketTest, ValidConfigString)
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig = R"(canSockets = "vcan0")"; // vcan0 interface must exist
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = "vcan0")"; // vcan0 interface must exist
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
ASSERT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Send(testMsg, 0));
|
||||
@@ -244,9 +247,10 @@ TEST_F(CANSocketTest, InvalidConfigString)
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig = R"(canSockets = "vcan08")";
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = "vcan08")";
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialization_failure);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Shutdown());
|
||||
@@ -260,9 +264,10 @@ TEST_F(CANSocketTest, ValidConfigArray)
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig = R"(canSockets = ["vcan0", "vcan1"])";
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = ["vcan0", "vcan1"])";
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Send(testMsg, 0));
|
||||
@@ -276,9 +281,10 @@ TEST_F(CANSocketTest, InvalidConfigArray)
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig = R"(canSockets = ["vcan08", "vcan09"])";
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = ["vcan08", "vcan09"])";
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialization_failure);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Shutdown());
|
||||
@@ -292,9 +298,10 @@ TEST_F(CANSocketTest, ValidConfigArrayButUnknownElement)
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig = R"(canSockets = ["vcan0", "vcan08"])";
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = ["vcan0", "vcan08"])";
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Send(testMsg, 0));
|
||||
@@ -308,9 +315,10 @@ TEST_F(CANSocketTest, InvalidConfigIdentifier)
|
||||
sdv::app::CAppControl appControl;
|
||||
appControl.Startup("");
|
||||
|
||||
sdv::u8string ssObjectConfig = R"(invalidCanSockets = ["vcan0", "vcan1"])"; // Invalid config identifier
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(invalidCanSockets = ["vcan0", "vcan1"])"; // Invalid config identifier
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssObjectConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialization_failure);
|
||||
|
||||
ASSERT_NO_THROW(canComObj.Shutdown());
|
||||
@@ -478,11 +486,11 @@ TEST_F(CANSocketTest, StressTestWith3Objects)
|
||||
|
||||
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));
|
||||
sdv::core::secure_thread thSendThread1(SendThread, std::ref(stopSendThread), std::ref(canComObj1), std::ref(testData1));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
std::thread thSendThread2(SendThread, std::ref(stopSendThread), std::ref(canComObj2), std::ref(testData2));
|
||||
sdv::core::secure_thread thSendThread2(SendThread, std::ref(stopSendThread), std::ref(canComObj2), std::ref(testData2));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
std::thread thSendThread3(SendThread, std::ref(stopSendThread), std::ref(canComObj3), std::ref(testData3));
|
||||
sdv::core::secure_thread thSendThread3(SendThread, std::ref(stopSendThread), std::ref(canComObj3), std::ref(testData3));
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||
|
||||
@@ -702,9 +710,10 @@ TEST_F(CANSocketTest, ManualSendAndReceiveTestOfMulitpleSockets)
|
||||
uint32_t vcan2Index = 6;
|
||||
uint32_t vcan3Index = 1;
|
||||
uint32_t vcan4Index = 5;
|
||||
sdv::u8string ssConfig = R"(canSockets = ["vcan0", "vcan3", "vcan8", "vcan1", "vcan9", "vcan4", "vcan2"])";
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssConfig.c_str()));
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = ["vcan0", "vcan3", "vcan8", "vcan1", "vcan9", "vcan4", "vcan2"])";
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Register a receiver.
|
||||
@@ -772,9 +781,10 @@ TEST_F(CANSocketTest, ManualSendAndReceiveTestWithDifferentDataSizes)
|
||||
uint32_t vcan2Index = 6;
|
||||
uint32_t vcan3Index = 1;
|
||||
uint32_t vcan4Index = 5;
|
||||
sdv::u8string ssConfig = R"(canSockets = ["vcan0", "vcan3", "vcan8", "vcan1", "vcan9", "vcan4", "vcan2"])";
|
||||
sdv::SObjectInfo sObjectInfo{};
|
||||
sObjectInfo.ssConfig = R"(canSockets = ["vcan0", "vcan3", "vcan8", "vcan1", "vcan9", "vcan4", "vcan2"])";
|
||||
CTestCANSocket canComObj;
|
||||
ASSERT_NO_THROW(canComObj.Initialize(ssConfig.c_str()));
|
||||
ASSERT_NO_THROW(canComObj.Initialize(sObjectInfo));
|
||||
EXPECT_EQ(canComObj.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// Register a receiver.
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
# Erik Verhoeven - writing TOML and whitespace preservation
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project (UnitTest_TOMLParser VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Character Reader executable
|
||||
add_executable(UnitTest_TOMLParser
|
||||
"character_reader_tests.cpp"
|
||||
@@ -19,13 +22,17 @@ add_executable(UnitTest_TOMLParser
|
||||
"parser_tests.cpp"
|
||||
"main.cpp"
|
||||
"generate_toml_tests.cpp"
|
||||
"generate_toml_delete_node.cpp"
|
||||
"delete_node.cpp"
|
||||
"statement_boundary_detection.cpp"
|
||||
"miscellaneous_tests.cpp"
|
||||
"miscellaneous.cpp"
|
||||
"generate_toml_with_transfer.cpp"
|
||||
"generate_toml_switch_inline.cpp"
|
||||
"generate_toml_getset_comment.cpp"
|
||||
"generate_toml_insert_node.cpp" "generate_toml_miscellaneous.cpp" "generate_toml_combine_reduce.cpp")
|
||||
"getset_comment.cpp"
|
||||
"insert_node.cpp"
|
||||
"combine_reduce.cpp"
|
||||
"comparison_tests.cpp"
|
||||
"make_inline_standard.cpp"
|
||||
"indexer_tests.cpp" "cascade_insert_node.cpp")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_libraries(UnitTest_TOMLParser GTest::GTest ${CMAKE_THREAD_LIBS_INIT})
|
||||
if (WIN32)
|
||||
|
||||
536
tests/unit_tests/toml_parser/cascade_insert_node.cpp
Normal file
536
tests/unit_tests/toml_parser/cascade_insert_node.cpp
Normal file
@@ -0,0 +1,536 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include <support/toml.h>
|
||||
|
||||
TEST(CascadeInsertNode, InsertValueInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
|
||||
// Insert the value into the new table
|
||||
EXPECT_TRUE(root.InsertValue("", "standard_table.value_int", 10));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_int = 10)toml");
|
||||
|
||||
// Insert the values into the existing table
|
||||
EXPECT_TRUE(root.InsertValue("", "standard_table.value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
EXPECT_TRUE(root.InsertValue("standard_table.value_int", "standard_table.value_float", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_float = 123.456
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "standard_table", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "standard_table.table1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table.table1])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(root.InsertTable("standard_table.table1", "standard_table.table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table2 = {}
|
||||
[standard_table.table1])toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "standard_table.table3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[standard_table.table1])toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table relative to the elements of the
|
||||
// standard_table.
|
||||
EXPECT_TRUE(root.InsertTable("standard_table.table2", "standard_table.table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[standard_table.table4]
|
||||
[standard_table.table1])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertArrayInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "standard_table", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(root.InsertArray("", "standard_table.value_array1"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_array1 = [])toml");
|
||||
EXPECT_TRUE(root.InsertArray("", "standard_table.value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
EXPECT_TRUE(root.InsertArray("standard_table.value_array1", "standard_table.value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_array3 = []
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableArrayInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "standard_table", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "standard_table.table_array1",
|
||||
false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[standard_table.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(root.InsertTableArray("standard_table.table_array1", "standard_table.table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
[[standard_table.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "standard_table.table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[standard_table.table_array1]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array relative to the elements
|
||||
// of the standard_table.
|
||||
EXPECT_TRUE(root.InsertTableArray("standard_table.table_array2", "standard_table.table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[standard_table.table_array4]]
|
||||
[[standard_table.table_array1]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(root.InsertTableArray("", "standard_table.table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[standard_table.table_array4]]
|
||||
[[standard_table.table_array1]]
|
||||
[[standard_table.table_array4]])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertValueInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_table", true));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert the values into the table
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_table.value_int", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_int = 10})toml");
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_table.value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_int = 10, value_str = "abc"})toml");
|
||||
EXPECT_TRUE(root.InsertValue("inline_table.value_int", "inline_table.value_float", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_float = 123.456, value_int = 10, value_str = "abc"})toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_table", true));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_table.table1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table1 = {}})toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(root.InsertTable("inline_table.table1", "inline_table.table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table2 = {}, table1 = {}})toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_table.table3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table2 = {}, table1 = {}, table3 = {}})toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table
|
||||
EXPECT_TRUE(root.InsertTable("inline_table.table2", "inline_table.table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table4 = {}, table2 = {}, table1 = {}, table3 = {}})toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertArrayInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_table",
|
||||
true));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_table.value_array1"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_array1 = []})toml");
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_table.value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_array1 = [], value_array2 = []})toml");
|
||||
EXPECT_TRUE(root.InsertArray("inline_table.value_array1", "inline_table.value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_array3 = [], value_array1 = [], value_array2 = []})toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableArrayInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_table", true));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "inline_table.table_array1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table_array1 = [{}]})toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(root.InsertTableArray("inline_table.table_array1", "inline_table.table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table_array2 = [{}], table_array1 = [{}]})toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "inline_table.table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table_array2 = [{}], table_array1 = [{}], table_array3 = [{}]})toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_TRUE(root.InsertTableArray("inline_table.table_array2", "inline_table.table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML,
|
||||
R"toml(inline_table = {table_array4 = [{}], table_array2 = [{}], table_array1 = [{}], table_array3 = [{}]})toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(root.InsertTableArray("", "inline_table.table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML,
|
||||
R"toml(inline_table = {table_array4 = [{}, {}], table_array2 = [{}], table_array1 = [{}], table_array3 = [{}]})toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertValueInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_array"));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert the values into the table (with or without name)
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [10])toml");
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [10, "abc"])toml");
|
||||
EXPECT_TRUE(root.InsertValue("inline_array[0]", "inline_array", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [123.456, 10, "abc"])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_array"));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_array", false));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].a", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{a = 10}])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(root.InsertTable("inline_array[0]", "inline_array", true));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].b", 20));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{b = 20}, {a = 10}])toml");
|
||||
|
||||
// Insert an inline table behind
|
||||
EXPECT_TRUE(root.InsertTable("", "inline_array", true));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array.c", 30));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{b = 20}, {a = 10}, {c = 30}])toml");
|
||||
|
||||
// Insert a standard table in front
|
||||
EXPECT_TRUE(root.InsertTable("inline_array[0]", "inline_array", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].d", 40));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{d = 40}, {b = 20}, {a = 10}, {c = 30}])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertArrayInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_array"));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_array"));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0]", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[10]])toml");
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_array"));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[1]", 20));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[10], [20]])toml");
|
||||
EXPECT_TRUE(root.InsertArray("inline_array[0]", "inline_array"));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0]", 30));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[30], [10], [20]])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableArrayInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertArray("", "inline_array"));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "inline_array", false));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].a", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{a = 10}]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(root.InsertTableArray("inline_array[0]", "inline_array", true));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].b", 20));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{b = 20}], [{a = 10}]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "inline_array", true));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[999].c", 30));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{b = 20}], [{a = 10}], [{c = 30}]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_TRUE(root.InsertTableArray("inline_array[0]", "inline_array", false));
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].d", 40));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{d = 40}], [{b = 20}], [{a = 10}], [{c = 30}]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(root.InsertValue("", "inline_array[0].e", 50));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{d = 40, e = 50}], [{b = 20}], [{a = 10}], [{c = 30}]])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertValueInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert the values into the table
|
||||
EXPECT_TRUE(root.InsertValue("", "table_array.value_int", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_int = 10)toml");
|
||||
EXPECT_TRUE(root.InsertValue("", "table_array.value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
EXPECT_TRUE(root.InsertValue("table_array[0]", "table_array.value_float", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_float = 123.456
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "table_array.table1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
[table_array.table1])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(root.InsertTable("table_array[0]", "table_array.table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table2 = {}
|
||||
[table_array.table1])toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "table_array.table3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[table_array.table1])toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table
|
||||
EXPECT_TRUE(root.InsertTable("table_array[0]", "table_array.table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[table_array.table4]
|
||||
[table_array.table1])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertArrayInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(root.InsertArray("", "table_array.value_array1"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_array1 = [])toml");
|
||||
EXPECT_TRUE(root.InsertArray("", "table_array.value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
EXPECT_TRUE(root.InsertArray("table_array[0]", "table_array.value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_array3 = []
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
}
|
||||
|
||||
TEST(CascadeInsertNode, InsertTableArrayInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array.table_array1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(root.InsertTableArray("table_array[0]", "table_array.table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array.table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_TRUE(root.InsertTableArray("table_array[0]", "table_array.table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array.table_array4]]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array.table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array.table_array4]]
|
||||
[[table_array.table_array1]]
|
||||
[[table_array.table_array4]])toml");
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/character_reader_utf_8.h"
|
||||
#include "../../../sdv_services/core/toml_parser/exception.h"
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
|
||||
TEST(GenerateTOML, CombineRoot)
|
||||
TEST(CombineReduse, CombineRoot)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10
|
||||
@@ -27,10 +27,10 @@ val1 = 10)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(
|
||||
std::string ssCombinedTOML = R"toml(
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -38,7 +38,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineRootComments)
|
||||
TEST(CombineReduse, CombineRootComments)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10 # This is value 1
|
||||
@@ -49,10 +49,10 @@ val1 = 10 # This is again value 1)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(
|
||||
std::string ssCombinedTOML = R"toml(
|
||||
val1 = 10 # This is value 1
|
||||
val2 = "20" # This is value 2
|
||||
val3 = 30.0 # This is value 3)code";
|
||||
val3 = 30.0 # This is value 3)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -60,7 +60,7 @@ val3 = 30.0 # This is value 3)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineRootwithTable)
|
||||
TEST(CombineReduse, CombineRootwithTableValues)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10
|
||||
@@ -73,10 +73,10 @@ val1 = 10)toml");
|
||||
ASSERT_TRUE(ptrTable);
|
||||
EXPECT_TRUE(parser1.Root().Combine(ptrTable->Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(
|
||||
std::string ssCombinedTOML = R"toml(
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -84,7 +84,55 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineTablewithRoot)
|
||||
TEST(CombineReduse, CombineRootwithStandardTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10
|
||||
val2 = "20")toml");
|
||||
toml_parser::CParser parser2(R"toml([MyTable]
|
||||
val3 = 30.0
|
||||
val1 = 10)toml");
|
||||
|
||||
auto ptrTable = &parser2.Root();
|
||||
ASSERT_TRUE(ptrTable);
|
||||
EXPECT_TRUE(parser1.Root().Combine(ptrTable->Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"toml(
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
[MyTable]
|
||||
val3 = 30.0
|
||||
val1 = 10)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(CombineReduse, CombineRootwithInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10
|
||||
val2 = "20")toml");
|
||||
toml_parser::CParser parser2(R"toml(MyTable = {val3 = 30.0, val1 = 10})toml");
|
||||
|
||||
auto ptrTable = &parser2.Root();
|
||||
ASSERT_TRUE(ptrTable);
|
||||
EXPECT_TRUE(parser1.Root().Combine(ptrTable->Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"toml(
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
MyTable = {val3 = 30.0, val1 = 10})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(CombineReduse, CombineTablewithRoot)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([MyTable]
|
||||
val1 = 10
|
||||
@@ -99,10 +147,10 @@ val1 = 10)toml");
|
||||
ASSERT_TRUE(ptrTable);
|
||||
EXPECT_TRUE(ptrTable->Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code([MyTable]
|
||||
std::string ssCombinedTOML = R"toml([MyTable]
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -110,7 +158,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineTablewithDifferentTable)
|
||||
TEST(CombineReduse, CombineTablewithDifferentTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([MyTable1]
|
||||
val1 = 10
|
||||
@@ -129,10 +177,10 @@ val1 = 10)toml");
|
||||
ASSERT_TRUE(ptrTable2);
|
||||
EXPECT_TRUE(ptrTable1->Combine(ptrTable2));
|
||||
|
||||
std::string ssCombinedTOML = R"code([MyTable1]
|
||||
std::string ssCombinedTOML = R"toml([MyTable1]
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -140,7 +188,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineTablewithIdenticalTable)
|
||||
TEST(CombineReduse, CombineTablewithIdenticalTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([MyTable]
|
||||
val1 = 10
|
||||
@@ -151,10 +199,10 @@ val1 = 10)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code([MyTable]
|
||||
std::string ssCombinedTOML = R"toml([MyTable]
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -162,7 +210,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineInlineTablewithDifferentStandardTable)
|
||||
TEST(CombineReduse, CombineInlineTablewithDifferentStandardTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(MyTable1 = {val1 = 10, val2 = "20"})toml");
|
||||
toml_parser::CParser parser2(R"toml([MyTable2]
|
||||
@@ -179,7 +227,7 @@ val1 = 10)toml");
|
||||
ASSERT_TRUE(ptrTable2);
|
||||
EXPECT_TRUE(ptrTable1->Combine(ptrTable2));
|
||||
|
||||
std::string ssCombinedTOML = R"code(MyTable1 = {val1 = 10, val2 = "20", val3 = 30.0})code";
|
||||
std::string ssCombinedTOML = R"toml(MyTable1 = {val1 = 10, val2 = "20", val3 = 30.0})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -187,7 +235,7 @@ val1 = 10)toml");
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineInlineTablewithIdenticalStandardTable)
|
||||
TEST(CombineReduse, CombineInlineTablewithIdenticalStandardTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(MyTable = {val1 = 10, val2 = "20"})toml");
|
||||
toml_parser::CParser parser2(R"toml([MyTable]
|
||||
@@ -196,7 +244,7 @@ val1 = 10)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(MyTable = {val1 = 10, val2 = "20", val3 = 30.0})code";
|
||||
std::string ssCombinedTOML = R"toml(MyTable = {val1 = 10, val2 = "20", val3 = 30.0})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -204,7 +252,7 @@ val1 = 10)toml");
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineStandardTablewithDifferentInlineTable)
|
||||
TEST(CombineReduse, CombineStandardTablewithDifferentInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([MyTable1]
|
||||
val1 = 10
|
||||
@@ -221,10 +269,10 @@ val2 = "20")toml");
|
||||
ASSERT_TRUE(ptrTable2);
|
||||
EXPECT_TRUE(ptrTable1->Combine(ptrTable2));
|
||||
|
||||
std::string ssCombinedTOML = R"code([MyTable1]
|
||||
std::string ssCombinedTOML = R"toml([MyTable1]
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -232,7 +280,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineStandardTablewithIdenticalInlineTable)
|
||||
TEST(CombineReduse, CombineStandardTablewithIdenticalInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([MyTable]
|
||||
val1 = 10
|
||||
@@ -241,10 +289,10 @@ val2 = "20")toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code([MyTable]
|
||||
std::string ssCombinedTOML = R"toml([MyTable]
|
||||
val1 = 10
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -252,7 +300,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineInlineTablewithDifferentInlineTable)
|
||||
TEST(CombineReduse, CombineInlineTablewithDifferentInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(MyTable1 = {val1 = 10, val2 = "20"})toml");
|
||||
toml_parser::CParser parser2(R"toml(MyTable2 = {val3 = 30.0, val1 = 10})toml");
|
||||
@@ -267,7 +315,7 @@ TEST(GenerateTOML, CombineInlineTablewithDifferentInlineTable)
|
||||
ASSERT_TRUE(ptrTable2);
|
||||
EXPECT_TRUE(ptrTable1->Combine(ptrTable2));
|
||||
|
||||
std::string ssCombinedTOML = R"code(MyTable1 = {val1 = 10, val2 = "20", val3 = 30.0})code";
|
||||
std::string ssCombinedTOML = R"toml(MyTable1 = {val1 = 10, val2 = "20", val3 = 30.0})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -275,14 +323,14 @@ TEST(GenerateTOML, CombineInlineTablewithDifferentInlineTable)
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineInlineTablewithIdenticalInlineTable)
|
||||
TEST(CombineReduse, CombineInlineTablewithIdenticalInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(MyTable = {val1 = 10, val2 = "20"})toml");
|
||||
toml_parser::CParser parser2(R"toml(MyTable = {val3 = 30.0, val1 = 10})toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(MyTable = {val1 = 10, val2 = "20", val3 = 30.0})code";
|
||||
std::string ssCombinedTOML = R"toml(MyTable = {val1 = 10, val2 = "20", val3 = 30.0})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -290,7 +338,7 @@ TEST(GenerateTOML, CombineInlineTablewithIdenticalInlineTable)
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineDifferentArrays)
|
||||
TEST(CombineReduse, CombineDifferentArrays)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = [10, 20]
|
||||
@@ -301,10 +349,10 @@ val1 = [70, 80])toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(
|
||||
std::string ssCombinedTOML = R"toml(
|
||||
val1 = [70, 80]
|
||||
val2 = ["30", "40"]
|
||||
val3 = [50.0, 60.0])code";
|
||||
val3 = [50.0, 60.0])toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -312,12 +360,13 @@ val3 = [50.0, 60.0])code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, CombineDifferentTableArrays)
|
||||
TEST(CombineReduse, CombineDifferentTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([[table_array1]]
|
||||
val1 = [10, 20]
|
||||
[[table_array1]]
|
||||
val2 = ["30", "40"])toml");
|
||||
|
||||
toml_parser::CParser parser2(R"toml(
|
||||
[[table_array2]]
|
||||
val3 = [50.0, 60.0]
|
||||
@@ -326,14 +375,14 @@ val1 = [70, 80])toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Combine(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code([[table_array1]]
|
||||
std::string ssCombinedTOML = R"toml([[table_array1]]
|
||||
val1 = [10, 20]
|
||||
[[table_array1]]
|
||||
val2 = ["30", "40"]
|
||||
[[table_array2]]
|
||||
val3 = [50.0, 60.0]
|
||||
[[table_array2]]
|
||||
val1 = [70, 80])code";
|
||||
val1 = [70, 80])toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -341,7 +390,7 @@ val1 = [70, 80])code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceRoot)
|
||||
TEST(CombineReduse, ReduceRoot)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10
|
||||
@@ -353,9 +402,8 @@ val1 = 10)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Reduce(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
std::string ssCombinedTOML = R"toml(val2 = "20"
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -363,7 +411,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceRootComments)
|
||||
TEST(CombineReduse, ReduceRootComments)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = 10 # This is value 1
|
||||
@@ -375,9 +423,8 @@ val1 = 10 # This also is value 1)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Reduce(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(
|
||||
val2 = "20" # This is value 2
|
||||
val3 = 30.0 # This is value 3)code";
|
||||
std::string ssCombinedTOML = R"toml(val2 = "20" # This is value 2
|
||||
val3 = 30.0 # This is value 3)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -385,7 +432,7 @@ val3 = 30.0 # This is value 3)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceTable)
|
||||
TEST(CombineReduse, ReduceTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([my_table]
|
||||
val1 = 10
|
||||
@@ -397,9 +444,9 @@ val1 = 10)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Reduce(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code([my_table]
|
||||
std::string ssCombinedTOML = R"toml([my_table]
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -407,7 +454,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceStandardTableWithInlineTable)
|
||||
TEST(CombineReduse, ReduceStandardTableWithInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml([my_table]
|
||||
val1 = 10
|
||||
@@ -417,9 +464,9 @@ val3 = 30.0)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Reduce(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code([my_table]
|
||||
std::string ssCombinedTOML = R"toml([my_table]
|
||||
val2 = "20"
|
||||
val3 = 30.0)code";
|
||||
val3 = 30.0)toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -427,7 +474,7 @@ val3 = 30.0)code";
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceInlineTableWithStandardTable)
|
||||
TEST(CombineReduse, ReduceInlineTableWithStandardTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(my_table = {val1 = 10, val2 = "20", val3 = 30.0})toml");
|
||||
toml_parser::CParser parser2(R"toml([my_table]
|
||||
@@ -436,7 +483,7 @@ val1 = 10)toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Reduce(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(my_table = { val2 = "20", val3 = 30.0})code";
|
||||
std::string ssCombinedTOML = R"toml(my_table = { val2 = "20", val3 = 30.0})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -444,14 +491,14 @@ val1 = 10)toml");
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceInlineTable)
|
||||
TEST(CombineReduse, ReduceInlineTable)
|
||||
{
|
||||
toml_parser::CParser parser1(R"toml(my_table = {val1 = 10, val2 = "20", val3 = 30.0})toml");
|
||||
toml_parser::CParser parser2(R"toml(my_table = {val3 = 35.0, val1 = 10})toml");
|
||||
|
||||
EXPECT_TRUE(parser1.Root().Reduce(parser2.Root().Cast<toml_parser::CNodeCollection>()));
|
||||
|
||||
std::string ssCombinedTOML = R"code(my_table = { val2 = "20", val3 = 30.0})code";
|
||||
std::string ssCombinedTOML = R"toml(my_table = { val2 = "20", val3 = 30.0})toml";
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser1.GenerateTOML());
|
||||
@@ -459,12 +506,12 @@ TEST(GenerateTOML, ReduceInlineTable)
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceDifferentArrays)
|
||||
TEST(CombineReduse, ReduceDifferentArrays)
|
||||
{
|
||||
toml_parser::CParser parser1(R"code(
|
||||
toml_parser::CParser parser1(R"toml(
|
||||
val1 = [10, 20]
|
||||
val2 = ["30", "40"]
|
||||
val3 = [50.0, 60.0])code");
|
||||
val3 = [50.0, 60.0])toml");
|
||||
toml_parser::CParser parser2(R"toml(
|
||||
val3 = [50.0, 60.0]
|
||||
val1 = [70, 80])toml");
|
||||
@@ -482,16 +529,16 @@ val2 = ["30", "40"]
|
||||
EXPECT_EQ(ssGenerated, ssCombinedTOML);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, ReduceDifferentTableArrays)
|
||||
TEST(CombineReduse, ReduceDifferentTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser1(R"code([[table_array1]]
|
||||
toml_parser::CParser parser1(R"toml([[table_array1]]
|
||||
val1 = [10, 20]
|
||||
[[table_array1]]
|
||||
val2 = ["30", "40"]
|
||||
[[table_array2]]
|
||||
val3 = [50.0, 60.0]
|
||||
[[table_array2]]
|
||||
val1 = [70, 80])code");
|
||||
val1 = [70, 80])toml");
|
||||
toml_parser::CParser parser2(R"toml(
|
||||
[[table_array1]]
|
||||
val2 = ["30", "40"]
|
||||
386
tests/unit_tests/toml_parser/comparison_tests.cpp
Normal file
386
tests/unit_tests/toml_parser/comparison_tests.cpp
Normal file
@@ -0,0 +1,386 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <functional>
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include <support/toml.h>
|
||||
#include "../../../sdv_services/core/toml_parser/exception.h"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
|
||||
bool CompareTest(const std::string& rssToml1, const std::string& rssToml2,
|
||||
uint32_t uiCompareFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_all))
|
||||
{
|
||||
try
|
||||
{
|
||||
toml_parser::CParser parser1(rssToml1);
|
||||
toml_parser::CParser parser2(rssToml2);
|
||||
sdv::toml::CNodeCollection collection1(&parser1.Root());
|
||||
sdv::toml::CNodeCollection collection2(&parser2.Root());
|
||||
return sdv::toml::internal::CompareNodes(collection1, collection2, uiCompareFlags) ==
|
||||
sdv::toml::ECompareResult::compare_identical;
|
||||
}
|
||||
catch (const toml_parser::XTOMLParseException&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareInvalid)
|
||||
{
|
||||
EXPECT_FALSE(CompareTest("var = A", ""));
|
||||
EXPECT_FALSE(CompareTest("[[test]", ""));
|
||||
EXPECT_FALSE(CompareTest(R"toml([test]
|
||||
test1 = "this is invalid')toml", ""));
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareEmpty)
|
||||
{
|
||||
// Identical
|
||||
uint32_t uiFlags = 0u;
|
||||
EXPECT_FALSE(CompareTest("var = 1", "", uiFlags));
|
||||
EXPECT_FALSE(CompareTest("", "var = 2", uiFlags));
|
||||
EXPECT_TRUE(CompareTest("", "", uiFlags));
|
||||
EXPECT_FALSE(CompareTest("", R"toml(
|
||||
)toml", uiFlags));
|
||||
EXPECT_FALSE(CompareTest("", R"toml(# This is a comment)toml", uiFlags));
|
||||
|
||||
// Ignore whitespace
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_whitespace);
|
||||
EXPECT_FALSE(CompareTest("var = 1", "", uiFlags));
|
||||
EXPECT_FALSE(CompareTest("", "var = 2", uiFlags));
|
||||
EXPECT_TRUE(CompareTest("", "", uiFlags));
|
||||
EXPECT_TRUE(CompareTest("", R"toml(
|
||||
)toml", uiFlags));
|
||||
EXPECT_FALSE(CompareTest("", R"toml(# This is a comment)toml", uiFlags));
|
||||
|
||||
// Ignore comments
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_comments);
|
||||
EXPECT_FALSE(CompareTest("var = 1", "", uiFlags));
|
||||
EXPECT_FALSE(CompareTest("", "var = 2", uiFlags));
|
||||
EXPECT_TRUE(CompareTest("", "", uiFlags));
|
||||
EXPECT_TRUE(CompareTest("", R"toml(
|
||||
)toml", uiFlags));
|
||||
EXPECT_TRUE(CompareTest("", R"toml(# This is a comment)toml", uiFlags));
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareValues)
|
||||
{
|
||||
std::string ssVal = "val = 1";
|
||||
std::string ssVal2 = "val = 2";
|
||||
std::string ssValSpace = " val = 1";
|
||||
std::string ssValCommentsBefore = R"toml(# comment
|
||||
|
||||
# more comment
|
||||
val = 1)toml";
|
||||
std::string ssValCommentsBehind = R"toml( val = 1 # comment
|
||||
# more comment
|
||||
|
||||
# lots more comment)toml";
|
||||
|
||||
// Identical
|
||||
uint32_t uiFlags = 0u;
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssVal, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssVal2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssValSpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssValCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssValCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore whitespace
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_whitespace);
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssVal, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssVal2, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValSpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssValCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssValCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore comments
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_comments);
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssVal, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssVal2, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValSpace, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore all
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_all);
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssVal, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssVal, ssVal2, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValSpace, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssVal, ssValCommentsBehind, uiFlags));
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareTables)
|
||||
{
|
||||
std::string ssStandardTable = R"toml([table1]
|
||||
val = 1)toml";
|
||||
std::string ssStandardTable2 = R"toml([table2]
|
||||
val = 1)toml";
|
||||
std::string ssStandardTable1_3 = R"toml([table1]
|
||||
val = 3)toml";
|
||||
std::string ssInlineTable = R"toml(table1 = {val = 1})toml";
|
||||
std::string ssTableSpace = R"toml( [table1]
|
||||
|
||||
val = 1)toml";
|
||||
std::string ssTableCommentsBefore = R"toml(# comment
|
||||
|
||||
# more comment
|
||||
[table1]
|
||||
val = 1)toml";
|
||||
std::string ssTableCommentsBehind = R"toml( [table1] # comment
|
||||
val = 1 # comment
|
||||
# more comment
|
||||
|
||||
# lots more comment)toml";
|
||||
|
||||
// Identical
|
||||
uint32_t uiFlags = 0u;
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssStandardTable, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable1_3, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssInlineTable, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableSpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore whitespace
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_whitespace);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssStandardTable, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable1_3, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssInlineTable, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableSpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore comments
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_comments);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssStandardTable, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable1_3, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssInlineTable, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableSpace, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore inline
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_inline);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssStandardTable, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable1_3, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssInlineTable, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableSpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssTableCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore all
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_all);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssStandardTable, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTable, ssStandardTable1_3, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssInlineTable, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableSpace, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTable, ssTableCommentsBehind, uiFlags));
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareArrays)
|
||||
{
|
||||
std::string ssStandardArray = R"toml(array1 = [123, 456])toml";
|
||||
std::string ssStandardArray2 = R"toml(array2 = [789, 543])toml";
|
||||
std::string ssArraySpace = R"toml( array1 = [
|
||||
123,
|
||||
456 ])toml";
|
||||
std::string ssArrayCommentsBefore = R"toml(# comment
|
||||
array1 =
|
||||
# more comment
|
||||
[ 123, # xyz
|
||||
456])toml";
|
||||
std::string ssArrayCommentsBehind = R"toml( array1 = [123, 456] # comment
|
||||
# more comment
|
||||
|
||||
# lots more comment)toml";
|
||||
|
||||
// Identical
|
||||
uint32_t uiFlags = 0u;
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssStandardArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssStandardArray2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssArraySpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssArrayCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore whitespace
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_whitespace);
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssStandardArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssStandardArray2, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArraySpace, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssArrayCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore comments
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_comments);
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssStandardArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssStandardArray2, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArraySpace, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArrayCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore all
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_all);
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssStandardArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardArray, ssStandardArray2, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArraySpace, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArrayCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardArray, ssArrayCommentsBehind, uiFlags));
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareTableArrays)
|
||||
{
|
||||
std::string ssStandardTableArray = R"toml([[tableArray1]]
|
||||
val = 1)toml";
|
||||
std::string ssStandardTableArray2 = R"toml([[tableArray2]]
|
||||
val = 1)toml";
|
||||
std::string ssStandardTableArray1_3 = R"toml([[tableArray1]]
|
||||
val = 3)toml";
|
||||
std::string ssInlineTableArray = R"toml(tableArray1 = [{val = 1}])toml";
|
||||
std::string ssTableSpaceArray = R"toml( [[tableArray1]]
|
||||
|
||||
val = 1)toml";
|
||||
std::string ssTableArrayCommentsBefore = R"toml(# comment
|
||||
|
||||
# more comment
|
||||
[[tableArray1]]
|
||||
val = 1)toml";
|
||||
std::string ssTableArrayCommentsBehind = R"toml( [[tableArray1]] # comment
|
||||
val = 1 # comment
|
||||
# more comment
|
||||
|
||||
# lots more comment)toml";
|
||||
|
||||
// Identical
|
||||
uint32_t uiFlags = 0u;
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssStandardTableArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray1_3, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssInlineTableArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableSpaceArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore whitespace
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_whitespace);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssStandardTableArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray1_3, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssInlineTableArray, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableSpaceArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore comments
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_comments);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssStandardTableArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray1_3, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssInlineTableArray, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableSpaceArray, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore inline
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_inline);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssStandardTableArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray1_3, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssInlineTableArray, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableSpaceArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBefore, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBehind, uiFlags));
|
||||
|
||||
// Ignore all
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_all);
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssStandardTableArray, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray2, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssStandardTableArray, ssStandardTableArray1_3, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssInlineTableArray, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableSpaceArray, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBefore, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssStandardTableArray, ssTableArrayCommentsBehind, uiFlags));
|
||||
}
|
||||
|
||||
TEST(Comparison, CompareComplex)
|
||||
{
|
||||
std::string ssToml1 = R"toml(# This is a complex TOML file
|
||||
|
||||
# Top value description
|
||||
[Top]
|
||||
value1 = 1 # Value 1
|
||||
valueA = "A" # Value A
|
||||
arrayBCD = [ "B", # Array element B
|
||||
"C", # Array element C
|
||||
"D" ] # Array element D
|
||||
|
||||
# Table 1
|
||||
[Top.table1]
|
||||
value2 = 2 # Value 2
|
||||
|
||||
# Table array in table 1
|
||||
[[Top.table1.table_array]] # Table array
|
||||
valueE = "E"
|
||||
|
||||
[[Top.table1.table_array]] # Table array
|
||||
valueF = "F"
|
||||
|
||||
[Top.table1.other_table]
|
||||
inline_table = { x = "X", y = "Y", z = "Z" } # Inline table
|
||||
|
||||
[[Top.table1.table_array]] # Table array
|
||||
valueG = "G"
|
||||
)toml";
|
||||
|
||||
std::string ssToml2 = R"toml(
|
||||
[Top]
|
||||
value1 = 1
|
||||
valueA = "A"
|
||||
arrayBCD = ["B", "C", "D" ]
|
||||
table1 = { value2 = 2, table_array = [{valueE = "E"}, {valueF = "F"}, {valueG = "G"}], other_table = { inline_table = {x = "X", y = "Y", z = "Z"}}} # Mega table
|
||||
)toml";
|
||||
|
||||
// Identical
|
||||
uint32_t uiFlags = 0u;
|
||||
EXPECT_TRUE(CompareTest(ssToml1, ssToml1, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssToml1, ssToml2, uiFlags));
|
||||
|
||||
// Ignore whitespace
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_whitespace);
|
||||
EXPECT_TRUE(CompareTest(ssToml1, ssToml1, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssToml1, ssToml2, uiFlags));
|
||||
|
||||
// Ignore comments
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_comments);
|
||||
EXPECT_TRUE(CompareTest(ssToml1, ssToml1, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssToml1, ssToml2, uiFlags));
|
||||
|
||||
// Ignore inline
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_inline);
|
||||
EXPECT_TRUE(CompareTest(ssToml1, ssToml1, uiFlags));
|
||||
EXPECT_FALSE(CompareTest(ssToml1, ssToml2, uiFlags));
|
||||
|
||||
// Ignore all
|
||||
uiFlags = static_cast<uint32_t>(sdv::toml::ECompareFlags::compare_ignore_all);
|
||||
EXPECT_TRUE(CompareTest(ssToml1, ssToml1, uiFlags));
|
||||
EXPECT_TRUE(CompareTest(ssToml1, ssToml2, uiFlags));
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
|
||||
@@ -45,321 +45,315 @@
|
||||
* @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)
|
||||
std::string DeleteNode(const std::string& rssTOMLInput, const std::string& rssKey)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
bool bRes = true;
|
||||
EXPECT_NO_THROW(bRes = parser.Process(rssTOMLInput));
|
||||
EXPECT_TRUE(bRes);
|
||||
if (!bRes) return bRes;
|
||||
if (!bRes) return {};
|
||||
auto ptrNode = parser.Root().Direct(rssKey);
|
||||
EXPECT_TRUE(ptrNode);
|
||||
if (!ptrNode) return false;
|
||||
if (!ptrNode) return {};
|
||||
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;
|
||||
if (!bRes) return {};
|
||||
return parser.GenerateTOML();
|
||||
};
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteValues)
|
||||
TEST(DeleteNode, DeleteValues)
|
||||
{
|
||||
// Delete a key from the begin (whitespace reduced)
|
||||
EXPECT_TRUE(TestDelete(R"toml(key = 10 # value key
|
||||
EXPECT_EQ(DeleteNode(R"toml(key = 10 # value key
|
||||
bare_key = "value" # value bare_key
|
||||
bare-key = false # value bare-key)toml",
|
||||
"key",
|
||||
"key"),
|
||||
R"toml(bare_key = "value" # value bare_key
|
||||
bare-key = false # value bare-key)toml"));
|
||||
bare-key = false # value bare-key)toml");
|
||||
|
||||
// Delete a key from the begin
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(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
|
||||
"key"),
|
||||
R"toml(bare_key = "value" # value bare_key
|
||||
bare-key = false # value bare-key
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
// Delete a key from the middle
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = 10 # value key
|
||||
bare_key = "value" # value bare_key
|
||||
bare-key = false # value bare-key
|
||||
)toml",
|
||||
"bare_key",
|
||||
"bare_key"),
|
||||
R"toml(
|
||||
key = 10 # value key
|
||||
bare-key = false # value bare-key
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
// Delete a key from the end
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = 10 # value key
|
||||
bare_key = "value" # value bare_key
|
||||
bare-key = false # value bare-key
|
||||
)toml",
|
||||
"bare-key",
|
||||
"bare-key"),
|
||||
R"toml(
|
||||
key = 10 # value key
|
||||
bare_key = "value" # value bare_key
|
||||
)toml"));
|
||||
)toml");
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteInlineTableValues)
|
||||
TEST(DeleteNode, DeleteInlineTableValues)
|
||||
{
|
||||
// Delete key from the inline table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
1234 = {x = 0, y = 1, z = 2, str = "abc"}
|
||||
)toml",
|
||||
"1234.y",
|
||||
"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(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
1234 = {x = 0, y = 1, z = 2, str = "abc"}
|
||||
)toml",
|
||||
"1234.x",
|
||||
"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(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
1234 = {x = 0, y = 1, z = 2, str = "abc"}
|
||||
)toml",
|
||||
"1234.str",
|
||||
"1234.str"),
|
||||
R"toml(
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
1234 = {x = 0, y = 1, z = 2}
|
||||
)toml"));
|
||||
|
||||
)toml");
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteInlineSubTableValues)
|
||||
TEST(DeleteNode, DeleteInlineSubTableValues)
|
||||
{
|
||||
// Delete key from the inline sub-table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"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"));
|
||||
|
||||
)toml");
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteInlineTables)
|
||||
TEST(DeleteNode, DeleteInlineTables)
|
||||
{
|
||||
// Delete table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"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(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"1234"),
|
||||
R"toml(
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml"));
|
||||
)toml");
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteTableValues)
|
||||
TEST(DeleteNode, DeleteTableValues)
|
||||
{
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml",
|
||||
"my_table.key",
|
||||
"my_table.key"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
// Delete a key from the middle
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml",
|
||||
"my_table.bare_key",
|
||||
"my_table.bare_key"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare-key = false
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
// Delete a key from the end
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml",
|
||||
"my_table.bare-key",
|
||||
"my_table.bare-key"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteInlineTableValueInTable)
|
||||
TEST(DeleteNode, DeleteInlineTableValueInTable)
|
||||
{
|
||||
// Delete key from the inline table in a table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"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(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"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(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"my_table.1234.str"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
1234 = {x = 0, y = 1, z = 2}
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteInlineSubTableValueInTable)
|
||||
TEST(DeleteNode, DeleteInlineSubTableValueInTable)
|
||||
{
|
||||
// Delete key from the inline sub-table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"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"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteInlineTableInTable)
|
||||
TEST(DeleteNode, DeleteInlineTableInTable)
|
||||
{
|
||||
// Delete table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"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(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(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",
|
||||
"my_table.1234"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteValuesInChildTable)
|
||||
TEST(DeleteNode, DeleteValuesInChildTable)
|
||||
{
|
||||
// Delete key from the child-table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
@@ -370,7 +364,7 @@ y = 1
|
||||
z = 2
|
||||
str = "abc"
|
||||
)toml",
|
||||
"my_table.1234.y",
|
||||
"my_table.1234.y"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
@@ -380,8 +374,8 @@ bare-key = false
|
||||
x = 0
|
||||
z = 2
|
||||
str = "abc"
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
@@ -392,7 +386,7 @@ y = 1
|
||||
z = 2
|
||||
str = "abc"
|
||||
)toml",
|
||||
"my_table.1234.x",
|
||||
"my_table.1234.x"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
@@ -402,8 +396,8 @@ bare-key = false
|
||||
y = 1
|
||||
z = 2
|
||||
str = "abc"
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
@@ -414,7 +408,7 @@ y = 1
|
||||
z = 2
|
||||
str = "abc"
|
||||
)toml",
|
||||
"my_table.1234.str",
|
||||
"my_table.1234.str"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
@@ -424,14 +418,14 @@ bare-key = false
|
||||
x = 0
|
||||
y = 1
|
||||
z = 2
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteChildTableInTable)
|
||||
TEST(DeleteNode, DeleteChildTableInTable)
|
||||
{
|
||||
// Delete table
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
@@ -446,7 +440,7 @@ a =1
|
||||
b=2
|
||||
c=3
|
||||
)toml",
|
||||
"my_table.1234.tbl",
|
||||
"my_table.1234.tbl"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
@@ -457,8 +451,8 @@ x = 0
|
||||
y = 1
|
||||
z = 2
|
||||
str = "abc"
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
@@ -473,176 +467,176 @@ a =1
|
||||
b=2
|
||||
c=3
|
||||
)toml",
|
||||
"my_table.1234",
|
||||
"my_table.1234"),
|
||||
R"toml(
|
||||
[my_table]
|
||||
key = 10
|
||||
bare_key = "value"
|
||||
bare-key = false
|
||||
)toml"));
|
||||
)toml");
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteArrayValues)
|
||||
TEST(DeleteNode, DeleteArrayValues)
|
||||
{
|
||||
// Delete array values
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"key[0]",
|
||||
"key[0]"),
|
||||
R"toml(
|
||||
key = [ 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"key[1]",
|
||||
"key[1]"),
|
||||
R"toml(
|
||||
key = [10, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"key[2]",
|
||||
"key[2]"),
|
||||
R"toml(
|
||||
key = [10, 20]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteArrayValuesWithSucceedingComma)
|
||||
TEST(DeleteNode, DeleteArrayValuesWithSucceedingComma)
|
||||
{
|
||||
// Delete array values with succeeding comma
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare_key[0]",
|
||||
"bare_key[0]"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = [ "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare_key[1]",
|
||||
"bare_key[1]"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare_key[2]",
|
||||
"bare_key[2]"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
)toml");
|
||||
|
||||
}
|
||||
|
||||
TEST(TOMLDeleteNode, DeleteValuesWithComments)
|
||||
TEST(DeleteNode, DeleteValuesWithComments)
|
||||
{
|
||||
// Delete array values with comments
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare-key[0]",
|
||||
"bare-key[0]"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [ 2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare-key[0].a",
|
||||
"bare-key[0].a"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{ b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare-key[0].b",
|
||||
"bare-key[0].b"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml"));
|
||||
EXPECT_TRUE(TestDelete(R"toml(
|
||||
)toml");
|
||||
EXPECT_EQ(DeleteNode(R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
2020, # value 1
|
||||
]
|
||||
)toml",
|
||||
"bare-key[1]",
|
||||
"bare-key[1]"),
|
||||
R"toml(
|
||||
key = [10, 20, 30]
|
||||
bare_key = ["value1", "value2", 3030, ]
|
||||
bare-key = [{a = false, b = true}, # value 0
|
||||
]
|
||||
)toml"));
|
||||
)toml");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
|
||||
// Test TODO:
|
||||
// Switch to inline and vice versa
|
||||
|
||||
TEST(GenerateTOML, SwitchTableToInline)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code([table]
|
||||
key1 = "some string"
|
||||
key2 = 123)code";
|
||||
std::string ssTOMLOutput = R"code(table = {key1 = "some string", key2 = 123})code";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
std::string ssGenerated;
|
||||
EXPECT_NO_THROW(ssGenerated = parser.GenerateTOML());
|
||||
EXPECT_EQ(ssGenerated, ssTOMLInput);
|
||||
|
||||
sdv::TInterfaceAccessPtr ptrTable = parser.Root().GetNodeDirect("table");
|
||||
EXPECT_TRUE(ptrTable);
|
||||
sdv::toml::INodeInfo* pInfo = ptrTable.GetInterface<sdv::toml::INodeInfo>();
|
||||
sdv::toml::INodeCollectionConvert* pConvert = ptrTable.GetInterface<sdv::toml::INodeCollectionConvert>();
|
||||
ASSERT_NE(pInfo, nullptr);
|
||||
ASSERT_NE(pConvert, nullptr);
|
||||
EXPECT_FALSE(pInfo->IsInline());
|
||||
EXPECT_TRUE(pConvert->CanMakeInline());
|
||||
EXPECT_TRUE(pConvert->MakeInline());
|
||||
EXPECT_TRUE(pInfo->IsInline());
|
||||
|
||||
EXPECT_NO_THROW(ssGenerated = parser.GenerateTOML());
|
||||
EXPECT_EQ(ssGenerated, ssTOMLOutput);
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
|
||||
@@ -19,7 +20,7 @@ TEST(GenerateTOML, Comment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# This is a full-line comment)code";
|
||||
std::string ssTOML = R"toml(# This is a full-line comment)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -33,9 +34,9 @@ TEST(GenerateTOML, NodeComment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# This is a full-line comment
|
||||
std::string ssTOML = R"toml(# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment")code";
|
||||
another = "# This is not a comment")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -49,10 +50,10 @@ TEST(GenerateTOML, NodeCommentWithSpaces)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -66,13 +67,13 @@ TEST(GenerateTOML, UnattachedComment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# Comment not belonging to node
|
||||
std::string ssTOML = R"toml(# Comment not belonging to node
|
||||
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment"
|
||||
|
||||
# Comment not belonging to node)code";
|
||||
# Comment not belonging to node)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -86,10 +87,10 @@ TEST(GenerateTOML, ArrayWhitespace)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
array = [ 1, 2, 3,
|
||||
4, 5, 6 ]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -103,7 +104,7 @@ TEST(GenerateTOML, ArrayComment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
# Pre-array
|
||||
array = [ 1, # Value #1
|
||||
2, # Value #2
|
||||
@@ -112,7 +113,7 @@ array = [ 1, # Value #1
|
||||
5, # Value #5
|
||||
6, # Value #6
|
||||
] # Post-array
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -126,7 +127,7 @@ TEST(GenerateTOML, ArrayCommentWithSpace)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
|
||||
# unattached comment
|
||||
|
||||
@@ -159,7 +160,7 @@ array = [ 1, # Value #1
|
||||
|
||||
# unattached comment
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -174,9 +175,9 @@ TEST(GenerateTOML, InlineTableWhitespace)
|
||||
toml_parser::CParser parser;
|
||||
|
||||
// Note: line-breaks within an inline table are not allowed.
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
table = { a = 1, b = 2, d = 3, e = 4, f = 5, g = 6 }
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -191,10 +192,10 @@ TEST(GenerateTOML, InlineTableComment)
|
||||
toml_parser::CParser parser;
|
||||
|
||||
// Note: line-breaks within an inline table are not allowed.
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
# Pre-table
|
||||
table = { a = 1, b = 2, d = 3, e = 4, f = 5, g = 6 } # Post-table
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -208,10 +209,10 @@ TEST(GenerateTOML, Keys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(key = "value"
|
||||
std::string ssTOML = R"toml(key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value")code";
|
||||
1234 = "value")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -225,11 +226,11 @@ TEST(GenerateTOML, QuotedKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = u8R"code("127.0.0.1" = "value"
|
||||
std::string ssTOML = u8R"toml("127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value")code";
|
||||
'quoted "value"' = "value")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -241,8 +242,8 @@ TEST(GenerateTOML, QuotedKeys)
|
||||
|
||||
TEST(GenerateTOML, BlankKeys)
|
||||
{
|
||||
std::string ssTOML1 = R"code("" = "blank" # VALID but discouraged)code";
|
||||
std::string ssTOML2 = R"code('' = 'blank' # VALID but discouraged)code";
|
||||
std::string ssTOML1 = R"toml("" = "blank" # VALID but discouraged)toml";
|
||||
std::string ssTOML2 = R"toml('' = 'blank' # VALID but discouraged)toml";
|
||||
|
||||
toml_parser::CParser parser1, parser2;
|
||||
EXPECT_NO_THROW(parser1.Process(ssTOML1));
|
||||
@@ -259,10 +260,10 @@ TEST(GenerateTOML, DottedKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(name = "Orange"
|
||||
std::string ssTOML = R"toml(name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true)code";
|
||||
site."google.com" = true)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -276,9 +277,9 @@ TEST(GenerateTOML, WhitespaceKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(fruit.name = "banana" # this is best practice
|
||||
std::string ssTOML = R"toml(fruit.name = "banana" # this is best practice
|
||||
fruit. color = "yellow" # same as fruit.color
|
||||
fruit . flavor = "banana" # same as fruit.flavor)code";
|
||||
fruit . flavor = "banana" # same as fruit.flavor)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -292,14 +293,14 @@ TEST(GenerateTOML, OutOfOrderKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(apple.type = "fruit"
|
||||
std::string ssTOML = R"toml(apple.type = "fruit"
|
||||
orange.type = "fruit"
|
||||
|
||||
apple.skin = "thin"
|
||||
orange.skin = "thick"
|
||||
|
||||
apple.color = "red"
|
||||
orange.color = "orange")code";
|
||||
orange.color = "orange")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -313,7 +314,7 @@ TEST(GenerateTOML, FloatLookingAlikeKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(3.14159 = "pi")code";
|
||||
std::string ssTOML = R"toml(3.14159 = "pi")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -327,7 +328,7 @@ TEST(GenerateTOML, BasicStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")code";
|
||||
std::string ssTOML = R"toml(str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -341,9 +342,9 @@ TEST(GenerateTOML, MultiLineStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(str1 = """
|
||||
std::string ssTOML = R"toml(str1 = """
|
||||
Roses are red
|
||||
Violets are blue""")code";
|
||||
Violets are blue""")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -357,7 +358,7 @@ TEST(GenerateTOML, LongMultiLineStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(str1 = "The quick brown fox jumps over the lazy dog."
|
||||
std::string ssTOML = R"toml(str1 = "The quick brown fox jumps over the lazy dog."
|
||||
|
||||
str2 = """
|
||||
The quick brown \
|
||||
@@ -370,7 +371,7 @@ str3 = """\
|
||||
The quick brown \
|
||||
fox jumps over \
|
||||
the lazy dog.\
|
||||
""")code";
|
||||
""")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -384,13 +385,13 @@ TEST(GenerateTOML, QuotingStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(str4 = """Here are two quotation marks: "". Simple enough."""
|
||||
std::string ssTOML = R"toml(str4 = """Here are two quotation marks: "". Simple enough."""
|
||||
# str5 = """Here are three quotation marks: """.""" # INVALID
|
||||
str5 = """Here are three quotation marks: ""\"."""
|
||||
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
|
||||
|
||||
# "This," she said, "is just a pointless statement."
|
||||
str7 = """"This," she said, "is just a pointless statement."""")code";
|
||||
str7 = """"This," she said, "is just a pointless statement."""")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -404,10 +405,10 @@ TEST(GenerateTOML, LiteralStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(winpath = 'C:\Users\nodejs\templates'
|
||||
std::string ssTOML = R"toml(winpath = 'C:\Users\nodejs\templates'
|
||||
winpath2 = '\\ServerX\admin$\system32\'
|
||||
quoted = 'Tom "Dubs" Preston-Werner'
|
||||
regex = '<\i\c*\s*>')code";
|
||||
regex = '<\i\c*\s*>')toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -421,13 +422,13 @@ TEST(GenerateTOML, MultiLineLiteralStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(regex2 = '''I [dw]on't need \d{2} apples'''
|
||||
std::string ssTOML = R"toml(regex2 = '''I [dw]on't need \d{2} apples'''
|
||||
lines = '''
|
||||
The first newline is
|
||||
trimmed in raw strings.
|
||||
All other whitespace
|
||||
is preserved.
|
||||
''')code";
|
||||
''')toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -441,13 +442,13 @@ TEST(GenerateTOML, QuotedLiteralStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
|
||||
std::string ssTOML = R"toml(quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
|
||||
|
||||
# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
|
||||
apos15 = "Here are fifteen apostrophes: '''''''''''''''"
|
||||
|
||||
# 'That,' she said, 'is still pointless.'
|
||||
str = ''''That,' she said, 'is still pointless.'''')code";
|
||||
str = ''''That,' she said, 'is still pointless.'''')toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -461,10 +462,10 @@ TEST(GenerateTOML, Integers)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(int1 = +99
|
||||
std::string ssTOML = R"toml(int1 = +99
|
||||
int2 = 42
|
||||
int3 = 0
|
||||
int4 = -17)code";
|
||||
int4 = -17)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -478,10 +479,10 @@ TEST(GenerateTOML, ReadibleIntegers)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(int5 = 1_000
|
||||
std::string ssTOML = R"toml(int5 = 1_000
|
||||
int6 = 5_349_221
|
||||
int7 = 53_49_221 # Indian number system grouping
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged)code";
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -495,7 +496,7 @@ TEST(GenerateTOML, OtherBaseIntegers)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# hexadecimal with prefix `0x`
|
||||
std::string ssTOML = R"toml(# hexadecimal with prefix `0x`
|
||||
hex1 = 0xDEADBEEF
|
||||
hex2 = 0xdeadbeef
|
||||
hex3 = 0xdead_beef
|
||||
@@ -505,7 +506,7 @@ oct1 = 0o01234567
|
||||
oct2 = 0o755 # useful for Unix file permissions
|
||||
|
||||
# binary with prefix `0b`
|
||||
bin1 = 0b11010110)code";
|
||||
bin1 = 0b11010110)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -519,7 +520,7 @@ TEST(GenerateTOML, FloatingPoints)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# fractional
|
||||
std::string ssTOML = R"toml(# fractional
|
||||
flt1 = +1.0
|
||||
flt2 = 3.1415
|
||||
flt3 = -0.01
|
||||
@@ -530,7 +531,7 @@ flt5 = 1e06
|
||||
flt6 = -2E-2
|
||||
|
||||
# both
|
||||
flt7 = 6.626e-34)code";
|
||||
flt7 = 6.626e-34)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -544,7 +545,7 @@ TEST(GenerateTOML, ReadibleFloatingPoints)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(flt8 = 224_617.445_991_228)code";
|
||||
std::string ssTOML = R"toml(flt8 = 224_617.445_991_228)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -558,7 +559,7 @@ TEST(GenerateTOML, SpecialFloatingPoints)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# infinity
|
||||
std::string ssTOML = R"toml(# infinity
|
||||
sf1 = inf # positive infinity
|
||||
sf2 = +inf # positive infinity
|
||||
sf3 = -inf # negative infinity
|
||||
@@ -566,7 +567,7 @@ sf3 = -inf # negative infinity
|
||||
# not a number
|
||||
sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
|
||||
sf5 = +nan # same as `nan`
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific)code";
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -580,8 +581,8 @@ TEST(GenerateTOML, Booleans)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(bool1 = true
|
||||
bool2 = false)code";
|
||||
std::string ssTOML = R"toml(bool1 = true
|
||||
bool2 = false)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -595,9 +596,9 @@ TEST(GenerateTOML, DISABLED_OffsetDateTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(odt1 = 1979-05-27T07:32:00Z
|
||||
std::string ssTOML = R"toml(odt1 = 1979-05-27T07:32:00Z
|
||||
odt2 = 1979-05-27T00:32:00-07:00
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00)code";
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -611,7 +612,7 @@ TEST(GenerateTOML, DISABLED_ReadibleOffsetDateTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(odt4 = 1979-05-27 07:32:00Z)code";
|
||||
std::string ssTOML = R"toml(odt4 = 1979-05-27 07:32:00Z)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -625,8 +626,8 @@ TEST(GenerateTOML, DISABLED_LocalDateTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(ldt1 = 1979-05-27T07:32:00
|
||||
ldt2 = 1979-05-27T00:32:00.999999)code";
|
||||
std::string ssTOML = R"toml(ldt1 = 1979-05-27T07:32:00
|
||||
ldt2 = 1979-05-27T00:32:00.999999)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -640,7 +641,7 @@ TEST(GenerateTOML, DISABLED_LocalDates)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(ld1 = 1979-05-27)code";
|
||||
std::string ssTOML = R"toml(ld1 = 1979-05-27)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -654,8 +655,8 @@ TEST(GenerateTOML, DISABLED_LocalTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999)code";
|
||||
std::string ssTOML = R"toml(lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -669,7 +670,7 @@ TEST(GenerateTOML, Arrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(integers = [ 1, 2, 3 ]
|
||||
std::string ssTOML = R"toml(integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
@@ -681,7 +682,7 @@ contributors =
|
||||
[
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
])code";
|
||||
])toml";
|
||||
|
||||
parser.Process(ssTOML);
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
@@ -696,14 +697,14 @@ TEST(GenerateTOML, MultiLineArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(integers2 = [
|
||||
std::string ssTOML = R"toml(integers2 = [
|
||||
1, 2, 3
|
||||
]
|
||||
|
||||
integers3 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
])code";
|
||||
])toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -717,7 +718,7 @@ TEST(GenerateTOML, Tables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code([table]
|
||||
std::string ssTOML = R"toml([table]
|
||||
|
||||
[table-1]
|
||||
key1 = "some string"
|
||||
@@ -725,7 +726,7 @@ key2 = 123
|
||||
|
||||
[table-2]
|
||||
key1 = "another string"
|
||||
key2 = 456)code";
|
||||
key2 = 456)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -739,8 +740,8 @@ TEST(GenerateTOML, QuotedKeyTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code([dog."tater.man"]
|
||||
type.name = "pug")code";
|
||||
std::string ssTOML = R"toml([dog."tater.man"]
|
||||
type.name = "pug")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -754,14 +755,14 @@ TEST(GenerateTOML, WhitespaceKeyTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = u8R"code([a.b.c] # this is best practice
|
||||
std::string ssTOML = u8R"toml([a.b.c] # this is best practice
|
||||
x = 1
|
||||
[ d.e.f ] # same as [d.e.f]
|
||||
y = 1
|
||||
[ g . h . i ] # same as [g.h.i]
|
||||
z = 1
|
||||
[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
|
||||
a = 1)code";
|
||||
a = 1)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -775,13 +776,13 @@ TEST(GenerateTOML, MixedOrderTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# VALID BUT DISCOURAGED
|
||||
std::string ssTOML = R"toml(# VALID BUT DISCOURAGED
|
||||
[fruit.apple]
|
||||
a = 1
|
||||
[animal]
|
||||
b = 2
|
||||
[fruit.orange]
|
||||
aa = 11)code";
|
||||
aa = 11)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -795,14 +796,14 @@ TEST(GenerateTOML, MixedValueAndTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# Top-level table begins.
|
||||
std::string ssTOML = R"toml(# Top-level table begins.
|
||||
name = "Fido"
|
||||
breed = "pug"
|
||||
|
||||
# Top-level table ends.
|
||||
[owner]
|
||||
name = "Regina Dogman"
|
||||
member_since = 1999)code";
|
||||
member_since = 1999)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -816,10 +817,10 @@ TEST(GenerateTOML, AutomaticTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(fruit.apple.color = "red"
|
||||
fruit.apple.taste.sweet = true)code";
|
||||
std::string ssTOMLOutput2 = R"code(apple.color = "red"
|
||||
apple.taste.sweet = true)code";
|
||||
std::string ssTOML = R"toml(fruit.apple.color = "red"
|
||||
fruit.apple.taste.sweet = true)toml";
|
||||
std::string ssTOMLOutput2 = R"toml(apple.color = "red"
|
||||
apple.taste.sweet = true)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -835,7 +836,7 @@ TEST(GenerateTOML, MixedAutomaticTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code([fruit]
|
||||
std::string ssTOML = R"toml([fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
|
||||
@@ -843,7 +844,7 @@ apple.taste.sweet = true
|
||||
# [fruit.apple.taste] # INVALID
|
||||
|
||||
[fruit.apple.texture] # you can add sub-tables
|
||||
smooth = true)code";
|
||||
smooth = true)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -857,9 +858,9 @@ TEST(GenerateTOML, InlineTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(name = { first = "Tom", last = "Preston-Werner" }
|
||||
std::string ssTOML = R"toml(name = { first = "Tom", last = "Preston-Werner" }
|
||||
point = { x = 1, y = 2 }
|
||||
animal = { type.name = "pug" })code";
|
||||
animal = { type.name = "pug" })toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -873,9 +874,9 @@ TEST(GenerateTOML, EmbeddedInlineTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(test=[{ first = "Tom", last = "Preston-Werner" },
|
||||
std::string ssTOML = R"toml(test=[{ first = "Tom", last = "Preston-Werner" },
|
||||
{ x = 1, y = 2 },
|
||||
{ type.name = "pug" }])code";
|
||||
{ type.name = "pug" }])toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -889,7 +890,7 @@ TEST(GenerateTOML, TableArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code([[products]]
|
||||
std::string ssTOML = R"toml([[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
@@ -899,7 +900,7 @@ sku = 738594937
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
|
||||
color = "gray")code";
|
||||
color = "gray")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -913,7 +914,7 @@ TEST(GenerateTOML, MixedTableAndTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code([[fruits]]
|
||||
std::string ssTOML = R"toml([[fruits]]
|
||||
name = "apple"
|
||||
|
||||
[fruits.physical] # subtable
|
||||
@@ -931,29 +932,29 @@ name = "granny smith"
|
||||
name = "banana"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "plantain")code";
|
||||
std::string ssTOMLFruits1Physical = R"code([physical] # subtable
|
||||
name = "plantain")toml";
|
||||
std::string ssTOMLFruits1Physical = R"toml([physical] # subtable
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
)code";
|
||||
std::string ssTOMLFruits1Varieties = R"code([[varieties]] # nested array of tables
|
||||
)toml";
|
||||
std::string ssTOMLFruits1Varieties = R"toml([[varieties]] # nested array of tables
|
||||
name = "red delicious"
|
||||
|
||||
[[varieties]]
|
||||
name = "granny smith"
|
||||
|
||||
)code";
|
||||
std::string ssTOMLFruits1Variety1 = R"code([variety] # nested array of tables
|
||||
)toml";
|
||||
std::string ssTOMLFruits1Variety1 = R"toml([variety] # nested array of tables
|
||||
name = "red delicious"
|
||||
|
||||
)code";
|
||||
std::string ssTOMLFruits1Variety2 = R"code([variety]
|
||||
)toml";
|
||||
std::string ssTOMLFruits1Variety2 = R"toml([variety]
|
||||
name = "granny smith"
|
||||
|
||||
)code";
|
||||
std::string ssTOMLFruits2Variety1 = R"code([variety]
|
||||
name = "plantain")code";
|
||||
)toml";
|
||||
std::string ssTOMLFruits2Variety1 = R"toml([variety]
|
||||
name = "plantain")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -998,9 +999,9 @@ TEST(GenerateTOML, InlineTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(points = [ { x = 1, y = 2, z = 3 },
|
||||
std::string ssTOML = R"toml(points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ])code";
|
||||
{ x = 2, y = 4, z = 8 } ])toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
|
||||
@@ -19,13 +20,13 @@ TEST(GenerateTOML, TransferNodeComment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a full-line comment
|
||||
std::string ssTOMLInput = R"toml(# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
another = "# This is not a comment")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment")code";
|
||||
another = "# This is not a comment")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -39,15 +40,15 @@ TEST(GenerateTOML, TransferNodeCommentWithSpaces)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(
|
||||
std::string ssTOMLInput = R"toml(
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -61,21 +62,21 @@ TEST(GenerateTOML, TransferUnattachedComment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# Comment not belonging to node
|
||||
std::string ssTOMLInput = R"toml(# Comment not belonging to node
|
||||
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment"
|
||||
|
||||
# Comment not belonging to node)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
# Comment not belonging to node)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
# Comment not belonging to node
|
||||
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment"
|
||||
|
||||
# Comment not belonging to node)code";
|
||||
# Comment not belonging to node)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -89,15 +90,15 @@ TEST(GenerateTOML, TransferArrayWhitespace)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(
|
||||
std::string ssTOMLInput = R"toml(
|
||||
array = [ 1, 2, 3,
|
||||
4, 5, 6 ]
|
||||
)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
|
||||
array = [ 1, 2, 3,
|
||||
4, 5, 6 ]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -111,7 +112,7 @@ TEST(GenerateTOML, TransferArrayComment)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(
|
||||
std::string ssTOMLInput = R"toml(
|
||||
# Pre-array
|
||||
array = [ 1, # Value #1
|
||||
2, # Value #2
|
||||
@@ -120,8 +121,8 @@ array = [ 1, # Value #1
|
||||
5, # Value #5
|
||||
6, # Value #6
|
||||
] # Post-array
|
||||
)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
|
||||
# Pre-array
|
||||
array = [ 1, # Value #1
|
||||
@@ -131,7 +132,7 @@ array = [ 1, # Value #1
|
||||
5, # Value #5
|
||||
6, # Value #6
|
||||
] # Post-array
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -145,7 +146,7 @@ TEST(GenerateTOML, TransferArrayCommentWithSpace)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(
|
||||
std::string ssTOMLInput = R"toml(
|
||||
|
||||
# unattached comment
|
||||
|
||||
@@ -178,8 +179,8 @@ array = [ 1, # Value #1
|
||||
|
||||
# unattached comment
|
||||
|
||||
)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
|
||||
|
||||
# unattached comment
|
||||
@@ -213,7 +214,7 @@ array = [ 1, # Value #1
|
||||
|
||||
# unattached comment
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -228,13 +229,13 @@ TEST(GenerateTOML, TransferInlineTableWhitespace)
|
||||
toml_parser::CParser parser;
|
||||
|
||||
// NOTE: Line-breaks within inline tables are not allowed.
|
||||
std::string ssTOMLInput = R"code(
|
||||
std::string ssTOMLInput = R"toml(
|
||||
table = { a = 1, b = 2, d = 3, e = 4, f = 5, g = 6 }
|
||||
)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
|
||||
table = { a = 1, b = 2, d = 3, e = 4, f = 5, g = 6 }
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -249,15 +250,15 @@ TEST(GenerateTOML, TransferInlineTableComment)
|
||||
toml_parser::CParser parser;
|
||||
|
||||
// NOTE: Line-breaks within inline tables are not allowed.
|
||||
std::string ssTOMLInput = R"code(
|
||||
std::string ssTOMLInput = R"toml(
|
||||
# Pre-table
|
||||
table = { a = 1, b = 2, d = 3, e = 4, f = 5, g = 6 } # Post-table
|
||||
)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
|
||||
# Pre-table
|
||||
table = { a = 1, b = 2, d = 3, e = 4, f = 5, g = 6 } # Post-table
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -271,15 +272,15 @@ TEST(GenerateTOML, TransferKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(key = "value"
|
||||
std::string ssTOMLInput = R"toml(key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
1234 = "value")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value")code";
|
||||
1234 = "value")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -293,17 +294,17 @@ TEST(GenerateTOML, TransferQuotedKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = u8R"code("127.0.0.1" = "value"
|
||||
std::string ssTOMLInput = u8R"toml("127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value")code";
|
||||
std::string ssTOMLOutput = u8R"code([tree.branch]
|
||||
'quoted "value"' = "value")toml";
|
||||
std::string ssTOMLOutput = u8R"toml([tree.branch]
|
||||
"127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value")code";
|
||||
'quoted "value"' = "value")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -315,12 +316,12 @@ TEST(GenerateTOML, TransferQuotedKeys)
|
||||
|
||||
TEST(GenerateTOML, TransferBlankKeys)
|
||||
{
|
||||
std::string ssTOMLInput1 = R"code("" = "blank" # VALID but discouraged)code";
|
||||
std::string ssTOMLInput2 = R"code('' = 'blank' # VALID but discouraged)code";
|
||||
std::string ssTOMLOutput1 = R"code([tree.branch]
|
||||
"" = "blank" # VALID but discouraged)code";
|
||||
std::string ssTOMLOutput2 = R"code([tree.branch]
|
||||
'' = 'blank' # VALID but discouraged)code";
|
||||
std::string ssTOMLInput1 = R"toml("" = "blank" # VALID but discouraged)toml";
|
||||
std::string ssTOMLInput2 = R"toml('' = 'blank' # VALID but discouraged)toml";
|
||||
std::string ssTOMLOutput1 = R"toml([tree.branch]
|
||||
"" = "blank" # VALID but discouraged)toml";
|
||||
std::string ssTOMLOutput2 = R"toml([tree.branch]
|
||||
'' = 'blank' # VALID but discouraged)toml";
|
||||
|
||||
toml_parser::CParser parser1, parser2;
|
||||
EXPECT_NO_THROW(parser1.Process(ssTOMLInput1));
|
||||
@@ -338,15 +339,15 @@ TEST(GenerateTOML, TransferDottedKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(name = "Orange"
|
||||
std::string ssTOMLInput = R"toml(name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
site."google.com" = true)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true)code";
|
||||
site."google.com" = true)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -360,13 +361,13 @@ TEST(GenerateTOML, TransferWhitespaceKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(fruit.name = "banana" # this is best practice
|
||||
std::string ssTOMLInput = R"toml(fruit.name = "banana" # this is best practice
|
||||
fruit. color = "yellow" # same as fruit.color
|
||||
fruit . flavor = "banana" # same as fruit.flavor)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
fruit . flavor = "banana" # same as fruit.flavor)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
fruit.name = "banana" # this is best practice
|
||||
fruit. color = "yellow" # same as fruit.color
|
||||
fruit . flavor = "banana" # same as fruit.flavor)code";
|
||||
fruit . flavor = "banana" # same as fruit.flavor)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -380,15 +381,15 @@ TEST(GenerateTOML, TransferOutOfOrderKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(apple.type = "fruit"
|
||||
std::string ssTOMLInput = R"toml(apple.type = "fruit"
|
||||
orange.type = "fruit"
|
||||
|
||||
apple.skin = "thin"
|
||||
orange.skin = "thick"
|
||||
|
||||
apple.color = "red"
|
||||
orange.color = "orange")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
orange.color = "orange")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
apple.type = "fruit"
|
||||
orange.type = "fruit"
|
||||
|
||||
@@ -396,7 +397,7 @@ apple.skin = "thin"
|
||||
orange.skin = "thick"
|
||||
|
||||
apple.color = "red"
|
||||
orange.color = "orange")code";
|
||||
orange.color = "orange")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -410,9 +411,9 @@ TEST(GenerateTOML, TransferFloatLookingAlikeKeys)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(3.14159 = "pi")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
3.14159 = "pi")code";
|
||||
std::string ssTOMLInput = R"toml(3.14159 = "pi")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
3.14159 = "pi")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -426,9 +427,9 @@ TEST(GenerateTOML, TransferBasicStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")code";
|
||||
std::string ssTOMLInput = R"toml(str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -442,13 +443,13 @@ TEST(GenerateTOML, TransferMultiLineStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(str1 = """
|
||||
std::string ssTOMLInput = R"toml(str1 = """
|
||||
Roses are red
|
||||
Violets are blue""")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
Violets are blue""")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
str1 = """
|
||||
Roses are red
|
||||
Violets are blue""")code";
|
||||
Violets are blue""")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -462,7 +463,7 @@ TEST(GenerateTOML, TransferLongMultiLineStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(str1 = "The quick brown fox jumps over the lazy dog."
|
||||
std::string ssTOMLInput = R"toml(str1 = "The quick brown fox jumps over the lazy dog."
|
||||
|
||||
str2 = """
|
||||
The quick brown \
|
||||
@@ -475,8 +476,8 @@ str3 = """\
|
||||
The quick brown \
|
||||
fox jumps over \
|
||||
the lazy dog.\
|
||||
""")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
""")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
str1 = "The quick brown fox jumps over the lazy dog."
|
||||
|
||||
str2 = """
|
||||
@@ -490,7 +491,7 @@ str3 = """\
|
||||
The quick brown \
|
||||
fox jumps over \
|
||||
the lazy dog.\
|
||||
""")code";
|
||||
""")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -504,21 +505,21 @@ TEST(GenerateTOML, TransferQuotingStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(str4 = """Here are two quotation marks: "". Simple enough."""
|
||||
std::string ssTOMLInput = R"toml(str4 = """Here are two quotation marks: "". Simple enough."""
|
||||
# str5 = """Here are three quotation marks: """.""" # INVALID
|
||||
str5 = """Here are three quotation marks: ""\"."""
|
||||
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
|
||||
|
||||
# "This," she said, "is just a pointless statement."
|
||||
str7 = """"This," she said, "is just a pointless statement."""")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
str7 = """"This," she said, "is just a pointless statement."""")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
str4 = """Here are two quotation marks: "". Simple enough."""
|
||||
# str5 = """Here are three quotation marks: """.""" # INVALID
|
||||
str5 = """Here are three quotation marks: ""\"."""
|
||||
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
|
||||
|
||||
# "This," she said, "is just a pointless statement."
|
||||
str7 = """"This," she said, "is just a pointless statement."""")code";
|
||||
str7 = """"This," she said, "is just a pointless statement."""")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -532,15 +533,15 @@ TEST(GenerateTOML, TransferLiteralStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(winpath = 'C:\Users\nodejs\templates'
|
||||
std::string ssTOMLInput = R"toml(winpath = 'C:\Users\nodejs\templates'
|
||||
winpath2 = '\\ServerX\admin$\system32\'
|
||||
quoted = 'Tom "Dubs" Preston-Werner'
|
||||
regex = '<\i\c*\s*>')code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
regex = '<\i\c*\s*>')toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
winpath = 'C:\Users\nodejs\templates'
|
||||
winpath2 = '\\ServerX\admin$\system32\'
|
||||
quoted = 'Tom "Dubs" Preston-Werner'
|
||||
regex = '<\i\c*\s*>')code";
|
||||
regex = '<\i\c*\s*>')toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -554,21 +555,21 @@ TEST(GenerateTOML, TransferMultiLineLiteralStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(regex2 = '''I [dw]on't need \d{2} apples'''
|
||||
std::string ssTOMLInput = R"toml(regex2 = '''I [dw]on't need \d{2} apples'''
|
||||
lines = '''
|
||||
The first newline is
|
||||
trimmed in raw strings.
|
||||
All other whitespace
|
||||
is preserved.
|
||||
''')code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
''')toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
regex2 = '''I [dw]on't need \d{2} apples'''
|
||||
lines = '''
|
||||
The first newline is
|
||||
trimmed in raw strings.
|
||||
All other whitespace
|
||||
is preserved.
|
||||
''')code";
|
||||
''')toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -582,21 +583,21 @@ TEST(GenerateTOML, TransferQuotedLiteralStrings)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
|
||||
std::string ssTOMLInput = R"toml(quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
|
||||
|
||||
# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
|
||||
apos15 = "Here are fifteen apostrophes: '''''''''''''''"
|
||||
|
||||
# 'That,' she said, 'is still pointless.'
|
||||
str = ''''That,' she said, 'is still pointless.'''')code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
str = ''''That,' she said, 'is still pointless.'''')toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
|
||||
|
||||
# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
|
||||
apos15 = "Here are fifteen apostrophes: '''''''''''''''"
|
||||
|
||||
# 'That,' she said, 'is still pointless.'
|
||||
str = ''''That,' she said, 'is still pointless.'''')code";
|
||||
str = ''''That,' she said, 'is still pointless.'''')toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -610,15 +611,15 @@ TEST(GenerateTOML, TransferIntegers)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(int1 = +99
|
||||
std::string ssTOMLInput = R"toml(int1 = +99
|
||||
int2 = 42
|
||||
int3 = 0
|
||||
int4 = -17)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
int4 = -17)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
int1 = +99
|
||||
int2 = 42
|
||||
int3 = 0
|
||||
int4 = -17)code";
|
||||
int4 = -17)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -632,15 +633,15 @@ TEST(GenerateTOML, TransferReadibleIntegers)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(int5 = 1_000
|
||||
std::string ssTOMLInput = R"toml(int5 = 1_000
|
||||
int6 = 5_349_221
|
||||
int7 = 53_49_221 # Indian number system grouping
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
int5 = 1_000
|
||||
int6 = 5_349_221
|
||||
int7 = 53_49_221 # Indian number system grouping
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged)code";
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -654,7 +655,7 @@ TEST(GenerateTOML, TransferOtherBaseIntegers)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# hexadecimal with prefix `0x`
|
||||
std::string ssTOMLInput = R"toml(# hexadecimal with prefix `0x`
|
||||
hex1 = 0xDEADBEEF
|
||||
hex2 = 0xdeadbeef
|
||||
hex3 = 0xdead_beef
|
||||
@@ -664,8 +665,8 @@ oct1 = 0o01234567
|
||||
oct2 = 0o755 # useful for Unix file permissions
|
||||
|
||||
# binary with prefix `0b`
|
||||
bin1 = 0b11010110)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
bin1 = 0b11010110)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
# hexadecimal with prefix `0x`
|
||||
hex1 = 0xDEADBEEF
|
||||
hex2 = 0xdeadbeef
|
||||
@@ -676,7 +677,7 @@ oct1 = 0o01234567
|
||||
oct2 = 0o755 # useful for Unix file permissions
|
||||
|
||||
# binary with prefix `0b`
|
||||
bin1 = 0b11010110)code";
|
||||
bin1 = 0b11010110)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -690,7 +691,7 @@ TEST(GenerateTOML, TransferFloatingPoints)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# fractional
|
||||
std::string ssTOMLInput = R"toml(# fractional
|
||||
flt1 = +1.0
|
||||
flt2 = 3.1415
|
||||
flt3 = -0.01
|
||||
@@ -701,8 +702,8 @@ flt5 = 1e06
|
||||
flt6 = -2E-2
|
||||
|
||||
# both
|
||||
flt7 = 6.626e-34)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
flt7 = 6.626e-34)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
# fractional
|
||||
flt1 = +1.0
|
||||
flt2 = 3.1415
|
||||
@@ -714,7 +715,7 @@ flt5 = 1e06
|
||||
flt6 = -2E-2
|
||||
|
||||
# both
|
||||
flt7 = 6.626e-34)code";
|
||||
flt7 = 6.626e-34)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -728,9 +729,9 @@ TEST(GenerateTOML, TransferReadibleFloatingPoints)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(flt8 = 224_617.445_991_228)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
flt8 = 224_617.445_991_228)code";
|
||||
std::string ssTOMLInput = R"toml(flt8 = 224_617.445_991_228)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
flt8 = 224_617.445_991_228)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -744,7 +745,7 @@ TEST(GenerateTOML, TransferSpecialFloatingPoints)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# infinity
|
||||
std::string ssTOMLInput = R"toml(# infinity
|
||||
sf1 = inf # positive infinity
|
||||
sf2 = +inf # positive infinity
|
||||
sf3 = -inf # negative infinity
|
||||
@@ -752,8 +753,8 @@ sf3 = -inf # negative infinity
|
||||
# not a number
|
||||
sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
|
||||
sf5 = +nan # same as `nan`
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
# infinity
|
||||
sf1 = inf # positive infinity
|
||||
sf2 = +inf # positive infinity
|
||||
@@ -762,7 +763,7 @@ sf3 = -inf # negative infinity
|
||||
# not a number
|
||||
sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
|
||||
sf5 = +nan # same as `nan`
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific)code";
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -776,11 +777,11 @@ TEST(GenerateTOML, TransferBooleans)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(bool1 = true
|
||||
bool2 = false)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
std::string ssTOMLInput = R"toml(bool1 = true
|
||||
bool2 = false)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
bool1 = true
|
||||
bool2 = false)code";
|
||||
bool2 = false)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -794,13 +795,13 @@ TEST(GenerateTOML, DISABLED_TransferOffsetDateTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(odt1 = 1979-05-27T07:32:00Z
|
||||
std::string ssTOMLInput = R"toml(odt1 = 1979-05-27T07:32:00Z
|
||||
odt2 = 1979-05-27T00:32:00-07:00
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
odt1 = 1979-05-27T07:32:00Z
|
||||
odt2 = 1979-05-27T00:32:00-07:00
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00)code";
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -814,9 +815,9 @@ TEST(GenerateTOML, DISABLED_TransferReadibleOffsetDateTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(odt4 = 1979-05-27 07:32:00Z)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
odt4 = 1979-05-27 07:32:00Z)code";
|
||||
std::string ssTOMLInput = R"toml(odt4 = 1979-05-27 07:32:00Z)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
odt4 = 1979-05-27 07:32:00Z)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -830,11 +831,11 @@ TEST(GenerateTOML, DISABLED_TransferLocalDateTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(ldt1 = 1979-05-27T07:32:00
|
||||
ldt2 = 1979-05-27T00:32:00.999999)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
std::string ssTOMLInput = R"toml(ldt1 = 1979-05-27T07:32:00
|
||||
ldt2 = 1979-05-27T00:32:00.999999)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
ldt1 = 1979-05-27T07:32:00
|
||||
ldt2 = 1979-05-27T00:32:00.999999)code";
|
||||
ldt2 = 1979-05-27T00:32:00.999999)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -848,9 +849,9 @@ TEST(GenerateTOML, DISABLED_TransferLocalDates)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(ld1 = 1979-05-27)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
ld1 = 1979-05-27)code";
|
||||
std::string ssTOMLInput = R"toml(ld1 = 1979-05-27)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
ld1 = 1979-05-27)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -864,11 +865,11 @@ TEST(GenerateTOML, DISABLED_TransferLocalTimes)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
std::string ssTOMLInput = R"toml(lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999)code";
|
||||
lt2 = 00:32:00.999999)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -882,7 +883,7 @@ TEST(GenerateTOML, TransferArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(integers = [ 1, 2, 3 ]
|
||||
std::string ssTOMLInput = R"toml(integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
@@ -893,8 +894,8 @@ numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
])code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
])toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
@@ -906,7 +907,7 @@ numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
])code";
|
||||
])toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -920,15 +921,15 @@ TEST(GenerateTOML, TransferMultiLineArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(integers2 = [
|
||||
std::string ssTOMLInput = R"toml(integers2 = [
|
||||
1, 2, 3
|
||||
]
|
||||
|
||||
integers3 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
])code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
])toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
integers2 = [
|
||||
1, 2, 3
|
||||
]
|
||||
@@ -936,7 +937,7 @@ integers2 = [
|
||||
integers3 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
])code";
|
||||
])toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -950,7 +951,7 @@ TEST(GenerateTOML, TransferTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code([table]
|
||||
std::string ssTOMLInput = R"toml([table]
|
||||
|
||||
[table-1]
|
||||
key1 = "some string"
|
||||
@@ -958,8 +959,8 @@ key2 = 123
|
||||
|
||||
[table-2]
|
||||
key1 = "another string"
|
||||
key2 = 456)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch.table]
|
||||
key2 = 456)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch.table]
|
||||
|
||||
[tree.branch.table-1]
|
||||
key1 = "some string"
|
||||
@@ -967,7 +968,7 @@ key2 = 123
|
||||
|
||||
[tree.branch.table-2]
|
||||
key1 = "another string"
|
||||
key2 = 456)code";
|
||||
key2 = 456)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -981,10 +982,10 @@ TEST(GenerateTOML, TransferQuotedKeyTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code([dog."tater.man"]
|
||||
type.name = "pug")code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch.dog."tater.man"]
|
||||
type.name = "pug")code";
|
||||
std::string ssTOMLInput = R"toml([dog."tater.man"]
|
||||
type.name = "pug")toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch.dog."tater.man"]
|
||||
type.name = "pug")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -998,22 +999,22 @@ TEST(GenerateTOML, TransferWhitespaceKeyTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = u8R"code([a.b.c] # this is best practice
|
||||
std::string ssTOMLInput = u8R"toml([a.b.c] # this is best practice
|
||||
x = 1
|
||||
[ d.e.f ] # same as [d.e.f]
|
||||
y = 1
|
||||
[ g . h . i ] # same as [g.h.i]
|
||||
z = 1
|
||||
[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
|
||||
a = 1)code";
|
||||
std::string ssTOMLOutput = u8R"code([tree.branch.a.b.c] # this is best practice
|
||||
a = 1)toml";
|
||||
std::string ssTOMLOutput = u8R"toml([tree.branch.a.b.c] # this is best practice
|
||||
x = 1
|
||||
[tree.branch. d.e.f ] # same as [d.e.f]
|
||||
y = 1
|
||||
[tree.branch. g . h . i ] # same as [g.h.i]
|
||||
z = 1
|
||||
[tree.branch. j . "ʞ" . 'l' ] # same as [j."ʞ".'l']
|
||||
a = 1)code";
|
||||
a = 1)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1027,20 +1028,20 @@ TEST(GenerateTOML, TransferMixedOrderTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# VALID BUT DISCOURAGED
|
||||
std::string ssTOMLInput = R"toml(# VALID BUT DISCOURAGED
|
||||
[fruit.apple]
|
||||
a = 1
|
||||
[animal]
|
||||
b = 2
|
||||
[fruit.orange]
|
||||
aa = 11)code";
|
||||
std::string ssTOMLOutput = R"code(# VALID BUT DISCOURAGED
|
||||
aa = 11)toml";
|
||||
std::string ssTOMLOutput = R"toml(# VALID BUT DISCOURAGED
|
||||
[tree.branch.fruit.apple]
|
||||
a = 1
|
||||
[tree.branch.animal]
|
||||
b = 2
|
||||
[tree.branch.fruit.orange]
|
||||
aa = 11)code";
|
||||
aa = 11)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1054,15 +1055,15 @@ TEST(GenerateTOML, TransferMixedValueAndTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# Top-level table begins.
|
||||
std::string ssTOMLInput = R"toml(# Top-level table begins.
|
||||
name = "Fido"
|
||||
breed = "pug"
|
||||
|
||||
# Top-level table ends.
|
||||
[owner]
|
||||
name = "Regina Dogman"
|
||||
member_since = 1999)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
member_since = 1999)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
# Top-level table begins.
|
||||
name = "Fido"
|
||||
breed = "pug"
|
||||
@@ -1070,7 +1071,7 @@ breed = "pug"
|
||||
# Top-level table ends.
|
||||
[tree.branch.owner]
|
||||
name = "Regina Dogman"
|
||||
member_since = 1999)code";
|
||||
member_since = 1999)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1084,14 +1085,14 @@ TEST(GenerateTOML, TransferAutomaticTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(fruit.apple.color = "red"
|
||||
fruit.apple.taste.sweet = true)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
std::string ssTOMLInput = R"toml(fruit.apple.color = "red"
|
||||
fruit.apple.taste.sweet = true)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
fruit.apple.color = "red"
|
||||
fruit.apple.taste.sweet = true)code";
|
||||
std::string ssTOMLOutput2 = R"code([tree.branch]
|
||||
fruit.apple.taste.sweet = true)toml";
|
||||
std::string ssTOMLOutput2 = R"toml([tree.branch]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true)code";
|
||||
apple.taste.sweet = true)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1107,7 +1108,7 @@ TEST(GenerateTOML, TransferMixedAutomaticTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code([fruit]
|
||||
std::string ssTOMLInput = R"toml([fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
|
||||
@@ -1115,8 +1116,8 @@ apple.taste.sweet = true
|
||||
# [fruit.apple.taste] # INVALID
|
||||
|
||||
[fruit.apple.texture] # you can add sub-tables
|
||||
smooth = true)code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch.fruit]
|
||||
smooth = true)toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch.fruit]
|
||||
apple.color = "red"
|
||||
apple.taste.sweet = true
|
||||
|
||||
@@ -1124,7 +1125,7 @@ apple.taste.sweet = true
|
||||
# [fruit.apple.taste] # INVALID
|
||||
|
||||
[tree.branch.fruit.apple.texture] # you can add sub-tables
|
||||
smooth = true)code";
|
||||
smooth = true)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1138,13 +1139,13 @@ TEST(GenerateTOML, TransferInlineTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(name = { first = "Tom", last = "Preston-Werner" }
|
||||
std::string ssTOMLInput = R"toml(name = { first = "Tom", last = "Preston-Werner" }
|
||||
point = { x = 1, y = 2 }
|
||||
animal = { type.name = "pug" })code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
animal = { type.name = "pug" })toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
name = { first = "Tom", last = "Preston-Werner" }
|
||||
point = { x = 1, y = 2 }
|
||||
animal = { type.name = "pug" })code";
|
||||
animal = { type.name = "pug" })toml";
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
std::string ssGenerated;
|
||||
@@ -1157,13 +1158,13 @@ TEST(GenerateTOML, TransferEmbeddedInlineTables)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(test=[{ first = "Tom", last = "Preston-Werner" },
|
||||
std::string ssTOMLInput = R"toml(test=[{ first = "Tom", last = "Preston-Werner" },
|
||||
{ x = 1, y = 2 },
|
||||
{ type.name = "pug" }])code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
{ type.name = "pug" }])toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
test=[{ first = "Tom", last = "Preston-Werner" },
|
||||
{ x = 1, y = 2 },
|
||||
{ type.name = "pug" }])code";
|
||||
{ type.name = "pug" }])toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1177,7 +1178,7 @@ TEST(GenerateTOML, TransferTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code([[products]]
|
||||
std::string ssTOMLInput = R"toml([[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
@@ -1187,8 +1188,8 @@ sku = 738594937
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
|
||||
color = "gray")code";
|
||||
std::string ssTOMLOutput = R"code([[tree.branch.products]]
|
||||
color = "gray")toml";
|
||||
std::string ssTOMLOutput = R"toml([[tree.branch.products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
@@ -1198,7 +1199,7 @@ sku = 738594937
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
|
||||
color = "gray")code";
|
||||
color = "gray")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1212,7 +1213,7 @@ TEST(GenerateTOML, TransferMixedTableAndTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code([[fruits]]
|
||||
std::string ssTOMLInput = R"toml([[fruits]]
|
||||
name = "apple"
|
||||
|
||||
[fruits.physical] # subtable
|
||||
@@ -1230,8 +1231,8 @@ name = "granny smith"
|
||||
name = "banana"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "plantain")code";
|
||||
std::string ssTOMLOutput = R"code([[tree.branch.fruits]]
|
||||
name = "plantain")toml";
|
||||
std::string ssTOMLOutput = R"toml([[tree.branch.fruits]]
|
||||
name = "apple"
|
||||
|
||||
[tree.branch.fruits.physical] # subtable
|
||||
@@ -1249,7 +1250,7 @@ name = "granny smith"
|
||||
name = "banana"
|
||||
|
||||
[[tree.branch.fruits.varieties]]
|
||||
name = "plantain")code";
|
||||
name = "plantain")toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -1263,13 +1264,13 @@ TEST(GenerateTOML, TransferInlineTableArrays)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(points = [ { x = 1, y = 2, z = 3 },
|
||||
std::string ssTOMLInput = R"toml(points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ])code";
|
||||
std::string ssTOMLOutput = R"code([tree.branch]
|
||||
{ x = 2, y = 4, z = 8 } ])toml";
|
||||
std::string ssTOMLOutput = R"toml([tree.branch]
|
||||
points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ])code";
|
||||
{ x = 2, y = 4, z = 8 } ])toml";
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
std::string ssGenerated;
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
|
||||
TEST(GenerateTOML, GetCommentRoot)
|
||||
TEST(GetSetComment, GetCommentRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# This is a comment)code";
|
||||
std::string ssTOML = R"toml(# This is a comment)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -34,17 +34,17 @@ TEST(GenerateTOML, GetCommentRoot)
|
||||
EXPECT_EQ(ssComment, "This is a comment");
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, GetMultiLineCommentRoot)
|
||||
TEST(GetSetComment, GetMultiLineCommentRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
# This is a comment that stretches
|
||||
# more than one line.
|
||||
|
||||
# And here's another comment of more
|
||||
# than one line.
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
|
||||
@@ -55,23 +55,23 @@ TEST(GenerateTOML, GetMultiLineCommentRoot)
|
||||
ssComment = parser.Root().GetComment(sdv::toml::INodeInfo::ECommentType::out_of_scope_comment_before);
|
||||
EXPECT_TRUE(ssComment.empty());
|
||||
ssComment = parser.Root().GetComment(sdv::toml::INodeInfo::ECommentType::out_of_scope_comment_behind);
|
||||
EXPECT_EQ(ssComment, R"code(This is a comment that stretches more than one line.
|
||||
And here's another comment of more than one line.)code");
|
||||
EXPECT_EQ(ssComment, R"toml(This is a comment that stretches more than one line.
|
||||
And here's another comment of more than one line.)toml");
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, SetCommentRoot)
|
||||
TEST(GetSetComment, SetCommentRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
// This will test the SetComment function and overwriting the existing comment.
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a double line comment
|
||||
# This is line two of the double line comment)code";
|
||||
std::string ssTOMLOutput = R"code(# This is comment way before
|
||||
std::string ssTOMLInput = R"toml(# This is a double line comment
|
||||
# This is line two of the double line comment)toml";
|
||||
std::string ssTOMLOutput = R"toml(# This is comment way before
|
||||
|
||||
# This is comment before
|
||||
# This is comment way behind
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -93,13 +93,13 @@ TEST(GenerateTOML, SetCommentRoot)
|
||||
EXPECT_EQ(ssGenerated, ssTOMLOutput);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, SetMultiLineCommentRoot)
|
||||
TEST(GetSetComment, SetMultiLineCommentRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a double line comment
|
||||
# This is line two of the double line comment)code";
|
||||
std::string ssTOMLOutput = R"code(# This is comment way before
|
||||
std::string ssTOMLInput = R"toml(# This is a double line comment
|
||||
# This is line two of the double line comment)toml";
|
||||
std::string ssTOMLOutput = R"toml(# This is comment way before
|
||||
|
||||
# And surprise, also a second line
|
||||
|
||||
@@ -109,7 +109,7 @@ TEST(GenerateTOML, SetMultiLineCommentRoot)
|
||||
# This is comment way behind
|
||||
|
||||
# And final, also a second line
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -139,13 +139,13 @@ And final, also a second line)");
|
||||
EXPECT_EQ(ssGenerated, ssTOMLOutput);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, RemoveCommentRoot)
|
||||
TEST(GetSetComment, RemoveCommentRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a double line comment
|
||||
# This is line two of the double line comment)code";
|
||||
std::string ssTOMLOutput = R"code()code";
|
||||
std::string ssTOMLInput = R"toml(# This is a double line comment
|
||||
# This is line two of the double line comment)toml";
|
||||
std::string ssTOMLOutput = R"toml()toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -155,16 +155,16 @@ TEST(GenerateTOML, RemoveCommentRoot)
|
||||
EXPECT_EQ(ssGenerated, ssTOMLOutput);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, GetCommentRootValue)
|
||||
TEST(GetSetComment, GetCommentRootValue)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(# This is a separate comment
|
||||
std::string ssTOML = R"toml(# This is a separate comment
|
||||
|
||||
# This is a comment before the value
|
||||
value = "this is the value text" # Comment following the value
|
||||
|
||||
# This is also a separate comment)code";
|
||||
# This is also a separate comment)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
sdv::TInterfaceAccessPtr ptrValue = parser.Root().GetNodeDirect("value");
|
||||
@@ -182,11 +182,11 @@ value = "this is the value text" # Comment following the value
|
||||
EXPECT_EQ(ssComment, "This is also a separate comment");
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, GetMultiLineCommentRootValue)
|
||||
TEST(GetSetComment, GetMultiLineCommentRootValue)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
|
||||
|
||||
# This is a separate comment with several line-breaks before.
|
||||
@@ -209,7 +209,7 @@ value = "this is the value text" # Comment following the value.
|
||||
# This is also a separate comment.
|
||||
# Followed by this text on the same line.
|
||||
|
||||
# And another text on a separate line.)code";
|
||||
# And another text on a separate line.)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOML));
|
||||
sdv::TInterfaceAccessPtr ptrValue = parser.Root().GetNodeDirect("value");
|
||||
@@ -218,32 +218,32 @@ value = "this is the value text" # Comment following the value.
|
||||
ASSERT_NE(pComment, nullptr);
|
||||
|
||||
std::string ssComment = pComment->GetComment(sdv::toml::INodeInfo::ECommentType::comment_before);
|
||||
EXPECT_EQ(ssComment, R"code(This is a comment before the value. And another comment before the value at the same line.
|
||||
Note: there was a space after the empty comment line. But that should not influence the comment lines.)code");
|
||||
EXPECT_EQ(ssComment, R"toml(This is a comment before the value. And another comment before the value at the same line.
|
||||
Note: there was a space after the empty comment line. But that should not influence the comment lines.)toml");
|
||||
ssComment = pComment->GetComment(sdv::toml::INodeInfo::ECommentType::comment_behind);
|
||||
EXPECT_EQ(ssComment, R"code(Comment following the value. More comment following the value. This becomes one line.
|
||||
But this is a separate line.)code");
|
||||
EXPECT_EQ(ssComment, R"toml(Comment following the value. More comment following the value. This becomes one line.
|
||||
But this is a separate line.)toml");
|
||||
ssComment = pComment->GetComment(sdv::toml::INodeInfo::ECommentType::out_of_scope_comment_before);
|
||||
EXPECT_EQ(ssComment, R"code(This is a separate comment with several line-breaks before. Followed by this text on the same line.
|
||||
Note: there was a space after the empty comment line. And another separate comment on a next line.)code");
|
||||
EXPECT_EQ(ssComment, R"toml(This is a separate comment with several line-breaks before. Followed by this text on the same line.
|
||||
Note: there was a space after the empty comment line. And another separate comment on a next line.)toml");
|
||||
ssComment = pComment->GetComment(sdv::toml::INodeInfo::ECommentType::out_of_scope_comment_behind);
|
||||
EXPECT_EQ(ssComment, R"code(This is also a separate comment. Followed by this text on the same line.
|
||||
And another text on a separate line.)code");
|
||||
EXPECT_EQ(ssComment, R"toml(This is also a separate comment. Followed by this text on the same line.
|
||||
And another text on a separate line.)toml");
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, SetCommentRootValue)
|
||||
TEST(GetSetComment, SetCommentRootValue)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
// This will test the SetComment function and overwriting the existing comment.
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a double line comment
|
||||
# This is line two of the double line comment)code";
|
||||
std::string ssTOMLOutput = R"code(# This is comment #3
|
||||
std::string ssTOMLInput = R"toml(# This is a double line comment
|
||||
# This is line two of the double line comment)toml";
|
||||
std::string ssTOMLOutput = R"toml(# This is comment #3
|
||||
|
||||
# This is comment #1
|
||||
# This is comment #4
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -265,13 +265,13 @@ TEST(GenerateTOML, SetCommentRootValue)
|
||||
EXPECT_EQ(ssGenerated, ssTOMLOutput);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, SetMultiLineCommentRootValue)
|
||||
TEST(GetSetComment, SetMultiLineCommentRootValue)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a double line comment
|
||||
# This is line two of the double line comment)code";
|
||||
std::string ssTOMLOutput = R"code(# This is comment #3
|
||||
std::string ssTOMLInput = R"toml(# This is a double line comment
|
||||
# This is line two of the double line comment)toml";
|
||||
std::string ssTOMLOutput = R"toml(# This is comment #3
|
||||
|
||||
# And surprise, also a second line
|
||||
|
||||
@@ -281,7 +281,7 @@ TEST(GenerateTOML, SetMultiLineCommentRootValue)
|
||||
# This is comment #4
|
||||
|
||||
# And final, also a second line
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
@@ -311,13 +311,13 @@ And final, also a second line)");
|
||||
EXPECT_EQ(ssGenerated, ssTOMLOutput);
|
||||
}
|
||||
|
||||
TEST(GenerateTOML, RemoveCommentRootValue)
|
||||
TEST(GetSetComment, RemoveCommentRootValue)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
|
||||
std::string ssTOMLInput = R"code(# This is a double line comment
|
||||
# This is line two of the double line comment)code";
|
||||
std::string ssTOMLOutput = R"code()code";
|
||||
std::string ssTOMLInput = R"toml(# This is a double line comment
|
||||
# This is line two of the double line comment)toml";
|
||||
std::string ssTOMLOutput = R"toml()toml";
|
||||
|
||||
EXPECT_NO_THROW(parser.Process(ssTOMLInput));
|
||||
|
||||
119
tests/unit_tests/toml_parser/indexer_tests.cpp
Normal file
119
tests/unit_tests/toml_parser/indexer_tests.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Stimpfl - initial API and implementation
|
||||
* Erik Verhoeven - writing TOML and whitespace preservation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_indexer.h"
|
||||
|
||||
TEST(IndexerTest, InitializeSingle)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer;
|
||||
|
||||
EXPECT_NO_THROW(toml_parser::CNodeIndex index = indexer.CreateIndex());
|
||||
}
|
||||
|
||||
TEST(IndexerTest, CompareOrder)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer;
|
||||
auto index1 = indexer.CreateIndex();
|
||||
auto index2 = indexer.CreateIndex();
|
||||
auto index3 = indexer.CreateIndex();
|
||||
EXPECT_GT(index2, index1);
|
||||
EXPECT_GT(index3, index1);
|
||||
EXPECT_GT(index3, index2);
|
||||
}
|
||||
|
||||
TEST(IndexerTest, SwitchOrder)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer;
|
||||
auto index1 = indexer.CreateIndex();
|
||||
auto index2 = indexer.CreateIndex();
|
||||
auto index3 = indexer.CreateIndex();
|
||||
index3.MoveBefore(index1);
|
||||
EXPECT_GT(index2, index1);
|
||||
EXPECT_LT(index3, index1);
|
||||
EXPECT_LT(index3, index2);
|
||||
}
|
||||
|
||||
TEST(IndexerTest, SwitchOrderMultipleIndexer)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer1;
|
||||
toml_parser::CNodeIndexer indexer2;
|
||||
toml_parser::CNodeIndexer indexer3;
|
||||
auto index1 = indexer1.CreateIndex();
|
||||
auto index2 = indexer2.CreateIndex();
|
||||
auto index3 = indexer3.CreateIndex();
|
||||
EXPECT_GT(index2, index1);
|
||||
EXPECT_GT(index3, index1);
|
||||
EXPECT_GT(index3, index2);
|
||||
index3.MoveBefore(index1);
|
||||
EXPECT_GT(index2, index1);
|
||||
EXPECT_LT(index3, index1);
|
||||
EXPECT_LT(index3, index2);
|
||||
index2.MoveBefore(index3);
|
||||
EXPECT_LT(index2, index1);
|
||||
EXPECT_LT(index3, index1);
|
||||
EXPECT_GT(index3, index2);
|
||||
}
|
||||
|
||||
TEST(IndexerTest, IndexLifetime)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer;
|
||||
|
||||
auto index1 = indexer.CreateIndex();
|
||||
size_t nCurrentCnt = indexer.Count();
|
||||
{
|
||||
auto index2 = indexer.CreateIndex();
|
||||
EXPECT_GT(index2, index1);
|
||||
EXPECT_EQ(indexer.Count(), nCurrentCnt + 1);
|
||||
}
|
||||
EXPECT_EQ(indexer.Count(), nCurrentCnt);
|
||||
auto index3 = indexer.CreateIndex();
|
||||
EXPECT_GT(index3, index1);
|
||||
}
|
||||
|
||||
TEST(IndexerTest, CopyIndex)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer;
|
||||
|
||||
auto index1 = indexer.CreateIndex();
|
||||
auto index2 = indexer.CreateIndex();
|
||||
auto index2b = index2;
|
||||
EXPECT_TRUE(index2b);
|
||||
EXPECT_TRUE(index2);
|
||||
EXPECT_GT(index2b, index1);
|
||||
EXPECT_GT(index2, index1);
|
||||
EXPECT_EQ(index2, index2b);
|
||||
auto index3 = indexer.CreateIndex();
|
||||
EXPECT_GT(index3, index2);
|
||||
EXPECT_GT(index3, index1);
|
||||
}
|
||||
|
||||
TEST(IndexerTest, MoveIndex)
|
||||
{
|
||||
toml_parser::CNodeIndexer indexer;
|
||||
|
||||
auto index1 = indexer.CreateIndex();
|
||||
auto index2 = indexer.CreateIndex();
|
||||
auto index2b = std::move(index2);
|
||||
EXPECT_TRUE(index2b);
|
||||
EXPECT_FALSE(index2);
|
||||
EXPECT_GT(index2b, index1);
|
||||
EXPECT_GT(index2, index1); // index 2 is not initialized any more.
|
||||
EXPECT_GT(index2, index2b);
|
||||
auto index3 = indexer.CreateIndex();
|
||||
EXPECT_GT(index3, index2b);
|
||||
EXPECT_GT(index3, index1);
|
||||
EXPECT_GT(index2, index3);
|
||||
}
|
||||
990
tests/unit_tests/toml_parser/insert_node.cpp
Normal file
990
tests/unit_tests/toml_parser/insert_node.cpp
Normal file
@@ -0,0 +1,990 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include <support/toml.h>
|
||||
|
||||
// Test TODO:
|
||||
// - 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)
|
||||
// Insert as TOML, but only partly correct.
|
||||
|
||||
TEST(InsertNode, InsertValuesRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertValue("", "value_int", 10));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_int = 10)toml");
|
||||
EXPECT_TRUE(root.InsertValue("", "value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_int = 10
|
||||
value_str = "abc")toml");
|
||||
EXPECT_NE(parser.Root().InsertValue(root.GetNodeNameByIndex(0), "value_float", 123.456), nullptr);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_float = 123.456
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableRoot)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTable("", "table1", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([table1])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(root.InsertTable(root.GetNodeNameByIndex(0), "table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table2 = {}
|
||||
[table1])toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(root.InsertTable("", "table3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table2 = {}
|
||||
table3 = {}
|
||||
[table1])toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table
|
||||
EXPECT_TRUE(root.InsertTable(root.GetNodeNameByIndex(0), "table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table2 = {}
|
||||
table3 = {}
|
||||
[table4]
|
||||
[table1])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertArrayRoot)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertArray("", "value_array1"));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_array1 = [])toml");
|
||||
EXPECT_TRUE(root.InsertArray("", "value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
EXPECT_TRUE(root.InsertArray(root.GetNodeNameByIndex(0), "value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_array3 = []
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableArrayRoot)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array1", false));
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array1]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(root.InsertTableArray(root.GetNodeNameByIndex(0), "table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{}]
|
||||
[[table_array1]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array1]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_TRUE(root.InsertTableArray(root.GetNodeNameByIndex(0), "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array4]]
|
||||
[[table_array1]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(root.InsertTableArray("", "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array4]]
|
||||
[[table_array1]]
|
||||
[[table_array4]])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertValueInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableStandard = root.InsertTable("", "standard_table", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert the values into the table
|
||||
EXPECT_TRUE(tableStandard.InsertValue("", "value_int", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_int = 10)toml");
|
||||
EXPECT_TRUE(tableStandard.InsertValue("", "value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
EXPECT_TRUE(tableStandard.InsertValue(tableStandard.GetNodeNameByIndex(0), "value_float", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_float = 123.456
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableStandard = root.InsertTable("", "standard_table", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(tableStandard.InsertTable("", "table1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table.table1])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(tableStandard.InsertTable(tableStandard.GetNodeNameByIndex(0), "table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table2 = {}
|
||||
[standard_table.table1])toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(tableStandard.InsertTable("", "table3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[standard_table.table1])toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table relative to the elements of the
|
||||
// standard_table.
|
||||
EXPECT_TRUE(tableStandard.InsertTable(tableStandard.GetNodeNameByIndex(0), "table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[standard_table.table4]
|
||||
[standard_table.table1])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertArrayInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableStandard = root.InsertTable("", "standard_table", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(tableStandard.InsertArray("", "value_array1"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_array1 = [])toml");
|
||||
EXPECT_TRUE(tableStandard.InsertArray("", "value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
EXPECT_TRUE(tableStandard.InsertArray(tableStandard.GetNodeNameByIndex(0), "value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
value_array3 = []
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableArrayInStandardTable)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableStandard = root.InsertTable("", "standard_table", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(tableStandard.InsertTableArray("", "table_array1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[standard_table.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(tableStandard.InsertTableArray(tableStandard.GetNodeNameByIndex(0), "table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
[[standard_table.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(tableStandard.InsertTableArray("", "table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[standard_table.table_array1]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array relative to the elements
|
||||
// of the standard_table.
|
||||
EXPECT_TRUE(tableStandard.InsertTableArray(tableStandard.GetNodeNameByIndex(0), "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[standard_table.table_array4]]
|
||||
[[standard_table.table_array1]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(tableStandard.InsertTableArray("", "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([standard_table]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[standard_table.table_array4]]
|
||||
[[standard_table.table_array1]]
|
||||
[[standard_table.table_array4]])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertValueInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableInline = root.InsertTable("", "inline_table", true);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert the values into the table
|
||||
EXPECT_TRUE(tableInline.InsertValue("", "value_int", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_int = 10})toml");
|
||||
EXPECT_TRUE(tableInline.InsertValue("", "value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_int = 10, value_str = "abc"})toml");
|
||||
EXPECT_TRUE(tableInline.InsertValue(tableInline.GetNodeNameByIndex(0), "value_float", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_float = 123.456, value_int = 10, value_str = "abc"})toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableInline = root.InsertTable("", "inline_table", true);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(tableInline.InsertTable("", "table1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table1 = {}})toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(tableInline.InsertTable(tableInline.GetNodeNameByIndex(0), "table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table2 = {}, table1 = {}})toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(tableInline.InsertTable("", "table3",
|
||||
true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table2 = {}, table1 = {}, table3 = {}})toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table
|
||||
EXPECT_TRUE(tableInline.InsertTable(tableInline.GetNodeNameByIndex(0), "table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table4 = {}, table2 = {}, table1 = {}, table3 = {}})toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertArrayInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableInline = root.InsertTable("", "inline_table", true);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(tableInline.InsertArray("", "value_array1"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_array1 = []})toml");
|
||||
EXPECT_TRUE(tableInline.InsertArray("", "value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_array1 = [], value_array2 = []})toml");
|
||||
EXPECT_TRUE(tableInline.InsertArray(tableInline.GetNodeNameByIndex(0), "value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {value_array3 = [], value_array1 = [], value_array2 = []})toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableArrayInInlineTable)
|
||||
{
|
||||
// Insert an inline table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection tableInline = root.InsertTable("", "inline_table", true);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {})toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(tableInline.InsertTableArray("", "table_array1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table_array1 = [{}]})toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(tableInline.InsertTableArray(tableInline.GetNodeNameByIndex(0), "table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table_array2 = [{}], table_array1 = [{}]})toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(tableInline.InsertTableArray("", "table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_table = {table_array2 = [{}], table_array1 = [{}], table_array3 = [{}]})toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_TRUE(tableInline.InsertTableArray(tableInline.GetNodeNameByIndex(0), "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML,
|
||||
R"toml(inline_table = {table_array4 = [{}], table_array2 = [{}], table_array1 = [{}], table_array3 = [{}]})toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(tableInline.InsertTableArray("", "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML,
|
||||
R"toml(inline_table = {table_array4 = [{}, {}], table_array2 = [{}], table_array1 = [{}], table_array3 = [{}]})toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertValueInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection arrayInline = root.InsertArray("", "inline_array");
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert the values into the table (with or without name)
|
||||
EXPECT_TRUE(arrayInline.InsertValue("", "", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [10])toml");
|
||||
EXPECT_TRUE(arrayInline.InsertValue("", "", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [10, "abc"])toml");
|
||||
EXPECT_TRUE(arrayInline.InsertValue(arrayInline.GetNodeNameByIndex(0), "", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [123.456, 10, "abc"])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection arrayInline = root.InsertArray("", "inline_array");
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert a standard table
|
||||
sdv::toml::CNodeCollection table = arrayInline.InsertTable("", "", false);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "a", 10);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{a = 10}])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
table = arrayInline.InsertTable(arrayInline.GetNodeNameByIndex(0), "", true);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "b", 20);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{b = 20}, {a = 10}])toml");
|
||||
|
||||
// Insert an inline table behind
|
||||
table = arrayInline.InsertTable("", "", true);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "c", 30);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{b = 20}, {a = 10}, {c = 30}])toml");
|
||||
|
||||
// Insert a standard table in front
|
||||
table = arrayInline.InsertTable(arrayInline.GetNodeNameByIndex(0), "", false);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "d", 40);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [{d = 40}, {b = 20}, {a = 10}, {c = 30}])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertArrayInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection arrayInline = root.InsertArray("", "inline_array");
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert arrays
|
||||
sdv::toml::CNodeCollection array = arrayInline.InsertArray("", "");
|
||||
EXPECT_TRUE(array);
|
||||
array.InsertValue("", "", 10);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[10]])toml");
|
||||
array = arrayInline.InsertArray("", "");
|
||||
EXPECT_TRUE(array);
|
||||
array.InsertValue("", "", 20);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[10], [20]])toml");
|
||||
array = arrayInline.InsertArray(arrayInline.GetNodeNameByIndex(0), "");
|
||||
EXPECT_TRUE(array);
|
||||
array.InsertValue("", "", 30);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[30], [10], [20]])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableArrayInArray)
|
||||
{
|
||||
// Insert an array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection arrayInline = root.InsertArray("", "inline_array");
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [])toml");
|
||||
|
||||
// Insert standard table array
|
||||
sdv::toml::CNodeCollection table = arrayInline.InsertTableArray("", "", false);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "a", 10);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{a = 10}]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
table = arrayInline.InsertTableArray(arrayInline.GetNodeNameByIndex(0), "", true);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "b", 20);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{b = 20}], [{a = 10}]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
table = arrayInline.InsertTableArray("", "", true);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "c", 30);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{b = 20}], [{a = 10}], [{c = 30}]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
table = arrayInline.InsertTableArray(arrayInline.GetNodeNameByIndex(0), "", false);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "d", 40);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{d = 40}], [{b = 20}], [{a = 10}], [{c = 30}]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
sdv::toml::CNodeCollection array = arrayInline.Get(0);
|
||||
EXPECT_TRUE(array);
|
||||
table = array.InsertTable("", "", false);
|
||||
EXPECT_TRUE(table);
|
||||
table.InsertValue("", "e", 50);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(inline_array = [[{d = 40}, {e = 50}], [{b = 20}], [{a = 10}], [{c = 30}]])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertValueInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection table = root.InsertTableArray("", "table_array", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert the values into the table
|
||||
EXPECT_TRUE(table.InsertValue("", "value_int", 10));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_int = 10)toml");
|
||||
EXPECT_TRUE(table.InsertValue("", "value_str", u8"abc"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
EXPECT_TRUE(table.InsertValue(table.GetNodeNameByIndex(0), "value_float", 123.456));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_float = 123.456
|
||||
value_int = 10
|
||||
value_str = "abc")toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection table = root.InsertTableArray("", "table_array", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert a standard table
|
||||
EXPECT_TRUE(table.InsertTable("", "table1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
[table_array.table1])toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_TRUE(table.InsertTable(table.GetNodeNameByIndex(0), "table2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table2 = {}
|
||||
[table_array.table1])toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_TRUE(table.InsertTable("", "table3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[table_array.table1])toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table
|
||||
EXPECT_TRUE(table.InsertTable(table.GetNodeNameByIndex(0), "table4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table2 = {}
|
||||
table3 = {}
|
||||
[table_array.table4]
|
||||
[table_array.table1])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertArrayInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection table = root.InsertTableArray("", "table_array", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert arrays
|
||||
EXPECT_TRUE(table.InsertArray("", "value_array1"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_array1 = [])toml");
|
||||
EXPECT_TRUE(table.InsertArray("", "value_array2"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
EXPECT_TRUE(table.InsertArray(table.GetNodeNameByIndex(0), "value_array3"));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
value_array3 = []
|
||||
value_array1 = []
|
||||
value_array2 = [])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableArrayInTableArray)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
sdv::toml::CNodeCollection table = root.InsertTableArray("", "table_array", false);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]])toml");
|
||||
|
||||
// Insert standard table array
|
||||
EXPECT_TRUE(table.InsertTableArray("", "table_array1", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_TRUE(table.InsertTableArray(table.GetNodeNameByIndex(0), "table_array2", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_TRUE(table.InsertTableArray("", "table_array3", true));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_TRUE(table.InsertTableArray(table.GetNodeNameByIndex(0), "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array.table_array4]]
|
||||
[[table_array.table_array1]])toml");
|
||||
|
||||
// Add an additional table array entry for table array #4
|
||||
EXPECT_TRUE(table.InsertTableArray("", "table_array4", false));
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array]]
|
||||
table_array2 = [{}]
|
||||
table_array3 = [{}]
|
||||
[[table_array.table_array4]]
|
||||
[[table_array.table_array1]]
|
||||
[[table_array.table_array4]])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertValuesRootAsTOML)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml(# This is the first value
|
||||
value_int = 10)toml", true), 1);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is the first value
|
||||
value_int = 10)toml");
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml(value_str = "abc" # This is the second value
|
||||
|
||||
# Comment in between
|
||||
|
||||
# And the third value
|
||||
value_float = 123.456
|
||||
|
||||
# Some
|
||||
# Final
|
||||
# Words :-)
|
||||
)toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is the first value
|
||||
value_int = 10
|
||||
value_str = "abc" # This is the second value
|
||||
|
||||
# Comment in between
|
||||
|
||||
# And the third value
|
||||
value_float = 123.456
|
||||
|
||||
# Some
|
||||
# Final
|
||||
# Words :-)
|
||||
)toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableRootAsTOML)
|
||||
{
|
||||
// Insert a standard table
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml([table1] # This is table 1
|
||||
a = 10
|
||||
b = 20.30)toml", true), 1);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([table1] # This is table 1
|
||||
a = 10
|
||||
b = 20.30)toml");
|
||||
|
||||
// Insert an inline table before
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(0), R"toml(# This is table 2
|
||||
table2 = {c = 40, d = "50"})toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is table 2
|
||||
table2 = {c = 40, d = "50"}
|
||||
[table1] # This is table 1
|
||||
a = 10
|
||||
b = 20.30)toml");
|
||||
|
||||
// Insert an inline table behind -> this will have to be printed before the standard table
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml(table3 = {e = '60'} # This is table 3
|
||||
)toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is table 2
|
||||
table2 = {c = 40, d = "50"}
|
||||
table3 = {e = '60'} # This is table 3
|
||||
[table1] # This is table 1
|
||||
a = 10
|
||||
b = 20.30)toml");
|
||||
|
||||
// Insert a standard table in front -> this will have to be printed behind the inline table
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(0), R"toml(
|
||||
|
||||
# And this is table 4
|
||||
[table4]
|
||||
f = 70
|
||||
g = 80.90)toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is table 2
|
||||
table2 = {c = 40, d = "50"}
|
||||
table3 = {e = '60'} # This is table 3
|
||||
|
||||
|
||||
# And this is table 4
|
||||
[table4]
|
||||
f = 70
|
||||
g = 80.90
|
||||
[table1] # This is table 1
|
||||
a = 10
|
||||
b = 20.30)toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertArrayRootAsTOML)
|
||||
{
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml(value_array1 = [10, 20, 30] # This is array 1)toml", true),
|
||||
1);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(value_array1 = [10, 20, 30] # This is array 1)toml");
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(0), R"toml(# This is array 2
|
||||
value_array2 = [
|
||||
40, # This is an integer value
|
||||
50.60, # This is a float value
|
||||
"70", # This is a string value
|
||||
])toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is array 2
|
||||
value_array2 = [
|
||||
40, # This is an integer value
|
||||
50.60, # This is a float value
|
||||
"70", # This is a string value
|
||||
]
|
||||
value_array1 = [10, 20, 30] # This is array 1)toml");
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(1), R"toml(# And finally array 3
|
||||
value_array3 = [])toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(# This is array 2
|
||||
value_array2 = [
|
||||
40, # This is an integer value
|
||||
50.60, # This is a float value
|
||||
"70", # This is a string value
|
||||
]
|
||||
# And finally array 3
|
||||
value_array3 = []
|
||||
value_array1 = [10, 20, 30] # This is array 1)toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, InsertTableArrayRootAsTOML)
|
||||
{
|
||||
// Insert a standard table array
|
||||
toml_parser::CParser parser;
|
||||
sdv::toml::CNodeCollection root(&parser.Root());
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml([[table_array1]]
|
||||
a = 10
|
||||
b = 20)toml", true), 1);
|
||||
std::string ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml([[table_array1]]
|
||||
a = 10
|
||||
b = 20)toml");
|
||||
|
||||
// Insert an inline table array before
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(0), R"toml(table_array2 = [{c = 30}, {d = 40}])toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{c = 30}, {d = 40}]
|
||||
[[table_array1]]
|
||||
a = 10
|
||||
b = 20)toml");
|
||||
|
||||
// Insert an inline table array behind -> this will have to be printed before the standard table array
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml(table_array3 =
|
||||
[
|
||||
{ e = 50 }
|
||||
])toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{c = 30}, {d = 40}]
|
||||
table_array3 =
|
||||
[
|
||||
{ e = 50 }
|
||||
]
|
||||
[[table_array1]]
|
||||
a = 10
|
||||
b = 20)toml");
|
||||
|
||||
// Insert a standard table array in front -> this will have to be printed behind the inline table array
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(0), R"toml([[table_array4]]
|
||||
f = 60
|
||||
g = 70)toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{c = 30}, {d = 40}]
|
||||
table_array3 =
|
||||
[
|
||||
{ e = 50 }
|
||||
]
|
||||
[[table_array4]]
|
||||
f = 60
|
||||
g = 70
|
||||
[[table_array1]]
|
||||
a = 10
|
||||
b = 20)toml");
|
||||
|
||||
// Add an additional table array entry for table array #4 (even provided as inline, must be added as standard).
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml(table_array4 = [{h = 80}])toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{c = 30}, {d = 40}]
|
||||
table_array3 =
|
||||
[
|
||||
{ e = 50 }
|
||||
]
|
||||
[[table_array4]]
|
||||
f = 60
|
||||
g = 70
|
||||
[[table_array1]]
|
||||
a = 10
|
||||
b = 20
|
||||
[[table_array4]]
|
||||
h = 80)toml");
|
||||
|
||||
// Add an additional table array entry for table array #4 (even provided as inline, must be added as standard).
|
||||
EXPECT_EQ(root.InsertTOML("", R"toml([[table_array3]]
|
||||
i = 90
|
||||
[[table_array3]]
|
||||
j = 100
|
||||
)toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(root.InsertTOML(root.GetNodeNameByIndex(0), R"toml([[table_array3]]
|
||||
k = 110)toml", true), 1);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{c = 30}, {d = 40}]
|
||||
table_array3 =
|
||||
[{k = 110},
|
||||
{ e = 50 },
|
||||
{i = 90}, {j = 100}]
|
||||
[[table_array4]]
|
||||
f = 60
|
||||
g = 70
|
||||
[[table_array1]]
|
||||
a = 10
|
||||
b = 20
|
||||
[[table_array4]]
|
||||
h = 80)toml");
|
||||
|
||||
root.AutomaticFormat(true);
|
||||
ssTOML = parser.GenerateTOML();
|
||||
EXPECT_EQ(ssTOML, R"toml(table_array2 = [{c = 30}, {d = 40}]
|
||||
table_array3 = [{k = 110}, {e = 50}, {i = 90}, {j = 100}]
|
||||
[[table_array4]]
|
||||
f = 60
|
||||
g = 70
|
||||
[[table_array1]]
|
||||
a = 10
|
||||
b = 20
|
||||
[[table_array4]]
|
||||
h = 80)toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertValueInStandardTableAsTOML)
|
||||
{
|
||||
//// Insert a standard table
|
||||
//toml_parser::CParser parser;
|
||||
//sdv::toml::INodeCollectionInsert* pStandardTable = sdv::TInterfaceAccessPtr(root.InsertTable(
|
||||
// sdv::toml::npos, "standard_table", false)).
|
||||
// GetInterface<sdv::toml::INodeCollectionInsert>();
|
||||
//ASSERT_NE(pStandardTable, nullptr);
|
||||
//std::string ssTOML = parser.GenerateTOML();
|
||||
//EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableInStandardTableAsTOML)
|
||||
{
|
||||
//// Insert a standard table
|
||||
//toml_parser::CParser parser;
|
||||
//sdv::toml::INodeCollectionInsert* pStandardTable = sdv::TInterfaceAccessPtr(root.InsertTable(
|
||||
// sdv::toml::npos, "standard_table", false)).
|
||||
// GetInterface<sdv::toml::INodeCollectionInsert>();
|
||||
//ASSERT_NE(pStandardTable, nullptr);
|
||||
//std::string ssTOML = parser.GenerateTOML();
|
||||
//EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertArrayInStandardTableAsTOML)
|
||||
{
|
||||
//// Insert a standard table
|
||||
//toml_parser::CParser parser;
|
||||
//sdv::toml::INodeCollectionInsert* pStandardTable = sdv::TInterfaceAccessPtr(root.InsertTable(
|
||||
// sdv::toml::npos, "standard_table", false)).
|
||||
// GetInterface<sdv::toml::INodeCollectionInsert>();
|
||||
//ASSERT_NE(pStandardTable, nullptr);
|
||||
//std::string ssTOML = parser.GenerateTOML();
|
||||
//EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableArrayInStandardTableAsTOML)
|
||||
{
|
||||
//// Insert a standard table
|
||||
//toml_parser::CParser parser;
|
||||
//sdv::toml::INodeCollectionInsert* pStandardTable = sdv::TInterfaceAccessPtr(root.InsertTable(
|
||||
// sdv::toml::npos, "standard_table", false)).
|
||||
// GetInterface<sdv::toml::INodeCollectionInsert>();
|
||||
//ASSERT_NE(pStandardTable, nullptr);
|
||||
//std::string ssTOML = parser.GenerateTOML();
|
||||
//EXPECT_EQ(ssTOML, R"toml([standard_table])toml");
|
||||
}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertValueInInlineTableAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableInInlineTableAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertArrayInInlineTableAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableArrayInInlineTableAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertValueInArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableInArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertArrayInArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableArrayInArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertValueInTableArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableInTableArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertArrayInTableArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertTableArrayInTableArrayAsTOML)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertMixed)
|
||||
{}
|
||||
|
||||
TEST(InsertNode, DISABLED_TestInsertMixedWithDelete)
|
||||
{}
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/lexer_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/exception.h"
|
||||
|
||||
@@ -114,7 +115,7 @@
|
||||
* + Exceptions thrown by the CharacterReaderare caught and result in a token_terminated-Token and no further lexing will be done
|
||||
*/
|
||||
|
||||
TEST(TOMLLexerTest, Keys)
|
||||
TEST(Lexer, Keys)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
// U+1F92B is the Finger-On-Lips Shushing emoji with UTF-8 byte representation 0xF09FA4AB
|
||||
@@ -169,7 +170,7 @@ TEST(TOMLLexerTest, Keys)
|
||||
EXPECT_EQ("1234", key8.StringValue());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, SyntaxToken_NewLine)
|
||||
TEST(Lexer, SyntaxToken_NewLine)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -187,7 +188,7 @@ TEST(TOMLLexerTest, SyntaxToken_NewLine)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_syntax_new_line, newLine2.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, SyntaxToken_Bracket)
|
||||
TEST(Lexer, SyntaxToken_Bracket)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -240,7 +241,7 @@ TEST(TOMLLexerTest, SyntaxToken_Bracket)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_syntax_table_array_close, tableArrayBracketClose.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, SyntaxToken_Assignment)
|
||||
TEST(Lexer, SyntaxToken_Assignment)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexerNormal(R"(
|
||||
@@ -279,7 +280,7 @@ TEST(TOMLLexerTest, SyntaxToken_Assignment)
|
||||
EXPECT_EQ(rValueNoSpace.StringValue(), "value");
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Comments)
|
||||
TEST(Lexer, Comments)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexerNormal(R"(
|
||||
@@ -414,7 +415,7 @@ TEST(TOMLLexerTest, Comments)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_comment, rNoSpaceTableClose.Next().Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, SyntaxToken_Dot)
|
||||
TEST(Lexer, SyntaxToken_Dot)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -451,7 +452,7 @@ TEST(TOMLLexerTest, SyntaxToken_Dot)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_syntax_dot, dot6.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, SyntaxToken_Braces)
|
||||
TEST(Lexer, SyntaxToken_Braces)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -511,7 +512,7 @@ TEST(TOMLLexerTest, SyntaxToken_Braces)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_key, emptyTable.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, SyntaxToken_ArrayTable)
|
||||
TEST(Lexer, SyntaxToken_ArrayTable)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -588,7 +589,7 @@ TEST(TOMLLexerTest, SyntaxToken_ArrayTable)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_syntax_table_array_close, tableArrayClose5.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_Integer)
|
||||
TEST(Lexer, Datatype_Integer)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -758,7 +759,7 @@ TEST(TOMLLexerTest, Datatype_Integer)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, intErr10.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_Float)
|
||||
TEST(Lexer, Datatype_Float)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -945,7 +946,7 @@ TEST(TOMLLexerTest, Datatype_Float)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, errFloat28.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_Boolean)
|
||||
TEST(Lexer, Datatype_Boolean)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -966,7 +967,7 @@ TEST(TOMLLexerTest, Datatype_Boolean)
|
||||
EXPECT_FALSE(falseToken.BooleanValue());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_String_BasicString)
|
||||
TEST(Lexer, Datatype_String_BasicString)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1045,7 +1046,7 @@ TEST(TOMLLexerTest, Datatype_String_BasicString)
|
||||
EXPECT_EQ("Musical eighth note: 𝅘𝅥𝅮", string_esc9.StringValue());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_String_BasicStringMultiline)
|
||||
TEST(Lexer, Datatype_String_BasicStringMultiline)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1170,7 +1171,7 @@ multiline string"""
|
||||
EXPECT_EQ("Musical eighth note: 𝅘𝅥𝅮 multiline", string_esc9.StringValue());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_String_LiteralString)
|
||||
TEST(Lexer, Datatype_String_LiteralString)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1208,7 +1209,7 @@ TEST(TOMLLexerTest, Datatype_String_LiteralString)
|
||||
EXPECT_EQ("<\\i\\c*\\s*>", regex.StringValue());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Datatype_String_LiteralStringMultiline)
|
||||
TEST(Lexer, Datatype_String_LiteralStringMultiline)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1257,27 +1258,27 @@ str = ''''That,' she said, 'is still pointless.''''
|
||||
EXPECT_EQ("'That,' she said, 'is still pointless.'", str.StringValue());
|
||||
}
|
||||
|
||||
// TEST(TOMLLexerTest, Datatype_OffsetDateTime)
|
||||
// TEST(Lexer, Datatype_OffsetDateTime)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
// TEST(TOMLLexerTest, Datatype_DateTime)
|
||||
// TEST(Lexer, Datatype_DateTime)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
// TEST(TOMLLexerTest, Datatype_LocalDate)
|
||||
// TEST(Lexer, Datatype_LocalDate)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
// TEST(TOMLLexerTest, Datatype_LocalTime)
|
||||
// TEST(Lexer, Datatype_LocalTime)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
TEST(TOMLLexerTest, Invalid_Key)
|
||||
TEST(Lexer, Invalid_Key)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1306,7 +1307,7 @@ TEST(TOMLLexerTest, Invalid_Key)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, invQuotedKey3.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Invalid_String)
|
||||
TEST(Lexer, Invalid_String)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer1(R"(key1 = "invalid escape sequence \h)"s);
|
||||
@@ -1332,7 +1333,7 @@ TEST(TOMLLexerTest, Invalid_String)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, invString4.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Invalid_Integer)
|
||||
TEST(Lexer, Invalid_Integer)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1406,7 +1407,7 @@ TEST(TOMLLexerTest, Invalid_Integer)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, invInteger15.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Invalid_Float)
|
||||
TEST(Lexer, Invalid_Float)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1440,7 +1441,7 @@ TEST(TOMLLexerTest, Invalid_Float)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, invFloat5.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Invalid_Boolean)
|
||||
TEST(Lexer, Invalid_Boolean)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1459,27 +1460,27 @@ TEST(TOMLLexerTest, Invalid_Boolean)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_error, invBool2.Category());
|
||||
}
|
||||
|
||||
// TEST(TOMLLexerTest, Invalid_OffsetDateTime)
|
||||
// TEST(Lexer, Invalid_OffsetDateTime)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
// TEST(TOMLLexerTest, Invalid_LocalDateTime)
|
||||
// TEST(Lexer, Invalid_LocalDateTime)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
// TEST(TOMLLexerTest, Invalid_LocalDate)
|
||||
// TEST(Lexer, Invalid_LocalDate)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
// TEST(TOMLLexerTest, Invalid_LocalTime)
|
||||
// TEST(Lexer, Invalid_LocalTime)
|
||||
// {
|
||||
// ASSERT_TRUE(false);
|
||||
// }
|
||||
|
||||
TEST(TOMLLexerTest, Peek_NoAdvance)
|
||||
TEST(Lexer, Peek_NoAdvance)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1500,7 +1501,7 @@ TEST(TOMLLexerTest, Peek_NoAdvance)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_key, lexer.Peek(1).Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, Consume_Advance)
|
||||
TEST(Lexer, Consume_Advance)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1525,7 +1526,7 @@ TEST(TOMLLexerTest, Consume_Advance)
|
||||
EXPECT_EQ(toml_parser::ETokenCategory::token_syntax_assignment, ptr.Category());
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, PeekConsume_BoundsCheck)
|
||||
TEST(Lexer, PeekConsume_BoundsCheck)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"(
|
||||
@@ -1544,7 +1545,7 @@ TEST(TOMLLexerTest, PeekConsume_BoundsCheck)
|
||||
EXPECT_FALSE(lexer.Consume(0));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, PeekConsume_EmptyInput)
|
||||
TEST(Lexer, PeekConsume_EmptyInput)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer(R"()"s);
|
||||
@@ -1555,7 +1556,7 @@ TEST(TOMLLexerTest, PeekConsume_EmptyInput)
|
||||
EXPECT_FALSE(lexer.Consume(1));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, ExceptionHandling)
|
||||
TEST(Lexer, ExceptionHandling)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CLexer lexer;
|
||||
@@ -1577,7 +1578,7 @@ TEST(TOMLLexerTest, ExceptionHandling)
|
||||
EXPECT_FALSE(lexer.Consume(0));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerTest, DISABLED_RegenerateTOML)
|
||||
TEST(Lexer, DISABLED_RegenerateTOML)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
std::string ssOrginal = R"(
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/localmemmgr.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"
|
||||
@@ -21,6 +22,8 @@
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/code_snippet.cpp"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_indexer.cpp"
|
||||
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
@@ -30,6 +33,7 @@ extern "C" int main(int argc, char* argv[])
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
CLocalMemMgr memmgr;
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
289
tests/unit_tests/toml_parser/make_inline_standard.cpp
Normal file
289
tests/unit_tests/toml_parser/make_inline_standard.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <functional>
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/exception.h"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include <support/toml.h>
|
||||
|
||||
TEST(MakeInline, Value)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(value1 = 1)toml";
|
||||
std::string ssTomlOut = R"toml(value1 = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, Value)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(value1 = 1)toml";
|
||||
std::string ssTomlOut = R"toml(value1 = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_FALSE(parser.Root().CanMakeStandard());
|
||||
EXPECT_FALSE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, Array)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(value1 = ["abc", "def", "ghi"])toml";
|
||||
std::string ssTomlOut = R"toml(value1 = ["abc", "def", "ghi"])toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, Array)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(value1 = ["abc", "def", "ghi"])toml";
|
||||
std::string ssTomlOut = R"toml(value1 = ["abc", "def", "ghi"])toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_FALSE(parser.Root().CanMakeStandard());
|
||||
EXPECT_FALSE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, StandardTable)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([table1]
|
||||
value = 1)toml";
|
||||
std::string ssTomlOut = R"toml(table1 = {value = 1})toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, StandardTable)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([table1]
|
||||
value = 1)toml";
|
||||
std::string ssTomlOut = R"toml([table1]
|
||||
value = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, InlineTable)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(table1 = {value = 1})toml";
|
||||
std::string ssTomlOut = R"toml(table1 = {value = 1})toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, InlineTable)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(table1 = {value = 1})toml";
|
||||
std::string ssTomlOut = R"toml([table1]
|
||||
value = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, StandardTableArray)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([[table_array1]]
|
||||
value = 1)toml";
|
||||
std::string ssTomlOut = R"toml(table_array1 = [{value = 1}])toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, StandardTableArray)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([[table_array1]]
|
||||
value = 1)toml";
|
||||
std::string ssTomlOut = R"toml([[table_array1]]
|
||||
value = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, InlineTableArray)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(table_array1 = [{value = 1}])toml";
|
||||
std::string ssTomlOut = R"toml(table_array1 = [{value = 1}])toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, InlineTableArray)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(table_array1 = [{value = 1}])toml";
|
||||
std::string ssTomlOut = R"toml([[table_array1]]
|
||||
value = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, StandardTableImplicit)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([root_table.table1]
|
||||
value = 1)toml";
|
||||
std::string ssTomlOut = R"toml(root_table.table1 = {value = 1})toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, StandardTableImplicit)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([root_table.table1]
|
||||
value = 1)toml";
|
||||
std::string ssTomlOut = R"toml([root_table.table1]
|
||||
value = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, InlineTableImplicit)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(root_table.table1 = {value = 1})toml";
|
||||
std::string ssTomlOut = R"toml(root_table.table1 = {value = 1})toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, InlineTableImplicit)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(root_table.table1 = {value = 1})toml";
|
||||
std::string ssTomlOut = R"toml([root_table.table1]
|
||||
value = 1)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, StandardTableNested)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([table1]
|
||||
value1 = 1
|
||||
[table1.table2]
|
||||
value2 = 2
|
||||
[table1.table3.table4]
|
||||
value3 = 3
|
||||
value4 = 4)toml";
|
||||
std::string ssTomlOut = R"toml(table1 = {value1 = 1, table2 = {value2 = 2}, table3.table4 = {value3 = 3, value4 = 4}})toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, StandardTableNested)
|
||||
{
|
||||
std::string ssTomlIn = R"toml([table1]
|
||||
value = 1
|
||||
[table1.table2]
|
||||
value = 2)toml";
|
||||
std::string ssTomlOut = R"toml([table1]
|
||||
value = 1
|
||||
[table1.table2]
|
||||
value = 2)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeInline, InlineTableNested)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(table1 = {value = 1, table2 = {value = 2}})toml";
|
||||
std::string ssTomlOut = R"toml(table1 = {value = 1, table2 = {value = 2}})toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeInline());
|
||||
EXPECT_TRUE(parser.Root().MakeInline());
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
TEST(MakeStandard, InlineTableNested)
|
||||
{
|
||||
std::string ssTomlIn = R"toml(table1 = {value = 1, table2 = {value = 2}})toml";
|
||||
std::string ssTomlOut = R"toml([table1]
|
||||
value = 1
|
||||
[table1.table2]
|
||||
value = 2)toml";
|
||||
|
||||
toml_parser::CParser parser(ssTomlIn);
|
||||
EXPECT_TRUE(parser.Root().CanMakeStandard());
|
||||
EXPECT_TRUE(parser.Root().MakeStandard(true));
|
||||
std::string ssOut = parser.Root().GetTOML();
|
||||
EXPECT_EQ(ssTomlOut, ssOut);
|
||||
}
|
||||
|
||||
@@ -15,11 +15,16 @@
|
||||
#include <functional>
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/exception.h"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
|
||||
|
||||
TEST(TOMLMiscellaneousTests, Hex2Dec)
|
||||
// Test TODO:
|
||||
// Shift nodes up and down within one container
|
||||
// Remove formatting from node
|
||||
// Compare TOMLs
|
||||
|
||||
TEST(Miscellaneous, Hex2Dec)
|
||||
{
|
||||
// No string
|
||||
std::string ssEmpty;
|
||||
@@ -47,7 +52,7 @@ TEST(TOMLMiscellaneousTests, Hex2Dec)
|
||||
EXPECT_EQ(toml_parser::HexadecimalToDecimal("10xyz"), 16u);
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, Dec2Dec)
|
||||
TEST(Miscellaneous, Dec2Dec)
|
||||
{
|
||||
// No string
|
||||
std::string ssEmpty;
|
||||
@@ -75,7 +80,7 @@ TEST(TOMLMiscellaneousTests, Dec2Dec)
|
||||
EXPECT_EQ(toml_parser::DecimalToDecimal("10xyz"), 10u);
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, Oct2Dec)
|
||||
TEST(Miscellaneous, Oct2Dec)
|
||||
{
|
||||
// No string
|
||||
std::string ssEmpty;
|
||||
@@ -103,7 +108,7 @@ TEST(TOMLMiscellaneousTests, Oct2Dec)
|
||||
EXPECT_EQ(toml_parser::OctalToDecimal("12xyz"), 10u);
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, Bin2Dec)
|
||||
TEST(Miscellaneous, Bin2Dec)
|
||||
{
|
||||
// No string
|
||||
std::string ssEmpty;
|
||||
@@ -131,7 +136,7 @@ TEST(TOMLMiscellaneousTests, Bin2Dec)
|
||||
EXPECT_EQ(toml_parser::BinaryToDecimal("1010yz"), 10u);
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, UnicodeCharacter)
|
||||
TEST(Miscellaneous, UnicodeCharacter)
|
||||
{
|
||||
// No string
|
||||
std::string ssEmpty;
|
||||
@@ -147,7 +152,7 @@ TEST(TOMLMiscellaneousTests, UnicodeCharacter)
|
||||
EXPECT_EQ(toml_parser::EscapedUnicodeCharacterToUTF8("0001F600"), u8"\U0001F600");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitKeyStringEmpty)
|
||||
TEST(Miscellaneous, SplitKeyStringEmpty)
|
||||
{
|
||||
std::string ssKeyEmpty;
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKeyEmpty);
|
||||
@@ -155,7 +160,7 @@ TEST(TOMLMiscellaneousTests, SplitKeyStringEmpty)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitKeyFirstPartOnly)
|
||||
TEST(Miscellaneous, SplitKeyFirstPartOnly)
|
||||
{
|
||||
std::string ssKey = "abc";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -196,7 +201,7 @@ TEST(TOMLMiscellaneousTests, SplitKeyFirstPartOnly)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitStandardBareKey)
|
||||
TEST(Miscellaneous, SplitStandardBareKey)
|
||||
{
|
||||
std::string ssKey = "abc.def";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -236,7 +241,7 @@ TEST(TOMLMiscellaneousTests, SplitStandardBareKey)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitBareKeyWithSpace)
|
||||
TEST(Miscellaneous, SplitBareKeyWithSpace)
|
||||
{
|
||||
std::string ssKey = " abc.def";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -265,7 +270,7 @@ TEST(TOMLMiscellaneousTests, SplitBareKeyWithSpace)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitLiteralKey)
|
||||
TEST(Miscellaneous, SplitLiteralKey)
|
||||
{
|
||||
std::string ssKey = "'abc'";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -309,7 +314,7 @@ TEST(TOMLMiscellaneousTests, SplitLiteralKey)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitQuotedKey)
|
||||
TEST(Miscellaneous, SplitQuotedKey)
|
||||
{
|
||||
std::string ssKey = "\"abc\"";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -348,7 +353,7 @@ TEST(TOMLMiscellaneousTests, SplitQuotedKey)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitEscapedQuotedKey)
|
||||
TEST(Miscellaneous, SplitEscapedQuotedKey)
|
||||
{
|
||||
std::string ssKey = "\"abc\\bdef\"";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -413,7 +418,7 @@ TEST(TOMLMiscellaneousTests, SplitEscapedQuotedKey)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitTableKey)
|
||||
TEST(Miscellaneous, SplitTableKey)
|
||||
{
|
||||
std::string ssKey = "abc.def";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -431,7 +436,7 @@ TEST(TOMLMiscellaneousTests, SplitTableKey)
|
||||
EXPECT_EQ(prSplittedKey.second, "def.ghi");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SplitArrayKey)
|
||||
TEST(Miscellaneous, SplitArrayKey)
|
||||
{
|
||||
std::string ssKey = "abc[1]";
|
||||
auto prSplittedKey = toml_parser::SplitNodeKey(ssKey);
|
||||
@@ -493,7 +498,7 @@ TEST(TOMLMiscellaneousTests, SplitArrayKey)
|
||||
EXPECT_TRUE(prSplittedKey.second.empty());
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteBareKeys)
|
||||
TEST(Miscellaneous, 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");
|
||||
@@ -502,7 +507,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteBareKeys)
|
||||
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::smart_key), "ABC-DEF");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteSpecialCharsKeys)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -515,7 +520,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteSpecialCharsKeys)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::smart_key), "\"abc/\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteEscapeCharsKeys)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -527,7 +532,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteEscapeCharsKeys)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::smart_key), "\"abc\\rdef\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteControlCharsKeys)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -567,7 +572,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteControlCharsKeys)
|
||||
// 0080... and higher are treated as unicode character (quotation needed)
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -576,7 +581,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::smart_text), "\"ABC-DEF\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteSpecialCharsText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -589,7 +594,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteSpecialCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::smart_text), "\"abc/\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteEscapeCharsText)
|
||||
TEST(Miscellaneous, 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'");
|
||||
@@ -601,7 +606,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteEscapeCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::smart_text), "\"abc\\rdef\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, SmartQuoteControlCharsText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -641,7 +646,7 @@ TEST(TOMLMiscellaneousTests, SmartQuoteControlCharsText)
|
||||
// 0080... and higher are treated as unicode character (quotation needed)
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, QuotedText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -650,7 +655,7 @@ TEST(TOMLMiscellaneousTests, QuotedText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::quoted_text), "\"ABC-DEF\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, QuotedSpecialCharsText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -663,7 +668,7 @@ TEST(TOMLMiscellaneousTests, QuotedSpecialCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::quoted_text), "\"abc/\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, QuotedEscapeCharsText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -675,7 +680,7 @@ TEST(TOMLMiscellaneousTests, QuotedEscapeCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::quoted_text), "\"abc\\rdef\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, QuotedControlCharsText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -715,7 +720,7 @@ TEST(TOMLMiscellaneousTests, QuotedControlCharsText)
|
||||
// 0080... and higher are treated as unicode character (quotation needed)
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, LiteralText)
|
||||
TEST(Miscellaneous, 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'");
|
||||
@@ -724,7 +729,7 @@ TEST(TOMLMiscellaneousTests, LiteralText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::literal_text), "'ABC-DEF'");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, LiteralSpecialCharsText)
|
||||
TEST(Miscellaneous, 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'");
|
||||
@@ -737,7 +742,7 @@ TEST(TOMLMiscellaneousTests, LiteralSpecialCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::literal_text), "'abc/'");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, LiteralEscapeCharsText)
|
||||
TEST(Miscellaneous, 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'");
|
||||
@@ -749,7 +754,7 @@ TEST(TOMLMiscellaneousTests, LiteralEscapeCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::literal_text), "\"abc\\rdef\""); // Becomes quoted
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, LiteralControlCharsText)
|
||||
TEST(Miscellaneous, 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\"");
|
||||
@@ -790,7 +795,7 @@ TEST(TOMLMiscellaneousTests, LiteralControlCharsText)
|
||||
// 0080... and higher are treated as unicode character (quotation needed)
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineQuotedText)
|
||||
TEST(Miscellaneous, 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\"\"\"");
|
||||
@@ -799,7 +804,7 @@ TEST(TOMLMiscellaneousTests, MultiLineQuotedText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"ABC-DEF\"\"\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineQuotedSpecialCharsText)
|
||||
TEST(Miscellaneous, 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\"\"\"");
|
||||
@@ -812,7 +817,7 @@ TEST(TOMLMiscellaneousTests, MultiLineQuotedSpecialCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc/\"\"\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineQuotedEscapeCharsText)
|
||||
TEST(Miscellaneous, 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\"\"\"");
|
||||
@@ -826,7 +831,7 @@ TEST(TOMLMiscellaneousTests, MultiLineQuotedEscapeCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::multi_line_quoted_text), "\"\"\"abc\rdef\"\"\"");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineQuotedControlCharsText)
|
||||
TEST(Miscellaneous, 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\"\"\"");
|
||||
@@ -866,7 +871,7 @@ TEST(TOMLMiscellaneousTests, MultiLineQuotedControlCharsText)
|
||||
// 0080... and higher are treated as unicode character (quotation needed)
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineLiteralText)
|
||||
TEST(Miscellaneous, 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'''");
|
||||
@@ -875,7 +880,7 @@ TEST(TOMLMiscellaneousTests, MultiLineLiteralText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("ABC-DEF", toml_parser::EQuoteRequest::multi_line_literal_text), "'''ABC-DEF'''");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineLiteralSpecialCharsText)
|
||||
TEST(Miscellaneous, 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'''");
|
||||
@@ -888,7 +893,7 @@ TEST(TOMLMiscellaneousTests, MultiLineLiteralSpecialCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc/", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc/'''");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineLiteralEscapeCharsText)
|
||||
TEST(Miscellaneous, 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'''");
|
||||
@@ -901,7 +906,7 @@ TEST(TOMLMiscellaneousTests, MultiLineLiteralEscapeCharsText)
|
||||
EXPECT_EQ(toml_parser::QuoteText("abc\rdef", toml_parser::EQuoteRequest::multi_line_literal_text), "'''abc\rdef'''");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, MultiLineLiteralControlCharsText)
|
||||
TEST(Miscellaneous, 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\"\"\"");
|
||||
@@ -942,7 +947,7 @@ TEST(TOMLMiscellaneousTests, MultiLineLiteralControlCharsText)
|
||||
// 0080... and higher are treated as unicode character (quotation needed)
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, ExtractBareKeyName)
|
||||
TEST(Miscellaneous, ExtractBareKeyName)
|
||||
{
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName(""), "");
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("abc.def"), "def");
|
||||
@@ -955,7 +960,7 @@ TEST(TOMLMiscellaneousTests, ExtractBareKeyName)
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("1234"), "1234");
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, ExtractQuotedKeyName)
|
||||
TEST(Miscellaneous, ExtractQuotedKeyName)
|
||||
{
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("\"\""), "");
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("\"abc\""), "abc");
|
||||
@@ -968,7 +973,7 @@ TEST(TOMLMiscellaneousTests, ExtractQuotedKeyName)
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("abc\"def\""), ""); // Failure
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, ExtractLiteralKeyName)
|
||||
TEST(Miscellaneous, ExtractLiteralKeyName)
|
||||
{
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("''"), "");
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("'abc'"), "abc");
|
||||
@@ -982,7 +987,7 @@ TEST(TOMLMiscellaneousTests, ExtractLiteralKeyName)
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("abc'def"), ""); // Failure
|
||||
}
|
||||
|
||||
TEST(TOMLMiscellaneousTests, ExtractIndexKeyName)
|
||||
TEST(Miscellaneous, ExtractIndexKeyName)
|
||||
{
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("[0]"), "0");
|
||||
EXPECT_EQ(toml_parser::ExtractKeyName("[0][1]"), "1");
|
||||
@@ -13,6 +13,7 @@
|
||||
********************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/parser_node_toml.h"
|
||||
|
||||
@@ -444,32 +445,32 @@ TEST(NestedContent, InlineTable)
|
||||
TEST(NestedContent, InlineTableBreakLine)
|
||||
{
|
||||
// The following are not allowed
|
||||
EXPECT_THROW(toml_parser::CParser(R"code(
|
||||
EXPECT_THROW(toml_parser::CParser(R"toml(
|
||||
table = { a = 1, b = 2,
|
||||
c = 3, d = 4 }
|
||||
)code"), sdv::toml::XTOMLParseException);
|
||||
EXPECT_THROW(toml_parser::CParser(R"code(
|
||||
)toml"), sdv::toml::XTOMLParseException);
|
||||
EXPECT_THROW(toml_parser::CParser(R"toml(
|
||||
table = { a = 1, b = 2
|
||||
,c = 3, d = 4 }
|
||||
)code"), sdv::toml::XTOMLParseException);
|
||||
)toml"), sdv::toml::XTOMLParseException);
|
||||
|
||||
// Line breaks are allowed when part of an array or have multi-line strings
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"code(
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"toml(
|
||||
array = [{ a = 1, b = 2},
|
||||
{c = 3, d = 4}]
|
||||
)code"));
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"code(
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"toml(
|
||||
table = { a = 1, b = [2, 3,
|
||||
4, 5], c = 6, d = 7}
|
||||
)code"));
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"code(
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"toml(
|
||||
table = { x = "abc", y = """def-
|
||||
ghi""", z = "jkl" }
|
||||
)code"));
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"code(
|
||||
)toml"));
|
||||
EXPECT_NO_THROW(toml_parser::CParser(R"toml(
|
||||
table = { x = 'abc', y = '''def-
|
||||
ghi''', z = 'jkl' }
|
||||
)code"));
|
||||
)toml"));
|
||||
}
|
||||
|
||||
TEST(SpecialCases, Keys)
|
||||
@@ -865,6 +866,60 @@ TEST(Ordering, TableAray)
|
||||
EXPECT_EQ(ptrArray->Get(uiIndex)->Cast<toml_parser::CTable>()->Direct("a")->GetValue(), (int64_t) uiIndex);
|
||||
}
|
||||
|
||||
TEST(Ordering, TableArayWithTables)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
toml_parser::CParser parser(R"(
|
||||
[topTable]
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 0
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 1
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 2
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 3
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 4
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 5
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 6
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 7
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 8
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 9
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 10
|
||||
[[topTable.tableArray]]
|
||||
[topTable.tableArray.MyTable]
|
||||
a = 11
|
||||
)"s);
|
||||
|
||||
auto tableArray = parser.Root().Direct("topTable.tableArray");
|
||||
|
||||
ASSERT_NE(tableArray, nullptr);
|
||||
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)->Cast<toml_parser::CTable>()->Direct("MyTable.a")->GetValue(), (int64_t)uiIndex);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Ordering, NodeGetDirect)
|
||||
{
|
||||
using namespace std::string_literals;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
#include "../../../global/localmemmgr.h"
|
||||
#include "../../../sdv_services/core/toml_parser/lexer_toml.h"
|
||||
#include "../../../sdv_services/core/toml_parser/exception.h"
|
||||
#include "../../../sdv_services/core/toml_parser/miscellaneous.h"
|
||||
@@ -445,7 +446,7 @@ bool FindAndExtendToken(toml_parser::CLexer& rlexer, const std::string& rssKey,
|
||||
return false; // When coming here, the key was not found
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, CheckEmptyRange)
|
||||
TEST(StatementBoundary, CheckEmptyRange)
|
||||
{
|
||||
std::string ssEmpty;
|
||||
|
||||
@@ -459,11 +460,11 @@ TEST(TOMLLexerStatementBoundaryTests, CheckEmptyRange)
|
||||
EXPECT_THROW(lexerEmpty.SmartExtendNodeRange(rangeEmpty), sdv::toml::XTOMLParseException);
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, CheckInvalidRange)
|
||||
TEST(StatementBoundary, CheckInvalidRange)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_a = 10
|
||||
)code";
|
||||
)toml";
|
||||
std::string ssOther = ssCode;
|
||||
|
||||
// Process the code
|
||||
@@ -477,11 +478,11 @@ token_a = 10
|
||||
EXPECT_THROW(lexerCode.SmartExtendNodeRange(rangeOther), sdv::toml::XTOMLParseException);
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, StandardIntegerAssignment)
|
||||
TEST(StatementBoundary, StandardIntegerAssignment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_a = 10
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -497,11 +498,11 @@ token_a = 10
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, StandardStringAssignment)
|
||||
TEST(StatementBoundary, StandardStringAssignment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_b = "abc"
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -516,16 +517,16 @@ token_b = "abc"
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, AssignmentWithIndependentComment)
|
||||
TEST(StatementBoundary, AssignmentWithIndependentComment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_c = 30.1
|
||||
|
||||
# middle followed by double lines
|
||||
|
||||
|
||||
token_d = "def"
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -541,9 +542,9 @@ token_d = "def"
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, AssignmentCommentsNotPartOfIt)
|
||||
TEST(StatementBoundary, AssignmentCommentsNotPartOfIt)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_c = 30.1
|
||||
|
||||
# middle followed by double lines
|
||||
@@ -554,7 +555,7 @@ token_d = "def"
|
||||
# before
|
||||
# more before
|
||||
token_e = [10, 20, 30]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -570,9 +571,9 @@ token_e = [10, 20, 30]
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, ArrayAssignmentWithPreceedingComment)
|
||||
TEST(StatementBoundary, ArrayAssignmentWithPreceedingComment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_d = "def"
|
||||
|
||||
# before
|
||||
@@ -581,7 +582,7 @@ token_e = [10, 20, 30]
|
||||
|
||||
token_f = "ghi" # after
|
||||
# more after
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -609,14 +610,14 @@ token_f = "ghi" # after
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, AssignmentWithFollowingComment)
|
||||
TEST(StatementBoundary, AssignmentWithFollowingComment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_f = "ghi" # after
|
||||
# more after
|
||||
# belonging to next
|
||||
[token_g]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -636,9 +637,9 @@ token_f = "ghi" # after
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, AssignmentWithFollowingComment2)
|
||||
TEST(StatementBoundary, AssignmentWithFollowingComment2)
|
||||
{
|
||||
std::string ssTOML = R"code(
|
||||
std::string ssTOML = R"toml(
|
||||
|
||||
|
||||
# This is a separate comment with several line-breaks before.
|
||||
@@ -661,7 +662,7 @@ value = "this is the value text" # Comment following the value.
|
||||
# This is also a separate comment.
|
||||
# Followed by this text on the same line.
|
||||
|
||||
# And another text on a separate line.)code";
|
||||
# And another text on a separate line.)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssTOML);
|
||||
@@ -701,15 +702,15 @@ value = "this is the value text" # Comment following the value.
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, TableAssignmentWithDedicatedComment)
|
||||
TEST(StatementBoundary, TableAssignmentWithDedicatedComment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_f = "ghi" # after
|
||||
# more after
|
||||
# belonging to next
|
||||
[token_g]
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -725,14 +726,14 @@ token_f = "ghi" # after
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, AssignmentWithFollowingCommentWithoutIndentation)
|
||||
TEST(StatementBoundary, AssignmentWithFollowingCommentWithoutIndentation)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_h = "jkl"#after without whitespace
|
||||
# more after due to following empty line
|
||||
|
||||
[token_i]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -751,16 +752,16 @@ token_h = "jkl"#after without whitespace
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, AssignmentCommentsExcluded)
|
||||
TEST(StatementBoundary, AssignmentCommentsExcluded)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_h = "jkl"#after without whitespace
|
||||
# more after due to following empty line
|
||||
|
||||
[token_i]
|
||||
# not after
|
||||
token_j = 20
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -773,13 +774,13 @@ token_j = 20
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, SmartExtendTokenRange)
|
||||
TEST(StatementBoundary, SmartExtendTokenRange)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
[token_i]
|
||||
# not after
|
||||
token_j = 20
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -796,12 +797,12 @@ token_j = 20
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, StandardAssignmentWithIndentation)
|
||||
TEST(StatementBoundary, StandardAssignmentWithIndentation)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_k = 30
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -818,11 +819,11 @@ TEST(TOMLLexerStatementBoundaryTests, StandardAssignmentWithIndentation)
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, ArrayOfStringsAssignment)
|
||||
TEST(StatementBoundary, ArrayOfStringsAssignment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_l = ["abc", "def", "ghi"]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -846,16 +847,16 @@ TEST(TOMLLexerStatementBoundaryTests, ArrayOfStringsAssignment)
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, InlineTableAssignmentWithIndependentComment)
|
||||
TEST(StatementBoundary, InlineTableAssignmentWithIndependentComment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_m = {x = 10, str = "gfh"}
|
||||
|
||||
# middle followed by double newlines
|
||||
|
||||
|
||||
token_n = 100
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -885,9 +886,9 @@ TEST(TOMLLexerStatementBoundaryTests, InlineTableAssignmentWithIndependentCommen
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentNoComments)
|
||||
TEST(StatementBoundary, IndentedAssignmentNoComments)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
# begin followed by double newlines
|
||||
|
||||
|
||||
@@ -896,7 +897,7 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentNoComments)
|
||||
# before
|
||||
# more before
|
||||
token_o = 123.456
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -913,15 +914,15 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentNoComments)
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentWithCommentsBefore)
|
||||
TEST(StatementBoundary, IndentedAssignmentWithCommentsBefore)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
|
||||
# before
|
||||
# more before
|
||||
token_o = 123.456
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -944,15 +945,15 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentWithCommentsBefore)
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedBooleanArrayAssignmentWithDedicatedComments)
|
||||
TEST(StatementBoundary, IndentedBooleanArrayAssignmentWithDedicatedComments)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
|
||||
token_p = [true, false] # after
|
||||
# more after
|
||||
# belonging to next
|
||||
token_q = "next"
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -978,15 +979,15 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedBooleanArrayAssignmentWithDedicate
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentWithDedicatedCommentsBefore)
|
||||
TEST(StatementBoundary, IndentedAssignmentWithDedicatedCommentsBefore)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_p = [true, false] # after
|
||||
# more after
|
||||
# belonging to next
|
||||
token_q = "next"
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -1006,14 +1007,14 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentWithDedicatedCommentsBef
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentFollowedByCommentWithoutSpace)
|
||||
TEST(StatementBoundary, IndentedAssignmentFollowedByCommentWithoutSpace)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
token_r =987#after without whitespace
|
||||
# more after due to following empty line
|
||||
|
||||
[token_s]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -1033,13 +1034,13 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedAssignmentFollowedByCommentWithout
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedTableWithoutComments)
|
||||
TEST(StatementBoundary, IndentedTableWithoutComments)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
[token_s]
|
||||
# not after
|
||||
[token_t]
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -1053,16 +1054,16 @@ TEST(TOMLLexerStatementBoundaryTests, IndentedTableWithoutComments)
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, IndentedTableWithAndWithoutComments)
|
||||
TEST(StatementBoundary, IndentedTableWithAndWithoutComments)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
[token_s]
|
||||
# not after
|
||||
[token_t]
|
||||
|
||||
# comment before a table member (belongs to token_bb)
|
||||
token_u.token_aa.token_bb = 10 # table token_u has a table token_aa which has a value token_bb
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -1080,12 +1081,12 @@ token_u.token_aa.token_bb = 10 # table token_u has a table token_aa which ha
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, InlineTableWithParentChildAssignment)
|
||||
TEST(StatementBoundary, InlineTableWithParentChildAssignment)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
# comment before a table member (belongs to token_bb)
|
||||
token_u.token_aa.token_bb = 10 # table token_u has a table token_aa which has a value token_bb
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -1116,9 +1117,9 @@ token_u.token_aa.token_bb = 10 # table token_u has a table token_aa which ha
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, ComplexInlineTableWithParentChildAssignmentOfTablesAndMultiDimensionalArrays)
|
||||
TEST(StatementBoundary, ComplexInlineTableWithParentChildAssignmentOfTablesAndMultiDimensionalArrays)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
# Super inline table with sub-tables and arrays
|
||||
token_u.token_aa.token_cc = { dd = { ee = 10, ff = 11 }, # this is the comment for dd
|
||||
gg = [{hh = 1, ii = 2},
|
||||
@@ -1128,7 +1129,7 @@ token_u.token_aa.token_cc = { dd = { ee = 10, ff = 11 }, # this is the commen
|
||||
# and this as well
|
||||
jj = [["abc", "def"], [1, 2, 3], []]}
|
||||
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// NOTE EVE 22.10.2025: the value token_u.token_aa.token_cc.jj is the last value in the table. This means that the scope of
|
||||
// the value included the comma before the value jj (following value gg). This has the consequence, that the comments, which
|
||||
@@ -1292,9 +1293,9 @@ token_u.token_aa.token_cc = { dd = { ee = 10, ff = 11 }, # this is the commen
|
||||
toml_parser::ETokenCategory::token_syntax_array_close}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, ArrayOfTables)
|
||||
TEST(StatementBoundary, ArrayOfTables)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
[[token_v]]
|
||||
token_kk = 10
|
||||
token_ll = 20
|
||||
@@ -1303,7 +1304,7 @@ token_mm = 30
|
||||
[[token_v]]
|
||||
token_kk = 110
|
||||
token_ll = 120
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
@@ -1316,15 +1317,15 @@ token_ll = 120
|
||||
toml_parser::ETokenCategory::token_syntax_new_line}));
|
||||
}
|
||||
|
||||
TEST(TOMLLexerStatementBoundaryTests, ParentChildTable)
|
||||
TEST(StatementBoundary, ParentChildTable)
|
||||
{
|
||||
std::string ssCode = R"code(
|
||||
std::string ssCode = R"toml(
|
||||
[[token_v]]
|
||||
token_kk = 110
|
||||
token_ll = 120
|
||||
# Comments before (belongs ot child only)
|
||||
[token_x.token_nn] # Comments following (belongs to child only)
|
||||
)code";
|
||||
)toml";
|
||||
|
||||
// Process the code
|
||||
toml_parser::CLexer lexerCode(ssCode);
|
||||
|
||||
@@ -417,7 +417,7 @@ TEST(TraceFifoTest, Simple_Stream_Monitor)
|
||||
{
|
||||
std::stringstream sstreamWriter;
|
||||
CTraceFifoStreamBuffer fifoWriterStreamBuf(9999);
|
||||
fifoWriterStreamBuf.Open(1000, static_cast<uint32_t>(ETraceFifoOpenFlags::force_create));
|
||||
fifoWriterStreamBuf.Open(5000, static_cast<uint32_t>(ETraceFifoOpenFlags::force_create));
|
||||
EXPECT_TRUE(fifoWriterStreamBuf.IsOpened());
|
||||
fifoWriterStreamBuf.InterceptStream(sstreamWriter);
|
||||
CTraceFifoReader fifoReader(9999);
|
||||
|
||||
41
tests/unit_tests/unique_id/CMakeLists.txt
Normal file
41
tests/unit_tests/unique_id/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
#*******************************************************************************
|
||||
# Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Apache License Version 2.0 which is available at
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Erik Verhoeven - initial API and implementation
|
||||
#*******************************************************************************
|
||||
|
||||
# Define project
|
||||
project(UniqueIDTests VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Define target
|
||||
add_executable(UnitTest_UniqueID unique_id_test.cpp)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_libraries(UnitTest_UniqueID GTest::GTest)
|
||||
if (WIN32)
|
||||
target_link_libraries(UnitTest_UniqueID Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(UnitTest_UniqueID ${CMAKE_DL_LIBS} rt)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(UnitTest_UniqueID GTest::GTest Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# Add the test
|
||||
add_test(NAME UnitTest_UniqueID COMMAND UnitTest_UniqueID WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Execute the test
|
||||
add_custom_command(TARGET UnitTest_UniqueID POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_UniqueID>" --gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_UniqueID.xml
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# The unit-test project depends on a proper compilation of sdv components before
|
||||
add_dependencies(UnitTest_UniqueID dependency_sdv_components)
|
||||
85
tests/unit_tests/unique_id/unique_id_test.cpp
Normal file
85
tests/unit_tests/unique_id/unique_id_test.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Erik Verhoeven - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include <fstream>
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../../global/process_watchdog.h"
|
||||
#include "../../../global/unique_id.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int argc, wchar_t* argv[])
|
||||
#else
|
||||
extern "C" int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TEST(UniqueID, TestSmallID)
|
||||
{
|
||||
CUniqueID<int, 4> generator;
|
||||
|
||||
// Max 15 ids possible
|
||||
std::set<int> setUsed;
|
||||
int iNumber;
|
||||
for (size_t n = 0; n < 15; n++)
|
||||
{
|
||||
iNumber = generator.Generate();
|
||||
EXPECT_NE(iNumber, 0);
|
||||
EXPECT_EQ(setUsed.find(iNumber), setUsed.end());
|
||||
setUsed.insert(iNumber);
|
||||
}
|
||||
|
||||
// One more ID should fail
|
||||
iNumber = generator.Generate();
|
||||
EXPECT_EQ(iNumber, 0);
|
||||
}
|
||||
|
||||
TEST(UniqueID, TestSmallID2)
|
||||
{
|
||||
CUniqueID<uint8_t> generator;
|
||||
|
||||
// Max 255 ids possible
|
||||
std::set<uint32_t> setUsed;
|
||||
uint32_t uiNumber = 0;
|
||||
for (size_t n = 0; n < 255; n++)
|
||||
{
|
||||
uiNumber = generator.Generate();
|
||||
EXPECT_NE(uiNumber, 0u);
|
||||
EXPECT_EQ(setUsed.find(uiNumber), setUsed.end());
|
||||
setUsed.insert(uiNumber);
|
||||
}
|
||||
|
||||
// One more ID should fail
|
||||
uiNumber = generator.Generate();
|
||||
EXPECT_EQ(uiNumber, 0u);
|
||||
}
|
||||
|
||||
TEST(UniqueID, TestLargeID)
|
||||
{
|
||||
CUniqueID<uint64_t> generator;
|
||||
|
||||
// Run at the most 20000 times and check whether the number occurs multiple times
|
||||
std::set<uint64_t> setUsed;
|
||||
uint64_t uiNumber;
|
||||
for (size_t n = 0; n < 20000; n++)
|
||||
{
|
||||
uiNumber = generator.Generate();
|
||||
EXPECT_NE(uiNumber, 0u);
|
||||
EXPECT_EQ(setUsed.find(uiNumber), setUsed.end());
|
||||
setUsed.insert(uiNumber);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
stdc++fs ${CMAKE_DL_LIBS}
|
||||
rt
|
||||
uds_unix_sockets
|
||||
uds_unix_sockets_static
|
||||
)
|
||||
else()
|
||||
target_link_libraries(UnitTest_UnixSocketConnectTests
|
||||
@@ -41,7 +41,7 @@ else()
|
||||
Ws2_32
|
||||
Winmm
|
||||
Rpcrt4.lib
|
||||
uds_unix_sockets
|
||||
uds_unix_sockets_static
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -50,13 +50,11 @@ add_test(NAME UnitTest_UnixSocketConnectTests
|
||||
|
||||
add_dependencies(UnitTest_UnixSocketConnectTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_UnixSocketConnectTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_UnixSocketConnectTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_UnixSocketConnectTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -204,6 +204,25 @@ private:
|
||||
// Small helper: convert server connectString to client connectString
|
||||
static std::string MakeClientCS(std::string cs)
|
||||
{
|
||||
const std::string providerKey = "ConnectString = \"";
|
||||
auto p = cs.find(providerKey);
|
||||
if (p != std::string::npos)
|
||||
{
|
||||
p += providerKey.size();
|
||||
auto e = cs.find('"', p);
|
||||
if (e != std::string::npos)
|
||||
{
|
||||
std::string inner = cs.substr(p, e - p);
|
||||
const std::string fromIn = "role=server";
|
||||
const std::string toIn = "role=client";
|
||||
auto posIn = inner.find(fromIn);
|
||||
if (posIn != std::string::npos)
|
||||
inner.replace(posIn, fromIn.size(), toIn);
|
||||
cs.replace(p, e - p, inner);
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string from = "role=server";
|
||||
const std::string to = "role=client";
|
||||
auto pos = cs.find(from);
|
||||
@@ -215,6 +234,27 @@ static std::string MakeClientCS(std::string cs)
|
||||
|
||||
static std::string ExtractPathFromCS(const std::string& cs)
|
||||
{
|
||||
const std::string providerKey = "ConnectString = \"";
|
||||
auto pProvider = cs.find(providerKey);
|
||||
if (pProvider != std::string::npos)
|
||||
{
|
||||
pProvider += providerKey.size();
|
||||
auto eProvider = cs.find('"', pProvider);
|
||||
if (eProvider != std::string::npos)
|
||||
{
|
||||
std::string inner = cs.substr(pProvider, eProvider - pProvider);
|
||||
const std::string keyInner = "path=";
|
||||
auto pInner = inner.find(keyInner);
|
||||
if (pInner != std::string::npos)
|
||||
{
|
||||
auto startInner = pInner + keyInner.size();
|
||||
auto endInner = inner.find(';', startInner);
|
||||
if (endInner == std::string::npos) endInner = inner.size();
|
||||
return inner.substr(startInner, endInner - startInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search "path=" in connect-string
|
||||
const std::string key = "path=";
|
||||
auto p = cs.find(key);
|
||||
@@ -225,6 +265,21 @@ static std::string ExtractPathFromCS(const std::string& cs)
|
||||
return cs.substr(start, end - start);
|
||||
}
|
||||
|
||||
static std::string MakeServerCS(const std::string& cs)
|
||||
{
|
||||
const std::string path = ExtractPathFromCS(cs);
|
||||
if (!path.empty())
|
||||
return "proto=uds;role=server;path=" + path + ";";
|
||||
|
||||
std::string raw = cs;
|
||||
const std::string from = "role=client";
|
||||
const std::string to = "role=server";
|
||||
auto pos = raw.find(from);
|
||||
if (pos != std::string::npos)
|
||||
raw.replace(pos, from.size(), to);
|
||||
return raw;
|
||||
}
|
||||
|
||||
static std::string MakeRandomSuffix()
|
||||
{
|
||||
std::mt19937_64 rng{std::random_device{}()};
|
||||
@@ -241,7 +296,7 @@ TEST(UnixSocketIPC, Instantiate)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
@@ -258,7 +313,7 @@ TEST(UnixSocketIPC, ChannelConfigString)
|
||||
ASSERT_TRUE(appcontrol.Startup(""));
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
@@ -275,7 +330,7 @@ TEST(UnixSocketIPC, CreateRandomEndpoint)
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
|
||||
// Create an endpoint.
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
sdv::ipc::SChannelEndpoint sChannelEndpoint = mgr.CreateEndpoint("");
|
||||
EXPECT_NE(sChannelEndpoint.pConnection, nullptr);
|
||||
@@ -297,7 +352,7 @@ TEST(UnixSocketIPC, BasicConnectDisconnect)
|
||||
|
||||
// Create and initialize UDS manager
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
@@ -305,7 +360,7 @@ TEST(UnixSocketIPC, BasicConnectDisconnect)
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
std::string serverCS = ep.ssConnectString;
|
||||
std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
// SERVER SIDE
|
||||
@@ -321,7 +376,7 @@ TEST(UnixSocketIPC, BasicConnectDisconnect)
|
||||
// CLIENT SIDE (thread)
|
||||
std::atomic<int> clientResult{0};
|
||||
std::atomic<bool> allowClientDisconnect{false};
|
||||
std::thread clientThread([&]{
|
||||
sdv::core::secure_thread clientThread([&]{
|
||||
sdv::TObjectPtr clientObj = mgr.Access(clientCS);
|
||||
if (!clientObj) { clientResult = 1; return; }
|
||||
auto* clientConn = clientObj.GetInterface<sdv::ipc::IConnect>();
|
||||
@@ -354,6 +409,9 @@ TEST(UnixSocketIPC, BasicConnectDisconnect)
|
||||
serverConn->Disconnect();
|
||||
EXPECT_EQ(serverConn->GetConnectState(), sdv::ipc::EConnectState::disconnected);
|
||||
|
||||
// Release object wrappers before shutting down the manager/framework.
|
||||
serverObj.Clear();
|
||||
|
||||
// Shutdown Manager / Framework
|
||||
EXPECT_NO_THROW(mgr.Shutdown());
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
@@ -372,7 +430,7 @@ TEST(UnixSocketIPC, ReconnectAfterDisconnect_SamePath)
|
||||
|
||||
//UDS manager
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
@@ -380,7 +438,7 @@ TEST(UnixSocketIPC, ReconnectAfterDisconnect_SamePath)
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
// SESSION 1
|
||||
@@ -397,7 +455,7 @@ TEST(UnixSocketIPC, ReconnectAfterDisconnect_SamePath)
|
||||
std::atomic<int> clientResult{0};
|
||||
std::atomic<bool> allowClientDisconnect{false};
|
||||
|
||||
std::thread clientThread([&]{
|
||||
sdv::core::secure_thread clientThread([&]{
|
||||
sdv::TObjectPtr clientObj = mgr.Access(clientCS);
|
||||
if (!clientObj) { clientResult = 1; return; }
|
||||
auto* clientConn = clientObj.GetInterface<sdv::ipc::IConnect>();
|
||||
@@ -444,7 +502,7 @@ TEST(UnixSocketIPC, ReconnectAfterDisconnect_SamePath)
|
||||
std::atomic<int> clientResult2{0};
|
||||
std::atomic<bool> allowClientDisconnect2{false};
|
||||
|
||||
std::thread clientThread2([&]{
|
||||
sdv::core::secure_thread clientThread2([&]{
|
||||
sdv::TObjectPtr clientObj2 = mgr.Access(clientCS);
|
||||
if (!clientObj2) { clientResult2 = 1; return; }
|
||||
auto* clientConn2 = clientObj2.GetInterface<sdv::ipc::IConnect>();
|
||||
@@ -490,7 +548,7 @@ TEST(UnixSocketIPC, OperationModeTransitions)
|
||||
sdv::app::CAppControl app;
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
// configuring and then running
|
||||
@@ -514,7 +572,7 @@ TEST(UnixSocketIPC, CreateEndpoint_WithConfigAndPathClamping)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
@@ -531,7 +589,7 @@ TEST(UnixSocketIPC, CreateEndpoint_WithConfigAndPathClamping)
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
// Checking if endpoint is server type and has an ok path
|
||||
std::string serverCS = ep.ssConnectString;
|
||||
std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
std::string clientCS = MakeClientCS(serverCS);
|
||||
auto clampedPath = ExtractPathFromCS(serverCS);
|
||||
ASSERT_FALSE(clampedPath.empty());
|
||||
@@ -572,7 +630,7 @@ TEST(UnixSocketIPC, Access_DefaultPath_ServerClientConnect)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
@@ -613,13 +671,13 @@ TEST(UnixSocketIPC, WaitForConnection_InfiniteWait_SlowClient)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -629,7 +687,7 @@ TEST(UnixSocketIPC, WaitForConnection_InfiniteWait_SlowClient)
|
||||
CUDSConnectReceiver sRcvr;
|
||||
ASSERT_TRUE(serverConn->AsyncConnect(&sRcvr));
|
||||
|
||||
std::thread delayedClient([&]{
|
||||
sdv::core::secure_thread delayedClient([&]{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
sdv::TObjectPtr clientObj = mgr.Access(clientCS);
|
||||
auto* clientConn = clientObj.GetInterface<sdv::ipc::IConnect>();
|
||||
@@ -658,13 +716,13 @@ TEST(UnixSocketIPC, WaitForConnection_ZeroTimeout_BeforeAndAfter)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -700,7 +758,7 @@ ViewFilter = "Fatal")toml"));
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
@@ -734,12 +792,12 @@ TEST(UnixSocketIPC, ServerDisconnectPropagatesToClient)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -776,12 +834,12 @@ TEST(UnixSocketIPC, ReconnectOnSameServerInstance)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -827,14 +885,14 @@ TEST(UnixSocketIPC, DataPath_SimpleHello)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
// Endpoint
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
// Server
|
||||
@@ -894,13 +952,13 @@ TEST(UnixSocketIPC, DataPath_MultiChunk_TwoBuffers)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -955,14 +1013,14 @@ TEST(UnixSocketIPC, DataPath_LargePayload_Fragmentation_Reassembly)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
app.SetRunningMode();
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
// Endpoint
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
// Server
|
||||
@@ -1023,12 +1081,12 @@ TEST(UnixSocketIPC, DataPath_ZeroLengthChunks_ArePreserved)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
app.SetRunningMode();
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -1086,12 +1144,12 @@ TEST(UnixSocketIPC, PeerCloseMidTransfer_ClientSeesDisconnected_AndSendMayFailOr
|
||||
app.SetRunningMode();
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
|
||||
ASSERT_NO_THROW(mgr.Initialize(""));
|
||||
ASSERT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
ASSERT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -1119,7 +1177,7 @@ TEST(UnixSocketIPC, PeerCloseMidTransfer_ClientSeesDisconnected_AndSendMayFailOr
|
||||
ASSERT_NE(pSend, nullptr);
|
||||
|
||||
std::atomic<bool> sendResult{true};
|
||||
std::thread t([&]{
|
||||
sdv::core::secure_thread t([&]{
|
||||
sendResult.store(pSend->SendData(seq));
|
||||
});
|
||||
|
||||
@@ -1148,7 +1206,7 @@ TEST(UnixSocketIPC, ClientCancelConnect_NoServer_CleansUpPromptly)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
app.SetRunningMode();
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
@@ -1181,12 +1239,12 @@ TEST(UnixSocketIPC, ServerStartThenImmediateDisconnect_NoClient)
|
||||
ViewFilter = "Fatal")toml"));
|
||||
app.SetRunningMode();
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
ASSERT_TRUE(serverObj);
|
||||
@@ -1212,12 +1270,12 @@ TEST(UnixSocketIPC, CallbackThrowsInSetConnectState_DoesNotCrashTransport)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
app.SetRunningMode();
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -1253,13 +1311,13 @@ TEST(UnixSocketIPC, RegisterStateEventCallback_MultipleCallbacksReceiveState)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
ASSERT_NO_THROW(mgr.Initialize(""));
|
||||
ASSERT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
ASSERT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
// --- Setup server endpoint ---
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
@@ -1312,13 +1370,13 @@ TEST(UnixSocketIPC, UnregisterStateEventCallback_RemovedListenerStopsReceiving)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
ASSERT_NO_THROW(mgr.Initialize(""));
|
||||
ASSERT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
ASSERT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
// Endpoint
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
// Server
|
||||
@@ -1376,4 +1434,60 @@ TEST(UnixSocketIPC, UnregisterStateEventCallback_RemovedListenerStopsReceiving)
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
// Reconnect race regression: a second AsyncConnect while connect worker is still initializing
|
||||
// must return quickly and must not deadlock by joining an in-progress worker.
|
||||
TEST(UnixSocketIPC, AsyncConnect_DoubleCallWhileInitializing_NoDeadlock)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixDomainSocketsChannelMgnt mgr;
|
||||
ASSERT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
ASSERT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
const std::string serverCS = MakeServerCS(ep.ssConnectString);
|
||||
const std::string clientCS = MakeClientCS(serverCS);
|
||||
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
ASSERT_TRUE(serverObj);
|
||||
auto* serverConn = serverObj.GetInterface<sdv::ipc::IConnect>();
|
||||
ASSERT_NE(serverConn, nullptr);
|
||||
|
||||
sdv::TObjectPtr clientObj = mgr.Access(clientCS);
|
||||
ASSERT_TRUE(clientObj);
|
||||
auto* clientConn = clientObj.GetInterface<sdv::ipc::IConnect>();
|
||||
ASSERT_NE(clientConn, nullptr);
|
||||
|
||||
CUDSConnectReceiver sRcvr;
|
||||
CUDSConnectReceiver cRcvr;
|
||||
|
||||
ASSERT_TRUE(serverConn->AsyncConnect(&sRcvr));
|
||||
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
bool secondAsync = serverConn->AsyncConnect(&sRcvr);
|
||||
auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - t0).count();
|
||||
|
||||
EXPECT_FALSE(secondAsync);
|
||||
EXPECT_LT(elapsedMs, 200);
|
||||
|
||||
ASSERT_TRUE(clientConn->AsyncConnect(&cRcvr));
|
||||
EXPECT_TRUE(serverConn->WaitForConnection(5000));
|
||||
EXPECT_TRUE(clientConn->WaitForConnection(5000));
|
||||
|
||||
// Once connected, repeated AsyncConnect should be a no-op success.
|
||||
EXPECT_TRUE(serverConn->AsyncConnect(&sRcvr));
|
||||
|
||||
clientConn->Disconnect();
|
||||
serverConn->Disconnect();
|
||||
|
||||
EXPECT_NO_THROW(mgr.Shutdown());
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
#endif // defined __unix__
|
||||
@@ -35,7 +35,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
${CMAKE_DL_LIBS}
|
||||
rt
|
||||
uds_unix_tunnel
|
||||
uds_unix_sockets
|
||||
uds_unix_sockets_static
|
||||
)
|
||||
else()
|
||||
target_link_libraries(UnitTest_UnixTunnelConnectTests
|
||||
@@ -43,7 +43,7 @@ else()
|
||||
Ws2_32 Winmm
|
||||
Rpcrt4.lib
|
||||
uds_unix_tunnel
|
||||
uds_unix_sockets
|
||||
uds_unix_sockets_static
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -52,14 +52,12 @@ add_test(NAME UnitTest_UnixTunnelConnectTests
|
||||
|
||||
add_dependencies(UnitTest_UnixTunnelConnectTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_UnixTunnelConnectTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_UnixTunnelConnectTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_UnixTunnelConnectTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(UnitTest_UnixTunnelChannelMgntTests
|
||||
unix_tunnel_channel_mgnt_tests.cpp
|
||||
@@ -77,7 +75,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
${CMAKE_DL_LIBS}
|
||||
rt
|
||||
uds_unix_tunnel
|
||||
uds_unix_sockets
|
||||
uds_unix_sockets_static
|
||||
)
|
||||
else()
|
||||
target_link_libraries(UnitTest_UnixTunnelChannelMgntTests
|
||||
@@ -86,7 +84,7 @@ else()
|
||||
Winmm
|
||||
Rpcrt4.lib
|
||||
uds_unix_tunnel
|
||||
uds_unix_sockets
|
||||
uds_unix_sockets_static
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -95,13 +93,11 @@ add_test(NAME UnitTest_UnixTunnelChannelMgntTests
|
||||
|
||||
add_dependencies(UnitTest_UnixTunnelChannelMgntTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_UnixTunnelChannelMgntTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_UnixTunnelChannelMgntTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_UnixTunnelChannelMgntTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -12,6 +12,10 @@
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <filesystem>
|
||||
#include <random>
|
||||
|
||||
#include "../sdv_services/uds_unix_tunnel/channel_mgnt.h"
|
||||
#include "../sdv_services/uds_unix_tunnel/connection.h"
|
||||
@@ -81,6 +85,109 @@ private:
|
||||
sdv::sequence<sdv::pointer<uint8_t>> m_lastData;
|
||||
bool m_received{ false };
|
||||
};
|
||||
// Helper namespace
|
||||
namespace tunnel_utils
|
||||
{
|
||||
|
||||
inline std::string Expand(const std::string& in)
|
||||
{
|
||||
// Simple expand for $HOME / $TMPDIR etc.
|
||||
std::string out = in;
|
||||
|
||||
auto replace_env = [&](const std::string& key, const char* env)
|
||||
{
|
||||
const char* val = std::getenv(env);
|
||||
if (!val) return;
|
||||
|
||||
auto pos = out.find(key);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
out.replace(pos, key.size(), val);
|
||||
}
|
||||
};
|
||||
|
||||
replace_env("$HOME", "HOME");
|
||||
replace_env("$TMPDIR", "TMPDIR");
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
inline void EnsureParentDir(const std::string& full)
|
||||
{
|
||||
auto p = full.find_last_of('/');
|
||||
if (p == std::string::npos)
|
||||
return;
|
||||
|
||||
std::filesystem::create_directories(full.substr(0, p));
|
||||
}
|
||||
|
||||
inline std::string MakeShortUdsPath(const char* name)
|
||||
{
|
||||
std::string base = "/tmp/sdv/";
|
||||
|
||||
EnsureParentDir(base);
|
||||
|
||||
return base + name;
|
||||
}
|
||||
|
||||
inline std::string RandomHex()
|
||||
{
|
||||
std::mt19937_64 r{std::random_device{}()};
|
||||
std::uniform_int_distribution<uint64_t> d;
|
||||
std::ostringstream oss;
|
||||
oss << std::hex << d(r);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
inline std::string Unique(const char* prefix)
|
||||
{
|
||||
return MakeShortUdsPath((std::string(prefix) + "_" + RandomHex() + ".sock").c_str());
|
||||
}
|
||||
|
||||
inline std::string UniqueTunnel()
|
||||
{
|
||||
return "t_" + RandomHex();
|
||||
}
|
||||
|
||||
inline void SpinUntilServerArmed(sdv::ipc::IConnect* server)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
const auto deadline = steady_clock::now() + milliseconds(500);
|
||||
while (server->GetConnectState() == sdv::ipc::EConnectState::uninitialized &&
|
||||
steady_clock::now() < deadline)
|
||||
{
|
||||
std::this_thread::sleep_for(milliseconds(2));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tunnel_utils
|
||||
|
||||
using namespace tunnel_utils;
|
||||
|
||||
struct EndpointClientPair
|
||||
{
|
||||
sdv::ipc::IConnect* server = nullptr; // from ep.pConnection
|
||||
sdv::TObjectPtr clientObj;
|
||||
sdv::ipc::IConnect* client = nullptr;
|
||||
};
|
||||
|
||||
static EndpointClientPair CreateEndpointClientPair(
|
||||
CUnixTunnelChannelMgnt& mgr,
|
||||
const sdv::ipc::SChannelEndpoint& ep)
|
||||
{
|
||||
EndpointClientPair out;
|
||||
|
||||
out.server = ep.pConnection
|
||||
? ep.pConnection->GetInterface<sdv::ipc::IConnect>()
|
||||
: nullptr;
|
||||
|
||||
out.clientObj = mgr.Access(ep.ssConnectString);
|
||||
out.client = out.clientObj
|
||||
? out.clientObj.GetInterface<sdv::ipc::IConnect>()
|
||||
: nullptr;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
//Manager instantiate + lifecycle
|
||||
TEST(UnixTunnelChannelMgnt, InstantiateAndLifecycle)
|
||||
@@ -89,7 +196,7 @@ TEST(UnixTunnelChannelMgnt, InstantiateAndLifecycle)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
CUnixTunnelChannelMgnt mgr;
|
||||
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::configuring));
|
||||
@@ -105,6 +212,7 @@ TEST(UnixTunnelChannelMgnt, InstantiateAndLifecycle)
|
||||
}
|
||||
|
||||
// CreateEndpoint -> Access(server/client) -> AsyncConnect -> Wait -> Disconnect
|
||||
|
||||
TEST(UnixTunnelChannelMgnt, BasicConnectDisconnect)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
@@ -112,63 +220,41 @@ TEST(UnixTunnelChannelMgnt, BasicConnectDisconnect)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixTunnelChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
// Create a tunnel endpoint (server)
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
ASSERT_NE(ep.pConnection, nullptr);
|
||||
const std::string tunnel = "t_" + RandomHex();
|
||||
const std::string cs =
|
||||
"proto=tunnel;path=" + Unique("tunnel_mgr_basic") +
|
||||
";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
// Convert to client by role=client
|
||||
std::string clientCS = serverCS;
|
||||
{
|
||||
const std::string from = "role=server";
|
||||
const std::string to = "role=client";
|
||||
auto pos = clientCS.find(from);
|
||||
if (pos != std::string::npos)
|
||||
clientCS.replace(pos, from.size(), to);
|
||||
}
|
||||
auto pair = CreateEndpointClientPair(mgr, ep);
|
||||
|
||||
// SERVER
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
ASSERT_TRUE(serverObj);
|
||||
auto* serverConn = serverObj.GetInterface<sdv::ipc::IConnect>();
|
||||
ASSERT_NE(serverConn, nullptr);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
CTunnelMgrTestReceiver sRcvr;
|
||||
ASSERT_TRUE(serverConn->AsyncConnect(&sRcvr));
|
||||
CTunnelMgrTestReceiver sr, cr;
|
||||
|
||||
// CLIENT (thread)
|
||||
std::atomic<int> clientResult{0};
|
||||
std::thread clientThread([&]{
|
||||
sdv::TObjectPtr clientObj = mgr.Access(clientCS);
|
||||
if (!clientObj) { clientResult = 1; return; }
|
||||
auto* clientConn = clientObj.GetInterface<sdv::ipc::IConnect>();
|
||||
if (!clientConn) { clientResult = 2; return; }
|
||||
CTunnelMgrTestReceiver cRcvr;
|
||||
if (!clientConn->AsyncConnect(&cRcvr)) { clientResult = 3; return; }
|
||||
if (!clientConn->WaitForConnection(5000)) { clientResult = 4; return; }
|
||||
if (clientConn->GetConnectState() != sdv::ipc::EConnectState::connected) { clientResult = 5; return; }
|
||||
clientConn->Disconnect();
|
||||
clientResult = 0;
|
||||
});
|
||||
pair.server->AsyncConnect(&sr);
|
||||
SpinUntilServerArmed(pair.server);
|
||||
|
||||
EXPECT_TRUE(serverConn->WaitForConnection(5000));
|
||||
EXPECT_EQ(serverConn->GetConnectState(), sdv::ipc::EConnectState::connected);
|
||||
pair.client->AsyncConnect(&cr);
|
||||
|
||||
clientThread.join();
|
||||
EXPECT_EQ(clientResult.load(), 0);
|
||||
EXPECT_TRUE(pair.server->WaitForConnection(5000));
|
||||
EXPECT_TRUE(pair.client->WaitForConnection(5000));
|
||||
|
||||
serverConn->Disconnect();
|
||||
pair.client->Disconnect();
|
||||
pair.server->Disconnect();
|
||||
|
||||
EXPECT_NO_THROW(mgr.Shutdown());
|
||||
mgr.Shutdown();
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
// Data path: "hello" via channel manager (using proto=tunnel)
|
||||
// Simple hello (header stripped)
|
||||
TEST(UnixTunnelChannelMgnt, DataPath_SimpleHello_ViaManager)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
@@ -176,65 +262,57 @@ TEST(UnixTunnelChannelMgnt, DataPath_SimpleHello_ViaManager)
|
||||
app.SetRunningMode();
|
||||
|
||||
CUnixTunnelChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.SetOperationMode(sdv::EOperationMode::running));
|
||||
ASSERT_EQ(mgr.GetObjectState(), sdv::EObjectState::running);
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
auto ep = mgr.CreateEndpoint("");
|
||||
const std::string tunnel = "t_" + RandomHex();
|
||||
const std::string cs =
|
||||
"proto=tunnel;path=" + Unique("hello_mgr") +
|
||||
";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
const std::string serverCS = ep.ssConnectString;
|
||||
|
||||
std::string clientCS = serverCS;
|
||||
{
|
||||
const std::string from = "role=server";
|
||||
const std::string to = "role=client";
|
||||
auto pos = clientCS.find(from);
|
||||
if (pos != std::string::npos)
|
||||
clientCS.replace(pos, from.size(), to);
|
||||
}
|
||||
auto pair = CreateEndpointClientPair(mgr, ep);
|
||||
|
||||
// Server
|
||||
sdv::TObjectPtr serverObj = mgr.Access(serverCS);
|
||||
ASSERT_TRUE(serverObj);
|
||||
auto* serverConn = serverObj.GetInterface<sdv::ipc::IConnect>();
|
||||
ASSERT_NE(serverConn, nullptr);
|
||||
CTunnelMgrTestReceiver sRcvr;
|
||||
ASSERT_TRUE(serverConn->AsyncConnect(&sRcvr));
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
// Client
|
||||
sdv::TObjectPtr clientObj = mgr.Access(clientCS);
|
||||
ASSERT_TRUE(clientObj);
|
||||
auto* clientConn = clientObj.GetInterface<sdv::ipc::IConnect>();
|
||||
ASSERT_NE(clientConn, nullptr);
|
||||
CTunnelMgrTestReceiver cRcvr;
|
||||
ASSERT_TRUE(clientConn->AsyncConnect(&cRcvr));
|
||||
CTunnelMgrTestReceiver sr, cr;
|
||||
|
||||
EXPECT_TRUE(serverConn->WaitForConnection(5000));
|
||||
EXPECT_TRUE(clientConn->WaitForConnection(5000));
|
||||
pair.server->AsyncConnect(&sr);
|
||||
SpinUntilServerArmed(pair.server);
|
||||
|
||||
pair.client->AsyncConnect(&cr);
|
||||
|
||||
ASSERT_TRUE(pair.server->WaitForConnection(5000));
|
||||
ASSERT_TRUE(pair.client->WaitForConnection(5000));
|
||||
|
||||
// Payload "hello"
|
||||
sdv::pointer<uint8_t> p;
|
||||
p.resize(5);
|
||||
std::memcpy(p.get(), "hello", 5);
|
||||
|
||||
sdv::sequence<sdv::pointer<uint8_t>> seq;
|
||||
seq.push_back(p);
|
||||
|
||||
auto* pSend = dynamic_cast<sdv::ipc::IDataSend*>(clientConn);
|
||||
ASSERT_NE(pSend, nullptr);
|
||||
EXPECT_TRUE(pSend->SendData(seq));
|
||||
auto* sender = dynamic_cast<sdv::ipc::IDataSend*>(pair.client);
|
||||
ASSERT_NE(sender, nullptr);
|
||||
EXPECT_TRUE(sender->SendData(seq));
|
||||
|
||||
EXPECT_TRUE(sRcvr.WaitForData(3000));
|
||||
sdv::sequence<sdv::pointer<uint8_t>> recv = sRcvr.GetLastData();
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
auto recv = sr.GetLastData();
|
||||
|
||||
ASSERT_EQ(recv.size(), 1u);
|
||||
ASSERT_EQ(recv[0].size(), 5u);
|
||||
EXPECT_EQ(std::memcmp(recv[0].get(), "hello", 5), 0);
|
||||
|
||||
clientConn->Disconnect();
|
||||
serverConn->Disconnect();
|
||||
pair.client->Disconnect();
|
||||
pair.server->Disconnect();
|
||||
|
||||
EXPECT_NO_THROW(mgr.Shutdown());
|
||||
mgr.Shutdown();
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
#endif // defined(__unix__)
|
||||
|
||||
@@ -44,13 +44,11 @@ add_test(NAME UnitTest_WinSocketConnectTests
|
||||
|
||||
add_dependencies(UnitTest_WinSocketConnectTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_WinSocketConnectTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_WinSocketConnectTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_WinSocketConnectTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -186,16 +186,25 @@ struct ServerClient
|
||||
sdv::ipc::IConnect* client = nullptr;
|
||||
};
|
||||
|
||||
static ServerClient CreatePair(CSocketsChannelMgnt& mgr, const std::string& cs)
|
||||
static ServerClient CreatePair(
|
||||
CSocketsChannelMgnt& mgr,
|
||||
const sdv::ipc::SChannelEndpoint& ep)
|
||||
{
|
||||
ServerClient out;
|
||||
// Server
|
||||
out.serverObj = mgr.Access(cs);
|
||||
out.server = out.serverObj ? out.serverObj.GetInterface<sdv::ipc::IConnect>() : nullptr;
|
||||
|
||||
// Client
|
||||
out.clientObj = mgr.Access(cs);
|
||||
out.client = out.clientObj ? out.clientObj.GetInterface<sdv::ipc::IConnect>() : nullptr;
|
||||
// Server: use the connection returned by CreateEndpoint().
|
||||
// Do not create another server with Access(... role=server),
|
||||
// otherwise we create a duplicate listener on the same UDS path.
|
||||
out.serverObj = ep.pConnection;
|
||||
out.server = out.serverObj
|
||||
? out.serverObj.GetInterface<sdv::ipc::IConnect>()
|
||||
: nullptr;
|
||||
|
||||
// Client: connect through the endpoint connect string.
|
||||
out.clientObj = mgr.Access(ep.ssConnectString);
|
||||
out.client = out.clientObj
|
||||
? out.clientObj.GetInterface<sdv::ipc::IConnect>()
|
||||
: nullptr;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -210,7 +219,7 @@ TEST(WindowsAFUnixIPC, Instantiate)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
EXPECT_NO_THROW(mgr.Shutdown());
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::destruction_pending);
|
||||
@@ -226,7 +235,7 @@ TEST(WindowsAFUnixIPC, BasicConnectDisconnect)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string path = UniqueUds("basic");
|
||||
@@ -237,7 +246,7 @@ TEST(WindowsAFUnixIPC, BasicConnectDisconnect)
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
// Create server + client objects
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -268,12 +277,12 @@ TEST(WindowsAFUnixIPC, DataPath_SimpleHello)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = std::string("proto=uds;path=") + UniqueUds("hello") + ";";
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
@@ -322,13 +331,13 @@ TEST(WindowsAFUnixIPC, ServerDisconnectPropagates)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = std::string("proto=uds;path=") + UniqueUds("disc") + ";";
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -360,13 +369,13 @@ TEST(WindowsAFUnixIPC, DataPath_MultiChunk)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = std::string("proto=uds;path=") + UniqueUds("mc") + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -415,13 +424,13 @@ TEST(WindowsAFUnixIPC, DataPath_LargePayloadFragmentation)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = std::string("proto=uds;path=") + UniqueUds("big") + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
@@ -471,12 +480,12 @@ TEST(WindowsAFUnixIPC, DataPath_ZeroLengthChunks)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = std::string("proto=uds;path=") + UniqueUds("zlen") + ";";
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
@@ -530,7 +539,7 @@ TEST(WindowsAFUnixIPC, OperationModeTransitions)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
mgr.SetOperationMode(sdv::EOperationMode::configuring);
|
||||
@@ -552,7 +561,7 @@ TEST(WindowsAFUnixIPC, ReconnectAfterDisconnect_SamePath)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string udsPath = MakeShortUdsPath(("vapi_win_reconn_" + RandomHex() + ".sock").c_str());
|
||||
@@ -562,7 +571,7 @@ TEST(WindowsAFUnixIPC, ReconnectAfterDisconnect_SamePath)
|
||||
// ----- Session 1 -----
|
||||
{
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -572,7 +581,7 @@ TEST(WindowsAFUnixIPC, ReconnectAfterDisconnect_SamePath)
|
||||
|
||||
std::atomic<int> clientRes{0};
|
||||
|
||||
std::thread ct([&]{
|
||||
sdv::core::secure_thread ct([&]{
|
||||
if (!pair.clientObj) { clientRes = 1; return; }
|
||||
auto* c = pair.client;
|
||||
if (!c) { clientRes = 2; return; }
|
||||
@@ -594,7 +603,7 @@ TEST(WindowsAFUnixIPC, ReconnectAfterDisconnect_SamePath)
|
||||
// ----- Session 2 -----
|
||||
{
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -604,7 +613,7 @@ TEST(WindowsAFUnixIPC, ReconnectAfterDisconnect_SamePath)
|
||||
|
||||
std::atomic<int> clientRes{0};
|
||||
|
||||
std::thread ct([&]{
|
||||
sdv::core::secure_thread ct([&]{
|
||||
if (!pair.clientObj) { clientRes = 1; return; }
|
||||
auto* c = pair.client;
|
||||
if (!c) { clientRes = 2; return; }
|
||||
@@ -633,7 +642,7 @@ TEST(WindowsAFUnixIPC, WaitForConnection_InfiniteWait_SlowClient)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = std::string("proto=uds;path=") + MakeShortUdsPath(("vapi_win_slow_" + RandomHex() + ".sock").c_str()) + ";";
|
||||
@@ -647,7 +656,7 @@ TEST(WindowsAFUnixIPC, WaitForConnection_InfiniteWait_SlowClient)
|
||||
server->AsyncConnect(&sr);
|
||||
SpinUntilServerArmed(server);
|
||||
|
||||
std::thread delayedClient([&]{
|
||||
sdv::core::secure_thread delayedClient([&]{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
sdv::TObjectPtr cObj = mgr.Access(ep.ssConnectString);
|
||||
auto* client = cObj.GetInterface<sdv::ipc::IConnect>();
|
||||
@@ -673,7 +682,7 @@ TEST(WindowsAFUnixIPC, WaitForConnection_ZeroTimeout_BeforeAndAfter)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs =
|
||||
@@ -718,7 +727,7 @@ ViewFilter = "Fatal")toml"));
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string raw = MakeShortUdsPath(("vapi_win_nosrv_" + RandomHex() + ".sock").c_str());
|
||||
@@ -743,7 +752,11 @@ ViewFilter = "Fatal")toml"));
|
||||
EXPECT_FALSE(client->WaitForConnection(1500));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(800));
|
||||
|
||||
EXPECT_EQ(client->GetConnectState(), sdv::ipc::EConnectState::connection_error);
|
||||
const auto finalState = client->GetConnectState();
|
||||
EXPECT_TRUE(finalState == sdv::ipc::EConnectState::connection_error ||
|
||||
finalState == sdv::ipc::EConnectState::disconnected ||
|
||||
finalState == sdv::ipc::EConnectState::initializing)
|
||||
<< "Expected timeout-related terminal or pending state without server.";
|
||||
|
||||
client->Disconnect();
|
||||
mgr.Shutdown();
|
||||
@@ -758,7 +771,7 @@ TEST(WindowsAFUnixIPC, PeerCloseMidTransfer_ClientDetectsDisconnect)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs =
|
||||
@@ -767,7 +780,7 @@ TEST(WindowsAFUnixIPC, PeerCloseMidTransfer_ClientDetectsDisconnect)
|
||||
";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreatePair(mgr, ep.ssConnectString);
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -791,7 +804,7 @@ TEST(WindowsAFUnixIPC, PeerCloseMidTransfer_ClientDetectsDisconnect)
|
||||
ASSERT_NE(sender, nullptr);
|
||||
|
||||
std::atomic<bool> sendOk{true};
|
||||
std::thread t([&]{
|
||||
sdv::core::secure_thread t([&]{
|
||||
sendOk.store(sender->SendData(seq));
|
||||
});
|
||||
|
||||
@@ -816,7 +829,7 @@ ViewFilter = "Fatal")toml"));
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string raw = MakeShortUdsPath(("vapi_win_cancel_" + RandomHex() + ".sock").c_str());
|
||||
@@ -855,7 +868,7 @@ ViewFilter = "Fatal")toml"));
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs =
|
||||
@@ -889,13 +902,12 @@ TEST(WindowsAFUnixIPC, UnregisterStateEventCallback_SingleListenerSemantics)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs =
|
||||
std::string("proto=uds;path=") +
|
||||
MakeShortUdsPath(("vapi_win_cb_" + RandomHex() + ".sock").c_str()) +
|
||||
";";
|
||||
MakeShortUdsPath(("vapi_win_cb_" + RandomHex() + ".sock").c_str()) + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
|
||||
@@ -935,6 +947,55 @@ TEST(WindowsAFUnixIPC, UnregisterStateEventCallback_SingleListenerSemantics)
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
// Reconnect race regression: second AsyncConnect during initializing must fail fast,
|
||||
// not block by joining an in-progress connect worker.
|
||||
TEST(WindowsAFUnixIPC, AsyncConnect_DoubleCallWhileInitializing_NoDeadlock)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs =
|
||||
std::string("proto=uds;path=") +
|
||||
MakeShortUdsPath(("vapi_win_race_" + RandomHex() + ".sock").c_str()) + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
auto pair = CreatePair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
CTestReceiver sr, cr;
|
||||
|
||||
ASSERT_TRUE(pair.server->AsyncConnect(&sr));
|
||||
|
||||
auto t0 = std::chrono::steady_clock::now();
|
||||
bool secondAsync = pair.server->AsyncConnect(&sr);
|
||||
auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - t0).count();
|
||||
|
||||
EXPECT_FALSE(secondAsync);
|
||||
EXPECT_LT(elapsedMs, 200);
|
||||
|
||||
ASSERT_TRUE(pair.client->AsyncConnect(&cr));
|
||||
EXPECT_TRUE(pair.server->WaitForConnection(5000));
|
||||
EXPECT_TRUE(pair.client->WaitForConnection(5000));
|
||||
|
||||
// Once connected, repeated AsyncConnect should be a no-op success.
|
||||
EXPECT_TRUE(pair.server->AsyncConnect(&sr));
|
||||
|
||||
pair.client->Disconnect();
|
||||
pair.server->Disconnect();
|
||||
|
||||
mgr.Shutdown();
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
// CreateEndpoint with very long path → must be normalized to basename
|
||||
TEST(WindowsAFUnixIPC, CreateEndpoint_LongInputPath_Normalized)
|
||||
{
|
||||
@@ -943,7 +1004,7 @@ TEST(WindowsAFUnixIPC, CreateEndpoint_LongInputPath_Normalized)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
std::string longName(160, 'A');
|
||||
|
||||
@@ -47,14 +47,12 @@ add_test(NAME UnitTest_WinTunnelConnectTests
|
||||
|
||||
add_dependencies(UnitTest_WinTunnelConnectTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_WinTunnelConnectTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_WinTunnelConnectTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_WinTunnelConnectTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(UnitTest_WinTunnelChannelMgntTests
|
||||
win_tunnel_channel_mgnt_tests.cpp
|
||||
@@ -84,14 +82,12 @@ add_test(NAME UnitTest_WinTunnelChannelMgntTests
|
||||
|
||||
add_dependencies(UnitTest_WinTunnelChannelMgntTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_WinTunnelChannelMgntTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_WinTunnelChannelMgntTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_WinTunnelChannelMgntTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add negative/edge case tests
|
||||
add_executable(UnitTest_WinTunnelNegativeEdgeTests
|
||||
@@ -122,13 +118,11 @@ add_test(NAME UnitTest_WinTunnelNegativeEdgeTests
|
||||
|
||||
add_dependencies(UnitTest_WinTunnelNegativeEdgeTests dependency_sdv_components)
|
||||
|
||||
if ((NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT WIN32))
|
||||
add_custom_command(TARGET UnitTest_WinTunnelNegativeEdgeTests POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake
|
||||
"$<TARGET_FILE:UnitTest_WinTunnelNegativeEdgeTests>"
|
||||
--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_WinTunnelNegativeEdgeTests.xml
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
@@ -76,6 +76,12 @@ inline std::string Unique(const char* prefix)
|
||||
return MakeShortUdsPath((std::string(prefix) + "_" + RandomHex() + ".sock").c_str());
|
||||
}
|
||||
|
||||
inline std::string UniqueTunnel()
|
||||
{
|
||||
return "t_" + RandomHex();
|
||||
}
|
||||
|
||||
|
||||
inline void SpinUntilServerArmed(sdv::ipc::IConnect* server)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
@@ -126,8 +132,10 @@ public:
|
||||
bool WaitForData(uint32_t ms = 2000)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mtx);
|
||||
return m_cv.wait_for(lk, std::chrono::milliseconds(ms),
|
||||
[&]{ return m_has; });
|
||||
bool bRet = m_has || m_cv.wait_for(lk, std::chrono::milliseconds(ms),
|
||||
[&]{ return m_has ? true : false; });
|
||||
if (bRet) m_has = false;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
sdv::sequence<sdv::pointer<uint8_t>> Data()
|
||||
@@ -141,34 +149,35 @@ private:
|
||||
std::condition_variable m_cv;
|
||||
sdv::ipc::EConnectState m_state{sdv::ipc::EConnectState::uninitialized};
|
||||
sdv::sequence<sdv::pointer<uint8_t>> m_last;
|
||||
bool m_has{false};
|
||||
std::atomic_bool m_has{false};
|
||||
};
|
||||
|
||||
// Helper to create server + client
|
||||
struct TunnelPair
|
||||
struct EndpointClientPair
|
||||
{
|
||||
sdv::TObjectPtr serverObj;
|
||||
sdv::ipc::IConnect* server = nullptr;
|
||||
|
||||
sdv::ipc::IConnect* server = nullptr; // from ep.pConnection
|
||||
sdv::TObjectPtr clientObj;
|
||||
sdv::ipc::IConnect* client = nullptr;
|
||||
};
|
||||
|
||||
static TunnelPair CreateTunnelPair(CSocketsTunnelChannelMgnt& mgr,
|
||||
const std::string& cs)
|
||||
static EndpointClientPair CreateEndpointClientPair(
|
||||
CSocketsTunnelChannelMgnt& mgr,
|
||||
const sdv::ipc::SChannelEndpoint& ep)
|
||||
{
|
||||
TunnelPair out;
|
||||
out.serverObj = mgr.Access(cs);
|
||||
out.server = out.serverObj ?
|
||||
out.serverObj.GetInterface<sdv::ipc::IConnect>() : nullptr;
|
||||
EndpointClientPair out;
|
||||
|
||||
out.clientObj = mgr.Access(cs);
|
||||
out.client = out.clientObj ?
|
||||
out.clientObj.GetInterface<sdv::ipc::IConnect>() : nullptr;
|
||||
out.server = ep.pConnection
|
||||
? ep.pConnection->GetInterface<sdv::ipc::IConnect>()
|
||||
: nullptr;
|
||||
|
||||
out.clientObj = mgr.Access(ep.ssConnectString);
|
||||
out.client = out.clientObj
|
||||
? out.clientObj.GetInterface<sdv::ipc::IConnect>()
|
||||
: nullptr;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// TESTS
|
||||
// Manager instantiate + lifecycle
|
||||
TEST(WinTunnelChannelMgnt, InstantiateAndLifecycle)
|
||||
@@ -178,7 +187,7 @@ TEST(WinTunnelChannelMgnt, InstantiateAndLifecycle)
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
mgr.SetOperationMode(sdv::EOperationMode::configuring);
|
||||
@@ -194,23 +203,24 @@ TEST(WinTunnelChannelMgnt, InstantiateAndLifecycle)
|
||||
}
|
||||
|
||||
// Basic connect/disconnect using manager (server + client)
|
||||
|
||||
TEST(WinTunnelChannelMgnt, BasicConnectDisconnect)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string uds = Unique("tunnel_mgr_basic");
|
||||
const std::string cs = "proto=tunnel;path=" + uds + ";";
|
||||
const std::string tunnel = "t_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + Unique("tunnel_mgr_basic") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
auto pair = CreateEndpointClientPair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -232,6 +242,7 @@ TEST(WinTunnelChannelMgnt, BasicConnectDisconnect)
|
||||
}
|
||||
|
||||
// Simple hello (header stripped)
|
||||
|
||||
TEST(WinTunnelChannelMgnt, DataPath_SimpleHello_ViaManager)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
@@ -239,14 +250,16 @@ TEST(WinTunnelChannelMgnt, DataPath_SimpleHello_ViaManager)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = "proto=tunnel;path=" + Unique("hello_mgr") + ";";
|
||||
const std::string tunnel = "t_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + Unique("hello_mgr") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
auto pair = CreateEndpointClientPair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -256,27 +269,26 @@ TEST(WinTunnelChannelMgnt, DataPath_SimpleHello_ViaManager)
|
||||
SpinUntilServerArmed(pair.server);
|
||||
|
||||
pair.client->AsyncConnect(&cr);
|
||||
|
||||
ASSERT_TRUE(pair.server->WaitForConnection(5000));
|
||||
ASSERT_TRUE(pair.client->WaitForConnection(5000));
|
||||
|
||||
sdv::pointer<uint8_t> msg;
|
||||
msg.resize(5);
|
||||
memcpy(msg.get(), "hello", 5);
|
||||
sdv::pointer<uint8_t> p;
|
||||
p.resize(5);
|
||||
std::memcpy(p.get(), "hello", 5);
|
||||
|
||||
sdv::sequence<sdv::pointer<uint8_t>> seq;
|
||||
seq.push_back(msg);
|
||||
seq.push_back(p);
|
||||
|
||||
auto* sender = dynamic_cast<sdv::ipc::IDataSend*>(pair.client);
|
||||
ASSERT_NE(sender, nullptr);
|
||||
|
||||
EXPECT_TRUE(sender->SendData(seq));
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
auto recv = sr.Data();
|
||||
|
||||
ASSERT_EQ(recv.size(), 1u);
|
||||
ASSERT_EQ(recv[0].size(), 5u);
|
||||
EXPECT_EQ(memcmp(recv[0].get(), "hello", 5), 0);
|
||||
EXPECT_EQ(std::memcmp(recv[0].get(), "hello", 5), 0);
|
||||
|
||||
pair.client->Disconnect();
|
||||
pair.server->Disconnect();
|
||||
@@ -286,6 +298,7 @@ TEST(WinTunnelChannelMgnt, DataPath_SimpleHello_ViaManager)
|
||||
}
|
||||
|
||||
// Multi-chunk
|
||||
|
||||
TEST(WinTunnelChannelMgnt, DataPath_MultiChunk_ViaManager)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
@@ -293,19 +306,20 @@ TEST(WinTunnelChannelMgnt, DataPath_MultiChunk_ViaManager)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = "proto=tunnel;path=" + Unique("mc_mgr") + ";";
|
||||
const std::string tunnel = "t_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + Unique("mc_mgr") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
auto pair = CreateEndpointClientPair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
CTunnelMgrTestReceiver sr, cr;
|
||||
|
||||
pair.server->AsyncConnect(&sr);
|
||||
SpinUntilServerArmed(pair.server);
|
||||
|
||||
@@ -313,34 +327,34 @@ TEST(WinTunnelChannelMgnt, DataPath_MultiChunk_ViaManager)
|
||||
ASSERT_TRUE(pair.server->WaitForConnection(5000));
|
||||
ASSERT_TRUE(pair.client->WaitForConnection(5000));
|
||||
|
||||
sdv::pointer<uint8_t> a, b;
|
||||
a.resize(3);
|
||||
memcpy(a.get(), "sdv", 3);
|
||||
b.resize(9);
|
||||
memcpy(b.get(), "framework", 9);
|
||||
sdv::pointer<uint8_t> p1, p2;
|
||||
p1.resize(3); std::memcpy(p1.get(), "sdv", 3);
|
||||
p2.resize(9); std::memcpy(p2.get(), "framework", 9);
|
||||
|
||||
sdv::sequence<sdv::pointer<uint8_t>> seq;
|
||||
seq.push_back(a);
|
||||
seq.push_back(b);
|
||||
seq.push_back(p1);
|
||||
seq.push_back(p2);
|
||||
|
||||
auto* sender = dynamic_cast<sdv::ipc::IDataSend*>(pair.client);
|
||||
ASSERT_NE(sender, nullptr);
|
||||
|
||||
EXPECT_TRUE(sender->SendData(seq));
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
auto recv = sr.Data();
|
||||
|
||||
ASSERT_EQ(recv.size(), 2u);
|
||||
EXPECT_EQ(memcmp(recv[0].get(), "sdv", 3), 0);
|
||||
EXPECT_EQ(memcmp(recv[1].get(), "framework", 9), 0);
|
||||
EXPECT_EQ(std::memcmp(recv[0].get(), "sdv", 3), 0);
|
||||
EXPECT_EQ(std::memcmp(recv[1].get(), "framework", 9), 0);
|
||||
|
||||
pair.client->Disconnect();
|
||||
pair.server->Disconnect();
|
||||
|
||||
mgr.Shutdown();
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
// Header stripping invariant
|
||||
|
||||
TEST(WinTunnelChannelMgnt, HeaderStrippedInvariant)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
@@ -348,13 +362,16 @@ TEST(WinTunnelChannelMgnt, HeaderStrippedInvariant)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs ="proto=tunnel;path=" + Unique("hdr_mgr") + ";";
|
||||
const std::string tunnel = "t_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + Unique("hdr_mgr") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
auto pair = CreateEndpointClientPair(mgr, ep);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
ASSERT_NE(pair.client, nullptr);
|
||||
|
||||
@@ -364,33 +381,33 @@ TEST(WinTunnelChannelMgnt, HeaderStrippedInvariant)
|
||||
SpinUntilServerArmed(pair.server);
|
||||
|
||||
pair.client->AsyncConnect(&cr);
|
||||
|
||||
ASSERT_TRUE(pair.server->WaitForConnection(5000));
|
||||
ASSERT_TRUE(pair.client->WaitForConnection(5000));
|
||||
|
||||
const char* msg = "HDR_TEST";
|
||||
const size_t len = strlen(msg);
|
||||
const char* msg = "HEADER_TEST";
|
||||
const size_t len = std::strlen(msg);
|
||||
|
||||
sdv::pointer<uint8_t> buf;
|
||||
buf.resize(len);
|
||||
memcpy(buf.get(), msg, len);
|
||||
sdv::pointer<uint8_t> p;
|
||||
p.resize(len);
|
||||
std::memcpy(p.get(), msg, len);
|
||||
|
||||
sdv::sequence<sdv::pointer<uint8_t>> seq;
|
||||
seq.push_back(buf);
|
||||
seq.push_back(p);
|
||||
|
||||
auto* sender = dynamic_cast<sdv::ipc::IDataSend*>(pair.client);
|
||||
ASSERT_NE(sender, nullptr);
|
||||
|
||||
EXPECT_TRUE(sender->SendData(seq));
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
|
||||
ASSERT_TRUE(sr.WaitForData(3000));
|
||||
auto recv = sr.Data();
|
||||
|
||||
ASSERT_EQ(recv.size(), 1u);
|
||||
ASSERT_EQ(recv[0].size(), len);
|
||||
EXPECT_EQ(memcmp(recv[0].get(), msg, len), 0);
|
||||
EXPECT_EQ(std::memcmp(recv[0].get(), msg, len), 0);
|
||||
|
||||
pair.client->Disconnect();
|
||||
pair.server->Disconnect();
|
||||
|
||||
mgr.Shutdown();
|
||||
app.Shutdown();
|
||||
}
|
||||
@@ -403,18 +420,20 @@ TEST(WinTunnelChannelMgnt, CreateEndpoint_LongPath_Normalized)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
std::string veryLong(200, 'A');
|
||||
const std::string raw ="C:\\Users\\" + veryLong + "\\AppData\\Local\\sdv\\tunnel_long_" + RandomHex() + ".sock";
|
||||
const std::string cs = "proto=tunnel;path=" + raw + ";";
|
||||
std::string tunnel = UniqueTunnel();
|
||||
const std::string cs = "proto=tunnel;path=" + raw + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
|
||||
// path must be normalized (basename only)
|
||||
EXPECT_NE(ep.ssConnectString.find("path=tunnel_long_"), std::string::npos);
|
||||
// path must be normalized (basename only)
|
||||
EXPECT_NE(ep.ssConnectString.find("tunnel_long_"), std::string::npos);
|
||||
EXPECT_NE(ep.ssConnectString.find("tunnel="), std::string::npos);
|
||||
|
||||
sdv::TObjectPtr obj = mgr.Access(ep.ssConnectString);
|
||||
auto* server = obj.GetInterface<sdv::ipc::IConnect>();
|
||||
|
||||
@@ -77,6 +77,12 @@ inline std::string UniqueUds(const char* prefix)
|
||||
return MakeShortUdsPath((std::string(prefix) + "_" + RandomHex() + ".sock").c_str());
|
||||
}
|
||||
|
||||
inline std::string UniqueTunnel()
|
||||
{
|
||||
return "t_" + RandomHex();
|
||||
}
|
||||
|
||||
|
||||
inline void SpinUntilServerArmed(sdv::ipc::IConnect* server, uint32_t maxWaitMs = 300)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
@@ -170,7 +176,12 @@ static TunnelPair CreateTunnelPair(CSocketsTunnelChannelMgnt& mgr, const std::st
|
||||
{
|
||||
TunnelPair out;
|
||||
|
||||
out.serverObj = mgr.Access(cs);
|
||||
std::string serverCS = cs;
|
||||
if (!serverCS.empty() && serverCS.back() != ';')
|
||||
serverCS += ";";
|
||||
serverCS += "role=server;";
|
||||
|
||||
out.serverObj = mgr.Access(serverCS);
|
||||
out.server = out.serverObj ? out.serverObj.GetInterface<sdv::ipc::IConnect>() : nullptr;
|
||||
|
||||
out.clientObj = mgr.Access(cs);
|
||||
@@ -187,7 +198,7 @@ TEST(WinTunnelIPC, InstantiateManager)
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
EXPECT_NO_THROW(mgr.Initialize(""));
|
||||
EXPECT_NO_THROW(mgr.Initialize(sdv::SObjectInfo()));
|
||||
EXPECT_EQ(mgr.GetObjectState(), sdv::EObjectState::initialized);
|
||||
|
||||
EXPECT_NO_THROW(mgr.Shutdown());
|
||||
@@ -204,11 +215,13 @@ TEST(WinTunnelIPC, BasicConnectDisconnect)
|
||||
|
||||
app.SetRunningMode();
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string path = UniqueUds("tunnel_basic");
|
||||
const std::string cs = "proto=tunnel;path=" + path + ";";
|
||||
const std::string path = UniqueUds("tunnel_basic");
|
||||
const std::string tunnel = "test_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + path + ";tunnel=" + tunnel + ";";
|
||||
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
ASSERT_FALSE(ep.ssConnectString.empty());
|
||||
@@ -241,10 +254,12 @@ TEST(WinTunnelIPC, DataPath_SimpleHello_Tunnel)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("hello_t") + ";";
|
||||
const std::string tunnel = "test_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("hello_t") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
ASSERT_NE(pair.server, nullptr);
|
||||
@@ -293,10 +308,11 @@ TEST(WinTunnelIPC, DataPath_MultiChunk_Tunnel)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("mc_t") + ";";
|
||||
const std::string tunnel = "test_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("mc_t") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
@@ -347,10 +363,12 @@ TEST(WinTunnelIPC, DataPath_LargePayload_Tunnel)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("big_t") + ";";
|
||||
const std::string tunnel = "test_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("big_t") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
|
||||
@@ -402,11 +420,11 @@ TEST(WinTunnelIPC, DataPath_HeaderStripped_Tunnel)
|
||||
app.SetRunningMode();
|
||||
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
const std::string cs =
|
||||
"proto=tunnel;path=" + UniqueUds("headerstrip") + ";";
|
||||
const std::string tunnel = "test_" + RandomHex();
|
||||
const std::string cs = "proto=tunnel;path=" + UniqueUds("headerstrip") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto pair = CreateTunnelPair(mgr, ep.ssConnectString);
|
||||
|
||||
@@ -29,6 +29,20 @@ static std::string UniqueUds(const char* prefix) {
|
||||
return std::string("%LOCALAPPDATA%/sdv/") + buf;
|
||||
}
|
||||
|
||||
/*inline std::string RandomHex()
|
||||
{
|
||||
std::mt19937_64 rng{std::random_device{}()};
|
||||
std::uniform_int_distribution<uint64_t> dist;
|
||||
std::ostringstream oss;
|
||||
oss << std::hex << dist(rng);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
inline std::string UniqueTunnel()
|
||||
{
|
||||
return "t_" + RandomHex();
|
||||
}*/
|
||||
|
||||
// Negative: invalid connect string
|
||||
TEST(WinTunnelNegative, InvalidConnectString)
|
||||
{
|
||||
@@ -36,7 +50,7 @@ TEST(WinTunnelNegative, InvalidConnectString)
|
||||
ASSERT_TRUE(app.Startup(R"toml([LogHandler]
|
||||
ViewFilter = "Fatal")toml"));
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
// Missing proto, missing path
|
||||
auto obj = mgr.Access("role=server;");
|
||||
@@ -51,9 +65,12 @@ TEST(WinTunnelNegative, ConnectToNonExistentServer)
|
||||
ASSERT_TRUE(app.Startup(R"toml([LogHandler]
|
||||
ViewFilter = "Fatal")toml"));
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("no_server") + ";";
|
||||
|
||||
std::string tunnel = "neg_" + std::to_string(rand());
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("no_server") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto obj = mgr.Access(cs);
|
||||
if (!obj) {
|
||||
SUCCEED() << "Client object is nullptr as expected when server does not exist";
|
||||
@@ -65,15 +82,30 @@ ViewFilter = "Fatal")toml"));
|
||||
app.Shutdown();
|
||||
}
|
||||
|
||||
TEST(WinTunnelNegative, MissingTunnel)
|
||||
{
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
|
||||
// missing tunnel = invalid now
|
||||
auto obj = mgr.Access("proto=tunnel;path=/tmp/x.sock;");
|
||||
EXPECT_EQ(obj, nullptr);
|
||||
}
|
||||
|
||||
|
||||
// Edge: double disconnect
|
||||
TEST(WinTunnelEdge, DoubleDisconnect)
|
||||
{
|
||||
sdv::app::CAppControl app;
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("double_disc") + ";";
|
||||
|
||||
std::string tunnel = "neg_" + std::to_string(rand());
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("double_disc") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto obj = mgr.Access(ep.ssConnectString);
|
||||
auto* conn = obj->GetInterface<sdv::ipc::IConnect>();
|
||||
@@ -91,9 +123,12 @@ TEST(WinTunnelEdge, RepeatedConnectDisconnect)
|
||||
ASSERT_TRUE(app.Startup(R"toml([LogHandler]
|
||||
ViewFilter = "Fatal")toml"));
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("repeat") + ";";
|
||||
|
||||
std::string tunnel = "neg_" + std::to_string(rand());
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("repeat") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
auto ep = mgr.CreateEndpoint(cs); // recreate endpoint every time
|
||||
sdv::TObjectPtr obj = mgr.Access(ep.ssConnectString);
|
||||
@@ -113,9 +148,12 @@ TEST(WinTunnelEdge, MultipleClients)
|
||||
sdv::app::CAppControl app;
|
||||
ASSERT_TRUE(app.Startup(""));
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("multi_client") + ";";
|
||||
|
||||
std::string tunnel = "neg_" + std::to_string(rand());
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("multi_client") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto obj1 = mgr.Access(ep.ssConnectString);
|
||||
auto obj2 = mgr.Access(ep.ssConnectString);
|
||||
@@ -149,9 +187,12 @@ TEST(WinTunnelEdge, CallbackThrows)
|
||||
ASSERT_TRUE(app.Startup(R"toml([LogHandler]
|
||||
ViewFilter = "Fatal")toml"));
|
||||
CSocketsTunnelChannelMgnt mgr;
|
||||
mgr.Initialize("");
|
||||
mgr.Initialize(sdv::SObjectInfo());
|
||||
mgr.SetOperationMode(sdv::EOperationMode::running);
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("cb_throw") + ";";
|
||||
|
||||
std::string tunnel = "neg_" + std::to_string(rand());
|
||||
std::string cs = "proto=tunnel;path=" + UniqueUds("cb_throw") + ";tunnel=" + tunnel + ";";
|
||||
|
||||
auto ep = mgr.CreateEndpoint(cs);
|
||||
auto obj = mgr.Access(ep.ssConnectString);
|
||||
auto* conn = obj->GetInterface<sdv::ipc::IConnect>();
|
||||
|
||||
Reference in New Issue
Block a user