Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vader#assert#diff to describe differences in lists/dicts #123

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions autoload/vader/assert.vim
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,59 @@ function! vader#assert#throws(exp)
else | throw 'Exception expected but not raised: '.a:exp
endif
endfunction

function! vader#assert#diff(Exp, Got, ...) abort
let desc_only = a:0 ? a:1 : 0 " used for recursion with lists.
if type(a:Exp) !=# type(a:Got)
return printf("type mismatch: %s (%s) should be equal to %s (%s)",
\ string(a:Got), get(s:type_names, type(a:Got), type(a:Got)),
\ string(a:Exp), get(s:type_names, type(a:Exp), type(a:Exp)))
endif

if a:Exp ==# a:Got
return ''
endif

if type(a:Exp) == type({})
let desc = {'only in expected': [], 'only in gotten': [], 'diff': []}
for [k, V] in items(a:Exp)
if !has_key(a:Got, k)
call add(desc['only in expected'], k)
continue
endif
if type(V) !=# type(a:Got[k]) || V !=# a:Got[k]
call add(desc['diff'], printf('%s (%s / %s)', k, string(a:Got[k]), string(V)))
endif
endfor
for [k, V] in items(a:Got)
if !has_key(a:Exp, k)
call add(desc['only in gotten'], k)
endif
endfor
let desc = join(values(map(filter(desc, '!empty(v:val)'), "v:key.': '.join(v:val, ', ')")), '; ')
if desc_only
return 'unequal dicts: '.desc
endif
return printf('%s should be equal to %s (%s)', string(a:Got), string(a:Exp), desc)
elseif type(a:Exp) == type([])
let msg = ''
if len(a:Exp) != len(a:Got)
let desc = 'different lengths'
else
let idx = 0
for V in a:Exp
if type(V) != type(a:Got[idx]) || V !=# a:Got[idx]
let desc = printf('diff at index %d: %s', idx, vader#assert#diff(V, a:Got[idx], 1))
break
endif
let idx += 1
endfor
endif
if desc_only
return 'unequal lists: '.desc
endif
return printf('%s should be equal to %s (%s)', string(a:Got), string(a:Exp), desc)
else
return printf('%s should be equal to %s', string(a:Got), string(a:Exp))
endif
endfunction
41 changes: 41 additions & 0 deletions test/feature/diff.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Execute (Recursive comparison / diff description):
runtime autoload/vader/assert.vim

AssertEqual vader#assert#diff({}, {}), ''
AssertEqual vader#assert#diff({'left': 1}, {}),
\ '{} should be equal to {''left'': 1} (only in expected: left)'

AssertEqual vader#assert#diff({'left': 1}, {'right': 2}),
\ '{''right'': 2} should be equal to {''left'': 1} '.
\ '(only in expected: left; only in gotten: right)'

AssertEqual vader#assert#diff({'a': '1'}, {'a': 1}),
\ '{''a'': 1} should be equal to {''a'': ''1''} '.
\ '(diff: a (1 / ''1''))'

AssertEqual vader#assert#diff([1, 2], [2, 1]),
\ '[2, 1] should be equal to [1, 2] '.
\ '(diff at index 0: 2 should be equal to 1)'

AssertEqual vader#assert#diff([1, 2, []], [1, 2]),
\ '[1, 2] should be equal to [1, 2, []] '.
\ '(different lengths)'

AssertEqual vader#assert#diff(['1'], [1]),
\ '[1] should be equal to [''1''] '.
\ '(diff at index 0: type mismatch: 1 (Number) should be equal to ''1'' (String))'

AssertEqual vader#assert#diff([1, 2], {}),
\ 'type mismatch: {} (Dictionary) should be equal to [1, 2] (List)'

let l1 = [{'lnum': 1, 'bufnr': 1, 'col': 0}, {'lnum': 6, 'bufnr': 1, 'col': 0}]
let l2 = [{'lnum': 2, 'bufnr': 4, 'col': 0, 'more': 1}, {'lnum': 7, 'bufnr': 4, 'col': 0}]
AssertEqual vader#assert#diff(l1, l2),
\ string(l2).' should be equal to '.string(l1).' '.
\ "(diff at index 0: unequal dicts: only in gotten: more; diff: lnum (2 / 1), bufnr (4 / 1))"

AssertEqual vader#assert#diff([{1: 2}], [{3: 4}]),
\ '[{''3'': 4}] should be equal to [{''1'': 2}] (diff at index 0: unequal dicts: only in expected: 1; only in gotten: 3)'

AssertEqual vader#assert#diff([{1: 2}], [{3: 4}, 2]),
\ '[{''3'': 4}, 2] should be equal to [{''1'': 2}] (different lengths)'