diff --git a/.forgejo/workflows/pr_check.yaml b/.forgejo/workflows/pr_check.yaml index b8f8f80..19355ab 100644 --- a/.forgejo/workflows/pr_check.yaml +++ b/.forgejo/workflows/pr_check.yaml @@ -134,6 +134,8 @@ jobs: -GNinja -DCMAKE_BUILD_TYPE=Release \ -DENABLE_EXAMPLES=ON \ -DENABLE_TESTS=ON \ + -DLOG_LEVEL=0 \ + -DTEST_LOG_LEVEL=0 \ -DCMAKE_CXX_FLAGS="-ftemplate-backtrace-limit=0" cmake --build ${{ github.workspace }}/build_gcc --parallel `nproc` @@ -160,6 +162,8 @@ jobs: -GNinja -DCMAKE_BUILD_TYPE=Release \ -DENABLE_EXAMPLES=ON \ -DENABLE_TESTS=ON \ + -DLOG_LEVEL=0 \ + -DTEST_LOG_LEVEL=0 \ -DCMAKE_CXX_FLAGS="-stdlib=libc++ -I/home/LLVM-${LLVM_VER}/include/c++/v1 -fno-modules" echo "::group::compile_commands.json content" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4720fa7..b1b88cc 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -80,7 +80,7 @@ "cd ${workspaceFolder} &&", "mkdir -p build && cd build &&", "cmake cmake -Wno-dev ", - " -DCMAKE_BUILD_TYPE=Debug -DENABLE_EXAMPLES=ON -DENABLE_TESTS=ON .." + " -DCMAKE_BUILD_TYPE=Debug -DENABLE_EXAMPLES=ON -DENABLE_TESTS=ON -DLOG_LEVEL=0 -DTEST_LOG_LEVEL=0 .." ], "options": { "env": { @@ -138,6 +138,7 @@ "mkdir -p build_clang && cd build_clang &&", "cmake -Wno-dev ", " -DCMAKE_BUILD_TYPE=Debug -DENABLE_EXAMPLES=ON -DENABLE_TESTS=ON ", + " -DLOG_LEVEL=0 -DTEST_LOG_LEVEL=0", " -DCMAKE_CXX_FLAGS=\"-stdlib=libstdc++\"", " -DCMAKE_EXE_LINKER_FLAGS=\"-L/usr/lib/x86_64-linux-gnu -lstdc++\" .." ], @@ -160,6 +161,7 @@ "mkdir -p build_clang && cd build_clang &&", "cmake -Wno-dev ", " -DCMAKE_BUILD_TYPE=Debug -DENABLE_EXAMPLES=ON -DENABLE_TESTS=ON", + " -DLOG_LEVEL=0 -DTEST_LOG_LEVEL=0" // // Uncomment for GCC standart library: libstdc++ //" -DCMAKE_CXX_FLAGS=\"-stdlib=libstdc++ -fno-omit-frame-pointer -g -fsanitize=address,undefined,leak,function,nullability,vptr\"", @@ -211,6 +213,7 @@ "mkdir -p build_clang && cd build_clang &&", "cmake -Wno-dev ", " -DCMAKE_BUILD_TYPE=Debug -DENABLE_EXAMPLES=ON -DENABLE_TESTS=ON ", + " -DLOG_LEVEL=0 -DTEST_LOG_LEVEL=0", " -DCMAKE_CXX_FLAGS=\"-stdlib=libstdc++ -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fsanitize=memory\"", " -DCMAKE_EXE_LINKER_FLAGS=\"-L/usr/lib/x86_64-linux-gnu -lstdc++ -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fsanitize=memory\" ..", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fd11ac..7c55017 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,8 @@ set(BOOST_INCLUDE_LIBRARIES "pfr;asio;serialization") option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON) option(UTEMPL_USE_LOCAL_PACKAGE "Use utempl local package" OFF) option(BUILD_EXECUTABLE ON) -set(LOG_LEVEL 0 "Available log levels: 0=TRACE, 1=DEBUG,2= INFO,3= WARN, 4=ERROR, 5=CRITICAL, 6=OFF") # Compile program with highest available log levle to trace everything +set(LOG_LEVEL 2 CACHE STRING "Available log levels: 0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR, 5=CRITICAL, 6=OFF") +set(TEST_LOG_LEVEL 2 CACHE STRING "Available log levels: 0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR, 5=CRITICAL, 6=OFF") set(UTEMPL_URL "https://sha512sum.xyz/git/sha512sum/utempl" CACHE STRING "utempl repository URL") @@ -260,7 +261,7 @@ if(ENABLE_TESTS) target_sources(larra_xmpp_tests PUBLIC ${SOURCES}) target_link_libraries(larra_xmpp_tests GTest::gtest_main larra_xmpp) - target_compile_definitions(larra_xmpp_tests PRIVATE SPDLOG_ACTIVE_LEVEL=0) # SPDLOG_LEVEL_TRACE=0. Check LOG_LEVEL variable and spdlog documentation for more details + target_compile_definitions(larra_xmpp_tests PRIVATE SPDLOG_ACTIVE_LEVEL=${TEST_LOG_LEVEL}) set_property(TARGET larra_xmpp_tests PROPERTY CXX_STANDARD 23) include(GoogleTest) gtest_discover_tests(larra_xmpp_tests) @@ -272,8 +273,7 @@ if(ENABLE_EXAMPLES) get_filename_component(EXAMPLE_NAME ${EXAMPLE_SRC} NAME_WE) add_executable(${EXAMPLE_NAME} ${EXAMPLE_SRC}) target_link_libraries(${EXAMPLE_NAME} larra_xmpp) - # TODO(unknown): Fixed 'command line' error occured and uncomment below - # target_compile_definitions(${EXAMPLE_NAME} PRIVATE SPDLOG_ACTIVE_LEVEL=${LOG_LEVEL}) + target_compile_definitions(${EXAMPLE_NAME} PRIVATE SPDLOG_ACTIVE_LEVEL=${TEST_LOG_LEVEL}) set_property(TARGET ${EXAMPLE_NAME} PROPERTY CXX_STANDARD 23) set_target_properties(${EXAMPLE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/examples/output") diff --git a/library/include/larra/iq.hpp b/library/include/larra/iq.hpp index 183ec0e..20d5609 100644 --- a/library/include/larra/iq.hpp +++ b/library/include/larra/iq.hpp @@ -1,9 +1,9 @@ #pragma once #include -#include #include #include +#include #include #include #include @@ -118,7 +118,7 @@ using Error = BaseImplWithPayload; } // namespace iq -using IqError = iq::Error; +using IqError = iq::Error; template using Iq = std::variant, iq::Set, iq::Result, IqError>; diff --git a/library/include/larra/iq_error.hpp b/library/include/larra/stanza_error.hpp similarity index 50% rename from library/include/larra/iq_error.hpp rename to library/include/larra/stanza_error.hpp index 2dfc6bd..6dea891 100644 --- a/library/include/larra/iq_error.hpp +++ b/library/include/larra/stanza_error.hpp @@ -5,16 +5,14 @@ #include #include -namespace larra::xmpp::iq::error { +namespace larra::xmpp::stanza::error { -namespace impl { - -struct IqBaseError : std::exception {}; +struct StanzaBaseError : std::exception {}; // DO NOT MOVE TO ANOTHER NAMESPACE(where no heirs). VIA friend A FUNCTION IS ADDED THAT VIA ADL WILL BE SEARCHED FOR HEIRS // C++20 modules very unstable in clangd :( template -struct IqErrorImpl : IqBaseError { +struct StanzaErrorImpl : StanzaBaseError { static constexpr auto kDefaultName = "error"; static constexpr auto kDefaultNamespace = "urn:ietf:params:xml:ns:xmpp-stanzas"; static inline const auto kKebabCaseName = static_cast(utils::ToKebabCaseName()); @@ -67,7 +65,7 @@ struct IqErrorImpl : IqBaseError { auto node = element->add_child_element(kKebabCaseName); node->set_namespace_declaration(kDefaultNamespace); } - constexpr auto operator==(const IqErrorImpl&) const -> bool { + constexpr auto operator==(const StanzaErrorImpl&) const -> bool { return true; }; [[nodiscard]] constexpr auto what() const noexcept -> const char* override { @@ -76,20 +74,20 @@ struct IqErrorImpl : IqBaseError { }; // Helper class to prevent parsing response stream into an expected return type if its name is an 'error' -struct UnknownIqError : IqBaseError { +struct UnknownStanzaError : StanzaBaseError { static constexpr auto kDefaultName = "stream:error"; static constexpr std::string_view kErrorMessage = "Unknown XMPP stream error"; static constexpr auto TryParse(xmlpp::Element* element) { - return std::optional{UnknownIqError{}}; + return std::optional{UnknownStanzaError{}}; } static constexpr auto Parse(xmlpp::Element* element) { return TryParse(element).value(); } - friend constexpr auto operator<<(xmlpp::Element* element, const UnknownIqError& obj) -> void { + friend constexpr auto operator<<(xmlpp::Element* element, const UnknownStanzaError& obj) -> void { throw std::format("'{}' must never be written into the real stream!", kErrorMessage); } - constexpr auto operator==(const UnknownIqError&) const -> bool { + constexpr auto operator==(const UnknownStanzaError&) const -> bool { return true; }; [[nodiscard]] constexpr auto what() const noexcept -> const char* override { @@ -97,56 +95,54 @@ struct UnknownIqError : IqBaseError { } }; -struct BadRequest : IqErrorImpl {}; -struct Conflict : IqErrorImpl {}; -struct FeatureNotImplemented : IqErrorImpl {}; -struct Forbidden : IqErrorImpl {}; -struct Gone : IqErrorImpl {}; -struct InternalServerError : IqErrorImpl {}; -struct ItemNotFound : IqErrorImpl {}; -struct JidMalformed : IqErrorImpl {}; -struct NotAcceptable : IqErrorImpl {}; -struct NotAllowed : IqErrorImpl {}; -struct NotAuthorized : IqErrorImpl {}; -struct PolicyViolation : IqErrorImpl {}; -struct RecipientUnavailable : IqErrorImpl {}; -struct Redirect : IqErrorImpl {}; -struct RegistrationRequired : IqErrorImpl {}; -struct RemoteServerNotFound : IqErrorImpl {}; -struct RemoteServerTimeout : IqErrorImpl {}; -struct ResourceConstraint : IqErrorImpl {}; -struct ServiceUnavailable : IqErrorImpl {}; -struct SubscriptionRequired : IqErrorImpl {}; -struct UndefinedCondition : IqErrorImpl {}; -struct UnexpectedRequest : IqErrorImpl {}; +struct BadRequest : StanzaErrorImpl {}; +struct Conflict : StanzaErrorImpl {}; +struct FeatureNotImplemented : StanzaErrorImpl {}; +struct Forbidden : StanzaErrorImpl {}; +struct Gone : StanzaErrorImpl {}; +struct InternalServerError : StanzaErrorImpl {}; +struct ItemNotFound : StanzaErrorImpl {}; +struct JidMalformed : StanzaErrorImpl {}; +struct NotAcceptable : StanzaErrorImpl {}; +struct NotAllowed : StanzaErrorImpl {}; +struct NotAuthorized : StanzaErrorImpl {}; +struct PolicyViolation : StanzaErrorImpl {}; +struct RecipientUnavailable : StanzaErrorImpl {}; +struct Redirect : StanzaErrorImpl {}; +struct RegistrationRequired : StanzaErrorImpl {}; +struct RemoteServerNotFound : StanzaErrorImpl {}; +struct RemoteServerTimeout : StanzaErrorImpl {}; +struct ResourceConstraint : StanzaErrorImpl {}; +struct ServiceUnavailable : StanzaErrorImpl {}; +struct SubscriptionRequired : StanzaErrorImpl {}; +struct UndefinedCondition : StanzaErrorImpl {}; +struct UnexpectedRequest : StanzaErrorImpl {}; -} // namespace impl +using StanzaError = std::variant; -using IqError = std::variant; +static_assert(!std::is_same_v - 1, StanzaError>, StanzaError>, + "'UnknownStanzaError' must be at the end of 'StanzaError' variant"); -static_assert(!std::is_same_v - 1, IqError>, IqError>, - "'UnknownIqError' must be at the end of 'IqError' variant"); - -} // namespace larra::xmpp::iq::error +} // namespace larra::xmpp::stanza::error diff --git a/tests/iq.cpp b/tests/iq.cpp index 1dae134..833711c 100644 --- a/tests/iq.cpp +++ b/tests/iq.cpp @@ -69,7 +69,7 @@ TEST(IQ, ParseForbiddenError) { ASSERT_TRUE(std::holds_alternative(iqRes)); auto errorRes = std::get(iqRes); - ASSERT_TRUE(std::holds_alternative(errorRes.payload)); + ASSERT_TRUE(std::holds_alternative(errorRes.payload)); } TEST(IQ, IqErrThrowVisitorThrow) { @@ -87,7 +87,7 @@ TEST(IQ, IqErrThrowVisitorThrow) { static constexpr auto throwErrMsg = "Stanza IQ Error: Forbidden"; try { std::visit(utempl::Overloaded([](iq::Result r) {}, IqErrThrowVisitor{visitorErrMsg}), std::move(iqRes)); - } catch(const iq::error::impl::IqBaseError& err) { + } catch(const stanza::error::StanzaBaseError& err) { ASSERT_STREQ(throwErrMsg, err.what()); return; } catch(const std::runtime_error& err) { @@ -114,7 +114,7 @@ TEST(IQ, IqErrThrowVisitorThrowGet) { static constexpr auto throwErrMsg = "Test Error: 'Get' is an invalid type for IQ result. Expected 'Result' or 'Error'"; try { std::visit(utempl::Overloaded([](iq::Result r) {}, IqErrThrowVisitor{"Test Error"}), std::move(iqRes)); - } catch(const iq::error::impl::IqBaseError& err) { + } catch(const stanza::error::StanzaBaseError& err) { ASSERT_TRUE(false) << "\tERROR: Invalid throw type throw"; } catch(const std::runtime_error& err) { ASSERT_STREQ(throwErrMsg, err.what()); @@ -141,7 +141,7 @@ TEST(IQ, IqErrThrowVisitorThrowSet) { static constexpr auto throwErrMsg = "Test Error: 'Set' is an invalid type for IQ result. Expected 'Result' or 'Error'"; try { std::visit(utempl::Overloaded([](iq::Result r) {}, IqErrThrowVisitor{"Test Error"}), std::move(iqRes)); - } catch(const iq::error::impl::IqBaseError& err) { + } catch(const stanza::error::StanzaBaseError& err) { ASSERT_TRUE(false) << "\tERROR: Invalid throw type throw"; } catch(const std::runtime_error& err) { ASSERT_STREQ(throwErrMsg, err.what());