選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

rspamd_assertions.lua 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. local logger = require "rspamd_logger"
  2. local telescope = require "telescope"
  3. local util = require 'lua_util'
  4. local function rspamd_assert_equals(tbl)
  5. return tbl.expect == tbl.actual
  6. end
  7. local function rspamd_assert_equals_msg(_, tbl)
  8. return logger.slog(
  9. "Failed asserting that \n (actual) : %1 \n equals to\n (expected) : %2",
  10. tbl.actual, tbl.expect
  11. )
  12. end
  13. local function rspamd_assert_table_equals(tbl)
  14. return util.table_cmp(tbl.expect, tbl.actual)
  15. end
  16. local function rspamd_assert_table_equals_sorted(tbl)
  17. local expect = util.deepcopy(tbl.expect)
  18. local actual = util.deepcopy(tbl.actual)
  19. util.deepsort(expect)
  20. util.deepsort(actual)
  21. return util.table_cmp(expect, actual)
  22. end
  23. local function table_keys_sorted(t)
  24. local keys = {}
  25. for k,_ in pairs(t) do
  26. table.insert(keys, k)
  27. end
  28. table.sort(keys)
  29. return keys;
  30. end
  31. local function format_line(level, key, v_expect, v_actual)
  32. local prefix
  33. if v_expect == v_actual then
  34. prefix = string.rep(' ', level * 2 + 1)
  35. return string.format("%s[%s] = %s", prefix, tostring(key), tostring(v_expect))
  36. else
  37. prefix = string.rep(' ', level * 2)
  38. local ret = {}
  39. if v_expect then
  40. ret[#ret + 1] = string.format("-%s[%s] = %s: %s", prefix, tostring(key), type(v_expect), tostring(v_expect))
  41. end
  42. if v_actual then
  43. ret[#ret + 1] = string.format("+%s[%s] = %s: %s", prefix, tostring(key), type(v_actual), tostring(v_actual))
  44. end
  45. return table.concat(ret, "\n")
  46. end
  47. end
  48. local function format_table_begin(level, key)
  49. local prefix = string.rep(' ', level * 2 + 1)
  50. return string.format("%s[%s] = {", prefix, tostring(key))
  51. end
  52. local function format_table_end(level)
  53. local prefix = string.rep(' ', level * 2 + 1)
  54. return string.format("%s}", prefix)
  55. end
  56. local function rspamd_assert_table_diff_msg(_, tbl)
  57. local avoid_loops = {}
  58. local msg = rspamd_assert_equals_msg(_, tbl)
  59. local diff = {}
  60. local function recurse(expect, actual, level)
  61. if avoid_loops[actual] then
  62. return
  63. end
  64. avoid_loops[actual] = true
  65. local keys_expect = table_keys_sorted(expect)
  66. local keys_actual = table_keys_sorted(actual)
  67. local i_k_expect, i_v_expect = next(keys_expect)
  68. local i_k_actual, i_v_actual = next(keys_actual)
  69. while i_k_expect and i_k_actual do
  70. local v_expect = expect[i_v_expect]
  71. local v_actual = actual[i_v_actual]
  72. if i_v_expect == i_v_actual then
  73. -- table keys are the same: compare values
  74. if type(v_expect) == 'table' and type(v_actual) == 'table' then
  75. if util.table_cmp(v_expect, v_actual) then
  76. -- we use the same value for 'actual' and 'expect' as soon as they're equal and don't bother us
  77. diff[#diff + 1] = format_line(level, i_v_expect, v_expect, v_expect)
  78. else
  79. diff[#diff + 1] = format_table_begin(level, i_v_expect)
  80. recurse(v_expect, v_actual, level + 1)
  81. diff[#diff + 1] = format_table_end(level)
  82. end
  83. else
  84. diff[#diff + 1] = format_line(level, i_v_expect, v_expect, v_actual)
  85. end
  86. i_k_expect, i_v_expect = next(keys_expect, i_k_expect)
  87. i_k_actual, i_v_actual = next(keys_actual, i_k_actual)
  88. elseif tostring(v_actual) > tostring(v_expect) then
  89. diff[#diff + 1] = format_line(level, i_v_expect, v_expect, nil)
  90. i_k_expect, i_v_expect = next(keys_expect, i_k_expect)
  91. else
  92. diff[#diff + 1] = format_line(level, i_v_actual, nil, v_actual)
  93. i_k_actual, i_v_actual = next(keys_actual, i_k_actual)
  94. end
  95. end
  96. while i_k_expect do
  97. local v_expect = expect[i_v_expect]
  98. diff[#diff + 1] = format_line(level, i_v_expect, v_expect, nil)
  99. i_k_expect, i_v_expect = next(keys_expect, i_k_expect)
  100. end
  101. while i_k_actual do
  102. local v_actual = actual[i_v_actual]
  103. diff[#diff + 1] = format_line(level, i_v_actual, nil, v_actual)
  104. i_k_actual, i_v_actual = next(keys_actual, i_k_actual)
  105. end
  106. end
  107. recurse(tbl.expect, tbl.actual, 0)
  108. return string.format("%s\n===== diff (-expect, +actual) ======\n%s", msg, table.concat(diff, "\n"))
  109. end
  110. telescope.make_assertion("rspamd_eq", rspamd_assert_equals_msg, rspamd_assert_equals)
  111. -- telescope.make_assertion("rspamd_table_eq", rspamd_assert_equals_msg, rspamd_assert_table_equals)
  112. telescope.make_assertion("rspamd_table_eq", rspamd_assert_table_diff_msg, rspamd_assert_table_equals)
  113. telescope.make_assertion("rspamd_table_eq_sorted", rspamd_assert_table_diff_msg,
  114. rspamd_assert_table_equals_sorted)