Use template for UnitTest

This commit is contained in:
Vinnie Falco
2013-07-13 04:48:53 -07:00
parent 4a00e8feed
commit a1289eb502
13 changed files with 148 additions and 139 deletions

View File

@@ -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"

View File

@@ -125,13 +125,13 @@ void AbstractFifo::finishedRead (int numRead) noexcept
}
//==============================================================================
//==============================================================================
#if BEAST_UNIT_TESTS
class AbstractFifoTests : public UnitTest
class AbstractFifoTests : public UnitTestType <AbstractFifoTests>
{
public:
AbstractFifoTests() : UnitTest ("Abstract Fifo") {}
AbstractFifoTests() : UnitTestType <AbstractFifoTests> ("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 <AbstractFifoTests>;
#endif

View File

@@ -41,7 +41,7 @@ Array<UnitTest*>& 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<UnitTest*>& tests)
void UnitTests::runTests (const Array<UnitTest*>& tests)
{
results.clear();
resultsUpdated();
@@ -128,22 +128,22 @@ void UnitTestRunner::runTests (const Array<UnitTest*>& 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());

View File

@@ -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<UnitTest*>& 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 <TestResult, CriticalSection> 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 <TestResult, CriticalSection> 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 <MyTest>
{
public:
MyTest() : UnitTestType <MyTest> ("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 <MyTest>;
@endcode
To run one or more unit tests, use the UnitTests class.
@see UnitTests
*/
template <class Type>
class UnitTestType : public UnitTest
{
public:
explicit UnitTestType (String const& name)
: UnitTest (name)
{
}
static Type s_test;
};
template <class Type>
Type UnitTestType <Type>::s_test;
#endif

View File

@@ -921,14 +921,12 @@ MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRa
openInternal (file, mode);
}
//==============================================================================
#if BEAST_UNIT_TESTS
class FileTests : public UnitTest
class FileTests : public UnitTestType <FileTests>
{
public:
FileTests() : UnitTest ("Files") {}
FileTests() : UnitTestType <FileTests> ("File") {}
void runTest()
{
@@ -1108,6 +1106,7 @@ public:
}
};
static FileTests fileUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <FileTests>;
#endif

View File

@@ -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 <JSONTests>
{
public:
JSONTests() : UnitTest ("JSON") {}
JSONTests() : UnitTestType <JSONTests> ("JSON") {}
static String createRandomWideCharString (Random& r)
{
@@ -640,6 +639,6 @@ public:
}
};
static JSONTests JSONUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <JSONTests>;
#endif

View File

@@ -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 <RandomTests>
{
public:
RandomTests() : UnitTest ("Random") {}
RandomTests() : UnitTestType <RandomTests> ("Random") {}
void runTest()
{
@@ -166,6 +165,6 @@ public:
}
};
static RandomTests randomTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <RandomTests>;
#endif

View File

@@ -87,14 +87,12 @@ int64 MemoryInputStream::getPosition()
return position;
}
//==============================================================================
#if BEAST_UNIT_TESTS
class MemoryStreamTests : public UnitTest
class MemoryStreamTests : public UnitTestType <MemoryStreamTests>
{
public:
MemoryStreamTests() : UnitTest ("MemoryInputStream & MemoryOutputStream") {}
MemoryStreamTests() : UnitTestType <MemoryStreamTests> ("MemoryStream") {}
void runTest()
{
@@ -150,6 +148,7 @@ public:
}
};
static MemoryStreamTests memoryInputStreamUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <MemoryStreamTests>;
#endif

View File

@@ -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 <StringTests>
{
public:
StringTests() : UnitTest ("String class") {}
StringTests() : UnitTestType <StringTests> ("String") {}
template <class CharPointerType>
struct TestUTFConversion
@@ -2403,6 +2402,6 @@ public:
}
};
static StringTests stringUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <StringTests>;
#endif

View File

@@ -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 <DiffTests>
{
public:
DiffTests() : UnitTest ("TextDiff class") {}
DiffTests() : UnitTestType <DiffTests> ("TextDiff") {}
static String createString()
{
@@ -231,6 +229,6 @@ public:
}
};
static DiffTests diffTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <DiffTests>;
#endif

View File

@@ -57,12 +57,11 @@ String ChildProcess::readAllProcessOutput()
}
//==============================================================================
#if BEAST_UNIT_TESTS
class ChildProcessTests : public UnitTest
class ChildProcessTests : public UnitTestType <ChildProcessTests>
{
public:
ChildProcessTests() : UnitTest ("ChildProcess") {}
ChildProcessTests() : UnitTestType <ChildProcessTests> ("ChildProcess") {}
void runTest()
{
@@ -83,6 +82,6 @@ public:
}
};
static ChildProcessTests childProcessUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <ChildProcessTests>;
#endif

View File

@@ -251,12 +251,11 @@ void SpinLock::enter() const noexcept
}
//==============================================================================
#if BEAST_UNIT_TESTS
class AtomicTests : public UnitTest
class AtomicTests : public UnitTestType <AtomicTests>
{
public:
AtomicTests() : UnitTest ("Atomics") {}
AtomicTests() : UnitTestType <AtomicTests> ("Atomic") {}
void runTest()
{
@@ -351,6 +350,6 @@ public:
};
};
static AtomicTests atomicUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <AtomicTests>;
#endif

View File

@@ -157,12 +157,11 @@ bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/)
}
//==============================================================================
#if BEAST_UNIT_TESTS
class GZIPTests : public UnitTest
class GZIPTests : public UnitTestType <GZIPTests>
{
public:
GZIPTests() : UnitTest ("GZIP") {}
GZIPTests() : UnitTestType <GZIPTests> ("GZIP") {}
void runTest()
{
@@ -206,6 +205,6 @@ public:
}
};
static GZIPTests gzipTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <GZIPTests>;
#endif