testautomation_properties.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /**
  2. * Properties test suite
  3. */
  4. #include <SDL3/SDL.h>
  5. #include <SDL3/SDL_test.h>
  6. #include "testautomation_suites.h"
  7. /* Test case functions */
  8. /**
  9. * Test basic functionality
  10. */
  11. static void SDLCALL count_properties(void *userdata, SDL_PropertiesID props, const char *name)
  12. {
  13. int *count = (int *)userdata;
  14. ++(*count);
  15. }
  16. static void SDLCALL count_foo_properties(void *userdata, SDL_PropertiesID props, const char *name)
  17. {
  18. int *count = (int *)userdata;
  19. if (SDL_strcmp(name, "foo") == 0) {
  20. ++(*count);
  21. }
  22. }
  23. static int SDLCALL properties_testBasic(void *arg)
  24. {
  25. SDL_PropertiesID props;
  26. char key[2], expected_value[2];
  27. SDL_PropertyType type;
  28. void *value;
  29. const char *value_string;
  30. Sint64 value_number;
  31. float value_float;
  32. bool value_bool;
  33. int i, result, count;
  34. props = SDL_CreateProperties();
  35. SDLTest_AssertPass("Call to SDL_CreateProperties()");
  36. SDLTest_AssertCheck(props != 0,
  37. "Verify props were created, got: %" SDL_PRIu32, props);
  38. for (i = 0; i < 10; ++i) {
  39. SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i);
  40. SDL_snprintf(expected_value, SDL_arraysize(expected_value), "%c", 'a' + i);
  41. result = SDL_SetPointerProperty(props, key, expected_value);
  42. SDLTest_AssertPass("Call to SDL_SetPointerProperty()");
  43. SDLTest_AssertCheck(result == true,
  44. "Verify property value was set, got: %d", result);
  45. value = SDL_GetPointerProperty(props, key, NULL);
  46. SDLTest_AssertPass("Call to SDL_GetPointerProperty()");
  47. SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, expected_value) == 0,
  48. "Verify property value was set, got %s, expected %s", value ? (const char *)value : "NULL", expected_value);
  49. }
  50. count = 0;
  51. SDL_EnumerateProperties(props, count_properties, &count);
  52. SDLTest_AssertCheck(count == 10,
  53. "Verify property count, expected 10, got: %d", count);
  54. for (i = 0; i < 10; ++i) {
  55. SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i);
  56. result = SDL_SetPointerProperty(props, key, NULL);
  57. SDLTest_AssertPass("Call to SDL_SetPointerProperty(NULL)");
  58. SDLTest_AssertCheck(result == true,
  59. "Verify property value was set, got: %d", result);
  60. value = SDL_GetPointerProperty(props, key, NULL);
  61. SDLTest_AssertPass("Call to SDL_GetPointerProperty()");
  62. SDLTest_AssertCheck(value == NULL,
  63. "Verify property value was set, got %s, expected NULL", (const char *)value);
  64. }
  65. count = 0;
  66. SDL_EnumerateProperties(props, count_properties, &count);
  67. SDLTest_AssertCheck(count == 0,
  68. "Verify property count, expected 0, got: %d", count);
  69. /* Check default values */
  70. value = SDL_GetPointerProperty(props, "foo", (void *)0xabcd);
  71. SDLTest_AssertCheck(value == (void *)0xabcd,
  72. "Verify property, expected 0xabcd, got: %p", value);
  73. value_string = SDL_GetStringProperty(props, "foo", "abcd");
  74. SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "abcd") == 0,
  75. "Verify string property, expected abcd, got: %s", value_string);
  76. value_number = SDL_GetNumberProperty(props, "foo", 1234);
  77. SDLTest_AssertCheck(value_number == 1234,
  78. "Verify number property, expected 1234, got: %" SDL_PRIu64, value_number);
  79. value_float = SDL_GetFloatProperty(props, "foo", 1234.0f);
  80. SDLTest_AssertCheck(value_float == 1234.0f,
  81. "Verify float property, expected 1234, got: %f", value_float);
  82. value_bool = SDL_GetBooleanProperty(props, "foo", true);
  83. SDLTest_AssertCheck(value_bool == true,
  84. "Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
  85. /* Check data value */
  86. SDLTest_AssertPass("Call to SDL_SetPointerProperty(\"foo\", 0x01)");
  87. SDL_SetPointerProperty(props, "foo", (void *)0x01);
  88. type = SDL_GetPropertyType(props, "foo");
  89. SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_POINTER,
  90. "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_POINTER, type);
  91. value = SDL_GetPointerProperty(props, "foo", NULL);
  92. SDLTest_AssertCheck(value == (void *)0x01,
  93. "Verify property, expected 0x01, got: %p", value);
  94. value_string = SDL_GetStringProperty(props, "foo", NULL);
  95. SDLTest_AssertCheck(value_string == NULL,
  96. "Verify string property, expected NULL, got: %s", value_string);
  97. value_number = SDL_GetNumberProperty(props, "foo", 0);
  98. SDLTest_AssertCheck(value_number == 0,
  99. "Verify number property, expected 0, got: %" SDL_PRIu64, value_number);
  100. value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
  101. SDLTest_AssertCheck(value_float == 0.0f,
  102. "Verify float property, expected 0, got: %f", value_float);
  103. value_bool = SDL_GetBooleanProperty(props, "foo", false);
  104. SDLTest_AssertCheck(value_bool == false,
  105. "Verify boolean property, expected false, got: %s", value_bool ? "true" : "false");
  106. /* Check string value */
  107. SDLTest_AssertPass("Call to SDL_SetStringProperty(\"foo\", \"bar\")");
  108. SDL_SetStringProperty(props, "foo", "bar");
  109. type = SDL_GetPropertyType(props, "foo");
  110. SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_STRING,
  111. "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_STRING, type);
  112. value = SDL_GetPointerProperty(props, "foo", NULL);
  113. SDLTest_AssertCheck(value == NULL,
  114. "Verify property, expected NULL, got: %p", value);
  115. value_string = SDL_GetStringProperty(props, "foo", NULL);
  116. SDLTest_AssertCheck(value_string != NULL && SDL_strcmp(value_string, "bar") == 0,
  117. "Verify string property, expected bar, got: %s", value_string);
  118. value_number = SDL_GetNumberProperty(props, "foo", 0);
  119. SDLTest_AssertCheck(value_number == 0,
  120. "Verify number property, expected 0, got: %" SDL_PRIu64, value_number);
  121. value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
  122. SDLTest_AssertCheck(value_float == 0.0f,
  123. "Verify float property, expected 0, got: %f", value_float);
  124. value_bool = SDL_GetBooleanProperty(props, "foo", false);
  125. SDLTest_AssertCheck(value_bool == true,
  126. "Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
  127. /* Check number value */
  128. SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)");
  129. SDL_SetNumberProperty(props, "foo", 1);
  130. type = SDL_GetPropertyType(props, "foo");
  131. SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_NUMBER,
  132. "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_NUMBER, type);
  133. value = SDL_GetPointerProperty(props, "foo", NULL);
  134. SDLTest_AssertCheck(value == NULL,
  135. "Verify property, expected NULL, got: %p", value);
  136. value_string = SDL_GetStringProperty(props, "foo", NULL);
  137. SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "1") == 0,
  138. "Verify string property, expected 1, got: %s", value_string);
  139. value_number = SDL_GetNumberProperty(props, "foo", 0);
  140. SDLTest_AssertCheck(value_number == 1,
  141. "Verify number property, expected 1, got: %" SDL_PRIu64, value_number);
  142. value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
  143. SDLTest_AssertCheck(value_float == 1.0f,
  144. "Verify float property, expected 1, got: %f", value_float);
  145. value_bool = SDL_GetBooleanProperty(props, "foo", false);
  146. SDLTest_AssertCheck(value_bool == true,
  147. "Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
  148. /* Check float value */
  149. SDLTest_AssertPass("Call to SDL_SetFloatProperty(\"foo\", 1)");
  150. SDL_SetFloatProperty(props, "foo", 1.75f);
  151. type = SDL_GetPropertyType(props, "foo");
  152. SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_FLOAT,
  153. "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_FLOAT, type);
  154. value = SDL_GetPointerProperty(props, "foo", NULL);
  155. SDLTest_AssertCheck(value == NULL,
  156. "Verify property, expected NULL, got: %p", value);
  157. value_string = SDL_GetStringProperty(props, "foo", NULL);
  158. SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "1.750000") == 0,
  159. "Verify string property, expected 1.750000, got: %s", value_string);
  160. value_number = SDL_GetNumberProperty(props, "foo", 0);
  161. SDLTest_AssertCheck(value_number == 2,
  162. "Verify number property, expected 2, got: %" SDL_PRIu64, value_number);
  163. value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
  164. SDLTest_AssertCheck(value_float == 1.75f,
  165. "Verify float property, expected 1.75, got: %f", value_float);
  166. value_bool = SDL_GetBooleanProperty(props, "foo", false);
  167. SDLTest_AssertCheck(value_bool == true,
  168. "Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
  169. /* Check boolean value */
  170. SDLTest_AssertPass("Call to SDL_SetBooleanProperty(\"foo\", true)");
  171. SDL_SetBooleanProperty(props, "foo", 3); /* Note we're testing non-true/false value here */
  172. type = SDL_GetPropertyType(props, "foo");
  173. SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_BOOLEAN,
  174. "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_BOOLEAN, type);
  175. value = SDL_GetPointerProperty(props, "foo", NULL);
  176. SDLTest_AssertCheck(value == NULL,
  177. "Verify property, expected NULL, got: %p", value);
  178. value_string = SDL_GetStringProperty(props, "foo", NULL);
  179. SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "true") == 0,
  180. "Verify string property, expected true, got: %s", value_string);
  181. value_number = SDL_GetNumberProperty(props, "foo", 0);
  182. SDLTest_AssertCheck(value_number == 1,
  183. "Verify number property, expected 1, got: %" SDL_PRIu64, value_number);
  184. value_float = SDL_GetFloatProperty(props, "foo", 0.0f);
  185. SDLTest_AssertCheck(value_float == 1.0f,
  186. "Verify float property, expected 1, got: %f", value_float);
  187. value_bool = SDL_GetBooleanProperty(props, "foo", false);
  188. SDLTest_AssertCheck(value_bool == true,
  189. "Verify boolean property, expected true, got: %s", value_bool ? "true" : "false");
  190. /* Make sure we have exactly one property named foo */
  191. count = 0;
  192. SDL_EnumerateProperties(props, count_foo_properties, &count);
  193. SDLTest_AssertCheck(count == 1,
  194. "Verify foo property count, expected 1, got: %d", count);
  195. SDL_DestroyProperties(props);
  196. return TEST_COMPLETED;
  197. }
  198. /**
  199. * Test copy functionality
  200. */
  201. static void SDLCALL copy_cleanup(void *userdata, void *value)
  202. {
  203. }
  204. static int SDLCALL properties_testCopy(void *arg)
  205. {
  206. SDL_PropertiesID a, b;
  207. int num;
  208. const char *string;
  209. void *data;
  210. int result;
  211. a = SDL_CreateProperties();
  212. SDL_SetNumberProperty(a, "num", 1);
  213. SDL_SetStringProperty(a, "string", "foo");
  214. SDL_SetPointerProperty(a, "data", &a);
  215. SDL_SetPointerPropertyWithCleanup(a, "cleanup", &a, copy_cleanup, &a);
  216. b = SDL_CreateProperties();
  217. SDL_SetNumberProperty(b, "num", 2);
  218. SDLTest_AssertPass("Call to SDL_CopyProperties(a, 0)");
  219. result = SDL_CopyProperties(a, 0);
  220. SDLTest_AssertCheck(result == false,
  221. "SDL_CopyProperties() result, got %d, expected false", result);
  222. SDLTest_AssertPass("Call to SDL_CopyProperties(0, b)");
  223. result = SDL_CopyProperties(0, b);
  224. SDLTest_AssertCheck(result == false,
  225. "SDL_CopyProperties() result, got %d, expected false", result);
  226. SDLTest_AssertPass("Call to SDL_CopyProperties(a, b)");
  227. result = SDL_CopyProperties(a, b);
  228. SDLTest_AssertCheck(result == true,
  229. "SDL_CopyProperties() result, got %d, expected true", result);
  230. SDL_DestroyProperties(a);
  231. num = (int)SDL_GetNumberProperty(b, "num", 0);
  232. SDLTest_AssertCheck(num == 1,
  233. "Checking number property, got %d, expected 1", num);
  234. string = SDL_GetStringProperty(b, "string", NULL);
  235. SDLTest_AssertCheck(string && SDL_strcmp(string, "foo") == 0,
  236. "Checking string property, got \"%s\", expected \"foo\"", string);
  237. data = SDL_GetPointerProperty(b, "data", NULL);
  238. SDLTest_AssertCheck(data == &a,
  239. "Checking data property, got %p, expected %p", data, &a);
  240. data = SDL_GetPointerProperty(b, "cleanup", NULL);
  241. SDLTest_AssertCheck(data == NULL,
  242. "Checking cleanup property, got %p, expected NULL", data);
  243. SDL_DestroyProperties(b);
  244. return TEST_COMPLETED;
  245. }
  246. /**
  247. * Test cleanup functionality
  248. */
  249. static void SDLCALL cleanup(void *userdata, void *value)
  250. {
  251. int *count = (int *)userdata;
  252. ++(*count);
  253. }
  254. static int SDLCALL properties_testCleanup(void *arg)
  255. {
  256. SDL_PropertiesID props;
  257. char key[2], expected_value[2];
  258. int i, count;
  259. props = SDL_CreateProperties();
  260. SDLTest_AssertPass("Call to SDL_SetPointerProperty(cleanup)");
  261. count = 0;
  262. SDL_SetPointerPropertyWithCleanup(props, "a", "0", cleanup, &count);
  263. SDL_ClearProperty(props, "a");
  264. SDLTest_AssertCheck(count == 1,
  265. "Verify cleanup for deleting property, got %d, expected 1", count);
  266. SDLTest_AssertPass("Call to SDL_DestroyProperties()");
  267. count = 0;
  268. for (i = 0; i < 10; ++i) {
  269. SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i);
  270. SDL_snprintf(expected_value, SDL_arraysize(expected_value), "%c", 'a' + i);
  271. SDL_SetPointerPropertyWithCleanup(props, key, expected_value, cleanup, &count);
  272. }
  273. SDL_DestroyProperties(props);
  274. SDLTest_AssertCheck(count == 10,
  275. "Verify cleanup for destroying properties, got %d, expected 10", count);
  276. return TEST_COMPLETED;
  277. }
  278. /**
  279. * Test locking functionality
  280. */
  281. struct properties_thread_data
  282. {
  283. bool done;
  284. SDL_PropertiesID props;
  285. };
  286. static int SDLCALL properties_thread(void *arg)
  287. {
  288. struct properties_thread_data *data = (struct properties_thread_data *)arg;
  289. while (!data->done) {
  290. SDL_LockProperties(data->props);
  291. SDL_SetPointerProperty(data->props, "a", "thread_loop");
  292. SDL_UnlockProperties(data->props);
  293. }
  294. SDL_LockProperties(data->props);
  295. SDL_SetPointerProperty(data->props, "a", "thread_done");
  296. SDL_UnlockProperties(data->props);
  297. return 0;
  298. }
  299. static int SDLCALL properties_testLocking(void *arg)
  300. {
  301. struct properties_thread_data data;
  302. SDL_Thread *thread;
  303. void *value;
  304. SDLTest_AssertPass("Testing property locking");
  305. data.done = false;
  306. data.props = SDL_CreateProperties();
  307. SDLTest_AssertPass("Setting property to 'init'");
  308. SDL_SetPointerProperty(data.props, "a", "init");
  309. thread = SDL_CreateThread(properties_thread, "properties_thread", &data);
  310. if (thread) {
  311. SDLTest_AssertPass("Waiting for property to change to 'thread_loop'");
  312. for ( ; ; )
  313. {
  314. SDL_Delay(10);
  315. SDL_LockProperties(data.props);
  316. value = SDL_GetPointerProperty(data.props, "a", NULL);
  317. SDL_UnlockProperties(data.props);
  318. if (!value || SDL_strcmp((const char *)value, "thread_loop") == 0) {
  319. break;
  320. }
  321. }
  322. SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "thread_loop") == 0,
  323. "After thread loop, property is %s, expected 'thread_loop'", value ? (const char *)value : "NULL");
  324. SDLTest_AssertPass("Setting property to 'main'");
  325. SDL_LockProperties(data.props);
  326. SDL_SetPointerProperty(data.props, "a", "main");
  327. SDL_Delay(100);
  328. value = SDL_GetPointerProperty(data.props, "a", NULL);
  329. SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "main") == 0,
  330. "After 100ms sleep, property is %s, expected 'main'", value ? (const char *)value : "NULL");
  331. SDL_UnlockProperties(data.props);
  332. data.done = true;
  333. SDL_WaitThread(thread, NULL);
  334. value = SDL_GetPointerProperty(data.props, "a", NULL);
  335. SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "thread_done") == 0,
  336. "After thread complete, property is %s, expected 'thread_done'", value ? (const char *)value : "NULL");
  337. }
  338. SDL_DestroyProperties(data.props);
  339. return TEST_COMPLETED;
  340. }
  341. /* ================= Test References ================== */
  342. /* Properties test cases */
  343. static const SDLTest_TestCaseReference propertiesTestBasic = {
  344. properties_testBasic, "properties_testBasic", "Test basic property functionality", TEST_ENABLED
  345. };
  346. static const SDLTest_TestCaseReference propertiesTestCopy = {
  347. properties_testCopy, "properties_testCopy", "Test property copy functionality", TEST_ENABLED
  348. };
  349. static const SDLTest_TestCaseReference propertiesTestCleanup = {
  350. properties_testCleanup, "properties_testCleanup", "Test property cleanup functionality", TEST_ENABLED
  351. };
  352. static const SDLTest_TestCaseReference propertiesTestLocking = {
  353. properties_testLocking, "properties_testLocking", "Test property locking functionality", TEST_ENABLED
  354. };
  355. /* Sequence of Properties test cases */
  356. static const SDLTest_TestCaseReference *propertiesTests[] = {
  357. &propertiesTestBasic,
  358. &propertiesTestCopy,
  359. &propertiesTestCleanup,
  360. &propertiesTestLocking,
  361. NULL
  362. };
  363. /* Properties test suite (global) */
  364. SDLTest_TestSuiteReference propertiesTestSuite = {
  365. "Properties",
  366. NULL,
  367. propertiesTests,
  368. NULL
  369. };