Create linked list of CuSuites rather than copy test cases

This commit is contained in:
Ueli Niederer 2020-03-07 23:43:09 +01:00
parent 5bc92d86d5
commit b860872e29
4 changed files with 189 additions and 47 deletions

View File

@ -5,6 +5,7 @@
CuSuite* CuGetSuite(void);
CuSuite* CuStringGetSuite(void);
CuSuite* CuSuiteFrameGetSuite(void);
CuSuite* CuSuiteChainGetSuite(void);
int RunAllTests(void)
{
@ -14,6 +15,7 @@ int RunAllTests(void)
CuSuiteAddSuite(suite, CuGetSuite());
CuSuiteAddSuite(suite, CuStringGetSuite());
CuSuiteAddSuite(suite, CuSuiteFrameGetSuite());
CuSuiteAddSuite(suite, CuSuiteChainGetSuite());
CuSuiteRun(suite);
CuSuiteSummary(suite, output);

110
CuTest.c
View File

@ -273,6 +273,7 @@ void CuSuiteInitWithFrame(CuSuite* testSuite, const CuTestFrame *frame, void *fr
memset(testSuite->list, 0, sizeof(testSuite->list));
testSuite->frame = frame;
testSuite->frameContext = frameContext;
testSuite->next = NULL;
}
CuSuite* CuSuiteNew(void)
@ -309,77 +310,100 @@ void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
{
int i;
for (i = 0 ; i < testSuite2->count ; ++i)
{
CuTest* testCase = testSuite2->list[i];
CuSuiteAdd(testSuite, testCase);
CuSuite *cursor = testSuite;
while (NULL != cursor->next) {
cursor = cursor->next;
}
cursor->next = testSuite2;
testSuite2->next = NULL;
}
void CuSuiteRun(CuSuite* testSuite)
{
const CuTestFrame * const frame = testSuite->frame;
int i;
while (NULL != testSuite) {
const CuTestFrame * const frame = testSuite->frame;
int i;
for (i = 0 ; i < testSuite->count ; ++i)
{
CuTest* testCase = testSuite->list[i];
testCase->context = testSuite->frameContext;
for (i = 0 ; i < testSuite->count ; ++i)
{
CuTest* testCase = testSuite->list[i];
testCase->context = testSuite->frameContext;
TestFunctionRun(testCase, frame->setup);
if (!testCase->failed) {
CuTestRun(testCase);
TestFunctionRun(testCase, frame->teardown);
TestFunctionRun(testCase, frame->setup);
if (!testCase->failed) {
CuTestRun(testCase);
TestFunctionRun(testCase, frame->teardown);
}
testSuite->frameContext = testCase->context;
if (testCase->failed) { testSuite->failCount += 1; }
}
testSuite->frameContext = testCase->context;
if (testCase->failed) { testSuite->failCount += 1; }
testSuite = testSuite->next;
}
}
void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
{
int i;
for (i = 0 ; i < testSuite->count ; ++i)
{
CuTest* testCase = testSuite->list[i];
CuStringAppend(summary, testCase->failed ? "F" : ".");
while (NULL != testSuite) {
int i;
for (i = 0 ; i < testSuite->count ; ++i)
{
CuTest* testCase = testSuite->list[i];
CuStringAppend(summary, testCase->failed ? "F" : ".");
}
testSuite = testSuite->next;
}
CuStringAppend(summary, "\n\n");
}
void CuSuiteDetails(CuSuite* testSuite, CuString* details)
{
int i;
int failCount = 0;
int testCount = 0;
CuString epilogue;
const CuSuite *cursor = testSuite;
if (testSuite->failCount == 0)
{
int passCount = testSuite->count - testSuite->failCount;
const char* testWord = passCount == 1 ? "test" : "tests";
CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
}
else
{
if (testSuite->failCount == 1)
CuStringAppend(details, "There was 1 failure:\n");
else
CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
CuStringInit(&epilogue);
for (i = 0 ; i < testSuite->count ; ++i)
while (NULL != cursor) {
testCount += cursor->count;
int i;
for (i = 0 ; i < cursor->count ; ++i)
{
CuTest* testCase = testSuite->list[i];
CuTest* testCase = cursor->list[i];
if (testCase->failed)
{
failCount++;
CuStringAppendFormat(details, "%d) %s: %s\n",
failCount, testCase->name, testCase->message->buffer);
CuStringAppendFormat(&epilogue, "%d) %s: %s\n",
failCount, testCase->name, testCase->message->buffer);
}
}
CuStringAppend(details, "\n!!!FAILURES!!!\n");
CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
cursor = cursor->next;
}
{
int passCount = testCount - failCount;
if (failCount == 0)
{
const char* testWord = passCount == 1 ? "test" : "tests";
CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
}
else
{
if (failCount == 1)
CuStringAppend(details, "There was 1 failure:\n");
else
CuStringAppendFormat(details, "There were %d failures:\n", failCount);
CuStringAppend(details, epilogue.buffer);
CuStringAppend(details, "\n!!!FAILURES!!!\n");
CuStringAppendFormat(details, "Runs: %d ", testCount);
CuStringAppendFormat(details, "Passes: %d ", passCount);
CuStringAppendFormat(details, "Fails: %d\n", failCount);
}
}
}

View File

@ -103,7 +103,7 @@ typedef struct CuTestFrame {
void (*teardown)(CuTest *tc);
}CuTestFrame;
typedef struct
typedef struct CuSuite
{
int count;
CuTest* list[MAX_TEST_CASES];
@ -111,6 +111,8 @@ typedef struct
const CuTestFrame *frame;
void *frameContext;
struct CuSuite *next;
} CuSuite;
void CuSuiteInit(CuSuite* testSuite);

View File

@ -267,6 +267,7 @@ void TestCuSuiteInit(CuTest* tc)
CuSuiteInit(&ts);
CuAssertTrue(tc, ts.count == 0);
CuAssertTrue(tc, ts.failCount == 0);
CuAssertPtrEquals(tc, NULL, ts.next);
}
void TestCuSuiteNew(CuTest* tc)
@ -274,6 +275,7 @@ void TestCuSuiteNew(CuTest* tc)
CuSuite* ts = CuSuiteNew();
CuAssertTrue(tc, ts->count == 0);
CuAssertTrue(tc, ts->failCount == 0);
CuAssertPtrEquals(tc, NULL, ts->next);
}
void TestCuSuiteAddTest(CuTest* tc)
@ -302,12 +304,14 @@ void TestCuSuiteAddSuite(CuTest* tc)
CuSuiteAdd(ts2, CuTestNew("TestFails4", zTestFails));
CuSuiteAddSuite(ts1, ts2);
CuAssertIntEquals(tc, 4, ts1->count);
CuAssertIntEquals(tc, 2, ts1->count);
CuAssertIntEquals(tc, 2, ts2->count);
CuAssertPtrEquals(tc, ts2, ts1->next);
CuAssertStrEquals(tc, "TestFails1", ts1->list[0]->name);
CuAssertStrEquals(tc, "TestFails2", ts1->list[1]->name);
CuAssertStrEquals(tc, "TestFails3", ts1->list[2]->name);
CuAssertStrEquals(tc, "TestFails4", ts1->list[3]->name);
CuAssertStrEquals(tc, "TestFails3", ts2->list[0]->name);
CuAssertStrEquals(tc, "TestFails4", ts2->list[1]->name);
}
void TestCuSuiteRun(CuTest* tc)
@ -969,6 +973,25 @@ static void TestSuiteSetupTestTeardownWithContext(CuTest *tc) {
CuAssertPtrEquals(tc, &TheTeardownContext, uut->frameContext);
}
static void TestSuitesSetupTestTeardownWithTwoSeparateContexts(CuTest *tc) {
int context = 0;
TheSetupContext = NULL;
TheTestContext = NULL;
TheTeardownContext = NULL;
CuSuite* uut = CuSuiteNew();
CuSuite* uut2 = CuSuiteNewWithFrame(&FrameContextMock, &context);
SUITE_ADD_TEST(uut2, FrameContextTest);
CuSuiteAddSuite(uut, uut2);
CuSuiteRun(uut);
CuAssertPtrEquals(tc, &context, TheSetupContext);
}
CuSuite* CuSuiteFrameGetSuite(void) {
CuSuite* suite = CuSuiteNew();
@ -983,6 +1006,97 @@ CuSuite* CuSuiteFrameGetSuite(void) {
SUITE_ADD_TEST(suite, TestSuiteTestInterruptsUponFailedAssert);
SUITE_ADD_TEST(suite, TestSuiteTeardownInterruptsUponFailedAssert);
SUITE_ADD_TEST(suite, TestSuiteSetupTestTeardownWithContext);
SUITE_ADD_TEST(suite, TestSuitesSetupTestTeardownWithTwoSeparateContexts);
return suite;
}
static void TestSuiteChainSetup(CuTest *tc) {
CuSuite *uut = CuSuiteNew();
CuSuite *uut2 = CuSuiteNew();
SUITE_ADD_TEST(uut2, TestPasses);
SUITE_ADD_TEST(uut2, TestPasses);
CuSuite *uut3 = CuSuiteNew();
SUITE_ADD_TEST(uut3, zTestFails);
SUITE_ADD_TEST(uut3, TestPasses);
CuSuite *uut4 = CuSuiteNew();
SUITE_ADD_TEST(uut4, TestPasses);
CuSuiteAddSuite(uut, uut2);
CuSuiteAddSuite(uut, uut3);
CuSuiteAddSuite(uut, uut4);
CuSuiteRun(uut);
CuTestContextSet(tc, uut);
}
static void TestSuiteChainTeardown(CuTest *tc) {
CuSuite *uut = CuTestContextGet(tc);
CuTestContextSet(tc, NULL);
CuSuite *toDelete = uut;
while (NULL != toDelete) {
CuSuite *next = toDelete->next;
CuSuiteDelete(toDelete);
toDelete = next;
}
}
static const CuTestFrame TestSuiteChainFrame = {
.setup = TestSuiteChainSetup,
.teardown = TestSuiteChainTeardown,
};
static void TestFrameSuiteChainStatistics(CuTest *tc) {
CuSuite *uut = CuTestContextGet(tc);
CuSuite *uut2 = uut->next;
CuSuite *uut3 = uut2->next;
CuSuite *uut4 = uut3->next;
CuAssertIntEquals(tc, 0, uut->count);
CuAssertIntEquals(tc, 0, uut->failCount);
CuAssertIntEquals(tc, 2, uut2->count);
CuAssertIntEquals(tc, 0, uut2->failCount);
CuAssertIntEquals(tc, 2, uut3->count);
CuAssertIntEquals(tc, 1, uut3->failCount);
CuAssertIntEquals(tc, 1, uut4->count);
CuAssertIntEquals(tc, 0, uut4->failCount);
}
static void TestFrameSuiteChainSummary(CuTest *tc) {
CuSuite *uut = CuTestContextGet(tc);
const char *expectedSummary = "..F..\n\n";
CuString summary;
CuStringInit(&summary);
CuSuiteSummary(uut, &summary);
CuAssertStrEquals(tc, expectedSummary, summary.buffer);
}
static void TestFrameSuiteChainDetails(CuTest *tc) {
CuSuite *uut = CuTestContextGet(tc);
const char* expectedDetails = "There was 1 failure:\n"
"1) zTestFails: ../CuTestTest.c:143: test should fail\n\n"
"!!!FAILURES!!!\n"
"Runs: 5 Passes: 4 Fails: 1\n";
CuString details;
CuStringInit(&details);
CuSuiteDetails(uut, &details);
CuAssertStrEquals(tc, expectedDetails, details.buffer);
}
CuSuite* CuSuiteChainGetSuite(void) {
CuSuite* suite = CuSuiteNewWithFrame(&TestSuiteChainFrame, NULL);
SUITE_ADD_TEST(suite, TestFrameSuiteChainStatistics);
SUITE_ADD_TEST(suite, TestFrameSuiteChainSummary);
SUITE_ADD_TEST(suite, TestFrameSuiteChainDetails);
return suite;
}