test_macros.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #include "../test/unit_tests.h"
  23. #include <src/core/macros.h>
  24. // These represent enabled and disabled configuration options for testing.
  25. // They will be used by multiple tests.
  26. #define OPTION_ENABLED 1
  27. #define OPTION_DISABLED 0
  28. MARLIN_TEST(macros_bitwise_8, TEST) {
  29. uint8_t odd_set = 0xAA;
  30. uint8_t even_set = 0x55;
  31. for (uint8_t b = 0; b < 8; ++b) {
  32. TEST_ASSERT_EQUAL((b % 2) != 0, TEST(odd_set, b));
  33. TEST_ASSERT_EQUAL((b % 2) == 0, TEST(even_set, b));
  34. }
  35. }
  36. MARLIN_TEST(macros_bitwise_8, SET_BIT_TO) {
  37. uint8_t n = 0x00;
  38. // Test LSB
  39. SET_BIT_TO(n, 0, true);
  40. TEST_ASSERT_EQUAL(0x01, n);
  41. SET_BIT_TO(n, 0, false);
  42. TEST_ASSERT_EQUAL(0x00, n);
  43. // Test MSB
  44. SET_BIT_TO(n, 7, true);
  45. TEST_ASSERT_EQUAL(0x80, n);
  46. SET_BIT_TO(n, 7, false);
  47. TEST_ASSERT_EQUAL(0x00, n);
  48. // Test a bit in the middle
  49. SET_BIT_TO(n, 3, true);
  50. TEST_ASSERT_EQUAL(0x08, n);
  51. SET_BIT_TO(n, 3, false);
  52. TEST_ASSERT_EQUAL(0x00, n);
  53. }
  54. MARLIN_TEST(macros_bitwise_8, SBI) {
  55. uint8_t n;
  56. // Test LSB
  57. n = 0x00;
  58. SBI(n, 0);
  59. TEST_ASSERT_EQUAL(0x01, n);
  60. // Test MSB
  61. n = 0x00;
  62. SBI(n, 7);
  63. TEST_ASSERT_EQUAL(0x80, n);
  64. // Test a bit in the middle
  65. n = 0x00;
  66. SBI(n, 3);
  67. TEST_ASSERT_EQUAL(0x08, n);
  68. }
  69. MARLIN_TEST(macros_bitwise_8, CBI) {
  70. uint8_t n;
  71. // Test LSB
  72. n = 0xFF;
  73. CBI(n, 0);
  74. TEST_ASSERT_EQUAL(0xFE, n);
  75. // Test MSB
  76. n = 0xFF;
  77. CBI(n, 7);
  78. TEST_ASSERT_EQUAL(0x7F, n);
  79. // Test a bit in the middle
  80. n = 0xFF;
  81. CBI(n, 3);
  82. TEST_ASSERT_EQUAL(0xF7, n);
  83. }
  84. MARLIN_TEST(macros_bitwise_8, TBI) {
  85. uint8_t n;
  86. // Test LSB
  87. n = 0xAA;
  88. TBI(n, 0);
  89. TEST_ASSERT_EQUAL(0xAB, n);
  90. // Test MSB
  91. n = 0xAA;
  92. TBI(n, 7);
  93. TEST_ASSERT_EQUAL(0x2A, n);
  94. // Test a bit in the middle
  95. n = 0xAA;
  96. TBI(n, 3);
  97. TEST_ASSERT_EQUAL(0xA2, n);
  98. }
  99. // 32-bit BIT operation tests
  100. // These verify the above macros, but specifically with the MSB of a uint32_t.
  101. // This ensures that the macros are not limited to 8-bit operations.
  102. MARLIN_TEST(macros_bitwise_32, TEST_32bit) {
  103. uint32_t odd_set = 0x80000000;
  104. uint32_t even_set = 0x00000000;
  105. TEST_ASSERT_EQUAL(true, TEST(odd_set, 31));
  106. TEST_ASSERT_EQUAL(false, TEST(even_set, 31));
  107. }
  108. MARLIN_TEST(macros_bitwise_32, SET_BIT_TO_32bit) {
  109. uint32_t n = 0x00000000;
  110. // Test MSB
  111. SET_BIT_TO(n, 31, true);
  112. TEST_ASSERT_EQUAL(0x80000000, n);
  113. SET_BIT_TO(n, 31, false);
  114. TEST_ASSERT_EQUAL(0x00000000, n);
  115. }
  116. MARLIN_TEST(macros_bitwise_32, SBI_32bit) {
  117. uint32_t n = 0x00000000;
  118. // Test MSB
  119. SBI(n, 31);
  120. TEST_ASSERT_EQUAL(0x80000000, n);
  121. }
  122. MARLIN_TEST(macros_bitwise_32, CBI_32bit) {
  123. uint32_t n = 0xFFFFFFFF;
  124. // Test MSB
  125. CBI(n, 31);
  126. TEST_ASSERT_EQUAL(0x7FFFFFFF, n);
  127. }
  128. MARLIN_TEST(macros_bitwise_32, TBI_32bit) {
  129. uint32_t n = 0x7FFFFFFF;
  130. // Test MSB
  131. TBI(n, 31);
  132. TEST_ASSERT_EQUAL(0xFFFFFFFF, n);
  133. }
  134. // Geometry macros
  135. MARLIN_TEST(macros_geometry, cu_int) {
  136. TEST_ASSERT_EQUAL(8, cu(2));
  137. TEST_ASSERT_EQUAL(27, cu(3));
  138. }
  139. MARLIN_TEST(macros_geometry, cu_float) {
  140. TEST_ASSERT_FLOAT_WITHIN(0.001f, 8.615f, cu(2.05f));
  141. TEST_ASSERT_FLOAT_WITHIN(0.001f, 28.094f, cu(3.04f));
  142. TEST_ASSERT_FLOAT_WITHIN(0.001f, 13.998f, cu(2.41f));
  143. }
  144. MARLIN_TEST(macros_geometry, RADIANS) {
  145. TEST_ASSERT_FLOAT_WITHIN(0.001f, float(M_PI), RADIANS(180.0f));
  146. TEST_ASSERT_FLOAT_WITHIN(0.001f, 0.0f, RADIANS(0.0f));
  147. TEST_ASSERT_FLOAT_WITHIN(0.001f, float(M_PI) / 4, RADIANS(45.0f));
  148. TEST_ASSERT_FLOAT_WITHIN(0.001f, float(M_PI) / 2, RADIANS(90.0f));
  149. TEST_ASSERT_FLOAT_WITHIN(0.001f, 3 * float(M_PI) / 2, RADIANS(270.0f));
  150. TEST_ASSERT_FLOAT_WITHIN(0.001f, 4 * float(M_PI), RADIANS(720.0f));
  151. }
  152. MARLIN_TEST(macros_geometry, DEGREES) {
  153. TEST_ASSERT_FLOAT_WITHIN(0.001f, 180.0f, DEGREES(float(M_PI)));
  154. TEST_ASSERT_FLOAT_WITHIN(0.001f, 0.0f, DEGREES(0.0f));
  155. TEST_ASSERT_FLOAT_WITHIN(0.001f, 45.0f, DEGREES(float(M_PI) / 4));
  156. TEST_ASSERT_FLOAT_WITHIN(0.001f, 90.0f, DEGREES(float(M_PI) / 2));
  157. TEST_ASSERT_FLOAT_WITHIN(0.001f, 270.0f, DEGREES(3 * float(M_PI) / 2));
  158. TEST_ASSERT_FLOAT_WITHIN(0.001f, 720.0f, DEGREES(4 * float(M_PI)));
  159. }
  160. MARLIN_TEST(macros_geometry, HYPOT2) {
  161. TEST_ASSERT_EQUAL(25, HYPOT2(3, 4));
  162. TEST_ASSERT_FLOAT_WITHIN(0.001f, 13.0f, HYPOT2(2.0f, 3.0f));
  163. TEST_ASSERT_FLOAT_WITHIN(0.001f, 18.72f, HYPOT2(2.4f, 3.6f));
  164. }
  165. MARLIN_TEST(macros_geometry, NORMSQ) {
  166. TEST_ASSERT_EQUAL(14, NORMSQ(1, 2, 3));
  167. TEST_ASSERT_FLOAT_WITHIN(0.001f, 14.0f, NORMSQ(1.0f, 2.0f, 3.0f));
  168. TEST_ASSERT_FLOAT_WITHIN(0.001f, 20.16f, NORMSQ(1.2f, 2.4f, 3.6f));
  169. }
  170. MARLIN_TEST(macros_geometry, CIRCLE_AREA) {
  171. TEST_ASSERT_EQUAL(float(M_PI) * 4, CIRCLE_AREA(2));
  172. }
  173. MARLIN_TEST(macros_geometry, CIRCLE_CIRC) {
  174. TEST_ASSERT_EQUAL(2 * float(M_PI) * 3, CIRCLE_CIRC(3));
  175. }
  176. MARLIN_TEST(macros_numeric, SIGN) {
  177. TEST_ASSERT_EQUAL(1, SIGN(100));
  178. TEST_ASSERT_EQUAL(-1, SIGN(-100));
  179. TEST_ASSERT_EQUAL(0, SIGN(0));
  180. }
  181. MARLIN_TEST(macros_numeric, IS_POWER_OF_2) {
  182. TEST_ASSERT_EQUAL(false, IS_POWER_OF_2(0));
  183. TEST_ASSERT_EQUAL(true, IS_POWER_OF_2(1));
  184. TEST_ASSERT_EQUAL(true, IS_POWER_OF_2(4));
  185. TEST_ASSERT_EQUAL(false, IS_POWER_OF_2(5));
  186. TEST_ASSERT_EQUAL(false, IS_POWER_OF_2(0x80000001));
  187. TEST_ASSERT_EQUAL(true, IS_POWER_OF_2(0x80000000));
  188. }
  189. // Numeric constraints
  190. MARLIN_TEST(macros_numeric, NOLESS_int) {
  191. // Scenario 1: Input was already acceptable
  192. int a = 8;
  193. NOLESS(a, 5);
  194. TEST_ASSERT_EQUAL(8, a);
  195. // Original scenario: Input was less than the limit
  196. a = 5;
  197. NOLESS(a, 10);
  198. TEST_ASSERT_EQUAL(10, a);
  199. // Scenario 2: Input is negative, and coerces to a positive number
  200. a = -5;
  201. NOLESS(a, 0);
  202. TEST_ASSERT_EQUAL(0, a);
  203. // Scenario 3: Input is negative, and coerces to another negative number
  204. a = -10;
  205. NOLESS(a, -5);
  206. TEST_ASSERT_EQUAL(-5, a);
  207. }
  208. MARLIN_TEST(macros_numeric, NOLESS_uint) {
  209. // Scenario 1: Input was already acceptable
  210. unsigned int b = 8u;
  211. NOLESS(b, 5u);
  212. TEST_ASSERT_EQUAL(8u, b);
  213. // Original scenario: Input was less than the limit
  214. b = 5u;
  215. NOLESS(b, 10u);
  216. TEST_ASSERT_EQUAL(10u, b);
  217. }
  218. MARLIN_TEST(macros_numeric, NOLESS_float) {
  219. // Scenario 1: Input was already acceptable
  220. float c = 8.5f;
  221. NOLESS(c, 5.5f);
  222. TEST_ASSERT_EQUAL_FLOAT(8.5f, c);
  223. // Original scenario: Input was less than the limit
  224. c = 5.5f;
  225. NOLESS(c, 10.5f);
  226. TEST_ASSERT_EQUAL_FLOAT(10.5f, c);
  227. // Scenario 2: Input is negative, and coerces to a positive number
  228. c = -5.5f;
  229. NOLESS(c, 5.0f);
  230. TEST_ASSERT_EQUAL_FLOAT(5.0f, c);
  231. // Scenario 3: Input is negative, and coerces to another negative number
  232. c = -10.5f;
  233. NOLESS(c, -5.5f);
  234. TEST_ASSERT_EQUAL_FLOAT(-5.5f, c);
  235. c = -5.5f;
  236. NOLESS(c, -10.5f);
  237. TEST_ASSERT_EQUAL_FLOAT(-5.5f, c);
  238. }
  239. MARLIN_TEST(macros_numeric, NOMORE_int) {
  240. // Scenario 1: Input was already acceptable
  241. int a = 8;
  242. NOMORE(a, 10);
  243. TEST_ASSERT_EQUAL(8, a);
  244. // Original scenario: Input was more than the limit
  245. a = 15;
  246. NOMORE(a, 10);
  247. TEST_ASSERT_EQUAL(10, a);
  248. // Scenario 2: Input is positive, and coerces to a negative number
  249. a = 5;
  250. NOMORE(a, -2);
  251. TEST_ASSERT_EQUAL(-2, a);
  252. // Scenario 3: Input is negative, and coerces to another negative number
  253. a = -5;
  254. NOMORE(a, -10);
  255. TEST_ASSERT_EQUAL(-10, a);
  256. }
  257. MARLIN_TEST(macros_numeric, NOMORE_uint) {
  258. // Scenario 1: Input was already acceptable
  259. unsigned int b = 8u;
  260. NOMORE(b, 10u);
  261. TEST_ASSERT_EQUAL(8u, b);
  262. // Original scenario: Input was more than the limit
  263. b = 15u;
  264. NOMORE(b, 10u);
  265. TEST_ASSERT_EQUAL(10u, b);
  266. }
  267. MARLIN_TEST(macros_numeric, NOMORE_float) {
  268. // Scenario 1: Input was already acceptable
  269. float c = 8.5f;
  270. NOMORE(c, 10.5f);
  271. TEST_ASSERT_EQUAL_FLOAT(8.5f, c);
  272. // Original scenario: Input was more than the limit
  273. c = 15.5f;
  274. NOMORE(c, 10.5f);
  275. TEST_ASSERT_EQUAL_FLOAT(10.5f, c);
  276. // Scenario 2: Input is positive, and coerces to a negative number
  277. c = 5.5f;
  278. NOMORE(c, -1.7f);
  279. TEST_ASSERT_EQUAL_FLOAT(-1.7f, c);
  280. // Scenario 3: Input is negative, and coerces to another negative number
  281. c = -5.5f;
  282. NOMORE(c, -10.5f);
  283. TEST_ASSERT_EQUAL_FLOAT(-10.5f, c);
  284. }
  285. MARLIN_TEST(macros_numeric, LIMIT_int) {
  286. int a = 15;
  287. LIMIT(a, 10, 20);
  288. TEST_ASSERT_EQUAL(15, a);
  289. a = 5;
  290. LIMIT(a, 10, 20);
  291. TEST_ASSERT_EQUAL(10, a);
  292. a = 25;
  293. LIMIT(a, 10, 20);
  294. TEST_ASSERT_EQUAL(20, a);
  295. // Scenario: Range is [-10, -5]
  296. a = -8;
  297. LIMIT(a, -10, -5);
  298. TEST_ASSERT_EQUAL(-8, a);
  299. a = -12;
  300. LIMIT(a, -10, -5);
  301. TEST_ASSERT_EQUAL(-10, a);
  302. a = -3;
  303. LIMIT(a, -10, -5);
  304. TEST_ASSERT_EQUAL(-5, a);
  305. // Scenario: Range is [-10, 5]
  306. a = 0;
  307. LIMIT(a, -10, 5);
  308. TEST_ASSERT_EQUAL(0, a);
  309. a = -12;
  310. LIMIT(a, -10, 5);
  311. TEST_ASSERT_EQUAL(-10, a);
  312. a = 6;
  313. LIMIT(a, -10, 5);
  314. TEST_ASSERT_EQUAL(5, a);
  315. }
  316. MARLIN_TEST(macros_numeric, LIMIT_uint) {
  317. unsigned int b = 15u;
  318. LIMIT(b, 10u, 20u);
  319. TEST_ASSERT_EQUAL(15u, b);
  320. b = 5u;
  321. LIMIT(b, 10u, 20u);
  322. TEST_ASSERT_EQUAL(10u, b);
  323. b = 25u;
  324. LIMIT(b, 10u, 20u);
  325. TEST_ASSERT_EQUAL(20u, b);
  326. }
  327. MARLIN_TEST(macros_numeric, LIMIT_float) {
  328. float c = 15.5f;
  329. LIMIT(c, 10.5f, 20.5f);
  330. TEST_ASSERT_EQUAL_FLOAT(15.5f, c);
  331. c = 5.5f;
  332. LIMIT(c, 10.5f, 20.5f);
  333. TEST_ASSERT_EQUAL_FLOAT(10.5f, c);
  334. c = 25.5f;
  335. LIMIT(c, 10.5f, 20.5f);
  336. TEST_ASSERT_EQUAL_FLOAT(20.5f, c);
  337. // Scenario: Range is [-10.5, -5.5]
  338. c = -8.5f;
  339. LIMIT(c, -10.5f, -5.5f);
  340. TEST_ASSERT_EQUAL_FLOAT(-8.5f, c);
  341. c = -12.5f;
  342. LIMIT(c, -10.5f, -5.5f);
  343. TEST_ASSERT_EQUAL_FLOAT(-10.5f, c);
  344. c = -3.5f;
  345. LIMIT(c, -10.5f, -5.5f);
  346. TEST_ASSERT_EQUAL_FLOAT(-5.5f, c);
  347. // Scenario: Range is [-10.5, 5.5]
  348. c = 0.0f;
  349. LIMIT(c, -10.5f, 5.5f);
  350. TEST_ASSERT_EQUAL_FLOAT(0.0f, c);
  351. c = -12.5f;
  352. LIMIT(c, -10.5f, 5.5f);
  353. TEST_ASSERT_EQUAL_FLOAT(-10.5f, c);
  354. c = 6.5f;
  355. LIMIT(c, -10.5f, 5.5f);
  356. TEST_ASSERT_EQUAL_FLOAT(5.5f, c);
  357. }
  358. // Looping macros
  359. MARLIN_TEST(macros_looping, DO_macro) {
  360. #define _M_1(A) (A)
  361. int sum = DO(M, +, 1, 2, 3, 4, 5);
  362. TEST_ASSERT_EQUAL(15, sum);
  363. // Test with maximum number of arguments
  364. sum = DO(M, +, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  365. 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40);
  366. TEST_ASSERT_EQUAL(820, sum);
  367. #undef _M_1
  368. }
  369. // Configuration Options
  370. MARLIN_TEST(macros_options, ENABLED_DISABLED) {
  371. #define OPTION_A
  372. #define OPTION_B 1
  373. #define OPTION_C true
  374. #define OPTION_D 0
  375. #define OPTION_E false
  376. // #define OPTION_F
  377. // Test ENABLED macro
  378. TEST_ASSERT_TRUE(ENABLED(OPTION_A));
  379. TEST_ASSERT_TRUE(ENABLED(OPTION_B));
  380. TEST_ASSERT_TRUE(ENABLED(OPTION_C));
  381. TEST_ASSERT_FALSE(ENABLED(OPTION_D));
  382. TEST_ASSERT_FALSE(ENABLED(OPTION_E));
  383. TEST_ASSERT_FALSE(ENABLED(OPTION_F));
  384. // Test DISABLED macro
  385. TEST_ASSERT_FALSE(DISABLED(OPTION_A));
  386. TEST_ASSERT_FALSE(DISABLED(OPTION_B));
  387. TEST_ASSERT_FALSE(DISABLED(OPTION_C));
  388. TEST_ASSERT_TRUE(DISABLED(OPTION_D));
  389. TEST_ASSERT_TRUE(DISABLED(OPTION_E));
  390. TEST_ASSERT_TRUE(DISABLED(OPTION_F));
  391. #undef OPTION_A
  392. #undef OPTION_B
  393. #undef OPTION_C
  394. #undef OPTION_D
  395. #undef OPTION_E
  396. }
  397. MARLIN_TEST(macros_options, ANY) {
  398. TEST_ASSERT_TRUE(ANY(OPTION_DISABLED, OPTION_ENABLED, OPTION_DISABLED)); // Enabled option in the middle
  399. TEST_ASSERT_TRUE(ANY(OPTION_ENABLED, OPTION_DISABLED, OPTION_DISABLED)); // Enabled option at the beginning
  400. TEST_ASSERT_TRUE(ANY(OPTION_DISABLED, OPTION_DISABLED, OPTION_ENABLED)); // Enabled option at the end
  401. TEST_ASSERT_FALSE(ANY(OPTION_DISABLED, OPTION_DISABLED, OPTION_DISABLED)); // All options disabled
  402. }
  403. MARLIN_TEST(macros_options, ALL) {
  404. TEST_ASSERT_TRUE(ALL(OPTION_ENABLED, OPTION_ENABLED, OPTION_ENABLED)); // All options enabled
  405. TEST_ASSERT_FALSE(ALL(OPTION_ENABLED, OPTION_DISABLED, OPTION_ENABLED)); // Disabled option in the middle
  406. TEST_ASSERT_FALSE(ALL(OPTION_DISABLED, OPTION_ENABLED, OPTION_ENABLED)); // Disabled option at the beginning
  407. TEST_ASSERT_FALSE(ALL(OPTION_ENABLED, OPTION_ENABLED, OPTION_DISABLED)); // Disabled option at the end
  408. TEST_ASSERT_FALSE(ALL(OPTION_DISABLED, OPTION_DISABLED, OPTION_DISABLED)); // All options disabled
  409. }
  410. MARLIN_TEST(macros_options, NONE) {
  411. TEST_ASSERT_FALSE(NONE(OPTION_ENABLED, OPTION_ENABLED, OPTION_ENABLED)); // All options enabled
  412. TEST_ASSERT_FALSE(NONE(OPTION_ENABLED, OPTION_DISABLED, OPTION_ENABLED)); // Disabled option in the middle
  413. TEST_ASSERT_FALSE(NONE(OPTION_DISABLED, OPTION_ENABLED, OPTION_ENABLED)); // Disabled option at the beginning
  414. TEST_ASSERT_FALSE(NONE(OPTION_ENABLED, OPTION_ENABLED, OPTION_DISABLED)); // Disabled option at the end
  415. TEST_ASSERT_TRUE(NONE(OPTION_DISABLED, OPTION_DISABLED, OPTION_DISABLED)); // All options disabled
  416. }
  417. MARLIN_TEST(macros_options, COUNT_ENABLED) {
  418. TEST_ASSERT_EQUAL(3, COUNT_ENABLED(OPTION_ENABLED, OPTION_ENABLED, OPTION_ENABLED)); // All options enabled
  419. TEST_ASSERT_EQUAL(2, COUNT_ENABLED(OPTION_ENABLED, OPTION_DISABLED, OPTION_ENABLED)); // Disabled option in the middle
  420. TEST_ASSERT_EQUAL(2, COUNT_ENABLED(OPTION_DISABLED, OPTION_ENABLED, OPTION_ENABLED)); // Disabled option at the beginning
  421. TEST_ASSERT_EQUAL(2, COUNT_ENABLED(OPTION_ENABLED, OPTION_ENABLED, OPTION_DISABLED)); // Disabled option at the end
  422. TEST_ASSERT_EQUAL(0, COUNT_ENABLED(OPTION_DISABLED, OPTION_DISABLED, OPTION_DISABLED)); // All options disabled
  423. }
  424. MARLIN_TEST(macros_options, MANY) {
  425. TEST_ASSERT_FALSE(MANY(OPTION_ENABLED, OPTION_DISABLED, OPTION_DISABLED)); // Only one option enabled
  426. TEST_ASSERT_TRUE(MANY(OPTION_ENABLED, OPTION_ENABLED, OPTION_DISABLED)); // Two options enabled
  427. TEST_ASSERT_TRUE(MANY(OPTION_ENABLED, OPTION_ENABLED, OPTION_ENABLED)); // All options enabled
  428. TEST_ASSERT_FALSE(MANY(OPTION_DISABLED, OPTION_DISABLED, OPTION_DISABLED)); // No options enabled
  429. }
  430. // Ternary macros
  431. MARLIN_TEST(macros_options, TERN) {
  432. TEST_ASSERT_EQUAL(1, TERN(OPTION_ENABLED, 1, 0)); // OPTION_ENABLED is enabled, so it should return '1'
  433. TEST_ASSERT_EQUAL(0, TERN(OPTION_DISABLED, 1, 0)); // OPTION_DISABLED is disabled, so it should return '0'
  434. }
  435. MARLIN_TEST(macros_options, TERN0) {
  436. TEST_ASSERT_EQUAL(1, TERN0(OPTION_ENABLED, 1)); // OPTION_ENABLED is enabled, so it should return '1'
  437. TEST_ASSERT_EQUAL(0, TERN0(OPTION_DISABLED, 1)); // OPTION_DISABLED is disabled, so it should return '0'
  438. }
  439. MARLIN_TEST(macros_options, TERN1) {
  440. TEST_ASSERT_EQUAL(0, TERN1(OPTION_ENABLED, 0)); // OPTION_ENABLED is enabled, so it should return '0'
  441. TEST_ASSERT_EQUAL(1, TERN1(OPTION_DISABLED, 0)); // OPTION_DISABLED is disabled, so it should return '1'
  442. }
  443. MARLIN_TEST(macros_options, TERN_) {
  444. TEST_ASSERT_EQUAL(-1, TERN_(OPTION_ENABLED, -)1); // OPTION_ENABLED is enabled, so it should return '1'
  445. TEST_ASSERT_EQUAL(1, TERN_(OPTION_DISABLED, -)1); // OPTION_DISABLED is disabled, so it should return nothing
  446. }
  447. MARLIN_TEST(macros_options, IF_DISABLED) {
  448. TEST_ASSERT_EQUAL(1, IF_DISABLED(OPTION_ENABLED, -)1); // OPTION_ENABLED is enabled, so it should return nothing
  449. TEST_ASSERT_EQUAL(-1, IF_DISABLED(OPTION_DISABLED, -)1); // OPTION_DISABLED is disabled, so it should return '1'
  450. }
  451. MARLIN_TEST(macros_options, OPTITEM) {
  452. int enabledArray[] = {OPTITEM(OPTION_ENABLED, 1, 2)};
  453. int disabledArray[] = {OPTITEM(OPTION_DISABLED, 1, 2)};
  454. TEST_ASSERT_EQUAL(2, sizeof(enabledArray) / sizeof(int)); // OPTION_ENABLED is enabled, so it should return an array of size 2
  455. TEST_ASSERT_EQUAL(0, sizeof(disabledArray) / sizeof(int)); // OPTION_DISABLED is disabled, so it should return an array of size 0
  456. }
  457. MARLIN_TEST(macros_options, OPTARG) {
  458. int enabledArgs[] = {0 OPTARG(OPTION_ENABLED, 1, 2)};
  459. int disabledArgs[] = {0 OPTARG(OPTION_DISABLED, 1, 2)};
  460. int sumEnabledArgs = 0;
  461. for (const auto& arg : enabledArgs) {
  462. sumEnabledArgs += arg;
  463. }
  464. int sumDisabledArgs = 0;
  465. for (const auto& arg : disabledArgs) {
  466. sumDisabledArgs += arg;
  467. }
  468. TEST_ASSERT_EQUAL(3, sumEnabledArgs); // OPTION_ENABLED is enabled, so it should return 3
  469. TEST_ASSERT_EQUAL(0, sumDisabledArgs); // OPTION_DISABLED is disabled, so it should return 0
  470. }
  471. MARLIN_TEST(macros_options, OPTCODE) {
  472. int enabledCode = 0; OPTCODE(OPTION_ENABLED, enabledCode = 1);
  473. int disabledCode = 0; OPTCODE(OPTION_DISABLED, disabledCode = 1);
  474. TEST_ASSERT_EQUAL(1, enabledCode); // OPTION_ENABLED is enabled, so it should return 1
  475. TEST_ASSERT_EQUAL(0, disabledCode); // OPTION_DISABLED is disabled, so it should return 0
  476. }
  477. MARLIN_TEST(macros_optional_math, PLUS_TERN0) {
  478. int enabledPlus = 5 PLUS_TERN0(OPTION_ENABLED, 2);
  479. int disabledPlus = 5 PLUS_TERN0(OPTION_DISABLED, 2);
  480. TEST_ASSERT_EQUAL(7, enabledPlus); // OPTION_ENABLED is enabled, so it should return 7
  481. TEST_ASSERT_EQUAL(5, disabledPlus); // OPTION_DISABLED is disabled, so it should return 5
  482. }
  483. MARLIN_TEST(macros_optional_math, MINUS_TERN0) {
  484. int enabledMinus = 5 MINUS_TERN0(OPTION_ENABLED, 2);
  485. int disabledMinus = 5 MINUS_TERN0(OPTION_DISABLED, 2);
  486. TEST_ASSERT_EQUAL(3, enabledMinus); // OPTION_ENABLED is enabled, so it should return 3
  487. TEST_ASSERT_EQUAL(5, disabledMinus); // OPTION_DISABLED is disabled, so it should return 5
  488. }
  489. MARLIN_TEST(macros_optional_math, MUL_TERN1) {
  490. int enabledMul = 5 MUL_TERN1(OPTION_ENABLED, 2);
  491. int disabledMul = 5 MUL_TERN1(OPTION_DISABLED, 2);
  492. TEST_ASSERT_EQUAL(10, enabledMul); // OPTION_ENABLED is enabled, so it should return 10
  493. TEST_ASSERT_EQUAL(5, disabledMul); // OPTION_DISABLED is disabled, so it should return 5
  494. }
  495. MARLIN_TEST(macros_optional_math, DIV_TERN1) {
  496. int enabledDiv = 10 DIV_TERN1(OPTION_ENABLED, 2);
  497. int disabledDiv = 10 DIV_TERN1(OPTION_DISABLED, 2);
  498. TEST_ASSERT_EQUAL(5, enabledDiv); // OPTION_ENABLED is enabled, so it should return 5
  499. TEST_ASSERT_EQUAL(10, disabledDiv); // OPTION_DISABLED is disabled, so it should return 10
  500. }
  501. MARLIN_TEST(macros_optional_math, SUM_TERN) {
  502. int enabledSum = SUM_TERN(OPTION_ENABLED, 5, 2);
  503. int disabledSum = SUM_TERN(OPTION_DISABLED, 5, 2);
  504. TEST_ASSERT_EQUAL(7, enabledSum); // OPTION_ENABLED is enabled, so it should return 7
  505. TEST_ASSERT_EQUAL(5, disabledSum); // OPTION_DISABLED is disabled, so it should return 5
  506. }
  507. MARLIN_TEST(macros_optional_math, DIFF_TERN) {
  508. int enabledDiff = DIFF_TERN(OPTION_ENABLED, 5, 2);
  509. int disabledDiff = DIFF_TERN(OPTION_DISABLED, 5, 2);
  510. TEST_ASSERT_EQUAL(3, enabledDiff); // OPTION_ENABLED is enabled, so it should return 3
  511. TEST_ASSERT_EQUAL(5, disabledDiff); // OPTION_DISABLED is disabled, so it should return 5
  512. }
  513. MARLIN_TEST(macros_optional_math, MUL_TERN) {
  514. int enabledMul = MUL_TERN(OPTION_ENABLED, 5, 2);
  515. int disabledMul = MUL_TERN(OPTION_DISABLED, 5, 2);
  516. TEST_ASSERT_EQUAL(10, enabledMul); // OPTION_ENABLED is enabled, so it should return 10
  517. TEST_ASSERT_EQUAL(5, disabledMul); // OPTION_DISABLED is disabled, so it should return 5
  518. }
  519. MARLIN_TEST(macros_optional_math, DIV_TERN) {
  520. int enabledDiv = DIV_TERN(OPTION_ENABLED, 10, 2);
  521. int disabledDiv = DIV_TERN(OPTION_DISABLED, 10, 2);
  522. TEST_ASSERT_EQUAL(5, enabledDiv); // OPTION_ENABLED is enabled, so it should return 5
  523. TEST_ASSERT_EQUAL(10, disabledDiv); // OPTION_DISABLED is disabled, so it should return 10
  524. }
  525. // Mock pin definitions
  526. #define PIN1_PIN 1
  527. #define PIN2_PIN 2
  528. #define PIN3_PIN -1
  529. MARLIN_TEST(macros_pins, PIN_EXISTS) {
  530. // Test PIN_EXISTS macro
  531. int pin1_exists, pin2_exists, pin3_exists, pin4_exists;
  532. #if PIN_EXISTS(PIN1)
  533. pin1_exists = 1;
  534. #else
  535. pin1_exists = 0;
  536. #endif
  537. #if PIN_EXISTS(PIN2)
  538. pin2_exists = 1;
  539. #else
  540. pin2_exists = 0;
  541. #endif
  542. #if PIN_EXISTS(PIN3)
  543. pin3_exists = 1;
  544. #else
  545. pin3_exists = 0;
  546. #endif
  547. #if PIN_EXISTS(PIN4)
  548. pin4_exists = 1;
  549. #else
  550. pin4_exists = 0;
  551. #endif
  552. TEST_ASSERT_TRUE(pin1_exists);
  553. TEST_ASSERT_TRUE(pin2_exists);
  554. TEST_ASSERT_FALSE(pin3_exists);
  555. TEST_ASSERT_FALSE(pin4_exists);
  556. }
  557. MARLIN_TEST(macros_pins, PINS_EXIST) {
  558. // Test PINS_EXIST macro
  559. int pins1_2_exist, pins1_3_exist;
  560. #if PINS_EXIST(PIN1, PIN2)
  561. pins1_2_exist = 1;
  562. #else
  563. pins1_2_exist = 0;
  564. #endif
  565. #if PINS_EXIST(PIN1, PIN3)
  566. pins1_3_exist = 1;
  567. #else
  568. pins1_3_exist = 0;
  569. #endif
  570. TEST_ASSERT_TRUE(pins1_2_exist);
  571. TEST_ASSERT_FALSE(pins1_3_exist);
  572. }
  573. MARLIN_TEST(macros_pins, ANY_PIN) {
  574. // Test ANY_PIN macro
  575. int any_pin1_3, any_pin3_4;
  576. #if ANY_PIN(PIN1, PIN3)
  577. any_pin1_3 = 1;
  578. #else
  579. any_pin1_3 = 0;
  580. #endif
  581. #if ANY_PIN(PIN3, PIN4)
  582. any_pin3_4 = 1;
  583. #else
  584. any_pin3_4 = 0;
  585. #endif
  586. TEST_ASSERT_TRUE(any_pin1_3);
  587. TEST_ASSERT_FALSE(any_pin3_4);
  588. }
  589. // Undefine mock pin definitions
  590. #undef PIN1_PIN
  591. #undef PIN2_PIN
  592. #undef PIN3_PIN
  593. // Mock button definitions
  594. #define BTN_BUTTON1 1
  595. #define BTN_BUTTON2 2
  596. #define BTN_BUTTON3 -1
  597. MARLIN_TEST(macros_buttons, BUTTON_EXISTS) {
  598. // Test BUTTON_EXISTS macro
  599. int button1_exists, button2_exists, button3_exists, button4_exists;
  600. #if BUTTON_EXISTS(BUTTON1)
  601. button1_exists = 1;
  602. #else
  603. button1_exists = 0;
  604. #endif
  605. #if BUTTON_EXISTS(BUTTON2)
  606. button2_exists = 1;
  607. #else
  608. button2_exists = 0;
  609. #endif
  610. #if BUTTON_EXISTS(BUTTON3)
  611. button3_exists = 1;
  612. #else
  613. button3_exists = 0;
  614. #endif
  615. #if BUTTON_EXISTS(BUTTON4)
  616. button4_exists = 1;
  617. #else
  618. button4_exists = 0;
  619. #endif
  620. TEST_ASSERT_TRUE(button1_exists);
  621. TEST_ASSERT_TRUE(button2_exists);
  622. TEST_ASSERT_FALSE(button3_exists);
  623. TEST_ASSERT_FALSE(button4_exists);
  624. }
  625. MARLIN_TEST(macros_buttons, BUTTONS_EXIST) {
  626. // Test BUTTONS_EXIST macro
  627. int buttons1_2_exist, buttons1_3_exist;
  628. #if BUTTONS_EXIST(BUTTON1, BUTTON2)
  629. buttons1_2_exist = 1;
  630. #else
  631. buttons1_2_exist = 0;
  632. #endif
  633. #if BUTTONS_EXIST(BUTTON1, BUTTON3)
  634. buttons1_3_exist = 1;
  635. #else
  636. buttons1_3_exist = 0;
  637. #endif
  638. TEST_ASSERT_TRUE(buttons1_2_exist);
  639. TEST_ASSERT_FALSE(buttons1_3_exist);
  640. }
  641. MARLIN_TEST(macros_buttons, ANY_BUTTON) {
  642. // Test ANY_BUTTON macro
  643. int any_button1_3, any_button3_4;
  644. #if ANY_BUTTON(BUTTON1, BUTTON3)
  645. any_button1_3 = 1;
  646. #else
  647. any_button1_3 = 0;
  648. #endif
  649. #if ANY_BUTTON(BUTTON3, BUTTON4)
  650. any_button3_4 = 1;
  651. #else
  652. any_button3_4 = 0;
  653. #endif
  654. TEST_ASSERT_TRUE(any_button1_3);
  655. TEST_ASSERT_FALSE(any_button3_4);
  656. }
  657. // Undefine mock button definitions
  658. #undef BTN_BUTTON1
  659. #undef BTN_BUTTON2
  660. #undef BTN_BUTTON3
  661. MARLIN_TEST(macros_value_functions, WITHIN) {
  662. // Test WITHIN macro
  663. TEST_ASSERT_TRUE(WITHIN(5, 1, 10)); // 5 is within 1 and 10
  664. TEST_ASSERT_TRUE(WITHIN(1, 1, 10)); // Edge case: 1 is the lower limit
  665. TEST_ASSERT_TRUE(WITHIN(10, 1, 10)); // Edge case: 10 is the upper limit
  666. TEST_ASSERT_FALSE(WITHIN(0, 1, 10)); // Edge case: 0 is just below the lower limit
  667. TEST_ASSERT_FALSE(WITHIN(11, 1, 10)); // Edge case: 11 is just above the upper limit
  668. TEST_ASSERT_FALSE(WITHIN(15, 1, 10)); // 15 is not within 1 and 10
  669. }
  670. MARLIN_TEST(macros_value_functions, ISEOL) {
  671. // Test ISEOL macro
  672. TEST_ASSERT_TRUE(ISEOL('\n')); // '\n' is an end-of-line character
  673. TEST_ASSERT_TRUE(ISEOL('\r')); // '\r' is an end-of-line character
  674. TEST_ASSERT_FALSE(ISEOL('a')); // 'a' is not an end-of-line character
  675. }
  676. MARLIN_TEST(macros_value_functions, NUMERIC) {
  677. // Test NUMERIC macro
  678. TEST_ASSERT_TRUE(NUMERIC('0')); // Edge case: '0' is the lowest numeric character
  679. TEST_ASSERT_TRUE(NUMERIC('5')); // '5' is a numeric character
  680. TEST_ASSERT_TRUE(NUMERIC('9')); // Edge case: '9' is the highest numeric character
  681. TEST_ASSERT_FALSE(NUMERIC('0' - 1)); // Edge case: '/' is just before '0' in ASCII
  682. TEST_ASSERT_FALSE(NUMERIC('9' + 1)); // Edge case: ':' is just after '9' in ASCII
  683. TEST_ASSERT_FALSE(NUMERIC('a')); // 'a' is not a numeric character
  684. }
  685. MARLIN_TEST(macros_value_functions, DECIMAL) {
  686. // Test DECIMAL macro
  687. TEST_ASSERT_TRUE(DECIMAL('0')); // Edge case: '0' is the lowest numeric character
  688. TEST_ASSERT_TRUE(DECIMAL('5')); // '5' is a numeric character
  689. TEST_ASSERT_TRUE(DECIMAL('9')); // Edge case: '9' is the highest numeric character
  690. TEST_ASSERT_TRUE(DECIMAL('.')); // '.' is a decimal character
  691. TEST_ASSERT_FALSE(DECIMAL('0' - 1)); // Edge case: '/' is just before '0' in ASCII
  692. TEST_ASSERT_FALSE(DECIMAL('9' + 1)); // Edge case: ':' is just after '9' in ASCII
  693. TEST_ASSERT_FALSE(DECIMAL('-')); // '-' is not a decimal character, but can appear in numbers
  694. TEST_ASSERT_FALSE(DECIMAL('+')); // '+' is not a decimal character, but can appear in numbers
  695. TEST_ASSERT_FALSE(DECIMAL('e')); // 'e' is not a decimal character, but can appear in scientific notation
  696. }
  697. MARLIN_TEST(macros_value_functions, HEXCHR) {
  698. // Test HEXCHR macro
  699. TEST_ASSERT_EQUAL(0, HEXCHR('0')); // Edge case: '0' is the lowest numeric character
  700. TEST_ASSERT_EQUAL(9, HEXCHR('9')); // Edge case: '9' is the highest numeric character
  701. TEST_ASSERT_EQUAL(10, HEXCHR('a')); // 'a' is a hex character with value 10
  702. TEST_ASSERT_EQUAL(10, HEXCHR('A')); // 'A' is a hex character with value 10
  703. TEST_ASSERT_EQUAL(15, HEXCHR('f')); // Edge case: 'f' is the highest lowercase hex character
  704. TEST_ASSERT_EQUAL(15, HEXCHR('F')); // Edge case: 'F' is the highest uppercase hex character
  705. TEST_ASSERT_EQUAL(-1, HEXCHR('g')); // 'g' is not a hex character
  706. }
  707. MARLIN_TEST(macros_value_functions, NUMERIC_SIGNED) {
  708. // Test NUMERIC_SIGNED macro
  709. TEST_ASSERT_TRUE(NUMERIC_SIGNED('0')); // Edge case: '0' is the lowest numeric character
  710. TEST_ASSERT_TRUE(NUMERIC_SIGNED('5')); // '5' is a numeric character
  711. TEST_ASSERT_TRUE(NUMERIC_SIGNED('9')); // Edge case: '9' is the highest numeric character
  712. TEST_ASSERT_TRUE(NUMERIC_SIGNED('-')); // '-' is not a numeric character, but can appear in signed numbers
  713. TEST_ASSERT_TRUE(NUMERIC_SIGNED('+')); // '+' is not a numeric character, but can appear in signed numbers
  714. TEST_ASSERT_FALSE(NUMERIC_SIGNED('.')); // '.' is not a numeric character
  715. TEST_ASSERT_FALSE(NUMERIC_SIGNED('0' - 1)); // Edge case: '/' is just before '0' in ASCII
  716. TEST_ASSERT_FALSE(NUMERIC_SIGNED('9' + 1)); // Edge case: ':' is just after '9' in ASCII
  717. TEST_ASSERT_FALSE(NUMERIC_SIGNED('e')); // 'e' is not a numeric character, but can appear in scientific notation
  718. }
  719. MARLIN_TEST(macros_value_functions, DECIMAL_SIGNED) {
  720. // Test DECIMAL_SIGNED macro
  721. TEST_ASSERT_TRUE(DECIMAL_SIGNED('0')); // Edge case: '0' is the lowest numeric character
  722. TEST_ASSERT_TRUE(DECIMAL_SIGNED('5')); // '5' is a decimal character
  723. TEST_ASSERT_TRUE(DECIMAL_SIGNED('9')); // Edge case: '9' is the highest numeric character
  724. TEST_ASSERT_TRUE(DECIMAL_SIGNED('-')); // '-' is not a numeric character, but can appear in signed numbers
  725. TEST_ASSERT_TRUE(DECIMAL_SIGNED('+')); // '+' is not a numeric character, but can appear in signed numbers
  726. TEST_ASSERT_TRUE(DECIMAL_SIGNED('.')); // '.' is a decimal character
  727. TEST_ASSERT_FALSE(DECIMAL_SIGNED('0' - 1)); // Edge case: '/' is just before '0' in ASCII
  728. TEST_ASSERT_FALSE(DECIMAL_SIGNED('9' + 1)); // Edge case: ':' is just after '9' in ASCII
  729. TEST_ASSERT_FALSE(DECIMAL_SIGNED('e')); // 'e' is not a decimal character, but can appear in scientific notation
  730. }
  731. MARLIN_TEST(macros_array, COUNT) {
  732. // Test COUNT macro
  733. int array[10];
  734. TEST_ASSERT_EQUAL(10, COUNT(array)); // The array has 10 elements
  735. }
  736. MARLIN_TEST(macros_array, ZERO) {
  737. // Test ZERO macro
  738. int array[5] = {1, 2, 3, 4, 5};
  739. ZERO(array);
  740. for (auto& element : array) {
  741. TEST_ASSERT_EQUAL(0, element);
  742. }
  743. }
  744. MARLIN_TEST(macros_array, COPY) {
  745. int array1[5] = {1, 2, 3, 4, 5};
  746. int array2[5] = {0};
  747. COPY(array2, array1);
  748. for (const auto& element : array1) {
  749. TEST_ASSERT_EQUAL(element, array2[&element - &array1[0]]); // All elements should be equal
  750. }
  751. }
  752. MARLIN_TEST(macros_expansion, CODE_N) {
  753. int a = 0;
  754. CODE_N(0, a+=1, a+=2, a+=3, a+=4, a+=5, a+=6, a+=7, a+=8, a+=9, a+=10, a+=11, a+=12, a+=13, a+=14, a+=15, a+=16);
  755. TEST_ASSERT_EQUAL(0, a);
  756. a = 0;
  757. CODE_N(1, a+=1, a+=2, a+=3, a+=4, a+=5, a+=6, a+=7, a+=8, a+=9, a+=10, a+=11, a+=12, a+=13, a+=14, a+=15, a+=16);
  758. TEST_ASSERT_EQUAL(1, a);
  759. a = 0;
  760. CODE_N(2, a+=1, a+=2, a+=3, a+=4, a+=5, a+=6, a+=7, a+=8, a+=9, a+=10, a+=11, a+=12, a+=13, a+=14, a+=15, a+=16);
  761. TEST_ASSERT_EQUAL(3, a);
  762. a = 0;
  763. CODE_N(16, a+=1, a+=2, a+=3, a+=4, a+=5, a+=6, a+=7, a+=8, a+=9, a+=10, a+=11, a+=12, a+=13, a+=14, a+=15, a+=16);
  764. TEST_ASSERT_EQUAL(136, a);
  765. // 16 is the highest number supported by the CODE_N macro
  766. }
  767. MARLIN_TEST(macros_expansion, GANG_N) {
  768. TEST_ASSERT_EQUAL(0, 0 GANG_N(0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16));
  769. TEST_ASSERT_EQUAL(1, 0 GANG_N(1, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16));
  770. TEST_ASSERT_EQUAL(3, 0 GANG_N(2, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16));
  771. TEST_ASSERT_EQUAL(136, 0 GANG_N(16, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16));
  772. // 16 is the highest number supported by the GANG_N macro
  773. }
  774. MARLIN_TEST(macros_expansion, GANG_N_1) {
  775. // Count by twos to be sure it can't bass by returning N
  776. TEST_ASSERT_EQUAL(0, 0 GANG_N_1(0, +2));
  777. TEST_ASSERT_EQUAL(2, 0 GANG_N_1(1, +2));
  778. TEST_ASSERT_EQUAL(4, 0 GANG_N_1(2, +2));
  779. TEST_ASSERT_EQUAL(32, 0 GANG_N_1(16, +2));
  780. }
  781. MARLIN_TEST(macros_expansion, LIST_N) {
  782. std::vector<int> expected, result;
  783. int compare_size;
  784. expected = {};
  785. result = {LIST_N(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)};
  786. TEST_ASSERT_EQUAL(expected.size(), result.size());
  787. compare_size = _MIN(expected.size(), result.size());
  788. for (int i = 0; i < compare_size; i++) {
  789. TEST_ASSERT_EQUAL(expected[i], result[i]);
  790. }
  791. expected = {1};
  792. result = {LIST_N(1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)};
  793. TEST_ASSERT_EQUAL(expected.size(), result.size());
  794. compare_size = _MIN(expected.size(), result.size());
  795. for (int i = 0; i < compare_size; i++) {
  796. TEST_ASSERT_EQUAL(expected[i], result[i]);
  797. }
  798. expected = {1, 2};
  799. result = {LIST_N(2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)};
  800. TEST_ASSERT_EQUAL(expected.size(), result.size());
  801. compare_size = _MIN(expected.size(), result.size());
  802. for (int i = 0; i < compare_size; i++) {
  803. TEST_ASSERT_EQUAL(expected[i], result[i]);
  804. }
  805. expected = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
  806. result = {LIST_N(16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)};
  807. TEST_ASSERT_EQUAL(expected.size(), result.size());
  808. compare_size = _MIN(expected.size(), result.size());
  809. for (int i = 0; i < compare_size; i++) {
  810. TEST_ASSERT_EQUAL(expected[i], result[i]);
  811. }
  812. }
  813. MARLIN_TEST(macros_expansion, LIST_N_1) {
  814. std::vector<int> expected, result;
  815. int compare_size;
  816. expected = {};
  817. result = {LIST_N_1(0, 1)};
  818. TEST_ASSERT_EQUAL(expected.size(), result.size());
  819. compare_size = _MIN(expected.size(), result.size());
  820. for (int i = 0; i < compare_size; i++) {
  821. TEST_ASSERT_EQUAL(expected[i], result[i]);
  822. }
  823. expected = {2};
  824. result = {LIST_N_1(1, 2)};
  825. TEST_ASSERT_EQUAL(expected.size(), result.size());
  826. compare_size = _MIN(expected.size(), result.size());
  827. for (int i = 0; i < compare_size; i++) {
  828. TEST_ASSERT_EQUAL(expected[i], result[i]);
  829. }
  830. expected = {1, 1};
  831. result = {LIST_N_1(2, 1)};
  832. TEST_ASSERT_EQUAL(expected.size(), result.size());
  833. compare_size = _MIN(expected.size(), result.size());
  834. for (int i = 0; i < compare_size; i++) {
  835. TEST_ASSERT_EQUAL(expected[i], result[i]);
  836. }
  837. expected = std::vector<int>(16, 1);
  838. result = {LIST_N_1(16, 1)};
  839. TEST_ASSERT_EQUAL(expected.size(), result.size());
  840. compare_size = _MIN(expected.size(), result.size());
  841. for (int i = 0; i < compare_size; i++) {
  842. TEST_ASSERT_EQUAL(expected[i], result[i]);
  843. }
  844. }
  845. MARLIN_TEST(macros_expansion, ARRAY_N) {
  846. // Test ARRAY_N macro
  847. std::array<int, 5> expected = {1, 2, 3, 4, 5};
  848. std::array<int, 5> result = ARRAY_N(5, 1, 2, 3, 4, 5);
  849. TEST_ASSERT_EQUAL(expected.size(), result.size());
  850. std::array<int, 3> expected2 = {1, 2, 3};
  851. std::array<int, 3> result2 = ARRAY_N(3, 1, 2, 3);
  852. TEST_ASSERT_EQUAL(expected2.size(), result2.size());
  853. }
  854. MARLIN_TEST(macros_expansion, ARRAY_N_1) {
  855. // Test ARRAY_N_1 macro
  856. std::array<int, 5> expected = {2, 2, 2, 2, 2};
  857. std::array<int, 5> result = ARRAY_N_1(5, 2);
  858. TEST_ASSERT_EQUAL(expected.size(), result.size());
  859. std::array<int, 3> expected2 = {1, 1, 1};
  860. std::array<int, 3> result2 = ARRAY_N_1(3, 1);
  861. TEST_ASSERT_EQUAL(expected2.size(), result2.size());
  862. }
  863. MARLIN_TEST(macros_math, CEILING) {
  864. TEST_ASSERT_EQUAL(2, CEILING(3, 2));
  865. TEST_ASSERT_EQUAL(5, CEILING(10, 2));
  866. TEST_ASSERT_EQUAL(0, CEILING(0, 2));
  867. }
  868. MARLIN_TEST(macros_math, ABS) {
  869. TEST_ASSERT_EQUAL(5, ABS(-5));
  870. TEST_ASSERT_EQUAL(5, ABS(5));
  871. TEST_ASSERT_EQUAL_FLOAT(5.5, ABS(-5.5));
  872. TEST_ASSERT_EQUAL_FLOAT(5.5, ABS(5.5));
  873. }
  874. MARLIN_TEST(macros_float, UNEAR_ZERO) {
  875. TEST_ASSERT_TRUE(UNEAR_ZERO(0.0000009f));
  876. TEST_ASSERT_FALSE(UNEAR_ZERO(0.000001f));
  877. }
  878. MARLIN_TEST(macros_float, NEAR_ZERO) {
  879. TEST_ASSERT_TRUE(NEAR_ZERO(0.0000001f));
  880. TEST_ASSERT_TRUE(NEAR_ZERO(-0.0000001f));
  881. TEST_ASSERT_FALSE(NEAR_ZERO(0.0000011f));
  882. TEST_ASSERT_FALSE(NEAR_ZERO(-0.0000011f));
  883. }
  884. MARLIN_TEST(macros_float, NEAR) {
  885. TEST_ASSERT_TRUE(NEAR(0.000001f, 0.000002f));
  886. TEST_ASSERT_FALSE(NEAR(0.0000009f, 0.000002f));
  887. }
  888. MARLIN_TEST(macros_float, RECIPROCAL) {
  889. TEST_ASSERT_EQUAL_FLOAT(1.0f, RECIPROCAL(1.0f));
  890. TEST_ASSERT_EQUAL_FLOAT(0.0f, RECIPROCAL(0.0f));
  891. TEST_ASSERT_EQUAL_FLOAT(2.0f, RECIPROCAL(0.5f));
  892. TEST_ASSERT_EQUAL_FLOAT(-2.0f, RECIPROCAL(-0.5f));
  893. TEST_ASSERT_EQUAL_FLOAT(0.0f, RECIPROCAL(0.0000001f));
  894. TEST_ASSERT_EQUAL_FLOAT(0.0f, RECIPROCAL(-0.0000001f));
  895. }
  896. MARLIN_TEST(macros_float, FIXFLOAT) {
  897. TEST_ASSERT_EQUAL(0.0000005f, FIXFLOAT(0.0f));
  898. TEST_ASSERT_EQUAL(-0.0000005f, FIXFLOAT(-0.0f));
  899. }
  900. MARLIN_TEST(macros_math, MATH_MACROS) {
  901. // Sanity check of macros typically mapped to compiler functions
  902. TEST_ASSERT_EQUAL_FLOAT(0.0f, ACOS(1.0f));
  903. TEST_ASSERT_EQUAL_FLOAT(0.785398f, ATAN2(1.0f, 1.0f));
  904. TEST_ASSERT_EQUAL_FLOAT(8.0f, POW(2.0f, 3.0f));
  905. TEST_ASSERT_EQUAL_FLOAT(2.0f, SQRT(4.0f));
  906. TEST_ASSERT_EQUAL_FLOAT(0.5f, RSQRT(4.0f));
  907. TEST_ASSERT_EQUAL_FLOAT(2.0f, CEIL(1.5f));
  908. TEST_ASSERT_EQUAL_FLOAT(1.0f, FLOOR(1.5f));
  909. TEST_ASSERT_EQUAL_FLOAT(1.0f, TRUNC(1.5f));
  910. TEST_ASSERT_EQUAL(2, LROUND(1.5f));
  911. TEST_ASSERT_EQUAL_FLOAT(1.0f, FMOD(5.0f, 2.0f));
  912. TEST_ASSERT_EQUAL_FLOAT(5.0f, HYPOT(3.0f, 4.0f));
  913. }
  914. MARLIN_TEST(macros_math, MIN_MAX) {
  915. // _MIN tests
  916. TEST_ASSERT_EQUAL(-1, _MIN(-1, 0));
  917. TEST_ASSERT_EQUAL(-1, _MIN(0, -1));
  918. TEST_ASSERT_EQUAL(-1, _MIN(-1, 1));
  919. TEST_ASSERT_EQUAL(-1, _MIN(1, -1));
  920. TEST_ASSERT_EQUAL(-1, _MIN(-1, -1));
  921. TEST_ASSERT_EQUAL(1, _MIN(1, 1));
  922. TEST_ASSERT_EQUAL_FLOAT(-1.5f, _MIN(-1.5f, 0.5f));
  923. TEST_ASSERT_EQUAL_FLOAT(-1.5f, _MIN(0.5f, -1.5f));
  924. // _MAX tests
  925. TEST_ASSERT_EQUAL(0, _MAX(-1, 0));
  926. TEST_ASSERT_EQUAL(0, _MAX(0, -1));
  927. TEST_ASSERT_EQUAL(1, _MAX(-1, 1));
  928. TEST_ASSERT_EQUAL(1, _MAX(1, -1));
  929. TEST_ASSERT_EQUAL(-1, _MAX(-1, -1));
  930. TEST_ASSERT_EQUAL(1, _MAX(1, 1));
  931. TEST_ASSERT_EQUAL_FLOAT(0.5f, _MAX(-1.5f, 0.5f));
  932. TEST_ASSERT_EQUAL_FLOAT(0.5f, _MAX(0.5f, -1.5f));
  933. }
  934. MARLIN_TEST(macros_math, INCREMENT) {
  935. TEST_ASSERT_EQUAL(1, INCREMENT(0));
  936. TEST_ASSERT_EQUAL(21, INCREMENT(20));
  937. // 20 is the highest number supported by the INCREMENT macro
  938. }
  939. MARLIN_TEST(macros_math, ADD) {
  940. // Test smallest add
  941. TEST_ASSERT_EQUAL(0, ADD0(0));
  942. TEST_ASSERT_EQUAL(10, ADD0(10));
  943. // Test largest add
  944. TEST_ASSERT_EQUAL(10, ADD10(0));
  945. TEST_ASSERT_EQUAL(20, ADD10(10));
  946. }
  947. MARLIN_TEST(macros_math, SUM) {
  948. // Test smallest sum
  949. TEST_ASSERT_EQUAL(3, SUM(0, 3));
  950. TEST_ASSERT_EQUAL(7, SUM(3, 4));
  951. // Test largest sum
  952. TEST_ASSERT_EQUAL(15, SUM(10, 5));
  953. TEST_ASSERT_EQUAL(19, SUM(9, 10));
  954. }
  955. MARLIN_TEST(macros_math, DOUBLE) {
  956. // Test double
  957. TEST_ASSERT_EQUAL(0, DOUBLE(0));
  958. TEST_ASSERT_EQUAL(2, DOUBLE(1));
  959. TEST_ASSERT_EQUAL(4, DOUBLE(2));
  960. TEST_ASSERT_EQUAL(20, DOUBLE(10));
  961. }
  962. MARLIN_TEST(macros_math, DECREMENT) {
  963. TEST_ASSERT_EQUAL(0, DECREMENT(1));
  964. TEST_ASSERT_EQUAL(14, DECREMENT(15));
  965. }
  966. MARLIN_TEST(macros_math, SUB) {
  967. // Test smallest subtraction
  968. TEST_ASSERT_EQUAL(0, SUB0(0));
  969. TEST_ASSERT_EQUAL(10, SUB0(10));
  970. // Test subtracting 1
  971. TEST_ASSERT_EQUAL(0, SUB1(1));
  972. TEST_ASSERT_EQUAL(5, SUB1(6));
  973. // Test largest subtraction
  974. TEST_ASSERT_EQUAL(0, SUB10(10));
  975. TEST_ASSERT_EQUAL(5, SUB10(15));
  976. }
  977. // Define a helper macro for testing
  978. #define TEST_OP(i) ++counter;
  979. #define TEST_OP2(i, j) counter += j;
  980. MARLIN_TEST(macros_repeat, REPEAT) {
  981. int counter = 0;
  982. REPEAT(5, TEST_OP);
  983. TEST_ASSERT_EQUAL(5, counter);
  984. }
  985. MARLIN_TEST(macros_repeat, REPEAT_1) {
  986. int counter = 0;
  987. REPEAT_1(5, TEST_OP);
  988. TEST_ASSERT_EQUAL(5, counter);
  989. }
  990. MARLIN_TEST(macros_repeat, REPEAT2) {
  991. int counter = 0;
  992. REPEAT2(5, TEST_OP2, 1);
  993. TEST_ASSERT_EQUAL(5, counter);
  994. }
  995. MARLIN_TEST(macros_repeat, RREPEAT) {
  996. int counter = 0;
  997. RREPEAT(5, TEST_OP);
  998. TEST_ASSERT_EQUAL(5, counter);
  999. }
  1000. MARLIN_TEST(macros_repeat, RREPEAT_1) {
  1001. int counter = 0;
  1002. RREPEAT_1(5, TEST_OP);
  1003. TEST_ASSERT_EQUAL(5, counter);
  1004. }
  1005. MARLIN_TEST(macros_repeat, RREPEAT2) {
  1006. int counter = 0;
  1007. RREPEAT2(5, TEST_OP2, 1);
  1008. TEST_ASSERT_EQUAL(5, counter);
  1009. }