Migrates the project from bazel to cmake and copies tinytest into the project temporarily.
This commit is contained in:
34
tests/CMakeLists.txt
Normal file
34
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
# Enable testing
|
||||
enable_testing()
|
||||
|
||||
# Define the ansi_escapes_test executable
|
||||
add_executable(ansi_escapes_test ansi_escapes_test.cpp)
|
||||
target_link_libraries(ansi_escapes_test PRIVATE ansi_escapes tinytest)
|
||||
add_test(NAME ansi_escapes_test COMMAND ansi_escapes_test)
|
||||
|
||||
# Define the console_logger_test executable
|
||||
add_executable(console_logger_test console_logger_test.cpp)
|
||||
target_link_libraries(console_logger_test PRIVATE console_logger tinytest)
|
||||
add_test(NAME console_logger_test COMMAND console_logger_test)
|
||||
|
||||
# Define the logger_test executable
|
||||
add_executable(logger_test logger_test.cpp)
|
||||
target_link_libraries(logger_test PRIVATE logger tinytest)
|
||||
add_test(NAME logger_test COMMAND logger_test)
|
||||
|
||||
# Define the pretty_print_test executable
|
||||
add_executable(pretty_print_test pretty_print_test.cpp)
|
||||
target_link_libraries(pretty_print_test PRIVATE pretty_print tinytest)
|
||||
add_test(NAME pretty_print_test COMMAND pretty_print_test)
|
||||
|
||||
# Define the windows_logger_test executable only for Windows
|
||||
if(WIN32)
|
||||
add_executable(windows_logger_test windows_logger_test.cpp)
|
||||
target_link_libraries(windows_logger_test PRIVATE windows_logger tinytest)
|
||||
add_test(NAME windows_logger_test COMMAND windows_logger_test)
|
||||
endif()
|
||||
|
||||
# Define the tinytest_test executable
|
||||
add_executable(tinytest_test tinytest_test.cpp)
|
||||
target_link_libraries(tinytest_test PRIVATE tinytest gtest_main gtest gmock)
|
||||
add_test(NAME tinytest_test COMMAND tinytest_test)
|
||||
256
tests/ansi_escapes_test.cpp
Normal file
256
tests/ansi_escapes_test.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/**********************************************************************************************************************
|
||||
* *
|
||||
* @file ansi_escapes_test.cpp *
|
||||
* *
|
||||
* @brief Defines constants and functions for working with screen colors. *
|
||||
* @copyright Copyright (C) 2023 by Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Licensed under the MIT license see below for details. *
|
||||
* *
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2023 Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated *
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and *
|
||||
* to permit persons to whom the Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of *
|
||||
* the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO *
|
||||
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
|
||||
* IN THE SOFTWARE. *
|
||||
* *
|
||||
**********************************************************************************************************************/
|
||||
// clang-format off
|
||||
#include "ansi_escapes.h"
|
||||
#include "tinytest.h"
|
||||
|
||||
// clang-format on
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
|
||||
namespace {
|
||||
using std::make_tuple;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using TinyTest::ExecuteSuite;
|
||||
using TinyTest::MakeTest;
|
||||
using TinyTest::MakeTestSuite;
|
||||
using TinyTest::TestResults;
|
||||
} // End namespace
|
||||
|
||||
string filter(const string &text) {
|
||||
std::regex pattern("\033");
|
||||
return std::regex_replace(text, pattern, "\\033");
|
||||
}
|
||||
|
||||
TestResults test_GetRedComponent() {
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::GetRedComponent(uint32_t)",
|
||||
CPPUtils::GetRedComponent,
|
||||
{
|
||||
MakeTest("should get the red component 0x34 from 0x12345678", 0x34U, make_tuple(0x12345678U)),
|
||||
MakeTest("should get the red component 0x56 from 0x34567890", 0x56U, make_tuple(0x34567890U)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_GetGreenComponent() {
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::GetGreenComponent(uint32_t)",
|
||||
CPPUtils::GetGreenComponent,
|
||||
{
|
||||
MakeTest("should get the green component 0x56 from 0x12345678", 0x56U, make_tuple(0x12345678U)),
|
||||
MakeTest("should get the green component 0x78 from 0x34567890", 0x78U, make_tuple(0x34567890U)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_GetBlueComponent() {
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::GetBlueComponent(uint32_t)",
|
||||
CPPUtils::GetBlueComponent,
|
||||
{
|
||||
MakeTest("should get the blue component 0x78 from 0x12345678", 0x78, make_tuple(0x12345678)),
|
||||
MakeTest("should get the blue component 0x90 from 0x34567890", 0x90, make_tuple(0x34567890)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_EscapeWithBasicString() {
|
||||
auto function_to_test = [](string text) {
|
||||
ostringstream os;
|
||||
CPPUtils::Escape(os, text);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Escape(string)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should escape \"asdf\" to \"\\033[asdfm\"", (string) "\033[asdfm", make_tuple("asdf")),
|
||||
MakeTest("should escape \"fdsa\" to \"\\033[fdsam\"", (string) "\033[fdsam", make_tuple("fdsa")),
|
||||
MakeTest("should escape \"1;2;3\" to \"\\033[1;2;3m\"", (string) "\033[1;2;3m", make_tuple("1;2;3")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_EscapeWithBasicStringView() {
|
||||
auto function_to_test = [](string_view text) {
|
||||
ostringstream os;
|
||||
CPPUtils::Escape(os, text);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Escape(string_view)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should escape \"asdf\" to \"\\033[asdfm\"", (string) "\033[asdfm", make_tuple("asdf")),
|
||||
MakeTest("should escape \"fdsa\" to \"\\033[fdsam\"", (string) "\033[fdsam", make_tuple("fdsa")),
|
||||
MakeTest("should escape \"1;2;3\" to \"\\033[1;2;3m\"", (string) "\033[1;2;3m", make_tuple("1;2;3")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_EscapeWithConstCharStar() {
|
||||
auto function_to_test = [](const char *text) {
|
||||
ostringstream os;
|
||||
CPPUtils::Escape(os, text);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Escape(const char*)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should escape \"asdf\" to \"\\033[asdfm\"", (string) "\033[asdfm", make_tuple("asdf")),
|
||||
MakeTest("should escape \"fdsa\" to \"\\033[fdsam\"", (string) "\033[fdsam", make_tuple("fdsa")),
|
||||
MakeTest("should escape \"1;2;3\" to \"\\033[1;2;3m\"", (string) "\033[1;2;3m", make_tuple("1;2;3")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_ForegroundColor8Bit() {
|
||||
auto function_to_test = [](uint8_t color) {
|
||||
ostringstream os;
|
||||
CPPUtils::ForegroundColor8Bit(os, color);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::ForegroundColor8Bit(uint8_t)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[38;5;7m\"", (string) "\033[38;5;7m", make_tuple(0x07U)),
|
||||
MakeTest("should write \"\\033[38;5;1m\"", (string) "\033[38;5;1m", make_tuple(0x01U)),
|
||||
MakeTest("should write \"\\033[38;5;11m\"", (string) "\033[38;5;11m", make_tuple(0x0BU)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_BackgroundColor8Bit() {
|
||||
auto function_to_test = [](uint8_t color) {
|
||||
ostringstream os;
|
||||
CPPUtils::BackgroundColor8Bit(os, color);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::BackgroundColor8Bit(uint8_t)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[48;5;7m\"", (string) "\033[48;5;7m", make_tuple(0x07U)),
|
||||
MakeTest("should write \"\\033[48;5;1m\"", (string) "\033[48;5;1m", make_tuple(0x01U)),
|
||||
MakeTest("should write \"\\033[48;5;11m\"", (string) "\033[48;5;11m", make_tuple(0x0BU)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_ForegroundTrueColorWithUInt32() {
|
||||
auto function_to_test = [](uint32_t color) {
|
||||
ostringstream os;
|
||||
CPPUtils::ForegroundTrueColor(os, color);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::ForegroundTrueColor(uint32_t)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[38;2;21;69;136m\"", (string) "\033[38;2;21;69;136m", make_tuple(0x00154588)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_BackgroundTrueColorWithUInt32() {
|
||||
auto function_to_test = [](uint32_t color) {
|
||||
ostringstream os;
|
||||
CPPUtils::BackgroundTrueColor(os, color);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::BackgroundTrueColor(uint32_t)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[48;2;21;69;136m\"", (string) "\033[48;2;21;69;136m", make_tuple(0x00154588)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_ForegroundTrueColorWith3UInt8() {
|
||||
auto function_to_test = [](uint8_t red, uint8_t green, uint8_t blue) {
|
||||
ostringstream os;
|
||||
CPPUtils::ForegroundTrueColor(os, red, green, blue);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::ForegroundTrueColor(uint8_t, uint8_t, uint8_t)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[38;2;21;69;136m\"",
|
||||
(string) "\033[38;2;21;69;136m",
|
||||
make_tuple(0x15, 0x45, 0x88)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_BackgroundTrueColorWith3UInt8() {
|
||||
auto function_to_test = [](uint8_t red, uint8_t green, uint8_t blue) {
|
||||
ostringstream os;
|
||||
CPPUtils::BackgroundTrueColor(os, red, green, blue);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::BackgroundTrueColor(uint8_t, uint8_t, uint8_t)",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[48;2;21;69;136m\"",
|
||||
(string) "\033[48;2;21;69;136m",
|
||||
make_tuple(0x15, 0x45, 0x88)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Reset() {
|
||||
auto function_to_test = []() {
|
||||
ostringstream os;
|
||||
CPPUtils::Reset(os);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::Reset",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should write \"\\033[m\"", (string) "\033[m", make_tuple()),
|
||||
}));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
TestResults results;
|
||||
|
||||
results += test_GetRedComponent();
|
||||
results += test_GetGreenComponent();
|
||||
results += test_GetBlueComponent();
|
||||
results += test_EscapeWithBasicString();
|
||||
results += test_EscapeWithBasicStringView();
|
||||
results += test_EscapeWithConstCharStar();
|
||||
results += test_ForegroundColor8Bit();
|
||||
results += test_BackgroundColor8Bit();
|
||||
results += test_ForegroundTrueColorWithUInt32();
|
||||
results += test_BackgroundTrueColorWithUInt32();
|
||||
results += test_ForegroundTrueColorWith3UInt8();
|
||||
results += test_BackgroundTrueColorWith3UInt8();
|
||||
results += test_Reset();
|
||||
|
||||
return results.Failed() + results.Errors();
|
||||
}
|
||||
201
tests/console_logger_test.cpp
Normal file
201
tests/console_logger_test.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/**********************************************************************************************************************
|
||||
* *
|
||||
* @file console_logger_test.cpp *
|
||||
* *
|
||||
* @brief Defines tests for the ConsoleLogger class that is a logging destination for the Logger class declared in *
|
||||
* logger.h. *
|
||||
* @copyright Copyright (C) 2023 by Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Licensed under the MIT license see below for details. *
|
||||
* *
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2023 Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated *
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and *
|
||||
* to permit persons to whom the Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of *
|
||||
* the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO *
|
||||
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
|
||||
* IN THE SOFTWARE. *
|
||||
* *
|
||||
**********************************************************************************************************************/
|
||||
#include "console_logger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
|
||||
#include "logger.h"
|
||||
#include "tinytest.h"
|
||||
|
||||
namespace {
|
||||
using CPPUtils::ConsoleLogger;
|
||||
using CPPUtils::Logger;
|
||||
using std::cout;
|
||||
using std::make_shared;
|
||||
using std::make_tuple;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
using TinyTest::ExecuteSuite;
|
||||
using TinyTest::MakeTest;
|
||||
using TinyTest::MakeTestSuite;
|
||||
using TinyTest::TestResults;
|
||||
string no_errors = "no errors";
|
||||
|
||||
} // namespace
|
||||
|
||||
TestResults test_ConsoleLogger_LogMessage() {
|
||||
auto log_message = [](const Logger::MessageType &type, const string &message) -> string {
|
||||
ostringstream errors;
|
||||
ostringstream output;
|
||||
auto destination = make_shared<ConsoleLogger>();
|
||||
destination->SetOutputStream(output);
|
||||
destination->LogMessage(type, message);
|
||||
return output.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::ConsoleLogger::LogMessage(cosnt std::string&)",
|
||||
log_message,
|
||||
{MakeTest("should print \"[Debug] this is a message\"",
|
||||
(string) "[Debug] this is a message\n",
|
||||
make_tuple(Logger::MessageType::Debug, "this is a message")),
|
||||
MakeTest("should print \"[Error] this is an error\"",
|
||||
(string) "[Error] this is an error\n",
|
||||
make_tuple(Logger::MessageType::Error, "this is an error")),
|
||||
MakeTest("should print \"[Wtf] what a terrible failure\"",
|
||||
(string) "[Wtf] what a terrible failure\n",
|
||||
make_tuple(Logger::MessageType::Wtf, "what a terrible failure")),
|
||||
MakeTest("should print \"[Info] this is some information\"",
|
||||
(string) "[Info] this is some information\n",
|
||||
make_tuple(Logger::MessageType::Info, "this is some information")),
|
||||
MakeTest("should print \"[Warning] this is a warning\"",
|
||||
(string) "[Warning] this is a warning\n",
|
||||
make_tuple(Logger::MessageType::Warning, "this is a warning")),
|
||||
MakeTest("should print \"[Verbose] this is verbose\"",
|
||||
(string) "[Verbose] this is verbose\n",
|
||||
make_tuple(Logger::MessageType::Verbose, "this is verbose")),
|
||||
MakeTest("should print \"[Unclassified] unclassified message\"",
|
||||
(string) "[Unclassified] unclassified message\n",
|
||||
make_tuple((Logger::MessageType)1000, "unclassified message"))}));
|
||||
}
|
||||
|
||||
TestResults test_ConsoleLogger_LogErrorWithMessage() {
|
||||
auto log_error = [](const Logger::MessageType &type, const std::exception &ex) -> string {
|
||||
ostringstream errors;
|
||||
ostringstream output;
|
||||
auto destination = make_shared<ConsoleLogger>();
|
||||
destination->SetOutputStream(output);
|
||||
destination->LogError(type, ex);
|
||||
return output.str();
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::ConsoleLogger::LogError(const std::exception&)",
|
||||
log_error,
|
||||
{MakeTest("should print \"[Debug] caught exception: this is an exception\"",
|
||||
(string) "[Debug] caught exception: this is an exception\n",
|
||||
make_tuple(Logger::MessageType::Debug, std::runtime_error("this is an exception"))),
|
||||
MakeTest("should print \"[Error] caught exception: this is an error\"",
|
||||
(string) "[Error] caught exception: this is an error\n",
|
||||
make_tuple(Logger::MessageType::Error, std::runtime_error("this is an error"))),
|
||||
MakeTest("should print \"[Wtf] caught exception: what a terrible failure\"",
|
||||
(string) "[Wtf] caught exception: what a terrible failure\n",
|
||||
make_tuple(Logger::MessageType::Wtf, std::runtime_error("what a terrible failure"))),
|
||||
MakeTest("should print \"[Info] caught exception: this is some information\"",
|
||||
(string) "[Info] caught exception: this is some information\n",
|
||||
make_tuple(Logger::MessageType::Info, std::runtime_error("this is some information"))),
|
||||
MakeTest("should print \"[Warning] caught exception: this is a warning\"",
|
||||
(string) "[Warning] caught exception: this is a warning\n",
|
||||
make_tuple(Logger::MessageType::Warning, std::runtime_error("this is a warning"))),
|
||||
MakeTest("should print \"[Verbose] caught exception: this is verbose\"",
|
||||
(string) "[Verbose] caught exception: this is verbose\n",
|
||||
make_tuple(Logger::MessageType::Verbose, std::runtime_error("this is verbose"))),
|
||||
MakeTest("should print \"[Unclassified] caught exception: unclassified message\"",
|
||||
(string) "[Unclassified] caught exception: unclassified message\n",
|
||||
make_tuple((Logger::MessageType)1000, std::runtime_error("unclassified message")))}));
|
||||
}
|
||||
|
||||
TestResults test_ConsoleLogger_LogErrorWithoutMessage() {
|
||||
auto log_error = [](const Logger::MessageType &type, const std::string &message, const std::exception &ex) -> string {
|
||||
ostringstream errors;
|
||||
ostringstream output;
|
||||
auto destination = make_shared<ConsoleLogger>();
|
||||
destination->SetOutputStream(output);
|
||||
destination->LogError(type, message, ex);
|
||||
return output.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::ConsoleLogger::LogError(const std::string&, const std::exception&)",
|
||||
log_error,
|
||||
{
|
||||
MakeTest(
|
||||
"should print \"[Debug] this is a message with caught exception this is an exception\"",
|
||||
(string) "[Debug] this is a message with caught exception this is an exception\n",
|
||||
make_tuple(Logger::MessageType::Debug, "this is a message", std::runtime_error("this is an exception"))),
|
||||
MakeTest(
|
||||
"should print \"[Error] this is an error with caught exception this is an exception\"",
|
||||
(string) "[Error] this is an error with caught exception this is an exception\n",
|
||||
make_tuple(Logger::MessageType::Error, "this is an error", std::runtime_error("this is an exception"))),
|
||||
MakeTest("should print \"[Wtf] what a terrible failure with caught exception this is an exception\"",
|
||||
(string) "[Wtf] what a terrible failure with caught exception this is an exception\n",
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
"what a terrible failure",
|
||||
std::runtime_error("this is an exception"))),
|
||||
MakeTest("should print \"[Info] this is some information with caught exception this is an exception\"",
|
||||
(string) "[Info] this is some information with caught exception this is an exception\n",
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
"this is some information",
|
||||
std::runtime_error("this is an exception"))),
|
||||
MakeTest("should print \"[Warning] this is a warning with caught exception this is an exception\"",
|
||||
(string) "[Warning] this is a warning with caught exception this is an exception\n",
|
||||
make_tuple(
|
||||
Logger::MessageType::Warning, "this is a warning", std::runtime_error("this is an exception"))),
|
||||
MakeTest(
|
||||
"should print \"[Verbose] this is verbose with caught exception this is an exception\"",
|
||||
(string) "[Verbose] this is verbose with caught exception this is an exception\n",
|
||||
make_tuple(Logger::MessageType::Verbose, "this is verbose", std::runtime_error("this is an exception"))),
|
||||
MakeTest("should print \"[Unclassified] unclassified message with caught exception this is an exception\"",
|
||||
(string) "[Unclassified] unclassified message with caught exception this is an exception\n",
|
||||
make_tuple(
|
||||
(Logger::MessageType)1000, "unclassified message", std::runtime_error("this is an exception"))),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_ConsoleLogger_SetOutputStream() {
|
||||
auto set_get_output_stream = [](std::ostream &os, bool only_get) -> bool {
|
||||
auto destination = make_shared<ConsoleLogger>();
|
||||
if (!only_get) {
|
||||
destination->SetOutputStream(os);
|
||||
}
|
||||
return &destination->GetOutputStream() == &os;
|
||||
};
|
||||
std::ostringstream os1;
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::ConsoleLogger::Set/GetOutputStream(std::ostream&)",
|
||||
set_get_output_stream,
|
||||
{
|
||||
MakeTest("should get cout by default", true, make_tuple(std::ref(std::cout), true)),
|
||||
MakeTest("should set and get the same output stream", true, make_tuple(std::ref(std::cout), false)),
|
||||
MakeTest("should set and get the same output stream", true, make_tuple(std::ref((std::ostream &)os1), false)),
|
||||
}));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
TestResults results;
|
||||
|
||||
results += test_ConsoleLogger_LogMessage();
|
||||
results += test_ConsoleLogger_LogErrorWithMessage();
|
||||
results += test_ConsoleLogger_LogErrorWithoutMessage();
|
||||
results += test_ConsoleLogger_SetOutputStream();
|
||||
|
||||
PrintResults(cout, results);
|
||||
|
||||
return results.Failed() + results.Errors();
|
||||
}
|
||||
806
tests/logger_test.cpp
Normal file
806
tests/logger_test.cpp
Normal file
@@ -0,0 +1,806 @@
|
||||
/**********************************************************************************************************************
|
||||
* *
|
||||
* @file logger_test.h *
|
||||
* *
|
||||
* @brief Defines tests for the Logger class declared in logger.h. *
|
||||
* @copyright Copyright (C) 2023 by Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Licensed under the MIT license see below for details. *
|
||||
* *
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2023 Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated *
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and *
|
||||
* to permit persons to whom the Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of *
|
||||
* the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO *
|
||||
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
|
||||
* IN THE SOFTWARE. *
|
||||
* *
|
||||
**********************************************************************************************************************/
|
||||
#include "logger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "tinytest.h"
|
||||
|
||||
namespace {
|
||||
using CPPUtils::Logger;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::get;
|
||||
using std::make_optional;
|
||||
using std::make_shared;
|
||||
using std::make_tuple;
|
||||
using std::nullopt;
|
||||
using std::optional;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::runtime_error;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
using std::tuple;
|
||||
using std::vector;
|
||||
using TinyTest::ExecuteSuite;
|
||||
using TinyTest::MakeTest;
|
||||
using TinyTest::MakeTestSuite;
|
||||
using TinyTest::TestResults;
|
||||
|
||||
string no_errors = "no errors";
|
||||
typedef tuple<Logger::MessageType, optional<string>, optional<string>> LogEntry;
|
||||
|
||||
class SpyLoggerDestination : public Logger::Destination {
|
||||
public:
|
||||
SpyLoggerDestination() {
|
||||
min_type_ = Logger::MessageType::Unknown;
|
||||
max_type_ = Logger::MessageType::Wtf;
|
||||
}
|
||||
|
||||
virtual ~SpyLoggerDestination() {}
|
||||
|
||||
virtual void LogMessage(const Logger::MessageType &type, const std::string &message) const {
|
||||
log.push_back(make_tuple(type, message, nullopt));
|
||||
}
|
||||
|
||||
virtual void LogError(const Logger::MessageType &type, const std::exception &ex) const {
|
||||
log.push_back(make_tuple(type, nullopt, ex.what()));
|
||||
}
|
||||
|
||||
virtual void LogError(const Logger::MessageType &type, const std::string &message, const std::exception &ex) const {
|
||||
log.push_back(make_tuple(type, message, ex.what()));
|
||||
}
|
||||
|
||||
mutable vector<LogEntry> log;
|
||||
};
|
||||
|
||||
template <typename T> ostream &PrintOptional(ostream &os, optional<T> op) {
|
||||
if (op.has_value()) {
|
||||
os << op.value();
|
||||
} else {
|
||||
os << "nullopt";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
void ExpectMessageType(ostream &error_message, const Logger::MessageType &expected, const LogEntry &log_entry) {
|
||||
Logger::MessageType actual = get<0>(log_entry);
|
||||
if (actual != expected) {
|
||||
error_message << "Unexpected MessageType expected: " << expected << ", actual: " << actual << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectMessageText(ostream &error_message, optional<string> expected, const LogEntry &log_entry) {
|
||||
optional<string> actual = get<1>(log_entry);
|
||||
if (actual != expected) {
|
||||
error_message << "Unexpected message text. Expected: ";
|
||||
PrintOptional(error_message, expected) << ", Actual: ";
|
||||
PrintOptional(error_message, actual) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectMessageException(ostream &error_message, optional<string> expected, const LogEntry &log_entry) {
|
||||
optional<string> actual = get<2>(log_entry);
|
||||
if (actual != expected) {
|
||||
error_message << "Unexpected message exception. Expected: ";
|
||||
PrintOptional(error_message, expected) << ", Actual: ";
|
||||
PrintOptional(error_message, actual) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectLogSize(ostream &error_message, size_t expected, shared_ptr<SpyLoggerDestination> destination) {
|
||||
size_t actual = destination->log.size();
|
||||
if (actual != expected) {
|
||||
error_message << "Unexpected number of events logged. Expected: " << expected << ", Actual: " << actual << endl;
|
||||
}
|
||||
}
|
||||
|
||||
string GetError(ostringstream &error_message) {
|
||||
string error = error_message.str();
|
||||
if (error.size() > 0) {
|
||||
return error;
|
||||
}
|
||||
return no_errors;
|
||||
}
|
||||
} // End namespace
|
||||
|
||||
TestResults test_Destination_TypeRangeGettersAndSetters() {
|
||||
TestResults results;
|
||||
auto set_min_type = [](const Logger::MessageType &type) {
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
if (type == Logger::MessageType::Unknown) {
|
||||
spy->SetMinType(Logger::MessageType::Debug);
|
||||
} else {
|
||||
spy->SetMinType(Logger::MessageType::Unknown);
|
||||
}
|
||||
spy->SetMinType(type);
|
||||
return spy->GetMinType();
|
||||
};
|
||||
results += ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Logger::SetMinType(const MessageType&)",
|
||||
set_min_type,
|
||||
{
|
||||
MakeTest(
|
||||
"should set min type to Unknown", Logger::MessageType::Unknown, make_tuple(Logger::MessageType::Unknown)),
|
||||
MakeTest("should set min type to Debug", Logger::MessageType::Debug, make_tuple(Logger::MessageType::Debug)),
|
||||
MakeTest(
|
||||
"should set min type to Verbose", Logger::MessageType::Verbose, make_tuple(Logger::MessageType::Verbose)),
|
||||
MakeTest("should set min type to Info", Logger::MessageType::Info, make_tuple(Logger::MessageType::Info)),
|
||||
MakeTest(
|
||||
"should set min type to Warning", Logger::MessageType::Warning, make_tuple(Logger::MessageType::Warning)),
|
||||
MakeTest("should set min type to Error", Logger::MessageType::Error, make_tuple(Logger::MessageType::Error)),
|
||||
MakeTest("should set min type to Wtf", Logger::MessageType::Wtf, make_tuple(Logger::MessageType::Wtf)),
|
||||
MakeTest("should set min type to Unknown for an invalid MessageType",
|
||||
Logger::MessageType::Unknown,
|
||||
(make_tuple((Logger::MessageType)-1))),
|
||||
}));
|
||||
auto set_max_type = [](const Logger::MessageType &type) {
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
if (type == Logger::MessageType::Unknown) {
|
||||
spy->SetMaxType(Logger::MessageType::Debug);
|
||||
} else {
|
||||
spy->SetMaxType(Logger::MessageType::Unknown);
|
||||
}
|
||||
spy->SetMaxType(type);
|
||||
return spy->GetMaxType();
|
||||
};
|
||||
results += ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Logger::SetMaxType(const MessageType&)",
|
||||
set_max_type,
|
||||
{
|
||||
MakeTest(
|
||||
"should set max type to Unknown", Logger::MessageType::Unknown, make_tuple(Logger::MessageType::Unknown)),
|
||||
MakeTest("should set max type to Debug", Logger::MessageType::Debug, make_tuple(Logger::MessageType::Debug)),
|
||||
MakeTest(
|
||||
"should set max type to Verbose", Logger::MessageType::Verbose, make_tuple(Logger::MessageType::Verbose)),
|
||||
MakeTest("should set max type to Info", Logger::MessageType::Info, make_tuple(Logger::MessageType::Info)),
|
||||
MakeTest(
|
||||
"should set max type to Warning", Logger::MessageType::Warning, make_tuple(Logger::MessageType::Warning)),
|
||||
MakeTest("should set max type to Error", Logger::MessageType::Error, make_tuple(Logger::MessageType::Error)),
|
||||
MakeTest("should set max type to Wtf", Logger::MessageType::Wtf, make_tuple(Logger::MessageType::Wtf)),
|
||||
MakeTest("should set max type to Unknown for an invalid MessageType",
|
||||
Logger::MessageType::Unknown,
|
||||
(make_tuple((Logger::MessageType)-1))),
|
||||
}));
|
||||
return results;
|
||||
}
|
||||
|
||||
TestResults test_Logger_GetShared() {
|
||||
auto function_to_test = []() {
|
||||
auto first = Logger::GetShared();
|
||||
auto second = Logger::GetShared();
|
||||
return first == second;
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::Logger::GetShared()",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should get the same instance twice", true, make_tuple()),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Logger_GetUnique() {
|
||||
auto get_unique_is_different = []() {
|
||||
auto first = Logger::GetUnique();
|
||||
auto second = Logger::GetUnique();
|
||||
return first != second;
|
||||
};
|
||||
|
||||
auto get_unique_is_not_get_shared = []() {
|
||||
auto shared = Logger::GetShared();
|
||||
auto unique = Logger::GetUnique();
|
||||
return unique != shared;
|
||||
};
|
||||
|
||||
TestResults results;
|
||||
|
||||
results += ExecuteSuite(MakeTestSuite("CPPUtils::Logger::GetUnique()",
|
||||
get_unique_is_different,
|
||||
{
|
||||
MakeTest("should get two different instances", true, make_tuple()),
|
||||
}));
|
||||
|
||||
results += ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::Logger::GetUnique()",
|
||||
get_unique_is_not_get_shared,
|
||||
{
|
||||
MakeTest("should get and instance that is not the shared instance", true, make_tuple()),
|
||||
}));
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
TestResults test_LogUnimplementedMethod() {
|
||||
#if __cplusplus >= 202002L
|
||||
return TestResults().fail("Not implemented for c++20 yet.");
|
||||
|
||||
ostringstream error_message;
|
||||
error_message << "Unimplemented method: \"" << location.function_name() << "\" at " << location.file_name() << " ("
|
||||
<< location.line() << ":" << location.column() << ")";
|
||||
LogDebug(error_message.str());
|
||||
// TODO: see what this results in when run in c++20 and test for those values.
|
||||
#else
|
||||
auto function_to_test = [](string method_name) -> string {
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
auto logger = Logger::GetUnique();
|
||||
logger->AddDestination(spy);
|
||||
#if __cplusplus >= 202002L
|
||||
std::source_location loc;
|
||||
logger->LogUnimplementedMethod()
|
||||
#else
|
||||
logger->LogUnimplementedMethodReal(method_name);
|
||||
#endif
|
||||
ostringstream error_message;
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, Logger::MessageType::Debug, message);
|
||||
ExpectMessageText(error_message, "Unimplemented method: int main(int argc, char* argv[])", message);
|
||||
ExpectMessageException(error_message, nullopt, message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Logger::LogUnimplementedMethod",
|
||||
function_to_test,
|
||||
{
|
||||
MakeTest("should log a debug message", no_errors, make_tuple("int main(int argc, char* argv[])")),
|
||||
}));
|
||||
#endif
|
||||
}
|
||||
|
||||
TestResults test_Logger_LogUnhandledError() {
|
||||
auto log_unhandled_error = []() {
|
||||
auto logger = Logger::GetUnique();
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
logger->AddDestination(spy);
|
||||
std::exception ex;
|
||||
logger->LogUnhandledError(ex);
|
||||
ostringstream error_message;
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, Logger::MessageType::Debug, message);
|
||||
ExpectMessageText(error_message, "Unhandled exception", message);
|
||||
ExpectMessageException(error_message, ex.what(), message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::Logger::LogUnhandledError(const std::exception&)",
|
||||
log_unhandled_error,
|
||||
{
|
||||
MakeTest("should log an error", no_errors, make_tuple()),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Logger_LogUnimplementedFeature() {
|
||||
auto log_unimplemented_feature = []() {
|
||||
auto logger = Logger::GetUnique();
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
logger->AddDestination(spy);
|
||||
string feature_name = "rolling over";
|
||||
logger->LogUnimplementedFeature(feature_name);
|
||||
ostringstream error_message;
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, Logger::MessageType::Debug, message);
|
||||
ExpectMessageText(error_message, "Unimplemented feature: " + feature_name, message);
|
||||
ExpectMessageException(error_message, nullopt, message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("CPPUtils::Logger::LogUnimplementedFeature()",
|
||||
log_unimplemented_feature,
|
||||
{
|
||||
MakeTest("should log an unimplemented feature", no_errors, make_tuple()),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Logger_Log_Level() {
|
||||
auto log = [](const Logger::MessageType &type,
|
||||
const optional<string> &message_text,
|
||||
const optional<std::exception> &ex) -> string {
|
||||
ostringstream error_message;
|
||||
auto logger = Logger::GetUnique();
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
logger->AddDestination(spy);
|
||||
switch (type) {
|
||||
case Logger::MessageType::Debug:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->LogDebug(message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->LogDebug(message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->LogDebug(ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Verbose:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->LogVerbose(message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->LogVerbose(message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->LogVerbose(ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Info:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->LogInfo(message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->LogInfo(message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->LogInfo(ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Warning:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->LogWarning(message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->LogWarning(message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->LogWarning(ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Error:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->LogError(message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->LogError(message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->LogError(ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Wtf:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->LogWtf(message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->LogWtf(message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->LogWtf(ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, type, message);
|
||||
ExpectMessageText(error_message, message_text, message);
|
||||
ExpectMessageException(error_message, ex.has_value() ? make_optional(ex.value().what()) : nullopt, message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::Logger::Log*(...)",
|
||||
log,
|
||||
{
|
||||
MakeTest("should log what a terrible failure with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log what a terrible failure with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log what a terrible failure with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an error with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log an error with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an error with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a warning with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log a warning with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a warning with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an info with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log an info with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an info with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a debug with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log a debug with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a debug with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a verbose with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log a verbose with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a verbose with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Logger_Log() {
|
||||
auto log = [](const Logger::MessageType &type,
|
||||
const optional<string> &message_text,
|
||||
const optional<std::exception> &ex) -> string {
|
||||
ostringstream error_message;
|
||||
auto logger = Logger::GetUnique();
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
logger->AddDestination(spy);
|
||||
switch (type) {
|
||||
case Logger::MessageType::Debug:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Debug, message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->Log(Logger::MessageType::Debug, message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Debug, ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Verbose:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Verbose, message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->Log(Logger::MessageType::Verbose, message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Verbose, ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Info:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Info, message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->Log(Logger::MessageType::Info, message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Info, ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Warning:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Warning, message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->Log(Logger::MessageType::Warning, message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Warning, ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Error:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Error, message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->Log(Logger::MessageType::Error, message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Error, ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Logger::MessageType::Wtf:
|
||||
if (message_text.has_value()) {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Wtf, message_text.value(), ex.value());
|
||||
} else {
|
||||
logger->Log(Logger::MessageType::Wtf, message_text.value());
|
||||
}
|
||||
} else {
|
||||
if (ex.has_value()) {
|
||||
logger->Log(Logger::MessageType::Wtf, ex.value());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, type, message);
|
||||
ExpectMessageText(error_message, message_text, message);
|
||||
ExpectMessageException(error_message, ex.has_value() ? make_optional(ex.value().what()) : nullopt, message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::Logger::Log(const MessageType&, ...)",
|
||||
log,
|
||||
{
|
||||
MakeTest("should log what a terrible failure with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log what a terrible failure with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log what a terrible failure with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an error with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log an error with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an error with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a warning with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log a warning with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a warning with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an info with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log an info with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log an info with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a debug with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log a debug with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a debug with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a verbose with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)nullopt)),
|
||||
MakeTest("should log a verbose with a message and an exception",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
(const optional<string> &)"this should never happen",
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
MakeTest("should log a verbose with a message",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
(const optional<string> &)nullopt,
|
||||
(const optional<std::exception> &)runtime_error("bad thing happen"))),
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Logger_LogToDo() {
|
||||
auto log_to_do = [](const string &todo_message) {
|
||||
auto logger = Logger::GetUnique();
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
logger->AddDestination(spy);
|
||||
logger->LogToDo(todo_message);
|
||||
ostringstream error_message;
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, Logger::MessageType::Debug, message);
|
||||
ExpectMessageText(error_message, "TODO: " + todo_message, message);
|
||||
ExpectMessageException(error_message, nullopt, message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::Logger::LogToDo(const std:;string&)",
|
||||
log_to_do,
|
||||
{
|
||||
MakeTest("should log a TODO for \"fill in this function\"", no_errors, make_tuple("fill in this function")),
|
||||
MakeTest("should log a TODO for \"delete this after fixing bug:2048\"",
|
||||
no_errors,
|
||||
make_tuple("delete this after fixing bug:2048")),
|
||||
MakeTest("should log a TODO for \"refactor this\"", no_errors, make_tuple("refactor this")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_Logger_AddDestination_and_ClearDestinations() {
|
||||
auto add_destination = []() {
|
||||
ostringstream error_message;
|
||||
auto logger = Logger::GetUnique();
|
||||
auto spy = make_shared<SpyLoggerDestination>();
|
||||
ExpectLogSize(error_message, 0, spy);
|
||||
logger->LogInfo("first message");
|
||||
ExpectLogSize(error_message, 0, spy);
|
||||
logger->AddDestination(spy);
|
||||
ExpectLogSize(error_message, 0, spy);
|
||||
logger->LogInfo("second message");
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
logger->ClearDestinations();
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
logger->LogInfo("third message");
|
||||
ExpectLogSize(error_message, 1, spy);
|
||||
if (spy->log.size() > 0) {
|
||||
auto message = spy->log.at(0);
|
||||
ExpectMessageType(error_message, Logger::MessageType::Info, message);
|
||||
ExpectMessageText(error_message, "second message", message);
|
||||
ExpectMessageException(error_message, nullopt, message);
|
||||
}
|
||||
return GetError(error_message);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite("",
|
||||
add_destination,
|
||||
{
|
||||
MakeTest("should add and clear destinations", no_errors, make_tuple()),
|
||||
}));
|
||||
}
|
||||
|
||||
// AddDestination
|
||||
// ClearDestinations
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
TestResults results;
|
||||
|
||||
results += test_Destination_TypeRangeGettersAndSetters();
|
||||
results += test_Logger_GetShared();
|
||||
results += test_Logger_GetUnique();
|
||||
results += test_LogUnimplementedMethod();
|
||||
results += test_Logger_LogUnhandledError();
|
||||
results += test_Logger_LogUnimplementedFeature();
|
||||
results += test_Logger_Log_Level();
|
||||
results += test_Logger_Log();
|
||||
results += test_Logger_LogToDo();
|
||||
results += test_Logger_AddDestination_and_ClearDestinations();
|
||||
|
||||
PrintResults(cout, results);
|
||||
|
||||
return results.Failed() + results.Errors();
|
||||
}
|
||||
447
tests/pretty_print_test.cpp
Normal file
447
tests/pretty_print_test.cpp
Normal file
@@ -0,0 +1,447 @@
|
||||
/**********************************************************************************************************************
|
||||
* *
|
||||
* @file pretty_print_test.cpp *
|
||||
* *
|
||||
* @brief Defines test for the printing functions declared in pretty_print.h. *
|
||||
* @copyright Copyright (C) 2023 by Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Licensed under the MIT license see below for details. *
|
||||
* *
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2023 Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated *
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and *
|
||||
* to permit persons to whom the Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of *
|
||||
* the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO *
|
||||
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
|
||||
* IN THE SOFTWARE. *
|
||||
* *
|
||||
**********************************************************************************************************************/
|
||||
// clang-format off
|
||||
#include "pretty_print.h"
|
||||
#include "tinytest.h"
|
||||
// clang-format on
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
using std::make_tuple;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using TinyTest::ExecuteSuite;
|
||||
using TinyTest::MakeTest;
|
||||
using TinyTest::MakeTestSuite;
|
||||
using TinyTest::TestResults;
|
||||
using namespace CPPUtils;
|
||||
using std::wstring;
|
||||
} // End namespace
|
||||
|
||||
TestResults test_EscapeForPrintingWithAConstCharPointer() {
|
||||
TestResults results;
|
||||
auto escape_const_char_pointer = [](const char *value) -> string { return EscapeForPrinting(value); };
|
||||
results += ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::EscapeForPrinting(const char*)",
|
||||
escape_const_char_pointer,
|
||||
{
|
||||
MakeTest("should escape an empty string", (string) "", make_tuple("")),
|
||||
MakeTest("should esacpe a string with no special characters",
|
||||
(string) "This is a normal string.",
|
||||
make_tuple("This is a normal string.")),
|
||||
MakeTest("should escape the escape character by itself", (string) "\\033", make_tuple("\033")),
|
||||
MakeTest("should escape the escape character within a string",
|
||||
(string) "This string has an \\033 in it.",
|
||||
make_tuple("This string has an \033 in it.")),
|
||||
}));
|
||||
return results;
|
||||
}
|
||||
|
||||
TestResults test_EscapeForPrintingWithAString() {
|
||||
TestResults results;
|
||||
auto escape_string = [](const string &value) -> string { return EscapeForPrinting(value); };
|
||||
results += ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::EscapeForPrinting(const std::string&)",
|
||||
escape_string,
|
||||
{
|
||||
MakeTest("should escape an empty string", (string) "", make_tuple((string) "")),
|
||||
MakeTest("should escape a string with no special characters",
|
||||
(string) "This is a normal string.",
|
||||
make_tuple((string) "This is a normal string.")),
|
||||
MakeTest("should escape the escape character by itself", (string) "\\033", make_tuple((string) "\033")),
|
||||
MakeTest("should escape the escape character within a string",
|
||||
(string) "This string has an \\033 in it.",
|
||||
make_tuple((string) "This string has an \033 in it.")),
|
||||
}));
|
||||
return results;
|
||||
}
|
||||
|
||||
TestResults test_EscapeForPrintingWithAStringView() {
|
||||
auto escape_string_view = [](const string_view &value) -> string { return EscapeForPrinting(value); };
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::EscapeForPrinting(const std::string_view&)",
|
||||
escape_string_view,
|
||||
{
|
||||
MakeTest("should escape an empty string", (string) "", make_tuple((string_view) "")),
|
||||
MakeTest("should escape a string with no special characters",
|
||||
(string) "This is a normal string.",
|
||||
make_tuple((string_view) "This is a normal string.")),
|
||||
MakeTest("should escape the escape character by itself", (string) "\\033", make_tuple((string_view) "\033")),
|
||||
MakeTest("should escape the escape character within a string",
|
||||
(string) "This string has an \\033 in it.",
|
||||
make_tuple((string_view) "This string has an \033 in it.")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithAConstCharPointer() {
|
||||
auto pretty_print = [](const char *value) -> string {
|
||||
ostringstream os;
|
||||
PrettyPrint(os, value);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::PrettyPrint(std::ostream&, const char*)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print \"\" for an empty string", (string) "\"\"", make_tuple("")),
|
||||
MakeTest("should print \"hello world\"", (string) "\"hello world\"", make_tuple("hello world")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithAString() {
|
||||
auto pretty_print = [](const string &value) -> string {
|
||||
ostringstream os;
|
||||
PrettyPrint(os, value);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrint(std::ostream&, const std::string&)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print \"\" for an empty string", (string) "\"\"", make_tuple((string) "")),
|
||||
MakeTest("should print \"hello world\"", (string) "\"hello world\"", make_tuple((string) "hello world")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithAStringView() {
|
||||
auto pretty_print = [](const std::string_view &value) -> string {
|
||||
ostringstream os;
|
||||
PrettyPrint(os, value);
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrint(std::ostream&, const std::string_view&)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print \"\" for an empty string", (string) "\"\"", make_tuple((string_view) "")),
|
||||
MakeTest("should print \"hello world\"", (string) "\"hello world\"", make_tuple((string_view) "hello world")),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithATuple() {
|
||||
auto pretty_print = [](int i) -> string {
|
||||
ostringstream os;
|
||||
switch (i) {
|
||||
case 1:
|
||||
PrettyPrint(os, make_tuple(1, "hello", 9));
|
||||
break;
|
||||
case 2:
|
||||
PrettyPrint(os, make_tuple());
|
||||
break;
|
||||
case 3:
|
||||
PrettyPrint(os, make_tuple("one", "two", "three"));
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrint(std::ostream&, std::tuple)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print a tuple of mixed types", (string) "[ 1, \"hello\", 9 ]", make_tuple(1)),
|
||||
MakeTest("should print an empty tuple", (string) "[]", make_tuple(2)),
|
||||
MakeTest("should print a tuple of strings", (string) "[ \"one\", \"two\", \"three\" ]", make_tuple(3)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithAnInitializerList() {
|
||||
auto pretty_print = [](int i) {
|
||||
ostringstream os;
|
||||
std::initializer_list<string> empty_initializer_list = {};
|
||||
switch (i) {
|
||||
case 1:
|
||||
PrettyPrint(os, {"one", "two", "three"});
|
||||
break;
|
||||
case 2:
|
||||
PrettyPrint(os, empty_initializer_list);
|
||||
break;
|
||||
case 3:
|
||||
PrettyPrint(os, {1, 2, 3});
|
||||
break;
|
||||
case 4:
|
||||
PrettyPrint(os, {"one", "two", "three", "four"});
|
||||
break;
|
||||
case 5:
|
||||
PrettyPrint(os, {1.1, 2.2, 3.3});
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrint(std::ostream&, std::initializer_list)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest(
|
||||
"should print an initializer_list of strings", (string) "[ \"one\", \"two\", \"three\" ]", make_tuple(1)),
|
||||
MakeTest("should print an empty initializer_list", (string) "[]", make_tuple(2)),
|
||||
MakeTest("should print an initializer_list of integers", (string) "[ 1, 2, 3 ]", make_tuple(3)),
|
||||
MakeTest("should print an initializer_list of strings with four elements",
|
||||
(string) "[ \"one\", \"two\", \"three\", \"four\" ]",
|
||||
make_tuple(4)),
|
||||
MakeTest("should print an initializer_list of doubles", (string) "[ 1.1, 2.2, 3.3 ]", make_tuple(5)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithDifferentContainerTypes() {
|
||||
auto pretty_print = [](int i) {
|
||||
ostringstream os;
|
||||
switch (i) {
|
||||
case 1: {
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
PrettyPrint(os, v);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::queue<int> q;
|
||||
q.push(1);
|
||||
q.push(2);
|
||||
q.push(3);
|
||||
PrettyPrint(os, q);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
std::vector<string> v = {"one", "two", "three"};
|
||||
PrettyPrint(os, v);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::queue<string> q;
|
||||
q.push("one");
|
||||
q.push("two");
|
||||
q.push("three");
|
||||
PrettyPrint(os, q);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrint(std::ostream&, TContainer)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print a vector of integers", (string) "[ 1, 2, 3 ]", make_tuple(1)),
|
||||
MakeTest("should print a queue of integers", (string) "[ 1, 2, 3 ]", make_tuple(2)),
|
||||
MakeTest("should print a vector of strings", (string) "[ \"one\", \"two\", \"three\" ]", make_tuple(3)),
|
||||
MakeTest("should print a queue of strings", (string) "[ \"one\", \"two\", \"three\" ]", make_tuple(4)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithSimpleTypes() {
|
||||
TestResults results;
|
||||
|
||||
auto pretty_print_int = [](int value) -> string {
|
||||
ostringstream os;
|
||||
PrettyPrint(os, value);
|
||||
return os.str();
|
||||
};
|
||||
results += ExecuteSuite(MakeTestSuite("CPPUtils::PrettyPrint(std::ostream&, const TItem&)",
|
||||
pretty_print_int,
|
||||
{
|
||||
MakeTest("should print 42 for an int", (string) "42", make_tuple(42)),
|
||||
}));
|
||||
|
||||
auto pretty_print_float = [](float value) -> string {
|
||||
ostringstream os;
|
||||
PrettyPrint(os, value);
|
||||
return os.str();
|
||||
};
|
||||
results +=
|
||||
ExecuteSuite(MakeTestSuite("CPPUtils::PrettyPrint(std::ostream&, const TItem&)",
|
||||
pretty_print_float,
|
||||
{
|
||||
MakeTest("should print 3.14 for a float", (string) "3.14", make_tuple(3.14f)),
|
||||
}));
|
||||
|
||||
auto pretty_print_string = [](const string &value) -> string {
|
||||
ostringstream os;
|
||||
PrettyPrint(os, value);
|
||||
return os.str();
|
||||
};
|
||||
results += ExecuteSuite(MakeTestSuite("CPPUtils::PrettyPrint(std::ostream&, const TItem&)",
|
||||
pretty_print_string,
|
||||
{
|
||||
MakeTest("should print \"hello world\" for a string",
|
||||
(string) "\"hello world\"",
|
||||
make_tuple((string) "hello world")),
|
||||
}));
|
||||
return results;
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithAPair() {
|
||||
auto pretty_print = [](int id) -> string {
|
||||
ostringstream os;
|
||||
switch (id) {
|
||||
case 1:
|
||||
PrettyPrint(os, std::make_pair(1, 2));
|
||||
break;
|
||||
case 2:
|
||||
PrettyPrint(os, std::make_pair(3.14f, 42));
|
||||
break;
|
||||
case 3:
|
||||
PrettyPrint(os, std::make_pair((string) "hello", (string) "world"));
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrint(std::ostream&, const std::pair<T1, T2>&)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print (1, 2) for a pair of ints", (string) "(1, 2)", make_tuple(1)),
|
||||
MakeTest("should print (3.14, 42) for a pair of float and int", (string) "(3.14, 42)", make_tuple(2)),
|
||||
MakeTest("should print (\"hello\", \"world\") for a pair of strings",
|
||||
(string) "(\"hello\", \"world\")",
|
||||
make_tuple(3)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithSeparatorWithAConstCharPointer() {
|
||||
auto pretty_print = [](const char *separator, int id) -> string {
|
||||
ostringstream os;
|
||||
switch (id) {
|
||||
case 1:
|
||||
PrettyPrintWithSeparator(os, separator, 1, 2, 3);
|
||||
break;
|
||||
case 2:
|
||||
PrettyPrintWithSeparator(os, separator, 3.14f, 42, (string) "hello world");
|
||||
break;
|
||||
case 3:
|
||||
PrettyPrintWithSeparator(os, separator, (string) "hello", (string) "world");
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(
|
||||
MakeTestSuite("CPPUtils::PrettyPrintWithSeparator(std::ostream&, const TChar*, Args&&...)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print 1, 2, 3 for a list of ints", (string) "1, 2, 3", make_tuple(", ", 1)),
|
||||
MakeTest("should print 3.14; 42; \"hello world\" for a list of float, int and string",
|
||||
(string) "3.14; 42; \"hello world\"",
|
||||
make_tuple("; ", 2)),
|
||||
MakeTest("should print \"hello\" \"world\" for a list of strings",
|
||||
(string) "\"hello\" \"world\"",
|
||||
make_tuple(" ", 3)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithSeparatorWithAString() {
|
||||
auto pretty_print = [](const string &separator, int id) -> string {
|
||||
ostringstream os;
|
||||
switch (id) {
|
||||
case 1:
|
||||
PrettyPrintWithSeparator(os, separator, 1, 2, 3);
|
||||
break;
|
||||
case 2:
|
||||
PrettyPrintWithSeparator(os, separator, 3.14f, 42, (string) "hello world");
|
||||
break;
|
||||
case 3:
|
||||
PrettyPrintWithSeparator(os, separator, (string) "hello", (string) "world");
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrintWithSeparator(std::ostream&, const TChar*, Args&&...)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest("should print 1 | 2 | 3 for a list of ints", (string) "1 | 2 | 3", make_tuple((string) " | ", 1)),
|
||||
MakeTest("should print 3.14 / 42 / \"hello world\" for a list of float, int and string",
|
||||
(string) "3.14 / 42 / \"hello world\"",
|
||||
make_tuple((string) " / ", 2)),
|
||||
MakeTest("should print \"hello\" - \"world\" for a list of strings",
|
||||
(string) "\"hello\" - \"world\"",
|
||||
make_tuple((string) " - ", 3)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_PrettyPrintWithSeparatorWithAStringView() {
|
||||
auto pretty_print = [](const string_view &separator, int id) -> string {
|
||||
ostringstream os;
|
||||
switch (id) {
|
||||
case 1:
|
||||
PrettyPrintWithSeparator(os, separator, 1, 2, 3);
|
||||
break;
|
||||
case 2:
|
||||
PrettyPrintWithSeparator(os, separator, 3.14f, 42, "hello world");
|
||||
break;
|
||||
case 3:
|
||||
PrettyPrintWithSeparator(os, separator, "hello", "world");
|
||||
break;
|
||||
}
|
||||
return os.str();
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::PrettyPrintWithSeparator(std::ostream&, const TChar*, Args&&...)",
|
||||
pretty_print,
|
||||
{
|
||||
MakeTest(
|
||||
"should print 1 | 2 | 3 for a list of ints", (string) "1 | 2 | 3", make_tuple((string_view) " | ", 1)),
|
||||
MakeTest("should print 3.14 / 42 / \"hello world\" for a list of float, int and string",
|
||||
(string) "3.14 / 42 / \"hello world\"",
|
||||
make_tuple((string_view) " / ", 2)),
|
||||
MakeTest("should print \"hello\" - \"world\" for a list of strings",
|
||||
(string) "\"hello\" - \"world\"",
|
||||
make_tuple((string_view) " - ", 3)),
|
||||
}));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
setlocale(LC_ALL, "");
|
||||
TestResults results;
|
||||
|
||||
results += test_EscapeForPrintingWithAConstCharPointer();
|
||||
results += test_EscapeForPrintingWithAString();
|
||||
results += test_EscapeForPrintingWithAStringView();
|
||||
|
||||
results += test_PrettyPrintWithAConstCharPointer();
|
||||
results += test_PrettyPrintWithAString();
|
||||
results += test_PrettyPrintWithAStringView();
|
||||
results += test_PrettyPrintWithATuple();
|
||||
results += test_PrettyPrintWithAnInitializerList();
|
||||
results += test_PrettyPrintWithDifferentContainerTypes();
|
||||
results += test_PrettyPrintWithSimpleTypes();
|
||||
results += test_PrettyPrintWithAPair();
|
||||
|
||||
results += test_PrettyPrintWithSeparatorWithAConstCharPointer();
|
||||
results += test_PrettyPrintWithSeparatorWithAString();
|
||||
results += test_PrettyPrintWithSeparatorWithAStringView();
|
||||
|
||||
return results.Failed() + results.Errors();
|
||||
}
|
||||
1251
tests/tinytest_test.cpp
Normal file
1251
tests/tinytest_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
527
tests/windows_logger_test.cpp
Normal file
527
tests/windows_logger_test.cpp
Normal file
@@ -0,0 +1,527 @@
|
||||
/**********************************************************************************************************************
|
||||
* *
|
||||
* @file windows_logger_test.cpp *
|
||||
* *
|
||||
* @brief Defines tests for the WindowsLogger logging destination class declared in windows_logger.h. *
|
||||
* This logging destination works with the Logger class declared in logger.h and logs messages by creating a modal *
|
||||
* windows message box *
|
||||
* @copyright Copyright (C) 2023 by Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Licensed under the MIT license see below for details. *
|
||||
* *
|
||||
* MIT License *
|
||||
* *
|
||||
* Copyright (c) 2023 Tom Hicks <headhunter3@gmail.com> *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated *
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation *
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and *
|
||||
* to permit persons to whom the Software is furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of *
|
||||
* the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO *
|
||||
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
|
||||
* IN THE SOFTWARE. *
|
||||
* *
|
||||
**********************************************************************************************************************/
|
||||
#include "windows_logger.h"
|
||||
#ifdef _WIN32
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
#include <winuser.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "tinytest.h"
|
||||
|
||||
namespace {
|
||||
using CPPUtils::Logger;
|
||||
using CPPUtils::WindowsLogger;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::get;
|
||||
using std::hex;
|
||||
using std::make_shared;
|
||||
using std::make_tuple;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
using std::tuple;
|
||||
using std::vector;
|
||||
using TinyTest::ExecuteSuite;
|
||||
using TinyTest::MakeTest;
|
||||
using TinyTest::MakeTestSuite;
|
||||
using TinyTest::TestResults;
|
||||
string no_errors = "no errors";
|
||||
typedef tuple<string, string, UINT> MessageBoxEvent;
|
||||
|
||||
/// @brief
|
||||
class WindowsLoggerSpy : public WindowsLogger {
|
||||
public:
|
||||
/// @brief
|
||||
mutable vector<MessageBoxEvent> log;
|
||||
|
||||
protected:
|
||||
/// @brief
|
||||
/// @param body
|
||||
/// @param title
|
||||
/// @param u_type
|
||||
virtual void ShowMessageBox(const string &body, const string &title, UINT u_type) const override {
|
||||
log.push_back(make_tuple(body, title, u_type));
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief
|
||||
/// @param errors
|
||||
/// @param expected
|
||||
/// @param spy
|
||||
void ExpectLogSize(ostream &errors, size_t expected, const shared_ptr<WindowsLoggerSpy> &spy) {
|
||||
size_t actual = spy->log.size();
|
||||
if (actual != expected) {
|
||||
errors << "Log size mismatch. Expected: " << expected << ", Actual: " << actual << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param errors
|
||||
/// @param expected
|
||||
/// @param event
|
||||
void ExpectMessage(ostream &errors, const string &expected, const MessageBoxEvent &event) {
|
||||
string actual = get<0>(event);
|
||||
if (actual != expected) {
|
||||
errors << "Message mismatch. Expected: " << expected << ", Actual: " << actual << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param errors
|
||||
/// @param expected
|
||||
/// @param event
|
||||
void ExpectTitle(ostream &errors, const string &expected, const MessageBoxEvent &event) {
|
||||
string actual = get<1>(event);
|
||||
if (actual != expected) {
|
||||
errors << "Title mismatch. Expected: \"" << expected << "\", Actual: \"" << actual << "\"" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param parts
|
||||
/// @param separator
|
||||
/// @return
|
||||
string Join(vector<string> parts, const string &separator) {
|
||||
ostringstream os;
|
||||
|
||||
bool first = true;
|
||||
;
|
||||
for_each(parts.begin(), parts.end(), [&os, &first, separator](string part) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
os << separator;
|
||||
}
|
||||
os << part;
|
||||
});
|
||||
return os.str();
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param u_type
|
||||
/// @param ignore_defaults
|
||||
/// @return
|
||||
string ConvertUTypeToString(UINT u_type, bool ignore_defaults = true) {
|
||||
UINT u_button = u_type & MB_TYPEMASK;
|
||||
UINT u_icon = u_type & MB_ICONMASK;
|
||||
UINT u_default_button = u_type & MB_DEFMASK;
|
||||
UINT u_mode = u_type & MB_MODEMASK;
|
||||
UINT u_misc = u_type & MB_MISCMASK;
|
||||
|
||||
vector<string> parts;
|
||||
|
||||
// MB_OK = 0x00000000L
|
||||
if (u_button == MB_OK) {
|
||||
parts.push_back("MB_OK");
|
||||
}
|
||||
// MB_OKCANCEL = 0x00000001L
|
||||
if (u_button == MB_OKCANCEL) {
|
||||
parts.push_back("MB_OKCANCEL");
|
||||
}
|
||||
// MB_ABORTRETRYIGNORE = 0x00000002L
|
||||
if (u_button == MB_ABORTRETRYIGNORE) {
|
||||
parts.push_back("MB_ABORTRETRYIGNORE");
|
||||
}
|
||||
// MB_YESNOCANCEL = 0x00000003L
|
||||
if (u_button == MB_YESNOCANCEL) {
|
||||
parts.push_back("MB_YESNOCANCEL");
|
||||
}
|
||||
// MB_YESNO = 0x00000004L
|
||||
if (u_button == MB_YESNO) {
|
||||
parts.push_back("MB_YESNO");
|
||||
}
|
||||
// MB_RETRYCANCEL = 0x00000005L
|
||||
if (u_button == MB_RETRYCANCEL) {
|
||||
parts.push_back("MB_RETRYCANCEL");
|
||||
}
|
||||
// MB_CANCELTRYCONTINUE = 0x00000006L
|
||||
if (u_button == MB_CANCELTRYCONTINUE) {
|
||||
parts.push_back("MB_CANCELTRYCONTINUE");
|
||||
}
|
||||
|
||||
// MB_ICONHAND = 0x00000010L
|
||||
if (u_icon == MB_ICONHAND) {
|
||||
parts.push_back("MB_ICONHAND");
|
||||
}
|
||||
// MB_ICONQUESTION = 0x00000020L
|
||||
if (u_icon == MB_ICONQUESTION) {
|
||||
parts.push_back("MB_ICONQUESTION");
|
||||
}
|
||||
// MB_ICONEXCLAMATION = 0x00000030L
|
||||
if (u_icon == MB_ICONEXCLAMATION) {
|
||||
parts.push_back("MB_ICONEXCLAMATION");
|
||||
}
|
||||
// MB_ICONASTERISK = 0x00000040L
|
||||
if (u_icon == MB_ICONASTERISK) {
|
||||
parts.push_back("MB_ICONASTERISK");
|
||||
}
|
||||
// MB_USERICON = 0x00000080L
|
||||
if (u_icon == MB_USERICON) {
|
||||
parts.push_back("MB_USERICON");
|
||||
}
|
||||
|
||||
// MB_DEFBUTTON1 = 0x00000000L
|
||||
if (u_default_button == MB_DEFBUTTON1 && !ignore_defaults) {
|
||||
parts.push_back("MB_DEFBUTTON1");
|
||||
}
|
||||
// MB_DEFBUTTON2 = 0x00000100L
|
||||
if (u_default_button == MB_DEFBUTTON2) {
|
||||
parts.push_back("MB_DEFBUTTON2");
|
||||
}
|
||||
// MB_DEFBUTTON3 = 0x00000200L
|
||||
if (u_default_button == MB_DEFBUTTON3) {
|
||||
parts.push_back("MB_DEFBUTTON3");
|
||||
}
|
||||
// MB_DEFBUTTON4 = 0x00000300L
|
||||
if (u_default_button == MB_DEFBUTTON4) {
|
||||
parts.push_back("MB_DEFBUTTON4");
|
||||
}
|
||||
|
||||
// MB_APPLMODAL = 0x00000000L
|
||||
if (u_mode == MB_APPLMODAL && !ignore_defaults) {
|
||||
parts.push_back("MB_APPLMODAL");
|
||||
}
|
||||
// MB_SYSTEMMODAL = 0x00001000L
|
||||
if (u_mode == MB_SYSTEMMODAL) {
|
||||
parts.push_back("MB_SYSTEMMODAL");
|
||||
}
|
||||
// MB_TASKMODAL = 0x00002000L
|
||||
if (u_mode == MB_TASKMODAL) {
|
||||
parts.push_back("MB_TASKMODAL");
|
||||
}
|
||||
// MB_HELP = 0x00004000L
|
||||
if (u_mode == MB_HELP) {
|
||||
parts.push_back("MB_HELP");
|
||||
}
|
||||
// MB_NOFOCUS = 0x00008000L
|
||||
if (u_mode == MB_NOFOCUS) {
|
||||
parts.push_back("MB_NOFOCUS");
|
||||
}
|
||||
|
||||
// MB_SETFOREGROUND = 0x00010000L
|
||||
if (u_misc == MB_SETFOREGROUND) {
|
||||
parts.push_back("MB_SETFOREGROUND");
|
||||
}
|
||||
// MB_DEFAULT_DESKTOP_ONLY = 0x00020000L
|
||||
if (u_misc == MB_DEFAULT_DESKTOP_ONLY) {
|
||||
parts.push_back("MB_DEFAULT_DESKTOP_ONLY");
|
||||
}
|
||||
// MB_TOPMOST = 0x00040000L
|
||||
if (u_misc == MB_TOPMOST) {
|
||||
parts.push_back("MB_TOPMOST");
|
||||
}
|
||||
// MB_RIGHT = 0x00080000L
|
||||
if (u_misc == MB_RIGHT) {
|
||||
parts.push_back("MB_RIGHT");
|
||||
}
|
||||
|
||||
// MB_RTLREADING = 0x00100000L
|
||||
if (u_misc == MB_RTLREADING) {
|
||||
parts.push_back("MB_RTLREADING");
|
||||
}
|
||||
// MB_SERVICE_NOTIFICATION = 0x00200000L
|
||||
// MB_SERVICE_NOTIFICATION = 0x00040000L
|
||||
if ((u_misc == MB_SERVICE_NOTIFICATION) || (u_misc == MB_SERVICE_NOTIFICATION)) {
|
||||
parts.push_back("MB_SERVICE_NOTIFICATION");
|
||||
}
|
||||
|
||||
return Join(parts, " | ");
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param errors
|
||||
/// @param expected
|
||||
/// @param event
|
||||
void ExpectUType(ostream &errors, UINT expected, const MessageBoxEvent &event) {
|
||||
UINT actual = get<2>(event);
|
||||
if (actual != expected) {
|
||||
errors << "u_type mismatch. Expected: " << hex << expected << " (" << ConvertUTypeToString(expected)
|
||||
<< "), Actual: " << hex << actual << " (" << ConvertUTypeToString(actual) << ")" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param error_messages
|
||||
/// @return
|
||||
string GetErrors(ostringstream &error_messages) {
|
||||
string errors = error_messages.str();
|
||||
if (errors.size() > 0) {
|
||||
return errors;
|
||||
}
|
||||
return no_errors;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TestResults test_WindowsLogger_LogMessage() {
|
||||
auto log_message = [](const Logger::MessageType &type,
|
||||
const string &message,
|
||||
const string &body,
|
||||
const string &title,
|
||||
UINT u_type) -> string {
|
||||
ostringstream errors;
|
||||
auto destination = make_shared<WindowsLoggerSpy>();
|
||||
destination->LogMessage(type, message);
|
||||
ExpectLogSize(errors, 1, destination);
|
||||
if (destination->log.size() > 0) {
|
||||
auto event = destination->log.at(0);
|
||||
ExpectMessage(errors, body, event);
|
||||
ExpectTitle(errors, title, event);
|
||||
ExpectUType(errors, u_type, event);
|
||||
}
|
||||
return GetErrors(errors);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::WindowsLogger::LogMessage(cosnt std::string&)",
|
||||
log_message,
|
||||
{
|
||||
MakeTest("should log \"this is a message\" with title \"Debug\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
"this is a message",
|
||||
"this is a message",
|
||||
"Debug",
|
||||
MB_OK | MB_ICONEXCLAMATION)),
|
||||
MakeTest(
|
||||
"should log \"this is an error\" with title \"ERROR\"",
|
||||
no_errors,
|
||||
make_tuple(
|
||||
Logger::MessageType::Error, "this is an error", "this is an error", "ERROR", MB_OK | MB_ICONHAND)),
|
||||
MakeTest("should log \"what a terrible failure\" with title \"How did you let this happen?\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
"what a terrible failure",
|
||||
"what a terrible failure",
|
||||
"How did you let this happen?",
|
||||
MB_OK | MB_ICONHAND)),
|
||||
MakeTest("should log \"this is some information\" with title \"Information\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
"this is some information",
|
||||
"this is some information",
|
||||
"Information",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
MakeTest("should log \"this is a warning\" with title \"Warning\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
"this is a warning",
|
||||
"this is a warning",
|
||||
"Warning",
|
||||
MB_OK | MB_ICONEXCLAMATION)),
|
||||
MakeTest("should log \"this is verbose\" with title \"Verbose\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
"this is verbose",
|
||||
"this is verbose",
|
||||
"Verbose",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
MakeTest("should log \"unclassified message\" with title \"Unclassified\"",
|
||||
no_errors,
|
||||
make_tuple((Logger::MessageType)1000,
|
||||
"unclassified message",
|
||||
"unclassified message",
|
||||
"Unclassified",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_WindowsLogger_LogErrorWithMessage() {
|
||||
auto log_error = [](const Logger::MessageType &type,
|
||||
const std::exception &ex,
|
||||
const string &expected_body,
|
||||
const string &expected_title,
|
||||
UINT expected_utype) -> string {
|
||||
ostringstream errors;
|
||||
auto destination = make_shared<WindowsLoggerSpy>();
|
||||
destination->LogError(type, ex);
|
||||
ExpectLogSize(errors, 1, destination);
|
||||
if (destination->log.size() > 0) {
|
||||
auto event = destination->log.at(0);
|
||||
ExpectMessage(errors, expected_body, event);
|
||||
ExpectTitle(errors, expected_title, event);
|
||||
ExpectUType(errors, expected_utype, event);
|
||||
}
|
||||
return GetErrors(errors);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::WindowsLogger::LogError(const std::exception&)",
|
||||
log_error,
|
||||
{
|
||||
MakeTest("should log \"Exception: this is an exception\" with title \"Debug\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"Debug",
|
||||
MB_OK | MB_ICONEXCLAMATION)),
|
||||
MakeTest("should log \"Exception: this is an error\" with title \"ERROR\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
std::runtime_error("this is an error"),
|
||||
"Exception: this is an error",
|
||||
"ERROR",
|
||||
MB_OK | MB_ICONHAND)),
|
||||
MakeTest("should log \"Exception: what a terrible failure\" with title \"How did you let this happen?\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
std::runtime_error("what a terrible failure"),
|
||||
"Exception: what a terrible failure",
|
||||
"How did you let this happen?",
|
||||
MB_OK | MB_ICONHAND)),
|
||||
MakeTest("should log \"Exception: this is some information\" with title \"Information\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
std::runtime_error("this is some information"),
|
||||
"Exception: this is some information",
|
||||
"Information",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
MakeTest("should log \"Exception: this is a warning\" with title \"Warning\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
std::runtime_error("this is a warning"),
|
||||
"Exception: this is a warning",
|
||||
"Warning",
|
||||
MB_OK | MB_ICONEXCLAMATION)),
|
||||
MakeTest("should log \"Exception: this is verbose\" with title \"Verbose\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
std::runtime_error("this is verbose"),
|
||||
"Exception: this is verbose",
|
||||
"Verbose",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
MakeTest("should log \"Exception: unclassified message\" with title \"Unclassified\"",
|
||||
no_errors,
|
||||
make_tuple((Logger::MessageType)1000,
|
||||
std::runtime_error("unclassified message"),
|
||||
"Exception: unclassified message",
|
||||
"Unclassified",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
}));
|
||||
}
|
||||
|
||||
TestResults test_WindowsLogger_LogErrorWithoutMessage() {
|
||||
auto log_error = [](const Logger::MessageType &type,
|
||||
const std::string &message,
|
||||
const std::exception &ex,
|
||||
const string &expected_body,
|
||||
const string &expected_title,
|
||||
UINT expected_utype) -> string {
|
||||
ostringstream errors;
|
||||
auto destination = make_shared<WindowsLoggerSpy>();
|
||||
destination->LogError(type, ex);
|
||||
ExpectLogSize(errors, 1, destination);
|
||||
if (destination->log.size() > 0) {
|
||||
auto event = destination->log.at(0);
|
||||
ExpectMessage(errors, expected_body, event);
|
||||
ExpectTitle(errors, expected_title, event);
|
||||
ExpectUType(errors, expected_utype, event);
|
||||
}
|
||||
return GetErrors(errors);
|
||||
};
|
||||
return ExecuteSuite(MakeTestSuite(
|
||||
"CPPUtils::WindowsLogger::LogError(const std::string&, const std::exception&)",
|
||||
log_error,
|
||||
{
|
||||
MakeTest("should log \"Exception: this is an exception\" with title \"Debug\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Debug,
|
||||
"this is a message",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"Debug",
|
||||
MB_OK | MB_ICONEXCLAMATION)),
|
||||
MakeTest("should log \"Exception: this is an exception\" with title \"ERROR\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Error,
|
||||
"this is an error",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"ERROR",
|
||||
MB_OK | MB_ICONHAND)),
|
||||
MakeTest("should log \"Exception: this is an exception\" with title \"How did you let this happen?\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Wtf,
|
||||
"what a terrible failure",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"How did you let this happen?",
|
||||
MB_OK | MB_ICONHAND)),
|
||||
MakeTest("should log \"Exception this is an exception\" with title \"Information\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Info,
|
||||
"this is some information",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"Information",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
MakeTest("should log \"Exception: this is a warning with caught exception this is an exception\" with title "
|
||||
"\"Warning\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Warning,
|
||||
"this is a warning",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"Warning",
|
||||
MB_OK | MB_ICONEXCLAMATION)),
|
||||
MakeTest("should log \"Exception: this is an exception\" with title \"Verbose\"",
|
||||
no_errors,
|
||||
make_tuple(Logger::MessageType::Verbose,
|
||||
"this is verbose",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"Verbose",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
MakeTest("should log \"Exception: this is an exception\" with title \"Unclassified\"",
|
||||
no_errors,
|
||||
make_tuple((Logger::MessageType)1000,
|
||||
"unclassified message",
|
||||
std::runtime_error("this is an exception"),
|
||||
"Exception: this is an exception",
|
||||
"Unclassified",
|
||||
MB_OK | MB_ICONASTERISK)),
|
||||
}));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
TestResults results;
|
||||
|
||||
results += test_WindowsLogger_LogMessage();
|
||||
results += test_WindowsLogger_LogErrorWithMessage();
|
||||
results += test_WindowsLogger_LogErrorWithoutMessage();
|
||||
|
||||
PrintResults(cout, results);
|
||||
|
||||
return results.Failed() + results.Errors();
|
||||
}
|
||||
#endif // End defined(_WIN32)
|
||||
Reference in New Issue
Block a user