Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4036,7 +4036,7 @@ sdl_compile_definitions(
##### Tests #####

if(SDL_TEST_LIBRARY)
file(GLOB TEST_SOURCES "${SDL3_SOURCE_DIR}/src/test/*.c")
file(GLOB TEST_SOURCES "${SDL3_SOURCE_DIR}/src/test/*.c" "${SDL3_SOURCE_DIR}/src/test/*.h")
target_sources(SDL3_test PRIVATE ${TEST_SOURCES})
if(APPLE)
set_target_properties(SDL3_test PROPERTIES
Expand Down
3 changes: 3 additions & 0 deletions VisualC-GDK/SDL_test/SDL_test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@
<TreatWarningAsError>$(TreatWarningsAsError)</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\test\SDL_test_internal.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\test\SDL_test_assert.c" />
<ClCompile Include="..\..\src\test\SDL_test_common.c" />
Expand Down
3 changes: 3 additions & 0 deletions VisualC/SDL_test/SDL_test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@
<TreatWarningAsError>$(TreatWarningsAsError)</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\test\SDL_test_internal.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\test\SDL_test_assert.c" />
<ClCompile Include="..\..\src\test\SDL_test_common.c" />
Expand Down
8 changes: 8 additions & 0 deletions include/SDL3/SDL_test_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@
extern "C" {
#endif

/**
* Prints given message with a timestamp in the TEST category and given priority.
*
* \param priority Priority of the message
* \param fmt Message to be logged
*/
void SDLCALL SDLTest_LogMessage(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...);

/**
* Prints given message with a timestamp in the TEST category and INFO priority.
*
Expand Down
58 changes: 28 additions & 30 deletions src/test/SDL_test_assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,32 @@

*/
#include <SDL3/SDL_test.h>

/* Enable to have color in logs */
#if 1
#define COLOR_RED "\033[0;31m"
#define COLOR_GREEN "\033[0;32m"
#define COLOR_YELLOW "\033[0;93m"
#define COLOR_BLUE "\033[0;94m"
#define COLOR_END "\033[0m"
#else
#define COLOR_RED ""
#define COLOR_GREEN ""
#define COLOR_BLUE ""
#define COLOR_YELLOW ""
#define COLOR_END ""
#endif

/* Assert check message format */
#define SDLTEST_ASSERT_CHECK_FORMAT "Assert '%s': %s"

/* Assert summary message format */
#define SDLTEST_ASSERT_SUMMARY_FORMAT "Assert Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_RED "Failed=%d" COLOR_END
#define SDLTEST_ASSERT_SUMMARY_FORMAT_OK "Assert Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_GREEN "Failed=%d" COLOR_END
#include "SDL_test_internal.h"

/* ! counts the failed asserts */
static int SDLTest_AssertsFailed = 0;

/* ! counts the passed asserts */
static int SDLTest_AssertsPassed = 0;

static void SDLTest_LogAssertMessage(bool success, const char *assertion)
{
SDL_LogPriority priority;
const char *color;
const char *message;

if (success) {
priority = SDL_LOG_PRIORITY_INFO;
color = COLOR_GREEN;
message = "Passed";
} else {
priority = SDL_LOG_PRIORITY_ERROR;
color = COLOR_RED;
message = "Failed";
}
SDLTest_LogMessage(priority, "Assert '%s': %s%s%s", assertion, color, message, COLOR_END);
}

/*
* Assert that logs and break execution flow on failures (i.e. for harness errors).
*/
Expand Down Expand Up @@ -89,10 +86,10 @@ int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char
/* Log pass or fail message */
if (assertCondition == ASSERT_FAIL) {
SDLTest_AssertsFailed++;
SDLTest_LogError(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, COLOR_RED "Failed" COLOR_END);
SDLTest_LogAssertMessage(false, logMessage);
} else {
SDLTest_AssertsPassed++;
SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogAssertMessage(true, logMessage);
}

return assertCondition;
Expand All @@ -114,7 +111,7 @@ void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription,

/* Log pass message */
SDLTest_AssertsPassed++;
SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogAssertMessage(true, logMessage);
}

/*
Expand All @@ -133,11 +130,12 @@ void SDLTest_ResetAssertSummary(void)
void SDLTest_LogAssertSummary(void)
{
int totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed;
if (SDLTest_AssertsFailed == 0) {
SDLTest_Log(SDLTEST_ASSERT_SUMMARY_FORMAT_OK, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed);
} else {
SDLTest_LogError(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed);
}
bool success = SDLTest_AssertsFailed == 0;

SDLTest_LogMessage(success ? SDL_LOG_PRIORITY_INFO : SDL_LOG_PRIORITY_ERROR,
"Assert Summary: Total=%d " "%s" "Passed=%d" "%s" " " "%s" "Failed=%d" "%s",
totalAsserts, COLOR_GREEN, SDLTest_AssertsPassed, COLOR_END,
success ? COLOR_GREEN : COLOR_RED, SDLTest_AssertsFailed, COLOR_END);
}

/*
Expand Down
19 changes: 19 additions & 0 deletions src/test/SDL_test_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,28 @@

/* Ported from original test/common.c file. */
#include <SDL3/SDL_test.h>
#include "SDL_test_internal.h"

#define SDL_MAIN_NOIMPL
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>

bool SDLTest_Color = true;

static bool get_environment_bool_variable(const char *name)
{
const char *var_string = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), name);
if (!var_string || var_string[0] == '\0') {
return false;
}
return true;
}

