feat: pl_test.h 1.0
This commit is contained in:
parent
7ad10ba734
commit
1721dc813a
298
pl_test.h
298
pl_test.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
pl_test
|
||||
pl_test.h
|
||||
Do this:
|
||||
#define PL_TEST_IMPLEMENTATION
|
||||
before you include this file in *one* C or C++ file to create the implementation.
|
||||
@ -9,17 +9,22 @@
|
||||
#include ...
|
||||
#define PL_TEST_IMPLEMENTATION
|
||||
#include "pl_test.h"
|
||||
Notes:
|
||||
* for console color output on windows, define "PL_TEST_WIN32_COLOR" before
|
||||
including the implementation
|
||||
*/
|
||||
|
||||
// library version
|
||||
#define PL_TEST_VERSION "0.1.0"
|
||||
#define PL_TEST_VERSION_NUM 00100
|
||||
// library version (format XYYZZ)
|
||||
#define PL_TEST_VERSION "1.0.0"
|
||||
#define PL_TEST_VERSION_NUM 10000
|
||||
|
||||
/*
|
||||
Index of this file:
|
||||
// [SECTION] header mess
|
||||
// [SECTION] includes
|
||||
// [SECTION] public api
|
||||
// [SECTION] structs
|
||||
// [SECTION] private
|
||||
// [SECTION] c file
|
||||
*/
|
||||
|
||||
@ -34,8 +39,8 @@ Index of this file:
|
||||
// [SECTION] includes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h> // bool
|
||||
#include <stdint.h> // uint32_t
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] forward declarations & basic types
|
||||
@ -43,6 +48,7 @@ Index of this file:
|
||||
|
||||
// forward declarations
|
||||
typedef struct _plTestContext plTestContext;
|
||||
typedef struct _plTestOptions plTestOptions;
|
||||
|
||||
typedef void (*PL_TEST_FUNCTION)(void*);
|
||||
|
||||
@ -52,26 +58,29 @@ typedef void (*PL_TEST_FUNCTION)(void*);
|
||||
|
||||
#define pl_test_register_test(TEST, DATA) pl__test_register_test((TEST), (DATA), #TEST)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] public api
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
plTestContext* pl_create_test_context(void);
|
||||
plTestContext* pl_create_test_context(plTestOptions);
|
||||
|
||||
// tests
|
||||
void pl__test_register_test(PL_TEST_FUNCTION tTest, void* pData, const char* pcName);
|
||||
bool pl_test_run(void);
|
||||
void pl_test_run_suite(const char* pcSuiteName);
|
||||
bool pl_test_finish(void);
|
||||
|
||||
// booleans
|
||||
bool pl_test_expect_true (bool bValue, const char* pcMsg);
|
||||
bool pl_test_expect_false(bool bValue, const char* pcMsg);
|
||||
|
||||
// numbers
|
||||
bool pl_test_expect_int_equal (int iValue0, int iValue1, const char* pcMsg);
|
||||
bool pl_test_expect_int_not_equal (int iValue0, int iValue1, const char* pcMsg);
|
||||
bool pl_test_expect_unsigned_equal (uint32_t uValue0, uint32_t uValue1, const char* pcMsg);
|
||||
bool pl_test_expect_unsigned_not_equal (uint32_t uValue0, uint32_t uValue1, const char* pcMsg);
|
||||
// integers
|
||||
bool pl_test_expect_int_equal (int iValue0, int iValue1, const char* pcMsg);
|
||||
bool pl_test_expect_int_not_equal (int iValue0, int iValue1, const char* pcMsg);
|
||||
bool pl_test_expect_uint32_equal (uint32_t uValue0, uint32_t uValue1, const char* pcMsg);
|
||||
bool pl_test_expect_uint32_not_equal(uint32_t uValue0, uint32_t uValue1, const char* pcMsg);
|
||||
bool pl_test_expect_uint64_equal (uint64_t uValue0, uint64_t uValue1, const char* pcMsg);
|
||||
bool pl_test_expect_uint64_not_equal(uint64_t uValue0, uint64_t uValue1, const char* pcMsg);
|
||||
|
||||
// floating point
|
||||
bool pl_test_expect_float_near_equal (float fValue0, float fValue1, float fError, const char* pcMsg);
|
||||
bool pl_test_expect_float_near_not_equal (float fValue0, float fValue1, float fError, const char* pcMsg);
|
||||
bool pl_test_expect_double_near_equal (double dValue0, double dValue1, double dError, const char* pcMsg);
|
||||
@ -81,6 +90,23 @@ bool pl_test_expect_double_near_not_equal(double dValue0, double dValue1, double
|
||||
bool pl_test_expect_string_equal (const char* pcValue0, const char* pcValue1, const char* pcMsg);
|
||||
bool pl_test_expect_string_not_equal(const char* pcValue0, const char* pcValue1, const char* pcMsg);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] structs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef struct _plTestOptions
|
||||
{
|
||||
bool bPrintSuiteResults;
|
||||
bool bPrintAllPassedChecks;
|
||||
bool bPrintColor;
|
||||
} plTestOptions;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] private
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void pl__test_register_test(PL_TEST_FUNCTION tTest, void* pData, const char* pcName);
|
||||
|
||||
#endif // PL_TEST_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -100,6 +126,13 @@ Index of this file:
|
||||
|
||||
#ifdef PL_TEST_IMPLEMENTATION
|
||||
|
||||
#if defined(PL_TEST_WIN32_COLOR) || defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
static DWORD gtOriginalMode = 0;
|
||||
static HANDLE gtStdOutHandle = 0;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] includes
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -130,12 +163,15 @@ typedef struct _plTest
|
||||
|
||||
typedef struct _plTestContext
|
||||
{
|
||||
plTest* atTests;
|
||||
plTest* ptCurrentTest;
|
||||
uint32_t uTestSize;
|
||||
uint32_t uTestCapacity;
|
||||
uint32_t uFailedTest;
|
||||
bool bPrintPasses;
|
||||
plTest* atTests;
|
||||
plTest* ptCurrentTest;
|
||||
uint32_t uTestSize;
|
||||
uint32_t uTestCapacity;
|
||||
uint32_t uFailedTest;
|
||||
plTestOptions tOptions;
|
||||
|
||||
uint32_t uTotalPassedTests;
|
||||
uint32_t uTotalFailedTests;
|
||||
} plTestContext;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -149,12 +185,26 @@ plTestContext* gptTestContext = NULL;
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
plTestContext*
|
||||
pl_create_test_context(void)
|
||||
pl_create_test_context(plTestOptions tOptions)
|
||||
{
|
||||
|
||||
#if defined(PL_TEST_WIN32_COLOR) || defined(_WIN32)
|
||||
DWORD tCurrentMode = 0;
|
||||
gtStdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if(gtStdOutHandle == INVALID_HANDLE_VALUE)
|
||||
exit(GetLastError());
|
||||
if(!GetConsoleMode(gtStdOutHandle, &tCurrentMode))
|
||||
exit(GetLastError());
|
||||
gtOriginalMode = tCurrentMode;
|
||||
tCurrentMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; // enable ANSI escape codes
|
||||
if(!SetConsoleMode(gtStdOutHandle, tCurrentMode))
|
||||
exit(GetLastError());
|
||||
#endif
|
||||
|
||||
gptTestContext = (plTestContext*)malloc(sizeof(plTestContext));
|
||||
memset(gptTestContext, 0, sizeof(plTestContext));
|
||||
gptTestContext->uTestCapacity = 64;
|
||||
gptTestContext->bPrintPasses = false;
|
||||
gptTestContext->tOptions = tOptions;
|
||||
gptTestContext->atTests = (plTest*)malloc(gptTestContext->uTestCapacity * sizeof(plTest));
|
||||
memset(gptTestContext->atTests, 0, sizeof(gptTestContext->uTestCapacity * sizeof(plTest)));
|
||||
return gptTestContext;
|
||||
@ -179,30 +229,67 @@ pl__test_register_test(PL_TEST_FUNCTION tTest, void* pData, const char* pcName)
|
||||
gptTestContext->atTests[gptTestContext->uTestSize - 1].pData = pData;
|
||||
}
|
||||
|
||||
bool
|
||||
pl_test_run(void)
|
||||
void
|
||||
pl_test_run_suite(const char* pcSuiteName)
|
||||
{
|
||||
printf("\n------%s suite------\n\n", pcSuiteName);
|
||||
|
||||
for(uint32_t i = 0; i < gptTestContext->uTestSize; i++)
|
||||
{
|
||||
|
||||
gptTestContext->ptCurrentTest = &gptTestContext->atTests[i];
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = false;
|
||||
|
||||
printf("-----------------------------------\n");
|
||||
printf("\"%s\" running...\n\n", gptTestContext->ptCurrentTest->pcName);
|
||||
printf("running -> \"%s\"\n", gptTestContext->ptCurrentTest->pcName);
|
||||
gptTestContext->ptCurrentTest->tTest(gptTestContext->ptCurrentTest->pData);
|
||||
|
||||
if(gptTestContext->ptCurrentTest->bFailureOccured)
|
||||
{
|
||||
pl__test_print_red("\n\n\"%s\" failed", NULL, gptTestContext->ptCurrentTest->pcName);
|
||||
pl__test_print_red("%s", NULL, " -> failed");
|
||||
gptTestContext->uFailedTest++;
|
||||
}
|
||||
else
|
||||
printf("\n\n\"%s\" passed\n\n", gptTestContext->ptCurrentTest->pcName);
|
||||
printf("-----------------------------------\n");
|
||||
pl__test_print_green("%s", NULL, " passed");
|
||||
}
|
||||
|
||||
return gptTestContext->uFailedTest == 0;
|
||||
if(gptTestContext->tOptions.bPrintSuiteResults)
|
||||
{
|
||||
printf("\nPassed: ");
|
||||
pl__test_print_green("%u", NULL, gptTestContext->uTestSize - gptTestContext->uFailedTest);
|
||||
|
||||
printf("Failed: ");
|
||||
pl__test_print_red("%u", NULL, gptTestContext->uFailedTest);
|
||||
}
|
||||
|
||||
// printf("\n------End tests------\n\n");
|
||||
|
||||
// reset context
|
||||
gptTestContext->uTotalPassedTests += gptTestContext->uTestSize - gptTestContext->uFailedTest;
|
||||
gptTestContext->uTotalFailedTests += gptTestContext->uFailedTest;
|
||||
gptTestContext->uTestSize = 0;
|
||||
gptTestContext->uFailedTest = 0;
|
||||
gptTestContext->ptCurrentTest = NULL;
|
||||
memset(gptTestContext->atTests, 0, sizeof(plTest) * gptTestContext->uTestCapacity);
|
||||
}
|
||||
|
||||
bool
|
||||
pl_test_finish(void)
|
||||
{
|
||||
|
||||
printf("\n------Results------\n");
|
||||
|
||||
printf("\nTests passed: ");
|
||||
pl__test_print_green("%u", NULL, gptTestContext->uTotalPassedTests);
|
||||
|
||||
printf("Tests failed: ");
|
||||
pl__test_print_red("%u", NULL, gptTestContext->uTotalFailedTests);
|
||||
|
||||
#if defined(PL_TEST_WIN32_COLOR) || defined(_WIN32)
|
||||
if(!SetConsoleMode(gtStdOutHandle, gtOriginalMode))
|
||||
exit(GetLastError());
|
||||
#endif
|
||||
|
||||
return gptTestContext->uTotalFailedTests == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -210,7 +297,8 @@ pl_test_expect_true(bool bValue, const char* pcMsg)
|
||||
{
|
||||
if(bValue)
|
||||
{
|
||||
pl__test_print_green("Value: true | Expected Value: true", pcMsg);
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks)
|
||||
pl__test_print_green("Value: true | Expected Value: true", pcMsg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -229,64 +317,67 @@ pl_test_expect_false(bool bValue, const char* pcMsg)
|
||||
return false;
|
||||
}
|
||||
|
||||
pl__test_print_green("Value: false | Expected Value: false", pcMsg);
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks)
|
||||
pl__test_print_green("Value: false | Expected Value: false", pcMsg);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define pl__test_expect_equal(value0, value1, pcMsg, format) \
|
||||
if((value0) == (value1)) \
|
||||
{ \
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks) \
|
||||
pl__test_print_green(format " equals " format " | Equality Expected", (pcMsg), (value0), (value1)); \
|
||||
return true; \
|
||||
} \
|
||||
pl__test_print_red(format " does not equal " format " | Equality Expected", (pcMsg), (value0), (value1)); \
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true; \
|
||||
return false;
|
||||
|
||||
#define pl__test_expect_not_equal(value0, value1, pcMsg, format) \
|
||||
if((value0) == (value1)) \
|
||||
{ \
|
||||
pl__test_print_red(format " equals " format " | Equality Not Expected", (pcMsg), (value0), (value1)); \
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true; \
|
||||
return false; \
|
||||
} \
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks) \
|
||||
pl__test_print_green(format " does not equal " format " | Equality Expected", (pcMsg), (value0), (value1)); \
|
||||
return true;
|
||||
|
||||
bool
|
||||
pl_test_expect_int_equal(int iValue0, int iValue1, const char* pcMsg)
|
||||
{
|
||||
if(iValue0 == iValue1)
|
||||
{
|
||||
pl__test_print_green("%i equals %i | Equality Expected", pcMsg, iValue0, iValue1);
|
||||
return true;
|
||||
}
|
||||
|
||||
pl__test_print_red("%i does not equal %i | Equality Expected", pcMsg, iValue0, iValue1);
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true;
|
||||
return false;
|
||||
pl__test_expect_equal(iValue0, iValue1, pcMsg, "%i");
|
||||
}
|
||||
|
||||
bool
|
||||
pl_test_expect_int_not_equal(int iValue0, int iValue1, const char* pcMsg)
|
||||
{
|
||||
if(iValue0 == iValue1)
|
||||
{
|
||||
pl__test_print_red("%i equals %i | Equality Not Expected", pcMsg, iValue0, iValue1);
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
pl__test_print_green("%i does not equal %i | Equality Not Expected", pcMsg, iValue0, iValue1);
|
||||
return true;
|
||||
pl__test_expect_not_equal(iValue0, iValue1, pcMsg, "%i");
|
||||
}
|
||||
|
||||
bool
|
||||
pl_test_expect_unsigned_equal(uint32_t uValue0, uint32_t uValue1, const char* pcMsg)
|
||||
pl_test_expect_uint64_equal(uint64_t uValue0, uint64_t uValue1, const char* pcMsg)
|
||||
{
|
||||
if(uValue0 == uValue1)
|
||||
{
|
||||
pl__test_print_green("%u equals %u | Equality Expected", pcMsg, uValue0, uValue1);
|
||||
return true;
|
||||
}
|
||||
|
||||
pl__test_print_red("%u does not equal %u | Equality Expected", pcMsg, uValue0, uValue1);
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true;
|
||||
return false;
|
||||
pl__test_expect_equal(uValue0, uValue1, pcMsg, "%llu");
|
||||
}
|
||||
|
||||
bool
|
||||
pl_test_expect_unsigned_not_equal(uint32_t uValue0, uint32_t uValue1, const char* pcMsg)
|
||||
pl_test_expect_uint64_not_equal(uint64_t uValue0, uint64_t uValue1, const char* pcMsg)
|
||||
{
|
||||
if(uValue0 == uValue1)
|
||||
{
|
||||
pl__test_print_red("%u equals %u | Equality Not Expected", pcMsg, uValue0, uValue1);
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true;
|
||||
return false;
|
||||
}
|
||||
pl__test_expect_not_equal(uValue0, uValue1, pcMsg, "%llu");
|
||||
}
|
||||
|
||||
pl__test_print_green("%u does not equal %u | Equality Not Expected", pcMsg, uValue0, uValue1);
|
||||
return true;
|
||||
bool
|
||||
pl_test_expect_uint32_equal(uint32_t uValue0, uint32_t uValue1, const char* pcMsg)
|
||||
{
|
||||
pl__test_expect_equal(uValue0, uValue1, pcMsg, "%u");
|
||||
}
|
||||
|
||||
bool
|
||||
pl_test_expect_uint32_not_equal(uint32_t uValue0, uint32_t uValue1, const char* pcMsg)
|
||||
{
|
||||
pl__test_expect_not_equal(uValue0, uValue1, pcMsg, "%u");
|
||||
}
|
||||
|
||||
bool
|
||||
@ -306,7 +397,8 @@ pl_test_expect_double_near_equal(double dValue0, double dValue1, double dError,
|
||||
{
|
||||
if(dValue0 >= dValue1 - dError && dValue0 <= dValue1 + dError)
|
||||
{
|
||||
pl__test_print_green("%0.6f equals %0.6f | Equality Expected within %0.6f", pcMsg, dValue0, dValue1, dError);
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks)
|
||||
pl__test_print_green("%0.6f equals %0.6f | Equality Expected within %0.6f", pcMsg, dValue0, dValue1, dError);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -325,7 +417,8 @@ pl_test_expect_double_near_not_equal(double dValue0, double dValue1, double dErr
|
||||
return false;
|
||||
}
|
||||
|
||||
pl__test_print_green("%0.6f does not equal %0.6f | Equality Not Expected within %0.6f", pcMsg, dValue0, dValue1, dError);
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks)
|
||||
pl__test_print_green("%0.6f does not equal %0.6f | Equality Not Expected within %0.6f", pcMsg, dValue0, dValue1, dError);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -334,7 +427,8 @@ pl_test_expect_string_equal(const char* pcValue0, const char* pcValue1, const ch
|
||||
{
|
||||
if(strcmp(pcValue0, pcValue1) == 0)
|
||||
{
|
||||
pl__test_print_green("\"%s\" equals \"%s\" | Equality Expected", pcMsg, pcValue0, pcValue1);
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks)
|
||||
pl__test_print_green("\"%s\" equals \"%s\" | Equality Expected", pcMsg, pcValue0, pcValue1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -348,7 +442,8 @@ pl_test_expect_string_not_equal(const char* pcValue0, const char* pcValue1, cons
|
||||
{
|
||||
if(strcmp(pcValue0, pcValue1) == 0)
|
||||
{
|
||||
pl__test_print_green("\"%s\" equals \"%s\" | Equality Not Expected", pcMsg, pcValue0, pcValue1);
|
||||
if(gptTestContext->tOptions.bPrintAllPassedChecks)
|
||||
pl__test_print_green("\"%s\" equals \"%s\" | Equality Not Expected", pcMsg, pcValue0, pcValue1);
|
||||
gptTestContext->ptCurrentTest->bFailureOccured = true;
|
||||
return false;
|
||||
}
|
||||
@ -374,11 +469,14 @@ pl__test_print_va(const char* cPFormat, va_list args)
|
||||
void static
|
||||
pl__test_print_red(const char* cPFormat, const char* pcMsg, ...)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
printf("[91m");
|
||||
#else
|
||||
printf("\033[91m");
|
||||
#endif
|
||||
if(gptTestContext->tOptions.bPrintColor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
printf("[91m");
|
||||
#else
|
||||
printf("\033[91m");
|
||||
#endif
|
||||
}
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, pcMsg);
|
||||
@ -390,24 +488,27 @@ pl__test_print_red(const char* cPFormat, const char* pcMsg, ...)
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
#ifdef _WIN32
|
||||
printf("[0m");
|
||||
#else
|
||||
printf("\033[0m");
|
||||
#endif
|
||||
if(gptTestContext->tOptions.bPrintColor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
printf("[0m");
|
||||
#else
|
||||
printf("\033[0m");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pl__test_print_green(const char* cPFormat, const char* pcMsg, ...)
|
||||
{
|
||||
if(!gptTestContext->bPrintPasses)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
printf("[92m");
|
||||
#else
|
||||
printf("\033[92m");
|
||||
#endif
|
||||
if(gptTestContext->tOptions.bPrintColor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
printf("[92m");
|
||||
#else
|
||||
printf("\033[92m");
|
||||
#endif
|
||||
}
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, pcMsg);
|
||||
@ -419,11 +520,14 @@ pl__test_print_green(const char* cPFormat, const char* pcMsg, ...)
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
#ifdef _WIN32
|
||||
printf("[0m");
|
||||
#else
|
||||
printf("\033[0m");
|
||||
#endif
|
||||
if(gptTestContext->tOptions.bPrintColor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
printf("[0m");
|
||||
#else
|
||||
printf("\033[0m");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PL_TEST_IMPLEMENTATION
|
Loading…
Reference in New Issue
Block a user