Skip to content

Conversation

@mandesero
Copy link
Contributor

@mandesero mandesero commented Nov 25, 2025

This patch adds unified diff output for t.assert_equals() failures when the test suite is run with the --diff option, using a vendored Lua implementation of google/diff-match-patch (luatest/vendor/diff_match_patch.lua taken from 1).

Closes #412


Here is the output for the example from the issue:

code
local t = require('luatest')

local g = t.group()

g.test_table_assertion = function()
    local a = {
      a = {
        ["a"] = 1,
        ["b"] = 2,
        ["c"] = 3,
      },
    }

    local b = {
      a = {
        ["a"] = 1,
        ["b"] = 5,
        ["c"] = 8,
      },
    }
    t.assert_equals(a, b, 'compare tables')
end

g.test_string_assertion = function()
    local a = [[
aaaaa
bbbbb
ccccc
]]
    local b = [[
aaaaa
ddddd
ccccc
]]

    t.assert_equals(a, b, 'compare multiline strings')
end

g.test_msgpack_assertion = function()
    local msgpack = require('msgpack')
    local a = {1, 2, 3}
    local b = {1, 4, 3}

    t.assert_equals(msgpack.encode(a), msgpack.encode(b), 'compare encoded msgpack')
end
Failed tests:
-------------

1) tmp.test_table_assertion
/home/ubuntu/luatest/test/tmp_test.lua:21: compare tables
expected: {a = {a = 1, b = 5, c = 8}}
actual: {a = {a = 1, b = 2, c = 3}}
diff:
@@ -1,32 +1,32 @@
 ---
 a:
-  b: 5
  a: 1
  c: 8
+  b: 2
  a: 1
  c: 3
 ...

2) tmp.test_string_assertion
/home/ubuntu/luatest/test/tmp_test.lua:36: compare multiline strings
expected:
"aaaaa\
ddddd\
ccccc\
"
actual:
"aaaaa\
bbbbb\
ccccc\
"
diff:
@@ -1,34 +1,34 @@
 --- |
  aaaaa
-  ddddd
+  bbbbb
   ccccc
 ...

3) tmp.test_msgpack_assertion
/home/ubuntu/luatest/test/tmp_test.lua:44: compare encoded msgpack
expected: "�\1\4\3"
actual: "�\1\2\3"
diff:
@@ -1,20 +1,20 @@
 ---
- 1
-- 4
+- 2
 - 3
 ...

Footnotes

  1. https://github.com/google/diff-match-patch/blob/master/lua/diff_match_patch.lua

Copy link
Member

@ligurio ligurio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Max, thanks for the patch!
Please take a look on my comments.

CHANGELOG.md Outdated
Comment on lines 5 to 6
- Added support for unified diff output in `t.assert_equals()` failure messages.
The diff is shown only when the test suite is run with the `--diff` option (gh-412).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This functionality does no break anything, I would enable it by default and remove the option at all. The most popular case (IMHO) is using luatest via build system (CMake/Makefile) and with the option disabled by default one should need to explicitly enable it in a build system.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW we can use unified diff only for values that can be serialized to YAML.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would enable it by default and remove the option at all.

Okay, done.

luatest/diff.lua Outdated
Comment on lines 48 to 52
local function url_unescape(s)
return s:gsub("%%(%x%x)", function(h)
return string.char(tonumber(h, 16))
end)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no, do not invent your own unescape function for URI.
Just use uri.unescape(), 1.

Footnotes

  1. https://www.tarantool.io/en/doc/latest/reference/reference_lua/uri/#lua-function.uri.unescape

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines 357 to 358
local actual_tbl = {a = {a = 1, b = 2, c = 3}}
local expected_tbl = {a = {a = 1, b = 5, c = 8}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These cases are trivial. Tables with userdata (use newproxy() to create a sample), cdata and custom Tarantool types (like decimal/varbinary) 1 are more interesting.

Footnotes

  1. https://www.tarantool.io/en/doc/latest/reference/internals/msgpack_extensions/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added support for custom types: decimal, datetime, uuid, and varbinary. Please check the latest changes.

end)
end

local function prettify_patch(patch_text)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function deserves a comment with high-level description a function purposes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

local ok, encoded = pcall(yaml.encode, value)
if ok then
return encoded
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it is not serializable to YAML then ...?

This patch adds unified diff output for `t.assert_equals()` failures when
the test suite is run with the `--diff` option, using a vendored Lua
implementation of google/diff-match-patch (`luatest/vendor/diff_match_patch.lua`
taken from [^1]).

Closes tarantool#412

[^1]: https://github.com/google/diff-match-patch/blob/master/lua/diff_match_patch.lua
Comment on lines +31 to +33
function M.private.set_diff_enabled(value)
diff_enabled = value and true or false
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sseems this function is not needed anymore, right?
As I get right, diff_enabled logic in the test was needed when option for diff support was present.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use this here to avoid editing old tests

g.before_all(function()
t.private.set_diff_enabled(false)
end)
g.after_all(function()
t.private.set_diff_enabled(true)
end)

@mandesero mandesero requested a review from ligurio December 1, 2025 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Print a diff for compared data

2 participants