From a1289eb502760ddf350e29f8059d090db8b73854 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 13 Jul 2013 04:48:53 -0700 Subject: [PATCH] Use template for UnitTest --- modules/beast_core/beast_core.h | 20 +-- .../containers/beast_AbstractFifo.cpp | 14 +- .../beast_core/diagnostic/beast_UnitTest.cpp | 32 ++--- .../beast_core/diagnostic/beast_UnitTest.h | 135 ++++++++++-------- modules/beast_core/files/beast_File.cpp | 11 +- modules/beast_core/json/beast_JSON.cpp | 9 +- modules/beast_core/maths/beast_Random.cpp | 9 +- .../streams/beast_MemoryInputStream.cpp | 11 +- modules/beast_core/text/beast_String.cpp | 9 +- modules/beast_core/text/beast_TextDiff.cpp | 10 +- .../beast_core/threads/beast_ChildProcess.cpp | 9 +- modules/beast_core/threads/beast_Thread.cpp | 9 +- .../zip/beast_GZIPCompressorOutputStream.cpp | 9 +- 13 files changed, 148 insertions(+), 139 deletions(-) diff --git a/modules/beast_core/beast_core.h b/modules/beast_core/beast_core.h index 093cd41fcb..cb17e5b69c 100644 --- a/modules/beast_core/beast_core.h +++ b/modules/beast_core/beast_core.h @@ -194,6 +194,9 @@ namespace beast // Order matters, since headers don't have their own #include lines. // Add new includes to the bottom. +#include "system/beast_PlatformDefs.h" +#include "system/beast_TargetPlatform.h" + #include "memory/beast_Uncopyable.h" #include "maths/beast_MathsFunctions.h" #include "memory/beast_Atomic.h" @@ -204,6 +207,14 @@ namespace beast #include "containers/beast_LockFreeStack.h" #include "threads/beast_SpinDelay.h" #include "memory/beast_StaticObject.h" + +#include "text/beast_String.h" +#include "text/beast_CharacterFunctions.h" +#include "text/beast_CharPointer_ASCII.h" +#include "text/beast_CharPointer_UTF16.h" +#include "text/beast_CharPointer_UTF32.h" +#include "text/beast_CharPointer_UTF8.h" + #include "time/beast_PerformedAtExit.h" #include "diagnostic/beast_LeakChecked.h" #include "memory/beast_Memory.h" @@ -280,19 +291,10 @@ namespace beast #include "streams/beast_OutputStream.h" #include "streams/beast_SubregionStream.h" #include "system/beast_Functional.h" -#include "system/beast_PlatformDefs.h" -#include "system/beast_StandardHeader.h" #include "system/beast_SystemStats.h" -#include "system/beast_TargetPlatform.h" -#include "text/beast_CharacterFunctions.h" -#include "text/beast_CharPointer_ASCII.h" -#include "text/beast_CharPointer_UTF16.h" -#include "text/beast_CharPointer_UTF32.h" -#include "text/beast_CharPointer_UTF8.h" #include "text/beast_Identifier.h" #include "text/beast_LocalisedStrings.h" #include "text/beast_NewLine.h" -#include "text/beast_String.h" #include "text/beast_StringArray.h" #include "text/beast_StringPairArray.h" #include "text/beast_StringPool.h" diff --git a/modules/beast_core/containers/beast_AbstractFifo.cpp b/modules/beast_core/containers/beast_AbstractFifo.cpp index 9663e79f6a..2e38d18021 100644 --- a/modules/beast_core/containers/beast_AbstractFifo.cpp +++ b/modules/beast_core/containers/beast_AbstractFifo.cpp @@ -125,13 +125,13 @@ void AbstractFifo::finishedRead (int numRead) noexcept } //============================================================================== -//============================================================================== -#if BEAST_UNIT_TESTS -class AbstractFifoTests : public UnitTest +class AbstractFifoTests : public UnitTestType { public: - AbstractFifoTests() : UnitTest ("Abstract Fifo") {} + AbstractFifoTests() : UnitTestType ("Abstract Fifo") + { + } class WriteThread : public Thread { @@ -201,7 +201,7 @@ public: && (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())) && (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize()))) { - expect (false, "prepareToRead returned -ve values"); + expect (false, "prepareToRead returned negative values"); break; } @@ -224,6 +224,6 @@ public: } }; -static AbstractFifoTests fifoUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/diagnostic/beast_UnitTest.cpp b/modules/beast_core/diagnostic/beast_UnitTest.cpp index 9bbaa50511..41903dc311 100644 --- a/modules/beast_core/diagnostic/beast_UnitTest.cpp +++ b/modules/beast_core/diagnostic/beast_UnitTest.cpp @@ -41,7 +41,7 @@ Array& UnitTest::getAllTests() void UnitTest::initialise() {} void UnitTest::shutdown() {} -void UnitTest::performTest (UnitTestRunner* const runner_) +void UnitTest::performTest (UnitTests* const runner_) { bassert (runner_ != nullptr); runner = runner_; @@ -70,42 +70,42 @@ void UnitTest::expect (const bool result, const String& failureMessage) } //============================================================================== -UnitTestRunner::UnitTestRunner() +UnitTests::UnitTests() : currentTest (nullptr), assertOnFailure (true), logPasses (false) { } -UnitTestRunner::~UnitTestRunner() +UnitTests::~UnitTests() { } -void UnitTestRunner::setAssertOnFailure (bool shouldAssert) noexcept +void UnitTests::setAssertOnFailure (bool shouldAssert) noexcept { assertOnFailure = shouldAssert; } -void UnitTestRunner::setPassesAreLogged (bool shouldDisplayPasses) noexcept +void UnitTests::setPassesAreLogged (bool shouldDisplayPasses) noexcept { logPasses = shouldDisplayPasses; } -int UnitTestRunner::getNumResults() const noexcept +int UnitTests::getNumResults() const noexcept { return results.size(); } -const UnitTestRunner::TestResult* UnitTestRunner::getResult (int index) const noexcept +const UnitTests::TestResult* UnitTests::getResult (int index) const noexcept { return results [index]; } -void UnitTestRunner::resultsUpdated() +void UnitTests::resultsUpdated() { } -void UnitTestRunner::runTests (const Array& tests) +void UnitTests::runTests (const Array& tests) { results.clear(); resultsUpdated(); @@ -128,22 +128,22 @@ void UnitTestRunner::runTests (const Array& tests) endTest(); } -void UnitTestRunner::runAllTests() +void UnitTests::runAllTests() { runTests (UnitTest::getAllTests()); } -void UnitTestRunner::logMessage (const String& message) +void UnitTests::logMessage (const String& message) { Logger::writeToLog (message); } -bool UnitTestRunner::shouldAbortTests() +bool UnitTests::shouldAbortTests() { return false; } -void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCategory) +void UnitTests::beginNewTest (UnitTest* const test, const String& subCategory) { endTest(); currentTest = test; @@ -160,7 +160,7 @@ void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCatego resultsUpdated(); } -void UnitTestRunner::endTest() +void UnitTests::endTest() { if (results.size() > 0) { @@ -183,7 +183,7 @@ void UnitTestRunner::endTest() } } -void UnitTestRunner::addPass() +void UnitTests::addPass() { { const ScopedLock sl (results.getLock()); @@ -204,7 +204,7 @@ void UnitTestRunner::addPass() resultsUpdated(); } -void UnitTestRunner::addFail (const String& failureMessage) +void UnitTests::addFail (const String& failureMessage) { { const ScopedLock sl (results.getLock()); diff --git a/modules/beast_core/diagnostic/beast_UnitTest.h b/modules/beast_core/diagnostic/beast_UnitTest.h index 96eb2c89b0..da20626542 100644 --- a/modules/beast_core/diagnostic/beast_UnitTest.h +++ b/modules/beast_core/diagnostic/beast_UnitTest.h @@ -26,46 +26,9 @@ #include "../text/beast_StringArray.h" #include "../containers/beast_OwnedArray.h" -class UnitTestRunner; +class UnitTests; - -//============================================================================== -/** - This is a base class for classes that perform a unit test. - - To write a test using this class, your code should look something like this: - - @code - class MyTest : public UnitTest - { - public: - MyTest() : UnitTest ("Foobar testing") {} - - void runTest() - { - beginTest ("Part 1"); - - expect (myFoobar.doesSomething()); - expect (myFoobar.doesSomethingElse()); - - beginTest ("Part 2"); - - expect (myOtherFoobar.doesSomething()); - expect (myOtherFoobar.doesSomethingElse()); - - ...etc.. - } - }; - - // Creating a static instance will automatically add the instance to the array - // returned by UnitTest::getAllTests(), so the test will be included when you call - // UnitTestRunner::runAllTests() - static MyTest test; - @endcode - - To run a test, use the UnitTestRunner class. - - @see UnitTestRunner +/** Factored base class for unit test template. */ class BEAST_API UnitTest : Uncopyable { @@ -80,11 +43,11 @@ public: /** Returns the name of the test. */ const String& getName() const noexcept { return name; } - /** Runs the test, using the specified UnitTestRunner. + /** Runs the test, using the specified UnitTests. You shouldn't need to call this method directly - use - UnitTestRunner::runTests() instead. + UnitTests::runTests() instead. */ - void performTest (UnitTestRunner* runner); + void performTest (UnitTests* runner); /** Returns the set of all UnitTest objects that currently exist. */ static Array& getAllTests(); @@ -163,10 +126,9 @@ public: private: //============================================================================== const String name; - UnitTestRunner* runner; + UnitTests* runner; }; - //============================================================================== /** Runs a set of unit tests. @@ -174,20 +136,20 @@ private: You can instantiate one of these objects and use it to invoke tests on a set of UnitTest objects. - By using a subclass of UnitTestRunner, you can intercept logging messages and + By using a subclass of UnitTests, you can intercept logging messages and perform custom behaviour when each test completes. @see UnitTest */ -class BEAST_API UnitTestRunner : Uncopyable +class BEAST_API UnitTests : Uncopyable { public: //============================================================================== /** */ - UnitTestRunner(); + UnitTests(); /** Destructor. */ - virtual ~UnitTestRunner(); + virtual ~UnitTests(); /** Runs a set of tests. @@ -199,7 +161,7 @@ public: /** Runs all the UnitTest objects that currently exist. This calls runTests() for all the objects listed in UnitTest::getAllTests(). */ - void runAllTests(); + void runAllTests (); /** Sets a flag to indicate whether an assertion should be triggered if a test fails. This is true by default. @@ -222,11 +184,13 @@ public: { /** The main name of this test (i.e. the name of the UnitTest object being run). */ String unitTestName; + /** The name of the current subcategory (i.e. the name that was set when UnitTest::beginTest() was called). */ String subcategoryName; /** The number of UnitTest::expect() calls that succeeded. */ int passes; + /** The number of UnitTest::expect() calls that failed. */ int failures; @@ -248,34 +212,87 @@ protected: /** Called when the list of results changes. You can override this to perform some sort of behaviour when results are added. */ - virtual void resultsUpdated(); + virtual void resultsUpdated (); /** Logs a message about the current test progress. By default this just writes the message to the Logger class, but you could override this to do something else with the data. */ - virtual void logMessage (const String& message); + virtual void logMessage (String const& message); /** This can be overridden to let the runner know that it should abort the tests as soon as possible, e.g. because the thread needs to stop. */ - virtual bool shouldAbortTests(); + virtual bool shouldAbortTests (); private: - //============================================================================== friend class UnitTest; - UnitTest* currentTest; - String currentSubCategory; - OwnedArray results; - bool assertOnFailure, logPasses; - void beginNewTest (UnitTest* test, const String& subCategory); void endTest(); void addPass(); void addFail (const String& failureMessage); + + UnitTest* currentTest; + String currentSubCategory; + OwnedArray results; + bool assertOnFailure; + bool logPasses; }; +//------------------------------------------------------------------------------ -#endif // BEAST_UNITTEST_BEASTHEADER +/** This is a base class for classes that perform a unit test. + + To write a test using this class, your code should look something like this: + + @code + + class MyTest : public UnitTestType + { + public: + MyTest() : UnitTestType ("Foobar testing") { } + + void runTest() + { + beginTest ("Part 1"); + + expect (myFoobar.doesSomething()); + expect (myFoobar.doesSomethingElse()); + + beginTest ("Part 2"); + + expect (myOtherFoobar.doesSomething()); + expect (myOtherFoobar.doesSomethingElse()); + + //... + } + }; + + // Explicit template instantiation is required to make the unit + // test get automatically added to the set of unit tests. + template class UnitTestType ; + + @endcode + + To run one or more unit tests, use the UnitTests class. + + @see UnitTests +*/ +template +class UnitTestType : public UnitTest +{ +public: + explicit UnitTestType (String const& name) + : UnitTest (name) + { + } + + static Type s_test; +}; + +template +Type UnitTestType ::s_test; + +#endif diff --git a/modules/beast_core/files/beast_File.cpp b/modules/beast_core/files/beast_File.cpp index 6c0706ed02..ab594bb9f3 100644 --- a/modules/beast_core/files/beast_File.cpp +++ b/modules/beast_core/files/beast_File.cpp @@ -921,14 +921,12 @@ MemoryMappedFile::MemoryMappedFile (const File& file, const Range& fileRa openInternal (file, mode); } - //============================================================================== -#if BEAST_UNIT_TESTS -class FileTests : public UnitTest +class FileTests : public UnitTestType { public: - FileTests() : UnitTest ("Files") {} + FileTests() : UnitTestType ("File") {} void runTest() { @@ -1108,6 +1106,7 @@ public: } }; -static FileTests fileUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif + diff --git a/modules/beast_core/json/beast_JSON.cpp b/modules/beast_core/json/beast_JSON.cpp index 268deb8cb5..1b4b98e903 100644 --- a/modules/beast_core/json/beast_JSON.cpp +++ b/modules/beast_core/json/beast_JSON.cpp @@ -531,12 +531,11 @@ void JSON::writeToStream (OutputStream& output, const var& data, const bool allO //============================================================================== //============================================================================== -#if BEAST_UNIT_TESTS -class JSONTests : public UnitTest +class JSONTests : public UnitTestType { public: - JSONTests() : UnitTest ("JSON") {} + JSONTests() : UnitTestType ("JSON") {} static String createRandomWideCharString (Random& r) { @@ -640,6 +639,6 @@ public: } }; -static JSONTests JSONUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/maths/beast_Random.cpp b/modules/beast_core/maths/beast_Random.cpp index aec64a81bb..115b4ae752 100644 --- a/modules/beast_core/maths/beast_Random.cpp +++ b/modules/beast_core/maths/beast_Random.cpp @@ -133,12 +133,11 @@ void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numB } //============================================================================== -#if BEAST_UNIT_TESTS -class RandomTests : public UnitTest +class RandomTests : public UnitTestType { public: - RandomTests() : UnitTest ("Random") {} + RandomTests() : UnitTestType ("Random") {} void runTest() { @@ -166,6 +165,6 @@ public: } }; -static RandomTests randomTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/streams/beast_MemoryInputStream.cpp b/modules/beast_core/streams/beast_MemoryInputStream.cpp index d14900e3b4..a3ea331885 100644 --- a/modules/beast_core/streams/beast_MemoryInputStream.cpp +++ b/modules/beast_core/streams/beast_MemoryInputStream.cpp @@ -87,14 +87,12 @@ int64 MemoryInputStream::getPosition() return position; } - //============================================================================== -#if BEAST_UNIT_TESTS -class MemoryStreamTests : public UnitTest +class MemoryStreamTests : public UnitTestType { public: - MemoryStreamTests() : UnitTest ("MemoryInputStream & MemoryOutputStream") {} + MemoryStreamTests() : UnitTestType ("MemoryStream") {} void runTest() { @@ -150,6 +148,7 @@ public: } }; -static MemoryStreamTests memoryInputStreamUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif + diff --git a/modules/beast_core/text/beast_String.cpp b/modules/beast_core/text/beast_String.cpp index 8bd0c53179..6e15b67ac4 100644 --- a/modules/beast_core/text/beast_String.cpp +++ b/modules/beast_core/text/beast_String.cpp @@ -2074,12 +2074,11 @@ String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) //============================================================================== //============================================================================== -#if BEAST_UNIT_TESTS -class StringTests : public UnitTest +class StringTests : public UnitTestType { public: - StringTests() : UnitTest ("String class") {} + StringTests() : UnitTestType ("String") {} template struct TestUTFConversion @@ -2403,6 +2402,6 @@ public: } }; -static StringTests stringUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/text/beast_TextDiff.cpp b/modules/beast_core/text/beast_TextDiff.cpp index 18645157d6..8453e1cac9 100644 --- a/modules/beast_core/text/beast_TextDiff.cpp +++ b/modules/beast_core/text/beast_TextDiff.cpp @@ -173,13 +173,11 @@ String TextDiff::Change::appliedTo (const String& text) const noexcept } //============================================================================== -//============================================================================== -#if BEAST_UNIT_TESTS -class DiffTests : public UnitTest +class DiffTests : public UnitTestType { public: - DiffTests() : UnitTest ("TextDiff class") {} + DiffTests() : UnitTestType ("TextDiff") {} static String createString() { @@ -231,6 +229,6 @@ public: } }; -static DiffTests diffTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/threads/beast_ChildProcess.cpp b/modules/beast_core/threads/beast_ChildProcess.cpp index 49a928a236..ede53e226c 100644 --- a/modules/beast_core/threads/beast_ChildProcess.cpp +++ b/modules/beast_core/threads/beast_ChildProcess.cpp @@ -57,12 +57,11 @@ String ChildProcess::readAllProcessOutput() } //============================================================================== -#if BEAST_UNIT_TESTS -class ChildProcessTests : public UnitTest +class ChildProcessTests : public UnitTestType { public: - ChildProcessTests() : UnitTest ("ChildProcess") {} + ChildProcessTests() : UnitTestType ("ChildProcess") {} void runTest() { @@ -83,6 +82,6 @@ public: } }; -static ChildProcessTests childProcessUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/threads/beast_Thread.cpp b/modules/beast_core/threads/beast_Thread.cpp index 145c38ba9b..f0ce078a49 100644 --- a/modules/beast_core/threads/beast_Thread.cpp +++ b/modules/beast_core/threads/beast_Thread.cpp @@ -251,12 +251,11 @@ void SpinLock::enter() const noexcept } //============================================================================== -#if BEAST_UNIT_TESTS -class AtomicTests : public UnitTest +class AtomicTests : public UnitTestType { public: - AtomicTests() : UnitTest ("Atomics") {} + AtomicTests() : UnitTestType ("Atomic") {} void runTest() { @@ -351,6 +350,6 @@ public: }; }; -static AtomicTests atomicUnitTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif diff --git a/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp b/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp index 725aba87f1..489e94baf6 100644 --- a/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp +++ b/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp @@ -157,12 +157,11 @@ bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/) } //============================================================================== -#if BEAST_UNIT_TESTS -class GZIPTests : public UnitTest +class GZIPTests : public UnitTestType { public: - GZIPTests() : UnitTest ("GZIP") {} + GZIPTests() : UnitTestType ("GZIP") {} void runTest() { @@ -206,6 +205,6 @@ public: } }; -static GZIPTests gzipTests; - +#if BEAST_UNIT_TESTS +template class UnitTestType ; #endif