您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

257 行
8.7 KiB

  1. #define epsilon 2.2204460492503131E-16
  2. #define testresult int
  3. #define pass 1
  4. #define fail 0
  5. #define print_assert_equal_fail(variable, value, type, format) \
  6. printf("\n\tAssertion failed for '" #variable "'" \
  7. "\n\t in %s:%d" \
  8. "\n\texpected: " format \
  9. "\n\tgot: " format "\n", \
  10. __FILE__, __LINE__, (type)value, (type)variable)
  11. #define print_assert_not_equal_fail(variable, value, type, format) \
  12. printf("\n\tAssertion failed for '" #variable "'" \
  13. "\n\t in %s:%d" \
  14. "\n\texpected not: " format \
  15. "\n\tgot anyways: " format "\n", \
  16. __FILE__, __LINE__, (type)value, (type)variable)
  17. /* print_assert_not_equal_fail(error, 0, int, "%d"); \ */
  18. #define assert_no_error(error) \
  19. if (error) { \
  20. printf("\n\tExpected no error to occur," \
  21. " but an error occured anyways:\n"); \
  22. log_error(); \
  23. return fail; \
  24. } \
  25. #define assert_equal_int(variable, value) \
  26. if (variable != value) { \
  27. print_assert_equal_fail(variable, value, int, "%d"); \
  28. return fail; \
  29. }
  30. #define assert_not_equal_int(variable, value) \
  31. if (variable == value) { \
  32. print_assert_not_equal_fail(variable, value, int, "%d"); \
  33. return fail; \
  34. }
  35. #define assert_equal_double(variable, value) \
  36. if (fabs((double)variable - (double)value) > epsilon) { \
  37. print_assert_equal_fail(variable, value, double, "%f"); \
  38. return fail; \
  39. }
  40. #define assert_not_equal_double(variable, value) \
  41. if (fabs((double)variable - (double)value) <= epsilon) { \
  42. print_assert_not_equal_fail(variable, value, double, "%f"); \
  43. return fail; \
  44. }
  45. #define assert_null(variable) \
  46. assert_equal_int(variable, NULL)
  47. #define assert_not_null(variable) \
  48. assert_not_equal_int(variable, NULL)
  49. #define invoke_test(name) \
  50. printf("" #name ":"); \
  51. for(int i = 0; i < 45 - strlen(#name); ++i) \
  52. printf(" "); \
  53. if (name() == pass) \
  54. printf("%spassed%s\n", console_green, console_normal); \
  55. else { \
  56. printf("%sfailed%s\n", console_red, console_normal); \
  57. if(error) { \
  58. free(error); \
  59. error = NULL; \
  60. } \
  61. } \
  62. testresult test_built_in_add() {
  63. Ast_Node* plus = create_ast_node_symbol("+");
  64. Ast_Node* ten = create_ast_node_number(10);
  65. Ast_Node* four = create_ast_node_number(4);
  66. Ast_Node* nil = create_ast_node_nil();
  67. Ast_Node* form = create_ast_node_pair(
  68. plus,
  69. create_ast_node_pair(
  70. ten,
  71. create_ast_node_pair(
  72. four,
  73. nil)));
  74. Ast_Node* result = eval_expr(form, new(Environment));
  75. assert_no_error(error);
  76. assert_not_null(result);
  77. assert_equal_int(result->type, Ast_Node_Type_Number);
  78. assert_equal_double(result->value.number->value, 14);
  79. return pass;
  80. }
  81. testresult test_built_in_substract() {
  82. Ast_Node* minus = create_ast_node_symbol("-");
  83. Ast_Node* ten = create_ast_node_number(10);
  84. Ast_Node* four = create_ast_node_number(4);
  85. Ast_Node* nil = create_ast_node_nil();
  86. Ast_Node* form = create_ast_node_pair(
  87. minus,
  88. create_ast_node_pair(
  89. ten,
  90. create_ast_node_pair(
  91. four,
  92. nil)));
  93. Ast_Node* result = eval_expr(form, new(Environment));
  94. assert_no_error(error);
  95. assert_not_null(result);
  96. assert_equal_int(result->type, Ast_Node_Type_Number);
  97. assert_equal_double(result->value.number->value, 6);
  98. return pass;
  99. }
  100. testresult test_built_in_multiply() {
  101. Ast_Node* times = create_ast_node_symbol("*");
  102. Ast_Node* ten = create_ast_node_number(10);
  103. Ast_Node* four = create_ast_node_number(4);
  104. Ast_Node* nil = create_ast_node_nil();
  105. Ast_Node* form = create_ast_node_pair(
  106. times,
  107. create_ast_node_pair(
  108. ten,
  109. create_ast_node_pair(
  110. four,
  111. nil)));
  112. Ast_Node* result = eval_expr(form, new(Environment));
  113. assert_no_error(error);
  114. assert_not_null(result);
  115. assert_equal_int(result->type, Ast_Node_Type_Number);
  116. assert_equal_double(result->value.number->value, 40);
  117. return pass;
  118. }
  119. testresult test_built_in_divide() {
  120. Ast_Node* over = create_ast_node_symbol("/");
  121. Ast_Node* ten = create_ast_node_number(20);
  122. Ast_Node* four = create_ast_node_number(4);
  123. Ast_Node* nil = create_ast_node_nil();
  124. Ast_Node* form = create_ast_node_pair(
  125. over,
  126. create_ast_node_pair(
  127. ten,
  128. create_ast_node_pair(
  129. four,
  130. nil)));
  131. Ast_Node* result = eval_expr(form, new(Environment));
  132. assert_null(error);
  133. assert_not_null(result);
  134. assert_equal_int(result->type, Ast_Node_Type_Number);
  135. assert_equal_double(result->value.number->value, 5);
  136. return pass;
  137. }
  138. testresult test_built_in_if() {
  139. Ast_Node* _if = create_ast_node_symbol("if");
  140. Ast_Node* cond = create_ast_node_number(1);
  141. Ast_Node* four = create_ast_node_number(4);
  142. Ast_Node* five = create_ast_node_number(5);
  143. Ast_Node* nil = create_ast_node_nil();
  144. Ast_Node* form = create_ast_node_pair(
  145. _if,
  146. create_ast_node_pair(
  147. cond,
  148. create_ast_node_pair(
  149. four,
  150. create_ast_node_pair(
  151. five,
  152. nil))));
  153. Ast_Node* result;
  154. // test *then* case
  155. result = eval_expr(form, new(Environment));
  156. assert_no_error(error);
  157. assert_not_null(result);
  158. assert_equal_int(result->type, Ast_Node_Type_Number);
  159. assert_equal_double(result->value.number->value, 4);
  160. // test *else* case
  161. cond->value.number->value = 0;
  162. result = eval_expr(form, new(Environment));
  163. assert_null(error);
  164. assert_not_null(result);
  165. assert_equal_int(result->type, Ast_Node_Type_Number);
  166. assert_equal_double(result->value.number->value, 5);
  167. return pass;
  168. }
  169. testresult test_built_in_and() {
  170. Ast_Node* _and = create_ast_node_symbol("and");
  171. Ast_Node* cond1 = create_ast_node_number(1);
  172. Ast_Node* cond2 = create_ast_node_string("asd");
  173. Ast_Node* cond3 = create_ast_node_number(4);
  174. Ast_Node* nil = create_ast_node_nil();
  175. Ast_Node* form = create_ast_node_pair(
  176. _and,
  177. create_ast_node_pair(
  178. cond1,
  179. create_ast_node_pair(
  180. cond2,
  181. create_ast_node_pair(
  182. cond3,
  183. nil))));
  184. Ast_Node* result;
  185. // a true case
  186. result = eval_expr(form, new(Environment));
  187. assert_no_error(error);
  188. assert_not_null(result);
  189. assert_equal_int(result->type, Ast_Node_Type_Number);
  190. assert_equal_double(result->value.number->value, 1);
  191. // a false case
  192. cond1->value.number->value = 0;
  193. result = eval_expr(form, new(Environment));
  194. assert_no_error(error);
  195. assert_not_null(result);
  196. assert_equal_int(result->type, Ast_Node_Type_Number);
  197. assert_equal_double(result->value.number->value, 0);
  198. return pass;
  199. }
  200. void run_all_tests() {
  201. log_level = Log_Level_None;
  202. invoke_test(test_built_in_add);
  203. invoke_test(test_built_in_substract);
  204. invoke_test(test_built_in_multiply);
  205. invoke_test(test_built_in_divide);
  206. invoke_test(test_built_in_if);
  207. invoke_test(test_built_in_and);
  208. }