y_testing.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /**--------------------------------------------------------------------------**\
  2. ====================================
  3. y_testing - Run unit tests easilly
  4. ====================================
  5. Description:
  6. Runs any functions named as tests when the Testing_Run function is called.
  7. Legal:
  8. Version: MPL 1.1
  9. The contents of this file are subject to the Mozilla Public License Version
  10. 1.1 (the "License"); you may not use this file except in compliance with
  11. the License. You may obtain a copy of the License at
  12. http://www.mozilla.org/MPL/
  13. Software distributed under the License is distributed on an "AS IS" basis,
  14. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  15. for the specific language governing rights and limitations under the
  16. License.
  17. The Original Code is the YSI testing include.
  18. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  19. Portions created by the Initial Developer are Copyright (C) 2011
  20. the Initial Developer. All Rights Reserved.
  21. Contributors:
  22. ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
  23. Thanks:
  24. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  25. ZeeX - Very productive conversations.
  26. koolk - IsPlayerinAreaEx code.
  27. TheAlpha - Danish translation.
  28. breadfish - German translation.
  29. Fireburn - Dutch translation.
  30. yom - French translation.
  31. 50p - Polish translation.
  32. Zamaroht - Spanish translation.
  33. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
  34. for me to strive to better.
  35. Pixels^ - Running XScripters where the idea was born.
  36. Matite - Pestering me to release it and using it.
  37. Very special thanks to:
  38. Thiadmer - PAWN, whose limits continue to amaze me!
  39. Kye/Kalcor - SA:MP.
  40. SA:MP Team past, present and future - SA:MP.
  41. Version:
  42. 1.0
  43. Changelog:
  44. 16/02/12:
  45. Added better error reporting (less verbose passes).
  46. Removed "Tests:".
  47. Added player requiring tests.
  48. 25/10/10:
  49. Integrated in to YSI.
  50. 06/08/10:
  51. First version
  52. </remarks>
  53. \**--------------------------------------------------------------------------**/
  54. #if defined _INC_y_testing
  55. #endinput
  56. #endif
  57. #define _INC_y_testing
  58. #include <a_samp>
  59. #include "y_debug"
  60. #include "..\YSI_Storage\y_amx"
  61. #include "..\YSI_Internal\amx_assembly"
  62. #include "..\YSI_Internal\y_shortvar"
  63. #if defined YSI_TESTS
  64. #if defined INCLUDE_TESTS
  65. #error Incompatible testing options (YSI_TESTS + INCLUDE_TESTS)
  66. #endif
  67. #if !defined RUN_TESTS
  68. #define RUN_TESTS
  69. #endif
  70. #endif
  71. #if defined INCLUDE_TESTS
  72. #define RUN_TESTS
  73. #define Debug_PrintT va_printf
  74. #elseif defined RUN_TESTS
  75. #define _AUTO_RUN_TESTS
  76. #define Debug_PrintT va_printf
  77. #else
  78. #if _DEBUG > 0 || defined _YSI_SPECIAL_DEBUG
  79. #define RUN_TESTS
  80. #define _AUTO_RUN_TESTS
  81. #define Debug_PrintT va_printf
  82. #else
  83. #define Debug_PrintT(%0);
  84. #endif
  85. #endif
  86. #if defined LIGHT_TEST_REPORT
  87. #define TEST_REPORT(%0) H@(%0)
  88. #else
  89. #define TEST_REPORT(%0) printf(%0)
  90. #endif
  91. #define Y_TESTING_DIALOG_ID (0x7974) // "yt"
  92. #define TEST_TRUE(%0) Testing_Test(!!%0)
  93. #define TEST_FALSE(%0) Testing_Test(!%0)
  94. #define TEST_NULL(%0) Testing_Test(0 == %0)
  95. #define TEST_NOT_NULL(%0) Testing_Test(0 != %0)
  96. #define TEST_N(%0,%1) Testing_Test(%1 == %0)
  97. #define TEST_TRUE_EX(%0,%2) Testing_Test(bool:(%0), (%2))
  98. #define TEST_FALSE_EX(%0,%2) Testing_Test(!(%0), (%2))
  99. #define TEST_NULL_EX(%0,%2) Testing_Test((%0) == 0, (%2))
  100. #define TEST_N_EX(%0,%1,%2) Testing_Test((%0) == (%1), (%2))
  101. #define TEST_MSG "\2\2\2\2\2"
  102. #define TEST_FAILED "FAIL:"
  103. #define TEST_PASSED "PASS!"
  104. #define _Y_TESTEQ(%0) "\"%0\"")
  105. #define _Y_TESTDQ:_Y_TESTEQ(%0"%1"%2) _Y_TESTDQ:_Y_TESTEQ(%0\x22;%1\x22;%2)
  106. #define _Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0)%1) _Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0\x29;%1)
  107. #define _Y_TESTOB:_Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0(%1) _Y_TESTOB:_Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0\x28;%1)
  108. #define ASSERT(%0) Testing_Test(%0,TEST_MSG" %s", _Y_TESTOB:_Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0)
  109. #define ASSERT_TRUE(%0) ASSERT(!!%0)
  110. #define ASSERT_FALSE(%0) ASSERT(!%0)
  111. #define ASSERT_NULL(%0) ASSERT(0 == %0)
  112. #define ASSERT_N:%1(%0) ASSERT(%1 == %0)
  113. #define ASK(%0) Testing_Ask(playerid,%0)
  114. static stock const
  115. Y_TESTING_TEST = _A<yQ@_>,
  116. Y_TESTING_INIT = _A<_yQ@>,
  117. Y_TESTING_SHUT = _A<yQ_@>,
  118. Y_TESTING_PTEST = _A<_@yQ>,
  119. Y_TESTING_PINIT = _A<_y@Q>,
  120. Y_TESTING_PSHUT = _A<y_@Q>;
  121. static stock
  122. YSI_g_sCurTest = 0,
  123. YSI_g_sFailTests = 0,
  124. YSI_g_sInTest = false,
  125. YSI_g_sTestResult,
  126. YSI_g_sFailMessage[512],
  127. YSI_g_sPlayer = cellmax,
  128. bool:YSI_g_sAsked,
  129. YSI_g_sTests,
  130. YSI_g_sFails;
  131. stock
  132. YSI_gCurTestName[32];
  133. #if defined RUN_TESTS
  134. #define Test:%1() forward bool:yQ@_%1(); public bool:yQ@_%1() for(new bool:__once = (_Testing_Start("\0\0"#%1), TEST_REPORT("*** Test %s start", YSI_gCurTestName) || true); __once; __once = (TEST_REPORT(" ") && false))
  135. #define TestInit:%1() forward _yQ@%1(); public _yQ@%1() for (new bool:__once = true; __once; __once = false)
  136. #define TestClose:%1() forward yQ_@%1(); public yQ_@%1() for (new bool:__once = true; __once; __once = false)
  137. #define PTest:%1(%2) forward bool:_@yQ%1(%2); public bool:_@yQ%1(%2) for(new bool:__once = (_Testing_Start("\0\0"#%1), TEST_REPORT("*** Player Test %s start", YSI_gCurTestName) || true); __once; __once = (TEST_REPORT(" ") && false))
  138. #define PTestInit:%1(%2) forward _y@Q%1(%2); public _y@Q%1(%2) for (new bool:__once = true; __once; __once = false)
  139. #define PTestClose:%1(%2) forward y_@Q%1(%2); public y_@Q%1(%2) for (new bool:__once = true; __once; __once = false)
  140. #else
  141. #define Test:%1() stock bool:yQ@_%1()
  142. #define TestInit:%1() stock _yQ@%1()
  143. #define TestClose:%1() stock yQ_@%1()
  144. #define PTest:%1(%2) stock bool:_@yQ%1(%2)
  145. #define PTestInit:%1(%2) stock _y@Q%1(%2)
  146. #define PTestClose:%1(%2) stock y_@Q%1(%2)
  147. #endif
  148. // These all need to come AFTER the types are defined in case the have tests.
  149. #include "..\YSI_Internal\y_version"
  150. #include "..\YSI_Storage\y_amx"
  151. #include "..\YSI_Internal\y_shortfunc"
  152. #include "y_debug"
  153. #include "..\YSI_Internal\y_natives"
  154. #include "..\YSI_Coding\y_va"
  155. /**--------------------------------------------------------------------------**\
  156. <summary>Testing_Start</summary>
  157. <param name="name">Name of the current function.</param>
  158. <returns>
  159. -
  160. </returns>
  161. <remarks>
  162. Gets a reference to the
  163. </remarks>
  164. \**--------------------------------------------------------------------------**/
  165. stock _Testing_Start(name[])
  166. {
  167. // Gets a reference to the name string, which is also an intrusive linked
  168. // list of failures.
  169. name[0] = name[1] = 0,
  170. YSI_g_sCurTest = ref(name);
  171. P:3("_Testing_Start %d %d %s = %d", name[0], name[1], name[2], YSI_g_sCurTest);
  172. YSI_gCurTestName[0] = '\0',
  173. strcpy(YSI_gCurTestName, name[2]);
  174. }
  175. /**--------------------------------------------------------------------------**\
  176. <summary>Testing_Ask</summary>
  177. <param name="playerid">Player to ask a question to.</param>
  178. <param name="str[]">What to ask.</param>
  179. <param name="va_args<>">Additional data.</param>
  180. <returns>
  181. -
  182. </returns>
  183. <remarks>
  184. Calls a dialog to ask the player if the given test actually passed.
  185. </remarks>
  186. \**--------------------------------------------------------------------------**/
  187. stock Testing_Ask(playerid, str[] = "", va_args<>)
  188. {
  189. va_format(YSI_g_sFailMessage, sizeof (YSI_g_sFailMessage), str, va_start<2>);
  190. ShowPlayerDialog(playerid, Y_TESTING_DIALOG_ID, DIALOG_STYLE_MSGBOX, "Did the test pass?", YSI_g_sFailMessage, "Yes", "No");
  191. YSI_g_sAsked = true;
  192. }
  193. stock Testing_Test(bool:x, str[] = "", va_args<>)
  194. {
  195. P:3("Testing_Test called: %i, \"%s\"", x, str);
  196. ++YSI_g_sTests;
  197. if (!x)
  198. {
  199. ++YSI_g_sFails;
  200. if (numargs() == 2)
  201. {
  202. P:T(TEST_FAILED " %s", va_start<1>);
  203. }
  204. else
  205. {
  206. if (str[0] == '\2')
  207. {
  208. strunpack(str, !TEST_FAILED, 6);
  209. str[5] = ' ';
  210. }
  211. P:T(str, va_start<2>);
  212. }
  213. }
  214. #if defined TEST_SHOW_PASSES
  215. else
  216. {
  217. P:T(TEST_PASSED, va_start<2>);
  218. }
  219. #endif
  220. }
  221. /**--------------------------------------------------------------------------**\
  222. <summary>Testing_Run</summary>
  223. <param name="&tests">Number of tests run.</param>
  224. <param name="&fails">Number of tests which failed.</param>
  225. <param name="buffer[33]">The name of the first test which failed.</param>
  226. <returns>
  227. Wether all tests were sucessful or not.
  228. </returns>
  229. <remarks>
  230. -
  231. native Testing_Run(&tests, &fails, buffer[33] = "");
  232. </remarks>
  233. \**--------------------------------------------------------------------------**/
  234. stock bool:Testing_Run(&tests, &fails, lastfail[33] = "", bool:p = false)
  235. {
  236. P:3("bool:Testing_Run called: %i, %i, \"%s\", %i", tests, fails, lastfail, p);
  237. #pragma unused p, lastfail
  238. #if defined RUN_TESTS
  239. P:2("Testing_Run() called");
  240. new
  241. idx,
  242. buffer[32];
  243. YSI_g_sCurTest = YSI_g_sFailTests = 0;
  244. while ((idx = AMX_GetPublicNamePrefix(idx, buffer, Y_TESTING_TEST)))
  245. {
  246. strunpack(buffer, buffer);
  247. // Call the setup function if there is one.
  248. buffer[0] = '_',
  249. buffer[1] = 'y',
  250. buffer[2] = 'Q',
  251. buffer[3] = '@',
  252. CallLocalFunction(buffer, "");
  253. // Call the test.
  254. buffer[0] = 'y',
  255. buffer[1] = 'Q',
  256. buffer[2] = '@',
  257. buffer[3] = '_',
  258. fails = YSI_g_sFails;
  259. P:5("Testing_Run(): Calling %s", unpack(buffer[1]));
  260. YSI_g_sInTest = true;
  261. CallLocalFunction(buffer, "");
  262. YSI_g_sInTest = false;
  263. if (YSI_g_sFails != fails)
  264. {
  265. WriteAmxMemory(YSI_g_sCurTest, YSI_g_sFailTests),
  266. WriteAmxMemory(YSI_g_sCurTest + 4, YSI_g_sFails - fails),
  267. YSI_g_sFailTests = YSI_g_sCurTest;
  268. }
  269. #if !defined TEST_SHOW_PASSES
  270. else
  271. {
  272. TEST_REPORT(TEST_PASSED);
  273. TEST_REPORT(" ");
  274. }
  275. #endif
  276. buffer[2] = '_',
  277. buffer[3] = '@',
  278. CallLocalFunction(buffer, "");
  279. }
  280. tests = YSI_g_sTests;
  281. fails = YSI_g_sFails;
  282. return fails == 0;
  283. #else
  284. #pragma unused tests, fails, lastfail
  285. return true;
  286. #endif
  287. }
  288. /**--------------------------------------------------------------------------**\
  289. <summary>Testing_Player</summary>
  290. <param name="playerid">Player to test on.</param>
  291. <param name="&idx">Next test to run.</param>
  292. <param name="&tests">Number of tests run.</param>
  293. <param name="&fails">Number of tests which failed.</param>
  294. <param name="buffer[33]">The name of the first test which failed.</param>
  295. <returns>
  296. Wether all tests were sucessful or not.
  297. </returns>
  298. <remarks>
  299. -
  300. native Testing_Run(&tests, &fails, buffer[33] = "");
  301. </remarks>
  302. \**--------------------------------------------------------------------------**/
  303. stock bool:Testing_Player(playerid, &idx, &tests, &fails, lastfail[33] = "", bool:p = false)
  304. {
  305. P:3("bool:Testing_Player called: %i, %i, %i, %i, \"%s\", %i", playerid, idx, tests, fails, lastfail, p);
  306. #pragma unused p
  307. #if defined RUN_TESTS
  308. P:2("Testing_Player() called");
  309. new
  310. buffer[32];
  311. if ((idx = AMX_GetPublicNamePrefix(YSI_g_sPlayer, buffer, Y_TESTING_PTEST)))
  312. {
  313. strunpack(buffer, buffer);
  314. // Call the setup function if there is one.
  315. buffer[0] = '_';
  316. buffer[1] = 'y';
  317. buffer[2] = '@';
  318. buffer[3] = 'Q';
  319. CallLocalFunction(buffer, "");
  320. // Call the test.
  321. buffer[1] = '@';
  322. buffer[2] = 'y';
  323. fails = YSI_g_sFails;
  324. P:5("Testing_Player(): Calling %s", buffer[6]);
  325. YSI_g_sInTest = true;
  326. CallLocalFunction(buffer, "");
  327. #if !defined TEST_SHOW_PASSES
  328. if (YSI_g_sFails == fails)
  329. {
  330. TEST_REPORT(TEST_PASSED);
  331. TEST_REPORT(" ");
  332. }
  333. #endif
  334. }
  335. tests = YSI_g_sTests;
  336. fails = YSI_g_sFails;
  337. return fails == 0;
  338. #else
  339. #pragma unused tests, fails, lastfail
  340. return true;
  341. #endif
  342. }
  343. forward OnTestsComplete(tests, fails);
  344. #if defined RUN_TESTS
  345. #if defined _AUTO_RUN_TESTS
  346. #if defined FILTERSCRIPT
  347. // Hook main in gamemodes.
  348. public OnFilterScriptInit()
  349. {
  350. #if defined Testing_OnFilterScriptInit
  351. Testing_OnFilterScriptInit();
  352. #endif
  353. Testing_RunAll();
  354. }
  355. #if defined _ALS_OnFilterScriptInit
  356. #undef OnFilterScriptInit
  357. #else
  358. #define _ALS_OnFilterScriptInit
  359. #endif
  360. #define OnFilterScriptInit Testing_OnFilterScriptInit
  361. #if defined Testing_OnFilterScriptInit
  362. forward Testing_OnFilterScriptInit();
  363. #endif
  364. #else
  365. // Hook main in gamemodes.
  366. main()
  367. {
  368. #if defined Testing_main
  369. Testing_main();
  370. #endif
  371. Testing_RunAll();
  372. }
  373. #if defined _ALS_main
  374. #undef main
  375. #else
  376. #define _ALS_main
  377. #endif
  378. #define main forward Testing_main(); public Testing_main
  379. #endif
  380. #endif
  381. Testing_Next(playerid)
  382. {
  383. YSI_g_sInTest = false;
  384. new
  385. buffer[32];
  386. for ( ; ; )
  387. {
  388. new
  389. fails = YSI_g_sFails;
  390. // Get the last test (nicely fails for cellmax).
  391. if ((YSI_g_sPlayer = AMX_GetPublicNamePrefix(YSI_g_sPlayer, buffer, Y_TESTING_PTEST)))
  392. {
  393. strunpack(buffer, buffer);
  394. // Call the shutdown function if there is one.
  395. buffer[0] = 'y';
  396. buffer[1] = '_';
  397. buffer[2] = '@';
  398. buffer[3] = 'Q';
  399. CallLocalFunction(buffer, "i", playerid);
  400. }
  401. // Get the new test, but don't store the index.
  402. if (AMX_GetPublicNamePrefix(YSI_g_sPlayer, buffer, Y_TESTING_PTEST))
  403. {
  404. YSI_g_sAsked = false;
  405. strunpack(buffer, buffer);
  406. // Call the setup function if there is one.
  407. buffer[0] = '_';
  408. buffer[1] = 'y';
  409. buffer[2] = '@';
  410. buffer[3] = 'Q';
  411. CallLocalFunction(buffer, "i", playerid);
  412. // Call the test.
  413. buffer[1] = '@';
  414. buffer[2] = 'y';
  415. P:5("Testing_Next(): Calling %s", unpack(buffer[1]));
  416. YSI_g_sInTest = true;
  417. CallLocalFunction(buffer, "i", playerid);
  418. }
  419. else
  420. {
  421. YSI_g_sAsked = true;
  422. // No more tests.
  423. printf("*** Tests: %d, Fails: %d", YSI_g_sTests, YSI_g_sFails);
  424. if (!YSI_g_sFails)
  425. {
  426. TEST_REPORT(" ");
  427. TEST_REPORT(" ||==========================|| ");
  428. TEST_REPORT(" || ALL PLAYER TESTS PASSED! || ");
  429. TEST_REPORT(" ||==========================|| ");
  430. TEST_REPORT(" ");
  431. }
  432. }
  433. // If the test needs a player but doesn't ask them anything
  434. // then we can't wait for "OnDialogResponse" to run the next
  435. // one.
  436. if (YSI_g_sAsked)
  437. {
  438. break;
  439. }
  440. else if (fails == YSI_g_sFails)
  441. {
  442. TEST_REPORT(TEST_PASSED);
  443. }
  444. }
  445. }
  446. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
  447. {
  448. if (dialogid == Y_TESTING_DIALOG_ID)
  449. {
  450. ++YSI_g_sTests;
  451. if (response)
  452. {
  453. // Pass.
  454. TEST_REPORT(TEST_PASSED);
  455. }
  456. else
  457. {
  458. // Fail.
  459. TEST_REPORT(TEST_FAILED " %s", YSI_g_sFailMessage);
  460. ++YSI_g_sFails;
  461. }
  462. Testing_Next(playerid);
  463. return 1;
  464. }
  465. #if defined Testing_OnDialogResponse
  466. return Testing_OnDialogResponse(playerid, dialogid, response, listitem, inputtext);
  467. #else
  468. return 1;
  469. #endif
  470. }
  471. #if defined _ALS_OnDialogResponse
  472. #undef OnDialogResponse
  473. #else
  474. #define _ALS_OnDialogResponse
  475. #endif
  476. #define OnDialogResponse Testing_OnDialogResponse
  477. #if defined Testing_OnDialogResponse
  478. forward Testing_OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]);
  479. #endif
  480. forward OnRuntimeError(code, &bool:suppress);
  481. public OnRuntimeError(code, &bool:suppress)
  482. {
  483. if (YSI_g_sInTest)
  484. {
  485. // Fail the current test if we see any runtime errors. Requires the
  486. // crashdetect plugin to function, but not to compile and run.
  487. Testing_Test(false, "Runtime error detected");
  488. }
  489. #if defined Testing_OnRuntimeError
  490. return Testing_OnRuntimeError(code, suppress);
  491. #else
  492. return 1;
  493. #endif
  494. }
  495. #if defined _ALS_OnRuntimeError
  496. #undef OnRuntimeError
  497. #else
  498. #define _ALS_OnRuntimeError
  499. #endif
  500. #define OnRuntimeError Testing_OnRuntimeError
  501. #if defined Testing_OnRuntimeError
  502. forward Testing_OnRuntimeError(code, &bool:suppress);
  503. #endif
  504. public OnPlayerSpawn(playerid)
  505. {
  506. if (YSI_g_sPlayer == cellmax && !IsPlayerNPC(playerid))
  507. {
  508. TEST_REPORT(" ");
  509. TEST_REPORT(" ||==========================|| ");
  510. TEST_REPORT(" || STARTING PLAYER TESTS... || ");
  511. TEST_REPORT(" ||==========================|| ");
  512. TEST_REPORT(" ");
  513. YSI_g_sTests = 0;
  514. YSI_g_sFails = 0;
  515. Testing_Next(playerid);
  516. }
  517. #if defined Testing_OnPlayerSpawn
  518. return Testing_OnPlayerSpawn(playerid);
  519. #else
  520. return 1;
  521. #endif
  522. }
  523. #if defined _ALS_OnPlayerSpawn
  524. #undef OnPlayerSpawn
  525. #else
  526. #define _ALS_OnPlayerSpawn
  527. #endif
  528. #define OnPlayerSpawn Testing_OnPlayerSpawn
  529. #if defined Testing_OnPlayerSpawn
  530. forward Testing_OnPlayerSpawn(playerid);
  531. #endif
  532. #endif
  533. stock Testing_RunAll()
  534. {
  535. // Disable error messages (as we're likely to generate them).
  536. //state ysi_debug : off;
  537. new
  538. tests,
  539. fails;
  540. TEST_REPORT(" ");
  541. TEST_REPORT(" ||===================|| ");
  542. TEST_REPORT(" || STARTING TESTS... || ");
  543. TEST_REPORT(" ||===================|| ");
  544. TEST_REPORT(" ");
  545. Testing_Run(tests, fails, _, true);
  546. if (YSI_g_sTestResult != 9) printf("*** Test system verification failed!");
  547. else
  548. {
  549. printf("*** Tests: %d, Fails: %d", tests, fails);
  550. if (fails)
  551. {
  552. // List all the failing tests, along with the number of "ASSERT"s
  553. // that didn't pass.
  554. while (YSI_g_sFailTests != 0)
  555. {
  556. printf(" - Test:%s (%d)", deref(YSI_g_sFailTests + 8), ReadAmxMemory(YSI_g_sFailTests + 4)),
  557. YSI_g_sFailTests = ReadAmxMemory(YSI_g_sFailTests);
  558. }
  559. }
  560. else
  561. {
  562. TEST_REPORT(" ");
  563. TEST_REPORT(" ||===================|| ");
  564. TEST_REPORT(" || ALL TESTS PASSED! || ");
  565. TEST_REPORT(" ||===================|| ");
  566. }
  567. TEST_REPORT(" ");
  568. }
  569. //state ysi_debug : on;
  570. CallLocalFunction("OnTestsComplete", "ii", tests, fails);
  571. #if defined TEST_AUTO_EXIT
  572. SendRconCommand("exit");
  573. #endif
  574. //state ysi_debug : on;
  575. }
  576. // Meta tests.
  577. stock Testing_TestRedirect(bool:x, str[] = "", va_args<>)
  578. {
  579. ASSERT(x == bool:YSI_g_sTestResult);
  580. ASSERT(str[0] != '\0');
  581. ASSERT(!strcmp(str, "\2\2\2\2\2", false, 5));
  582. }
  583. Test:y_testing_2()
  584. {
  585. new
  586. t = YSI_g_sTests,
  587. f = YSI_g_sFails;
  588. ASSERT(false == false);
  589. ASSERT(true == true);
  590. ASSERT(TRUE != FALSE);
  591. ASSERT(t + 3 == YSI_g_sTests);
  592. ASSERT(f == YSI_g_sFails);
  593. ASSERT(t + 5 == YSI_g_sTests);
  594. // Fail a fake test on purpose.
  595. //state ysi_debug : on;
  596. P:I("The next test hasn't really failed...");
  597. P:I(" - It is testing the test system.");
  598. //state ysi_debug : off;
  599. ASSERT(false);
  600. ASSERT(f + 1 == YSI_g_sFails); // Not a mistake. Run this test twice to
  601. ASSERT(f + 1 == YSI_g_sFails); // ensure the first one didn't fail too.
  602. --YSI_g_sFails; // Reduce the failure count to not fail the whole suite.
  603. }
  604. TestInit:y_testing_1()
  605. {
  606. YSI_g_sTestResult = 5;
  607. }
  608. Test:y_testing_1()
  609. {
  610. new
  611. x = YSI_g_sTestResult;
  612. ASSERT(FALSE == false);
  613. ASSERT(TRUE == true);
  614. ASSERT(true != false);
  615. ASSERT(isnull(NULL));
  616. ASSERT_TRUE(true);
  617. ASSERT_TRUE(!false);
  618. ASSERT_FALSE(false);
  619. ASSERT_FALSE(!true);
  620. // Test the messages themselves.
  621. #define Testing_Test Testing_TestRedirect
  622. YSI_g_sTestResult = false;
  623. ASSERT(false);
  624. YSI_g_sTestResult = true;
  625. ASSERT(true);
  626. #undef Testing_Test
  627. YSI_g_sTestResult = x + 3;
  628. }
  629. TestClose:y_testing_1()
  630. {
  631. ++YSI_g_sTestResult;
  632. }
  633. #include "..\YSI_Internal\y_shortfunc"