From 758cd85fcfce9b069f1626231bea83665bf963ae Mon Sep 17 00:00:00 2001 From: SwuduSusuwu <2002luvabbaluvu@gmail.com> Date: Mon, 25 Nov 2024 23:11:59 -0800 Subject: [PATCH] +`cxx/ClassObject.cxx`: +`classObjectTests()` Is followup to: commit 940915427d5a86c347a973fea4f9b73c9cc37ef9 (?`cxx/ClassObject.hxx`: +`SUSUWU_VIRTUAL_DEFAULTS), the first commit with known good {`Class`, `Object`} operators. Has to do with issues: #10 (Java port), #14 (more unit tests). ?`cxx/ClassObject.*xx`: +`classObjectTestValid()`, +`classObjectTestCommutative()`, +`classObjectTestMatch()`, +`classObjectTestMismatch()`; helper functions for `classObjectTests()`. +`classObjectTests()`; tests {`Class`, `Object`}::{`getObjectSize`, `getName`, `operator==`, `operator!=`, `hasImplementation`, `isInitialized`}. +`classObjectTestsNoexcept()`; `templateCatchAll` wrap for `classObjectTests()`. ?`build.sh`: ?`FLAGS_SPECIAL`: +`-DSUSUWU_VIRTUAL_VTABLE_COMPARISON`; "Error: classObjectTestMatch() { if(class1->operator!=(*class2 /*Susuwu::Object*/)) { /* `Susuwu::Object::operator!=` false negative. */ } }]" workaround. TODO: fix without workaround. ?`cxx/main.hxx`: +`susuwuUnitTestsClassObjectBit`; indicates error in `classSysObjectTests()`. ?`cxx/main.cxx`: ?`unitTestsCxx`; test `classSysObjectTests()`. ?`posts/VirusAnalysis.md`: include `cxx/main.*xx`; the virtuals (from `cxx/ClassObjects.hxx`) are not used enough to include. --- build.sh | 2 +- cxx/ClassObject.cxx | 140 +++++++++++++++++++++++++++++++++++++++++ cxx/ClassObject.hxx | 3 + cxx/main.cxx | 10 ++- cxx/main.hxx | 15 ++--- posts/VirusAnalysis.md | 30 +++++---- 6 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 cxx/ClassObject.cxx diff --git a/build.sh b/build.sh index 9fa74829..4dd481f8 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ . ./Macros.sh #/* SUSUWU_BUILD_CTAGS SUSUWU_BUILD_OBJECTS() SUSUWU_BUILD_EXECUTABLE() SUSUWU_INSTALL() SUSUWU_PRINT() SUSUWU_PROCESS_CLEAN_REBUILD() SUSUWU_PROCESS_MINGW() SUSUWU_PROCESS_RELEASE_DEBUG() SUSUWU_PROCESS_S() SUSUWU_PROCESS_VERBOSE() SUSUWU_SETUP_BUILD_FLAGS() SUSUWU_SETUP_CXX() SUSUWU_SETUP_BINDIR() SUSUWU_SETUP_OBJDIR() SUSUWU_SETUP_OUTPUT() SUSUWU_SH_* SUSUWU_TEST_OUTPUT() SUSUWU_UNINSTALL() */ SUSUWU_PRINT "${SUSUWU_SH_NOTICE}" "Dual licenses: choose \"Creative Commons\" or \"Apache 2\" (allows all uses)." -FLAGS_SPECIAL="" #/* You can put special flags from `build.sh` into this to use. */ +FLAGS_SPECIAL="-DSUSUWU_VIRTUAL_VTABLE_COMPARISON" #/* You can put special flags from `build.sh` into this to use. */ FLAGS_ANALYSIS="-Wall -Wno-unused-function -Wno-unused-function -Wextra -Wno-unused-parameter -Wno-ignored-qualifiers -Wpedantic" #/*TODO: -`-Wno-*`, +`-Werror` */ FLAGS_RELEASE="-fomit-frame-pointer -DNDEBUG -O2" #/* without frame pointer (pointer used for stacktraces), without `assert(...)`/`SUSUWU_DEBUG(...)`/`SUSUWU_NOTICE(...)`, with optimization level 2 */ CXXFLAGS_DEBUG="-std=c++11" #/* ensure unit tests pass with C++11 support as max */ diff --git a/cxx/ClassObject.cxx b/cxx/ClassObject.cxx new file mode 100644 index 00000000..a2b4e112 --- /dev/null +++ b/cxx/ClassObject.cxx @@ -0,0 +1,140 @@ +/* Dual licenses: choose "Creative Commons" or "Apache 2" (allows all uses) */ +#ifndef INCLUDES_cxx_ClassObject_cxx +#define INCLUDES_cxx_ClassObject_cxx +#include "Macros.hxx" /* SUSUWU_ERROR */ +#include "ClassObject.hxx" /* Class Object SUSUWU_CLASS_DEFAULTS SUSUWU_VIRTUAL_EQUALS_USE_ADDRESSES SUSUWU_VIRTUAL_VTABLE_COMPARISON SUSUWU_VIRTUAL_DEFAULTS */ +#include "ClassSys.hxx" /* templateCatchAll */ +//#include /* assert */ +#include /* size_t */ +//#include /* memcmp */ +//#include /* std::unique_ptr std::make_unique */ +//#include /* std::runtime_error */ +//#include /* std::string */ +namespace Susuwu { +class SubClass : public Class { SUSUWU_CLASS_DEFAULTS(SubClass) }; +class SubClassWithMemberObject : public Class { public: SUSUWU_CLASS_DEFAULTS(SubClassWithMemberObject) bool memberObject = true; }; +class SubObject : public Object { SUSUWU_VIRTUAL_DEFAULTS(SubObject) }; +class SubObjectWithMemberObject : public Object { public: SUSUWU_VIRTUAL_DEFAULTS(SubObjectWithMemberObject) bool memberObject = true;}; +const bool classObjectTestsNoexcept() SUSUWU_NOEXCEPT {return templateCatchAll(classObjectTests, "classObjectTests()");} +static const bool classObjectTestValid(const Class *clas) { + if(clas->getObjectSize() != sizeof(*clas)) { + SUSUWU_NOTICE("classObjectTestValid() { if(clas->sizeo() != sizeof(*clas)) { /* `" + clas->getName() + "::getObjectSize()` != `sizeof(" + clas->getName() + ")`. */ } }"); + } + return true; +} +static const bool classObjectTestCommutative(const Class *class1, const Class *class2) { /* TODO: call this "Symmetric"? */ + bool result = true /* TODO: classObjectTestValid(class1) && classObjectTestValid(class2) */; + if(class1->operator!=(*class2) != class2->operator!=(*class1)) { + SUSUWU_ERROR("classObjectTestCommutative() { if(class1->operator!=(*class2) != class2->operator!=(*class1)) { /* `" + class1->getName() + "::operator!=` not commutative to `" + class2->getName() + "::operator!=`. */ } }"); + result = false; + } + if(class1->operator==(*class2) != class2->operator==(*class1)) { + SUSUWU_ERROR("classObjectTestCommutative() { if(class1->operator==(*class2) != class2->operator==(*class1)) { /* `" + class1->getName() + "::operator==` not commutative to `" + class2->getName() + "::operator==`. */ } }"); + result = false; + } + if(class1->operator==(*class2) == class1->operator!=(*class2)) { + SUSUWU_ERROR("classObjectTestCommutative() { if(class1->operator==(*class2/*" + class2->getName() + "*/ == class1->operator!=(*class2)) { /* `" + class1->getName() + "::operator==` not anticommuttative to `" + class1->getName() + "::operator!=`. */ } }"); + result = false; + } + return result; +} +static const bool classObjectTestMatch(const Class *class1, const Class *class2) { + bool result = classObjectTestCommutative(class1, class2); + if(class1->operator!=(*class2)) { + SUSUWU_ERROR("classObjectTestMatch() { if(class1->operator!=(*class2 /*" + class2->getName() + "*/)) { /* `" + class1->getName() + "::operator!=` false negative. */ } }"); + result = false; + } + return result; +} +static const bool classObjectTestMismatch(const Class *class1, const Class *class2) { + bool result = classObjectTestCommutative(class1, class2); + if(class1->operator==(*class2)) { + SUSUWU_ERROR("classObjectTestMismatch() { if(class1->operator==(*class2 /*" + class2->getName() + "*/)) { /* `" + class1->getName() + "::operator==` false positive. */ } }"); + result = false; + } + if(class1->getName() == class2->getName()) { + SUSUWU_ERROR(std::string("classObjectTestMismatchs() { if(class1->getName() == class2->getName()) { /* `") + typeid(class1).name() + "::getName() == \"" + class1->getName() + "\"`, but also `" + typeid(class2).name() + "::getName() == \"" + class2->getName() + "\"` */ } }"); + result = false; + } + return result; +} +const bool classObjectTests() { + bool result = true; + + const Class *classPtr = new Class(), + *objectPtr = new Object(), + *subClassPtr = new SubClass(), + *subObjectPtr = new SubObject(), + *subClassWithMemberObjectPtr = new SubClassWithMemberObject(), + *subObjectWithMemberObjectPtr = new SubObjectWithMemberObject(); + const Class class2 = Class(); + const Object object2 = Object(); + + result &= classObjectTestMatch(classPtr, classPtr) /* reflexive */; + result &= classObjectTestMatch(subClassPtr, subClassPtr) /* reflexive */; + result &= classObjectTestMatch(subClassWithMemberObjectPtr, subClassWithMemberObjectPtr) /* reflexive */; + result &= classObjectTestMatch(objectPtr, objectPtr) /* reflexive */; + result &= classObjectTestMatch(subObjectPtr, subObjectPtr) /* reflexive */; + result &= classObjectTestMatch(subObjectWithMemberObjectPtr, subObjectWithMemberObjectPtr) /* reflexive */; +#ifdef SUSUWU_VIRTUAL_EQUALS_USE_ADDRESSES /* If you interpret `Java`'s standard as "Addresses must match". */ + result &= classObjectTestMismatch(classPtr, &class2); + result &= classObjectTestMismatch(objectPtr, &object2); +#else /* SUSUWU_VIRTUAL_EQUALS_USE_ADDRESSES else */ + SUSUWU_PRAGMA(message("TODO: SUSUWU_VIRTUAL_EQUALS_USE_ADDRESSES")) + result &= classObjectTestMatch(classPtr, &class2) /* reflexive */; + result &= classObjectTestMatch(objectPtr, &object2) /* reflexive */; +#endif /* SUSUWU_VIRTUAL_EQUALS_USE_ADDRESSES else */ +#ifdef SUSUWU_VIRTUAL_VTABLE_COMPARISON /* If you interpret `Java`'s standard as "`typeid` must match". */ + SUSUWU_PRAGMA(message("Notice: SUSUWU_VIRTUAL_VTABLE_COMPARISON")) + result &= classObjectTestMismatch(classPtr, subClassPtr); + result &= classObjectTestMismatch(classPtr, objectPtr); + result &= classObjectTestMismatch(classPtr, subObjectPtr); + result &= classObjectTestMismatch(classPtr, &object2); + result &= classObjectTestMismatch(objectPtr, subObjectPtr); + result &= classObjectTestMismatch(objectPtr, &class2); +#else /* SUSUWU_VIRTUAL_VTABLE_COMPARISON else */ + result &= classObjectTestMatch(classPtr, subClassPtr) /* transitive */; + result &= classObjectTestMatch(classPtr, objectPtr) /* transitive */; + result &= classObjectTestMatch(classPtr, subObjectPtr) /* transitive */; + result &= classObjectTestMatch(classPtr, &object2) /* transitive */; + result &= classObjectTestMatch(objectPtr, &class2) /* transitive */; + result &= classObjectTestMatch(objectPtr, subObjectPtr) /* transitive */; +#endif /* SUSUWU_VIRTUAL_VTABLE_COMPARISON else */ + result &= classObjectTestMismatch(classPtr, subObjectWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(classPtr, subClassWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(subClassPtr, subObjectWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(subClassPtr, subClassWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(objectPtr, subClassWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(objectPtr, subObjectWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(subObjectPtr, subClassWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + result &= classObjectTestMismatch(subObjectPtr, subObjectWithMemberObjectPtr) /* `getObjectSize()` mismatch */; + if(classPtr->getName() != class2.getName()) { + SUSUWU_ERROR("classObjectTests() { if(classPtr->getName() != class2.getName()) { /* `Class::getName()` virtual error */ } }"); + result = false; + } + if(objectPtr->getName() != object2.getName()) { + SUSUWU_ERROR("classObjectTests() { if(objectPtr->getName() != object2.getName()) { /* `Object::getName()` virtual error */ } }"); + result = false; + } + + if(!object2.hasImplementation()) { + SUSUWU_ERROR("classObjectTests() { if(!object2.hasImplementation()) { /* `Object::hasImplementation` false negative */ } }"); + result = false; + } + if(!object2.isInitialized()) { + SUSUWU_ERROR("classObjectTests() { if(!object2.hasIsInitialized()) { /* `Object::hasImplementation` false negative */ } }"); + result = false; + } + + delete subObjectWithMemberObjectPtr; + delete subClassWithMemberObjectPtr; + delete subObjectPtr; + delete subClassPtr; + delete objectPtr; + delete classPtr; + return result; +} + +}; /* namespace Susuwu */ +#endif /* ndef INCLUDES_cxx_ClassObject_cxx */ + diff --git a/cxx/ClassObject.hxx b/cxx/ClassObject.hxx index 52390fa2..d2166e20 100644 --- a/cxx/ClassObject.hxx +++ b/cxx/ClassObject.hxx @@ -11,6 +11,9 @@ * plus `Susuwu::Object` (a C++ port of [Java's `Object`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html) [superclass](https://docs.oracle.com/javase%2Ftutorial%2F/java/IandI/objectclass.html)), * to [assist future Java ports](https://github.com/SwuduSusuwu/SubStack/issues/10) */ namespace Susuwu { +const bool classObjectTests(); +const bool classObjectTestsNoexcept() SUSUWU_NOEXCEPT; + /* `clang-tidy` off: NOLINTBEGIN(cppcoreguidelines-macro-usage,fuchsia-overloaded-operator) */ #ifdef SUSUWU_CXX20 /* use for all `SubClass : public Class` or `SubClass : public Object` which do not have their own `operator==(const SubClass &)` */ # define SUSUWU_SUBCLASS_OPERATOREQUALTO(SUBCLASS) bool operator==(const Class &) const SUSUWU_DEFAULT diff --git a/cxx/main.cxx b/cxx/main.cxx index 5ec778ab..53be14fd 100644 --- a/cxx/main.cxx +++ b/cxx/main.cxx @@ -3,6 +3,7 @@ #define INCLUDES_cxx_main_cxx #include "main.hxx" #include "AssistantCns.hxx" /* assistantCnsTestsNoexcept */ +#include "ClassObject.hxx" /* classObjectTestsNoexcept */ #include "ClassResultList.hxx" /* classResultListTestsNoexcept */ #include "ClassSha2.hxx" /* classSha2TestsNoexcept */ #include "ClassSys.hxx" /* classSysSetConsoleInput classSysTestsNoexcept templateCatchAll */ @@ -15,7 +16,7 @@ #endif /* def SUSUWU_CXX17 */ namespace Susuwu { /* `clang-tidy` off: NOLINTBEGIN(hicpp-signed-bitwise, readability-simplify-boolean-expr) */ -static const SusuwuUnitTestsBitmask unitTestsCxx() SUSUWU_EXPECTS(std::cout.good()) SUSUWU_ENSURES(0 == macrosTestsNoexcept() && true == classSysTestsNoexcept() && true == classSha2TestsNoexcept() && true == virusAnalysisTestsNoexcept() && true == assistantCnsTestsNoexcept()) +static const SusuwuUnitTestsBitmask unitTestsCxx() SUSUWU_EXPECTS(std::cout.good()) SUSUWU_ENSURES(0 == macrosTestsNoexcept() && true == classObjectTestsNoexcept() && true == classSysTestsNoexcept() && true == classSha2TestsNoexcept() && true == virusAnalysisTestsNoexcept() && true == assistantCnsTestsNoexcept()) #ifdef SUSUWU_CXX17 /* `type_traits` is C++11 but `is_nothrow_invocable` is C++17 */ SUSUWU_NOEXCEPT(std::is_nothrow_invocable::value) #endif /* def SUSUWU_CXX17 */ @@ -39,6 +40,13 @@ static const SusuwuUnitTestsBitmask unitTestsCxx() SUSUWU_EXPECTS(std::cout.good std::cout << "error#" << std::to_string(macrosTestsErrno) << std::endl; susuwuUnitTestsErrno |= susuwuUnitTestsMacrosBit; } + std::cout << "classObjectTestsNoexcept(): " << std::flush; + if(true == classObjectTestsNoexcept()) { + std::cout << "pass" << std::endl; + } else { + std::cout << "error" << std::endl; + susuwuUnitTestsErrno |= susuwuUnitTestsClassObjectBit; + } std::cout << "classSysTestsNoexcept(): " << std::flush; if(true != classSysTestsNoexcept()) { susuwuUnitTestsErrno |= susuwuUnitTestsClassSysBit; diff --git a/cxx/main.hxx b/cxx/main.hxx index ca53f5df..679f5e15 100644 --- a/cxx/main.hxx +++ b/cxx/main.hxx @@ -7,13 +7,14 @@ extern "C" { /* progress to https://github.com/SwuduSusuwu/SubStack/issues/3 , s /* `clang-tidy` on: NOLINTBEGIN(hicpp-signed-bitwise) */ typedef int SusuwuUnitTestsBitmask; /* normal `int`, but used as bitmask (non-zero return value says which tests failed) */ /* bits in order which tests execute (not ordered included, but order used) */ -static const int susuwuUnitTestsMacrosBit = 1 << 0; /* 1: `Macros.hxx`:`macrosTestsNoexcept()` */ -static const int susuwuUnitTestsConsoleBit = 1 << 1; /* 2: `classSys.hxx`:`classSysSetConsoleInput()` */ -static const int susuwuUnitTestsClassSysBit = 1 << 2; /* 4: `ClassSys.hxx`:`classSysTestsNoexcept()` */ -static const int susuwuUnitTestsClassSha2Bit = 1 << 3; /* 8: `ClassSha2.hxx`:`classSha2TestsNoexcept()` */ -static const int susuwuUnitTestsClassResultListBit = 1 << 4; /* 16: `ClassResultList.hxx`:`classResultListTestsNoexcept()` */ -static const int susuwuUnitTestsVirusAnalysisBit = 1 << 5; /* 32: `VirusAnalysis.hxx`:`virusAnalysisTestsNoexcept()` */ -static const int susuwuUnitTestsAssistantCnsBit = 1 << 6; /* 64: `AssistantCns.hxx`:`assistantCnsTestsNoexcept()` */ +static const int susuwuUnitTestsMacrosBit = 1 << 0; /* 1: `Macros.hxx`:`macrosTestsNoexcept()` */ +static const int susuwuUnitTestsClassObjectBit = 1 << 1; /* 2: `ClassObjects.hxx`:`classObjectsTestsNoexcept()` */ +static const int susuwuUnitTestsConsoleBit = 1 << 2; /* 4: `ClassSys.hxx`:`classSysSetConsoleInput()` */ +static const int susuwuUnitTestsClassSysBit = 1 << 3; /* 8: `ClassSys.hxx`:`classSysTestsNoexcept()` */ +static const int susuwuUnitTestsClassSha2Bit = 1 << 4; /* 16: `ClassSha2.hxx`:`classSha2TestsNoexcept()` */ +static const int susuwuUnitTestsClassResultListBit = 1 << 5; /* 32: `ClassResultList.hxx`:`classResultListTestsNoexcept()` */ +static const int susuwuUnitTestsVirusAnalysisBit = 1 << 6; /* 64: `VirusAnalysis.hxx`:`virusAnalysisTestsNoexcept()` */ +static const int susuwuUnitTestsAssistantCnsBit = 1 << 7; /* 128: `AssistantCns.hxx`:`assistantCnsTestsNoexcept()` */ /* `clang-tidy` on: NOLINTEND(hicpp-signed-bitwise) */ const SusuwuUnitTestsBitmask susuwuUnitTests(); SusuwuUnitTestsBitmask main(int argc, const char **args); diff --git a/posts/VirusAnalysis.md b/posts/VirusAnalysis.md index 061b912d..6db7820a 100644 --- a/posts/VirusAnalysis.md +++ b/posts/VirusAnalysis.md @@ -1351,7 +1351,6 @@ const bool virusAnalysisTests() { return true; } -/* `clang-tidy` suppress: NOLINTBEGIN(readability-implicit-bool-conversion) */ const bool virusAnalysisHookTests() { const VirusAnalysisHook originalHookStatus = virusAnalysisGetHook(); VirusAnalysisHook hookStatus = virusAnalysisHook(virusAnalysisHookClear | virusAnalysisHookExec); @@ -1422,7 +1421,6 @@ const VirusAnalysisHook virusAnalysisHook(VirusAnalysisHook hookStatus) { /* Ign } return virusAnalysisGetHook(); } -/* `clang-tidy` on: NOLINTEND(readability-implicit-bool-conversion) */ const VirusAnalysisResult virusAnalysis(const PortableExecutable &file) { const auto fileHash = classSha2(file.bytecode); @@ -1656,15 +1654,18 @@ const FileBytecode cnsVirusFix(const PortableExecutable &file, const Cns &cns /* #ifdef __cplusplus extern "C" { /* progress to https://github.com/SwuduSusuwu/SubStack/issues/3 , such that other languages can execute unit tests */ #endif /* def __cplusplus */ +/* `clang-tidy` on: NOLINTBEGIN(hicpp-signed-bitwise) */ typedef int SusuwuUnitTestsBitmask; /* normal `int`, but used as bitmask (non-zero return value says which tests failed) */ /* bits in order which tests execute (not ordered included, but order used) */ -static const int susuwuUnitTestsMacrosBit = 1 << 0; /* 1: `Macros.hxx`:`macrosTestsNoexcept()` */ -static const int susuwuUnitTestsConsoleBit = 1 << 1; /* 2: `classSys.hxx`:`classSysSetConsoleInput()` */ -static const int susuwuUnitTestsClassSysBit = 1 << 2; /* 4: `ClassSys.hxx`:`classSysTestsNoexcept()` */ -static const int susuwuUnitTestsClassSha2Bit = 1 << 3; /* 8: `ClassSha2.hxx`:`classSha2TestsNoexcept()` */ -static const int susuwuUnitTestsClassResultListBit = 1 << 4; /* 16: `ClassResultList.hxx`:`classResultListTestsNoexcept()` */ -static const int susuwuUnitTestsVirusAnalysisBit = 1 << 5; /* 32: `VirusAnalysis.hxx`:`virusAnalysisTestsNoexcept()` */ -static const int susuwuUnitTestsAssistantCnsBit = 1 << 6; /* 64: `AssistantCns.hxx`:`assistantCnsTestsNoexcept()` */ +static const int susuwuUnitTestsMacrosBit = 1 << 0; /* 1: `Macros.hxx`:`macrosTestsNoexcept()` */ +static const int susuwuUnitTestsClassObjectBit = 1 << 1; /* 2: `ClassObjects.hxx`:`classObjectsTestsNoexcept()` */ +static const int susuwuUnitTestsConsoleBit = 1 << 2; /* 4: `ClassSys.hxx`:`classSysSetConsoleInput()` */ +static const int susuwuUnitTestsClassSysBit = 1 << 3; /* 8: `ClassSys.hxx`:`classSysTestsNoexcept()` */ +static const int susuwuUnitTestsClassSha2Bit = 1 << 4; /* 16: `ClassSha2.hxx`:`classSha2TestsNoexcept()` */ +static const int susuwuUnitTestsClassResultListBit = 1 << 5; /* 32: `ClassResultList.hxx`:`classResultListTestsNoexcept()` */ +static const int susuwuUnitTestsVirusAnalysisBit = 1 << 6; /* 64: `VirusAnalysis.hxx`:`virusAnalysisTestsNoexcept()` */ +static const int susuwuUnitTestsAssistantCnsBit = 1 << 7; /* 128: `AssistantCns.hxx`:`assistantCnsTestsNoexcept()` */ +/* `clang-tidy` on: NOLINTEND(hicpp-signed-bitwise) */ const SusuwuUnitTestsBitmask susuwuUnitTests(); SusuwuUnitTestsBitmask main(int argc, const char **args); #ifdef __cplusplus @@ -1675,11 +1676,11 @@ SusuwuUnitTestsBitmask main(int argc, const char **args); `less` [cxx/main.cxx](https://github.com/SwuduSusuwu/SubStack/blob/trunk/cxx/main.cxx) ``` namespace Susuwu { -static const SusuwuUnitTestsBitmask unitTestsCxx() SUSUWU_EXPECTS(std::cout.good()) SUSUWU_ENSURES(0 == macrosTestsNoexcept() && true == classSysTestsNoexcept() && true == classSha2TestsNoexcept() && true == virusAnalysisTestsNoexcept() && true == assistantCnsTestsNoexcept()) +static const SusuwuUnitTestsBitmask unitTestsCxx() SUSUWU_EXPECTS(std::cout.good()) SUSUWU_ENSURES(0 == macrosTestsNoexcept() && true == classObjectTestsNoexcept() && true == classSysTestsNoexcept() && true == classSha2TestsNoexcept() && true == virusAnalysisTestsNoexcept() && true == assistantCnsTestsNoexcept()) #ifdef SUSUWU_CXX17 /* `type_traits` is C++11 but `is_nothrow_invocable` is C++17 */ SUSUWU_NOEXCEPT(std::is_nothrow_invocable::value) #endif /* def SUSUWU_CXX17 */ - { +{ /* if the function names (or line numbers) change, update `SECURITY.md` to new values */ int susuwuUnitTestsErrno = 0; if(!std::cout.good()) { susuwuUnitTestsErrno |= susuwuUnitTestsConsoleBit; @@ -1699,6 +1700,13 @@ static const SusuwuUnitTestsBitmask unitTestsCxx() SUSUWU_EXPECTS(std::cout.good std::cout << "error#" << std::to_string(macrosTestsErrno) << std::endl; susuwuUnitTestsErrno |= susuwuUnitTestsMacrosBit; } + std::cout << "classObjectTestsNoexcept(): " << std::flush; + if(true == classObjectTestsNoexcept()) { + std::cout << "pass" << std::endl; + } else { + std::cout << "error" << std::endl; + susuwuUnitTestsErrno |= susuwuUnitTestsClassObjectBit; + } std::cout << "classSysTestsNoexcept(): " << std::flush; if(true != classSysTestsNoexcept()) { susuwuUnitTestsErrno |= susuwuUnitTestsClassSysBit;