From b860872e2958630360acbbb3f6940560c94e8e4e Mon Sep 17 00:00:00 2001 From: Ueli Niederer Date: Sat, 7 Mar 2020 23:43:09 +0100 Subject: [PATCH] Create linked list of CuSuites rather than copy test cases --- AllTests.c | 2 + CuTest.c | 110 ++++++++++++++++++++++++++++------------------ CuTest.h | 4 +- CuTestTest.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 189 insertions(+), 47 deletions(-) diff --git a/AllTests.c b/AllTests.c index 929bb4a..4a2e197 100644 --- a/AllTests.c +++ b/AllTests.c @@ -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); diff --git a/CuTest.c b/CuTest.c index dfd3587..bec2438 100644 --- a/CuTest.c +++ b/CuTest.c @@ -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); + } } } diff --git a/CuTest.h b/CuTest.h index f01a0ac..80f9d53 100644 --- a/CuTest.h +++ b/CuTest.h @@ -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); diff --git a/CuTestTest.c b/CuTestTest.c index 6c8be5f..e075186 100644 --- a/CuTestTest.c +++ b/CuTestTest.c @@ -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; +} +