test_expr.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2010, Digium, Inc.
  5. *
  6. * Tilghman Lesher <tlesher AT digium DOT com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief Expression Tests
  21. *
  22. * \author\verbatim Tilghman Lesher <tlesher AT digium DOT com> \endverbatim
  23. *
  24. * Verify that the expression parser works as intended.
  25. * \ingroup tests
  26. */
  27. /*** MODULEINFO
  28. <depend>TEST_FRAMEWORK</depend>
  29. <support_level>core</support_level>
  30. ***/
  31. #include "asterisk.h"
  32. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  33. #include "asterisk/utils.h"
  34. #include "asterisk/module.h"
  35. #include "asterisk/test.h"
  36. #include "asterisk/ast_expr.h"
  37. AST_TEST_DEFINE(expr_test)
  38. {
  39. int res = AST_TEST_PASS, i, len;
  40. struct {
  41. char *input;
  42. const char *output;
  43. } tests[] = {
  44. { "2 + 2", "4" },
  45. { " 2 + 2 ", "4" },
  46. { "", "" },
  47. { "2 - 4", "-2" },
  48. { "4 - 2", "2" },
  49. { "-4 - -2", "-2" },
  50. { "4 + 2 * 8", "20" },
  51. { "(4 + 2) * 8", "48" },
  52. { "4 + (2 * 8)", "20" },
  53. { "4 + (2 * 8) ? 3 :: 6", "3" },
  54. { "4 + 8 / 2", "8" },
  55. { "FLOOR(4 + 8 / 3)", "6" }, /* Floating point op on 1.6 and higher, need FLOOR() to keep result sane */
  56. { "(4+8) / 3", "4" },
  57. { "4 + 8 % 3", "6" },
  58. { "4 + 9 % 3", "4" },
  59. { "(4+9) %3", "1" },
  60. { "(4+8) %3", "0" },
  61. { "(4+9) %3", "1" },
  62. { "(4+8) %3", "0" },
  63. { "(4+9) % 3", "1" },
  64. { "(4+8) % 3", "0" },
  65. { "(4+9) % 3", "1" },
  66. { "(4+8) % 3", "0" },
  67. { "(4+9)% 3", "1" },
  68. { "(4+8)% 3", "0" },
  69. { "(4+9)% 3", "1" },
  70. { "(4+8)% 3", "0" },
  71. { "4 & 4", "4" },
  72. { "0 & 4", "0" },
  73. { "0 & 0", "0" },
  74. { "2 | 0", "2" },
  75. { "2 | 4", "2" },
  76. { "0 | 0", "0" },
  77. { "!0 | 0", "1" },
  78. { "!4 | 0", "0" },
  79. { "4 | !0", "4" },
  80. { "!4 | !0", "1" },
  81. { "0", "0" },
  82. { "!0", "1" },
  83. { "00", "00" },
  84. { "!00", "1" },
  85. { "1", "1" },
  86. { "!1", "0" },
  87. { "01", "01" },
  88. { "!01", "0" },
  89. { "3 < 4", "1" },
  90. { "4 < 3", "0" },
  91. { "3 > 4", "0" },
  92. { "4 > 3", "1" },
  93. { "3 = 3", "1" },
  94. { "3 = 4", "0" },
  95. { "3 != 3", "0" },
  96. { "3 != 4", "1" },
  97. { "3 >= 4", "0" },
  98. { "3 >= 3", "1" },
  99. { "4 >= 3", "1" },
  100. { "3 <= 4", "1" },
  101. { "4 <= 3", "0" },
  102. { "4 <= 4", "1" },
  103. { "3 > 4 & 4 < 3", "0" },
  104. { "4 > 3 & 3 < 4", "1" },
  105. { "x = x", "1" },
  106. { "y = x", "0" },
  107. { "x != y", "1" },
  108. { "x != x", "0" },
  109. { "\"Something interesting\" =~ interesting", "11" },
  110. { "\"Something interesting\" =~ Something", "9" },
  111. { "\"Something interesting\" : Something", "9" },
  112. { "\"Something interesting\" : interesting", "0" },
  113. { "\"Something interesting\" =~ \"interesting\"", "11" },
  114. { "\"Something interesting\" =~ \"Something\"", "9" },
  115. { "\"Something interesting\" : \"Something\"", "9" },
  116. { "\"Something interesting\" : \"interesting\"", "0" },
  117. { "\"Something interesting\" =~ (interesting)", "11" },
  118. { "\"Something interesting\" =~ (Something)", "9" },
  119. { "\"Something interesting\" : (Something)", "9" },
  120. { "\"Something interesting\" : (interesting)", "0" },
  121. { "\"Something interesting\" =~ \"\\(interesting\\)\"", "0" },
  122. { "\"Something interesting\" =~ \"\\(Something\\)\"", "0" },
  123. { "\"Something interesting\" : \"\\(Something\\)\"", "0" },
  124. { "\"Something interesting\" : \"\\(interesting\\)\"", "0" },
  125. { "\"011043567857575\" : \"011\\(..\\)\"", "0" },
  126. { "\"9011043567857575\" : \"011\\(..\\)\"", "0" },
  127. { "\"011043567857575\" =~ \"011\\(..\\)\"", "0" },
  128. { "\"9011043567857575\" =~ \"011\\(..\\)\"", "0" },
  129. { "\"Something interesting\" =~ (interesting)", "11" },
  130. { "\"Something interesting\" =~ (Something)", "9" },
  131. { "\"Something interesting\" : (Something)", "9" },
  132. { "\"Something interesting\" : (interesting)", "0" },
  133. { "\"Something interesting\" =~ \"(interesting)\"", "interesting" },
  134. { "\"Something interesting\" =~ \"(Something)\"", "Something" },
  135. { "\"Something interesting\" : \"(Something)\"", "Something" },
  136. { "\"Something interesting\" : \"(interesting)\"", "" },
  137. { "\"011043567857575\" : \"011(..)\"", "04" },
  138. { "\"9011043567857575\" : \"011(..)\"", "" },
  139. { "\"011043567857575\" =~ \"011(..)\"", "04" },
  140. { "\"9011043567857575\" =~ \"011(..)\"", "04" },
  141. { "3", "3" },
  142. { "something", "something" },
  143. { "043", "043" },
  144. { "${GLOBAL(ULKOPREFIX)}9${x}", "${GLOBAL(ULKOPREFIX)}9${x}" },
  145. { "512059${x}", "512059${x}" },
  146. };
  147. char buf[32];
  148. switch (cmd) {
  149. case TEST_INIT:
  150. info->name = "expr_test";
  151. info->category = "/main/ast_expr/";
  152. info->summary = "unit test for the internal expression engine";
  153. info->description =
  154. "Verifies behavior for the internal expression engine";
  155. return AST_TEST_NOT_RUN;
  156. case TEST_EXECUTE:
  157. break;
  158. }
  159. for (i = 0; i < ARRAY_LEN(tests); i++) {
  160. memset(buf, 0, sizeof(buf));
  161. len = ast_expr(tests[i].input, buf, sizeof(buf), NULL);
  162. buf[len] = '\0';
  163. if (strcmp(buf, tests[i].output)) {
  164. ast_test_status_update(test, "Case %d: expression '%s' evaluated as '%s', but should have evaluated as '%s'\n", i + 1, tests[i].input, buf, tests[i].output);
  165. res = AST_TEST_FAIL;
  166. }
  167. }
  168. return res;
  169. }
  170. static int unload_module(void)
  171. {
  172. AST_TEST_UNREGISTER(expr_test);
  173. return 0;
  174. }
  175. static int load_module(void)
  176. {
  177. AST_TEST_REGISTER(expr_test);
  178. return AST_MODULE_LOAD_SUCCESS;
  179. }
  180. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Expression evaluation tests");