diff --git a/AGENTS.md b/AGENTS.md index e219277..aac816d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,7 @@ ASWLog is a thread-safe, dependency-free C++20 logging library for Windows and L - `ASWLog/` contains the framework implementation. - `tests/` contains the unit tests: test modules (`Test_ASWLog_`, the tests of `ASWLog_`) and shared test helpers (`UT_Helper_`, e.g. `UT_Helper_DateTime`) in `tests/tests/`, their CMake project in `tests/cmake/`, their RAD Studio console project in `tests/rad370/`, and their RAD Studio VCL GUI runner project in `tests/vcl/gui/rad370/` (built from the submodule's `vcl/gui/src`). `tests/compile_checks/` holds "must not compile" checks, which `tests/cmake/CMakeLists.txt` runs with `try_compile` when configuring (a failed check stops the configure). `tests/package/` is a project that builds against an installed ASWLog with `find_package` (CI installs the library and runs it). - `CMakeLists.txt` (the root) defines the `ASWLog::ASWLog` library target and its install rules; `cmake/ASWLogConfig.cmake.in` is the template of the installed package file. The project version is read from `ASWLog/ASWLog_Version.h`. -- `third_party/asw-unit-tests/` is the ASWUnitTests framework, a git submodule pinned to a release tag. Never edit files in it; test modules self-register with `ASW_REGISTER_TEST_GROUP`, so adding a test only touches `tests/` and its build files. +- `third_party/asw-unit-tests/` is the ASWUnitTests framework, a git submodule pinned to a release tag. Never edit files in it; test modules self-register with `ASW_REGISTER_TEST_GROUP`, so adding a test only touches `tests/` and its build files. Each test group derives from `TAutoTestGroup`, so a new test is defined with `ASW_TEST(ClassName, TestName)` in the group's `.cpp` and declared as a public `Test_TestName()` method in its header, with no `RegisterTest()` call. - `.github/workflows/ci.yml` builds and runs the unit tests on Windows (MSVC, MinGW) and Linux (GCC, Clang), plus Linux Clang builds with ThreadSanitizer and with AddressSanitizer + UBSan (`ASWLOG_SANITIZE`); the non-sanitizer jobs also check the installed CMake package (`tests/package/`). A Linux GCC coverage job (informational, it never fails the run) shows the library's line coverage on its summary page and uploads an HTML report. - `example/` contains example app that uses the logger. - `example/rad370/` contains the RAD Studio 13.1 project and Windows build scripts. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ca334b..175e818 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,9 @@ unit tests. 2. Make the smallest change that addresses the issue. Don't bundle unrelated refactoring, formatting, or reordering into the same change. 3. Add or update focused tests in `tests/tests/` for the behavior change, - including error and platform-specific cases where applicable. A new test file + including error and platform-specific cases where applicable. Define a new + test with `ASW_TEST(ClassName, TestName)` and declare its `Test_TestName()` + method public in the group's header; it registers itself. A new test file goes into `tests/cmake/CMakeLists.txt`, `tests/rad370/ASWLogTests.cbproj`, and `tests/vcl/gui/rad370/ASWLogTests_VCL_GUI.cbproj`. A new library source file goes into the root `CMakeLists.txt`, the RAD Studio test and example projects, diff --git a/tests/tests/Test_ASWLog_Base.cpp b/tests/tests/Test_ASWLog_Base.cpp index b688ea0..3b9890c 100644 --- a/tests/tests/Test_ASWLog_Base.cpp +++ b/tests/tests/Test_ASWLog_Base.cpp @@ -223,39 +223,6 @@ ASWLog::TASWLogConfig MakeBacktraceConfig(std::size_t capacity, ASWLog::Level lo TTest_ASWLog_Base::TTest_ASWLog_Base() : inherited("ASWLog_Base_Tests") { - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_CapacityKeepsTheNewest, "Backtrace_CapacityKeepsTheNewest"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_DisabledLoggerKeepsAndWritesNothing, "Backtrace_DisabledLoggerKeepsAndWritesNothing"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_DumpAtLevelOffWritesOnlyOnRequest, "Backtrace_DumpAtLevelOffWritesOnlyOnRequest"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_KeptEntriesAreWrittenBeforeTheTrigger, "Backtrace_KeptEntriesAreWrittenBeforeTheTrigger"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_MinimumLevelChangesKeepTheBacktrace, "Backtrace_MinimumLevelChangesKeepTheBacktrace"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_OffKeepsNothing, "Backtrace_OffKeepsNothing"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_ReconfigureResizesKeepingTheNewest, "Backtrace_ReconfigureResizesKeepingTheNewest"); - RegisterTest(&TTest_ASWLog_Base::Test_Backtrace_ShouldLogAndFmtIncludeKeptLevels, "Backtrace_ShouldLogAndFmtIncludeKeptLevels"); - RegisterTest(&TTest_ASWLog_Base::Test_GetConfig_ReturnsUnchangingSnapshot, "GetConfig_ReturnsUnchangingSnapshot"); - RegisterTest(&TTest_ASWLog_Base::Test_GetFullVersionStr_ContainsVersion, "GetFullVersionStr_ContainsVersion"); - RegisterTest(&TTest_ASWLog_Base::Test_Interface_MethodsAreNoexcept, "Interface_MethodsAreNoexcept"); - RegisterTest(&TTest_ASWLog_Base::Test_LogFormatMethods_AcceptEveryArgumentKind, "LogFormatMethods_AcceptEveryArgumentKind"); - RegisterTest(&TTest_ASWLog_Base::Test_LogFormatMethods_LogErrorInsteadOfThrowing, "LogFormatMethods_LogErrorInsteadOfThrowing"); - RegisterTest(&TTest_ASWLog_Base::Test_LogFormatMethods_PassCallerLocation, "LogFormatMethods_PassCallerLocation"); - RegisterTest(&TTest_ASWLog_Base::Test_LogFormatMethods_SkipFormattingWhenNotWritten, "LogFormatMethods_SkipFormattingWhenNotWritten"); - RegisterTest(&TTest_ASWLog_Base::Test_LogLevelConvenienceMethods, "LogLevelConvenienceMethods"); - RegisterTest(&TTest_ASWLog_Base::Test_LogMethods_PassRecordsToWrite, "LogMethods_PassRecordsToWrite"); - RegisterTest(&TTest_ASWLog_Base::Test_OnBeforeWrite_DropsOrChangesEntries, "OnBeforeWrite_DropsOrChangesEntries"); - RegisterTest(&TTest_ASWLog_Base::Test_OnBeforeWrite_EntriesLoggedInsideTheHookAreWrittenAsIs, "OnBeforeWrite_EntriesLoggedInsideTheHookAreWrittenAsIs"); - RegisterTest(&TTest_ASWLog_Base::Test_OnBeforeWrite_ReconfigureSetsAndClearsTheHook, "OnBeforeWrite_ReconfigureSetsAndClearsTheHook"); - RegisterTest(&TTest_ASWLog_Base::Test_OnBeforeWrite_SeesEntriesThatPassTheLevelChecks, "OnBeforeWrite_SeesEntriesThatPassTheLevelChecks"); - RegisterTest(&TTest_ASWLog_Base::Test_OnBeforeWrite_ThrowingHookDropsTheEntryAndReports, "OnBeforeWrite_ThrowingHookDropsTheEntryAndReports"); - RegisterTest(&TTest_ASWLog_Base::Test_ReportError_FailureInHandlerIsNotReportedAgain, "ReportError_FailureInHandlerIsNotReportedAgain"); - RegisterTest(&TTest_ASWLog_Base::Test_ReportError_ThrottlesEachKindSeparately, "ReportError_ThrottlesEachKindSeparately"); - RegisterTest(&TTest_ASWLog_Base::Test_ReportError_ThrowingHandlerDoesNotEscape, "ReportError_ThrowingHandlerDoesNotEscape"); - RegisterTest(&TTest_ASWLog_Base::Test_ReportError_WritesToStdErrWithoutHandler, "ReportError_WritesToStdErrWithoutHandler"); - RegisterTest(&TTest_ASWLog_Base::Test_SetGetMinimumLevel_RoundTrips, "SetGetMinimumLevel_RoundTrips"); - RegisterTest(&TTest_ASWLog_Base::Test_ShouldLog_RecordFollowsWritesChecks, "ShouldLog_RecordFollowsWritesChecks"); - RegisterTest(&TTest_ASWLog_Base::Test_ShouldLog_ReflectsEnabledAndLevel, "ShouldLog_ReflectsEnabledAndLevel"); - RegisterTest(&TTest_ASWLog_Base::Test_Write_AppliesEnabledOffAndLevelChecks, "Write_AppliesEnabledOffAndLevelChecks"); - RegisterTest(&TTest_ASWLog_Base::Test_Write_KeepsFieldsAlreadyStamped, "Write_KeepsFieldsAlreadyStamped"); - RegisterTest(&TTest_ASWLog_Base::Test_Write_StampsOnlyWrittenEntries, "Write_StampsOnlyWrittenEntries"); - RegisterTest(&TTest_ASWLog_Base::Test_Write_ThrowingWriteRecordDropsEntry, "Write_ThrowingWriteRecordDropsEntry"); } //--------------------------------------------------------------------------- TTest_ASWLog_Base::~TTest_ASWLog_Base() @@ -282,7 +249,7 @@ void TTest_ASWLog_Base::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_CapacityKeepsTheNewest() +ASW_TEST(TTest_ASWLog_Base, Backtrace_CapacityKeepsTheNewest) { // Arrange TTestLogger logger; @@ -300,7 +267,7 @@ void TTest_ASWLog_Base::Test_Backtrace_CapacityKeepsTheNewest() CheckTrue(logger.Written == expected, "Only the newest entries should be kept, oldest first"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_DisabledLoggerKeepsAndWritesNothing() +ASW_TEST(TTest_ASWLog_Base, Backtrace_DisabledLoggerKeepsAndWritesNothing) { // Arrange TTestLogger logger; @@ -323,7 +290,7 @@ void TTest_ASWLog_Base::Test_Backtrace_DisabledLoggerKeepsAndWritesNothing() CheckTrue(logger.Written == expected, "Only the entry kept while enabled should be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_DumpAtLevelOffWritesOnlyOnRequest() +ASW_TEST(TTest_ASWLog_Base, Backtrace_DumpAtLevelOffWritesOnlyOnRequest) { // Arrange TTestLogger logger; @@ -343,7 +310,7 @@ void TTest_ASWLog_Base::Test_Backtrace_DumpAtLevelOffWritesOnlyOnRequest() CheckTrue(logger.Written == expected, "DumpBacktrace() should write it once, then forget it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_KeptEntriesAreWrittenBeforeTheTrigger() +ASW_TEST(TTest_ASWLog_Base, Backtrace_KeptEntriesAreWrittenBeforeTheTrigger) { // Arrange: each entry gets its own time using namespace std::chrono_literals; @@ -375,7 +342,7 @@ void TTest_ASWLog_Base::Test_Backtrace_KeptEntriesAreWrittenBeforeTheTrigger() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_MinimumLevelChangesKeepTheBacktrace() +ASW_TEST(TTest_ASWLog_Base, Backtrace_MinimumLevelChangesKeepTheBacktrace) { // Arrange TTestLogger logger; @@ -401,7 +368,7 @@ void TTest_ASWLog_Base::Test_Backtrace_MinimumLevelChangesKeepTheBacktrace() CheckTrue(logger.Written == expected, "Only the entry kept below Warn should be in the backtrace"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_OffKeepsNothing() +ASW_TEST(TTest_ASWLog_Base, Backtrace_OffKeepsNothing) { // Arrange: no capacity (the default), and a capacity with LowestLevel Off TTestLogger defaultLogger; @@ -424,7 +391,7 @@ void TTest_ASWLog_Base::Test_Backtrace_OffKeepsNothing() CheckTrue(offLogger.Written == std::vector{ "ERROR|error_1" }, "Nothing should be kept with LowestLevel Off"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_ReconfigureResizesKeepingTheNewest() +ASW_TEST(TTest_ASWLog_Base, Backtrace_ReconfigureResizesKeepingTheNewest) { // Arrange: a full backtrace that has wrapped around (debug_1 was replaced) TTestLogger shrinking; @@ -455,7 +422,7 @@ void TTest_ASWLog_Base::Test_Backtrace_ReconfigureResizesKeepingTheNewest() CheckTrue(growing.Written == expectedGrown, "A larger capacity should keep the order, with new entries after the newest"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Backtrace_ShouldLogAndFmtIncludeKeptLevels() +ASW_TEST(TTest_ASWLog_Base, Backtrace_ShouldLogAndFmtIncludeKeptLevels) { // Arrange TTestLogger logger; @@ -474,7 +441,7 @@ void TTest_ASWLog_Base::Test_Backtrace_ShouldLogAndFmtIncludeKeptLevels() CheckEquals(3, logger.Written.size(), "The kept entry should be written between the markers"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_GetConfig_ReturnsUnchangingSnapshot() +ASW_TEST(TTest_ASWLog_Base, GetConfig_ReturnsUnchangingSnapshot) { // Arrange: the snapshot is read-only, so it can't be changed behind the logger's back static_assert(std::is_same_v().GetConfig()), @@ -506,7 +473,7 @@ void TTest_ASWLog_Base::Test_GetConfig_ReturnsUnchangingSnapshot() "The config passed to Initialize() should be copied, not kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_GetFullVersionStr_ContainsVersion() +ASW_TEST(TTest_ASWLog_Base, GetFullVersionStr_ContainsVersion) { // Arrange TTestLogger logger; @@ -519,7 +486,7 @@ void TTest_ASWLog_Base::Test_GetFullVersionStr_ContainsVersion() CheckEquals(expected, version, "Full version string should combine the logger class name and the version number"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Interface_MethodsAreNoexcept() +ASW_TEST(TTest_ASWLog_Base, Interface_MethodsAreNoexcept) { // Arrange: through the interface, as a caller holding an IASWLog& sees it. String views rather than literals, since // the standard doesn't make converting a literal to std::string_view noexcept. @@ -563,7 +530,7 @@ void TTest_ASWLog_Base::Test_Interface_MethodsAreNoexcept() CheckTrue(logger.ShouldLog(ASWLog::Level::Info), "The noexcept checks above are made at compile time"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_LogFormatMethods_AcceptEveryArgumentKind() +ASW_TEST(TTest_ASWLog_Base, LogFormatMethods_AcceptEveryArgumentKind) { // Arrange // rvalue, lvalue and const lvalue arguments deduce different Args, which the level shortcuts must forward @@ -590,7 +557,7 @@ void TTest_ASWLog_Base::Test_LogFormatMethods_AcceptEveryArgumentKind() CheckEquals(std::string("1 2 three four 5"), logger.LastMessage, "A RuntimeFormat() string that matches its arguments should format like a literal"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_LogFormatMethods_LogErrorInsteadOfThrowing() +ASW_TEST(TTest_ASWLog_Base, LogFormatMethods_LogErrorInsteadOfThrowing) { // Arrange TTestLogger logger; @@ -617,7 +584,7 @@ void TTest_ASWLog_Base::Test_LogFormatMethods_LogErrorInsteadOfThrowing() CheckEquals(std::string("[ASWLog format error: unknown exception] value {}"), otherExceptionMessage, "Any other exception from a formatter should be logged too"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_LogFormatMethods_PassCallerLocation() +ASW_TEST(TTest_ASWLog_Base, LogFormatMethods_PassCallerLocation) { // Arrange TTestLogger logger; @@ -683,7 +650,7 @@ void TTest_ASWLog_Base::Test_LogFormatMethods_PassCallerLocation() checkCall(line, "LogInfoFmt with RuntimeFormat()", "runtime 11"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_LogFormatMethods_SkipFormattingWhenNotWritten() +ASW_TEST(TTest_ASWLog_Base, LogFormatMethods_SkipFormattingWhenNotWritten) { // Arrange TTestLogger logger; // Minimum level Info @@ -714,7 +681,7 @@ void TTest_ASWLog_Base::Test_LogFormatMethods_SkipFormattingWhenNotWritten() CheckEmpty(logger.LastMessage, "Nothing should reach the logger while it is disabled"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_LogLevelConvenienceMethods() +ASW_TEST(TTest_ASWLog_Base, LogLevelConvenienceMethods) { // Arrange TTestLogger logger; @@ -763,7 +730,7 @@ void TTest_ASWLog_Base::Test_LogLevelConvenienceMethods() CheckEquals(std::string("critical"), logger.LastMessage, "LogCritical should store the message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_LogMethods_PassRecordsToWrite() +ASW_TEST(TTest_ASWLog_Base, LogMethods_PassRecordsToWrite) { // Arrange: a logger that only implements WriteRecord(), as a custom logger would TTestLogger logger; @@ -821,7 +788,7 @@ void TTest_ASWLog_Base::Test_LogMethods_PassRecordsToWrite() CheckEquals(9, logger.WriteRecordCount, "Each call should pass exactly one record to WriteRecord()"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_OnBeforeWrite_DropsOrChangesEntries() +ASW_TEST(TTest_ASWLog_Base, OnBeforeWrite_DropsOrChangesEntries) { // Arrange: a hook that drops noisy entries and redacts secrets, raw ones included TTestLogger logger; @@ -860,7 +827,7 @@ void TTest_ASWLog_Base::Test_OnBeforeWrite_DropsOrChangesEntries() CheckTrue(logger.LastRecord.Raw, "A changed raw entry should stay raw"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_OnBeforeWrite_EntriesLoggedInsideTheHookAreWrittenAsIs() +ASW_TEST(TTest_ASWLog_Base, OnBeforeWrite_EntriesLoggedInsideTheHookAreWrittenAsIs) { // Arrange: a hook that logs to its own logger and to another one that has a hook TTestLogger logger; @@ -902,7 +869,7 @@ void TTest_ASWLog_Base::Test_OnBeforeWrite_EntriesLoggedInsideTheHookAreWrittenA CheckEquals(1, otherHookCount, "The other hook should run only for the entry logged outside a hook"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_OnBeforeWrite_ReconfigureSetsAndClearsTheHook() +ASW_TEST(TTest_ASWLog_Base, OnBeforeWrite_ReconfigureSetsAndClearsTheHook) { // Arrange TTestLogger logger; @@ -926,7 +893,7 @@ void TTest_ASWLog_Base::Test_OnBeforeWrite_ReconfigureSetsAndClearsTheHook() "The hook should apply from the Reconfigure() that sets it until the one that clears it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_OnBeforeWrite_SeesEntriesThatPassTheLevelChecks() +ASW_TEST(TTest_ASWLog_Base, OnBeforeWrite_SeesEntriesThatPassTheLevelChecks) { // Arrange: a backtrace of Debug entries; the hook marks what it sees and drops one Debug entry TTestLogger logger; @@ -959,7 +926,7 @@ void TTest_ASWLog_Base::Test_OnBeforeWrite_SeesEntriesThatPassTheLevelChecks() CheckTrue(logger.Written == expectedWritten, "The backtrace should keep the entries as the hook changed them"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_OnBeforeWrite_ThrowingHookDropsTheEntryAndReports() +ASW_TEST(TTest_ASWLog_Base, OnBeforeWrite_ThrowingHookDropsTheEntryAndReports) { // Arrange TTestLogger logger; @@ -989,7 +956,7 @@ void TTest_ASWLog_Base::Test_OnBeforeWrite_ThrowingHookDropsTheEntryAndReports() "The report should name the hook and give the exception's what()"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_ReportError_FailureInHandlerIsNotReportedAgain() +ASW_TEST(TTest_ASWLog_Base, ReportError_FailureInHandlerIsNotReportedAgain) { // Arrange: a handler that fails the same way again, like one that logs to the logger whose output failed. Without // the guard, each report would start another, until the stack overflowed. @@ -1013,7 +980,7 @@ void TTest_ASWLog_Base::Test_ReportError_FailureInHandlerIsNotReportedAgain() "Only the failures outside the handler should be reported, and the next failure after it should be reported again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_ReportError_ThrottlesEachKindSeparately() +ASW_TEST(TTest_ASWLog_Base, ReportError_ThrottlesEachKindSeparately) { // Arrange using namespace std::chrono_literals; @@ -1059,7 +1026,7 @@ void TTest_ASWLog_Base::Test_ReportError_ThrottlesEachKindSeparately() CheckEquals(0, reports[4].SuppressedCount, "With an interval of 0, nothing should be left out"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_ReportError_ThrowingHandlerDoesNotEscape() +ASW_TEST(TTest_ASWLog_Base, ReportError_ThrowingHandlerDoesNotEscape) { // Arrange TTestLogger logger; @@ -1083,7 +1050,7 @@ void TTest_ASWLog_Base::Test_ReportError_ThrowingHandlerDoesNotEscape() CheckEquals(2, handlerCalls, "A handler that threw should still be called for the next failure"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_ReportError_WritesToStdErrWithoutHandler() +ASW_TEST(TTest_ASWLog_Base, ReportError_WritesToStdErrWithoutHandler) { // Arrange const auto stdErrFile = std::filesystem::temp_directory_path() / "aswlog_base_stderr.txt"; @@ -1122,7 +1089,7 @@ void TTest_ASWLog_Base::Test_ReportError_WritesToStdErrWithoutHandler() "Without OnError, a failure should be written to stderr as one line naming the logger, once per interval"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_SetGetMinimumLevel_RoundTrips() +ASW_TEST(TTest_ASWLog_Base, SetGetMinimumLevel_RoundTrips) { // Arrange TTestLogger logger; @@ -1142,7 +1109,7 @@ void TTest_ASWLog_Base::Test_SetGetMinimumLevel_RoundTrips() CheckEquals(ASWLog::Level::Trace, logger.GetMinimumLevel(), "SetMinimumLevel should update the value returned by GetMinimumLevel immediately"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_ShouldLog_RecordFollowsWritesChecks() +ASW_TEST(TTest_ASWLog_Base, ShouldLog_RecordFollowsWritesChecks) { // Arrange: a logger at Warn keeping a backtrace from Debug, asked through the interface TTestLogger testLogger; @@ -1186,7 +1153,7 @@ void TTest_ASWLog_Base::Test_ShouldLog_RecordFollowsWritesChecks() CheckFalse(categoryWhileDisabled, "A disabled logger should use no entry of a category"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_ShouldLog_ReflectsEnabledAndLevel() +ASW_TEST(TTest_ASWLog_Base, ShouldLog_ReflectsEnabledAndLevel) { // Arrange: everything through the interface, as code holding only an IASWLog& would use it TTestLogger testLogger; @@ -1218,7 +1185,7 @@ void TTest_ASWLog_Base::Test_ShouldLog_ReflectsEnabledAndLevel() CheckFalse(shouldLogCriticalAtMinimumOff, "Nothing should be logged at a minimum level of Off"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Write_AppliesEnabledOffAndLevelChecks() +ASW_TEST(TTest_ASWLog_Base, Write_AppliesEnabledOffAndLevelChecks) { // Arrange TTestLogger logger; @@ -1242,7 +1209,7 @@ void TTest_ASWLog_Base::Test_Write_AppliesEnabledOffAndLevelChecks() CheckEquals(2, logger.WriteRecordCount, "A disabled logger should write nothing, even forced"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Write_KeepsFieldsAlreadyStamped() +ASW_TEST(TTest_ASWLog_Base, Write_KeepsFieldsAlreadyStamped) { // Arrange: a record stamped elsewhere, e.g. by a multi-log before passing it on TTestLogger logger; @@ -1266,7 +1233,7 @@ void TTest_ASWLog_Base::Test_Write_KeepsFieldsAlreadyStamped() CheckEquals(0, logger.NowUTCCount, "The clock should not be read for a record that already has its Timestamp"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Write_StampsOnlyWrittenEntries() +ASW_TEST(TTest_ASWLog_Base, Write_StampsOnlyWrittenEntries) { // Arrange TTestLogger logger; @@ -1287,7 +1254,7 @@ void TTest_ASWLog_Base::Test_Write_StampsOnlyWrittenEntries() CheckEquals(static_cast(ASWLog::GetCurrentOSThreadId()), static_cast(logger.LastRecord.ThreadId), "The ThreadId should be the calling thread's"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Base::Test_Write_ThrowingWriteRecordDropsEntry() +ASW_TEST(TTest_ASWLog_Base, Write_ThrowingWriteRecordDropsEntry) { // Arrange: a custom logger whose WriteRecord() throws. Without the catch in TASWLogBase::Write(), the exception // would leave a noexcept function and call std::terminate, ending the test run. diff --git a/tests/tests/Test_ASWLog_Base.h b/tests/tests/Test_ASWLog_Base.h index fc26b60..2ee6424 100644 --- a/tests/tests/Test_ASWLog_Base.h +++ b/tests/tests/Test_ASWLog_Base.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Base /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Base : public TTestGroupBase +class TTest_ASWLog_Base : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Backtrace_CapacityKeepsTheNewest(); void Test_Backtrace_DisabledLoggerKeepsAndWritesNothing(); void Test_Backtrace_DumpAtLevelOffWritesOnlyOnRequest(); diff --git a/tests/tests/Test_ASWLog_CategoryLog.cpp b/tests/tests/Test_ASWLog_CategoryLog.cpp index 5f53668..cb191ef 100644 --- a/tests/tests/Test_ASWLog_CategoryLog.cpp +++ b/tests/tests/Test_ASWLog_CategoryLog.cpp @@ -245,25 +245,6 @@ bool WaitUntil(const std::function& condition) TTest_ASWLog_CategoryLog::TTest_ASWLog_CategoryLog() : inherited("ASWLog_CategoryLog_Tests") { - RegisterTest(&TTest_ASWLog_CategoryLog::Test_ApplyLevels_AppliesToCategoriesMadeLater, "ApplyLevels_AppliesToCategoriesMadeLater"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_ApplyLevels_GivesTheLongestCoveringNamesLevel, "ApplyLevels_GivesTheLongestCoveringNamesLevel"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_ApplyLevels_IsSafeWhileCategoriesComeAndGo, "ApplyLevels_IsSafeWhileCategoriesComeAndGo"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_ApplyLevels_LeavesUncoveredCategories, "ApplyLevels_LeavesUncoveredCategories"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_ApplyLevels_RejectsAnInvalidSpec, "ApplyLevels_RejectsAnInvalidSpec"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Async_KeepsItsOwnCopyOfTheName, "Async_KeepsItsOwnCopyOfTheName"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Backtrace_KeepsEntriesBelowTheCategoryLevel, "Backtrace_KeepsEntriesBelowTheCategoryLevel"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Backtrace_KeepsItsOwnCopyOfTheName, "Backtrace_KeepsItsOwnCopyOfTheName"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_FileLog_WritesTheCategoryAfterTheLevel, "FileLog_WritesTheCategoryAfterTheLevel"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_GetMinimumLevel_FollowsTheWrappedLoggerUntilSet, "GetMinimumLevel_FollowsTheWrappedLoggerUntilSet"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Lifecycle_LeavesTheWrappedLoggerAlone, "Lifecycle_LeavesTheWrappedLoggerAlone"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_MultiLog_CategoryLevelReplacesOnlyTheCompositeLevel, "MultiLog_CategoryLevelReplacesOnlyTheCompositeLevel"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Nesting_JoinsNamesAndInheritsLevels, "Nesting_JoinsNamesAndInheritsLevels"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_SetEnabled_SilencesOnlyTheCategory, "SetEnabled_SilencesOnlyTheCategory"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_SetMinimumLevel_OffSilencesAllButForcedEntries, "SetMinimumLevel_OffSilencesAllButForcedEntries"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_SetMinimumLevel_ReplacesTheWrappedLoggersLevel, "SetMinimumLevel_ReplacesTheWrappedLoggersLevel"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_ShouldLog_MatchesWhatIsWritten, "ShouldLog_MatchesWhatIsWritten"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Write_KeepsACategoryAlreadySet, "Write_KeepsACategoryAlreadySet"); - RegisterTest(&TTest_ASWLog_CategoryLog::Test_Write_StampsTheNameAndOwnLevel, "Write_StampsTheNameAndOwnLevel"); } //--------------------------------------------------------------------------- TTest_ASWLog_CategoryLog::~TTest_ASWLog_CategoryLog() @@ -298,7 +279,7 @@ void TTest_ASWLog_CategoryLog::TearDown_Test(ITestCase& testCase) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_ApplyLevels_AppliesToCategoriesMadeLater() +ASW_TEST(TTest_ASWLog_CategoryLog, ApplyLevels_AppliesToCategoriesMadeLater) { // Arrange TCategoryLevelsReset resetLevels; @@ -327,7 +308,7 @@ void TTest_ASWLog_CategoryLog::Test_ApplyLevels_AppliesToCategoriesMadeLater() CheckEquals(ASWLog::Level::Debug, laterLog.GetMinimumLevel(), "An empty spec should leave the levels already set"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_ApplyLevels_GivesTheLongestCoveringNamesLevel() +ASW_TEST(TTest_ASWLog_CategoryLog, ApplyLevels_GivesTheLongestCoveringNamesLevel) { // Arrange TCategoryLevelsReset resetLevels; @@ -352,7 +333,7 @@ void TTest_ASWLog_CategoryLog::Test_ApplyLevels_GivesTheLongestCoveringNamesLeve CheckEquals(ASWLog::Level::Warn, networkLog.GetMinimumLevel(), "Net should not cover Network, only * should"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_ApplyLevels_IsSafeWhileCategoriesComeAndGo() +ASW_TEST(TTest_ASWLog_CategoryLog, ApplyLevels_IsSafeWhileCategoriesComeAndGo) { // Arrange constexpr int ThreadCount = 4; @@ -399,7 +380,7 @@ void TTest_ASWLog_CategoryLog::Test_ApplyLevels_IsSafeWhileCategoriesComeAndGo() CheckEquals(0, withoutLevelCount.load(), "Every category made after the first spec should get a level"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_ApplyLevels_LeavesUncoveredCategories() +ASW_TEST(TTest_ASWLog_CategoryLog, ApplyLevels_LeavesUncoveredCategories) { // Arrange TCategoryLevelsReset resetLevels; @@ -432,7 +413,7 @@ void TTest_ASWLog_CategoryLog::Test_ApplyLevels_LeavesUncoveredCategories() CheckFalse(coveredLog.HasOwnMinimumLevel(), "ResetMinimumLevel() should make the category follow again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_ApplyLevels_RejectsAnInvalidSpec() +ASW_TEST(TTest_ASWLog_CategoryLog, ApplyLevels_RejectsAnInvalidSpec) { // Arrange struct TInvalidSpec @@ -481,7 +462,7 @@ void TTest_ASWLog_CategoryLog::Test_ApplyLevels_RejectsAnInvalidSpec() CheckEquals(ASWLog::Level::Info, specLog.GetMinimumLevel(), "A valid spec should set the level"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Async_KeepsItsOwnCopyOfTheName() +ASW_TEST(TTest_ASWLog_CategoryLog, Async_KeepsItsOwnCopyOfTheName) { // Arrange: an asynchronous file logger calls OnLogEntry on its own thread, after the call that logged the entry std::mutex callbackMutex; @@ -518,7 +499,7 @@ void TTest_ASWLog_CategoryLog::Test_Async_KeepsItsOwnCopyOfTheName() "The line should show the category"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Backtrace_KeepsEntriesBelowTheCategoryLevel() +ASW_TEST(TTest_ASWLog_CategoryLog, Backtrace_KeepsEntriesBelowTheCategoryLevel) { // Arrange: the logger keeps a backtrace from Trace; Db is raised to Warn, Net lowered to Debug TRecordingLogger logger; @@ -549,7 +530,7 @@ void TTest_ASWLog_CategoryLog::Test_Backtrace_KeepsEntriesBelowTheCategoryLevel( CheckTrue(logger.Written == expected, "The entries below their category's level should be in the backtrace, with their category"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Backtrace_KeepsItsOwnCopyOfTheName() +ASW_TEST(TTest_ASWLog_CategoryLog, Backtrace_KeepsItsOwnCopyOfTheName) { // Arrange: a backtrace of one entry, so the second kept entry replaces the first TRecordingLogger logger; @@ -571,7 +552,7 @@ void TTest_ASWLog_CategoryLog::Test_Backtrace_KeepsItsOwnCopyOfTheName() "The kept entry should keep its category's name after the category is gone"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_FileLog_WritesTheCategoryAfterTheLevel() +ASW_TEST(TTest_ASWLog_CategoryLog, FileLog_WritesTheCategoryAfterTheLevel) { // Arrange: the file logger at Info; Net lowered to Debug const auto logFile = TestTempDir / "category.log"; @@ -598,7 +579,7 @@ void TTest_ASWLog_CategoryLog::Test_FileLog_WritesTheCategoryAfterTheLevel() "The category should follow the level, its own level should let its Debug entry in, and ShowCategory should hide it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_GetMinimumLevel_FollowsTheWrappedLoggerUntilSet() +ASW_TEST(TTest_ASWLog_CategoryLog, GetMinimumLevel_FollowsTheWrappedLoggerUntilSet) { // Arrange TRecordingLogger logger; @@ -630,7 +611,7 @@ void TTest_ASWLog_CategoryLog::Test_GetMinimumLevel_FollowsTheWrappedLoggerUntil CheckFalse(hasOwnLevelAfterReset, "HasOwnMinimumLevel should be false after ResetMinimumLevel"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Lifecycle_LeavesTheWrappedLoggerAlone() +ASW_TEST(TTest_ASWLog_CategoryLog, Lifecycle_LeavesTheWrappedLoggerAlone) { // Arrange: a logger with a backtrace, so DumpBacktrace() shows whether it was passed on TRecordingLogger logger; @@ -670,7 +651,7 @@ void TTest_ASWLog_CategoryLog::Test_Lifecycle_LeavesTheWrappedLoggerAlone() CheckEquals(3, logger.Written.size(), "DumpBacktrace should be passed on: the kept entry between the markers"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_MultiLog_CategoryLevelReplacesOnlyTheCompositeLevel() +ASW_TEST(TTest_ASWLog_CategoryLog, MultiLog_CategoryLevelReplacesOnlyTheCompositeLevel) { // Arrange: a multi-log at Info with one sink at Trace and one at Info; Net lowered to Debug TRecordingLogger traceSink; @@ -704,7 +685,7 @@ void TTest_ASWLog_CategoryLog::Test_MultiLog_CategoryLevelReplacesOnlyTheComposi CheckFalse(shouldLogDebugWithInfoSinkOnly, "ShouldLog should be false when no sink takes the entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Nesting_JoinsNamesAndInheritsLevels() +ASW_TEST(TTest_ASWLog_CategoryLog, Nesting_JoinsNamesAndInheritsLevels) { // Arrange TRecordingLogger logger; @@ -733,7 +714,7 @@ void TTest_ASWLog_CategoryLog::Test_Nesting_JoinsNamesAndInheritsLevels() CheckFalse(shouldLogWhileNetDisabled, "Disabling a category should silence the categories wrapping it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_SetEnabled_SilencesOnlyTheCategory() +ASW_TEST(TTest_ASWLog_CategoryLog, SetEnabled_SilencesOnlyTheCategory) { // Arrange TRecordingLogger logger; @@ -760,7 +741,7 @@ void TTest_ASWLog_CategoryLog::Test_SetEnabled_SilencesOnlyTheCategory() CheckFalse(shouldLogWhileLoggerDisabled, "ShouldLog should be false while the wrapped logger is disabled"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_SetMinimumLevel_OffSilencesAllButForcedEntries() +ASW_TEST(TTest_ASWLog_CategoryLog, SetMinimumLevel_OffSilencesAllButForcedEntries) { // Arrange TRecordingLogger logger; @@ -778,7 +759,7 @@ void TTest_ASWLog_CategoryLog::Test_SetMinimumLevel_OffSilencesAllButForcedEntri CheckEquals(ASWLog::Level::Info, logger.GetMinimumLevel(), "The wrapped logger's level should not change"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_SetMinimumLevel_ReplacesTheWrappedLoggersLevel() +ASW_TEST(TTest_ASWLog_CategoryLog, SetMinimumLevel_ReplacesTheWrappedLoggersLevel) { // Arrange: the logger at Info; Net lowered to Debug, Db raised to Warn, UI following the logger TRecordingLogger logger; @@ -802,7 +783,7 @@ void TTest_ASWLog_CategoryLog::Test_SetMinimumLevel_ReplacesTheWrappedLoggersLev CheckTrue(logger.Written == expected, "Each category's own level should replace the logger's, both ways, for its entries only"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_ShouldLog_MatchesWhatIsWritten() +ASW_TEST(TTest_ASWLog_CategoryLog, ShouldLog_MatchesWhatIsWritten) { // Arrange: one logger without a backtrace, one keeping a backtrace from Debug, both at Info TRecordingLogger plainLogger; @@ -845,7 +826,7 @@ void TTest_ASWLog_CategoryLog::Test_ShouldLog_MatchesWhatIsWritten() CheckTrue(plainLogger.Written == expected, "Only the entry at Net's level should be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Write_KeepsACategoryAlreadySet() +ASW_TEST(TTest_ASWLog_CategoryLog, Write_KeepsACategoryAlreadySet) { // Arrange: a record that already has a category and a level, as from a category wrapping this one TRecordingLogger logger; @@ -865,7 +846,7 @@ void TTest_ASWLog_CategoryLog::Test_Write_KeepsACategoryAlreadySet() CheckTrue(logger.Written == expected, "The record's own category and level should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CategoryLog::Test_Write_StampsTheNameAndOwnLevel() +ASW_TEST(TTest_ASWLog_CategoryLog, Write_StampsTheNameAndOwnLevel) { // Arrange TRecordingLogger logger; diff --git a/tests/tests/Test_ASWLog_CategoryLog.h b/tests/tests/Test_ASWLog_CategoryLog.h index d908ce9..c1217ac 100644 --- a/tests/tests/Test_ASWLog_CategoryLog.h +++ b/tests/tests/Test_ASWLog_CategoryLog.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_CategoryLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_CategoryLog : public TTestGroupBase +class TTest_ASWLog_CategoryLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_ApplyLevels_AppliesToCategoriesMadeLater(); void Test_ApplyLevels_GivesTheLongestCoveringNamesLevel(); void Test_ApplyLevels_IsSafeWhileCategoriesComeAndGo(); diff --git a/tests/tests/Test_ASWLog_Config.cpp b/tests/tests/Test_ASWLog_Config.cpp index 942822a..5cc421a 100644 --- a/tests/tests/Test_ASWLog_Config.cpp +++ b/tests/tests/Test_ASWLog_Config.cpp @@ -81,21 +81,6 @@ std::string TestVariable(std::string_view key) TTest_ASWLog_Config::TTest_ASWLog_Config() : inherited("ASWLog_Config_Tests") { - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_AppliesPatternAfterFormat, "ApplyEnvironment_AppliesPatternAfterFormat"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_AppliesTheCategoryLevels, "ApplyEnvironment_AppliesTheCategoryLevels"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_IgnoresUnsetAndEmptyVariables, "ApplyEnvironment_IgnoresUnsetAndEmptyVariables"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_ReadsTheDefaultPrefix, "ApplyEnvironment_ReadsTheDefaultPrefix"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_ReadsUTF8Values, "ApplyEnvironment_ReadsUTF8Values"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_ReportsInvalidValues, "ApplyEnvironment_ReportsInvalidValues"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_SeedsTheLevelAtInitialize, "ApplyEnvironment_SeedsTheLevelAtInitialize"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplyEnvironment_SetsEachKey, "ApplyEnvironment_SetsEachKey"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplySetting_ReportsAnUnknownKey, "ApplySetting_ReportsAnUnknownKey"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplySetting_SetsOneSetting, "ApplySetting_SetsOneSetting"); - RegisterTest(&TTest_ASWLog_Config::Test_ApplySetting_WritesToStdErrWithoutHandler, "ApplySetting_WritesToStdErrWithoutHandler"); - RegisterTest(&TTest_ASWLog_Config::Test_Defaults_MatchDocumentedValues, "Defaults_MatchDocumentedValues"); - RegisterTest(&TTest_ASWLog_Config::Test_ResolveFolder_CustomFolder, "ResolveFolder_CustomFolder"); - RegisterTest(&TTest_ASWLog_Config::Test_ResolvePath_AbsolutePath, "ResolvePath_AbsolutePath"); - RegisterTest(&TTest_ASWLog_Config::Test_ResolvePath_Defaults, "ResolvePath_Defaults"); } //--------------------------------------------------------------------------- TTest_ASWLog_Config::~TTest_ASWLog_Config() @@ -122,7 +107,7 @@ void TTest_ASWLog_Config::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_AppliesPatternAfterFormat() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_AppliesPatternAfterFormat) { // Arrange TScopedEnvironmentVariable format(TestVariable("FORMAT"), "JSON"); @@ -151,7 +136,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_AppliesPatternAfterFormat() CheckNull(config.Line.Formatter, "FORMAT=Text should clear the formatter (the built-in layout)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_AppliesTheCategoryLevels() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_AppliesTheCategoryLevels) { // Arrange TCategoryLevelsReset resetLevels; @@ -188,7 +173,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_AppliesTheCategoryLevels() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_IgnoresUnsetAndEmptyVariables() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_IgnoresUnsetAndEmptyVariables) { // Arrange: LEVEL empty, FLUSH only spaces, the rest unset TScopedEnvironmentVariable level(TestVariable("LEVEL"), ""); @@ -218,7 +203,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_IgnoresUnsetAndEmptyVariables() CheckSame(formatter.get(), config.Line.Formatter.get(), "Unset FORMAT and PATTERN should leave the formatter"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_ReadsTheDefaultPrefix() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_ReadsTheDefaultPrefix) { // Arrange: a developer's own ASWLOG_CATEGORIES must not change the process's category levels TScopedEnvironmentVariable categories("ASWLOG_CATEGORIES", std::nullopt); @@ -240,7 +225,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_ReadsTheDefaultPrefix() "Another prefix should not read the ASWLOG_ variables"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_ReadsUTF8Values() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_ReadsUTF8Values) { // Arrange: a lambda and a CJK character, in UTF-8 TScopedEnvironmentVariable folder(TestVariable("FOLDER"), "logs\xCE\xBB"); @@ -260,7 +245,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_ReadsUTF8Values() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_ReportsInvalidValues() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_ReportsInvalidValues) { // Arrange: every key but FOLDER invalid TScopedEnvironmentVariable level(TestVariable("LEVEL"), "Verbose"); @@ -330,7 +315,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_ReportsInvalidValues() CheckContains(errors.back().Message, "nope", "The PATTERN report should give the pattern's problem"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_SeedsTheLevelAtInitialize() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_SeedsTheLevelAtInitialize) { // Arrange TScopedEnvironmentVariable level(TestVariable("LEVEL"), "Debug"); @@ -360,7 +345,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_SeedsTheLevelAtInitialize() CheckContains(lines[0], "debug entry", "The Debug entry should be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplyEnvironment_SetsEachKey() +ASW_TEST(TTest_ASWLog_Config, ApplyEnvironment_SetsEachKey) { // Arrange: mixed case and spaces around the values TScopedEnvironmentVariable level(TestVariable("LEVEL"), " debug "); @@ -405,7 +390,7 @@ void TTest_ASWLog_Config::Test_ApplyEnvironment_SetsEachKey() CheckNotNull(dynamic_cast(config.Line.Formatter.get()), "FORMAT=json should set a JSON formatter"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplySetting_ReportsAnUnknownKey() +ASW_TEST(TTest_ASWLog_Config, ApplySetting_ReportsAnUnknownKey) { // Arrange std::vector errors; @@ -434,7 +419,7 @@ void TTest_ASWLog_Config::Test_ApplySetting_ReportsAnUnknownKey() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplySetting_SetsOneSetting() +ASW_TEST(TTest_ASWLog_Config, ApplySetting_SetsOneSetting) { // Arrange std::vector errors; @@ -478,7 +463,7 @@ void TTest_ASWLog_Config::Test_ApplySetting_SetsOneSetting() CheckEquals(6, errors.size(), "Only the invalid BACKTRACE values should be reported"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ApplySetting_WritesToStdErrWithoutHandler() +ASW_TEST(TTest_ASWLog_Config, ApplySetting_WritesToStdErrWithoutHandler) { // Arrange const auto stdErrFile = std::filesystem::temp_directory_path() / "aswlog_config_stderr.txt"; @@ -516,7 +501,7 @@ void TTest_ASWLog_Config::Test_ApplySetting_WritesToStdErrWithoutHandler() written, "Without OnError, an invalid value should be written to stderr as one line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_Defaults_MatchDocumentedValues() +ASW_TEST(TTest_ASWLog_Config, Defaults_MatchDocumentedValues) { // Arrange / Act const ASWLog::TASWLogConfig config; @@ -597,7 +582,7 @@ void TTest_ASWLog_Config::Test_Defaults_MatchDocumentedValues() CheckEquals(0, config.File.MaxBackupTotalBytes, "File.MaxBackupTotalBytes should default to 0 (unlimited)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ResolveFolder_CustomFolder() +ASW_TEST(TTest_ASWLog_Config, ResolveFolder_CustomFolder) { // Arrange const auto expectedDir = std::filesystem::path("custom") / "logs"; @@ -620,7 +605,7 @@ void TTest_ASWLog_Config::Test_ResolveFolder_CustomFolder() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ResolvePath_AbsolutePath() +ASW_TEST(TTest_ASWLog_Config, ResolvePath_AbsolutePath) { // Arrange const auto absolutePath = std::filesystem::absolute(std::filesystem::path("custom.log")).lexically_normal(); @@ -636,7 +621,7 @@ void TTest_ASWLog_Config::Test_ResolvePath_AbsolutePath() CheckTrue(resolvedPath == absolutePath, "Absolute log file paths should be preserved"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Config::Test_ResolvePath_Defaults() +ASW_TEST(TTest_ASWLog_Config, ResolvePath_Defaults) { // Arrange const auto expectedPath = (std::filesystem::path("logs") / std::filesystem::path("aswlog.txt")).lexically_normal(); diff --git a/tests/tests/Test_ASWLog_Config.h b/tests/tests/Test_ASWLog_Config.h index c86da4f..5b6924d 100644 --- a/tests/tests/Test_ASWLog_Config.h +++ b/tests/tests/Test_ASWLog_Config.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Config /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Config : public TTestGroupBase +class TTest_ASWLog_Config : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_ApplyEnvironment_AppliesPatternAfterFormat(); void Test_ApplyEnvironment_AppliesTheCategoryLevels(); void Test_ApplyEnvironment_IgnoresUnsetAndEmptyVariables(); diff --git a/tests/tests/Test_ASWLog_ConsoleLog.cpp b/tests/tests/Test_ASWLog_ConsoleLog.cpp index bb6418d..d9bdfc6 100644 --- a/tests/tests/Test_ASWLog_ConsoleLog.cpp +++ b/tests/tests/Test_ASWLog_ConsoleLog.cpp @@ -213,28 +213,6 @@ ASWLog::TASWLogConfig MakeQuietConfig() TTest_ASWLog_ConsoleLog::TTest_ASWLog_ConsoleLog() : inherited("ASWLog_ConsoleLog_Tests") { - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_ColorModeAlways_WrapsOutputWithAnsiCodes, "ColorModeAlways_WrapsOutputWithAnsiCodes"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_ColorModeAuto_ColorsOnlyStreamsThatSupportIt, "ColorModeAuto_ColorsOnlyStreamsThatSupportIt"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_ColorModeAuto_HonorsNoColor, "ColorModeAuto_HonorsNoColor"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_ColorModeNever_SuppressesAnsiCodes, "ColorModeNever_SuppressesAnsiCodes"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_Flush_FlushesStdOutAndStdErrWhileOpen, "Flush_FlushesStdOutAndStdErrWhileOpen"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_GetColorMode_ReflectsSetColorMode, "GetColorMode_ReflectsSetColorMode"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_GetInstance_ReturnsSameInstance, "GetInstance_ReturnsSameInstance"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_GetLevelColor_OffHasNoColor, "GetLevelColor_OffHasNoColor"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_Initialize_SuppressesInfoBannersBelowMinimumLevel, "Initialize_SuppressesInfoBannersBelowMinimumLevel"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_Initialize_WritesDriveInfoWhenEnabled, "Initialize_WritesDriveInfoWhenEnabled"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_IsColorSupported_ReflectsDetectedStreams, "IsColorSupported_ReflectsDetectedStreams"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_LogLineMetadata_Options, "LogLineMetadata_Options"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_LogProcessAndThreadIds_AreOSIds, "LogProcessAndThreadIds_AreOSIds"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_LogRawAndForceOptions, "LogRawAndForceOptions"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_LogRespectsMinimumLevel, "LogRespectsMinimumLevel"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_OnError_ReportsOnlyTheWriteThatFailedTheStream, "OnError_ReportsOnlyTheWriteThatFailedTheStream"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_OnLogEntry_FiresForQualifyingLevelsOnly, "OnLogEntry_FiresForQualifyingLevelsOnly"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_ResetLevelColor_RestoresDefault, "ResetLevelColor_RestoresDefault"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_ResetLevelColors_RestoresAllDefaults, "ResetLevelColors_RestoresAllDefaults"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_SetLevelColor_EmptyStringDisablesColorForLevel, "SetLevelColor_EmptyStringDisablesColorForLevel"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_SetLevelColor_OverridesDefaultColor, "SetLevelColor_OverridesDefaultColor"); - RegisterTest(&TTest_ASWLog_ConsoleLog::Test_WarnAndAboveWriteToStdErr, "WarnAndAboveWriteToStdErr"); } //--------------------------------------------------------------------------- TTest_ASWLog_ConsoleLog::~TTest_ASWLog_ConsoleLog() @@ -261,7 +239,7 @@ void TTest_ASWLog_ConsoleLog::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_ColorModeAlways_WrapsOutputWithAnsiCodes() +ASW_TEST(TTest_ASWLog_ConsoleLog, ColorModeAlways_WrapsOutputWithAnsiCodes) { // Arrange: the real stdout isn't a terminal under a test runner, so only Always colors it auto config = MakeQuietConfig(); @@ -280,7 +258,7 @@ void TTest_ASWLog_ConsoleLog::Test_ColorModeAlways_WrapsOutputWithAnsiCodes() CheckContains(outCapture.Str(), "\x1b[", "ColorMode::Always should wrap output with ANSI escape codes"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_ColorModeAuto_ColorsOnlyStreamsThatSupportIt() +ASW_TEST(TTest_ASWLog_ConsoleLog, ColorModeAuto_ColorsOnlyStreamsThatSupportIt) { // Arrange: stdout shows colors and stderr doesn't (e.g. stderr redirected to a file) TScopedEnvironmentVariable noColor("NO_COLOR", std::nullopt); @@ -309,7 +287,7 @@ void TTest_ASWLog_ConsoleLog::Test_ColorModeAuto_ColorsOnlyStreamsThatSupportIt( CheckContains(errContents, "stderr_message", "The uncolored message should still be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_ColorModeAuto_HonorsNoColor() +ASW_TEST(TTest_ASWLog_ConsoleLog, ColorModeAuto_HonorsNoColor) { // Arrange: both streams show colors, but NO_COLOR asks for none TScopedEnvironmentVariable noColor("NO_COLOR", "1"); @@ -368,7 +346,7 @@ void TTest_ASWLog_ConsoleLog::Test_ColorModeAuto_HonorsNoColor() CheckContains(emptyContents, "\x1b[", "Auto should still color when NO_COLOR is set but empty"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_ColorModeNever_SuppressesAnsiCodes() +ASW_TEST(TTest_ASWLog_ConsoleLog, ColorModeNever_SuppressesAnsiCodes) { // Arrange: a stream that shows colors, so only Never can suppress them auto config = MakeQuietConfig(); @@ -391,7 +369,7 @@ void TTest_ASWLog_ConsoleLog::Test_ColorModeNever_SuppressesAnsiCodes() CheckContains(contents, "plain_message", "The message should still be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_Flush_FlushesStdOutAndStdErrWhileOpen() +ASW_TEST(TTest_ASWLog_ConsoleLog, Flush_FlushesStdOutAndStdErrWhileOpen) { // Arrange ASWLog::TASWConsoleLog consoleLog; @@ -428,7 +406,7 @@ void TTest_ASWLog_ConsoleLog::Test_Flush_FlushesStdOutAndStdErrWhileOpen() CheckFalse(flushedWhileClosed, "Flush() should return false while the logger is closed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_GetColorMode_ReflectsSetColorMode() +ASW_TEST(TTest_ASWLog_ConsoleLog, GetColorMode_ReflectsSetColorMode) { // Arrange ASWLog::TASWConsoleLog logger; @@ -447,7 +425,7 @@ void TTest_ASWLog_ConsoleLog::Test_GetColorMode_ReflectsSetColorMode() CheckEquals(ASWLog::ColorMode::Auto, logger.GetColorMode(), "SetColorMode(Auto) should be reflected by GetColorMode()"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_GetInstance_ReturnsSameInstance() +ASW_TEST(TTest_ASWLog_ConsoleLog, GetInstance_ReturnsSameInstance) { // Act auto& first = ASWLog::TASWConsoleLog::GetInstance(); @@ -457,7 +435,7 @@ void TTest_ASWLog_ConsoleLog::Test_GetInstance_ReturnsSameInstance() CheckSame(&first, &second, "GetInstance should return the same logger on every call"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_GetLevelColor_OffHasNoColor() +ASW_TEST(TTest_ASWLog_ConsoleLog, GetLevelColor_OffHasNoColor) { // Arrange ASWLog::TASWConsoleLog logger; @@ -474,7 +452,7 @@ void TTest_ASWLog_ConsoleLog::Test_GetLevelColor_OffHasNoColor() "Setting or resetting Off's color should not change another level's color"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_Initialize_SuppressesInfoBannersBelowMinimumLevel() +ASW_TEST(TTest_ASWLog_ConsoleLog, Initialize_SuppressesInfoBannersBelowMinimumLevel) { // Arrange ASWLog::TASWLogConfig config; @@ -509,7 +487,7 @@ void TTest_ASWLog_ConsoleLog::Test_Initialize_SuppressesInfoBannersBelowMinimumL CheckContains(errContents, "this_error_should_appear", "Messages at or above InitialMinimumLevel should still be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_Initialize_WritesDriveInfoWhenEnabled() +ASW_TEST(TTest_ASWLog_ConsoleLog, Initialize_WritesDriveInfoWhenEnabled) { // Arrange auto config = MakeQuietConfig(); @@ -528,7 +506,7 @@ void TTest_ASWLog_ConsoleLog::Test_Initialize_WritesDriveInfoWhenEnabled() CheckContains(outCapture.Str(), "Drive:", "Startup.WriteDriveInfo should write disk space diagnostics to the console when enabled"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_IsColorSupported_ReflectsDetectedStreams() +ASW_TEST(TTest_ASWLog_ConsoleLog, IsColorSupported_ReflectsDetectedStreams) { // Arrange auto config = MakeQuietConfig(); @@ -553,7 +531,7 @@ void TTest_ASWLog_ConsoleLog::Test_IsColorSupported_ReflectsDetectedStreams() CheckTrue(stdErrOnlyLogger.IsColorSupported(), "IsColorSupported should be true when either stream shows colors"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_LogLineMetadata_Options() +ASW_TEST(TTest_ASWLog_ConsoleLog, LogLineMetadata_Options) { // Arrange auto config = MakeQuietConfig(); @@ -585,7 +563,7 @@ void TTest_ASWLog_ConsoleLog::Test_LogLineMetadata_Options() CheckContains(contents, "metadata_message", "Metadata log line should still contain the message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_LogProcessAndThreadIds_AreOSIds() +ASW_TEST(TTest_ASWLog_ConsoleLog, LogProcessAndThreadIds_AreOSIds) { // Arrange auto config = MakeQuietConfig(); @@ -622,7 +600,7 @@ void TTest_ASWLog_ConsoleLog::Test_LogProcessAndThreadIds_AreOSIds() CheckContains(contents, processTag + "[T:" + std::to_string(workerThreadId) + "]: worker_thread_entry", "An entry from another thread should show that thread's OS thread id"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_LogRawAndForceOptions() +ASW_TEST(TTest_ASWLog_ConsoleLog, LogRawAndForceOptions) { // Arrange auto config = MakeQuietConfig(); @@ -649,7 +627,7 @@ void TTest_ASWLog_ConsoleLog::Test_LogRawAndForceOptions() CheckNotContains(errContents, "raw_force_message\n", "LogForceRaw should not append a trailing newline"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_LogRespectsMinimumLevel() +ASW_TEST(TTest_ASWLog_ConsoleLog, LogRespectsMinimumLevel) { // Arrange auto config = MakeQuietConfig(); @@ -674,7 +652,7 @@ void TTest_ASWLog_ConsoleLog::Test_LogRespectsMinimumLevel() CheckContains(errCapture.Str(), "allowed_message", "Log should write a message at or above the minimum level"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_OnError_ReportsOnlyTheWriteThatFailedTheStream() +ASW_TEST(TTest_ASWLog_ConsoleLog, OnError_ReportsOnlyTheWriteThatFailedTheStream) { // Arrange auto config = MakeQuietConfig(); @@ -708,7 +686,7 @@ void TTest_ASWLog_ConsoleLog::Test_OnError_ReportsOnlyTheWriteThatFailedTheStrea CheckEquals(std::string("Couldn't write to stdout"), reports[0].Message, "The report should name the stream"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_OnLogEntry_FiresForQualifyingLevelsOnly() +ASW_TEST(TTest_ASWLog_ConsoleLog, OnLogEntry_FiresForQualifyingLevelsOnly) { // Arrange auto config = MakeQuietConfig(); @@ -738,7 +716,7 @@ void TTest_ASWLog_ConsoleLog::Test_OnLogEntry_FiresForQualifyingLevelsOnly() CheckContains(callbackMessages[0], "above_threshold", "Callback should receive the same formatted line written to the console"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_ResetLevelColor_RestoresDefault() +ASW_TEST(TTest_ASWLog_ConsoleLog, ResetLevelColor_RestoresDefault) { // Arrange ASWLog::TASWConsoleLog logger; @@ -754,7 +732,7 @@ void TTest_ASWLog_ConsoleLog::Test_ResetLevelColor_RestoresDefault() CheckEquals(defaultInfoColor, restoredColor, "ResetLevelColor should restore the level's built-in default color"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_ResetLevelColors_RestoresAllDefaults() +ASW_TEST(TTest_ASWLog_ConsoleLog, ResetLevelColors_RestoresAllDefaults) { // Arrange ASWLog::TASWConsoleLog logger; @@ -772,7 +750,7 @@ void TTest_ASWLog_ConsoleLog::Test_ResetLevelColors_RestoresAllDefaults() CheckEquals(defaultErrorColor, logger.GetLevelColor(ASWLog::Level::Error), "ResetLevelColors should restore Error's default color"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_SetLevelColor_EmptyStringDisablesColorForLevel() +ASW_TEST(TTest_ASWLog_ConsoleLog, SetLevelColor_EmptyStringDisablesColorForLevel) { // Arrange auto config = MakeQuietConfig(); @@ -795,7 +773,7 @@ void TTest_ASWLog_ConsoleLog::Test_SetLevelColor_EmptyStringDisablesColorForLeve CheckContains(contents, "uncolored_message", "The message should still be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_SetLevelColor_OverridesDefaultColor() +ASW_TEST(TTest_ASWLog_ConsoleLog, SetLevelColor_OverridesDefaultColor) { // Arrange auto config = MakeQuietConfig(); @@ -825,7 +803,7 @@ void TTest_ASWLog_ConsoleLog::Test_SetLevelColor_OverridesDefaultColor() CheckNotContains(contents, defaultInfoColor, "The default color should no longer appear for Info once overridden"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_ConsoleLog::Test_WarnAndAboveWriteToStdErr() +ASW_TEST(TTest_ASWLog_ConsoleLog, WarnAndAboveWriteToStdErr) { // Arrange auto config = MakeQuietConfig(); diff --git a/tests/tests/Test_ASWLog_ConsoleLog.h b/tests/tests/Test_ASWLog_ConsoleLog.h index ffa1ab1..ee44d02 100644 --- a/tests/tests/Test_ASWLog_ConsoleLog.h +++ b/tests/tests/Test_ASWLog_ConsoleLog.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_ConsoleLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_ConsoleLog : public TTestGroupBase +class TTest_ASWLog_ConsoleLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_ColorModeAlways_WrapsOutputWithAnsiCodes(); void Test_ColorModeAuto_ColorsOnlyStreamsThatSupportIt(); void Test_ColorModeAuto_HonorsNoColor(); diff --git a/tests/tests/Test_ASWLog_CrashHandler.cpp b/tests/tests/Test_ASWLog_CrashHandler.cpp index 66ee3c4..f3ce583 100644 --- a/tests/tests/Test_ASWLog_CrashHandler.cpp +++ b/tests/tests/Test_ASWLog_CrashHandler.cpp @@ -566,38 +566,6 @@ std::string TCrashingFormatter::Format(const ASWLog::TASWLogRecord& record, cons TTest_ASWLog_CrashHandler::TTest_ASWLog_CrashHandler() : inherited("ASWLog_CrashHandler_Tests") { - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_CutsALongTextButStaysValid, "AppendCrashJSONLine_CutsALongTextButStaysValid"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_ShowsTheFields, "AppendCrashJSONLine_ShowsTheFields"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_UsesTheFixedLayout, "AppendCrashJSONLine_UsesTheFixedLayout"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_CutsALongMessageButKeepsTheEnding, "AppendCrashLine_CutsALongMessageButKeepsTheEnding"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_FieldsThatDontFitAreLeftOut, "AppendCrashLine_FieldsThatDontFitAreLeftOut"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_FollowsTheMultilineMode, "AppendCrashLine_FollowsTheMultilineMode"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_NeverCutsARewrittenLineBreak, "AppendCrashLine_NeverCutsARewrittenLineBreak"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_ShowsTheFields, "AppendCrashLine_ShowsTheFields"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_ShowsTheCategory, "AppendCrashLine_ShowsTheCategory"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_AppendCrashLine_UsesTheFixedLayout, "AppendCrashLine_UsesTheFixedLayout"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_AbortWritesTheCrashLine, "CrashProcess_AbortWritesTheCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_AsyncQueueIsWrittenBeforeTheCrashLine, "CrashProcess_AsyncQueueIsWrittenBeforeTheCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_FaultWritesTheBacktrace, "CrashProcess_FaultWritesTheBacktrace"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_FaultWritesTheCrashLine, "CrashProcess_FaultWritesTheCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_LockHeldByTheCrashingThreadWritesTheLineDirectly, "CrashProcess_LockHeldByTheCrashingThreadWritesTheLineDirectly"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_StackOverflowWritesTheCrashLine, "CrashProcess_StackOverflowWritesTheCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_TerminateThenAbortWritesOneCrashLine, "CrashProcess_TerminateThenAbortWritesOneCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_CrashProcess_TerminateWritesTheExceptionAndFlushes, "CrashProcess_TerminateWritesTheExceptionAndFlushes"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_ConsoleLogWritesTheLineToStdErr, "HandleCrash_ConsoleLogWritesTheLineToStdErr"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_DisabledLoggerIsOnlyFlushed, "HandleCrash_DisabledLoggerIsOnlyFlushed"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_CrashLineHasTheThreadsScopeFields, "HandleCrash_CrashLineHasTheThreadsScopeFields"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_FixedLayoutLineFollowsTheMultilineMode, "HandleCrash_FixedLayoutLineFollowsTheMultilineMode"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_FlushesAndWritesTheCrashLine, "HandleCrash_FlushesAndWritesTheCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_JSONLoggerGetsJSONLinesWhenTheLockStaysBusy, "HandleCrash_JSONLoggerGetsJSONLinesWhenTheLockStaysBusy"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_SkipsClosedAndDestroyedLoggers, "HandleCrash_SkipsClosedAndDestroyedLoggers"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_SyncsTheLineAtSyncToDiskAtLevel, "HandleCrash_SyncsTheLineAtSyncToDiskAtLevel"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_ThrowingFormatterGetsTheFixedLayoutLine, "HandleCrash_ThrowingFormatterGetsTheFixedLayoutLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_WaitsForQueuedEntries, "HandleCrash_WaitsForQueuedEntries"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_WriteCrashLineFalseOnlyFlushes, "HandleCrash_WriteCrashLineFalseOnlyFlushes"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_WritesTheBacktraceBeforeTheCrashLine, "HandleCrash_WritesTheBacktraceBeforeTheCrashLine"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_HandleCrash_WritesTheLineDirectlyWhenTheLockStaysBusy, "HandleCrash_WritesTheLineDirectlyWhenTheLockStaysBusy"); - RegisterTest(&TTest_ASWLog_CrashHandler::Test_InstallCrashHandlers_ChainsAndUninstallRestores, "InstallCrashHandlers_ChainsAndUninstallRestores"); } //--------------------------------------------------------------------------- TTest_ASWLog_CrashHandler::~TTest_ASWLog_CrashHandler() @@ -630,7 +598,7 @@ void TTest_ASWLog_CrashHandler::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_CutsALongTextButStaysValid() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashJSONLine_CutsALongTextButStaysValid) { // Arrange: a category that alone would fill the buffer, and messages of two-byte characters and quotes, each // escaped as two characters, too long for the buffer; 0 to 3 leading characters move the cut through every @@ -682,7 +650,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_CutsALongTextButStaysVa } } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_ShowsTheFields() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashJSONLine_ShowsTheFields) { // Arrange: a kept entry with fields of each kind using namespace std::chrono; @@ -711,7 +679,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_ShowsTheFields() "The fixed layout should match the JSON formatter's default fields"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_UsesTheFixedLayout() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashJSONLine_UsesTheFixedLayout) { // Arrange: a crash line, and a raw backtrace entry from a category using namespace std::chrono; @@ -749,7 +717,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashJSONLine_UsesTheFixedLayout() "The fixed layout should match the JSON formatter's default fields"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_CutsALongMessageButKeepsTheEnding() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_CutsALongMessageButKeepsTheEnding) { // Arrange const std::string message(3000, 'x'); @@ -767,7 +735,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_CutsALongMessageButKeepsThe CheckEndsWith(text, "x\r\n", "The cut line should still end with the line ending"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_FieldsThatDontFitAreLeftOut() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_FieldsThatDontFitAreLeftOut) { // Arrange: a text field longer than the buffer, then one that no longer fits after it; and a field whose key alone // is too long, between two that fit @@ -812,7 +780,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_FieldsThatDontFitAreLeftOut CheckTrue(IsJSONObjectLine(json.substr(0, json.size() - 2)), "The JSON line should be one JSON object"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_FollowsTheMultilineMode() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_FollowsTheMultilineMode) { // Arrange: a message with each kind of line break, a lone CR, and a line break at its end ASWLog::TASWLogRecord record; @@ -839,7 +807,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_FollowsTheMultilineMode() CheckEndsWith(escaped, "][P:0][T:0]: a\\r\\nb\\n\\rc\\n\r\n", "Escape should keep the entry on one line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_NeverCutsARewrittenLineBreak() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_NeverCutsARewrittenLineBreak) { // Arrange: messages whose line break falls at each place around the end of the buffer struct TCase @@ -890,7 +858,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_NeverCutsARewrittenLineBrea } } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_ShowsTheFields() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_ShowsTheFields) { // Arrange: a kept entry with its own fields using namespace std::chrono; @@ -914,7 +882,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_ShowsTheFields() "The fields should follow the thread id, as in the built-in layout"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_UsesTheFixedLayout() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_UsesTheFixedLayout) { // Arrange using namespace std::chrono; @@ -940,7 +908,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_UsesTheFixedLayout() "The time should be written like the formatter writes it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_ShowsTheCategory() +ASW_TEST(TTest_ASWLog_CrashHandler, AppendCrashLine_ShowsTheCategory) { // Arrange: a backtrace entry from a category, as a crash handler writes it in the fixed layout using namespace std::chrono; @@ -961,7 +929,7 @@ void TTest_ASWLog_CrashHandler::Test_AppendCrashLine_ShowsTheCategory() "The category should follow the level, as in the built-in layout"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_AbortWritesTheCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_AbortWritesTheCrashLine) { // Act const int exitCode = RunCrashHelper("abort", TestTempDir / "abort_output.txt"); @@ -979,7 +947,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_AbortWritesTheCrashLine() CheckNotContains(ReadFileText(TestTempDir / "abort_output.txt"), "Sanitizer", "No sanitizer report"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_AsyncQueueIsWrittenBeforeTheCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_AsyncQueueIsWrittenBeforeTheCrashLine) { // Act const int exitCode = RunCrashHelper("async", TestTempDir / "async_output.txt"); @@ -993,7 +961,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_AsyncQueueIsWrittenBeforeTheCr CheckNotContains(ReadFileText(TestTempDir / "async_output.txt"), "Sanitizer", "No sanitizer report"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_FaultWritesTheBacktrace() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_FaultWritesTheBacktrace) { // Act const int exitCode = RunCrashHelper("fault_backtrace", TestTempDir / "fault_backtrace_output.txt"); @@ -1018,7 +986,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_FaultWritesTheBacktrace() CheckNotContains(ReadFileText(TestTempDir / "fault_backtrace_output.txt"), "Sanitizer", "No sanitizer report"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_FaultWritesTheCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_FaultWritesTheCrashLine) { // Act const int exitCode = RunCrashHelper("fault", TestTempDir / "fault_output.txt"); @@ -1041,7 +1009,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_FaultWritesTheCrashLine() CheckNotContains(ReadFileText(TestTempDir / "fault_output.txt"), "Sanitizer", "No sanitizer report"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_LockHeldByTheCrashingThreadWritesTheLineDirectly() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_LockHeldByTheCrashingThreadWritesTheLineDirectly) { #if defined(ASWLOG_TEST_DELPHI_RTL) Skip("With the Delphi RTL, a fault in a formatter ends the process before any crash handler runs"); @@ -1066,7 +1034,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_LockHeldByTheCrashingThreadWri CheckNotContains(ReadFileText(TestTempDir / "lock_held_output.txt"), "Sanitizer", "No sanitizer report"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_StackOverflowWritesTheCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_StackOverflowWritesTheCrashLine) { #if defined(ASWLOG_TEST_SANITIZED) Skip("A sanitizer handles the stack itself"); @@ -1089,7 +1057,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_StackOverflowWritesTheCrashLin #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_TerminateThenAbortWritesOneCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_TerminateThenAbortWritesOneCrashLine) { // Act const int exitCode = RunCrashHelper("terminate_then_abort", TestTempDir / "terminate_then_abort_output.txt"); @@ -1101,7 +1069,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_TerminateThenAbortWritesOneCra "The crash should get one line, from the terminate handler"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_CrashProcess_TerminateWritesTheExceptionAndFlushes() +ASW_TEST(TTest_ASWLog_CrashHandler, CrashProcess_TerminateWritesTheExceptionAndFlushes) { // Act const int exitCode = RunCrashHelper("terminate", TestTempDir / "terminate_output.txt"); @@ -1115,7 +1083,7 @@ void TTest_ASWLog_CrashHandler::Test_CrashProcess_TerminateWritesTheExceptionAnd CheckNotContains(ReadFileText(TestTempDir / "terminate_output.txt"), "Sanitizer", "No sanitizer report"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_ConsoleLogWritesTheLineToStdErr() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_ConsoleLogWritesTheLineToStdErr) { // Arrange ASWLog::TASWConsoleLog log; @@ -1136,7 +1104,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_ConsoleLogWritesTheLineToStdErr CheckEquals(std::string(), capturedOut.str(), "Nothing should go to stdout"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_DisabledLoggerIsOnlyFlushed() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_DisabledLoggerIsOnlyFlushed) { // Arrange ASWLog::TASWFileLog log; @@ -1152,7 +1120,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_DisabledLoggerIsOnlyFlushed() "A disabled logger should be flushed, without the crash line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_CrashLineHasTheThreadsScopeFields() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_CrashLineHasTheThreadsScopeFields) { // Arrange: two loggers, one whose lock another thread holds ASWLog::TASWFileLog log; @@ -1173,7 +1141,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_CrashLineHasTheThreadsScopeFiel ASWLog::GetCurrentOSThreadId()), "The fixed-layout crash line should have them too"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_FixedLayoutLineFollowsTheMultilineMode() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_FixedLayoutLineFollowsTheMultilineMode) { // Arrange: an Indent logger with a multi-line backtrace entry (HandleCrashWhileLocked() holds its lock on another // thread meanwhile), reconfigured to CRLF endings @@ -1197,7 +1165,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_FixedLayoutLineFollowsTheMultil CheckEndsWith(contents, "][CRITICAL]" + ids + "Crash: busy\r\n | reason\r\n", "The crash line should be indented"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_FlushesAndWritesTheCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_FlushesAndWritesTheCrashLine) { // Arrange ASWLog::TASWFileLog log; @@ -1214,7 +1182,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_FlushesAndWritesTheCrashLine() "The buffered entry should be flushed, then the formatted crash line written and flushed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_JSONLoggerGetsJSONLinesWhenTheLockStaysBusy() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_JSONLoggerGetsJSONLinesWhenTheLockStaysBusy) { // Arrange: a JSON logger with a backtrace entry (HandleCrashWhileLocked() holds its lock on another thread meanwhile) auto config = MakeCrashTestConfig("busy.json"); @@ -1254,7 +1222,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_JSONLoggerGetsJSONLinesWhenTheL CheckEndsWith(lines[3], R"("level":"CRITICAL",)" + ids + R"("message":"Crash: busy \"json\""})", "Then the crash line, escaped"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_SkipsClosedAndDestroyedLoggers() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_SkipsClosedAndDestroyedLoggers) { // Arrange: one logger closed, one destroyed (a crash handler must not touch it) ASWLog::TASWFileLog closedLog; @@ -1276,7 +1244,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_SkipsClosedAndDestroyedLoggers( CheckEquals(std::string("[INFO]: entry_1\n"), ReadFileText(TestTempDir / "destroyed.log"), "A destroyed logger should get no crash line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_SyncsTheLineAtSyncToDiskAtLevel() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_SyncsTheLineAtSyncToDiskAtLevel) { // Arrange: the null device takes every write, but can't be synced to disk (see the FileLog OnError tests), so a // sync shows as a SyncFailed report. A crash reports nothing itself; Close() passes on what it found. @@ -1315,7 +1283,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_SyncsTheLineAtSyncToDiskAtLevel CheckEquals(ASWLog::ErrorKind::SyncFailed, reports[0], "The report should be SyncFailed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_ThrowingFormatterGetsTheFixedLayoutLine() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_ThrowingFormatterGetsTheFixedLayoutLine) { // Arrange auto config = MakeCrashTestConfig("throwing.log"); @@ -1334,7 +1302,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_ThrowingFormatterGetsTheFixedLa ASWLog::GetCurrentOSThreadId()), "The fixed-layout line should replace the line the formatter failed to make"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_WaitsForQueuedEntries() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_WaitsForQueuedEntries) { // Arrange: the worker pauses after writing entry_1, and entry_2 and entry_3 are queued meanwhile std::mutex mutex; @@ -1378,7 +1346,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_WaitsForQueuedEntries() ReadFileText(TestTempDir / "async.log"), "The queued entries should be written before the crash line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_WriteCrashLineFalseOnlyFlushes() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_WriteCrashLineFalseOnlyFlushes) { // Arrange auto config = MakeCrashTestConfig("no_line.log"); @@ -1395,7 +1363,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_WriteCrashLineFalseOnlyFlushes( "The logger should be flushed, without the crash line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_WritesTheBacktraceBeforeTheCrashLine() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_WritesTheBacktraceBeforeTheCrashLine) { // Arrange auto config = MakeCrashTestConfig("backtrace.log"); @@ -1420,7 +1388,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_WritesTheBacktraceBeforeTheCras "The written backtrace should be forgotten"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_HandleCrash_WritesTheLineDirectlyWhenTheLockStaysBusy() +ASW_TEST(TTest_ASWLog_CrashHandler, HandleCrash_WritesTheLineDirectlyWhenTheLockStaysBusy) { // Arrange: a backtrace entry (HandleCrashWhileLocked() holds the logger's lock on another thread meanwhile) auto config = MakeCrashTestConfig("busy.log"); @@ -1448,7 +1416,7 @@ void TTest_ASWLog_CrashHandler::Test_HandleCrash_WritesTheLineDirectlyWhenTheLoc "The backtrace should be written straight to the file too, in the fixed layout, before the crash line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_CrashHandler::Test_InstallCrashHandlers_ChainsAndUninstallRestores() +ASW_TEST(TTest_ASWLog_CrashHandler, InstallCrashHandlers_ChainsAndUninstallRestores) { // Arrange: the handlers in place before const auto previousTerminate = std::set_terminate(ExitAsPassedOn); diff --git a/tests/tests/Test_ASWLog_CrashHandler.h b/tests/tests/Test_ASWLog_CrashHandler.h index e52550a..3cad174 100644 --- a/tests/tests/Test_ASWLog_CrashHandler.h +++ b/tests/tests/Test_ASWLog_CrashHandler.h @@ -34,12 +34,12 @@ namespace ASWUnitTests // tests start this test executable again, which then runs a crash scenario before main() (see // RunCrashHelperIfRequested() in the .cpp) and crashes; the test checks its log files. /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_CrashHandler : public TTestGroupBase +class TTest_ASWLog_CrashHandler : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_AppendCrashJSONLine_CutsALongTextButStaysValid(); void Test_AppendCrashJSONLine_ShowsTheFields(); void Test_AppendCrashJSONLine_UsesTheFixedLayout(); diff --git a/tests/tests/Test_ASWLog_DebuggerLog.cpp b/tests/tests/Test_ASWLog_DebuggerLog.cpp index b8c6b02..0667081 100644 --- a/tests/tests/Test_ASWLog_DebuggerLog.cpp +++ b/tests/tests/Test_ASWLog_DebuggerLog.cpp @@ -198,10 +198,6 @@ class TDebugOutputListener TTest_ASWLog_DebuggerLog::TTest_ASWLog_DebuggerLog() : inherited("ASWLog_DebuggerLog_Tests") { - RegisterTest(&TTest_ASWLog_DebuggerLog::Test_GetInstance_ReturnsTheSameLogger, "GetInstance_ReturnsTheSameLogger"); - RegisterTest(&TTest_ASWLog_DebuggerLog::Test_ShouldLog_FollowsThePlatform, "ShouldLog_FollowsThePlatform"); - RegisterTest(&TTest_ASWLog_DebuggerLog::Test_Windows_SendsEachLineToTheDebugOutput, "Windows_SendsEachLineToTheDebugOutput"); - RegisterTest(&TTest_ASWLog_DebuggerLog::Test_Windows_WritesTheCrashLineDirectly, "Windows_WritesTheCrashLineDirectly"); } //--------------------------------------------------------------------------- TTest_ASWLog_DebuggerLog::~TTest_ASWLog_DebuggerLog() @@ -229,7 +225,7 @@ void TTest_ASWLog_DebuggerLog::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_DebuggerLog::Test_GetInstance_ReturnsTheSameLogger() +ASW_TEST(TTest_ASWLog_DebuggerLog, GetInstance_ReturnsTheSameLogger) { // Act auto& first = ASWLog::TASWDebuggerLog::GetInstance(); @@ -239,7 +235,7 @@ void TTest_ASWLog_DebuggerLog::Test_GetInstance_ReturnsTheSameLogger() CheckSame(&first, &second, "GetInstance() should always return the same logger"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_DebuggerLog::Test_ShouldLog_FollowsThePlatform() +ASW_TEST(TTest_ASWLog_DebuggerLog, ShouldLog_FollowsThePlatform) { // Arrange ASWLog::TASWDebuggerLog log; @@ -264,7 +260,7 @@ void TTest_ASWLog_DebuggerLog::Test_ShouldLog_FollowsThePlatform() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_DebuggerLog::Test_Windows_SendsEachLineToTheDebugOutput() +ASW_TEST(TTest_ASWLog_DebuggerLog, Windows_SendsEachLineToTheDebugOutput) { #if defined(_WIN32) // Arrange: listen like DebugView, which needs no debugger attached and no other listener @@ -302,7 +298,7 @@ void TTest_ASWLog_DebuggerLog::Test_Windows_SendsEachLineToTheDebugOutput() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_DebuggerLog::Test_Windows_WritesTheCrashLineDirectly() +ASW_TEST(TTest_ASWLog_DebuggerLog, Windows_WritesTheCrashLineDirectly) { #if defined(_WIN32) // Arrange diff --git a/tests/tests/Test_ASWLog_DebuggerLog.h b/tests/tests/Test_ASWLog_DebuggerLog.h index cc6d992..3ecd159 100644 --- a/tests/tests/Test_ASWLog_DebuggerLog.h +++ b/tests/tests/Test_ASWLog_DebuggerLog.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_DebuggerLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_DebuggerLog : public TTestGroupBase +class TTest_ASWLog_DebuggerLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_GetInstance_ReturnsTheSameLogger(); void Test_ShouldLog_FollowsThePlatform(); void Test_Windows_SendsEachLineToTheDebugOutput(); diff --git a/tests/tests/Test_ASWLog_Fields.cpp b/tests/tests/Test_ASWLog_Fields.cpp index 62bcf31..4c91dc5 100644 --- a/tests/tests/Test_ASWLog_Fields.cpp +++ b/tests/tests/Test_ASWLog_Fields.cpp @@ -199,19 +199,6 @@ class TFieldsLogger final : public ASWLog::TASWLogBase TTest_ASWLog_Fields::TTest_ASWLog_Fields() : inherited("ASWLog_Fields_Tests") { - RegisterTest(&TTest_ASWLog_Fields::Test_Async_OnLogEntryGetsTheFieldsAfterTheScopeEnds, "Async_OnLogEntryGetsTheFieldsAfterTheScopeEnds"); - RegisterTest(&TTest_ASWLog_Fields::Test_Backtrace_KeepsTheFieldsAfterTheScopeEnds, "Backtrace_KeepsTheFieldsAfterTheScopeEnds"); - RegisterTest(&TTest_ASWLog_Fields::Test_Capture_TakesTheScopesToAnotherThread, "Capture_TakesTheScopesToAnotherThread"); - RegisterTest(&TTest_ASWLog_Fields::Test_ForEachLogField_EachKeyOnceInnermostWins, "ForEachLogField_EachKeyOnceInnermostWins"); - RegisterTest(&TTest_ASWLog_Fields::Test_ForEachLogField_RepeatedKeysInTheEntrysOwnFields, "ForEachLogField_RepeatedKeysInTheEntrysOwnFields"); - RegisterTest(&TTest_ASWLog_Fields::Test_Log_CategoryAndMultiLogPassTheFieldsOn, "Log_CategoryAndMultiLogPassTheFieldsOn"); - RegisterTest(&TTest_ASWLog_Fields::Test_Log_EachOverloadPassesItsFields, "Log_EachOverloadPassesItsFields"); - RegisterTest(&TTest_ASWLog_Fields::Test_Log_ScopeFieldsComeBeforeTheEntrysOwn, "Log_ScopeFieldsComeBeforeTheEntrysOwn"); - RegisterTest(&TTest_ASWLog_Fields::Test_Scope_CopiesTemporaryTexts, "Scope_CopiesTemporaryTexts"); - RegisterTest(&TTest_ASWLog_Fields::Test_Scope_IsPerThread, "Scope_IsPerThread"); - RegisterTest(&TTest_ASWLog_Fields::Test_Scope_NestsAndRestoresTheCurrentScope, "Scope_NestsAndRestoresTheCurrentScope"); - RegisterTest(&TTest_ASWLog_Fields::Test_Value_KindsFromEachType, "Value_KindsFromEachType"); - RegisterTest(&TTest_ASWLog_Fields::Test_Value_RejectsCharactersEnumsAndPointers, "Value_RejectsCharactersEnumsAndPointers"); } //--------------------------------------------------------------------------- TTest_ASWLog_Fields::~TTest_ASWLog_Fields() @@ -244,7 +231,7 @@ void TTest_ASWLog_Fields::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Async_OnLogEntryGetsTheFieldsAfterTheScopeEnds() +ASW_TEST(TTest_ASWLog_Fields, Async_OnLogEntryGetsTheFieldsAfterTheScopeEnds) { // Arrange: an asynchronous file logger whose OnLogEntry, on the logger's thread, describes each entry's fields std::mutex mutex; @@ -293,7 +280,7 @@ void TTest_ASWLog_Fields::Test_Async_OnLogEntryGetsTheFieldsAfterTheScopeEnds() "OnLogEntry should get copies of the entry's fields and its scope's, made when the entry was queued"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Backtrace_KeepsTheFieldsAfterTheScopeEnds() +ASW_TEST(TTest_ASWLog_Fields, Backtrace_KeepsTheFieldsAfterTheScopeEnds) { // Arrange ASWLog::TASWLogConfig config; @@ -318,7 +305,7 @@ void TTest_ASWLog_Fields::Test_Backtrace_KeepsTheFieldsAfterTheScopeEnds() CheckEquals(std::string("failed|code=i:5"), logger.Written[3], "The error should have its own fields only"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Capture_TakesTheScopesToAnotherThread() +ASW_TEST(TTest_ASWLog_Fields, Capture_TakesTheScopesToAnotherThread) { // Arrange ASWLog::TASWLogContext context; @@ -368,7 +355,7 @@ void TTest_ASWLog_Fields::Test_Capture_TakesTheScopesToAnotherThread() CheckEmpty(afterScopeOnOtherThread, "The other thread should have no scope once it ends"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_ForEachLogField_EachKeyOnceInnermostWins() +ASW_TEST(TTest_ASWLog_Fields, ForEachLogField_EachKeyOnceInnermostWins) { // Arrange: user and req in an outer scope, req again in an inner one, then the entry's own user and x (twice) const ASWLog::TASWLogScope outer{ { "user", "amy" }, { "req", 1 } }; @@ -385,7 +372,7 @@ void TTest_ASWLog_Fields::Test_ForEachLogField_EachKeyOnceInnermostWins() CheckEquals(std::string("user=t:amy req=i:2 depth=i:1"), scopesOnly, "Without the entry's fields, the inner scope should win"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_ForEachLogField_RepeatedKeysInTheEntrysOwnFields() +ASW_TEST(TTest_ASWLog_Fields, ForEachLogField_RepeatedKeysInTheEntrysOwnFields) { // Arrange const ASWLog::TASWLogField own[] = { { "a", 1 }, { "b", 2 }, { "a", 3 }, { "c", 4 }, { "b", 5 } }; @@ -399,7 +386,7 @@ void TTest_ASWLog_Fields::Test_ForEachLogField_RepeatedKeysInTheEntrysOwnFields( CheckEmpty(none, "No fields should give nothing"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Log_CategoryAndMultiLogPassTheFieldsOn() +ASW_TEST(TTest_ASWLog_Fields, Log_CategoryAndMultiLogPassTheFieldsOn) { // Arrange: a category over a multi-log over two loggers TFieldsLogger first; @@ -423,7 +410,7 @@ void TTest_ASWLog_Fields::Test_Log_CategoryAndMultiLogPassTheFieldsOn() CheckTrue(second.Written == expected, "The second logger should get them too"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Log_EachOverloadPassesItsFields() +ASW_TEST(TTest_ASWLog_Fields, Log_EachOverloadPassesItsFields) { // Arrange ASWLog::TASWLogConfig config; @@ -470,7 +457,7 @@ void TTest_ASWLog_Fields::Test_Log_EachOverloadPassesItsFields() CheckEquals(expected[index], logger.Written[index], "Each overload should pass its message and fields"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Log_ScopeFieldsComeBeforeTheEntrysOwn() +ASW_TEST(TTest_ASWLog_Fields, Log_ScopeFieldsComeBeforeTheEntrysOwn) { // Arrange TFieldsLogger logger; @@ -492,7 +479,7 @@ void TTest_ASWLog_Fields::Test_Log_ScopeFieldsComeBeforeTheEntrysOwn() CheckTrue(logger.Written == expected, "Entries in the scope should carry its fields, the entry's own after them and winning"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Scope_CopiesTemporaryTexts() +ASW_TEST(TTest_ASWLog_Fields, Scope_CopiesTemporaryTexts) { // Arrange & Act: keys and texts that are gone once the scope is made const ASWLog::TASWLogScope scope{ { std::string("requestId"), std::to_string(12345) }, @@ -505,7 +492,7 @@ void TTest_ASWLog_Fields::Test_Scope_CopiesTemporaryTexts() CheckEquals(std::size_t(16), filler.size(), "(keeps the filler alive)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Scope_IsPerThread() +ASW_TEST(TTest_ASWLog_Fields, Scope_IsPerThread) { // Arrange const ASWLog::TASWLogScope scope{ { "requestId", "r-3" } }; @@ -522,7 +509,7 @@ void TTest_ASWLog_Fields::Test_Scope_IsPerThread() CheckNull(onOtherThread, "Another thread should have no scope"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Scope_NestsAndRestoresTheCurrentScope() +ASW_TEST(TTest_ASWLog_Fields, Scope_NestsAndRestoresTheCurrentScope) { // Arrange const ASWLog::TASWLogScope* beforeAll = ASWLog::TASWLogScope::GetCurrent(); @@ -557,7 +544,7 @@ void TTest_ASWLog_Fields::Test_Scope_NestsAndRestoresTheCurrentScope() CheckNull(afterAll, "No scope should be current after both end"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Value_KindsFromEachType() +ASW_TEST(TTest_ASWLog_Fields, Value_KindsFromEachType) { // Arrange const std::string text = "from std::string"; @@ -584,7 +571,7 @@ void TTest_ASWLog_Fields::Test_Value_KindsFromEachType() CheckSame(text.data(), fields[12].Value.GetText().data(), "Text should be a view of the caller's characters, not a copy"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Fields::Test_Value_RejectsCharactersEnumsAndPointers() +ASW_TEST(TTest_ASWLog_Fields, Value_RejectsCharactersEnumsAndPointers) { // Act & Assert: these would otherwise become a number or a bool without the caller noticing CheckFalse(std::is_constructible_v, "A char should be rejected"); diff --git a/tests/tests/Test_ASWLog_Fields.h b/tests/tests/Test_ASWLog_Fields.h index d27b70f..a5bf7b4 100644 --- a/tests/tests/Test_ASWLog_Fields.h +++ b/tests/tests/Test_ASWLog_Fields.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Fields /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Fields : public TTestGroupBase +class TTest_ASWLog_Fields : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Async_OnLogEntryGetsTheFieldsAfterTheScopeEnds(); void Test_Backtrace_KeepsTheFieldsAfterTheScopeEnds(); void Test_Capture_TakesTheScopesToAnotherThread(); diff --git a/tests/tests/Test_ASWLog_FileLog.cpp b/tests/tests/Test_ASWLog_FileLog.cpp index 1fbe523..0568aad 100644 --- a/tests/tests/Test_ASWLog_FileLog.cpp +++ b/tests/tests/Test_ASWLog_FileLog.cpp @@ -364,101 +364,6 @@ bool WaitUntil(const std::function& condition) TTest_ASWLog_FileLog::TTest_ASWLog_FileLog() : inherited("ASWLog_FileLog_Tests") { - RegisterTest(&TTest_ASWLog_FileLog::Test_Async_DropsAnEntryWhileTheFileCantBeOpened, "Async_DropsAnEntryWhileTheFileCantBeOpened"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Async_EntryAtWaitAtLevelIsInTheFileWhenTheCallReturns, "Async_EntryAtWaitAtLevelIsInTheFileWhenTheCallReturns"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Async_EveryWriteFlushesEachBatch, "Async_EveryWriteFlushesEachBatch"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Async_PeriodicFlushesOnTheSameThread, "Async_PeriodicFlushesOnTheSameThread"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Async_ReconfigureWritesQueuedEntriesToTheOldFile, "Async_ReconfigureWritesQueuedEntriesToTheOldFile"); - RegisterTest(&TTest_ASWLog_FileLog::Test_AutoOpenClose_StaysInitializedBetweenWrites, "AutoOpenClose_StaysInitializedBetweenWrites"); - RegisterTest(&TTest_ASWLog_FileLog::Test_BackupLimits_ApplyOnlyToThisLogsBackups, "BackupLimits_ApplyOnlyToThisLogsBackups"); - RegisterTest(&TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupFilesKeepsNewestByLastWrite, "BackupLimits_MaxBackupFilesKeepsNewestByLastWrite"); - RegisterTest(&TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupTotalBytesDeletesOldestFirst, "BackupLimits_MaxBackupTotalBytesDeletesOldestFirst"); - RegisterTest(&TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupTotalBytesIsStrict, "BackupLimits_MaxBackupTotalBytesIsStrict"); - RegisterTest(&TTest_ASWLog_FileLog::Test_BackupLimits_ZeroKeepsEveryBackup, "BackupLimits_ZeroKeepsEveryBackup"); - RegisterTest(&TTest_ASWLog_FileLog::Test_ChildProcess_DoesNotInheritLogFile, "ChildProcess_DoesNotInheritLogFile"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_KeepsExistingBackupForSameDate, "DailyRolling_KeepsExistingBackupForSameDate"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_KeepsLeftoverLogFromSameDay, "DailyRolling_KeepsLeftoverLogFromSameDay"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_LocalZoneRollsAtLocalMidnight, "DailyRolling_LocalZoneRollsAtLocalMidnight"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_NamesBackupForContentDate, "DailyRolling_NamesBackupForContentDate"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_ReconfiguredZoneRollsAtItsMidnight, "DailyRolling_ReconfiguredZoneRollsAtItsMidnight"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_RotatesLeftoverLogFromEarlierDay, "DailyRolling_RotatesLeftoverLogFromEarlierDay"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_RotatesLeftoverLogFromEarlierLocalDay, "DailyRolling_RotatesLeftoverLogFromEarlierLocalDay"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DailyRolling_SharedLogRollsOverOnce, "DailyRolling_SharedLogRollsOverOnce"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DeleteOldLogs_AcceptsShortRelativeFolder, "DeleteOldLogs_AcceptsShortRelativeFolder"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DeleteOldLogs_EmptyPatternDeletesNothing, "DeleteOldLogs_EmptyPatternDeletesNothing"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DeleteOldLogs_KeepsNonMatchingFilesAndSubfolders, "DeleteOldLogs_KeepsNonMatchingFilesAndSubfolders"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DeleteOldLogs_MatchesNonASCIIFileNames, "DeleteOldLogs_MatchesNonASCIIFileNames"); - RegisterTest(&TTest_ASWLog_FileLog::Test_DeleteOldLogs_RemovesOldFiles, "DeleteOldLogs_RemovesOldFiles"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FailedOpen_TriesOpenRetryCountTimes, "FailedOpen_TriesOpenRetryCountTimes"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FailedReopen_RetriesAndResumesLogging, "FailedReopen_RetriesAndResumesLogging"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FailedReopen_ZeroResetDelayRetriesOnNextWrite, "FailedReopen_ZeroResetDelayRetriesOnNextWrite"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FailedSizeRotation_WaitsBeforeRetrying, "FailedSizeRotation_WaitsBeforeRetrying"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FileStream_FlushWorksAfterFailedWrite, "FileStream_FlushWorksAfterFailedWrite"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FileStream_InsertionIntoAClosedStreamFails, "FileStream_InsertionIntoAClosedStreamFails"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FileStream_InsertionWritesAndCountsTheSize, "FileStream_InsertionWritesAndCountsTheSize"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FlushImmediatelyAtLevel_FlushesEntriesAtOrAboveTheLevel, "FlushImmediatelyAtLevel_FlushesEntriesAtOrAboveTheLevel"); - RegisterTest(&TTest_ASWLog_FileLog::Test_FlushImmediatelyAtLevel_OffLeavesFlushingToFlushMode, "FlushImmediatelyAtLevel_OffLeavesFlushingToFlushMode"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Flush_WritesBufferedManualModeEntries, "Flush_WritesBufferedManualModeEntries"); - RegisterTest(&TTest_ASWLog_FileLog::Test_GetInstance_ReturnsSameInstance, "GetInstance_ReturnsSameInstance"); - RegisterTest(&TTest_ASWLog_FileLog::Test_InitializeAndLogInfo_WritesText, "InitializeAndLogInfo_WritesText"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Initialize_SuppressesInfoBannersBelowMinimumLevel, "Initialize_SuppressesInfoBannersBelowMinimumLevel"); - RegisterTest(&TTest_ASWLog_FileLog::Test_LogFormatMethods_FormatsMessage, "LogFormatMethods_FormatsMessage"); - RegisterTest(&TTest_ASWLog_FileLog::Test_LogFormatMethods_WriteCallerSourceLine, "LogFormatMethods_WriteCallerSourceLine"); - RegisterTest(&TTest_ASWLog_FileLog::Test_LogLineMetadata_Options, "LogLineMetadata_Options"); - RegisterTest(&TTest_ASWLog_FileLog::Test_LogNewLineAndForceOptions, "LogNewLineAndForceOptions"); - RegisterTest(&TTest_ASWLog_FileLog::Test_LogProcessAndThreadIds_AreOSIds, "LogProcessAndThreadIds_AreOSIds"); - RegisterTest(&TTest_ASWLog_FileLog::Test_LogRawOptions, "LogRawOptions"); - RegisterTest(&TTest_ASWLog_FileLog::Test_MultiThreadedStress_WritesAllMessagesToDisk, "MultiThreadedStress_WritesAllMessagesToDisk"); - RegisterTest(&TTest_ASWLog_FileLog::Test_MultiThreadedStress_WritesAllMessagesToDisk_OpenClose, "MultiThreadedStress_WritesAllMessagesToDisk_OpenClose"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_AsyncWorkerWritesTheStartupLinesBeforeTheEntry, "NewFile_AsyncWorkerWritesTheStartupLinesBeforeTheEntry"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_DailyRollingStartsWithTheStartupLines, "NewFile_DailyRollingStartsWithTheStartupLines"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_FailedRotationWritesNoStartupLines, "NewFile_FailedRotationWritesNoStartupLines"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_InitializeWritesItsStartupLinesOnce, "NewFile_InitializeWritesItsStartupLinesOnce"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_ManualRotationOpensASharedLogForTheStartupLines, "NewFile_ManualRotationOpensASharedLogForTheStartupLines"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_MinimumLevelAboveInfoLeavesOutTheStartupLines, "NewFile_MinimumLevelAboveInfoLeavesOutTheStartupLines"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_ReconfigureToANewPathStartsWithTheStartupLines, "NewFile_ReconfigureToANewPathStartsWithTheStartupLines"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_RotationWaitsUntilTheStartupLinesAreWritten, "NewFile_RotationWaitsUntilTheStartupLinesAreWritten"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_SharedLogGetsTheStartupLinesOnce, "NewFile_SharedLogGetsTheStartupLinesOnce"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_SizeRotationStartsWithTheStartupLines, "NewFile_SizeRotationStartsWithTheStartupLines"); - RegisterTest(&TTest_ASWLog_FileLog::Test_NewFile_UnopenedFileGetsTheStartupLinesWhenItOpens, "NewFile_UnopenedFileGetsTheStartupLinesWhenItOpens"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnBackupCreated_IsNotCalledWhenRotationFails, "OnBackupCreated_IsNotCalledWhenRotationFails"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnBackupCreated_LeavesARenamedBackupToTheApp, "OnBackupCreated_LeavesARenamedBackupToTheApp"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnBackupCreated_ReportsDailyBackupAtInitialize, "OnBackupCreated_ReportsDailyBackupAtInitialize"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnBackupCreated_ReportsEachBackup, "OnBackupCreated_ReportsEachBackup"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnBackupCreated_RunsOutsideTheLockBeforeCleanup, "OnBackupCreated_RunsOutsideTheLockBeforeCleanup"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnBackupCreated_ThrowingCallbackStillCleansUp, "OnBackupCreated_ThrowingCallbackStillCleansUp"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnError_ReportsFailedDelete, "OnError_ReportsFailedDelete"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnError_ReportsFailedOpen, "OnError_ReportsFailedOpen"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnError_ReportsFailedRotationAndReopen, "OnError_ReportsFailedRotationAndReopen"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnError_ReportsFailedSync, "OnError_ReportsFailedSync"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnError_ReportsFullDisk, "OnError_ReportsFullDisk"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnLogEntry_FiresForQualifyingLevelsOnly, "OnLogEntry_FiresForQualifyingLevelsOnly"); - RegisterTest(&TTest_ASWLog_FileLog::Test_OnLogEntry_ReentrantCallbackDoesNotDeadlock, "OnLogEntry_ReentrantCallbackDoesNotDeadlock"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Open_KeepsAnOpenFile, "Open_KeepsAnOpenFile"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_CloseStopsAndOpenRestartsTheThread, "Periodic_CloseStopsAndOpenRestartsTheThread"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_CloseStopsTheThreadWithoutWaitingForTheInterval, "Periodic_CloseStopsTheThreadWithoutWaitingForTheInterval"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_ConcurrentLoggingAndReconfigure, "Periodic_ConcurrentLoggingAndReconfigure"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_DestructorStopsTheThreadWithoutWaitingForTheInterval, "Periodic_DestructorStopsTheThreadWithoutWaitingForTheInterval"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_ErrorHandlerCanCloseAndReopenOnTheThread, "Periodic_ErrorHandlerCanCloseAndReopenOnTheThread"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_FlushesAfterTheLastEntry, "Periodic_FlushesAfterTheLastEntry"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_ReconfigureAppliesANewInterval, "Periodic_ReconfigureAppliesANewInterval"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_ReconfigureStartsAndStopsTheThread, "Periodic_ReconfigureStartsAndStopsTheThread"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Periodic_ZeroIntervalFlushesEveryEntry, "Periodic_ZeroIntervalFlushesEveryEntry"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Reconfigure_FlushesEntriesBufferedByPreviousMode, "Reconfigure_FlushesEntriesBufferedByPreviousMode"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Reconfigure_MovesOutputToNewFile, "Reconfigure_MovesOutputToNewFile"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Reconfigure_UnopenableFileFailsButLoggerStaysInitialized, "Reconfigure_UnopenableFileFailsButLoggerStaysInitialized"); - RegisterTest(&TTest_ASWLog_FileLog::Test_RetentionMaxAge_DefaultDisabledPreservesOldBackups, "RetentionMaxAge_DefaultDisabledPreservesOldBackups"); - RegisterTest(&TTest_ASWLog_FileLog::Test_RetentionMaxAge_DeletesExpiredBackupsAfterRotation, "RetentionMaxAge_DeletesExpiredBackupsAfterRotation"); - RegisterTest(&TTest_ASWLog_FileLog::Test_RotateLogFiles_FailsWhenEveryBackupNameIsTaken, "RotateLogFiles_FailsWhenEveryBackupNameIsTaken"); - RegisterTest(&TTest_ASWLog_FileLog::Test_RotateLogFiles_KeepsEveryBackup, "RotateLogFiles_KeepsEveryBackup"); - RegisterTest(&TTest_ASWLog_FileLog::Test_RotateLogFiles_NamesBackupInLocalTime, "RotateLogFiles_NamesBackupInLocalTime"); - RegisterTest(&TTest_ASWLog_FileLog::Test_SetEnabled_FalseStopsAutoOpenCloseLogging, "SetEnabled_FalseStopsAutoOpenCloseLogging"); - RegisterTest(&TTest_ASWLog_FileLog::Test_ShutdownLine_TimeFollowsTimestampZone, "ShutdownLine_TimeFollowsTimestampZone"); - RegisterTest(&TTest_ASWLog_FileLog::Test_SizeRotation_AutoOpenCloseCountsOtherWriters, "SizeRotation_AutoOpenCloseCountsOtherWriters"); - RegisterTest(&TTest_ASWLog_FileLog::Test_SizeRotation_CountsExistingFileSize, "SizeRotation_CountsExistingFileSize"); - RegisterTest(&TTest_ASWLog_FileLog::Test_SizeRotation_RotatesWhenLimitReached, "SizeRotation_RotatesWhenLimitReached"); - RegisterTest(&TTest_ASWLog_FileLog::Test_SyncToDiskAtLevel_FlushesAndSyncsEntriesAtOrAboveTheLevel, "SyncToDiskAtLevel_FlushesAndSyncsEntriesAtOrAboveTheLevel"); - RegisterTest(&TTest_ASWLog_FileLog::Test_Write_EarlierRecordDoesNotRollLogBack, "Write_EarlierRecordDoesNotRollLogBack"); } //--------------------------------------------------------------------------- TTest_ASWLog_FileLog::~TTest_ASWLog_FileLog() @@ -493,7 +398,7 @@ void TTest_ASWLog_FileLog::TearDown_Test(ITestCase& testCase) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Async_DropsAnEntryWhileTheFileCantBeOpened() +ASW_TEST(TTest_ASWLog_FileLog, Async_DropsAnEntryWhileTheFileCantBeOpened) { // Arrange: a "folder" that is a file can't hold the log, on any OS and for any user using namespace std::chrono_literals; @@ -534,7 +439,7 @@ void TTest_ASWLog_FileLog::Test_Async_DropsAnEntryWhileTheFileCantBeOpened() CheckTrue(callbackMessages == expectedMessages, "OnLogEntry should be called only for the entries written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Async_EntryAtWaitAtLevelIsInTheFileWhenTheCallReturns() +ASW_TEST(TTest_ASWLog_FileLog, Async_EntryAtWaitAtLevelIsInTheFileWhenTheCallReturns) { // Arrange: neither the flush mode nor the flush level would flush these entries const auto logFile = TestTempDir / "async_wait_level.log"; @@ -557,7 +462,7 @@ void TTest_ASWLog_FileLog::Test_Async_EntryAtWaitAtLevelIsInTheFileWhenTheCallRe "When the Error call returns, its entry and those before it should be in the file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Async_EveryWriteFlushesEachBatch() +ASW_TEST(TTest_ASWLog_FileLog, Async_EveryWriteFlushesEachBatch) { // Arrange const auto logFile = TestTempDir / "async_every_write.log"; @@ -579,7 +484,7 @@ void TTest_ASWLog_FileLog::Test_Async_EveryWriteFlushesEachBatch() CheckEquals(std::string(": entry_1\n: entry_2\n"), contents, "The logger's thread should flush what it wrote"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Async_PeriodicFlushesOnTheSameThread() +ASW_TEST(TTest_ASWLog_FileLog, Async_PeriodicFlushesOnTheSameThread) { // Arrange const auto logFile = TestTempDir / "async_periodic.log"; @@ -601,7 +506,7 @@ void TTest_ASWLog_FileLog::Test_Async_PeriodicFlushesOnTheSameThread() CheckEquals(std::string(": entry\n"), contents, "The logger's thread should also flush every FlushInterval"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Async_ReconfigureWritesQueuedEntriesToTheOldFile() +ASW_TEST(TTest_ASWLog_FileLog, Async_ReconfigureWritesQueuedEntriesToTheOldFile) { // Arrange const auto oldFile = TestTempDir / "async_old.log"; @@ -632,7 +537,7 @@ void TTest_ASWLog_FileLog::Test_Async_ReconfigureWritesQueuedEntriesToTheOldFile CheckEquals(std::string(": new_entry\n"), newContents, "Only the entry logged after Reconfigure should go to the new file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_AutoOpenClose_StaysInitializedBetweenWrites() +ASW_TEST(TTest_ASWLog_FileLog, AutoOpenClose_StaysInitializedBetweenWrites) { // Arrange: with File.AutoOpenClosePerWrite the file is closed after every entry, which must not uninitialize the // logger @@ -668,7 +573,7 @@ void TTest_ASWLog_FileLog::Test_AutoOpenClose_StaysInitializedBetweenWrites() "The destructor should write the shutdown line after the last entry: " + contents); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_BackupLimits_ApplyOnlyToThisLogsBackups() +ASW_TEST(TTest_ASWLog_FileLog, BackupLimits_ApplyOnlyToThisLogsBackups) { // Arrange: every file is old enough for File.RetentionMaxAge, and File.MaxBackupFiles keeps only the new backup using namespace std::chrono_literals; @@ -712,7 +617,7 @@ void TTest_ASWLog_FileLog::Test_BackupLimits_ApplyOnlyToThisLogsBackups() CheckEquals(1, CountFilesStartingWith("app.manual."), "The new backup should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupFilesKeepsNewestByLastWrite() +ASW_TEST(TTest_ASWLog_FileLog, BackupLimits_MaxBackupFilesKeepsNewestByLastWrite) { // Arrange: last write times in a different order than the names. The daily backup holds the end of its day, so it // is newer than that day's size backups although its name sorts before theirs. @@ -746,7 +651,7 @@ void TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupFilesKeepsNewestByLastWrit CheckFalse(std::filesystem::exists(sizeLatestName), "The oldest backup should be deleted, whatever its name says"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupTotalBytesDeletesOldestFirst() +ASW_TEST(TTest_ASWLog_FileLog, BackupLimits_MaxBackupTotalBytesDeletesOldestFirst) { // Arrange using namespace std::chrono_literals; @@ -780,7 +685,7 @@ void TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupTotalBytesDeletesOldestFir CheckFalse(std::filesystem::exists(smallOldest), "An older backup should be deleted too, even though it would fit"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupTotalBytesIsStrict() +ASW_TEST(TTest_ASWLog_FileLog, BackupLimits_MaxBackupTotalBytesIsStrict) { // Arrange: a limit smaller than the backup that rotation makes using namespace std::chrono_literals; @@ -806,7 +711,7 @@ void TTest_ASWLog_FileLog::Test_BackupLimits_MaxBackupTotalBytesIsStrict() CheckEquals(std::string(": after\n"), ReadFileText(TestTempDir / "strict.log"), "Logging should go on in the new log file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_BackupLimits_ZeroKeepsEveryBackup() +ASW_TEST(TTest_ASWLog_FileLog, BackupLimits_ZeroKeepsEveryBackup) { // Arrange: File.RetentionMaxAge is set, so the cleanup runs, but none of the backups has expired using namespace std::chrono_literals; @@ -830,7 +735,7 @@ void TTest_ASWLog_FileLog::Test_BackupLimits_ZeroKeepsEveryBackup() CheckEquals(1, CountFilesStartingWith("zero.manual."), "The new backup should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_ChildProcess_DoesNotInheritLogFile() +ASW_TEST(TTest_ASWLog_FileLog, ChildProcess_DoesNotInheritLogFile) { // Arrange const auto logFile = TestTempDir / "not_inherited.log"; @@ -889,7 +794,7 @@ void TTest_ASWLog_FileLog::Test_ChildProcess_DoesNotInheritLogFile() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_KeepsExistingBackupForSameDate() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_KeepsExistingBackupForSameDate) { // Arrange using namespace std::chrono_literals; @@ -922,7 +827,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_KeepsExistingBackupForSameDate() CheckContains(newBackupContents, "day_one_entry", "Daily rolling should add _1 to the name when the day's backup already exists"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_KeepsLeftoverLogFromSameDay() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_KeepsLeftoverLogFromSameDay) { // Arrange: a log last written 2 hours before the logger starts at 10:00 UTC, i.e. earlier the same UTC day using namespace std::chrono_literals; @@ -953,7 +858,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_KeepsLeftoverLogFromSameDay() CheckContains(contents, "new_entry", "New entries should be appended to the log"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_LocalZoneRollsAtLocalMidnight() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_LocalZoneRollsAtLocalMidnight) { // Arrange: US Eastern time, 5 hours behind UTC in January using namespace std::chrono_literals; @@ -989,7 +894,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_LocalZoneRollsAtLocalMidnight() CheckNotContains(currentContents, "evening_entry", "The new local day's file should not contain the previous day's entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_NamesBackupForContentDate() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_NamesBackupForContentDate) { // Arrange using namespace std::chrono_literals; @@ -1019,7 +924,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_NamesBackupForContentDate() CheckNotContains(currentContents, "day_one_entry", "The reopened log file should not contain the previous day's entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_ReconfiguredZoneRollsAtItsMidnight() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_ReconfiguredZoneRollsAtItsMidnight) { // Arrange: 01:00 UTC on the 16th is 20:00 on the 15th in US Eastern time using namespace std::chrono_literals; @@ -1053,7 +958,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_ReconfiguredZoneRollsAtItsMidnight( CheckNotContains(currentContents, "after_switch", "The new local day's file should not contain the previous day's entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_RotatesLeftoverLogFromEarlierDay() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_RotatesLeftoverLogFromEarlierDay) { // Arrange: a log last written 30 hours before the logger starts at 10:00 UTC on 2026-01-15, i.e. on 2026-01-14 using namespace std::chrono_literals; @@ -1086,7 +991,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_RotatesLeftoverLogFromEarlierDay() CheckNotContains(currentContents, "yesterday_entry", "The new log file should not contain the earlier day's entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_RotatesLeftoverLogFromEarlierLocalDay() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_RotatesLeftoverLogFromEarlierLocalDay) { // Arrange: the logger starts at 00:10 on the 16th in US Eastern time (05:10 UTC); the log was last written 20 minutes // earlier, on the 15th in local time but on the same UTC day @@ -1119,7 +1024,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_RotatesLeftoverLogFromEarlierLocalD CheckNotContains(ReadFileText(logFile), "local_yesterday_entry", "The new log file should not contain the earlier local day's entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DailyRolling_SharedLogRollsOverOnce() +ASW_TEST(TTest_ASWLog_FileLog, DailyRolling_SharedLogRollsOverOnce) { // Arrange: two loggers sharing one log, as two processes would (File.AutoOpenClosePerWrite), both logging at 23:59 UTC using namespace std::chrono_literals; @@ -1161,7 +1066,7 @@ void TTest_ASWLog_FileLog::Test_DailyRolling_SharedLogRollsOverOnce() CheckContains(currentContents, "second_day_two_entry", "Both loggers' entries from the second day should be in the current log"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DeleteOldLogs_AcceptsShortRelativeFolder() +ASW_TEST(TTest_ASWLog_FileLog, DeleteOldLogs_AcceptsShortRelativeFolder) { // Arrange: an old file in "lg", a relative folder name as short as a root folder such as "C:\" const auto shortFolder = TestTempDir / "lg"; @@ -1185,7 +1090,7 @@ void TTest_ASWLog_FileLog::Test_DeleteOldLogs_AcceptsShortRelativeFolder() CheckFalse(std::filesystem::exists(oldFile), "The old file in the relative folder should be removed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DeleteOldLogs_EmptyPatternDeletesNothing() +ASW_TEST(TTest_ASWLog_FileLog, DeleteOldLogs_EmptyPatternDeletesNothing) { // Arrange const auto oldFile = TestTempDir / "old_example.log"; @@ -1207,7 +1112,7 @@ void TTest_ASWLog_FileLog::Test_DeleteOldLogs_EmptyPatternDeletesNothing() CheckFalse(std::filesystem::exists(oldFile), "The \"*\" pattern should remove the old file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DeleteOldLogs_KeepsNonMatchingFilesAndSubfolders() +ASW_TEST(TTest_ASWLog_FileLog, DeleteOldLogs_KeepsNonMatchingFilesAndSubfolders) { // Arrange: an empty subfolder whose name matches the pattern, besides a matching and a non-matching file const auto matchingFile = TestTempDir / "old_example.log"; @@ -1228,7 +1133,7 @@ void TTest_ASWLog_FileLog::Test_DeleteOldLogs_KeepsNonMatchingFilesAndSubfolders CheckTrue(std::filesystem::is_directory(subfolder), "A subfolder should be kept, even if its name matches the pattern"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DeleteOldLogs_MatchesNonASCIIFileNames() +ASW_TEST(TTest_ASWLog_FileLog, DeleteOldLogs_MatchesNonASCIIFileNames) { // Arrange: a file name with a character outside the Windows ANSI code page (Greek small lambda, U+03BB, which is // CE BB in UTF-8). Written with escapes, and without a u8"" literal: MSVC builds turned both the raw character and @@ -1259,7 +1164,7 @@ void TTest_ASWLog_FileLog::Test_DeleteOldLogs_MatchesNonASCIIFileNames() CheckFalse(std::filesystem::exists(oldFile), "The matching old file should be removed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_DeleteOldLogs_RemovesOldFiles() +ASW_TEST(TTest_ASWLog_FileLog, DeleteOldLogs_RemovesOldFiles) { // Arrange const auto oldFile = TestTempDir / "old_example.log"; @@ -1287,7 +1192,7 @@ void TTest_ASWLog_FileLog::Test_DeleteOldLogs_RemovesOldFiles() CheckTrue(std::filesystem::exists(newFile), "Recent log file should remain"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FailedOpen_TriesOpenRetryCountTimes() +ASW_TEST(TTest_ASWLog_FileLog, FailedOpen_TriesOpenRetryCountTimes) { // Arrange: a "folder" that is a file can't hold the log, on any OS and for any user using namespace std::chrono_literals; @@ -1315,7 +1220,7 @@ void TTest_ASWLog_FileLog::Test_FailedOpen_TriesOpenRetryCountTimes() CheckEquals(1, reports.size(), "The failed open should be reported once, after the last try"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FailedReopen_RetriesAndResumesLogging() +ASW_TEST(TTest_ASWLog_FileLog, FailedReopen_RetriesAndResumesLogging) { // Arrange if (!CanBlockFiles()) @@ -1365,7 +1270,7 @@ void TTest_ASWLog_FileLog::Test_FailedReopen_RetriesAndResumesLogging() CheckTrue(openAfterRecovery, "The log should report open again after recovering"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FailedReopen_ZeroResetDelayRetriesOnNextWrite() +ASW_TEST(TTest_ASWLog_FileLog, FailedReopen_ZeroResetDelayRetriesOnNextWrite) { // Arrange if (!CanBlockFiles()) @@ -1396,7 +1301,7 @@ void TTest_ASWLog_FileLog::Test_FailedReopen_ZeroResetDelayRetriesOnNextWrite() CheckContains(ReadFileText(logFile), "next_write", "With File.CircuitBreakerResetDelay 0, the next write should reopen the file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FailedSizeRotation_WaitsBeforeRetrying() +ASW_TEST(TTest_ASWLog_FileLog, FailedSizeRotation_WaitsBeforeRetrying) { // Arrange if (!CanBlockFiles()) @@ -1452,7 +1357,7 @@ void TTest_ASWLog_FileLog::Test_FailedSizeRotation_WaitsBeforeRetrying() CheckNotContains(currentContents, "line_three", "The new log file should only hold entries after the successful rotation"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FileStream_FlushWorksAfterFailedWrite() +ASW_TEST(TTest_ASWLog_FileLog, FileStream_FlushWorksAfterFailedWrite) { // Arrange: a stream left in a failed state, as by a failed write (e.g. a full disk that has room again). The // standard flush() does nothing in that state, so the data would stay in the buffer until the file is closed. @@ -1474,7 +1379,7 @@ void TTest_ASWLog_FileLog::Test_FileStream_FlushWorksAfterFailedWrite() CheckEquals(std::string("buffered"), contents, "Flush should write the buffered data to the file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FileStream_InsertionIntoAClosedStreamFails() +ASW_TEST(TTest_ASWLog_FileLog, FileStream_InsertionIntoAClosedStreamFails) { // Arrange ASWLog::TASWFileStream textStream; @@ -1490,7 +1395,7 @@ void TTest_ASWLog_FileLog::Test_FileStream_InsertionIntoAClosedStreamFails() CheckEquals(0, textStream.GetSize() + characterStream.GetSize(), "Nothing should be counted"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FileStream_InsertionWritesAndCountsTheSize() +ASW_TEST(TTest_ASWLog_FileLog, FileStream_InsertionWritesAndCountsTheSize) { // Arrange: a file that already holds 4 bytes const auto file = TestTempDir / "insertion.log"; @@ -1513,7 +1418,7 @@ void TTest_ASWLog_FileLog::Test_FileStream_InsertionWritesAndCountsTheSize() CheckEquals(13, size, "GetSize() should count the file's bytes and every inserted one"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FlushImmediatelyAtLevel_FlushesEntriesAtOrAboveTheLevel() +ASW_TEST(TTest_ASWLog_FileLog, FlushImmediatelyAtLevel_FlushesEntriesAtOrAboveTheLevel) { // Arrange: FlushMode::Manual keeps the entries below the level in the file's buffer const auto logFile = TestTempDir / "flush_at_level.log"; @@ -1545,7 +1450,7 @@ void TTest_ASWLog_FileLog::Test_FlushImmediatelyAtLevel_FlushesEntriesAtOrAboveT CheckEquals(contentsAfterRaw, contentsAfterForcedTrace, "A forced entry below the level should stay buffered"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_FlushImmediatelyAtLevel_OffLeavesFlushingToFlushMode() +ASW_TEST(TTest_ASWLog_FileLog, FlushImmediatelyAtLevel_OffLeavesFlushingToFlushMode) { // Arrange const auto logFile = TestTempDir / "flush_at_level_off.log"; @@ -1569,7 +1474,7 @@ void TTest_ASWLog_FileLog::Test_FlushImmediatelyAtLevel_OffLeavesFlushingToFlush CheckEquals(std::string(": critical_entry\n: forced_critical_entry\n"), contentsAfterFlush, "Flush() should write the buffered entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Flush_WritesBufferedManualModeEntries() +ASW_TEST(TTest_ASWLog_FileLog, Flush_WritesBufferedManualModeEntries) { // Arrange: FlushMode::Manual keeps each entry in the file's buffer until Flush() const auto logFile = TestTempDir / "flush_manual.log"; @@ -1596,7 +1501,7 @@ void TTest_ASWLog_FileLog::Test_Flush_WritesBufferedManualModeEntries() CheckFalse(flushedWhileClosed, "Flush() should return false while the file is closed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_GetInstance_ReturnsSameInstance() +ASW_TEST(TTest_ASWLog_FileLog, GetInstance_ReturnsSameInstance) { // Act auto& first = ASWLog::TASWFileLog::GetInstance(); @@ -1606,7 +1511,7 @@ void TTest_ASWLog_FileLog::Test_GetInstance_ReturnsSameInstance() CheckSame(&first, &second, "GetInstance should return the same logger on every call"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_InitializeAndLogInfo_WritesText() +ASW_TEST(TTest_ASWLog_FileLog, InitializeAndLogInfo_WritesText) { // Arrange const auto logFile = TestTempDir / "aswlog_runtime.log"; @@ -1646,7 +1551,7 @@ void TTest_ASWLog_FileLog::Test_InitializeAndLogInfo_WritesText() CheckContains(contents, "unit_test_message", "Logged file should contain the test message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Initialize_SuppressesInfoBannersBelowMinimumLevel() +ASW_TEST(TTest_ASWLog_FileLog, Initialize_SuppressesInfoBannersBelowMinimumLevel) { // Arrange const auto logFile = TestTempDir / "suppressed_banners.log"; @@ -1681,7 +1586,7 @@ void TTest_ASWLog_FileLog::Test_Initialize_SuppressesInfoBannersBelowMinimumLeve CheckContains(contents, "this_error_should_appear", "Messages at or above InitialMinimumLevel should still be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_LogFormatMethods_FormatsMessage() +ASW_TEST(TTest_ASWLog_FileLog, LogFormatMethods_FormatsMessage) { // Arrange const auto logFile = TestTempDir / "format_message.log"; @@ -1716,7 +1621,7 @@ void TTest_ASWLog_FileLog::Test_LogFormatMethods_FormatsMessage() CheckContains(contents, "forced value", "LogForceFmt should bypass filter and format the message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_LogFormatMethods_WriteCallerSourceLine() +ASW_TEST(TTest_ASWLog_FileLog, LogFormatMethods_WriteCallerSourceLine) { // Arrange const auto logFile = TestTempDir / "fmt_location.log"; @@ -1743,7 +1648,7 @@ void TTest_ASWLog_FileLog::Test_LogFormatMethods_WriteCallerSourceLine() CheckNotContains(contents, "ASWLog_Interface.h", "Line.ShowSourceLine should not show the header that implements the *Fmt methods"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_LogLineMetadata_Options() +ASW_TEST(TTest_ASWLog_FileLog, LogLineMetadata_Options) { // Arrange const auto logFile = TestTempDir / "metadata_line.log"; @@ -1783,7 +1688,7 @@ void TTest_ASWLog_FileLog::Test_LogLineMetadata_Options() CheckContains(contents, "metadata_message", "Metadata log line should still contain the message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_LogNewLineAndForceOptions() +ASW_TEST(TTest_ASWLog_FileLog, LogNewLineAndForceOptions) { // Arrange const auto logFile = TestTempDir / "newline_force.log"; @@ -1819,7 +1724,7 @@ void TTest_ASWLog_FileLog::Test_LogNewLineAndForceOptions() CheckNotContains(contents, "ignored_message", "Log should not write a message below the configured minimum level"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_LogProcessAndThreadIds_AreOSIds() +ASW_TEST(TTest_ASWLog_FileLog, LogProcessAndThreadIds_AreOSIds) { // Arrange const auto logFile = TestTempDir / "os_ids.log"; @@ -1852,7 +1757,7 @@ void TTest_ASWLog_FileLog::Test_LogProcessAndThreadIds_AreOSIds() CheckContains(contents, processTag + "[T:" + std::to_string(workerThreadId) + "]: worker_thread_entry", "An entry from another thread should show that thread's OS thread id"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_LogRawOptions() +ASW_TEST(TTest_ASWLog_FileLog, LogRawOptions) { // Arrange const auto logFile = TestTempDir / "raw.log"; @@ -1887,7 +1792,7 @@ void TTest_ASWLog_FileLog::Test_LogRawOptions() CheckNotContains(contents, "raw_force_message\n", "LogForceRaw should not append a trailing newline"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_MultiThreadedStress_WritesAllMessagesToDisk() +ASW_TEST(TTest_ASWLog_FileLog, MultiThreadedStress_WritesAllMessagesToDisk) { // Arrange const auto logFile = TestTempDir / "stress.log"; @@ -1952,7 +1857,7 @@ void TTest_ASWLog_FileLog::Test_MultiThreadedStress_WritesAllMessagesToDisk() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_MultiThreadedStress_WritesAllMessagesToDisk_OpenClose() +ASW_TEST(TTest_ASWLog_FileLog, MultiThreadedStress_WritesAllMessagesToDisk_OpenClose) { // Arrange const auto logFile = TestTempDir / "stress.log"; @@ -2019,7 +1924,7 @@ void TTest_ASWLog_FileLog::Test_MultiThreadedStress_WritesAllMessagesToDisk_Open } } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_AsyncWorkerWritesTheStartupLinesBeforeTheEntry() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_AsyncWorkerWritesTheStartupLinesBeforeTheEntry) { // Arrange: the first entry reaches the 50-byte limit, so the logger's thread rotates the log for the second one using namespace std::chrono_literals; @@ -2044,7 +1949,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_AsyncWorkerWritesTheStartupLinesBeforeTh ReadFileText(logFile), "The logger's thread should write the startup lines at the top of the new file, before the entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_DailyRollingStartsWithTheStartupLines() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_DailyRollingStartsWithTheStartupLines) { // Arrange using namespace std::chrono_literals; @@ -2072,7 +1977,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_DailyRollingStartsWithTheStartupLines() CheckEquals(1, CountFilesStartingWith("new_daily.daily."), "Writing the startup lines should not roll the log over again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_FailedRotationWritesNoStartupLines() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_FailedRotationWritesNoStartupLines) { // Arrange if (!CanBlockFiles()) @@ -2103,7 +2008,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_FailedRotationWritesNoStartupLines() ReadFileText(logFile), "A failed rotation starts no new file, so it should write no startup lines"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_InitializeWritesItsStartupLinesOnce() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_InitializeWritesItsStartupLinesOnce) { // Arrange: a log last written 30 hours before the logger starts, which Initialize() rolls over using namespace std::chrono_literals; @@ -2129,7 +2034,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_InitializeWritesItsStartupLinesOnce() "The file Initialize() starts should get its startup lines once, without a continuation line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_ManualRotationOpensASharedLogForTheStartupLines() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_ManualRotationOpensASharedLogForTheStartupLines) { // Arrange using namespace std::chrono_literals; @@ -2159,7 +2064,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_ManualRotationOpensASharedLogForTheStart CheckEquals(std::string(startupLines) + ": after_rotation\n", ReadFileText(logFile), "The next entry should follow the startup lines"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_MinimumLevelAboveInfoLeavesOutTheStartupLines() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_MinimumLevelAboveInfoLeavesOutTheStartupLines) { // Arrange const auto logFile = TestTempDir / "new_level.log"; @@ -2182,7 +2087,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_MinimumLevelAboveInfoLeavesOutTheStartup "The startup lines are Info lines, so a minimum level above Info should leave them out of a new file too"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_ReconfigureToANewPathStartsWithTheStartupLines() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_ReconfigureToANewPathStartsWithTheStartupLines) { // Arrange const auto firstFile = TestTempDir / "new_reconfigure_first.log"; @@ -2212,7 +2117,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_ReconfigureToANewPathStartsWithTheStartu ReadFileText(secondFile), "The new file should start with the startup lines, naming the previous file's path, and only once"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_RotationWaitsUntilTheStartupLinesAreWritten() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_RotationWaitsUntilTheStartupLinesAreWritten) { // Arrange: the banner alone reaches the 50-byte limit, so each block of startup lines is longer than the limit using namespace std::chrono_literals; @@ -2241,7 +2146,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_RotationWaitsUntilTheStartupLinesAreWrit ReadFileText(logFile), "The new file's startup lines should stay together, followed by the entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_SharedLogGetsTheStartupLinesOnce() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_SharedLogGetsTheStartupLinesOnce) { // Arrange: two loggers sharing one log, as two processes would (File.AutoOpenClosePerWrite), both logging at 23:59 UTC using namespace std::chrono_literals; @@ -2278,7 +2183,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_SharedLogGetsTheStartupLinesOnce() ReadFileText(logFile), "Only the logger that rolled the shared log over should write the startup lines"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_SizeRotationStartsWithTheStartupLines() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_SizeRotationStartsWithTheStartupLines) { // Arrange: Initialize()'s lines and the first entry reach the 100-byte limit, so the second entry rotates the log using namespace std::chrono_literals; @@ -2306,7 +2211,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_SizeRotationStartsWithTheStartupLines() ReadFileText(logFile), "The new file should start with the continuation line and the startup lines, before the entry that rotated the log"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_NewFile_UnopenedFileGetsTheStartupLinesWhenItOpens() +ASW_TEST(TTest_ASWLog_FileLog, NewFile_UnopenedFileGetsTheStartupLinesWhenItOpens) { // Arrange: a "folder" that is a file can't hold the new log, on any OS and for any user using namespace std::chrono_literals; @@ -2339,7 +2244,7 @@ void TTest_ASWLog_FileLog::Test_NewFile_UnopenedFileGetsTheStartupLinesWhenItOpe ReadFileText(laterFolder / "later.log"), "The open that succeeds should write the startup lines, before its entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnBackupCreated_IsNotCalledWhenRotationFails() +ASW_TEST(TTest_ASWLog_FileLog, OnBackupCreated_IsNotCalledWhenRotationFails) { // Arrange if (!CanBlockFiles()) @@ -2371,7 +2276,7 @@ void TTest_ASWLog_FileLog::Test_OnBackupCreated_IsNotCalledWhenRotationFails() CheckEquals(0, callCount, "No backup was made, so OnBackupCreated should not be called"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnBackupCreated_LeavesARenamedBackupToTheApp() +ASW_TEST(TTest_ASWLog_FileLog, OnBackupCreated_LeavesARenamedBackupToTheApp) { // Arrange: the callback "compresses" the backup to a name outside the backup form, and the size limit is too small // for any backup @@ -2400,7 +2305,7 @@ void TTest_ASWLog_FileLog::Test_OnBackupCreated_LeavesARenamedBackupToTheApp() CheckTrue(std::filesystem::exists(compressedPath), "The cleanup should leave a file renamed out of the backup form to the application"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnBackupCreated_ReportsDailyBackupAtInitialize() +ASW_TEST(TTest_ASWLog_FileLog, OnBackupCreated_ReportsDailyBackupAtInitialize) { // Arrange: a log last written on 2026-01-14 (30 hours before the logger starts at 10:00 UTC on 2026-01-15) using namespace std::chrono_literals; @@ -2432,7 +2337,7 @@ void TTest_ASWLog_FileLog::Test_OnBackupCreated_ReportsDailyBackupAtInitialize() CheckTrue(backups[0].LogPath == config.File.ResolvePath(), "LogPath should be the log file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnBackupCreated_ReportsEachBackup() +ASW_TEST(TTest_ASWLog_FileLog, OnBackupCreated_ReportsEachBackup) { // Arrange const auto logFile = TestTempDir / "event.log"; @@ -2471,7 +2376,7 @@ void TTest_ASWLog_FileLog::Test_OnBackupCreated_ReportsEachBackup() CheckContains(ReadFileText(backups[0].BackupPath), "line_one", "The size backup should hold the entries before the rotation"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnBackupCreated_RunsOutsideTheLockBeforeCleanup() +ASW_TEST(TTest_ASWLog_FileLog, OnBackupCreated_RunsOutsideTheLockBeforeCleanup) { // Arrange: a size limit too small for any backup, so the cleanup deletes the new one right after the callback const auto logFile = TestTempDir / "before_cleanup.log"; @@ -2504,7 +2409,7 @@ void TTest_ASWLog_FileLog::Test_OnBackupCreated_RunsOutsideTheLockBeforeCleanup( CheckContains(ReadFileText(logFile), "logged_from_the_callback", "The callback should be able to log"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnBackupCreated_ThrowingCallbackStillCleansUp() +ASW_TEST(TTest_ASWLog_FileLog, OnBackupCreated_ThrowingCallbackStillCleansUp) { // Arrange const auto logFile = TestTempDir / "throwing_event.log"; @@ -2535,7 +2440,7 @@ void TTest_ASWLog_FileLog::Test_OnBackupCreated_ThrowingCallbackStillCleansUp() CheckEquals(std::string(": after\n"), ReadFileText(logFile), "Logging should go on"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedDelete() +ASW_TEST(TTest_ASWLog_FileLog, OnError_ReportsFailedDelete) { #if defined(_WIN32) // Arrange: an expired backup that another program holds open without delete sharing, so retention can't delete it @@ -2579,7 +2484,7 @@ void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedDelete() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedOpen() +ASW_TEST(TTest_ASWLog_FileLog, OnError_ReportsFailedOpen) { // Arrange: a "folder" that is a file can't hold the log, on any OS and for any user const auto notAFolder = TestTempDir / "not_a_folder"; @@ -2606,7 +2511,7 @@ void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedOpen() CheckTrue(static_cast(reports[0].Code), "The report should carry the operating system's error"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedRotationAndReopen() +ASW_TEST(TTest_ASWLog_FileLog, OnError_ReportsFailedRotationAndReopen) { // Arrange if (!CanBlockFiles()) @@ -2655,7 +2560,7 @@ void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedRotationAndReopen() CheckEquals(2, reports[2].SuppressedCount, "The report should count the failed opens left out"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedSync() +ASW_TEST(TTest_ASWLog_FileLog, OnError_ReportsFailedSync) { // Arrange: the null device takes every write, but can't be synced to disk (FlushFileBuffers fails with // ERROR_INVALID_FUNCTION on Windows, fsync with EINVAL on Linux) @@ -2694,7 +2599,7 @@ void TTest_ASWLog_FileLog::Test_OnError_ReportsFailedSync() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnError_ReportsFullDisk() +ASW_TEST(TTest_ASWLog_FileLog, OnError_ReportsFullDisk) { #if defined(__linux__) // Arrange: every write to /dev/full fails with "No space left on device" @@ -2734,7 +2639,7 @@ void TTest_ASWLog_FileLog::Test_OnError_ReportsFullDisk() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnLogEntry_FiresForQualifyingLevelsOnly() +ASW_TEST(TTest_ASWLog_FileLog, OnLogEntry_FiresForQualifyingLevelsOnly) { // Arrange const auto logFile = TestTempDir / "callback.log"; @@ -2792,7 +2697,7 @@ void TTest_ASWLog_FileLog::Test_OnLogEntry_FiresForQualifyingLevelsOnly() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_OnLogEntry_ReentrantCallbackDoesNotDeadlock() +ASW_TEST(TTest_ASWLog_FileLog, OnLogEntry_ReentrantCallbackDoesNotDeadlock) { // Arrange const auto logFile = TestTempDir / "reentrant.log"; @@ -2836,7 +2741,7 @@ void TTest_ASWLog_FileLog::Test_OnLogEntry_ReentrantCallbackDoesNotDeadlock() CheckContains(contents, "reentrant_message", "Re-entrant Log call from the callback should complete and be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Open_KeepsAnOpenFile() +ASW_TEST(TTest_ASWLog_FileLog, Open_KeepsAnOpenFile) { // Arrange const auto logFile = TestTempDir / "open_again.log"; @@ -2859,7 +2764,7 @@ void TTest_ASWLog_FileLog::Test_Open_KeepsAnOpenFile() CheckEquals(std::string(": before_open\n: after_open\n"), ReadFileText(logFile), "The logger should go on writing to its file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_CloseStopsAndOpenRestartsTheThread() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_CloseStopsAndOpenRestartsTheThread) { // Arrange const auto logFile = TestTempDir / "periodic_reopen.log"; @@ -2887,7 +2792,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_CloseStopsAndOpenRestartsTheThread() CheckEquals(std::string(": entry_after_reopen\n"), contents, "Open should start the flush thread again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_CloseStopsTheThreadWithoutWaitingForTheInterval() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_CloseStopsTheThreadWithoutWaitingForTheInterval) { // Arrange: an interval the test would never live to see const auto logFile = TestTempDir / "periodic_close.log"; @@ -2915,7 +2820,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_CloseStopsTheThreadWithoutWaitingForThe CheckEquals(std::string(": buffered_entry\n"), contentsAfterClose, "Close should flush the buffered entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_ConcurrentLoggingAndReconfigure() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_ConcurrentLoggingAndReconfigure) { // Arrange: a short interval, so the flush thread runs often while the other threads log and reconfigure const auto logFile = TestTempDir / "periodic_concurrent.log"; @@ -2971,7 +2876,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_ConcurrentLoggingAndReconfigure() CheckEquals(entryCount, std::count(contents.begin(), contents.end(), '\n'), "Every entry should be written once"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_DestructorStopsTheThreadWithoutWaitingForTheInterval() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_DestructorStopsTheThreadWithoutWaitingForTheInterval) { // Arrange const auto logFile = TestTempDir / "periodic_destructor.log"; @@ -2998,7 +2903,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_DestructorStopsTheThreadWithoutWaitingF CheckEquals(std::string(": buffered_entry\n"), contents, "The destructor should flush the buffered entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_ErrorHandlerCanCloseAndReopenOnTheThread() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_ErrorHandlerCanCloseAndReopenOnTheThread) { // Arrange: the flush thread's first flush fails, and its OnError call, on that thread, closes and reopens the // logger, which stops and then keeps that same thread @@ -3045,7 +2950,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_ErrorHandlerCanCloseAndReopenOnTheThrea CheckContains(contents, "entry_after_reopen", "After the reopen, the flush thread should flush again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_FlushesAfterTheLastEntry() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_FlushesAfterTheLastEntry) { // Arrange const auto logFile = TestTempDir / "periodic_last_entry.log"; @@ -3065,7 +2970,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_FlushesAfterTheLastEntry() CheckEquals(std::string(": last_entry\n"), contents, "The flush thread should flush the last entry within the interval"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_ReconfigureAppliesANewInterval() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_ReconfigureAppliesANewInterval) { // Arrange: the thread starts out waiting for an interval the test would never live to see const auto logFile = TestTempDir / "periodic_new_interval.log"; @@ -3089,7 +2994,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_ReconfigureAppliesANewInterval() CheckEquals(std::string(": entry\n"), contents, "The flush thread should use the new interval at once"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_ReconfigureStartsAndStopsTheThread() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_ReconfigureStartsAndStopsTheThread) { // Arrange const auto logFile = TestTempDir / "periodic_reconfigure.log"; @@ -3121,7 +3026,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_ReconfigureStartsAndStopsTheThread() CheckEquals(std::string(": periodic_entry\n"), contentsInManual, "Reconfigure to Manual should stop the flush thread"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Periodic_ZeroIntervalFlushesEveryEntry() +ASW_TEST(TTest_ASWLog_FileLog, Periodic_ZeroIntervalFlushesEveryEntry) { // Arrange const auto logFile = TestTempDir / "periodic_zero_interval.log"; @@ -3141,7 +3046,7 @@ void TTest_ASWLog_FileLog::Test_Periodic_ZeroIntervalFlushesEveryEntry() CheckEquals(std::string(": entry\n"), contents, "With no interval, each entry should be flushed as it is written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Reconfigure_FlushesEntriesBufferedByPreviousMode() +ASW_TEST(TTest_ASWLog_FileLog, Reconfigure_FlushesEntriesBufferedByPreviousMode) { // Arrange: FlushMode::Manual keeps each entry in the file's buffer until it is flushed const auto logFile = TestTempDir / "reconfigure_flush.log"; @@ -3170,7 +3075,7 @@ void TTest_ASWLog_FileLog::Test_Reconfigure_FlushesEntriesBufferedByPreviousMode "The new flush mode should apply to the next entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Reconfigure_MovesOutputToNewFile() +ASW_TEST(TTest_ASWLog_FileLog, Reconfigure_MovesOutputToNewFile) { // Arrange const auto firstFile = TestTempDir / "reconfigure_first.log"; @@ -3206,7 +3111,7 @@ void TTest_ASWLog_FileLog::Test_Reconfigure_MovesOutputToNewFile() "Entries after Reconfigure() should go to the new file, in either open mode"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Reconfigure_UnopenableFileFailsButLoggerStaysInitialized() +ASW_TEST(TTest_ASWLog_FileLog, Reconfigure_UnopenableFileFailsButLoggerStaysInitialized) { // Arrange: a "folder" that is a file can't hold the new log, on any OS and for any user using namespace std::chrono_literals; @@ -3239,7 +3144,7 @@ void TTest_ASWLog_FileLog::Test_Reconfigure_UnopenableFileFailsButLoggerStaysIni "Logging should resume in the file of the last Reconfigure()"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_RetentionMaxAge_DefaultDisabledPreservesOldBackups() +ASW_TEST(TTest_ASWLog_FileLog, RetentionMaxAge_DefaultDisabledPreservesOldBackups) { // Arrange const auto logFile = TestTempDir / "retention_disabled.log"; @@ -3280,7 +3185,7 @@ void TTest_ASWLog_FileLog::Test_RetentionMaxAge_DefaultDisabledPreservesOldBacku CheckTrue(std::filesystem::exists(staleBackup), "File.RetentionMaxAge left at its default (disabled) should not delete old backups after rotation"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_RetentionMaxAge_DeletesExpiredBackupsAfterRotation() +ASW_TEST(TTest_ASWLog_FileLog, RetentionMaxAge_DeletesExpiredBackupsAfterRotation) { // Arrange const auto logFile = TestTempDir / "retention.log"; @@ -3322,7 +3227,7 @@ void TTest_ASWLog_FileLog::Test_RetentionMaxAge_DeletesExpiredBackupsAfterRotati CheckTrue(std::filesystem::exists(logFile), "Log file should be recreated after rotation"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_RotateLogFiles_FailsWhenEveryBackupNameIsTaken() +ASW_TEST(TTest_ASWLog_FileLog, RotateLogFiles_FailsWhenEveryBackupNameIsTaken) { // Arrange: every name the rotation could use (the plain one, then "_1" to "_1000") is taken using namespace std::chrono_literals; @@ -3363,7 +3268,7 @@ void TTest_ASWLog_FileLog::Test_RotateLogFiles_FailsWhenEveryBackupNameIsTaken() CheckEquals(std::string("kept"), ReadFileText(TestTempDir / (backupName + "_1000.bak")), "The last backup name should not be replaced"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_RotateLogFiles_KeepsEveryBackup() +ASW_TEST(TTest_ASWLog_FileLog, RotateLogFiles_KeepsEveryBackup) { // Arrange: a fixed clock makes both rotations want the same backup name using namespace std::chrono_literals; @@ -3394,7 +3299,7 @@ void TTest_ASWLog_FileLog::Test_RotateLogFiles_KeepsEveryBackup() CheckContains(ReadFileText(logFile), "third_segment", "Entries after the last rotation should go to the reopened log file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_RotateLogFiles_NamesBackupInLocalTime() +ASW_TEST(TTest_ASWLog_FileLog, RotateLogFiles_NamesBackupInLocalTime) { // Arrange: 04:59:30.250 UTC on the 16th is 23:59:30.250 on the 15th in US Eastern time using namespace std::chrono_literals; @@ -3418,7 +3323,7 @@ void TTest_ASWLog_FileLog::Test_RotateLogFiles_NamesBackupInLocalTime() CheckContains(ReadFileText(TestTempDir / "rotate_local.manual.2026-01-15_235930_250.bak"), "rotated_entry", "The backup should be named for the local time"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_SetEnabled_FalseStopsAutoOpenCloseLogging() +ASW_TEST(TTest_ASWLog_FileLog, SetEnabled_FalseStopsAutoOpenCloseLogging) { // Arrange: with File.AutoOpenClosePerWrite the file is only open while an entry is written const auto logFile = TestTempDir / "disabled.log"; @@ -3448,7 +3353,7 @@ void TTest_ASWLog_FileLog::Test_SetEnabled_FalseStopsAutoOpenCloseLogging() CheckEquals(std::string(": enabled_again\n"), ReadFileText(logFile), "Logging should resume once enabled again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_ShutdownLine_TimeFollowsTimestampZone() +ASW_TEST(TTest_ASWLog_FileLog, ShutdownLine_TimeFollowsTimestampZone) { // Arrange: 04:59:30.250 UTC on the 16th is 23:59:30.250 on the 15th in US Eastern time using namespace std::chrono_literals; @@ -3472,7 +3377,7 @@ void TTest_ASWLog_FileLog::Test_ShutdownLine_TimeFollowsTimestampZone() CheckContains(ReadFileText(logFile), ": Logger shutdown: 2026-01-15T23:59:30.250000-05:00\n", "The shutdown line's time should use the line's zone and precision"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_SizeRotation_AutoOpenCloseCountsOtherWriters() +ASW_TEST(TTest_ASWLog_FileLog, SizeRotation_AutoOpenCloseCountsOtherWriters) { // Arrange: in File.AutoOpenClosePerWrite mode the log is closed between writes, so other processes can append to it const auto logFile = TestTempDir / "sized_shared.log"; @@ -3517,7 +3422,7 @@ void TTest_ASWLog_FileLog::Test_SizeRotation_AutoOpenCloseCountsOtherWriters() CheckNotContains(currentContents, "x", "The new log file should not contain the other writer's earlier entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_SizeRotation_CountsExistingFileSize() +ASW_TEST(TTest_ASWLog_FileLog, SizeRotation_CountsExistingFileSize) { // Arrange: a log left over from an earlier run is already over the limit const auto logFile = TestTempDir / "sized_existing.log"; @@ -3559,7 +3464,7 @@ void TTest_ASWLog_FileLog::Test_SizeRotation_CountsExistingFileSize() CheckNotContains(currentContents, "x", "The reopened log file should not contain the earlier run's contents"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_SizeRotation_RotatesWhenLimitReached() +ASW_TEST(TTest_ASWLog_FileLog, SizeRotation_RotatesWhenLimitReached) { // Arrange: ten lines of about 18 bytes each against a 50-byte limit need several rotations const auto logFile = TestTempDir / "sized.log"; @@ -3605,7 +3510,7 @@ void TTest_ASWLog_FileLog::Test_SizeRotation_RotatesWhenLimitReached() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_SyncToDiskAtLevel_FlushesAndSyncsEntriesAtOrAboveTheLevel() +ASW_TEST(TTest_ASWLog_FileLog, SyncToDiskAtLevel_FlushesAndSyncsEntriesAtOrAboveTheLevel) { // Arrange: only SyncToDiskAtLevel makes the logger flush (whether the data reached the disk itself can't be seen // from here, but a failed sync would be reported) @@ -3637,7 +3542,7 @@ void TTest_ASWLog_FileLog::Test_SyncToDiskAtLevel_FlushesAndSyncsEntriesAtOrAbov CheckEquals(0, reports.size(), "Syncing a log file should succeed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_FileLog::Test_Write_EarlierRecordDoesNotRollLogBack() +ASW_TEST(TTest_ASWLog_FileLog, Write_EarlierRecordDoesNotRollLogBack) { // Arrange: the logger's clock is just past UTC midnight, so the log already belongs to the new day, and an entry // stamped just before midnight arrives late (e.g. its thread got the lock after another thread's entry) diff --git a/tests/tests/Test_ASWLog_FileLog.h b/tests/tests/Test_ASWLog_FileLog.h index 2bb9021..8ffde7e 100644 --- a/tests/tests/Test_ASWLog_FileLog.h +++ b/tests/tests/Test_ASWLog_FileLog.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_FileLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_FileLog : public TTestGroupBase +class TTest_ASWLog_FileLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Async_DropsAnEntryWhileTheFileCantBeOpened(); void Test_Async_EntryAtWaitAtLevelIsInTheFileWhenTheCallReturns(); void Test_Async_EveryWriteFlushesEachBatch(); diff --git a/tests/tests/Test_ASWLog_Formatter.cpp b/tests/tests/Test_ASWLog_Formatter.cpp index 2d06343..2cf0443 100644 --- a/tests/tests/Test_ASWLog_Formatter.cpp +++ b/tests/tests/Test_ASWLog_Formatter.cpp @@ -177,34 +177,6 @@ std::string ReadFileText(const std::filesystem::path& path) TTest_ASWLog_Formatter::TTest_ASWLog_Formatter() : inherited("ASWLog_Formatter_Tests") { - RegisterTest(&TTest_ASWLog_Formatter::Test_Format_MatchesFormatLine, "Format_MatchesFormatLine"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_AllFieldsInOrder, "FormatLine_AllFieldsInOrder"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_CategoryOnlyWhenSetAndShown, "FormatLine_CategoryOnlyWhenSetAndShown"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_EntryFieldsBeforeTheMessage, "FormatLine_EntryFieldsBeforeTheMessage"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_LargestIdsAndEachLevel, "FormatLine_LargestIdsAndEachLevel"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_MemoryFields, "FormatLine_MemoryFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_NoFields, "FormatLine_NoFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_FormatLine_TimestampFollowsZoneAndPrecision, "FormatLine_TimestampFollowsZoneAndPrecision"); - RegisterTest(&TTest_ASWLog_Formatter::Test_Formatter_RawEntryLeavesOutTheFields, "Formatter_RawEntryLeavesOutTheFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_Formatter_ReceivesRecordFromLoggingThread, "Formatter_ReceivesRecordFromLoggingThread"); - RegisterTest(&TTest_ASWLog_Formatter::Test_Formatter_SharedByTwoLoggers, "Formatter_SharedByTwoLoggers"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_DefaultFields, "JSONFormatter_DefaultFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_EachShowOption, "JSONFormatter_EachShowOption"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_EmptyScopeLeavesOutTheFields, "JSONFormatter_EmptyScopeLeavesOutTheFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_EntryFields, "JSONFormatter_EntryFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_EscapesTheTexts, "JSONFormatter_EscapesTheTexts"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_FileLoggerWritesJSONLines, "JSONFormatter_FileLoggerWritesJSONLines"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_RawEntries, "JSONFormatter_RawEntries"); - RegisterTest(&TTest_ASWLog_Formatter::Test_JSONFormatter_TimeFollowsZoneAndPrecision, "JSONFormatter_TimeFollowsZoneAndPrecision"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_AffixesOnlyAroundAValue, "PatternFormatter_AffixesOnlyAroundAValue"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_BracesAndPlainText, "PatternFormatter_BracesAndPlainText"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_DefaultLayoutMatchesTextFormatter, "PatternFormatter_DefaultLayoutMatchesTextFormatter"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_EachPlaceholder, "PatternFormatter_EachPlaceholder"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_FieldsPlaceholder, "PatternFormatter_FieldsPlaceholder"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_FileLoggerWritesItsLines, "PatternFormatter_FileLoggerWritesItsLines"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_InvalidPatternThrows, "PatternFormatter_InvalidPatternThrows"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_MemoryFields, "PatternFormatter_MemoryFields"); - RegisterTest(&TTest_ASWLog_Formatter::Test_PatternFormatter_WidthPadsShortValues, "PatternFormatter_WidthPadsShortValues"); } //--------------------------------------------------------------------------- TTest_ASWLog_Formatter::~TTest_ASWLog_Formatter() @@ -239,7 +211,7 @@ void TTest_ASWLog_Formatter::TearDown_Test(ITestCase& testCase) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_Format_MatchesFormatLine() +ASW_TEST(TTest_ASWLog_Formatter, Format_MatchesFormatLine) { // Arrange const ASWLog::TASWTextFormatter textFormatter; @@ -255,7 +227,7 @@ void TTest_ASWLog_Formatter::Test_Format_MatchesFormatLine() "A TASWTextFormatter instance should produce the built-in layout"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_AllFieldsInOrder() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_AllFieldsInOrder) { // Arrange ASWLog::TASWLogConfig config; @@ -278,7 +250,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_AllFieldsInOrder() CheckEquals(expected, line, "Each field should be written from the record, in the documented order"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_CategoryOnlyWhenSetAndShown() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_CategoryOnlyWhenSetAndShown) { // Arrange: the level and the category only auto config = MakeConfigWithoutFields("unused.log"); @@ -299,7 +271,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_CategoryOnlyWhenSetAndShown() CheckEquals(std::string("[WARN]: categorized"), hiddenLine, "ShowCategory false should hide the category"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_EntryFieldsBeforeTheMessage() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_EntryFieldsBeforeTheMessage) { // Arrange: the level and the fields only; a value of each kind, and a text that needs escaping auto config = MakeConfigWithoutFields("unused.log"); @@ -332,7 +304,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_EntryFieldsBeforeTheMessage() CheckEquals(std::string("[WARN]: msg"), hiddenLine, "ShowFields false should hide the fields"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_LargestIdsAndEachLevel() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_LargestIdsAndEachLevel) { // Arrange auto config = MakeConfigWithoutFields("unused.log"); @@ -357,7 +329,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_LargestIdsAndEachLevel() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_MemoryFields() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_MemoryFields) { // Arrange auto config = MakeConfigWithoutFields("unused.log"); @@ -372,7 +344,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_MemoryFields() "The working set, then the peak working set, each a decimal number, should come before the message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_NoFields() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_NoFields) { // Arrange const auto config = MakeConfigWithoutFields("unused.log"); @@ -384,7 +356,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_NoFields() CheckEquals(std::string(": just the message"), line, "With every field off, only the separator and message remain"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_FormatLine_TimestampFollowsZoneAndPrecision() +ASW_TEST(TTest_ASWLog_Formatter, FormatLine_TimestampFollowsZoneAndPrecision) { // Arrange: FixedTime is 2026-09-21T14:13:20.123Z, during US Eastern daylight time auto config = MakeConfigWithoutFields("unused.log"); @@ -400,7 +372,7 @@ void TTest_ASWLog_Formatter::Test_FormatLine_TimestampFollowsZoneAndPrecision() CheckEquals(std::string("[2026-09-21T10:13:20.123000-04:00]: local"), line, "The timestamp should be local time with microseconds and the offset"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_Formatter_RawEntryLeavesOutTheFields() +ASW_TEST(TTest_ASWLog_Formatter, Formatter_RawEntryLeavesOutTheFields) { // Arrange: the level only, and a scope auto config = MakeConfigWithoutFields("raw_fields.log"); @@ -424,7 +396,7 @@ void TTest_ASWLog_Formatter::Test_Formatter_RawEntryLeavesOutTheFields() "A formatted entry should have its fields; a raw entry is written as is, without them"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_Formatter_ReceivesRecordFromLoggingThread() +ASW_TEST(TTest_ASWLog_Formatter, Formatter_ReceivesRecordFromLoggingThread) { // Arrange std::vector records; @@ -463,7 +435,7 @@ void TTest_ASWLog_Formatter::Test_Formatter_ReceivesRecordFromLoggingThread() "The file should get the formatter's line plus the line ending"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_Formatter_SharedByTwoLoggers() +ASW_TEST(TTest_ASWLog_Formatter, Formatter_SharedByTwoLoggers) { // Arrange const auto formatter = std::make_shared(); @@ -501,7 +473,7 @@ void TTest_ASWLog_Formatter::Test_Formatter_SharedByTwoLoggers() "Logger B's file should have its 100 lines in the shared format"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_DefaultFields() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_DefaultFields) { // Arrange const ASWLog::TASWJSONFormatter formatter; @@ -521,7 +493,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_DefaultFields() CheckTrue(IsJSONObjectLine(line) && IsJSONObjectLine(categorizedLine), "Each line should be one JSON object"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_EachShowOption() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_EachShowOption) { // Arrange: every field but memory use, memory use only, and no fields at all ASWLog::TASWLogConfig allConfig; @@ -556,7 +528,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_EachShowOption() CheckTrue(IsJSONObjectLine(allLine) && IsJSONObjectLine(memoryLine) && IsJSONObjectLine(noFieldsLine), "Each line should be one JSON object"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_EmptyScopeLeavesOutTheFields() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_EmptyScopeLeavesOutTheFields) { // Arrange: an entry in a scope without fields const auto config = MakeConfigWithoutFields("unused.log"); @@ -574,7 +546,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_EmptyScopeLeavesOutTheFields() CheckEquals(std::string(R"({"message":"msg"})"), line, "A scope without fields should add no \"fields\" object"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_EntryFields() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_EntryFields) { // Arrange: a scope and the entry's own fields, which replace the scope's n; a value of each kind, and the doubles // a JSON number can't hold @@ -612,7 +584,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_EntryFields() CheckTrue(IsJSONObjectLine(line) && IsJSONObjectLine(rawLine), "Each line should be one JSON object"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_EscapesTheTexts() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_EscapesTheTexts) { // Arrange: quotes, a backslash, control characters and invalid UTF-8 in the category and the message const auto config = MakeConfigWithoutFields("unused.log"); @@ -628,7 +600,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_EscapesTheTexts() CheckTrue(IsJSONObjectLine(line), "The line should be one JSON object"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_FileLoggerWritesJSONLines() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_FileLoggerWritesJSONLines) { // Arrange: every startup line (on Windows the drive and application info hold backslashes) and the shutdown line ASWLog::TASWLogConfig config; @@ -685,7 +657,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_FileLoggerWritesJSONLines() CheckEndsWith(lines.back(), R"(, Bye"})", "The shutdown line should have its banner"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_RawEntries() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_RawEntries) { // Arrange const ASWLog::TASWJSONFormatter formatter; @@ -703,7 +675,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_RawEntries() CheckEquals(std::string(R"({"raw":true,"message":"partial "})"), line, "A raw entry should be marked before the message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_JSONFormatter_TimeFollowsZoneAndPrecision() +ASW_TEST(TTest_ASWLog_Formatter, JSONFormatter_TimeFollowsZoneAndPrecision) { // Arrange: FixedTime in US Eastern daylight time with microseconds, and a time 1.49975 s before 1970 (the epoch // milliseconds round down, like the time's) @@ -729,7 +701,7 @@ void TTest_ASWLog_Formatter::Test_JSONFormatter_TimeFollowsZoneAndPrecision() "A time before 1970 should have negative epoch milliseconds, rounded down"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_AffixesOnlyAroundAValue() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_AffixesOnlyAroundAValue) { // Arrange: one record with a category and a function, one without (a default source location has empty names) auto withValues = MakeRecord("msg"); @@ -755,7 +727,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_AffixesOnlyAroundAValue() CheckEquals(std::string("[Net]msg|[]msg"), formatBoth("[{category}]{message}"), "Text outside the braces should always be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_BracesAndPlainText() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_BracesAndPlainText) { // Arrange const ASWLog::TASWLogConfig config; @@ -772,7 +744,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_BracesAndPlainText() CheckEmpty(empty, "An empty pattern should write an empty line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_DefaultLayoutMatchesTextFormatter() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_DefaultLayoutMatchesTextFormatter) { // Arrange: the patterns spelling the built-in layout, with the default fields and with every field but memory use const ASWLog::TASWPatternFormatter defaultFields("[{time}][{level}]{[category]}[P:{pid}][T:{tid}]: {message}"); @@ -816,7 +788,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_DefaultLayoutMatchesTextForma } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_EachPlaceholder() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_EachPlaceholder) { // Arrange const std::string pattern = "{time}|{level}|{category}|{pid}|{tid}|{function}|{file}|{line}|{message}"; @@ -835,7 +807,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_EachPlaceholder() CheckEquals(pattern, std::string(formatter.GetPattern()), "GetPattern should return the pattern"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_FieldsPlaceholder() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_FieldsPlaceholder) { // Arrange const ASWLog::TASWPatternFormatter formatter("{[fields] }{message}"); @@ -856,7 +828,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_FieldsPlaceholder() CheckEquals(std::string("msg"), lineWithout, "{fields} should write nothing, affixes included, without fields"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_FileLoggerWritesItsLines() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_FileLoggerWritesItsLines) { // Arrange: CRLF, so the line ending shows that the logger still adds it auto config = MakeConfigWithoutFields("pattern.log"); @@ -879,7 +851,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_FileLoggerWritesItsLines() "Each line should follow the pattern, then the line ending; a raw entry is written as is"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_InvalidPatternThrows() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_InvalidPatternThrows) { // Arrange: each pattern, and the start of the error message it should give struct TCase @@ -918,7 +890,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_InvalidPatternThrows() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_MemoryFields() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_MemoryFields) { // Arrange const ASWLog::TASWPatternFormatter formatter("{ws} {pws}: {message}"); @@ -930,7 +902,7 @@ void TTest_ASWLog_Formatter::Test_PatternFormatter_MemoryFields() CheckMatches(line, "[1-9][0-9]* [1-9][0-9]*: memory", "The working set and peak working set should be read, as decimal numbers"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Formatter::Test_PatternFormatter_WidthPadsShortValues() +ASW_TEST(TTest_ASWLog_Formatter, PatternFormatter_WidthPadsShortValues) { // Arrange const ASWLog::TASWLogConfig config; diff --git a/tests/tests/Test_ASWLog_Formatter.h b/tests/tests/Test_ASWLog_Formatter.h index 5d5c19e..bec9f95 100644 --- a/tests/tests/Test_ASWLog_Formatter.h +++ b/tests/tests/Test_ASWLog_Formatter.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Formatter /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Formatter : public TTestGroupBase +class TTest_ASWLog_Formatter : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Format_MatchesFormatLine(); void Test_FormatLine_AllFieldsInOrder(); void Test_FormatLine_CategoryOnlyWhenSetAndShown(); diff --git a/tests/tests/Test_ASWLog_Limiter.cpp b/tests/tests/Test_ASWLog_Limiter.cpp index 3ef8207..e1fc096 100644 --- a/tests/tests/Test_ASWLog_Limiter.cpp +++ b/tests/tests/Test_ASWLog_Limiter.cpp @@ -122,16 +122,6 @@ void LogRetry(ASWLog::IASWLog& log, int attempt) TTest_ASWLog_Limiter::TTest_ASWLog_Limiter() : inherited("ASWLog_Limiter_Tests") { - RegisterTest(&TTest_ASWLog_Limiter::Test_EveryInterval_AllowsOneCallPerInterval, "EveryInterval_AllowsOneCallPerInterval"); - RegisterTest(&TTest_ASWLog_Limiter::Test_EveryInterval_HandlesTheLongestInterval, "EveryInterval_HandlesTheLongestInterval"); - RegisterTest(&TTest_ASWLog_Limiter::Test_EveryInterval_ZeroAllowsEveryCall, "EveryInterval_ZeroAllowsEveryCall"); - RegisterTest(&TTest_ASWLog_Limiter::Test_EveryN_AllowsEveryNthCall, "EveryN_AllowsEveryNthCall"); - RegisterTest(&TTest_ASWLog_Limiter::Test_Macros_EveryIntervalAddsTheSuppressedField, "Macros_EveryIntervalAddsTheSuppressedField"); - RegisterTest(&TTest_ASWLog_Limiter::Test_Macros_EveryNCountsOnlyEntriesThatWouldBeWritten, "Macros_EveryNCountsOnlyEntriesThatWouldBeWritten"); - RegisterTest(&TTest_ASWLog_Limiter::Test_Macros_KeepTheCallersSourceLocation, "Macros_KeepTheCallersSourceLocation"); - RegisterTest(&TTest_ASWLog_Limiter::Test_Macros_OnceLogsTheFirstEntryThatWouldBeWritten, "Macros_OnceLogsTheFirstEntryThatWouldBeWritten"); - RegisterTest(&TTest_ASWLog_Limiter::Test_Once_AllowsOnlyTheFirstCall, "Once_AllowsOnlyTheFirstCall"); - RegisterTest(&TTest_ASWLog_Limiter::Test_Threads_AllowExactlyTheLimitedCalls, "Threads_AllowExactlyTheLimitedCalls"); } //--------------------------------------------------------------------------- TTest_ASWLog_Limiter::~TTest_ASWLog_Limiter() @@ -159,7 +149,7 @@ void TTest_ASWLog_Limiter::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_EveryInterval_AllowsOneCallPerInterval() +ASW_TEST(TTest_ASWLog_Limiter, EveryInterval_AllowsOneCallPerInterval) { // Arrange auto limiter = ASWLog::TASWLogLimiter::EveryInterval(5s); @@ -187,7 +177,7 @@ void TTest_ASWLog_Limiter::Test_EveryInterval_AllowsOneCallPerInterval() CheckEquals(1, refused[6], "The count should start again after each allowed call"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_EveryInterval_HandlesTheLongestInterval() +ASW_TEST(TTest_ASWLog_Limiter, EveryInterval_HandlesTheLongestInterval) { // Arrange: the time after the allowed call would overflow the clock's ticks auto limiter = ASWLog::TASWLogLimiter::EveryInterval(std::chrono::steady_clock::duration::max()); @@ -203,7 +193,7 @@ void TTest_ASWLog_Limiter::Test_EveryInterval_HandlesTheLongestInterval() CheckFalse(later, "A call within the (longest) interval should be refused, not allowed by a wrapped time"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_EveryInterval_ZeroAllowsEveryCall() +ASW_TEST(TTest_ASWLog_Limiter, EveryInterval_ZeroAllowsEveryCall) { // Arrange auto zero = ASWLog::TASWLogLimiter::EveryInterval(0s); @@ -220,7 +210,7 @@ void TTest_ASWLog_Limiter::Test_EveryInterval_ZeroAllowsEveryCall() CheckEquals(6, allowed, "An interval of 0 or less should allow every call"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_EveryN_AllowsEveryNthCall() +ASW_TEST(TTest_ASWLog_Limiter, EveryN_AllowsEveryNthCall) { // Arrange auto everyThird = ASWLog::TASWLogLimiter::EveryN(3); @@ -249,7 +239,7 @@ void TTest_ASWLog_Limiter::Test_EveryN_AllowsEveryNthCall() CheckEquals(8, zerothAllowed, "An n of 0 should allow every call"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_Macros_EveryIntervalAddsTheSuppressedField() +ASW_TEST(TTest_ASWLog_Limiter, Macros_EveryIntervalAddsTheSuppressedField) { // The call site's limiter lasts for the process static int runCount = 0; @@ -275,7 +265,7 @@ void TTest_ASWLog_Limiter::Test_Macros_EveryIntervalAddsTheSuppressedField() "The next entry should say how many calls were skipped, with the call's own fields"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_Macros_EveryNCountsOnlyEntriesThatWouldBeWritten() +ASW_TEST(TTest_ASWLog_Limiter, Macros_EveryNCountsOnlyEntriesThatWouldBeWritten) { static int runCount = 0; if (runCount++ > 0) @@ -300,7 +290,7 @@ void TTest_ASWLog_Limiter::Test_Macros_EveryNCountsOnlyEntriesThatWouldBeWritten CheckEquals(std::string("[INFO]: Item 9"), lines[2], "Then the 9th"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_Macros_KeepTheCallersSourceLocation() +ASW_TEST(TTest_ASWLog_Limiter, Macros_KeepTheCallersSourceLocation) { // Arrange ASWLog::TASWMemoryLog log; @@ -323,7 +313,7 @@ void TTest_ASWLog_Limiter::Test_Macros_KeepTheCallersSourceLocation() CheckEndsWith(std::string(location->file_name()), "Test_ASWLog_Limiter.cpp", "The entry should have the calling file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_Macros_OnceLogsTheFirstEntryThatWouldBeWritten() +ASW_TEST(TTest_ASWLog_Limiter, Macros_OnceLogsTheFirstEntryThatWouldBeWritten) { static int runCount = 0; if (runCount++ > 0) @@ -349,7 +339,7 @@ void TTest_ASWLog_Limiter::Test_Macros_OnceLogsTheFirstEntryThatWouldBeWritten() CheckEquals(1, LimiterFormatCount, "Only the written entry's arguments should be formatted"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_Once_AllowsOnlyTheFirstCall() +ASW_TEST(TTest_ASWLog_Limiter, Once_AllowsOnlyTheFirstCall) { // Arrange auto limiter = ASWLog::TASWLogLimiter::Once(); @@ -368,7 +358,7 @@ void TTest_ASWLog_Limiter::Test_Once_AllowsOnlyTheFirstCall() CheckEquals(0, refused, "A refused call should get a count of 0"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Limiter::Test_Threads_AllowExactlyTheLimitedCalls() +ASW_TEST(TTest_ASWLog_Limiter, Threads_AllowExactlyTheLimitedCalls) { // Arrange: threads sharing each kind of limiter (also for ThreadSanitizer), EveryInterval at one fixed time constexpr int ThreadCount = 8; diff --git a/tests/tests/Test_ASWLog_Limiter.h b/tests/tests/Test_ASWLog_Limiter.h index be141b4..82cbe8f 100644 --- a/tests/tests/Test_ASWLog_Limiter.h +++ b/tests/tests/Test_ASWLog_Limiter.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Limiter /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Limiter : public TTestGroupBase +class TTest_ASWLog_Limiter : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_EveryInterval_AllowsOneCallPerInterval(); void Test_EveryInterval_HandlesTheLongestInterval(); void Test_EveryInterval_ZeroAllowsEveryCall(); diff --git a/tests/tests/Test_ASWLog_MemoryLog.cpp b/tests/tests/Test_ASWLog_MemoryLog.cpp index 185bdc7..b0776cb 100644 --- a/tests/tests/Test_ASWLog_MemoryLog.cpp +++ b/tests/tests/Test_ASWLog_MemoryLog.cpp @@ -84,16 +84,6 @@ ASWLog::TASWLogConfig MakeMemoryConfig(std::size_t maxLines = 1000, std::size_t TTest_ASWLog_MemoryLog::TTest_ASWLog_MemoryLog() : inherited("ASWLog_MemoryLog_Tests") { - RegisterTest(&TTest_ASWLog_MemoryLog::Test_Async_KeepsTheQueuedLines, "Async_KeepsTheQueuedLines"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_Clear_ForgetsTheLinesButNotTheSequence, "Clear_ForgetsTheLinesButNotTheSequence"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_Close_KeepsTheLines, "Close_KeepsTheLines"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_GetLinesSince_ReturnsNewLinesAndCountsMissedOnes, "GetLinesSince_ReturnsNewLinesAndCountsMissedOnes"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_KeepsLinesWithoutTheirEnding, "KeepsLinesWithoutTheirEnding"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_MaxBytes_CutsALineThatAloneIsTooLong, "MaxBytes_CutsALineThatAloneIsTooLong"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_MaxBytes_DropsTheOldestLines, "MaxBytes_DropsTheOldestLines"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_MaxLines_KeepsTheNewest, "MaxLines_KeepsTheNewest"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_Reconfigure_AppliesTheNewLimits, "Reconfigure_AppliesTheNewLimits"); - RegisterTest(&TTest_ASWLog_MemoryLog::Test_Threads_ReaderGetsEveryLineOnce, "Threads_ReaderGetsEveryLineOnce"); } //--------------------------------------------------------------------------- TTest_ASWLog_MemoryLog::~TTest_ASWLog_MemoryLog() @@ -120,7 +110,7 @@ void TTest_ASWLog_MemoryLog::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_Async_KeepsTheQueuedLines() +ASW_TEST(TTest_ASWLog_MemoryLog, Async_KeepsTheQueuedLines) { // Arrange auto config = MakeMemoryConfig(); @@ -137,7 +127,7 @@ void TTest_ASWLog_MemoryLog::Test_Async_KeepsTheQueuedLines() CheckTrue(log.GetLines() == std::vector{ "[INFO]: one", "[WARN]: two" }, "The queued lines should be kept in order"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_Clear_ForgetsTheLinesButNotTheSequence() +ASW_TEST(TTest_ASWLog_MemoryLog, Clear_ForgetsTheLinesButNotTheSequence) { // Arrange ASWLog::TASWMemoryLog log; @@ -161,7 +151,7 @@ void TTest_ASWLog_MemoryLog::Test_Clear_ForgetsTheLinesButNotTheSequence() CheckEquals(0, afterNewLine.MissedCount, "Nothing should be missed after the cleared lines"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_Close_KeepsTheLines() +ASW_TEST(TTest_ASWLog_MemoryLog, Close_KeepsTheLines) { // Arrange ASWLog::TASWMemoryLog log; @@ -179,7 +169,7 @@ void TTest_ASWLog_MemoryLog::Test_Close_KeepsTheLines() CheckTrue(log.GetLines() == std::vector{ "[INFO]: kept" }, "The lines should be kept after Close(), and no more added"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_GetLinesSince_ReturnsNewLinesAndCountsMissedOnes() +ASW_TEST(TTest_ASWLog_MemoryLog, GetLinesSince_ReturnsNewLinesAndCountsMissedOnes) { // Arrange: lines 1 to 3 kept, then 4 and 5, which push 1 and 2 out ASWLog::TASWMemoryLog log; @@ -215,7 +205,7 @@ void TTest_ASWLog_MemoryLog::Test_GetLinesSince_ReturnsNewLinesAndCountsMissedOn CheckEquals(0, ahead.MissedCount, "A number past the last line should miss nothing"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_KeepsLinesWithoutTheirEnding() +ASW_TEST(TTest_ASWLog_MemoryLog, KeepsLinesWithoutTheirEnding) { // Arrange: LF, and CRLF with indented continuation lines ASWLog::TASWMemoryLog log; @@ -241,7 +231,7 @@ void TTest_ASWLog_MemoryLog::Test_KeepsLinesWithoutTheirEnding() "A CRLF ending should be left off, and the line breaks inside the line kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_MaxBytes_CutsALineThatAloneIsTooLong() +ASW_TEST(TTest_ASWLog_MemoryLog, MaxBytes_CutsALineThatAloneIsTooLong) { // Arrange: 20 bytes, so the line "[INFO]: abcde" + a 2-byte UTF-8 character + more is cut inside that character; // and 4 bytes, too few for the marker @@ -261,7 +251,7 @@ void TTest_ASWLog_MemoryLog::Test_MaxBytes_CutsALineThatAloneIsTooLong() CheckTrue(tinyLog.GetLines() == std::vector{ "[INF" }, "Without room for the marker, the line should only be cut"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_MaxBytes_DropsTheOldestLines() +ASW_TEST(TTest_ASWLog_MemoryLog, MaxBytes_DropsTheOldestLines) { // Arrange: 30 bytes, two 15-byte lines ASWLog::TASWMemoryLog log; @@ -278,7 +268,7 @@ void TTest_ASWLog_MemoryLog::Test_MaxBytes_DropsTheOldestLines() CheckTrue(log.GetLines() == std::vector{ "[INFO]: 2222222", "[INFO]: 3333333" }, "The oldest line should go to make room"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_MaxLines_KeepsTheNewest() +ASW_TEST(TTest_ASWLog_MemoryLog, MaxLines_KeepsTheNewest) { // Arrange ASWLog::TASWMemoryLog log; @@ -294,7 +284,7 @@ void TTest_ASWLog_MemoryLog::Test_MaxLines_KeepsTheNewest() "The newest lines should be kept, oldest first"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_Reconfigure_AppliesTheNewLimits() +ASW_TEST(TTest_ASWLog_MemoryLog, Reconfigure_AppliesTheNewLimits) { // Arrange ASWLog::TASWMemoryLog log; @@ -319,7 +309,7 @@ void TTest_ASWLog_MemoryLog::Test_Reconfigure_AppliesTheNewLimits() CheckEquals(6, log.GetLineCount(), "With no limits, every new line should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MemoryLog::Test_Threads_ReaderGetsEveryLineOnce() +ASW_TEST(TTest_ASWLog_MemoryLog, Threads_ReaderGetsEveryLineOnce) { // Arrange: four threads log while another reads the new lines as they come (for ThreadSanitizer) constexpr int ThreadCount = 4; diff --git a/tests/tests/Test_ASWLog_MemoryLog.h b/tests/tests/Test_ASWLog_MemoryLog.h index dea6a02..497a221 100644 --- a/tests/tests/Test_ASWLog_MemoryLog.h +++ b/tests/tests/Test_ASWLog_MemoryLog.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_MemoryLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_MemoryLog : public TTestGroupBase +class TTest_ASWLog_MemoryLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Async_KeepsTheQueuedLines(); void Test_Clear_ForgetsTheLinesButNotTheSequence(); void Test_Close_KeepsTheLines(); diff --git a/tests/tests/Test_ASWLog_MultiLog.cpp b/tests/tests/Test_ASWLog_MultiLog.cpp index b4b7d7c..8cd03df 100644 --- a/tests/tests/Test_ASWLog_MultiLog.cpp +++ b/tests/tests/Test_ASWLog_MultiLog.cpp @@ -278,37 +278,6 @@ ASWLog::TASWLogConfig MakeFileConfig(const std::filesystem::path& dir, const std TTest_ASWLog_MultiLog::TTest_ASWLog_MultiLog() : inherited("ASWLog_MultiLog_Tests") { - RegisterTest(&TTest_ASWLog_MultiLog::Test_AddLogger_RejectsDuplicateRegistration, "AddLogger_RejectsDuplicateRegistration"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_AddLogger_RejectsSelfRegistration, "AddLogger_RejectsSelfRegistration"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Backtrace_EachLoggerKeepsItsOwn, "Backtrace_EachLoggerKeepsItsOwn"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Backtrace_IsNotKeptByTheMultiLog, "Backtrace_IsNotKeptByTheMultiLog"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Close_AllowsInitializeAgain, "Close_AllowsInitializeAgain"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Close_ReachesEverySinkEvenAfterAFailure, "Close_ReachesEverySinkEvenAfterAFailure"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Contains_ReflectsRegistrationState, "Contains_ReflectsRegistrationState"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_DumpBacktrace_ReachesEverySinkUnlessDisabled, "DumpBacktrace_ReachesEverySinkUnlessDisabled"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Flush_ReachesEverySinkEvenAfterAFailure, "Flush_ReachesEverySinkEvenAfterAFailure"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Flush_SucceedsWithNoSinks, "Flush_SucceedsWithNoSinks"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Flush_WorksWhileDisabled, "Flush_WorksWhileDisabled"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Flush_WritesBufferedEntriesOfEveryFileSink, "Flush_WritesBufferedEntriesOfEveryFileSink"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_GetLoggerCount_ReflectsAddAndRemove, "GetLoggerCount_ReflectsAddAndRemove"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_GetLoggers_ReturnsSnapshotOfRegisteredSinks, "GetLoggers_ReturnsSnapshotOfRegisteredSinks"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Initialize_ConcurrentCallsSucceedOnce, "Initialize_ConcurrentCallsSucceedOnce"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Initialize_FailsOnlyForASinkThatIsNotOpen, "Initialize_FailsOnlyForASinkThatIsNotOpen"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_IsOpen_RequiresAllSinksOpen, "IsOpen_RequiresAllSinksOpen"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Log_AtLevelOffIsNotFannedOut, "Log_AtLevelOffIsNotFannedOut"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Log_FansOutToAllRegisteredSinks, "Log_FansOutToAllRegisteredSinks"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Log_ThrowingSinkDoesNotStopOtherSinks, "Log_ThrowingSinkDoesNotStopOtherSinks"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_LogFmt_FormatsOnceForAllSinks, "LogFmt_FormatsOnceForAllSinks"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_LogForce_BypassesCompositeGate, "LogForce_BypassesCompositeGate"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_OnBeforeWrite_RunsOnceBeforeTheFanOut, "OnBeforeWrite_RunsOnceBeforeTheFanOut"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Open_ReachesEverySinkEvenAfterAFailure, "Open_ReachesEverySinkEvenAfterAFailure"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Reconfigure_PassesConfigToEverySink, "Reconfigure_PassesConfigToEverySink"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_RemoveAllLoggers_ClearsRegistrationAndReturnsCount, "RemoveAllLoggers_ClearsRegistrationAndReturnsCount"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_RemoveLogger_StopsReceivingEntries, "RemoveLogger_StopsReceivingEntries"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_SetEnabled_FalseStopsFanOut, "SetEnabled_FalseStopsFanOut"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_SetMinimumLevel_GatesFanOutBeforeSinks, "SetMinimumLevel_GatesFanOutBeforeSinks"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_ShouldLog_RequiresCompositeGateAndAnySink, "ShouldLog_RequiresCompositeGateAndAnySink"); - RegisterTest(&TTest_ASWLog_MultiLog::Test_Write_PassesOneStampedRecordToEverySink, "Write_PassesOneStampedRecordToEverySink"); } //--------------------------------------------------------------------------- TTest_ASWLog_MultiLog::~TTest_ASWLog_MultiLog() @@ -343,7 +312,7 @@ void TTest_ASWLog_MultiLog::TearDown_Test(ITestCase& testCase) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_AddLogger_RejectsDuplicateRegistration() +ASW_TEST(TTest_ASWLog_MultiLog, AddLogger_RejectsDuplicateRegistration) { // Arrange const auto fileA = TestTempDir / "duplicate_sink.log"; @@ -369,7 +338,7 @@ void TTest_ASWLog_MultiLog::Test_AddLogger_RejectsDuplicateRegistration() CheckTrue(secondPos == std::string::npos, "The message should not be duplicated in the sink"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_AddLogger_RejectsSelfRegistration() +ASW_TEST(TTest_ASWLog_MultiLog, AddLogger_RejectsSelfRegistration) { // Arrange ASWLog::TASWMultiLog multiLog; @@ -385,7 +354,7 @@ void TTest_ASWLog_MultiLog::Test_AddLogger_RejectsSelfRegistration() multiLog.LogInfo("no_recursion_expected"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Backtrace_EachLoggerKeepsItsOwn() +ASW_TEST(TTest_ASWLog_MultiLog, Backtrace_EachLoggerKeepsItsOwn) { // Arrange: the multi-log lets every level through; each sink keeps what is below its own minimum level const auto config = MakeBacktraceConfig(ASWLog::Level::Trace); @@ -417,7 +386,7 @@ void TTest_ASWLog_MultiLog::Test_Backtrace_EachLoggerKeepsItsOwn() CheckTrue(warnSink.Calls == expectedWarn, "The Warn sink should keep the Debug and Info entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Backtrace_IsNotKeptByTheMultiLog() +ASW_TEST(TTest_ASWLog_MultiLog, Backtrace_IsNotKeptByTheMultiLog) { // Arrange: the multi-log's own minimum level is Info, and its config asks for a backtrace const auto config = MakeBacktraceConfig(ASWLog::Level::Info); @@ -438,7 +407,7 @@ void TTest_ASWLog_MultiLog::Test_Backtrace_IsNotKeptByTheMultiLog() CheckTrue(sink.Calls == std::vector{ "Log:error_1" }, "Neither the multi-log nor the sink should keep the Debug entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Close_AllowsInitializeAgain() +ASW_TEST(TTest_ASWLog_MultiLog, Close_AllowsInitializeAgain) { // Arrange const auto fileA = TestTempDir / "reinitialize_sink.log"; @@ -461,7 +430,7 @@ void TTest_ASWLog_MultiLog::Test_Close_AllowsInitializeAgain() CheckContains(ReadFileText(fileA), "after_reinitialize", "Initialize after Close should initialize the sinks again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Close_ReachesEverySinkEvenAfterAFailure() +ASW_TEST(TTest_ASWLog_MultiLog, Close_ReachesEverySinkEvenAfterAFailure) { // Arrange: the first sink's close fails TRecordingLogger failingSink; @@ -484,7 +453,7 @@ void TTest_ASWLog_MultiLog::Test_Close_ReachesEverySinkEvenAfterAFailure() CheckEquals(2, sink.CloseCount, "A sink's failed close should not stop the other sinks from being closed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Contains_ReflectsRegistrationState() +ASW_TEST(TTest_ASWLog_MultiLog, Contains_ReflectsRegistrationState) { // Arrange const auto fileA = TestTempDir / "contains_sink.log"; @@ -505,7 +474,7 @@ void TTest_ASWLog_MultiLog::Test_Contains_ReflectsRegistrationState() sinkA.Close(); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_DumpBacktrace_ReachesEverySinkUnlessDisabled() +ASW_TEST(TTest_ASWLog_MultiLog, DumpBacktrace_ReachesEverySinkUnlessDisabled) { // Arrange const auto config = MakeBacktraceConfig(ASWLog::Level::Trace); @@ -540,7 +509,7 @@ void TTest_ASWLog_MultiLog::Test_DumpBacktrace_ReachesEverySinkUnlessDisabled() CheckTrue(sinkB.Calls == expected, "The second sink should write its backtrace"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Flush_ReachesEverySinkEvenAfterAFailure() +ASW_TEST(TTest_ASWLog_MultiLog, Flush_ReachesEverySinkEvenAfterAFailure) { // Arrange: the first sink's flush fails TRecordingLogger failingSink; @@ -564,7 +533,7 @@ void TTest_ASWLog_MultiLog::Test_Flush_ReachesEverySinkEvenAfterAFailure() CheckTrue(sink.Calls == twoFlushes, "A sink's failed flush should not stop the other sinks from being flushed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Flush_SucceedsWithNoSinks() +ASW_TEST(TTest_ASWLog_MultiLog, Flush_SucceedsWithNoSinks) { // Arrange ASWLog::TASWMultiLog multiLog; @@ -573,7 +542,7 @@ void TTest_ASWLog_MultiLog::Test_Flush_SucceedsWithNoSinks() CheckTrue(multiLog.Flush(), "Flush() with no registered sinks should succeed, like IsOpen()"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Flush_WorksWhileDisabled() +ASW_TEST(TTest_ASWLog_MultiLog, Flush_WorksWhileDisabled) { // Arrange TRecordingLogger sink; @@ -589,7 +558,7 @@ void TTest_ASWLog_MultiLog::Test_Flush_WorksWhileDisabled() CheckTrue(sink.Calls == std::vector{ "Flush" }, "A disabled composite should still flush its sinks; disabling only stops new entries"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Flush_WritesBufferedEntriesOfEveryFileSink() +ASW_TEST(TTest_ASWLog_MultiLog, Flush_WritesBufferedEntriesOfEveryFileSink) { // Arrange: FlushMode::Manual keeps each entry in the file's buffer until Flush() const auto fileA = TestTempDir / "flush_sink_a.log"; @@ -628,7 +597,7 @@ void TTest_ASWLog_MultiLog::Test_Flush_WritesBufferedEntriesOfEveryFileSink() CheckContains(contentsAfterB, "buffered_entry", "Flush() should write sinkB's buffered entry to its file"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_GetLoggerCount_ReflectsAddAndRemove() +ASW_TEST(TTest_ASWLog_MultiLog, GetLoggerCount_ReflectsAddAndRemove) { // Arrange const auto fileA = TestTempDir / "count_a.log"; @@ -660,7 +629,7 @@ void TTest_ASWLog_MultiLog::Test_GetLoggerCount_ReflectsAddAndRemove() sinkB.Close(); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_GetLoggers_ReturnsSnapshotOfRegisteredSinks() +ASW_TEST(TTest_ASWLog_MultiLog, GetLoggers_ReturnsSnapshotOfRegisteredSinks) { // Arrange const auto fileA = TestTempDir / "loggers_a.log"; @@ -687,7 +656,7 @@ void TTest_ASWLog_MultiLog::Test_GetLoggers_ReturnsSnapshotOfRegisteredSinks() sinkB.Close(); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Initialize_ConcurrentCallsSucceedOnce() +ASW_TEST(TTest_ASWLog_MultiLog, Initialize_ConcurrentCallsSucceedOnce) { // Arrange constexpr int roundCount = 200; @@ -729,7 +698,7 @@ void TTest_ASWLog_MultiLog::Test_Initialize_ConcurrentCallsSucceedOnce() CheckEquals(roundCount, roundsWithOneSuccess, "Exactly one of the concurrent Initialize calls should succeed"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Initialize_FailsOnlyForASinkThatIsNotOpen() +ASW_TEST(TTest_ASWLog_MultiLog, Initialize_FailsOnlyForASinkThatIsNotOpen) { // Arrange: the first sink's Initialize() fails, as it does for a logger that is already initialized TRecordingLogger failingSink; @@ -753,7 +722,7 @@ void TTest_ASWLog_MultiLog::Test_Initialize_FailsOnlyForASinkThatIsNotOpen() CheckTrue(sink.WasInitialized, "A sink's failed Initialize() should not stop the other sinks from being initialized"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_IsOpen_RequiresAllSinksOpen() +ASW_TEST(TTest_ASWLog_MultiLog, IsOpen_RequiresAllSinksOpen) { // Arrange const auto fileA = TestTempDir / "open_a.log"; @@ -778,7 +747,7 @@ void TTest_ASWLog_MultiLog::Test_IsOpen_RequiresAllSinksOpen() sinkA.Close(); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Log_AtLevelOffIsNotFannedOut() +ASW_TEST(TTest_ASWLog_MultiLog, Log_AtLevelOffIsNotFannedOut) { // Arrange TRecordingLogger sink; @@ -805,7 +774,7 @@ void TTest_ASWLog_MultiLog::Test_Log_AtLevelOffIsNotFannedOut() "With the composite's minimum level at Off, only forced entries should be fanned out"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Log_FansOutToAllRegisteredSinks() +ASW_TEST(TTest_ASWLog_MultiLog, Log_FansOutToAllRegisteredSinks) { // Arrange const auto fileA = TestTempDir / "sink_a.log"; @@ -830,7 +799,7 @@ void TTest_ASWLog_MultiLog::Test_Log_FansOutToAllRegisteredSinks() CheckContains(ReadFileText(fileB), "fanned_out_message", "sinkB should receive the fanned-out message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Log_ThrowingSinkDoesNotStopOtherSinks() +ASW_TEST(TTest_ASWLog_MultiLog, Log_ThrowingSinkDoesNotStopOtherSinks) { // Arrange: the throwing sink is registered first, so it's called before the file sink const auto file = TestTempDir / "after_throwing_sink.log"; @@ -869,7 +838,7 @@ void TTest_ASWLog_MultiLog::Test_Log_ThrowingSinkDoesNotStopOtherSinks() CheckEquals(4, reportCount, "The failing sink should report each entry it dropped, through its own OnError"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_LogFmt_FormatsOnceForAllSinks() +ASW_TEST(TTest_ASWLog_MultiLog, LogFmt_FormatsOnceForAllSinks) { // Arrange: two sinks at the default minimum level (Info), and a composite that lets everything through TRecordingLogger sinkA; @@ -892,7 +861,7 @@ void TTest_ASWLog_MultiLog::Test_LogFmt_FormatsOnceForAllSinks() "Both sinks should get the formatted entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_LogForce_BypassesCompositeGate() +ASW_TEST(TTest_ASWLog_MultiLog, LogForce_BypassesCompositeGate) { // Arrange const auto fileA = TestTempDir / "force_sink.log"; @@ -912,7 +881,7 @@ void TTest_ASWLog_MultiLog::Test_LogForce_BypassesCompositeGate() CheckContains(ReadFileText(fileA), "forced_past_composite_gate", "LogForce should bypass the composite's own MinimumLevel gate"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_OnBeforeWrite_RunsOnceBeforeTheFanOut() +ASW_TEST(TTest_ASWLog_MultiLog, OnBeforeWrite_RunsOnceBeforeTheFanOut) { // Arrange: the second sink has a hook of its own, set directly TRecordingLogger first; @@ -956,7 +925,7 @@ void TTest_ASWLog_MultiLog::Test_OnBeforeWrite_RunsOnceBeforeTheFanOut() "A sink's own hook should run after the multi-log's, until the multi-log's Reconfigure() replaces its config"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Open_ReachesEverySinkEvenAfterAFailure() +ASW_TEST(TTest_ASWLog_MultiLog, Open_ReachesEverySinkEvenAfterAFailure) { // Arrange: the first sink's open fails TRecordingLogger failingSink; @@ -979,7 +948,7 @@ void TTest_ASWLog_MultiLog::Test_Open_ReachesEverySinkEvenAfterAFailure() CheckEquals(2, sink.OpenCount, "A sink's failed open should not stop the other sinks from being opened"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Reconfigure_PassesConfigToEverySink() +ASW_TEST(TTest_ASWLog_MultiLog, Reconfigure_PassesConfigToEverySink) { // Arrange: the first sink's Reconfigure() fails TRecordingLogger failingSink; @@ -1013,7 +982,7 @@ void TTest_ASWLog_MultiLog::Test_Reconfigure_PassesConfigToEverySink() CheckEquals(std::string("reconfigured"), multiLog.GetConfig()->Startup.Banner, "The multi-log should keep the new config"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_RemoveAllLoggers_ClearsRegistrationAndReturnsCount() +ASW_TEST(TTest_ASWLog_MultiLog, RemoveAllLoggers_ClearsRegistrationAndReturnsCount) { // Arrange const auto fileA = TestTempDir / "remove_all_a.log"; @@ -1041,7 +1010,7 @@ void TTest_ASWLog_MultiLog::Test_RemoveAllLoggers_ClearsRegistrationAndReturnsCo CheckNotContains(ReadFileText(fileB), "should_not_reach_any_sink", "sinkB should not receive entries after RemoveAllLoggers"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_RemoveLogger_StopsReceivingEntries() +ASW_TEST(TTest_ASWLog_MultiLog, RemoveLogger_StopsReceivingEntries) { // Arrange const auto fileA = TestTempDir / "remove_sink.log"; @@ -1068,7 +1037,7 @@ void TTest_ASWLog_MultiLog::Test_RemoveLogger_StopsReceivingEntries() CheckNotContains(contents, "after_removal", "Message logged after removal should not reach the sink"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_SetEnabled_FalseStopsFanOut() +ASW_TEST(TTest_ASWLog_MultiLog, SetEnabled_FalseStopsFanOut) { // Arrange TRecordingLogger sink; @@ -1094,7 +1063,7 @@ void TTest_ASWLog_MultiLog::Test_SetEnabled_FalseStopsFanOut() CheckTrue(sink.Calls == std::vector{ "Log:enabled_again" }, "Fan-out should resume once enabled again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_SetMinimumLevel_GatesFanOutBeforeSinks() +ASW_TEST(TTest_ASWLog_MultiLog, SetMinimumLevel_GatesFanOutBeforeSinks) { // Arrange const auto fileA = TestTempDir / "gate_sink.log"; @@ -1118,7 +1087,7 @@ void TTest_ASWLog_MultiLog::Test_SetMinimumLevel_GatesFanOutBeforeSinks() CheckContains(contents, "passes_composite_gate", "Entries at or above the composite level should still reach the sink"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_ShouldLog_RequiresCompositeGateAndAnySink() +ASW_TEST(TTest_ASWLog_MultiLog, ShouldLog_RequiresCompositeGateAndAnySink) { // Arrange TRecordingLogger errorSink; @@ -1156,7 +1125,7 @@ void TTest_ASWLog_MultiLog::Test_ShouldLog_RequiresCompositeGateAndAnySink() CheckFalse(shouldLogErrorWithCompositeDisabled, "A disabled composite should log nothing"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_MultiLog::Test_Write_PassesOneStampedRecordToEverySink() +ASW_TEST(TTest_ASWLog_MultiLog, Write_PassesOneStampedRecordToEverySink) { // Arrange: sinks on the system clock behind a composite with a fixed clock; sinkB only takes Error and above TRecordingLogger sinkA; diff --git a/tests/tests/Test_ASWLog_MultiLog.h b/tests/tests/Test_ASWLog_MultiLog.h index f4311a6..9c93e14 100644 --- a/tests/tests/Test_ASWLog_MultiLog.h +++ b/tests/tests/Test_ASWLog_MultiLog.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_MultiLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_MultiLog : public TTestGroupBase +class TTest_ASWLog_MultiLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_AddLogger_RejectsDuplicateRegistration(); void Test_AddLogger_RejectsSelfRegistration(); void Test_Backtrace_EachLoggerKeepsItsOwn(); diff --git a/tests/tests/Test_ASWLog_NullLog.cpp b/tests/tests/Test_ASWLog_NullLog.cpp index 580e4c4..0dce676 100644 --- a/tests/tests/Test_ASWLog_NullLog.cpp +++ b/tests/tests/Test_ASWLog_NullLog.cpp @@ -78,12 +78,6 @@ namespace ASWUnitTests TTest_ASWLog_NullLog::TTest_ASWLog_NullLog() : inherited("ASWLog_NullLog_Tests") { - RegisterTest(&TTest_ASWLog_NullLog::Test_Fmt_NeverFormats, "Fmt_NeverFormats"); - RegisterTest(&TTest_ASWLog_NullLog::Test_GetConfig_IsSafeWhileReconfiguring, "GetConfig_IsSafeWhileReconfiguring"); - RegisterTest(&TTest_ASWLog_NullLog::Test_GetInstance_ReturnsTheSameLogger, "GetInstance_ReturnsTheSameLogger"); - RegisterTest(&TTest_ASWLog_NullLog::Test_Lifecycle_SucceedsAndKeepsTheConfig, "Lifecycle_SucceedsAndKeepsTheConfig"); - RegisterTest(&TTest_ASWLog_NullLog::Test_ShouldLog_IsAlwaysFalse, "ShouldLog_IsAlwaysFalse"); - RegisterTest(&TTest_ASWLog_NullLog::Test_Wrapped_WritesNothing, "Wrapped_WritesNothing"); } //--------------------------------------------------------------------------- TTest_ASWLog_NullLog::~TTest_ASWLog_NullLog() @@ -111,7 +105,7 @@ void TTest_ASWLog_NullLog::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_NullLog::Test_Fmt_NeverFormats() +ASW_TEST(TTest_ASWLog_NullLog, Fmt_NeverFormats) { // Arrange: everything a real logger would need to write an entry ASWLog::TASWNullLog log; @@ -130,7 +124,7 @@ void TTest_ASWLog_NullLog::Test_Fmt_NeverFormats() CheckEquals(0, NullLogFormatCount, "No *Fmt call should format its message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_NullLog::Test_GetConfig_IsSafeWhileReconfiguring() +ASW_TEST(TTest_ASWLog_NullLog, GetConfig_IsSafeWhileReconfiguring) { // Arrange: two threads reconfigure while two read the config (for ThreadSanitizer) ASWLog::TASWNullLog log; @@ -172,7 +166,7 @@ void TTest_ASWLog_NullLog::Test_GetConfig_IsSafeWhileReconfiguring() CheckEquals(0, unexpectedCount.load(), "Every read should see one of the configs whole"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_NullLog::Test_GetInstance_ReturnsTheSameLogger() +ASW_TEST(TTest_ASWLog_NullLog, GetInstance_ReturnsTheSameLogger) { // Act auto& first = ASWLog::TASWNullLog::GetInstance(); @@ -183,7 +177,7 @@ void TTest_ASWLog_NullLog::Test_GetInstance_ReturnsTheSameLogger() CheckFalse(first.ShouldLog(ASWLog::Level::Critical), "The shared instance should write nothing either"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_NullLog::Test_Lifecycle_SucceedsAndKeepsTheConfig() +ASW_TEST(TTest_ASWLog_NullLog, Lifecycle_SucceedsAndKeepsTheConfig) { // Arrange ASWLog::TASWNullLog log; @@ -218,7 +212,7 @@ void TTest_ASWLog_NullLog::Test_Lifecycle_SucceedsAndKeepsTheConfig() CheckEquals(std::string(ASWLog::Version), std::string(log.GetVersionStr()), "The version should be the library's"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_NullLog::Test_ShouldLog_IsAlwaysFalse() +ASW_TEST(TTest_ASWLog_NullLog, ShouldLog_IsAlwaysFalse) { // Arrange ASWLog::TASWNullLog log; @@ -238,7 +232,7 @@ void TTest_ASWLog_NullLog::Test_ShouldLog_IsAlwaysFalse() log.LogCritical("not written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_NullLog::Test_Wrapped_WritesNothing() +ASW_TEST(TTest_ASWLog_NullLog, Wrapped_WritesNothing) { // Arrange: a category and a multi-log in front of a null log ASWLog::TASWNullLog log; diff --git a/tests/tests/Test_ASWLog_NullLog.h b/tests/tests/Test_ASWLog_NullLog.h index 3f60a25..c02a018 100644 --- a/tests/tests/Test_ASWLog_NullLog.h +++ b/tests/tests/Test_ASWLog_NullLog.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_NullLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_NullLog : public TTestGroupBase +class TTest_ASWLog_NullLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Fmt_NeverFormats(); void Test_GetConfig_IsSafeWhileReconfiguring(); void Test_GetInstance_ReturnsTheSameLogger(); diff --git a/tests/tests/Test_ASWLog_SyslogLog.cpp b/tests/tests/Test_ASWLog_SyslogLog.cpp index 85f1ca9..9f26caf 100644 --- a/tests/tests/Test_ASWLog_SyslogLog.cpp +++ b/tests/tests/Test_ASWLog_SyslogLog.cpp @@ -183,14 +183,6 @@ class TCapturingSyslogLog final : public ASWLog::TASWSyslogLog TTest_ASWLog_SyslogLog::TTest_ASWLog_SyslogLog() : inherited("ASWLog_SyslogLog_Tests") { - RegisterTest(&TTest_ASWLog_SyslogLog::Test_GetInstance_ReturnsTheSameLogger, "GetInstance_ReturnsTheSameLogger"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_HandleCrash_SendsTheFormattedCrashLineOnly, "HandleCrash_SendsTheFormattedCrashLineOnly"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_Initialize_OpensSyslogWithTheIdentAndFacility, "Initialize_OpensSyslogWithTheIdentAndFacility"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_Linux_SendsToTheRealSyslog, "Linux_SendsToTheRealSyslog"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_Send_FollowsTheMultilineMode, "Send_FollowsTheMultilineMode"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_Send_MapsEachLevelToAPriority, "Send_MapsEachLevelToAPriority"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_Send_StripsOnlyTheLineEnding, "Send_StripsOnlyTheLineEnding"); - RegisterTest(&TTest_ASWLog_SyslogLog::Test_ShouldLog_FollowsThePlatform, "ShouldLog_FollowsThePlatform"); } //--------------------------------------------------------------------------- TTest_ASWLog_SyslogLog::~TTest_ASWLog_SyslogLog() @@ -218,7 +210,7 @@ void TTest_ASWLog_SyslogLog::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_GetInstance_ReturnsTheSameLogger() +ASW_TEST(TTest_ASWLog_SyslogLog, GetInstance_ReturnsTheSameLogger) { // Act auto& first = ASWLog::TASWSyslogLog::GetInstance(); @@ -228,7 +220,7 @@ void TTest_ASWLog_SyslogLog::Test_GetInstance_ReturnsTheSameLogger() CheckSame(&first, &second, "GetInstance() should always return the same logger"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_HandleCrash_SendsTheFormattedCrashLineOnly() +ASW_TEST(TTest_ASWLog_SyslogLog, HandleCrash_SendsTheFormattedCrashLineOnly) { // Arrange TCapturingSyslogLog log; @@ -244,7 +236,7 @@ void TTest_ASWLog_SyslogLog::Test_HandleCrash_SendsTheFormattedCrashLineOnly() CheckEquals(std::string("[CRITICAL]: Crash: test crash"), log.Messages[0].Text, "The crash line should be sent without its line ending"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_Initialize_OpensSyslogWithTheIdentAndFacility() +ASW_TEST(TTest_ASWLog_SyslogLog, Initialize_OpensSyslogWithTheIdentAndFacility) { // Arrange TCapturingSyslogLog log; @@ -272,7 +264,7 @@ void TTest_ASWLog_SyslogLog::Test_Initialize_OpensSyslogWithTheIdentAndFacility( CheckEquals(ASWLog::SyslogFacility::Local3, log.Opens[1].Facility, "Reconfigure should pass the new facility"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_Linux_SendsToTheRealSyslog() +ASW_TEST(TTest_ASWLog_SyslogLog, Linux_SendsToTheRealSyslog) { #if defined(_WIN32) Skip("Only Linux has a syslog"); @@ -304,7 +296,7 @@ void TTest_ASWLog_SyslogLog::Test_Linux_SendsToTheRealSyslog() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_Send_FollowsTheMultilineMode() +ASW_TEST(TTest_ASWLog_SyslogLog, Send_FollowsTheMultilineMode) { // Arrange TCapturingSyslogLog log; @@ -328,7 +320,7 @@ void TTest_ASWLog_SyslogLog::Test_Send_FollowsTheMultilineMode() CheckEquals(std::string("[INFO]: first\\r\\nsecond"), log.Messages[2].Text, "Escape should write \\r and \\n"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_Send_MapsEachLevelToAPriority() +ASW_TEST(TTest_ASWLog_SyslogLog, Send_MapsEachLevelToAPriority) { // Arrange TCapturingSyslogLog log; @@ -366,7 +358,7 @@ void TTest_ASWLog_SyslogLog::Test_Send_MapsEachLevelToAPriority() CheckEquals((3 << 3) | 6, log.Messages[8].Priority, "The facility should be sent with each message (LOG_DAEMON | LOG_INFO)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_Send_StripsOnlyTheLineEnding() +ASW_TEST(TTest_ASWLog_SyslogLog, Send_StripsOnlyTheLineEnding) { // Arrange TCapturingSyslogLog log; @@ -391,7 +383,7 @@ void TTest_ASWLog_SyslogLog::Test_Send_StripsOnlyTheLineEnding() CheckEquals(std::string("[INFO]: ends with LF\n"), log.Messages[4].Text, "With CRLF endings, the message's own LF should stay"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_SyslogLog::Test_ShouldLog_FollowsThePlatform() +ASW_TEST(TTest_ASWLog_SyslogLog, ShouldLog_FollowsThePlatform) { #if defined(_WIN32) // Arrange: a startup and a shutdown line too, each of which would be formatted diff --git a/tests/tests/Test_ASWLog_SyslogLog.h b/tests/tests/Test_ASWLog_SyslogLog.h index 17bfb65..9944d64 100644 --- a/tests/tests/Test_ASWLog_SyslogLog.h +++ b/tests/tests/Test_ASWLog_SyslogLog.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_SyslogLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_SyslogLog : public TTestGroupBase +class TTest_ASWLog_SyslogLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_GetInstance_ReturnsTheSameLogger(); void Test_HandleCrash_SendsTheFormattedCrashLineOnly(); void Test_Initialize_OpensSyslogWithTheIdentAndFacility(); diff --git a/tests/tests/Test_ASWLog_TextLogBase.cpp b/tests/tests/Test_ASWLog_TextLogBase.cpp index cbe15a7..90d0377 100644 --- a/tests/tests/Test_ASWLog_TextLogBase.cpp +++ b/tests/tests/Test_ASWLog_TextLogBase.cpp @@ -402,49 +402,6 @@ bool WaitUntil(const std::function& condition) TTest_ASWLog_TextLogBase::TTest_ASWLog_TextLogBase() : inherited("ASWLog_TextLogBase_Tests") { - RegisterTest(&TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheCommandLineWhenAsked, "ApplicationInfo_WritesTheCommandLineWhenAsked"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheConfiguredVersion, "ApplicationInfo_WritesTheConfiguredVersion"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheExecutablesFileVersionByDefault, "ApplicationInfo_WritesTheExecutablesFileVersionByDefault"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_BacktraceIsTakenWhenTheTriggerIsLogged, "Async_BacktraceIsTakenWhenTheTriggerIsLogged"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_BlockWaitsForRoomInTheQueue, "Async_BlockWaitsForRoomInTheQueue"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_CallReturnsBeforeTheEntryIsWritten, "Async_CallReturnsBeforeTheEntryIsWritten"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_DestructorWritesQueuedEntriesBeforeTheShutdownLine, "Async_DestructorWritesQueuedEntriesBeforeTheShutdownLine"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_DropNewestReportsAndMarksDroppedEntries, "Async_DropNewestReportsAndMarksDroppedEntries"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_EntriesKeepTheirOrderPerThread, "Async_EntriesKeepTheirOrderPerThread"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_EntryAtWaitAtLevelIsNeverDropped, "Async_EntryAtWaitAtLevelIsNeverDropped"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_EntryAtWaitAtLevelReturnsOnceWrittenAndFlushed, "Async_EntryAtWaitAtLevelReturnsOnceWrittenAndFlushed"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_FlushWaitsForQueuedEntries, "Async_FlushWaitsForQueuedEntries"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_LoggingFromOnLogEntryDoesNotWait, "Async_LoggingFromOnLogEntryDoesNotWait"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_OnLogEntryRunsOnTheWorkerWithItsOwnCopy, "Async_OnLogEntryRunsOnTheWorkerWithItsOwnCopy"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_ReconfigureToSyncWritesQueuedEntriesFirst, "Async_ReconfigureToSyncWritesQueuedEntriesFirst"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Async_SwitchingOnAndOffKeepsEachThreadsOrder, "Async_SwitchingOnAndOffKeepsEachThreadsOrder"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Backtrace_IsFormattedAndWrittenBeforeTheTrigger, "Backtrace_IsFormattedAndWrittenBeforeTheTrigger"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Finalize_WritesShutdownLineFromDestructor, "Finalize_WritesShutdownLineFromDestructor"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Flush_CallsHookAndReturnsItsResult, "Flush_CallsHookAndReturnsItsResult"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Flush_ThrowingHookDoesNotEscape, "Flush_ThrowingHookDoesNotEscape"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Formatter_FormatsEveryFileLine, "Formatter_FormatsEveryFileLine"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Initialize_ThrowingFormatterStillInitializes, "Initialize_ThrowingFormatterStillInitializes"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Initialize_WritesLoggerVersionAfterTheBanner, "Initialize_WritesLoggerVersionAfterTheBanner"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Initialize_WritesStartupLinesThenCallsAfterEntry, "Initialize_WritesStartupLinesThenCallsAfterEntry"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Log_AtLevelOffIsNeverWritten, "Log_AtLevelOffIsNeverWritten"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Log_DroppedWhenNotReadyOrNotPrepared, "Log_DroppedWhenNotReadyOrNotPrepared"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Log_FormatsFiltersAndCallsAfterEntry, "Log_FormatsFiltersAndCallsAfterEntry"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Log_MinimumLevelOffAllowsOnlyForcedEntries, "Log_MinimumLevelOffAllowsOnlyForcedEntries"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Log_ThrowingWriteDoesNotEscape, "Log_ThrowingWriteDoesNotEscape"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_LogRaw_FormatterCanFormatRawEntries, "LogRaw_FormatterCanFormatRawEntries"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_LogRaw_WritesMessageAsIs, "LogRaw_WritesMessageAsIs"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Multiline_AppliesToEveryFormattersLine, "Multiline_AppliesToEveryFormattersLine"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Multiline_EscapeKeepsEachEntryOnOneLine, "Multiline_EscapeKeepsEachEntryOnOneLine"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Multiline_LogRawStaysAsIs, "Multiline_LogRawStaysAsIs"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Multiline_PreserveWritesLineBreaksAsTheyAre, "Multiline_PreserveWritesLineBreaksAsTheyAre"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_RunsOnEveryLoggingThread, "OnBeforeWrite_RunsOnEveryLoggingThread"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_RunsOutsideTheLockBeforeQueuing, "OnBeforeWrite_RunsOutsideTheLockBeforeQueuing"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_SkipsTheLoggersOwnLines, "OnBeforeWrite_SkipsTheLoggersOwnLines"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_OnLogEntry_CallbackCanReconfigureTheLogger, "OnLogEntry_CallbackCanReconfigureTheLogger"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Reconfigure_AppliesNewConfigButKeepsLevel, "Reconfigure_AppliesNewConfigButKeepsLevel"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_Reconfigure_IsSafeWhileOtherThreadsLog, "Reconfigure_IsSafeWhileOtherThreadsLog"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_ReportErrorUnlocked_ReportsAfterTheLockIsReleased, "ReportErrorUnlocked_ReportsAfterTheLockIsReleased"); - RegisterTest(&TTest_ASWLog_TextLogBase::Test_SetEnabled_FalseWritesNothing, "SetEnabled_FalseWritesNothing"); } //--------------------------------------------------------------------------- TTest_ASWLog_TextLogBase::~TTest_ASWLog_TextLogBase() @@ -479,7 +436,7 @@ void TTest_ASWLog_TextLogBase::TearDown_Test(ITestCase& testCase) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheCommandLineWhenAsked() +ASW_TEST(TTest_ASWLog_TextLogBase, ApplicationInfo_WritesTheCommandLineWhenAsked) { // Arrange TMemoryOutput defaultOutput; @@ -507,7 +464,7 @@ void TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheCommandLineWhenAske } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheConfiguredVersion() +ASW_TEST(TTest_ASWLog_TextLogBase, ApplicationInfo_WritesTheConfiguredVersion) { // Arrange TMemoryOutput output; @@ -530,7 +487,7 @@ void TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheConfiguredVersion() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheExecutablesFileVersionByDefault() +ASW_TEST(TTest_ASWLog_TextLogBase, ApplicationInfo_WritesTheExecutablesFileVersionByDefault) { // Arrange: no configured version. The test executable has a version resource in some builds (e.g. the VCL GUI // runner's 1.0.0.0) and none in others (e.g. MinGW's), where no version is written. @@ -560,7 +517,7 @@ void TTest_ASWLog_TextLogBase::Test_ApplicationInfo_WritesTheExecutablesFileVers } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_BlockWaitsForRoomInTheQueue() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_BlockWaitsForRoomInTheQueue) { // Arrange: a queue of one entry TMemoryOutput output; @@ -596,7 +553,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_BlockWaitsForRoomInTheQueue() CheckTrue(output.Lines == expected, "Every entry should be written, in order"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_BacktraceIsTakenWhenTheTriggerIsLogged() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_BacktraceIsTakenWhenTheTriggerIsLogged) { // Arrange: the error doesn't wait, so the test can log on while the worker is held TMemoryOutput output; @@ -632,7 +589,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_BacktraceIsTakenWhenTheTriggerIsLogged CheckEquals(std::string("[DEBUG]: debug_2\n"), output.Lines[6], "DumpBacktrace() should write it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_CallReturnsBeforeTheEntryIsWritten() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_CallReturnsBeforeTheEntryIsWritten) { // Arrange TMemoryOutput output; @@ -661,7 +618,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_CallReturnsBeforeTheEntryIsWritten() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_DestructorWritesQueuedEntriesBeforeTheShutdownLine() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_DestructorWritesQueuedEntriesBeforeTheShutdownLine) { // Arrange TMemoryOutput output; @@ -689,7 +646,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_DestructorWritesQueuedEntriesBeforeThe } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_DropNewestReportsAndMarksDroppedEntries() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_DropNewestReportsAndMarksDroppedEntries) { // Arrange: a queue of two entries TMemoryOutput output; @@ -733,7 +690,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_DropNewestReportsAndMarksDroppedEntrie } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_EntriesKeepTheirOrderPerThread() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_EntriesKeepTheirOrderPerThread) { // Arrange TMemoryOutput output; @@ -763,7 +720,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_EntriesKeepTheirOrderPerThread() CheckEquals(0, CountOutOfOrderEntries(output.Lines, ThreadCount), "Each thread's entries should keep their order"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_EntryAtWaitAtLevelIsNeverDropped() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_EntryAtWaitAtLevelIsNeverDropped) { // Arrange: a queue of one entry that drops entries below the wait level TMemoryOutput output; @@ -803,7 +760,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_EntryAtWaitAtLevelIsNeverDropped() CheckTrue(output.Lines == expected, "Only the Info entry should be dropped, and the Error entry written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_EntryAtWaitAtLevelReturnsOnceWrittenAndFlushed() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_EntryAtWaitAtLevelReturnsOnceWrittenAndFlushed) { // Arrange TMemoryOutput output; @@ -834,7 +791,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_EntryAtWaitAtLevelReturnsOnceWrittenAn CheckGreaterThanOrEqual(output.FlushCount, 1, "The Error entry should be flushed before its call returns"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_FlushWaitsForQueuedEntries() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_FlushWaitsForQueuedEntries) { // Arrange: after writing entry_1, the worker pauses outside the lock (see PauseAfterFirstEntry()) TMemoryOutput output; @@ -868,7 +825,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_FlushWaitsForQueuedEntries() CheckEquals(2, output.LineCountAtLastFlush, "Flush should flush after both queued entries are written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_LoggingFromOnLogEntryDoesNotWait() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_LoggingFromOnLogEntryDoesNotWait) { // Arrange: OnLogEntry, on the worker, logs an Error entry (which a caller waits for) into a full queue TMemoryOutput output; @@ -902,7 +859,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_LoggingFromOnLogEntryDoesNotWait() CheckTrue(output.Lines == expected, "The entries logged from the callback should be written after it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_OnLogEntryRunsOnTheWorkerWithItsOwnCopy() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_OnLogEntryRunsOnTheWorkerWithItsOwnCopy) { // Arrange TMemoryOutput output; @@ -946,7 +903,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_OnLogEntryRunsOnTheWorkerWithItsOwnCop } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_ReconfigureToSyncWritesQueuedEntriesFirst() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_ReconfigureToSyncWritesQueuedEntriesFirst) { // Arrange: after writing entry_1, the worker pauses outside the lock (see PauseAfterFirstEntry()) TMemoryOutput output; @@ -982,7 +939,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_ReconfigureToSyncWritesQueuedEntriesFi CheckTrue(output.WriteThreadIds[2] == std::this_thread::get_id(), "After the switch, the caller should write its entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Async_SwitchingOnAndOffKeepsEachThreadsOrder() +ASW_TEST(TTest_ASWLog_TextLogBase, Async_SwitchingOnAndOffKeepsEachThreadsOrder) { // Arrange TMemoryOutput output; @@ -1025,7 +982,7 @@ void TTest_ASWLog_TextLogBase::Test_Async_SwitchingOnAndOffKeepsEachThreadsOrder "Each thread's entries should keep their order, with none missing, across the switches"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Backtrace_IsFormattedAndWrittenBeforeTheTrigger() +ASW_TEST(TTest_ASWLog_TextLogBase, Backtrace_IsFormattedAndWrittenBeforeTheTrigger) { // Arrange TMemoryOutput output; @@ -1048,7 +1005,7 @@ void TTest_ASWLog_TextLogBase::Test_Backtrace_IsFormattedAndWrittenBeforeTheTrig CheckTrue(output.Lines == expected, "The kept entries should be formatted and written just before the error"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Finalize_WritesShutdownLineFromDestructor() +ASW_TEST(TTest_ASWLog_TextLogBase, Finalize_WritesShutdownLineFromDestructor) { // Arrange TMemoryOutput output; @@ -1072,7 +1029,7 @@ void TTest_ASWLog_TextLogBase::Test_Finalize_WritesShutdownLineFromDestructor() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Flush_CallsHookAndReturnsItsResult() +ASW_TEST(TTest_ASWLog_TextLogBase, Flush_CallsHookAndReturnsItsResult) { // Arrange: called through the interface, as generic code would TMemoryOutput output; @@ -1097,7 +1054,7 @@ void TTest_ASWLog_TextLogBase::Test_Flush_CallsHookAndReturnsItsResult() CheckEquals(3, output.FlushCount, "Each Flush() should call FlushUnlocked() once"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Flush_ThrowingHookDoesNotEscape() +ASW_TEST(TTest_ASWLog_TextLogBase, Flush_ThrowingHookDoesNotEscape) { // Arrange TMemoryOutput output; @@ -1116,7 +1073,7 @@ void TTest_ASWLog_TextLogBase::Test_Flush_ThrowingHookDoesNotEscape() CheckEquals(1, output.Lines.size(), "Logging should continue after a failed flush (the lock is released)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Formatter_FormatsEveryFileLine() +ASW_TEST(TTest_ASWLog_TextLogBase, Formatter_FormatsEveryFileLine) { // Arrange const auto logPath = TestTempDir / "textlogbase.log"; @@ -1152,7 +1109,7 @@ void TTest_ASWLog_TextLogBase::Test_Formatter_FormatsEveryFileLine() CheckEquals(std::string("INFO|hello\n"), callbackLines[0], "OnLogEntry should get the line in the formatter's layout"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Initialize_ThrowingFormatterStillInitializes() +ASW_TEST(TTest_ASWLog_TextLogBase, Initialize_ThrowingFormatterStillInitializes) { // Arrange: a startup line goes through a formatter that throws TMemoryOutput output; @@ -1184,7 +1141,7 @@ void TTest_ASWLog_TextLogBase::Test_Initialize_ThrowingFormatterStillInitializes "The skipped startup lines and the dropped entry should be reported"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Initialize_WritesLoggerVersionAfterTheBanner() +ASW_TEST(TTest_ASWLog_TextLogBase, Initialize_WritesLoggerVersionAfterTheBanner) { // Arrange TMemoryOutput output; @@ -1209,7 +1166,7 @@ void TTest_ASWLog_TextLogBase::Test_Initialize_WritesLoggerVersionAfterTheBanner } } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Initialize_WritesStartupLinesThenCallsAfterEntry() +ASW_TEST(TTest_ASWLog_TextLogBase, Initialize_WritesStartupLinesThenCallsAfterEntry) { // Arrange TMemoryOutput output; @@ -1235,7 +1192,7 @@ void TTest_ASWLog_TextLogBase::Test_Initialize_WritesStartupLinesThenCallsAfterE CheckEquals(1, output.AfterEntryCount, "Initialize should call AfterEntryUnlocked once, after the startup lines"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Log_AtLevelOffIsNeverWritten() +ASW_TEST(TTest_ASWLog_TextLogBase, Log_AtLevelOffIsNeverWritten) { // Arrange TMemoryOutput output; @@ -1266,7 +1223,7 @@ void TTest_ASWLog_TextLogBase::Test_Log_AtLevelOffIsNeverWritten() "An entry at Off should be dropped before reaching the logger's output"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Log_DroppedWhenNotReadyOrNotPrepared() +ASW_TEST(TTest_ASWLog_TextLogBase, Log_DroppedWhenNotReadyOrNotPrepared) { // Arrange TMemoryOutput output; @@ -1302,7 +1259,7 @@ void TTest_ASWLog_TextLogBase::Test_Log_DroppedWhenNotReadyOrNotPrepared() "AfterEntryUnlocked should be skipped when EnsureReadyUnlocked fails, but called when only PrepareWriteUnlocked drops the line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Log_FormatsFiltersAndCallsAfterEntry() +ASW_TEST(TTest_ASWLog_TextLogBase, Log_FormatsFiltersAndCallsAfterEntry) { // Arrange TMemoryOutput output; @@ -1331,7 +1288,7 @@ void TTest_ASWLog_TextLogBase::Test_Log_FormatsFiltersAndCallsAfterEntry() CheckEquals(afterEntryCountAtStart + 2, output.AfterEntryCount, "AfterEntryUnlocked should be called once per entry that reached the logger"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Log_MinimumLevelOffAllowsOnlyForcedEntries() +ASW_TEST(TTest_ASWLog_TextLogBase, Log_MinimumLevelOffAllowsOnlyForcedEntries) { // Arrange TMemoryOutput output; @@ -1366,7 +1323,7 @@ void TTest_ASWLog_TextLogBase::Test_Log_MinimumLevelOffAllowsOnlyForcedEntries() CheckEquals(0, callbackCount, "With OnLogEntryMinimumLevel at Off, OnLogEntry should never fire"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Log_ThrowingWriteDoesNotEscape() +ASW_TEST(TTest_ASWLog_TextLogBase, Log_ThrowingWriteDoesNotEscape) { // Arrange TMemoryOutput output; @@ -1394,7 +1351,7 @@ void TTest_ASWLog_TextLogBase::Test_Log_ThrowingWriteDoesNotEscape() "Each dropped entry should be reported"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_LogRaw_FormatterCanFormatRawEntries() +ASW_TEST(TTest_ASWLog_TextLogBase, LogRaw_FormatterCanFormatRawEntries) { // Arrange: a synchronous and an asynchronous logger whose formatter formats raw entries too TMemoryOutput syncOutput; @@ -1428,7 +1385,7 @@ void TTest_ASWLog_TextLogBase::Test_LogRaw_FormatterCanFormatRawEntries() CheckTrue(asyncOutput.EndsLine == std::vector{ true, true, true }, "A queued formatted raw entry should end its line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_LogRaw_WritesMessageAsIs() +ASW_TEST(TTest_ASWLog_TextLogBase, LogRaw_WritesMessageAsIs) { // Arrange TMemoryOutput output; @@ -1445,7 +1402,7 @@ void TTest_ASWLog_TextLogBase::Test_LogRaw_WritesMessageAsIs() CheckTrue(output.EndsLine == std::vector{ false, false }, "A raw entry doesn't end its line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Multiline_AppliesToEveryFormattersLine() +ASW_TEST(TTest_ASWLog_TextLogBase, Multiline_AppliesToEveryFormattersLine) { // Arrange: Indent with CRLF endings, for the built-in layout, a pattern, a user's own formatter and JSON auto config = MakeQuietConfig(); @@ -1477,7 +1434,7 @@ void TTest_ASWLog_TextLogBase::Test_Multiline_AppliesToEveryFormattersLine() "A JSON line has no line break to indent"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Multiline_EscapeKeepsEachEntryOnOneLine() +ASW_TEST(TTest_ASWLog_TextLogBase, Multiline_EscapeKeepsEachEntryOnOneLine) { // Arrange: a logger that starts with Preserve and is reconfigured to Escape, and an asynchronous one TMemoryOutput output; @@ -1512,7 +1469,7 @@ void TTest_ASWLog_TextLogBase::Test_Multiline_EscapeKeepsEachEntryOnOneLine() CheckTrue(asyncOutput.Lines == std::vector{ expected[1] }, "A queued line's line breaks should be escaped"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Multiline_LogRawStaysAsIs() +ASW_TEST(TTest_ASWLog_TextLogBase, Multiline_LogRawStaysAsIs) { // Arrange: Indent, without and with a formatter that formats raw entries TMemoryOutput output; @@ -1537,7 +1494,7 @@ void TTest_ASWLog_TextLogBase::Test_Multiline_LogRawStaysAsIs() "A raw entry the formatter formats should be indented like any formatted line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Multiline_PreserveWritesLineBreaksAsTheyAre() +ASW_TEST(TTest_ASWLog_TextLogBase, Multiline_PreserveWritesLineBreaksAsTheyAre) { // Arrange: the default mode, with CRLF endings TMemoryOutput output; @@ -1553,7 +1510,7 @@ void TTest_ASWLog_TextLogBase::Test_Multiline_PreserveWritesLineBreaksAsTheyAre( CheckTrue(output.Lines == std::vector{ "[INFO]: a\r\nb\nc\rd\n\r\n" }, "The message should be written as it is"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_RunsOnEveryLoggingThread() +ASW_TEST(TTest_ASWLog_TextLogBase, OnBeforeWrite_RunsOnEveryLoggingThread) { // Arrange: a synchronous and an asynchronous logger whose hook changes the message and a field of each entry, and // drops every fourth, while several threads log (for ThreadSanitizer) @@ -1608,7 +1565,7 @@ void TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_RunsOnEveryLoggingThread() CheckTrue(asyncOutput.Lines == expected, "Every kept queued entry should be written as the hook changed it"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_RunsOutsideTheLockBeforeQueuing() +ASW_TEST(TTest_ASWLog_TextLogBase, OnBeforeWrite_RunsOutsideTheLockBeforeQueuing) { // Arrange: a hook that redacts a token in the message and the user field, for a synchronous and an asynchronous // logger, both with OnLogEntry @@ -1682,7 +1639,7 @@ void TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_RunsOutsideTheLockBeforeQueuin CheckEquals(expected, asyncSeenLine, "The asynchronous OnLogEntry should get the changed line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_SkipsTheLoggersOwnLines() +ASW_TEST(TTest_ASWLog_TextLogBase, OnBeforeWrite_SkipsTheLoggersOwnLines) { // Arrange: a hook that drops every entry, with a startup banner and the shutdown line TMemoryOutput output; @@ -1709,7 +1666,7 @@ void TTest_ASWLog_TextLogBase::Test_OnBeforeWrite_SkipsTheLoggersOwnLines() CheckContains(output.Lines[1], "Logger shutdown", "The shutdown line should be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_OnLogEntry_CallbackCanReconfigureTheLogger() +ASW_TEST(TTest_ASWLog_TextLogBase, OnLogEntry_CallbackCanReconfigureTheLogger) { // Arrange: a callback that replaces the config it belongs to, e.g. to turn itself off after the first error. The // running callback (and the state it captured) must stay alive until it returns, and calling back into the logger @@ -1738,7 +1695,7 @@ void TTest_ASWLog_TextLogBase::Test_OnLogEntry_CallbackCanReconfigureTheLogger() "Both entries should be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Reconfigure_AppliesNewConfigButKeepsLevel() +ASW_TEST(TTest_ASWLog_TextLogBase, Reconfigure_AppliesNewConfigButKeepsLevel) { // Arrange TMemoryOutput output; @@ -1780,7 +1737,7 @@ void TTest_ASWLog_TextLogBase::Test_Reconfigure_AppliesNewConfigButKeepsLevel() "The new config should be kept when ReconfigureUnlocked() fails"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_Reconfigure_IsSafeWhileOtherThreadsLog() +ASW_TEST(TTest_ASWLog_TextLogBase, Reconfigure_IsSafeWhileOtherThreadsLog) { // Arrange: one thread keeps switching between configs that differ in the line layout, the formatter and the // callback, while others log. Run under ThreadSanitizer (CI) to find data races. @@ -1853,7 +1810,7 @@ void TTest_ASWLog_TextLogBase::Test_Reconfigure_IsSafeWhileOtherThreadsLog() "OnLogEntry should be called at most once per entry"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_ReportErrorUnlocked_ReportsAfterTheLockIsReleased() +ASW_TEST(TTest_ASWLog_TextLogBase, ReportErrorUnlocked_ReportsAfterTheLockIsReleased) { // Arrange: WriteLineUnlocked() reports a failure while m_Mutex is held TMemoryOutput output; @@ -1881,7 +1838,7 @@ void TTest_ASWLog_TextLogBase::Test_ReportErrorUnlocked_ReportsAfterTheLockIsRel CheckTrue(output.Lines == std::vector{ "[INFO]: first\n", "second" }, "The entries should still be written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_TextLogBase::Test_SetEnabled_FalseWritesNothing() +ASW_TEST(TTest_ASWLog_TextLogBase, SetEnabled_FalseWritesNothing) { // Arrange TMemoryOutput output; diff --git a/tests/tests/Test_ASWLog_TextLogBase.h b/tests/tests/Test_ASWLog_TextLogBase.h index 9bd407c..1de0a48 100644 --- a/tests/tests/Test_ASWLog_TextLogBase.h +++ b/tests/tests/Test_ASWLog_TextLogBase.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_TextLogBase /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_TextLogBase : public TTestGroupBase +class TTest_ASWLog_TextLogBase : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_ApplicationInfo_WritesTheCommandLineWhenAsked(); void Test_ApplicationInfo_WritesTheConfiguredVersion(); void Test_ApplicationInfo_WritesTheExecutablesFileVersionByDefault(); diff --git a/tests/tests/Test_ASWLog_Types.cpp b/tests/tests/Test_ASWLog_Types.cpp index a4bb888..571f63f 100644 --- a/tests/tests/Test_ASWLog_Types.cpp +++ b/tests/tests/Test_ASWLog_Types.cpp @@ -64,31 +64,6 @@ std::vector DescribeFields(const ASWLog::TASWPendingEntry& entry) TTest_ASWLog_Types::TTest_ASWLog_Types() : inherited("ASWLog_Types_Tests") { - RegisterTest(&TTest_ASWLog_Types::Test_AsyncOverflowPolicy_FromString, "AsyncOverflowPolicy_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_AsyncOverflowPolicy_ToString, "AsyncOverflowPolicy_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_ColorMode_FromString, "ColorMode_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_ColorMode_ToString, "ColorMode_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_ErrorKind_ToString, "ErrorKind_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_FlushMode_FromString, "FlushMode_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_FlushMode_ToString, "FlushMode_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_Level_FromString, "Level_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_Level_ToString, "Level_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_LineEnding_FromString, "LineEnding_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_LineEnding_ToString, "LineEnding_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_LogError_ToString, "LogError_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_MultilineMode_FromString, "MultilineMode_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_MultilineMode_ToString, "MultilineMode_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_PendingEntry_ChangingFieldsWhileVisitingIsSafe, "PendingEntry_ChangingFieldsWhileVisitingIsSafe"); - RegisterTest(&TTest_ASWLog_Types::Test_PendingEntry_FindsFieldsOfTheEntryAndItsScopes, "PendingEntry_FindsFieldsOfTheEntryAndItsScopes"); - RegisterTest(&TTest_ASWLog_Types::Test_PendingEntry_RemoveFieldRemovesItForThisEntry, "PendingEntry_RemoveFieldRemovesItForThisEntry"); - RegisterTest(&TTest_ASWLog_Types::Test_PendingEntry_SetFieldReplacesOrAddsACopy, "PendingEntry_SetFieldReplacesOrAddsACopy"); - RegisterTest(&TTest_ASWLog_Types::Test_PendingEntry_SetMessageOwnsTheText, "PendingEntry_SetMessageOwnsTheText"); - RegisterTest(&TTest_ASWLog_Types::Test_SyslogFacility_FromString, "SyslogFacility_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_SyslogFacility_ToString, "SyslogFacility_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_TimePrecision_FromString, "TimePrecision_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_TimePrecision_ToString, "TimePrecision_ToString"); - RegisterTest(&TTest_ASWLog_Types::Test_TimeZone_FromString, "TimeZone_FromString"); - RegisterTest(&TTest_ASWLog_Types::Test_TimeZone_ToString, "TimeZone_ToString"); } //--------------------------------------------------------------------------- TTest_ASWLog_Types::~TTest_ASWLog_Types() @@ -115,7 +90,7 @@ void TTest_ASWLog_Types::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_AsyncOverflowPolicy_FromString() +ASW_TEST(TTest_ASWLog_Types, AsyncOverflowPolicy_FromString) { // Arrange const auto block = ASWLog::AsyncOverflowPolicy_FromString("BLOCK"); @@ -133,14 +108,14 @@ void TTest_ASWLog_Types::Test_AsyncOverflowPolicy_FromString() CheckEquals(ASWLog::AsyncOverflowPolicy::DropNewest, *dropNewestAlias_mixedCase, "DropNewest should map to DropNewest"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_AsyncOverflowPolicy_ToString() +ASW_TEST(TTest_ASWLog_Types, AsyncOverflowPolicy_ToString) { // Arrange / Act / Assert CheckEquals(std::string("BLOCK"), std::string(ASWLog::AsyncOverflowPolicy_ToString(ASWLog::AsyncOverflowPolicy::Block)), "Block should stringify as BLOCK"); CheckEquals(std::string("DROP_NEWEST"), std::string(ASWLog::AsyncOverflowPolicy_ToString(ASWLog::AsyncOverflowPolicy::DropNewest)), "DropNewest should stringify as DROP_NEWEST"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_ColorMode_FromString() +ASW_TEST(TTest_ASWLog_Types, ColorMode_FromString) { // Arrange const auto autoMode = ASWLog::ColorMode_FromString("AUTO"); @@ -161,7 +136,7 @@ void TTest_ASWLog_Types::Test_ColorMode_FromString() CheckEquals(ASWLog::ColorMode::Never, *never_mixedCase, "Never should map to Never"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_ColorMode_ToString() +ASW_TEST(TTest_ASWLog_Types, ColorMode_ToString) { // Arrange const std::string autoMode = std::string(ASWLog::ColorMode_ToString(ASWLog::ColorMode::Auto)); @@ -174,7 +149,7 @@ void TTest_ASWLog_Types::Test_ColorMode_ToString() CheckEquals(std::string("NEVER"), never, "Never should stringify as NEVER"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_ErrorKind_ToString() +ASW_TEST(TTest_ASWLog_Types, ErrorKind_ToString) { // Arrange / Act / Assert CheckEquals(std::string("OPEN_FAILED"), std::string(ASWLog::ErrorKind_ToString(ASWLog::ErrorKind::OpenFailed)), "OpenFailed should stringify as OPEN_FAILED"); @@ -190,7 +165,7 @@ void TTest_ASWLog_Types::Test_ErrorKind_ToString() CheckEquals(static_cast(ASWLog::ErrorKind::InvalidSetting) + 1, ASWLog::ErrorKindCount, "ErrorKindCount should count every kind (InvalidSetting is the last)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_FlushMode_FromString() +ASW_TEST(TTest_ASWLog_Types, FlushMode_FromString) { // Arrange const auto everyWrite = ASWLog::FlushMode_FromString("EVERY_WRITE"); @@ -215,7 +190,7 @@ void TTest_ASWLog_Types::Test_FlushMode_FromString() CheckEquals(ASWLog::FlushMode::Periodic, *periodic, "PERIODIC should map to Periodic"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_FlushMode_ToString() +ASW_TEST(TTest_ASWLog_Types, FlushMode_ToString) { // Arrange const std::string everyWrite = std::string(ASWLog::FlushMode_ToString(ASWLog::FlushMode::EveryWrite)); @@ -230,7 +205,7 @@ void TTest_ASWLog_Types::Test_FlushMode_ToString() CheckEquals(std::string("PERIODIC"), periodic, "PERIODIC should stringify as PERIODIC"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_Level_FromString() +ASW_TEST(TTest_ASWLog_Types, Level_FromString) { // Arrange const auto trace = ASWLog::Level_FromString("TRACE"); @@ -268,7 +243,7 @@ void TTest_ASWLog_Types::Test_Level_FromString() CheckTrue(offAlias.has_value() && *offAlias == ASWLog::Level::Off, "none (NONE alias, any case) should map to Off"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_Level_ToString() +ASW_TEST(TTest_ASWLog_Types, Level_ToString) { // Arrange const std::string trace = std::string(ASWLog::Level_ToString(ASWLog::Level::Trace)); @@ -291,7 +266,7 @@ void TTest_ASWLog_Types::Test_Level_ToString() "LevelCount should count the severity levels, which come before Off"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_LineEnding_FromString() +ASW_TEST(TTest_ASWLog_Types, LineEnding_FromString) { // Arrange const auto lf = ASWLog::LineEnding_FromString("LF"); @@ -314,7 +289,7 @@ void TTest_ASWLog_Types::Test_LineEnding_FromString() CheckFalse(ASWLog::LineEnding_FromString("CR").has_value(), "An unknown name should not parse"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_LineEnding_ToString() +ASW_TEST(TTest_ASWLog_Types, LineEnding_ToString) { // Arrange const std::string lf = std::string(ASWLog::LineEnding_ToString(ASWLog::LineEnding::LF)); @@ -325,7 +300,7 @@ void TTest_ASWLog_Types::Test_LineEnding_ToString() CheckEquals(std::string("CRLF"), crlf, "CRLF should stringify as CRLF"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_LogError_ToString() +ASW_TEST(TTest_ASWLog_Types, LogError_ToString) { // Arrange ASWLog::TASWLogError messageOnly; @@ -349,7 +324,7 @@ void TTest_ASWLog_Types::Test_LogError_ToString() CheckEquals("OPEN_FAILED: Couldn't open the log file 'logs/app.log': " + code.message() + " (3 more not reported)", everyPartText, "Every part should be in the line"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_MultilineMode_FromString() +ASW_TEST(TTest_ASWLog_Types, MultilineMode_FromString) { // Arrange const auto preserve = ASWLog::MultilineMode_FromString("PRESERVE"); @@ -364,7 +339,7 @@ void TTest_ASWLog_Types::Test_MultilineMode_FromString() CheckFalse(unknown.has_value(), "An unknown mode should not parse"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_MultilineMode_ToString() +ASW_TEST(TTest_ASWLog_Types, MultilineMode_ToString) { // Act & Assert CheckEquals(std::string("PRESERVE"), std::string(ASWLog::MultilineMode_ToString(ASWLog::MultilineMode::Preserve)), "Preserve should stringify as PRESERVE"); @@ -372,7 +347,7 @@ void TTest_ASWLog_Types::Test_MultilineMode_ToString() CheckEquals(std::string("ESCAPE"), std::string(ASWLog::MultilineMode_ToString(ASWLog::MultilineMode::Escape)), "Escape should stringify as ESCAPE"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_PendingEntry_ChangingFieldsWhileVisitingIsSafe() +ASW_TEST(TTest_ASWLog_Types, PendingEntry_ChangingFieldsWhileVisitingIsSafe) { // Arrange: text fields from a scope, then (after the first change) the entry's own copies ASWLog::TASWLogScope scope{ { "a", "1" }, { "b", "2" }, { "c", "3" } }; @@ -399,7 +374,7 @@ void TTest_ASWLog_Types::Test_PendingEntry_ChangingFieldsWhileVisitingIsSafe() CheckTrue(DescribeFields(entry) == std::vector{ "a=xy", "b=xy", "c=xy" }, "Every change should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_PendingEntry_FindsFieldsOfTheEntryAndItsScopes() +ASW_TEST(TTest_ASWLog_Types, PendingEntry_FindsFieldsOfTheEntryAndItsScopes) { // Arrange: a scope and the entry's own fields, one of which replaces the scope's ASWLog::TASWLogScope scope{ { "requestId", "8f3a" }, { "user", "amy" } }; @@ -428,7 +403,7 @@ void TTest_ASWLog_Types::Test_PendingEntry_FindsFieldsOfTheEntryAndItsScopes() "ForEachField() should give each key once, as written"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_PendingEntry_RemoveFieldRemovesItForThisEntry() +ASW_TEST(TTest_ASWLog_Types, PendingEntry_RemoveFieldRemovesItForThisEntry) { // Arrange ASWLog::TASWLogScope scope{ { "user", "amy" }, { "requestId", "8f3a" } }; @@ -453,7 +428,7 @@ void TTest_ASWLog_Types::Test_PendingEntry_RemoveFieldRemovesItForThisEntry() "The scope itself should keep the field"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_PendingEntry_SetFieldReplacesOrAddsACopy() +ASW_TEST(TTest_ASWLog_Types, PendingEntry_SetFieldReplacesOrAddsACopy) { // Arrange ASWLog::TASWLogScope scope{ { "requestId", "8f3a" }, { "user", "amy" } }; @@ -482,7 +457,7 @@ void TTest_ASWLog_Types::Test_PendingEntry_SetFieldReplacesOrAddsACopy() CheckEquals(17, ownFields[0].Value.GetInt(), "The caller's fields should be unchanged"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_PendingEntry_SetMessageOwnsTheText() +ASW_TEST(TTest_ASWLog_Types, PendingEntry_SetMessageOwnsTheText) { // Arrange ASWLog::TASWLogRecord record; @@ -507,7 +482,7 @@ void TTest_ASWLog_Types::Test_PendingEntry_SetMessageOwnsTheText() CheckEquals(std::string("Net"), std::string(entry.GetRecord().Category), "The category should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_SyslogFacility_FromString() +ASW_TEST(TTest_ASWLog_Types, SyslogFacility_FromString) { // Arrange const auto user = ASWLog::SyslogFacility_FromString("USER"); @@ -526,7 +501,7 @@ void TTest_ASWLog_Types::Test_SyslogFacility_FromString() CheckFalse(kernel.has_value(), "A facility the logger doesn't offer should not parse"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_SyslogFacility_ToString() +ASW_TEST(TTest_ASWLog_Types, SyslogFacility_ToString) { // Act & Assert CheckEquals(std::string("USER"), std::string(ASWLog::SyslogFacility_ToString(ASWLog::SyslogFacility::User)), "User should stringify as USER"); @@ -538,7 +513,7 @@ void TTest_ASWLog_Types::Test_SyslogFacility_ToString() CheckEquals(184, static_cast(ASWLog::SyslogFacility::Local7) << 3, "Local7 should be RFC 5424 facility 23 (LOG_LOCAL7 = 184)"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_TimePrecision_FromString() +ASW_TEST(TTest_ASWLog_Types, TimePrecision_FromString) { // Arrange const auto milliseconds = ASWLog::TimePrecision_FromString("MILLISECONDS"); @@ -559,7 +534,7 @@ void TTest_ASWLog_Types::Test_TimePrecision_FromString() CheckFalse(unknown.has_value(), "An unknown precision should not parse"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_TimePrecision_ToString() +ASW_TEST(TTest_ASWLog_Types, TimePrecision_ToString) { // Act & Assert CheckEquals(std::string("MILLISECONDS"), std::string(ASWLog::TimePrecision_ToString(ASWLog::TimePrecision::Milliseconds)), "Milliseconds should stringify as MILLISECONDS"); @@ -567,7 +542,7 @@ void TTest_ASWLog_Types::Test_TimePrecision_ToString() CheckEquals(std::string("NANOSECONDS"), std::string(ASWLog::TimePrecision_ToString(ASWLog::TimePrecision::Nanoseconds)), "Nanoseconds should stringify as NANOSECONDS"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_TimeZone_FromString() +ASW_TEST(TTest_ASWLog_Types, TimeZone_FromString) { // Arrange const auto utc = ASWLog::TimeZone_FromString("UTC"); @@ -580,7 +555,7 @@ void TTest_ASWLog_Types::Test_TimeZone_FromString() CheckFalse(unknown.has_value(), "A named time zone should not parse"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Types::Test_TimeZone_ToString() +ASW_TEST(TTest_ASWLog_Types, TimeZone_ToString) { // Act & Assert CheckEquals(std::string("UTC"), std::string(ASWLog::TimeZone_ToString(ASWLog::TimeZone::UTC)), "UTC should stringify as UTC"); diff --git a/tests/tests/Test_ASWLog_Types.h b/tests/tests/Test_ASWLog_Types.h index ffdad6f..137ffb8 100644 --- a/tests/tests/Test_ASWLog_Types.h +++ b/tests/tests/Test_ASWLog_Types.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Types /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Types : public TTestGroupBase +class TTest_ASWLog_Types : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_AsyncOverflowPolicy_FromString(); void Test_AsyncOverflowPolicy_ToString(); void Test_ColorMode_FromString(); diff --git a/tests/tests/Test_ASWLog_Unicode.cpp b/tests/tests/Test_ASWLog_Unicode.cpp index e1612ad..0691d16 100644 --- a/tests/tests/Test_ASWLog_Unicode.cpp +++ b/tests/tests/Test_ASWLog_Unicode.cpp @@ -307,18 +307,6 @@ std::wstring ToWideString(char32_t value) TTest_ASWLog_Unicode::TTest_ASWLog_Unicode() : inherited("ASWLog_Unicode_Tests") { - RegisterTest(&TTest_ASWLog_Unicode::Test_Formatters_ConvertTheWrappedText, "Formatters_ConvertTheWrappedText"); - RegisterTest(&TTest_ASWLog_Unicode::Test_LogFmt_NarrowFormatTakesWideArguments, "LogFmt_NarrowFormatTakesWideArguments"); - RegisterTest(&TTest_ASWLog_Unicode::Test_LogFmt_WideFormatSkipsFilteredEntries, "LogFmt_WideFormatSkipsFilteredEntries"); - RegisterTest(&TTest_ASWLog_Unicode::Test_LogFmt_WideFormatWritesUTF8, "LogFmt_WideFormatWritesUTF8"); - RegisterTest(&TTest_ASWLog_Unicode::Test_LogWide_ConvertsOnlyEntriesThatAreUsed, "LogWide_ConvertsOnlyEntriesThatAreUsed"); - RegisterTest(&TTest_ASWLog_Unicode::Test_LogWide_EachMethodWritesUTF8, "LogWide_EachMethodWritesUTF8"); - RegisterTest(&TTest_ASWLog_Unicode::Test_LogWide_WritesThroughARealLogger, "LogWide_WritesThroughARealLogger"); - RegisterTest(&TTest_ASWLog_Unicode::Test_RoundTrip_KeepsEveryCharacter, "RoundTrip_KeepsEveryCharacter"); - RegisterTest(&TTest_ASWLog_Unicode::Test_UTF8ToUTF16_ReplacesInvalidSequences, "UTF8ToUTF16_ReplacesInvalidSequences"); - RegisterTest(&TTest_ASWLog_Unicode::Test_UTF8ToWide_FollowsTheWidthOfWchar, "UTF8ToWide_FollowsTheWidthOfWchar"); - RegisterTest(&TTest_ASWLog_Unicode::Test_WideText_TakesEachKindOfText, "WideText_TakesEachKindOfText"); - RegisterTest(&TTest_ASWLog_Unicode::Test_WideToUTF8_ReplacesWhatIsNotACharacter, "WideToUTF8_ReplacesWhatIsNotACharacter"); } //--------------------------------------------------------------------------- TTest_ASWLog_Unicode::~TTest_ASWLog_Unicode() @@ -345,7 +333,7 @@ void TTest_ASWLog_Unicode::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_Formatters_ConvertTheWrappedText() +ASW_TEST(TTest_ASWLog_Unicode, Formatters_ConvertTheWrappedText) { // Arrange const std::wstring wideEmoji = ToWideString(0x1F600); @@ -369,7 +357,7 @@ void TTest_ASWLog_Unicode::Test_Formatters_ConvertTheWrappedText() CheckTrue(wideWide == L"[x]", "Wide() should format wchar_t text as it is in a wide format"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_LogFmt_NarrowFormatTakesWideArguments() +ASW_TEST(TTest_ASWLog_Unicode, LogFmt_NarrowFormatTakesWideArguments) { // Arrange TCountingLog log; @@ -385,7 +373,7 @@ void TTest_ASWLog_Unicode::Test_LogFmt_NarrowFormatTakesWideArguments() }), "Each call should pass on one entry with its level, flags, fields and UTF-8 message"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_LogFmt_WideFormatSkipsFilteredEntries() +ASW_TEST(TTest_ASWLog_Unicode, LogFmt_WideFormatSkipsFilteredEntries) { // Arrange TCountingLog log; @@ -416,7 +404,7 @@ void TTest_ASWLog_Unicode::Test_LogFmt_WideFormatSkipsFilteredEntries() CheckEquals(3, log.Entries.size(), "Only the used entries should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_LogFmt_WideFormatWritesUTF8() +ASW_TEST(TTest_ASWLog_Unicode, LogFmt_WideFormatWritesUTF8) { // Arrange const std::wstring runtimeFormat = L"{} {}"; @@ -489,7 +477,7 @@ void TTest_ASWLog_Unicode::Test_LogFmt_WideFormatWritesUTF8() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_LogWide_ConvertsOnlyEntriesThatAreUsed() +ASW_TEST(TTest_ASWLog_Unicode, LogWide_ConvertsOnlyEntriesThatAreUsed) { // Arrange TCountingLog log; @@ -518,7 +506,7 @@ void TTest_ASWLog_Unicode::Test_LogWide_ConvertsOnlyEntriesThatAreUsed() CheckEquals(2, log.Entries.size(), "The used entries should be kept"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_LogWide_EachMethodWritesUTF8() +ASW_TEST(TTest_ASWLog_Unicode, LogWide_EachMethodWritesUTF8) { // Arrange TCountingLog log; @@ -580,7 +568,7 @@ void TTest_ASWLog_Unicode::Test_LogWide_EachMethodWritesUTF8() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_LogWide_WritesThroughARealLogger() +ASW_TEST(TTest_ASWLog_Unicode, LogWide_WritesThroughARealLogger) { // Arrange ASWLog::TASWMemoryLog log; @@ -600,7 +588,7 @@ void TTest_ASWLog_Unicode::Test_LogWide_WritesThroughARealLogger() CheckEquals(expected[index], lines[index], "The line should hold the message in UTF-8"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_RoundTrip_KeepsEveryCharacter() +ASW_TEST(TTest_ASWLog_Unicode, RoundTrip_KeepsEveryCharacter) { // Arrange: the first and last characters of each UTF-8 length, around the surrogates, and the largest const std::vector codePoints{ @@ -629,7 +617,7 @@ void TTest_ASWLog_Unicode::Test_RoundTrip_KeepsEveryCharacter() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_UTF8ToUTF16_ReplacesInvalidSequences() +ASW_TEST(TTest_ASWLog_Unicode, UTF8ToUTF16_ReplacesInvalidSequences) { // Arrange: valid text, then invalid sequences, each replaced by one U+FFFD per longest start of a valid sequence struct TCase @@ -661,7 +649,7 @@ void TTest_ASWLog_Unicode::Test_UTF8ToUTF16_ReplacesInvalidSequences() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_UTF8ToWide_FollowsTheWidthOfWchar() +ASW_TEST(TTest_ASWLog_Unicode, UTF8ToWide_FollowsTheWidthOfWchar) { // Arrange const std::wstring expected = std::wstring(L"a") + ToWideString(0x1F600) + ToWideString(0xFFFD); @@ -675,7 +663,7 @@ void TTest_ASWLog_Unicode::Test_UTF8ToWide_FollowsTheWidthOfWchar() "wchar_t where it has 16 bits, else one"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_WideText_TakesEachKindOfText() +ASW_TEST(TTest_ASWLog_Unicode, WideText_TakesEachKindOfText) { // Arrange const auto toUTF8 = [](ASWLog::TASWWideText text) @@ -706,7 +694,7 @@ void TTest_ASWLog_Unicode::Test_WideText_TakesEachKindOfText() "An unpaired surrogate should stay where wchar_t has 16 bits, and become U+FFFD where it has 32"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Unicode::Test_WideToUTF8_ReplacesWhatIsNotACharacter() +ASW_TEST(TTest_ASWLog_Unicode, WideToUTF8_ReplacesWhatIsNotACharacter) { // Arrange: UTF-16 with unpaired surrogates struct TCase diff --git a/tests/tests/Test_ASWLog_Unicode.h b/tests/tests/Test_ASWLog_Unicode.h index d9f4703..9fecaba 100644 --- a/tests/tests/Test_ASWLog_Unicode.h +++ b/tests/tests/Test_ASWLog_Unicode.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Unicode /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Unicode : public TTestGroupBase +class TTest_ASWLog_Unicode : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_Formatters_ConvertTheWrappedText(); void Test_LogFmt_NarrowFormatTakesWideArguments(); void Test_LogFmt_WideFormatSkipsFilteredEntries(); diff --git a/tests/tests/Test_ASWLog_Utils.cpp b/tests/tests/Test_ASWLog_Utils.cpp index dc1229a..3f214f8 100644 --- a/tests/tests/Test_ASWLog_Utils.cpp +++ b/tests/tests/Test_ASWLog_Utils.cpp @@ -107,39 +107,6 @@ std::string ToJSONString(std::string_view text) TTest_ASWLog_Utils::TTest_ASWLog_Utils() : inherited("ASWLog_Utils_Tests") { - RegisterTest(&TTest_ASWLog_Utils::Test_ApplyMultilineMode_EscapeWritesCRAndLFAsText, "ApplyMultilineMode_EscapeWritesCRAndLFAsText"); - RegisterTest(&TTest_ASWLog_Utils::Test_ApplyMultilineMode_FindsLineBreaksAnywhereInALongText, "ApplyMultilineMode_FindsLineBreaksAnywhereInALongText"); - RegisterTest(&TTest_ASWLog_Utils::Test_ApplyMultilineMode_IndentMarksEachLineAfterTheFirst, "ApplyMultilineMode_IndentMarksEachLineAfterTheFirst"); - RegisterTest(&TTest_ASWLog_Utils::Test_ApplyMultilineMode_LeavesOtherLinesAsTheyAre, "ApplyMultilineMode_LeavesOtherLinesAsTheyAre"); - RegisterTest(&TTest_ASWLog_Utils::Test_EqualsIgnoringCase_IgnoresOnlyASCIICase, "EqualsIgnoringCase_IgnoresOnlyASCIICase"); - RegisterTest(&TTest_ASWLog_Utils::Test_GenerateLogFileName_ContainsExpectedFields, "GenerateLogFileName_ContainsExpectedFields"); - RegisterTest(&TTest_ASWLog_Utils::Test_GenerateLogFileName_PrefixAndPostfixAreOptional, "GenerateLogFileName_PrefixAndPostfixAreOptional"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetCurrentOSProcessId_MatchesOS, "GetCurrentOSProcessId_MatchesOS"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetCurrentOSThreadId_IdentifiesCallingThread, "GetCurrentOSThreadId_IdentifiesCallingThread"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetFileVersionString_IsEmptyWithoutAVersionResource, "GetFileVersionString_IsEmptyWithoutAVersionResource"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetFileVersionString_ReadsTheFileVersion, "GetFileVersionString_ReadsTheFileVersion"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetOSInfoString_ContainsEdition, "GetOSInfoString_ContainsEdition"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetTimeInfoString_ReportsCurrentOffset, "GetTimeInfoString_ReportsCurrentOffset"); - RegisterTest(&TTest_ASWLog_Utils::Test_GetWindowsEditionName_ProductTypes, "GetWindowsEditionName_ProductTypes"); - RegisterTest(&TTest_ASWLog_Utils::Test_IsRootFolder_DetectsRootFolders, "IsRootFolder_DetectsRootFolders"); - RegisterTest(&TTest_ASWLog_Utils::Test_IsRootFolder_ResolvesRelativePaths, "IsRootFolder_ResolvesRelativePaths"); - RegisterTest(&TTest_ASWLog_Utils::Test_JSON_AppendString_EscapesQuotesBackslashAndControls, "JSON_AppendString_EscapesQuotesBackslashAndControls"); - RegisterTest(&TTest_ASWLog_Utils::Test_JSON_AppendString_FindsSpecialCharactersAnywhereInALongText, "JSON_AppendString_FindsSpecialCharactersAnywhereInALongText"); - RegisterTest(&TTest_ASWLog_Utils::Test_JSON_AppendString_KeepsValidUTF8, "JSON_AppendString_KeepsValidUTF8"); - RegisterTest(&TTest_ASWLog_Utils::Test_JSON_AppendString_ReplacesInvalidUTF8, "JSON_AppendString_ReplacesInvalidUTF8"); - RegisterTest(&TTest_ASWLog_Utils::Test_MatchesWildcard_Patterns, "MatchesWildcard_Patterns"); - RegisterTest(&TTest_ASWLog_Utils::Test_ReadEnvironmentVariable_ReadsUTF8Values, "ReadEnvironmentVariable_ReadsUTF8Values"); - RegisterTest(&TTest_ASWLog_Utils::Test_RenameWithoutReplacing_KeepsExistingTarget, "RenameWithoutReplacing_KeepsExistingTarget"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_GetUTCOffsetMinutes_FollowsDaylightSavingTime, "Time_GetUTCOffsetMinutes_FollowsDaylightSavingTime"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_ToDateString, "Time_ToDateString"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_ToDateString_FollowsZone, "Time_ToDateString_FollowsZone"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_ToISO8601String, "Time_ToISO8601String"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_ToLocalISO8601String_IncludesOffset, "Time_ToLocalISO8601String_IncludesOffset"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_WriteISO8601_CalendarEdges, "Time_WriteISO8601_CalendarEdges"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_WriteISO8601_LocalTimeWithEachPrecision, "Time_WriteISO8601_LocalTimeWithEachPrecision"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_WriteISO8601_UTCWithEachPrecision, "Time_WriteISO8601_UTCWithEachPrecision"); - RegisterTest(&TTest_ASWLog_Utils::Test_Time_WriteISO8601_YearPast9999IsWrittenInFull, "Time_WriteISO8601_YearPast9999IsWrittenInFull"); - RegisterTest(&TTest_ASWLog_Utils::Test_TrimSpaces_RemovesOuterSpacesAndTabs, "TrimSpaces_RemovesOuterSpacesAndTabs"); } //--------------------------------------------------------------------------- TTest_ASWLog_Utils::~TTest_ASWLog_Utils() @@ -166,7 +133,7 @@ void TTest_ASWLog_Utils::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_ApplyMultilineMode_EscapeWritesCRAndLFAsText() +ASW_TEST(TTest_ASWLog_Utils, ApplyMultilineMode_EscapeWritesCRAndLFAsText) { // Arrange: each CR and LF, alone or together, and other text around them struct TCase @@ -190,7 +157,7 @@ void TTest_ASWLog_Utils::Test_ApplyMultilineMode_EscapeWritesCRAndLFAsText() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_ApplyMultilineMode_FindsLineBreaksAnywhereInALongText() +ASW_TEST(TTest_ASWLog_Utils, ApplyMultilineMode_FindsLineBreaksAnywhereInALongText) { // Arrange: text is scanned 8 bytes at a time, so each line break goes at every position of the first two 8-byte // words of a longer text, with what it should become @@ -221,7 +188,7 @@ void TTest_ASWLog_Utils::Test_ApplyMultilineMode_FindsLineBreaksAnywhereInALongT } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_ApplyMultilineMode_IndentMarksEachLineAfterTheFirst() +ASW_TEST(TTest_ASWLog_Utils, ApplyMultilineMode_IndentMarksEachLineAfterTheFirst) { // Arrange struct TCase @@ -252,7 +219,7 @@ void TTest_ASWLog_Utils::Test_ApplyMultilineMode_IndentMarksEachLineAfterTheFirs } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_ApplyMultilineMode_LeavesOtherLinesAsTheyAre() +ASW_TEST(TTest_ASWLog_Utils, ApplyMultilineMode_LeavesOtherLinesAsTheyAre) { // Arrange const std::string multiline = "a\r\nb\n\rc\r"; @@ -274,7 +241,7 @@ void TTest_ASWLog_Utils::Test_ApplyMultilineMode_LeavesOtherLinesAsTheyAre() CheckEquals(std::string(), ApplyMode("", ASWLog::MultilineMode::Indent), "An empty line should stay empty"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_EqualsIgnoringCase_IgnoresOnlyASCIICase() +ASW_TEST(TTest_ASWLog_Utils, EqualsIgnoringCase_IgnoresOnlyASCIICase) { // Arrange / Act / Assert CheckTrue(ASWLog::Detail::EqualsIgnoringCase("", ""), "Two empty texts should be equal"); @@ -288,7 +255,7 @@ void TTest_ASWLog_Utils::Test_EqualsIgnoringCase_IgnoresOnlyASCIICase() CheckFalse(ASWLog::Detail::EqualsIgnoringCase("\xC3\x84", "\xC3\xA4"), "Non-ASCII letters should keep their case"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GenerateLogFileName_ContainsExpectedFields() +ASW_TEST(TTest_ASWLog_Utils, GenerateLogFileName_ContainsExpectedFields) { // Arrange const std::string logName = ASWLog::GenerateLogFileName("", "ExampleLog.txt"); @@ -304,7 +271,7 @@ void TTest_ASWLog_Utils::Test_GenerateLogFileName_ContainsExpectedFields() CheckContains(logName, idsPart, "Generated file name should use the OS process and thread ids"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GenerateLogFileName_PrefixAndPostfixAreOptional() +ASW_TEST(TTest_ASWLog_Utils, GenerateLogFileName_PrefixAndPostfixAreOptional) { // Arrange & Act const std::string withBoth = ASWLog::GenerateLogFileName("MyApp", "ExampleLog.txt"); @@ -328,7 +295,7 @@ void TTest_ASWLog_Utils::Test_GenerateLogFileName_PrefixAndPostfixAreOptional() CheckNotEndsWith(neither, "_", "An empty postfix should not leave a trailing separator when the prefix is also empty"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetCurrentOSProcessId_MatchesOS() +ASW_TEST(TTest_ASWLog_Utils, GetCurrentOSProcessId_MatchesOS) { // Act const auto processId = ASWLog::GetCurrentOSProcessId(); @@ -344,7 +311,7 @@ void TTest_ASWLog_Utils::Test_GetCurrentOSProcessId_MatchesOS() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetCurrentOSThreadId_IdentifiesCallingThread() +ASW_TEST(TTest_ASWLog_Utils, GetCurrentOSThreadId_IdentifiesCallingThread) { // Act const auto mainThreadId = ASWLog::GetCurrentOSThreadId(); @@ -376,7 +343,7 @@ void TTest_ASWLog_Utils::Test_GetCurrentOSThreadId_IdentifiesCallingThread() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetFileVersionString_IsEmptyWithoutAVersionResource() +ASW_TEST(TTest_ASWLog_Utils, GetFileVersionString_IsEmptyWithoutAVersionResource) { // Arrange: a text file, and a file that doesn't exist const auto folder = std::filesystem::temp_directory_path() / "aswlog_utils_version_test"; @@ -401,7 +368,7 @@ void TTest_ASWLog_Utils::Test_GetFileVersionString_IsEmptyWithoutAVersionResourc std::filesystem::remove_all(folder, errorCode); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetFileVersionString_ReadsTheFileVersion() +ASW_TEST(TTest_ASWLog_Utils, GetFileVersionString_ReadsTheFileVersion) { #if defined(_WIN32) // Arrange: kernel32.dll, e.g. "10.0.19041.5794" on Windows 10. To an executable without a compatibility manifest, @@ -443,7 +410,7 @@ void TTest_ASWLog_Utils::Test_GetFileVersionString_ReadsTheFileVersion() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetOSInfoString_ContainsEdition() +ASW_TEST(TTest_ASWLog_Utils, GetOSInfoString_ContainsEdition) { // Arrange const std::string osInfo = ASWLog::GetOSInfoString(); @@ -465,7 +432,7 @@ void TTest_ASWLog_Utils::Test_GetOSInfoString_ContainsEdition() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetTimeInfoString_ReportsCurrentOffset() +ASW_TEST(TTest_ASWLog_Utils, GetTimeInfoString_ReportsCurrentOffset) { // Arrange: US Eastern time, which is -300 minutes from UTC, or -240 while daylight saving time is in effect. The // C runtime's tm_isdst says which applies now. @@ -493,7 +460,7 @@ void TTest_ASWLog_Utils::Test_GetTimeInfoString_ReportsCurrentOffset() CheckContains(timeInfo, expectedLocalSuffix + ", " + offsetLabel, "The local time should end with the zone's current offset"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_GetWindowsEditionName_ProductTypes() +ASW_TEST(TTest_ASWLog_Utils, GetWindowsEditionName_ProductTypes) { #if defined(_WIN32) // Act & Assert @@ -514,7 +481,7 @@ void TTest_ASWLog_Utils::Test_GetWindowsEditionName_ProductTypes() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_IsRootFolder_DetectsRootFolders() +ASW_TEST(TTest_ASWLog_Utils, IsRootFolder_DetectsRootFolders) { // Arrange const auto tempDir = std::filesystem::temp_directory_path(); @@ -549,7 +516,7 @@ void TTest_ASWLog_Utils::Test_IsRootFolder_DetectsRootFolders() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_IsRootFolder_ResolvesRelativePaths() +ASW_TEST(TTest_ASWLog_Utils, IsRootFolder_ResolvesRelativePaths) { // Arrange: a relative path from the current folder up to its root, e.g. "..\..\.." const auto currentPath = std::filesystem::current_path(); @@ -562,7 +529,7 @@ void TTest_ASWLog_Utils::Test_IsRootFolder_ResolvesRelativePaths() CheckFalse(ASWLog::IsRootFolder("."), "\".\" should not be a root folder when the current folder isn't one"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_JSON_AppendString_EscapesQuotesBackslashAndControls() +ASW_TEST(TTest_ASWLog_Utils, JSON_AppendString_EscapesQuotesBackslashAndControls) { // Arrange: each control character's escape, the short form where JSON has one std::string appended = "key:"; @@ -595,7 +562,7 @@ void TTest_ASWLog_Utils::Test_JSON_AppendString_EscapesQuotesBackslashAndControl } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_JSON_AppendString_FindsSpecialCharactersAnywhereInALongText() +ASW_TEST(TTest_ASWLog_Utils, JSON_AppendString_FindsSpecialCharactersAnywhereInALongText) { // Arrange: plain text is scanned 8 bytes at a time, so each special character goes at every position of the first // two 8-byte words of a longer text, with what it should become @@ -624,7 +591,7 @@ void TTest_ASWLog_Utils::Test_JSON_AppendString_FindsSpecialCharactersAnywhereIn } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_JSON_AppendString_KeepsValidUTF8() +ASW_TEST(TTest_ASWLog_Utils, JSON_AppendString_KeepsValidUTF8) { // Arrange: the first and last character of each UTF-8 length, the characters around the surrogates, and a few // common ones @@ -638,7 +605,7 @@ void TTest_ASWLog_Utils::Test_JSON_AppendString_KeepsValidUTF8() CheckEquals("\"" + text + "\"", ToJSONString(text), "Valid UTF-8 should be written as it is: " + ToHex(text)); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_JSON_AppendString_ReplacesInvalidUTF8() +ASW_TEST(TTest_ASWLog_Utils, JSON_AppendString_ReplacesInvalidUTF8) { // Arrange: each invalid text and what it should become, U+FFFD (R) for each longest start of a valid sequence, or // else each byte @@ -677,7 +644,7 @@ void TTest_ASWLog_Utils::Test_JSON_AppendString_ReplacesInvalidUTF8() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_MatchesWildcard_Patterns() +ASW_TEST(TTest_ASWLog_Utils, MatchesWildcard_Patterns) { // Arrange const std::string fileName = "app_123.log"; @@ -696,7 +663,7 @@ void TTest_ASWLog_Utils::Test_MatchesWildcard_Patterns() CheckFalse(ASWLog::MatchesWildcard("", "?"), "'?' should need a character"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_ReadEnvironmentVariable_ReadsUTF8Values() +ASW_TEST(TTest_ASWLog_Utils, ReadEnvironmentVariable_ReadsUTF8Values) { // Arrange: a name with a lambda in it, a value with a lambda and a CJK character, and a value longer than any // first guess at its size @@ -723,7 +690,7 @@ void TTest_ASWLog_Utils::Test_ReadEnvironmentVariable_ReadsUTF8Values() CheckEquals(longValue, longReadValue.value_or("unset"), "A long value should be read whole"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_RenameWithoutReplacing_KeepsExistingTarget() +ASW_TEST(TTest_ASWLog_Utils, RenameWithoutReplacing_KeepsExistingTarget) { // Arrange const auto folder = std::filesystem::temp_directory_path() / "aswlog_utils_rename_test"; @@ -760,7 +727,7 @@ void TTest_ASWLog_Utils::Test_RenameWithoutReplacing_KeepsExistingTarget() std::filesystem::remove_all(folder, errorCode); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_GetUTCOffsetMinutes_FollowsDaylightSavingTime() +ASW_TEST(TTest_ASWLog_Utils, Time_GetUTCOffsetMinutes_FollowsDaylightSavingTime) { // Arrange: noon UTC on a summer and a winter day using namespace std::chrono_literals; @@ -779,7 +746,7 @@ void TTest_ASWLog_Utils::Test_Time_GetUTCOffsetMinutes_FollowsDaylightSavingTime } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_ToDateString() +ASW_TEST(TTest_ASWLog_Utils, Time_ToDateString) { // Arrange const auto now = std::chrono::system_clock::now(); @@ -792,7 +759,7 @@ void TTest_ASWLog_Utils::Test_Time_ToDateString() CheckContains(date, "-", "Date string should include date separators"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_ToDateString_FollowsZone() +ASW_TEST(TTest_ASWLog_Utils, Time_ToDateString_FollowsZone) { // Arrange: 02:00 UTC is still the evening before in US Eastern time using namespace std::chrono_literals; @@ -808,7 +775,7 @@ void TTest_ASWLog_Utils::Test_Time_ToDateString_FollowsZone() CheckEquals(std::string("2026-06-30"), localDate, "The local date should be the day before, 4 hours behind UTC"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_ToISO8601String() +ASW_TEST(TTest_ASWLog_Utils, Time_ToISO8601String) { // Arrange const auto now = std::chrono::system_clock::now(); @@ -822,7 +789,7 @@ void TTest_ASWLog_Utils::Test_Time_ToISO8601String() CheckGreaterThanOrEqual(iso.size(), 24, "ISO string should include date and time"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_ToLocalISO8601String_IncludesOffset() +ASW_TEST(TTest_ASWLog_Utils, Time_ToLocalISO8601String_IncludesOffset) { // Arrange: just after noon UTC on a summer and a winter day using namespace std::chrono_literals; @@ -846,7 +813,7 @@ void TTest_ASWLog_Utils::Test_Time_ToLocalISO8601String_IncludesOffset() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_WriteISO8601_CalendarEdges() +ASW_TEST(TTest_ASWLog_Utils, Time_WriteISO8601_CalendarEdges) { // Arrange using namespace std::chrono_literals; @@ -883,7 +850,7 @@ void TTest_ASWLog_Utils::Test_Time_WriteISO8601_CalendarEdges() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_WriteISO8601_LocalTimeWithEachPrecision() +ASW_TEST(TTest_ASWLog_Utils, Time_WriteISO8601_LocalTimeWithEachPrecision) { // Arrange: a winter noon UTC, with a fraction whose 7th digit only a clock finer than 1 us keeps using namespace std::chrono_literals; @@ -909,7 +876,7 @@ void TTest_ASWLog_Utils::Test_Time_WriteISO8601_LocalTimeWithEachPrecision() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_WriteISO8601_UTCWithEachPrecision() +ASW_TEST(TTest_ASWLog_Utils, Time_WriteISO8601_UTCWithEachPrecision) { // Arrange: a fraction with a digit in each place, the 7th only kept by a clock finer than 1 us using namespace std::chrono_literals; @@ -941,7 +908,7 @@ void TTest_ASWLog_Utils::Test_Time_WriteISO8601_UTCWithEachPrecision() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_Time_WriteISO8601_YearPast9999IsWrittenInFull() +ASW_TEST(TTest_ASWLog_Utils, Time_WriteISO8601_YearPast9999IsWrittenInFull) { // Arrange: libstdc++'s system_clock counts nanoseconds, which end in 2262; libc++'s microseconds and MSVC's 100 ns // ticks reach far past 9999. Compared in days, since converting the year to the clock's ticks could overflow. @@ -962,7 +929,7 @@ void TTest_ASWLog_Utils::Test_Time_WriteISO8601_YearPast9999IsWrittenInFull() CheckEquals(std::string("10000-01-01T01:02:03.004Z"), std::string(buffer, size), "A year past 9999 should be written in full"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Utils::Test_TrimSpaces_RemovesOuterSpacesAndTabs() +ASW_TEST(TTest_ASWLog_Utils, TrimSpaces_RemovesOuterSpacesAndTabs) { // Arrange / Act / Assert CheckEquals(std::string(), std::string(ASWLog::Detail::TrimSpaces("")), "An empty text should stay empty"); diff --git a/tests/tests/Test_ASWLog_Utils.h b/tests/tests/Test_ASWLog_Utils.h index 0b9b2ad..624a67a 100644 --- a/tests/tests/Test_ASWLog_Utils.h +++ b/tests/tests/Test_ASWLog_Utils.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Utils /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Utils : public TTestGroupBase +class TTest_ASWLog_Utils : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_ApplyMultilineMode_EscapeWritesCRAndLFAsText(); void Test_ApplyMultilineMode_FindsLineBreaksAnywhereInALongText(); void Test_ApplyMultilineMode_IndentMarksEachLineAfterTheFirst(); diff --git a/tests/tests/Test_ASWLog_Version.cpp b/tests/tests/Test_ASWLog_Version.cpp index 35bb4e4..2518bcd 100644 --- a/tests/tests/Test_ASWLog_Version.cpp +++ b/tests/tests/Test_ASWLog_Version.cpp @@ -51,9 +51,6 @@ namespace ASWUnitTests TTest_ASWLog_Version::TTest_ASWLog_Version() : inherited("ASWLog_Version_Tests") { - RegisterTest(&TTest_ASWLog_Version::Test_GetVersionStr_ReturnsVersion, "GetVersionStr_ReturnsVersion"); - RegisterTest(&TTest_ASWLog_Version::Test_PreRelease_IsValidSemVer, "PreRelease_IsValidSemVer"); - RegisterTest(&TTest_ASWLog_Version::Test_VersionString_MatchesParts, "VersionString_MatchesParts"); } //--------------------------------------------------------------------------- TTest_ASWLog_Version::~TTest_ASWLog_Version() @@ -80,7 +77,7 @@ void TTest_ASWLog_Version::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_Version::Test_GetVersionStr_ReturnsVersion() +ASW_TEST(TTest_ASWLog_Version, GetVersionStr_ReturnsVersion) { // Arrange ASWLog::TASWConsoleLog consoleLog; @@ -94,7 +91,7 @@ void TTest_ASWLog_Version::Test_GetVersionStr_ReturnsVersion() "GetVersionStr() should return ASWLOG_VERSION_STRING"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Version::Test_PreRelease_IsValidSemVer() +ASW_TEST(TTest_ASWLog_Version, PreRelease_IsValidSemVer) { // Arrange: a pre-release is empty (a release) or dot-separated identifiers, e.g. "dev.1". An identifier is // [0-9A-Za-z-], not empty, and has no leading zero if it is all digits (SemVer 2.0.0). @@ -108,7 +105,7 @@ void TTest_ASWLog_Version::Test_PreRelease_IsValidSemVer() "ASWLOG_VERSION_PRERELEASE should be empty or SemVer pre-release identifiers"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_Version::Test_VersionString_MatchesParts() +ASW_TEST(TTest_ASWLog_Version, VersionString_MatchesParts) { // Arrange const std::string_view preRelease = ASWLog::VersionPreRelease; diff --git a/tests/tests/Test_ASWLog_Version.h b/tests/tests/Test_ASWLog_Version.h index 715e921..eaa66f1 100644 --- a/tests/tests/Test_ASWLog_Version.h +++ b/tests/tests/Test_ASWLog_Version.h @@ -30,12 +30,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_Version /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_Version : public TTestGroupBase +class TTest_ASWLog_Version : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_GetVersionStr_ReturnsVersion(); void Test_PreRelease_IsValidSemVer(); void Test_VersionString_MatchesParts(); diff --git a/tests/tests/Test_ASWLog_WindowsEventLog.cpp b/tests/tests/Test_ASWLog_WindowsEventLog.cpp index 4b9d3b8..9b0a339 100644 --- a/tests/tests/Test_ASWLog_WindowsEventLog.cpp +++ b/tests/tests/Test_ASWLog_WindowsEventLog.cpp @@ -292,17 +292,6 @@ std::wstring Widen(std::string_view text) TTest_ASWLog_WindowsEventLog::TTest_ASWLog_WindowsEventLog() : inherited("ASWLog_WindowsEventLog_Tests") { - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_GetInstance_ReturnsTheSameLogger, "GetInstance_ReturnsTheSameLogger"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_HandleCrash_ReportsTheFormattedCrashLineOnly, "HandleCrash_ReportsTheFormattedCrashLineOnly"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Open_OpensTheConfiguredSource, "Open_OpensTheConfiguredSource"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_RegisterSource_NeedsAdministratorRights, "RegisterSource_NeedsAdministratorRights"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Report_CutsTooLongMessages, "Report_CutsTooLongMessages"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Report_MapsEachLevelToATypeAndEventId, "Report_MapsEachLevelToATypeAndEventId"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Report_StripsOnlyTheLineEnding, "Report_StripsOnlyTheLineEnding"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_ShouldLog_FollowsThePlatform, "ShouldLog_FollowsThePlatform"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsAFailedOpen, "Windows_ReportsAFailedOpen"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsARealEvent, "Windows_ReportsARealEvent"); - RegisterTest(&TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsARefusedEvent, "Windows_ReportsARefusedEvent"); } //--------------------------------------------------------------------------- TTest_ASWLog_WindowsEventLog::~TTest_ASWLog_WindowsEventLog() @@ -330,7 +319,7 @@ void TTest_ASWLog_WindowsEventLog::TearDown_Test(ITestCase& /*testCase*/) // /////// Begin tests after this line /////////////////////// //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_GetInstance_ReturnsTheSameLogger() +ASW_TEST(TTest_ASWLog_WindowsEventLog, GetInstance_ReturnsTheSameLogger) { // Act auto& first = ASWLog::TASWWindowsEventLog::GetInstance(); @@ -340,7 +329,7 @@ void TTest_ASWLog_WindowsEventLog::Test_GetInstance_ReturnsTheSameLogger() CheckSame(&first, &second, "GetInstance() should always return the same logger"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_HandleCrash_ReportsTheFormattedCrashLineOnly() +ASW_TEST(TTest_ASWLog_WindowsEventLog, HandleCrash_ReportsTheFormattedCrashLineOnly) { // Arrange TCapturingEventLog log; @@ -357,7 +346,7 @@ void TTest_ASWLog_WindowsEventLog::Test_HandleCrash_ReportsTheFormattedCrashLine CheckEquals(std::string("[CRITICAL]: Crash: test crash"), log.Events[0].Text, "The crash line should be reported without its line ending"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Open_OpensTheConfiguredSource() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Open_OpensTheConfiguredSource) { // Arrange TCapturingEventLog log; @@ -382,7 +371,7 @@ void TTest_ASWLog_WindowsEventLog::Test_Open_OpensTheConfiguredSource() CheckEquals(std::string("MyApp"), log.Sources[2], "Open after Close should open the current config's source again"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_RegisterSource_NeedsAdministratorRights() +ASW_TEST(TTest_ASWLog_WindowsEventLog, RegisterSource_NeedsAdministratorRights) { #if defined(_WIN32) // Arrange: a source of this test's own; elevated (e.g. on a CI runner) it is registered and removed again @@ -421,7 +410,7 @@ void TTest_ASWLog_WindowsEventLog::Test_RegisterSource_NeedsAdministratorRights( #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Report_CutsTooLongMessages() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Report_CutsTooLongMessages) { // Arrange: "[INFO]: " is 8 bytes. The longer line has 2-byte characters from byte MaxSize - 9 on, so the cut, which // keeps MaxSize - 6 bytes for the " [cut]" marker, falls inside one and backs off to the character before it. @@ -447,7 +436,7 @@ void TTest_ASWLog_WindowsEventLog::Test_Report_CutsTooLongMessages() CheckEndsWith(log.Events[1].Text, "\xC3\xA9 [cut]", "The cut should end with a whole character and the marker"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Report_MapsEachLevelToATypeAndEventId() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Report_MapsEachLevelToATypeAndEventId) { // Arrange TCapturingEventLog log; @@ -480,7 +469,7 @@ void TTest_ASWLog_WindowsEventLog::Test_Report_MapsEachLevelToATypeAndEventId() } } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Report_StripsOnlyTheLineEnding() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Report_StripsOnlyTheLineEnding) { // Arrange TCapturingEventLog log; @@ -505,7 +494,7 @@ void TTest_ASWLog_WindowsEventLog::Test_Report_StripsOnlyTheLineEnding() CheckEquals(std::string("[INFO]: ends with LF\n"), log.Events[4].Text, "With CRLF endings, the message's own LF should stay"); } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_ShouldLog_FollowsThePlatform() +ASW_TEST(TTest_ASWLog_WindowsEventLog, ShouldLog_FollowsThePlatform) { #if defined(_WIN32) // Arrange: no startup or shutdown lines, and only checks, so nothing reaches the Event Log @@ -555,7 +544,7 @@ void TTest_ASWLog_WindowsEventLog::Test_ShouldLog_FollowsThePlatform() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsAFailedOpen() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Windows_ReportsAFailedOpen) { #if defined(_WIN32) // Arrange: only the system (LSA) may report to the Security log, so other processes can't open it as a source @@ -583,7 +572,7 @@ void TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsAFailedOpen() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsARealEvent() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Windows_ReportsARealEvent) { #if defined(_WIN32) // Arrange: one Warning event of a test source in the Application log, found again by a token of this run @@ -608,7 +597,7 @@ void TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsARealEvent() #endif } //--------------------------------------------------------------------------- -void TTest_ASWLog_WindowsEventLog::Test_Windows_ReportsARefusedEvent() +ASW_TEST(TTest_ASWLog_WindowsEventLog, Windows_ReportsARefusedEvent) { #if defined(_WIN32) // Arrange: a real source, and an event the Event Log refuses (ERROR_INVALID_PARAMETER), so nothing is written diff --git a/tests/tests/Test_ASWLog_WindowsEventLog.h b/tests/tests/Test_ASWLog_WindowsEventLog.h index 38b5f95..0401498 100644 --- a/tests/tests/Test_ASWLog_WindowsEventLog.h +++ b/tests/tests/Test_ASWLog_WindowsEventLog.h @@ -32,12 +32,12 @@ namespace ASWUnitTests /////////////////////////////////////////////////////////////////////////// // TTest_ASWLog_WindowsEventLog /////////////////////////////////////////////////////////////////////////// -class TTest_ASWLog_WindowsEventLog : public TTestGroupBase +class TTest_ASWLog_WindowsEventLog : public TAutoTestGroup { private: - typedef TTestGroupBase inherited; + typedef TAutoTestGroup inherited; -private: // Test methods +public: // Test methods, each defined with ASW_TEST void Test_GetInstance_ReturnsTheSameLogger(); void Test_HandleCrash_ReportsTheFormattedCrashLineOnly(); void Test_Open_OpensTheConfiguredSource(); diff --git a/third_party/asw-unit-tests b/third_party/asw-unit-tests index 0304a70..c30bcbb 160000 --- a/third_party/asw-unit-tests +++ b/third_party/asw-unit-tests @@ -1 +1 @@ -Subproject commit 0304a7095a41a14f725c45b31126bba201c42ca6 +Subproject commit c30bcbb774f62206aeca4276410236015b6bf8fc