ext-SDL/test/testautomation_properties.c
Sam Lantinga a90ad3b0e2 Removed SDL_bool in favor of plain bool
We require stdbool.h in the build environment, so we might as well use the plain bool type.

If your environment doesn't have stdbool.h, this simple replacement will suffice:
typedef signed char bool;
2024-09-18 08:32:30 -07:00

420 lines
17 KiB
C

/**
* Properties test suite
*/
#include <SDL3/SDL.h>
#include <SDL3/SDL_test.h>
#include "testautomation_suites.h"
/* Test case functions */
/**
* Test basic functionality
*/
static void SDLCALL count_properties(void *userdata, SDL_PropertiesID props, const char *name)
{
int *count = (int *)userdata;
++(*count);
}
static void SDLCALL count_foo_properties(void *userdata, SDL_PropertiesID props, const char *name)
{
int *count = (int *)userdata;
if (SDL_strcmp(name, "foo") == 0) {
++(*count);
}
}
static int SDLCALL properties_testBasic(void *arg)
{
SDL_PropertiesID props;
char key[2], expected_value[2];
SDL_PropertyType type;
void *value;
const char *value_string;
Sint64 value_number;
float value_float;
bool value_bool;
int i, result, count;
props = SDL_CreateProperties();
SDLTest_AssertPass("Call to SDL_CreateProperties()");
SDLTest_AssertCheck(props != 0,
"Verify props were created, got: %" SDL_PRIu32, props);
for (i = 0; i < 10; ++i) {
SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i);
SDL_snprintf(expected_value, SDL_arraysize(expected_value), "%c", 'a' + i);
result = SDL_SetPointerProperty(props, key, expected_value);
SDLTest_AssertPass("Call to SDL_SetPointerProperty()");
SDLTest_AssertCheck(result == true,
"Verify property value was set, got: %d", result);
value = SDL_GetPointerProperty(props, key, NULL);
SDLTest_AssertPass("Call to SDL_GetPointerProperty()");
SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, expected_value) == 0,
"Verify property value was set, got %s, expected %s", value ? (const char *)value : "NULL", expected_value);
}
count = 0;
SDL_EnumerateProperties(props, count_properties, &count);
SDLTest_AssertCheck(count == 10,
"Verify property count, expected 10, got: %d", count);
for (i = 0; i < 10; ++i) {
SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i);
result = SDL_SetPointerProperty(props, key, NULL);
SDLTest_AssertPass("Call to SDL_SetPointerProperty(NULL)");
SDLTest_AssertCheck(result == true,
"Verify property value was set, got: %d", result);
value = SDL_GetPointerProperty(props, key, NULL);
SDLTest_AssertPass("Call to SDL_GetPointerProperty()");
SDLTest_AssertCheck(value == NULL,
"Verify property value was set, got %s, expected NULL", (const char *)value);
}
count = 0;
SDL_EnumerateProperties(props, count_properties, &count);
SDLTest_AssertCheck(count == 0,
"Verify property count, expected 0, got: %d", count);
/* Check default values */
value = SDL_GetPointerProperty(props, "foo", (void *)0xabcd);
SDLTest_AssertCheck(value == (void *)0xabcd,
"Verify property, expected 0xabcd, got: %p", value);
value_string = SDL_GetStringProperty(props, "foo", "abcd");
SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "abcd") == 0,
"Verify string property, expected abcd, got: %s", value_string);
value_number = SDL_GetNumberProperty(props, "foo", 1234);
SDLTest_AssertCheck(value_number == 1234,
"Verify number property, expected 1234, got: %" SDL_PRIu64, value_number);
value_float = SDL_GetFloatProperty(props, "foo", 1234.0f);
SDLTest_AssertCheck(value_float == 1234.0f,
"Verify float property, expected 1234, got: %f", value_float);
value_bool = SDL_GetBooleanProperty(props, "foo", true);
SDLTest_AssertCheck(value_bool == true,
"Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
/* Check data value */
SDLTest_AssertPass("Call to SDL_SetPointerProperty(\"foo\", 0x01)");
SDL_SetPointerProperty(props, "foo", (void *)0x01);
type = SDL_GetPropertyType(props, "foo");
SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_POINTER,
"Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_POINTER, type);
value = SDL_GetPointerProperty(props, "foo", NULL);
SDLTest_AssertCheck(value == (void *)0x01,
"Verify property, expected 0x01, got: %p", value);
value_string = SDL_GetStringProperty(props, "foo", NULL);
SDLTest_AssertCheck(value_string == NULL,
"Verify string property, expected NULL, got: %s", value_string);
value_number = SDL_GetNumberProperty(props, "foo", 0);
SDLTest_AssertCheck(value_number == 0,
"Verify number property, expected 0, got: %" SDL_PRIu64, value_number);
value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
SDLTest_AssertCheck(value_float == 0.0f,
"Verify float property, expected 0, got: %f", value_float);
value_bool = SDL_GetBooleanProperty(props, "foo", false);
SDLTest_AssertCheck(value_bool == false,
"Verify boolean property, expected false, got: %s", value_bool ? "true" : "false");
/* Check string value */
SDLTest_AssertPass("Call to SDL_SetStringProperty(\"foo\", \"bar\")");
SDL_SetStringProperty(props, "foo", "bar");
type = SDL_GetPropertyType(props, "foo");
SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_STRING,
"Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_STRING, type);
value = SDL_GetPointerProperty(props, "foo", NULL);
SDLTest_AssertCheck(value == NULL,
"Verify property, expected NULL, got: %p", value);
value_string = SDL_GetStringProperty(props, "foo", NULL);
SDLTest_AssertCheck(value_string != NULL && SDL_strcmp(value_string, "bar") == 0,
"Verify string property, expected bar, got: %s", value_string);
value_number = SDL_GetNumberProperty(props, "foo", 0);
SDLTest_AssertCheck(value_number == 0,
"Verify number property, expected 0, got: %" SDL_PRIu64, value_number);
value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
SDLTest_AssertCheck(value_float == 0.0f,
"Verify float property, expected 0, got: %f", value_float);
value_bool = SDL_GetBooleanProperty(props, "foo", false);
SDLTest_AssertCheck(value_bool == true,
"Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
/* Check number value */
SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)");
SDL_SetNumberProperty(props, "foo", 1);
type = SDL_GetPropertyType(props, "foo");
SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_NUMBER,
"Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_NUMBER, type);
value = SDL_GetPointerProperty(props, "foo", NULL);
SDLTest_AssertCheck(value == NULL,
"Verify property, expected NULL, got: %p", value);
value_string = SDL_GetStringProperty(props, "foo", NULL);
SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "1") == 0,
"Verify string property, expected 1, got: %s", value_string);
value_number = SDL_GetNumberProperty(props, "foo", 0);
SDLTest_AssertCheck(value_number == 1,
"Verify number property, expected 1, got: %" SDL_PRIu64, value_number);
value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
SDLTest_AssertCheck(value_float == 1.0f,
"Verify float property, expected 1, got: %f", value_float);
value_bool = SDL_GetBooleanProperty(props, "foo", false);
SDLTest_AssertCheck(value_bool == true,
"Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
/* Check float value */
SDLTest_AssertPass("Call to SDL_SetFloatProperty(\"foo\", 1)");
SDL_SetFloatProperty(props, "foo", 1.75f);
type = SDL_GetPropertyType(props, "foo");
SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_FLOAT,
"Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_FLOAT, type);
value = SDL_GetPointerProperty(props, "foo", NULL);
SDLTest_AssertCheck(value == NULL,
"Verify property, expected NULL, got: %p", value);
value_string = SDL_GetStringProperty(props, "foo", NULL);
SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "1.750000") == 0,
"Verify string property, expected 1.750000, got: %s", value_string);
value_number = SDL_GetNumberProperty(props, "foo", 0);
SDLTest_AssertCheck(value_number == 2,
"Verify number property, expected 2, got: %" SDL_PRIu64, value_number);
value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
SDLTest_AssertCheck(value_float == 1.75f,
"Verify float property, expected 1.75, got: %f", value_float);
value_bool = SDL_GetBooleanProperty(props, "foo", false);
SDLTest_AssertCheck(value_bool == true,
"Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
/* Check boolean value */
SDLTest_AssertPass("Call to SDL_SetBooleanProperty(\"foo\", true)");
SDL_SetBooleanProperty(props, "foo", 3); /* Note we're testing non-true/false value here */
type = SDL_GetPropertyType(props, "foo");
SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_BOOLEAN,
"Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_BOOLEAN, type);
value = SDL_GetPointerProperty(props, "foo", NULL);
SDLTest_AssertCheck(value == NULL,
"Verify property, expected NULL, got: %p", value);
value_string = SDL_GetStringProperty(props, "foo", NULL);
SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "true") == 0,
"Verify string property, expected true, got: %s", value_string);
value_number = SDL_GetNumberProperty(props, "foo", 0);
SDLTest_AssertCheck(value_number == 1,
"Verify number property, expected 1, got: %" SDL_PRIu64, value_number);
value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
SDLTest_AssertCheck(value_float == 1.0f,
"Verify float property, expected 1, got: %f", value_float);
value_bool = SDL_GetBooleanProperty(props, "foo", false);
SDLTest_AssertCheck(value_bool == true,
"Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
/* Make sure we have exactly one property named foo */
count = 0;
SDL_EnumerateProperties(props, count_foo_properties, &count);
SDLTest_AssertCheck(count == 1,
"Verify foo property count, expected 1, got: %d", count);
SDL_DestroyProperties(props);
return TEST_COMPLETED;
}
/**
* Test copy functionality
*/
static void SDLCALL copy_cleanup(void *userdata, void *value)
{
}
static int SDLCALL properties_testCopy(void *arg)
{
SDL_PropertiesID a, b;
int num;
const char *string;
void *data;
int result;
a = SDL_CreateProperties();
SDL_SetNumberProperty(a, "num", 1);
SDL_SetStringProperty(a, "string", "foo");
SDL_SetPointerProperty(a, "data", &a);
SDL_SetPointerPropertyWithCleanup(a, "cleanup", &a, copy_cleanup, &a);
b = SDL_CreateProperties();
SDL_SetNumberProperty(b, "num", 2);
SDLTest_AssertPass("Call to SDL_CopyProperties(a, 0)");
result = SDL_CopyProperties(a, 0);
SDLTest_AssertCheck(result == false,
"SDL_CopyProperties() result, got %d, expected false", result);
SDLTest_AssertPass("Call to SDL_CopyProperties(0, b)");
result = SDL_CopyProperties(0, b);
SDLTest_AssertCheck(result == false,
"SDL_CopyProperties() result, got %d, expected false", result);
SDLTest_AssertPass("Call to SDL_CopyProperties(a, b)");
result = SDL_CopyProperties(a, b);
SDLTest_AssertCheck(result == true,
"SDL_CopyProperties() result, got %d, expected true", result);
SDL_DestroyProperties(a);
num = (int)SDL_GetNumberProperty(b, "num", 0);
SDLTest_AssertCheck(num == 1,
"Checking number property, got %d, expected 1", num);
string = SDL_GetStringProperty(b, "string", NULL);
SDLTest_AssertCheck(string && SDL_strcmp(string, "foo") == 0,
"Checking string property, got \"%s\", expected \"foo\"", string);
data = SDL_GetPointerProperty(b, "data", NULL);
SDLTest_AssertCheck(data == &a,
"Checking data property, got %p, expected %p", data, &a);
data = SDL_GetPointerProperty(b, "cleanup", NULL);
SDLTest_AssertCheck(data == NULL,
"Checking cleanup property, got %p, expected NULL", data);
SDL_DestroyProperties(b);
return TEST_COMPLETED;
}
/**
* Test cleanup functionality
*/
static void SDLCALL cleanup(void *userdata, void *value)
{
int *count = (int *)userdata;
++(*count);
}
static int SDLCALL properties_testCleanup(void *arg)
{
SDL_PropertiesID props;
char key[2], expected_value[2];
int i, count;
props = SDL_CreateProperties();
SDLTest_AssertPass("Call to SDL_SetPointerProperty(cleanup)");
count = 0;
SDL_SetPointerPropertyWithCleanup(props, "a", "0", cleanup, &count);
SDL_ClearProperty(props, "a");
SDLTest_AssertCheck(count == 1,
"Verify cleanup for deleting property, got %d, expected 1", count);
SDLTest_AssertPass("Call to SDL_DestroyProperties()");
count = 0;
for (i = 0; i < 10; ++i) {
SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i);
SDL_snprintf(expected_value, SDL_arraysize(expected_value), "%c", 'a' + i);
SDL_SetPointerPropertyWithCleanup(props, key, expected_value, cleanup, &count);
}
SDL_DestroyProperties(props);
SDLTest_AssertCheck(count == 10,
"Verify cleanup for destroying properties, got %d, expected 10", count);
return TEST_COMPLETED;
}
/**
* Test locking functionality
*/
struct properties_thread_data
{
bool done;
SDL_PropertiesID props;
};
static int SDLCALL properties_thread(void *arg)
{
struct properties_thread_data *data = (struct properties_thread_data *)arg;
while (!data->done) {
SDL_LockProperties(data->props);
SDL_SetPointerProperty(data->props, "a", "thread_loop");
SDL_UnlockProperties(data->props);
}
SDL_LockProperties(data->props);
SDL_SetPointerProperty(data->props, "a", "thread_done");
SDL_UnlockProperties(data->props);
return 0;
}
static int SDLCALL properties_testLocking(void *arg)
{
struct properties_thread_data data;
SDL_Thread *thread;
void *value;
SDLTest_AssertPass("Testing property locking");
data.done = false;
data.props = SDL_CreateProperties();
SDLTest_AssertPass("Setting property to 'init'");
SDL_SetPointerProperty(data.props, "a", "init");
thread = SDL_CreateThread(properties_thread, "properties_thread", &data);
if (thread) {
SDLTest_AssertPass("Waiting for property to change to 'thread_loop'");
for ( ; ; )
{
SDL_Delay(10);
SDL_LockProperties(data.props);
value = SDL_GetPointerProperty(data.props, "a", NULL);
SDL_UnlockProperties(data.props);
if (!value || SDL_strcmp((const char *)value, "thread_loop") == 0) {
break;
}
}
SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "thread_loop") == 0,
"After thread loop, property is %s, expected 'thread_loop'", value ? (const char *)value : "NULL");
SDLTest_AssertPass("Setting property to 'main'");
SDL_LockProperties(data.props);
SDL_SetPointerProperty(data.props, "a", "main");
SDL_Delay(100);
value = SDL_GetPointerProperty(data.props, "a", NULL);
SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "main") == 0,
"After 100ms sleep, property is %s, expected 'main'", value ? (const char *)value : "NULL");
SDL_UnlockProperties(data.props);
data.done = true;
SDL_WaitThread(thread, NULL);
value = SDL_GetPointerProperty(data.props, "a", NULL);
SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "thread_done") == 0,
"After thread complete, property is %s, expected 'thread_done'", value ? (const char *)value : "NULL");
}
SDL_DestroyProperties(data.props);
return TEST_COMPLETED;
}
/* ================= Test References ================== */
/* Properties test cases */
static const SDLTest_TestCaseReference propertiesTestBasic = {
properties_testBasic, "properties_testBasic", "Test basic property functionality", TEST_ENABLED
};
static const SDLTest_TestCaseReference propertiesTestCopy = {
properties_testCopy, "properties_testCopy", "Test property copy functionality", TEST_ENABLED
};
static const SDLTest_TestCaseReference propertiesTestCleanup = {
properties_testCleanup, "properties_testCleanup", "Test property cleanup functionality", TEST_ENABLED
};
static const SDLTest_TestCaseReference propertiesTestLocking = {
properties_testLocking, "properties_testLocking", "Test property locking functionality", TEST_ENABLED
};
/* Sequence of Properties test cases */
static const SDLTest_TestCaseReference *propertiesTests[] = {
&propertiesTestBasic,
&propertiesTestCopy,
&propertiesTestCleanup,
&propertiesTestLocking,
NULL
};
/* Properties test suite (global) */
SDLTest_TestSuiteReference propertiesTestSuite = {
"Properties",
NULL,
propertiesTests,
NULL
};