diff --git a/Subtrees/beast/modules/beast_core/containers/beast_AbstractFifo.cpp b/Subtrees/beast/modules/beast_core/containers/beast_AbstractFifo.cpp index 004a8b94e2..32f3ff5f70 100644 --- a/Subtrees/beast/modules/beast_core/containers/beast_AbstractFifo.cpp +++ b/Subtrees/beast/modules/beast_core/containers/beast_AbstractFifo.cpp @@ -129,7 +129,7 @@ void AbstractFifo::finishedRead (int numRead) noexcept class AbstractFifoTests : public UnitTest { public: - AbstractFifoTests() : UnitTest ("Abstract Fifo") + AbstractFifoTests() : UnitTest ("Abstract Fifo", "beast") { } diff --git a/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.cpp b/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.cpp index 056d5fb248..8905ed2a12 100644 --- a/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.cpp +++ b/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.cpp @@ -21,8 +21,13 @@ */ //============================================================================== -UnitTest::UnitTest (const String& name_) - : name (name_), runner (nullptr) +UnitTest::UnitTest (String const& name, + String const& group, + When when) + : m_name (name) + , m_group (group) + , m_when (when) + , m_runner (nullptr) { getAllTests().add (this); } @@ -32,19 +37,25 @@ UnitTest::~UnitTest() getAllTests().removeFirstMatchingValue (this); } -Array& UnitTest::getAllTests() +UnitTest::TestList& UnitTest::getAllTests() { - static Array tests; - return tests; + static TestList s_tests; + + return s_tests; } -void UnitTest::initialise() {} -void UnitTest::shutdown() {} - -void UnitTest::performTest (UnitTests* const runner_) +void UnitTest::initialise() { - bassert (runner_ != nullptr); - runner = runner_; +} + +void UnitTest::shutdown() +{ +} + +void UnitTest::performTest (UnitTests* const runner) +{ + bassert (runner != nullptr); + m_runner = runner; initialise(); runTest(); @@ -53,23 +64,24 @@ void UnitTest::performTest (UnitTests* const runner_) void UnitTest::logMessage (const String& message) { - runner->logMessage (message); + m_runner->logMessage (message); } void UnitTest::beginTest (const String& testName) { - runner->beginNewTest (this, testName); + m_runner->beginNewTest (this, testName); } void UnitTest::expect (const bool result, const String& failureMessage) { if (result) - runner->addPass(); + m_runner->addPass(); else - runner->addFail (failureMessage); + m_runner->addFail (failureMessage); } //============================================================================== + UnitTests::UnitTests() : currentTest (nullptr), assertOnFailure (true), @@ -105,35 +117,52 @@ void UnitTests::resultsUpdated() { } +void UnitTests::runTest (UnitTest& test) +{ + try + { + test.performTest (this); + } + catch (std::exception& e) + { + String s; + s << "Got an exception: " << e.what (); + addFail (s); + } + catch (...) + { + addFail ("Got an unhandled exception"); + } +} + void UnitTests::runTest (String const& name) { results.clear(); resultsUpdated(); - Array& tests = UnitTest::getAllTests (); + UnitTest::TestList& tests (UnitTest::getAllTests ()); for (int i = 0; i < tests.size(); ++i) { UnitTest& test = *tests [i]; - if (test.getName () == name) + if (test.getGroup () == name && test.getWhen () == UnitTest::runAlways) { - try - { - test.performTest (this); - } - catch (...) - { - addFail ("An unhandled exception was thrown!"); - } - + runTest (test); + } + else if (test.getName () == name) + { + runTest (test); break; } + } } -void UnitTests::runTests (const Array& tests) +void UnitTests::runAllTests () { + UnitTest::TestList& tests (UnitTest::getAllTests ()); + results.clear(); resultsUpdated(); @@ -142,22 +171,14 @@ void UnitTests::runTests (const Array& tests) if (shouldAbortTests()) break; - try - { - tests.getUnchecked(i)->performTest (this); - } - catch (...) - { - addFail ("An unhandled exception was thrown!"); - } + UnitTest& test = *tests [i]; + + if (test.getWhen () == UnitTest::runAlways) + runTest (test); } endTest(); -} -void UnitTests::runAllTests() -{ - runTests (UnitTest::getAllTests()); } void UnitTests::logMessage (const String& message) @@ -177,7 +198,7 @@ void UnitTests::beginNewTest (UnitTest* const test, const String& subCategory) TestResult* const r = new TestResult(); results.add (r); - r->unitTestName = test->getName(); + r->unitTestName = test->getGroup() + "::" + test->getName(); r->subcategoryName = subCategory; r->passes = 0; r->failures = 0; diff --git a/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.h b/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.h index 6945bf7660..f7e8466c18 100644 --- a/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.h +++ b/Subtrees/beast/modules/beast_core/diagnostic/beast_UnitTest.h @@ -28,7 +28,6 @@ #include "../containers/beast_OwnedArray.h" 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: @@ -70,15 +69,38 @@ class UnitTests; class BEAST_API UnitTest : Uncopyable { public: + enum When + { + runAlways, + runManual + }; + + /** The type of a list of tests. + */ + typedef Array TestList; + //============================================================================== - /** Creates a test with the given name. */ - explicit UnitTest (String const& name); + /** Creates a test with the given name, group, and run option. + + The group is used when you want to run all tests in a particular group + instead of all tests in general. The run option allows you to write some + tests that are only available manually. For examplem, a performance unit + test that takes a long time which you might not want to run every time + you run all tests. + */ + explicit UnitTest (String const& name, String const& group = "", When when = runAlways); /** Destructor. */ virtual ~UnitTest(); /** Returns the name of the test. */ - const String& getName() const noexcept { return name; } + const String& getName() const noexcept { return m_name; } + + /** Returns the group of the test. */ + String const& getGroup () const noexcept { return m_group; } + + /** Returns the run option of the test. */ + When getWhen () const noexcept { return m_when; } /** Runs the test, using the specified UnitTests. You shouldn't need to call this method directly - use @@ -87,7 +109,7 @@ public: void performTest (UnitTests* runner); /** Returns the set of all UnitTest objects that currently exist. */ - static Array& getAllTests(); + static TestList& getAllTests(); //============================================================================== /** You can optionally implement this method to set up your test. @@ -156,14 +178,16 @@ public: //============================================================================== /** Writes a message to the test log. - This can only be called from within your runTest() method. + This can only be called during your runTest() method. */ void logMessage (const String& message); private: //============================================================================== - const String name; - UnitTests* runner; + String const m_name; + String const m_group; + When const m_when; + UnitTests* m_runner; }; //============================================================================== @@ -188,17 +212,15 @@ public: /** Destructor. */ virtual ~UnitTests(); - /** Run a particular test. + /** Run the specified unit test. + + Subclasses can override this to do extra stuff. */ + virtual void runTest (UnitTest& test); + + /** Run a particular test or group. */ void runTest (String const& name); - /** Runs a set of tests. - - The tests are performed in order, and the results are logged. To run all the - registered UnitTest objects that exist, use runAllTests(). - */ - void runTests (const Array& tests); - /** Runs all the UnitTest objects that currently exist. This calls runTests() for all the objects listed in UnitTest::getAllTests(). */ diff --git a/Subtrees/beast/modules/beast_core/files/beast_File.cpp b/Subtrees/beast/modules/beast_core/files/beast_File.cpp index f3a4f8713a..55bc1cafbd 100644 --- a/Subtrees/beast/modules/beast_core/files/beast_File.cpp +++ b/Subtrees/beast/modules/beast_core/files/beast_File.cpp @@ -926,7 +926,7 @@ MemoryMappedFile::MemoryMappedFile (const File& file, const Range& fileRa class FileTests : public UnitTest { public: - FileTests() : UnitTest ("File") {} + FileTests() : UnitTest ("File", "beast") {} void runTest() { diff --git a/Subtrees/beast/modules/beast_core/files/beast_RandomAccessFile.cpp b/Subtrees/beast/modules/beast_core/files/beast_RandomAccessFile.cpp index 33febec9c4..0131f520a0 100644 --- a/Subtrees/beast/modules/beast_core/files/beast_RandomAccessFile.cpp +++ b/Subtrees/beast/modules/beast_core/files/beast_RandomAccessFile.cpp @@ -158,7 +158,7 @@ class RandomAccessFileTests : public UnitTest { public: RandomAccessFileTests () - : UnitTest ("RandomAccessFile") + : UnitTest ("RandomAccessFile", "beast") , numRecords (1000) , seedValue (50) { diff --git a/Subtrees/beast/modules/beast_core/json/beast_JSON.cpp b/Subtrees/beast/modules/beast_core/json/beast_JSON.cpp index 518c5d45a8..216bdf7741 100644 --- a/Subtrees/beast/modules/beast_core/json/beast_JSON.cpp +++ b/Subtrees/beast/modules/beast_core/json/beast_JSON.cpp @@ -535,7 +535,7 @@ void JSON::writeToStream (OutputStream& output, const var& data, const bool allO class JSONTests : public UnitTest { public: - JSONTests() : UnitTest ("JSON") { } + JSONTests() : UnitTest ("JSON", "beast") { } static String createRandomWideCharString (Random& r) { diff --git a/Subtrees/beast/modules/beast_core/maths/beast_Random.cpp b/Subtrees/beast/modules/beast_core/maths/beast_Random.cpp index 4b8ac22b51..9f381e8479 100644 --- a/Subtrees/beast/modules/beast_core/maths/beast_Random.cpp +++ b/Subtrees/beast/modules/beast_core/maths/beast_Random.cpp @@ -159,7 +159,7 @@ void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numB class RandomTests : public UnitTest { public: - RandomTests() : UnitTest ("Random") {} + RandomTests() : UnitTest ("Random", "beast") {} void runTest() { diff --git a/Subtrees/beast/modules/beast_core/streams/beast_MemoryInputStream.cpp b/Subtrees/beast/modules/beast_core/streams/beast_MemoryInputStream.cpp index eef9e80fd0..2cdd4198a2 100644 --- a/Subtrees/beast/modules/beast_core/streams/beast_MemoryInputStream.cpp +++ b/Subtrees/beast/modules/beast_core/streams/beast_MemoryInputStream.cpp @@ -92,7 +92,7 @@ int64 MemoryInputStream::getPosition() class MemoryStreamTests : public UnitTest { public: - MemoryStreamTests() : UnitTest ("MemoryStream") { } + MemoryStreamTests() : UnitTest ("MemoryStream", "beast") { } void runTest() { diff --git a/Subtrees/beast/modules/beast_core/text/beast_String.cpp b/Subtrees/beast/modules/beast_core/text/beast_String.cpp index dff203b2eb..55ad6d5929 100644 --- a/Subtrees/beast/modules/beast_core/text/beast_String.cpp +++ b/Subtrees/beast/modules/beast_core/text/beast_String.cpp @@ -2078,7 +2078,7 @@ String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) class StringTests : public UnitTest { public: - StringTests() : UnitTest ("String") { } + StringTests() : UnitTest ("String", "beast") { } template struct TestUTFConversion diff --git a/Subtrees/beast/modules/beast_core/text/beast_TextDiff.cpp b/Subtrees/beast/modules/beast_core/text/beast_TextDiff.cpp index 8589683327..6da5b587bd 100644 --- a/Subtrees/beast/modules/beast_core/text/beast_TextDiff.cpp +++ b/Subtrees/beast/modules/beast_core/text/beast_TextDiff.cpp @@ -177,7 +177,7 @@ String TextDiff::Change::appliedTo (const String& text) const noexcept class DiffTests : public UnitTest { public: - DiffTests() : UnitTest ("TextDiff") {} + DiffTests() : UnitTest ("TextDiff", "beast") {} static String createString() { diff --git a/Subtrees/beast/modules/beast_core/threads/beast_ChildProcess.cpp b/Subtrees/beast/modules/beast_core/threads/beast_ChildProcess.cpp index da7a9accd9..0c08aa82d4 100644 --- a/Subtrees/beast/modules/beast_core/threads/beast_ChildProcess.cpp +++ b/Subtrees/beast/modules/beast_core/threads/beast_ChildProcess.cpp @@ -61,7 +61,7 @@ String ChildProcess::readAllProcessOutput() class ChildProcessTests : public UnitTest { public: - ChildProcessTests() : UnitTest ("ChildProcess") {} + ChildProcessTests() : UnitTest ("ChildProcess", "beast") {} void runTest() { diff --git a/Subtrees/beast/modules/beast_core/threads/beast_Thread.cpp b/Subtrees/beast/modules/beast_core/threads/beast_Thread.cpp index 1ffb1b9c6e..7685cfa00a 100644 --- a/Subtrees/beast/modules/beast_core/threads/beast_Thread.cpp +++ b/Subtrees/beast/modules/beast_core/threads/beast_Thread.cpp @@ -255,7 +255,7 @@ void SpinLock::enter() const noexcept class AtomicTests : public UnitTest { public: - AtomicTests() : UnitTest ("Atomic") {} + AtomicTests() : UnitTest ("Atomic", "beast") {} void runTest() { diff --git a/Subtrees/beast/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp b/Subtrees/beast/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp index da68fe9941..7d66da47a0 100644 --- a/Subtrees/beast/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp +++ b/Subtrees/beast/modules/beast_core/zip/beast_GZIPCompressorOutputStream.cpp @@ -161,7 +161,7 @@ bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/) class GZIPTests : public UnitTest { public: - GZIPTests() : UnitTest ("GZIP") {} + GZIPTests() : UnitTest ("GZIP", "beast") {} void runTest() { diff --git a/Subtrees/beast/modules/beast_crypto/math/beast_UnsignedInteger.cpp b/Subtrees/beast/modules/beast_crypto/math/beast_UnsignedInteger.cpp index a0532d38fa..b9a2b5d18f 100644 --- a/Subtrees/beast/modules/beast_crypto/math/beast_UnsignedInteger.cpp +++ b/Subtrees/beast/modules/beast_crypto/math/beast_UnsignedInteger.cpp @@ -20,7 +20,7 @@ class UnsignedIntegerTests : public UnitTest { public: - UnsignedIntegerTests () : UnitTest ("UnsignedInteger") + UnsignedIntegerTests () : UnitTest ("UnsignedInteger", "beast") { }