#include "UnitTest++/UnitTestPP.h"
#include "RecordingReporter.h"
#include "UnitTest++/ReportAssert.h"
#include "UnitTest++/TestList.h"
#include "UnitTest++/TimeHelpers.h"
#include "UnitTest++/TimeConstraint.h"
#include "UnitTest++/ReportAssertImpl.h"
using namespace UnitTest;
namespace
{
struct MockTest : public Test
{
MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1)
: Test(testName)
, success(success_)
, asserted(assert_)
, count(count_)
{}
virtual void RunImpl() const
{
TestResults& testResults_ = *CurrentTest::Results();
for (int i=0; i < count; ++i)
{
if (asserted)
{
ReportAssert("desc", "file", 0);
}
else if (!success)
{
testResults_.OnTestFailure(m_details, "message");
}
}
}
bool const success;
bool const asserted;
int const count;
};
struct FixtureBase
{
FixtureBase()
: runner(reporter)
{}
template
int RunTestsIf(TestList const& list, char const* suiteName,
const Predicate& predicate, int maxTestTimeInMs)
{
TestResults* oldResults = CurrentTest::Results();
const TestDetails* oldDetails = CurrentTest::Details();
int result = runner.RunTestsIf(list, suiteName, predicate, maxTestTimeInMs);
CurrentTest::Results() = oldResults;
CurrentTest::Details() = oldDetails;
return result;
}
TestRunner runner;
RecordingReporter reporter;
};
struct TestRunnerFixture : public FixtureBase
{
TestList list;
};
TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly)
{
MockTest test("goodtest", true, false);
list.Add(&test);
RunTestsIf(list, NULL, True(), 0);
CHECK_EQUAL(1, reporter.testRunCount);
CHECK_EQUAL("goodtest", reporter.lastStartedTest);
}
TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly)
{
MockTest test("goodtest", true, false);
list.Add(&test);
RunTestsIf(list, NULL, True(), 0);
CHECK_EQUAL(1, reporter.testFinishedCount);
CHECK_EQUAL("goodtest", reporter.lastFinishedTest);
}
class SlowTest : public Test
{
public:
SlowTest()
: Test("slow", "somesuite", "filename", 123)
{}
virtual void RunImpl() const
{
TimeHelpers::SleepMs(20);
}
};
TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime)
{
SlowTest test;
list.Add(&test);
// Using UnitTest::Timer here is arguably a bit hokey and self-referential, but
// it should guarantee that the test time recorded is less than that plus the
// overhead of RunTestsIf -- the only thing we can reliably assert without
// reworking the test to not use sleeps at all
Timer actual;
actual.Start();
RunTestsIf(list, NULL, True(), 0);
CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime m_details.testName, name));
}
char const* name;
};
TEST(TestMockPredicateBehavesCorrectly)
{
RunTestIfNameIs predicate("pass");
Test pass("pass");
Test fail("fail");
CHECK(predicate(&pass));
CHECK(!predicate(&fail));
}
TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate)
{
Test should_run("goodtest");
list.Add(&should_run);
Test should_not_run("badtest");
list.Add(&should_not_run);
RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0);
CHECK_EQUAL(1, reporter.testRunCount);
CHECK_EQUAL("goodtest", reporter.lastStartedTest);
}
TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate)
{
Test runningTest1("goodtest", "suite");
Test skippedTest2("goodtest");
Test skippedTest3("badtest", "suite");
Test skippedTest4("badtest");
list.Add(&runningTest1);
list.Add(&skippedTest2);
list.Add(&skippedTest3);
list.Add(&skippedTest4);
RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0);
CHECK_EQUAL(1, reporter.testRunCount);
CHECK_EQUAL("goodtest", reporter.lastStartedTest);
CHECK_EQUAL("suite", reporter.lastStartedSuite);
}
}