static const char *common_usage[] = {
"[-h | --help]",
"[--trackmem]",
"[--randmem]",
"[--no-color]",
"[--info all|video|modes|render|event|event_motion]",
"[--log all|error|system|audio|video|render|input]",
NULL
Expand Down Expand Up @@ -142,6 +155,10 @@ static int SDLCALL SDLTest_CommonStateParseCommonArguments(void *data, char **ar
/* Already handled in SDLTest_CommonCreateState() */
return 1;
}
if (SDL_strcasecmp(argv[index], "--no-color") == 0) {
SDLTest_Color = false;
return 1;
}
if (SDL_strcasecmp(argv[index], "--randmem") == 0) {
/* Already handled in SDLTest_CommonCreateState() */
return 1;
Expand Down Expand Up @@ -686,6 +703,8 @@ SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, SDL_InitFlags flags)
int i;
SDLTest_CommonState *state;

SDLTest_Color = !get_environment_bool_variable("NO_COLOR");

/* Do this first so we catch all allocations */
for (i = 1; argv[i]; ++i) {
if (SDL_strcasecmp(argv[i], "--trackmem") == 0) {
Expand Down
84 changes: 41 additions & 43 deletions src/test/SDL_test_harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,25 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL3/SDL_test.h>
#include "SDL_test_internal.h"

#include <stdlib.h> /* Needed for exit() */

/* Enable to have color in logs */
#if 1
#define COLOR_RED "\033[0;31m"
#define COLOR_GREEN "\033[0;32m"
#define COLOR_YELLOW "\033[0;93m"
#define COLOR_BLUE "\033[0;94m"
#define COLOR_END "\033[0m"
#else
#define COLOR_RED ""
#define COLOR_GREEN ""
#define COLOR_BLUE ""
#define COLOR_YELLOW ""
#define COLOR_END ""
#endif

/* Invalid test name/description message format */
#define SDLTEST_INVALID_NAME_FORMAT "(Invalid)"

/* Log summary message format */
#define SDLTEST_LOG_SUMMARY_FORMAT "%s Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_RED "Failed=%d" COLOR_END " " COLOR_BLUE "Skipped=%d" COLOR_END
#define SDLTEST_LOG_SUMMARY_FORMAT_OK "%s Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_GREEN "Failed=%d" COLOR_END " " COLOR_BLUE "Skipped=%d" COLOR_END
static void SDLTest_LogSummary(bool success, const char *name, int total, int passed, int failed, int skipped)
{
SDLTest_LogMessage(success ? SDL_LOG_PRIORITY_INFO : SDL_LOG_PRIORITY_ERROR,
"%s Summary: Total=%d " "%s" "Passed=%d" "%s" " " "%s" "Failed=%d" "%s" " " "%s" "Skipped=%d" "%s",
name, total, COLOR_GREEN, passed, COLOR_END, success ? COLOR_GREEN : COLOR_RED, failed, COLOR_END, COLOR_BLUE, skipped, COLOR_END);
}

/* Final result message format */
#define SDLTEST_FINAL_RESULT_FORMAT COLOR_YELLOW ">>> %s '%s':" COLOR_END " %s\n"
static void SDLTest_LogFinalResult(bool success, const char *stage, const char *name, const char *color_message, const char *message)
{
SDL_LogPriority priority = success ? SDL_LOG_PRIORITY_INFO : SDL_LOG_PRIORITY_ERROR;
SDLTest_LogMessage(priority, "%s>>> %s '%s':" "%s" " " "%s" "%s" "%s", COLOR_YELLOW, stage, name, COLOR_END, color_message ? color_message : "", message, color_message ? COLOR_END : "");
}

struct SDLTest_TestSuiteRunner {
struct
Expand Down Expand Up @@ -242,7 +234,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
}

if (!testCase->enabled && forceTestRun == false) {
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Disabled)");
SDLTest_LogFinalResult(true, "Test", testCase->name, NULL, "Skipped (Disabled)");
return TEST_RESULT_SKIPPED;
}

Expand All @@ -259,7 +251,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
if (testSuite->testSetUp) {
testSuite->testSetUp(&data);
if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) {
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite Setup", testSuite->name, COLOR_RED "Failed" COLOR_END);
SDLTest_LogFinalResult(false, "Suite Setup", testSuite->name, COLOR_RED, "Failed");
return TEST_RESULT_SETUP_FAILURE;
}
}
Expand Down Expand Up @@ -301,13 +293,13 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
/* Final log based on test execution result */
if (testCaseResult == TEST_SKIPPED) {
/* Test was programmatically skipped */
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, COLOR_BLUE "Skipped (Programmatically)" COLOR_END);
SDLTest_LogFinalResult(true, "Test", testCase->name, COLOR_BLUE, "Skipped (Programmatically)");
} else if (testCaseResult == TEST_STARTED) {
/* Test did not return a TEST_COMPLETED value; assume it failed */
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, COLOR_RED "Failed (test started, but did not return TEST_COMPLETED)" COLOR_END);
SDLTest_LogFinalResult(false, "Test", testCase->name, COLOR_RED, "Skipped (test started, but did not return TEST_COMPLETED)");
} else if (testCaseResult == TEST_ABORTED) {
/* Test was aborted early; assume it failed */
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, COLOR_RED "Failed (Aborted)" COLOR_END);
SDLTest_LogFinalResult(false, "Test", testCase->name, COLOR_RED, "Failed (Aborted)");
} else {
SDLTest_LogAssertSummary();
}
Expand Down Expand Up @@ -572,9 +564,11 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
if (suiteFilter == 1 && suiteFilterName && testSuite->name &&
SDL_strcasecmp(suiteFilterName, testSuite->name) != 0) {
/* Skip suite */
SDLTest_Log("===== Test Suite %i: '%s' " COLOR_BLUE "skipped" COLOR_END "\n",
SDLTest_Log("===== Test Suite %i: '%s' " "%s" "skipped" "%s" "\n",
suiteCounter,
currentSuiteName);
currentSuiteName,
COLOR_BLUE,
COLOR_END);
} else {

int nbTestCases = 0;
Expand Down Expand Up @@ -634,10 +628,12 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
if (testFilter == 1 && testFilterName && testCase->name &&
SDL_strcasecmp(testFilterName, testCase->name) != 0) {
/* Skip test */
SDLTest_Log("===== Test Case %i.%i: '%s' " COLOR_BLUE "skipped" COLOR_END "\n",
SDLTest_Log("===== Test Case %i.%i: '%s' " "%s" "skipped" "%s" "\n",
suiteCounter,
testCounter,
currentTestName);
currentTestName,
COLOR_BLUE,
COLOR_END);
} else {
/* Override 'disabled' flag if we specified a test filter (i.e. force run for debugging) */
if (testFilter == 1 && !testCase->enabled) {
Expand All @@ -649,10 +645,12 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
testStartSeconds = GetClock();

/* Log test started */
SDLTest_Log(COLOR_YELLOW "----- Test Case %i.%i: '%s' started" COLOR_END,
SDLTest_Log("%s" "----- Test Case %i.%i: '%s' started" "%s",
COLOR_YELLOW,
suiteCounter,
testCounter,
currentTestName);
currentTestName,
COLOR_END);
if (testCase->description && testCase->description[0] != '\0') {
SDLTest_Log("Test Description: '%s'",
(testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT);
Expand Down Expand Up @@ -703,13 +701,13 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
/* Log final test result */
switch (testResult) {
case TEST_RESULT_PASSED:
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogFinalResult(true, "Test", currentTestName, COLOR_GREEN, "Passed");
break;
case TEST_RESULT_FAILED:
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, COLOR_RED "Failed" COLOR_END);
SDLTest_LogFinalResult(false, "Test", currentTestName, COLOR_RED, "Failed");
break;
case TEST_RESULT_NO_ASSERT:
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, COLOR_BLUE "No Asserts" COLOR_END);
SDLTest_LogFinalResult(false, "Test", currentTestName, COLOR_BLUE, "No Asserts");
break;
}

Expand All @@ -734,11 +732,11 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
/* Log summary and final Suite result */
countSum = testPassedCount + testFailedCount + testSkippedCount;
if (testFailedCount == 0) {
SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT_OK, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogSummary(true, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_LogFinalResult(true, "Suite", currentSuiteName, COLOR_GREEN, "Passed");
} else {
SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, COLOR_RED "Failed" COLOR_END);
SDLTest_LogSummary(false, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_LogFinalResult(false, "Suite", currentSuiteName, COLOR_RED, "Failed");
}

SDL_free(arrayTestCases);
Expand All @@ -761,19 +759,19 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
countSum = totalTestPassedCount + totalTestFailedCount + totalTestSkippedCount;
if (totalTestFailedCount == 0) {
runResult = 0;
SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT_OK, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogSummary(true, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_LogFinalResult(true, "Run /w seed", runSeed, COLOR_GREEN, "Passed");
} else {
runResult = 1;
SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, COLOR_RED "Failed" COLOR_END);
SDLTest_LogSummary(false, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_LogFinalResult(false, "Run /w seed", runSeed, COLOR_RED, "Failed");
}

/* Print repro steps for failed tests */
if (failedNumberOfTests > 0) {
SDLTest_Log("Harness input to repro failures:");
for (testCounter = 0; testCounter < failedNumberOfTests; testCounter++) {
SDLTest_Log(COLOR_RED " --seed %s --filter %s" COLOR_END, runSeed, failedTests[testCounter]->name);
SDLTest_Log("%s" " --seed %s --filter %s" "%s", COLOR_RED, runSeed, failedTests[testCounter]->name, COLOR_END);
}
}
SDL_free((void *)failedTests);
Expand Down
Loading
Loading