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* CuGetSuite(void);
CuSuite* CuStringGetSuite(void); CuSuite* CuStringGetSuite(void);
CuSuite* CuSuiteFrameGetSuite(void); CuSuite* CuSuiteFrameGetSuite(void);
CuSuite* CuSuiteChainGetSuite(void);
int RunAllTests(void) int RunAllTests(void)
{ {
@ -14,6 +15,7 @@ int RunAllTests(void)
CuSuiteAddSuite(suite, CuGetSuite()); CuSuiteAddSuite(suite, CuGetSuite());
CuSuiteAddSuite(suite, CuStringGetSuite()); CuSuiteAddSuite(suite, CuStringGetSuite());
CuSuiteAddSuite(suite, CuSuiteFrameGetSuite()); CuSuiteAddSuite(suite, CuSuiteFrameGetSuite());
CuSuiteAddSuite(suite, CuSuiteChainGetSuite());
CuSuiteRun(suite); CuSuiteRun(suite);
CuSuiteSummary(suite, output); CuSuiteSummary(suite, output);

View File

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

View File

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

View File

@ -267,6 +267,7 @@ void TestCuSuiteInit(CuTest* tc)
CuSuiteInit(&ts); CuSuiteInit(&ts);
CuAssertTrue(tc, ts.count == 0); CuAssertTrue(tc, ts.count == 0);
CuAssertTrue(tc, ts.failCount == 0); CuAssertTrue(tc, ts.failCount == 0);
CuAssertPtrEquals(tc, NULL, ts.next);
} }
void TestCuSuiteNew(CuTest* tc) void TestCuSuiteNew(CuTest* tc)
@ -274,6 +275,7 @@ void TestCuSuiteNew(CuTest* tc)
CuSuite* ts = CuSuiteNew(); CuSuite* ts = CuSuiteNew();
CuAssertTrue(tc, ts->count == 0); CuAssertTrue(tc, ts->count == 0);
CuAssertTrue(tc, ts->failCount == 0); CuAssertTrue(tc, ts->failCount == 0);
CuAssertPtrEquals(tc, NULL, ts->next);
} }
void TestCuSuiteAddTest(CuTest* tc) void TestCuSuiteAddTest(CuTest* tc)
@ -302,12 +304,14 @@ void TestCuSuiteAddSuite(CuTest* tc)
CuSuiteAdd(ts2, CuTestNew("TestFails4", zTestFails)); CuSuiteAdd(ts2, CuTestNew("TestFails4", zTestFails));
CuSuiteAddSuite(ts1, ts2); 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, "TestFails1", ts1->list[0]->name);
CuAssertStrEquals(tc, "TestFails2", ts1->list[1]->name); CuAssertStrEquals(tc, "TestFails2", ts1->list[1]->name);
CuAssertStrEquals(tc, "TestFails3", ts1->list[2]->name); CuAssertStrEquals(tc, "TestFails3", ts2->list[0]->name);
CuAssertStrEquals(tc, "TestFails4", ts1->list[3]->name); CuAssertStrEquals(tc, "TestFails4", ts2->list[1]->name);
} }
void TestCuSuiteRun(CuTest* tc) void TestCuSuiteRun(CuTest* tc)
@ -969,6 +973,25 @@ static void TestSuiteSetupTestTeardownWithContext(CuTest *tc) {
CuAssertPtrEquals(tc, &TheTeardownContext, uut->frameContext); 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* CuSuiteFrameGetSuite(void) {
CuSuite* suite = CuSuiteNew(); CuSuite* suite = CuSuiteNew();
@ -983,6 +1006,97 @@ CuSuite* CuSuiteFrameGetSuite(void) {
SUITE_ADD_TEST(suite, TestSuiteTestInterruptsUponFailedAssert); SUITE_ADD_TEST(suite, TestSuiteTestInterruptsUponFailedAssert);
SUITE_ADD_TEST(suite, TestSuiteTeardownInterruptsUponFailedAssert); SUITE_ADD_TEST(suite, TestSuiteTeardownInterruptsUponFailedAssert);
SUITE_ADD_TEST(suite, TestSuiteSetupTestTeardownWithContext); SUITE_ADD_TEST(suite, TestSuiteSetupTestTeardownWithContext);
SUITE_ADD_TEST(suite, TestSuitesSetupTestTeardownWithTwoSeparateContexts);
return suite; 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;
}