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.

@mandesero mandesero force-pushed the gh-412-print-diff branch 2 times, most recently from 1d91b35 to 26138ab Compare November 27, 2025 23:20
@mandesero mandesero requested a review from ligurio November 27, 2025 23:23
@mandesero mandesero requested a review from ligurio December 1, 2025 07:52
@mandesero mandesero force-pushed the gh-412-print-diff branch 3 times, most recently from edcc8eb to 6a22390 Compare December 3, 2025 15:09
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.

LGTM, thanks!

@locker locker assigned mandesero and unassigned locker Dec 10, 2025
@mandesero mandesero requested a review from locker December 11, 2025 10:59
@mandesero mandesero assigned locker and unassigned mandesero Dec 11, 2025
@locker locker removed their assignment Dec 11, 2025
@mandesero
Copy link
Contributor Author

@locker
I implemented a custom line-based diff and pushed it as a separate commit - please take a look and let me know if it’s OK or not.

@mandesero mandesero assigned locker and unassigned mandesero Dec 15, 2025
Copy link
Member

@locker locker left a comment

Choose a reason for hiding this comment

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

@mandesero Thanks for implementing the diff algo. I like it much more than using a third-party module.

@locker locker assigned mandesero and unassigned locker Dec 18, 2025
@mandesero mandesero requested a review from locker December 18, 2025 16:43
@mandesero mandesero assigned locker and unassigned mandesero Dec 18, 2025
@locker locker assigned mandesero and unassigned locker Dec 19, 2025
This patch adds a simple line-by-line diff output for `t.assert_equals()`
and `t.assert_covers()` failures.

Closes tarantool#412
@mandesero mandesero assigned locker and unassigned mandesero Dec 19, 2025
@mandesero mandesero requested a review from locker December 19, 2025 12:02
local actual_text = pp.tostring(actual)
pp.LINE_LENGTH = old

if expected_text == nil or actual_text == nil then
Copy link
Member

Choose a reason for hiding this comment

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

AFAICS pp.tostring never returns nil.


local M = {}

local function diff_by_lines(text1, text2)
Copy link
Member

Choose a reason for hiding this comment

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

I presume you used this wiki page as a reference? It'd be nice to put a link to it somewhere in a comment.

return diffs
end

local function prettify_patch(diffs)
Copy link
Member

Choose a reason for hiding this comment

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

It doesn't look like there's much point in splitting this function in two. I'd simply merge prettify_patch into diff_by_lines.

end
end

if #out == 0 then
Copy link
Member

Choose a reason for hiding this comment

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

How can it be? Why do we need to care, anyways?

return nil
end

if expected_text == actual_text then
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need this check. actual and expected aren't supposed to be the same, but even if they are, we can print the diff without +-.

local diffs = diff_by_lines(expected_text, actual_text)
local patch_text = prettify_patch(diffs)

if patch_text == '' or patch_text == nil then
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need this special case, either.

assert_failure_contains('diff', t.assert_equals, actual, expected)
end

function g_diff.test_msgpack_table()
Copy link
Member

Choose a reason for hiding this comment

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

All these tests checking various Lua types look pointless now, when we use pp.tostring. They should already be covered by pp.tostring tests.

@locker locker assigned mandesero and unassigned locker Dec 19, 2025
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

3 participants