mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38:32 +00:00
vim-patch:8.2.0969: assert_equal() output for dicts is hard to figure out (#19317)
Problem: Assert_equal() output for dicts is hard to figure out.
Solution: Only show the different items.
4a021dfbee
This commit is contained in:
@@ -50,6 +50,26 @@ func Test_assert_equal()
|
||||
call remove(v:errors, 0)
|
||||
endfunc
|
||||
|
||||
func Test_assert_equal_dict()
|
||||
call assert_equal(0, assert_equal(#{one: 1, two: 2}, #{two: 2, one: 1}))
|
||||
|
||||
call assert_equal(1, assert_equal(#{one: 1, two: 2}, #{two: 2, one: 3}))
|
||||
call assert_match("Expected {'one': 1} but got {'one': 3} - 1 equal item omitted", v:errors[0])
|
||||
call remove(v:errors, 0)
|
||||
|
||||
call assert_equal(1, assert_equal(#{one: 1, two: 2}, #{two: 22, one: 11}))
|
||||
call assert_match("Expected {'one': 1, 'two': 2} but got {'one': 11, 'two': 22}", v:errors[0])
|
||||
call remove(v:errors, 0)
|
||||
|
||||
call assert_equal(1, assert_equal(#{}, #{two: 2, one: 1}))
|
||||
call assert_match("Expected {} but got {'one': 1, 'two': 2}", v:errors[0])
|
||||
call remove(v:errors, 0)
|
||||
|
||||
call assert_equal(1, assert_equal(#{two: 2, one: 1}, #{}))
|
||||
call assert_match("Expected {'one': 1, 'two': 2} but got {}", v:errors[0])
|
||||
call remove(v:errors, 0)
|
||||
endfunc
|
||||
|
||||
func Test_assert_equalfile()
|
||||
call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz'))
|
||||
call assert_match("E485: Can't read file abcabc", v:errors[0])
|
||||
|
@@ -110,9 +110,13 @@ static void ga_concat_shorten_esc(garray_T *gap, const char_u *str)
|
||||
|
||||
/// Fill "gap" with information about an assert error.
|
||||
static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str,
|
||||
typval_T *exp_tv, typval_T *got_tv, assert_type_T atype)
|
||||
typval_T *exp_tv_arg, typval_T *got_tv_arg, assert_type_T atype)
|
||||
{
|
||||
char_u *tofree;
|
||||
typval_T *exp_tv = exp_tv_arg;
|
||||
typval_T *got_tv = got_tv_arg;
|
||||
bool did_copy = false;
|
||||
int omitted = 0;
|
||||
|
||||
if (opt_msg_tv->v_type != VAR_UNKNOWN) {
|
||||
tofree = (char_u *)encode_tv2echo(opt_msg_tv, NULL);
|
||||
@@ -130,6 +134,55 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_s
|
||||
}
|
||||
|
||||
if (exp_str == NULL) {
|
||||
// When comparing dictionaries, drop the items that are equal, so that
|
||||
// it's a lot easier to see what differs.
|
||||
if (atype != ASSERT_NOTEQUAL
|
||||
&& exp_tv->v_type == VAR_DICT && got_tv->v_type == VAR_DICT
|
||||
&& exp_tv->vval.v_dict != NULL && got_tv->vval.v_dict != NULL) {
|
||||
dict_T *exp_d = exp_tv->vval.v_dict;
|
||||
dict_T *got_d = got_tv->vval.v_dict;
|
||||
|
||||
did_copy = true;
|
||||
exp_tv->vval.v_dict = tv_dict_alloc();
|
||||
got_tv->vval.v_dict = tv_dict_alloc();
|
||||
|
||||
int todo = (int)exp_d->dv_hashtab.ht_used;
|
||||
for (const hashitem_T *hi = exp_d->dv_hashtab.ht_array; todo > 0; hi++) {
|
||||
if (!HASHITEM_EMPTY(hi)) {
|
||||
dictitem_T *item2 = tv_dict_find(got_d, (const char *)hi->hi_key, -1);
|
||||
if (item2 == NULL
|
||||
|| !tv_equal(&TV_DICT_HI2DI(hi)->di_tv, &item2->di_tv, false, false)) {
|
||||
// item of exp_d not present in got_d or values differ.
|
||||
const size_t key_len = STRLEN(hi->hi_key);
|
||||
tv_dict_add_tv(exp_tv->vval.v_dict, (const char *)hi->hi_key, key_len,
|
||||
&TV_DICT_HI2DI(hi)->di_tv);
|
||||
if (item2 != NULL) {
|
||||
tv_dict_add_tv(got_tv->vval.v_dict, (const char *)hi->hi_key, key_len,
|
||||
&item2->di_tv);
|
||||
}
|
||||
} else {
|
||||
omitted++;
|
||||
}
|
||||
todo--;
|
||||
}
|
||||
}
|
||||
|
||||
// Add items only present in got_d.
|
||||
todo = (int)got_d->dv_hashtab.ht_used;
|
||||
for (const hashitem_T *hi = got_d->dv_hashtab.ht_array; todo > 0; hi++) {
|
||||
if (!HASHITEM_EMPTY(hi)) {
|
||||
dictitem_T *item2 = tv_dict_find(exp_d, (const char *)hi->hi_key, -1);
|
||||
if (item2 == NULL) {
|
||||
// item of got_d not present in exp_d
|
||||
const size_t key_len = STRLEN(hi->hi_key);
|
||||
tv_dict_add_tv(got_tv->vval.v_dict, (const char *)hi->hi_key, key_len,
|
||||
&TV_DICT_HI2DI(hi)->di_tv);
|
||||
}
|
||||
todo--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tofree = (char_u *)encode_tv2string(exp_tv, NULL);
|
||||
ga_concat_shorten_esc(gap, tofree);
|
||||
xfree(tofree);
|
||||
@@ -148,6 +201,18 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_s
|
||||
tofree = (char_u *)encode_tv2string(got_tv, NULL);
|
||||
ga_concat_shorten_esc(gap, tofree);
|
||||
xfree(tofree);
|
||||
|
||||
if (omitted != 0) {
|
||||
char buf[100];
|
||||
vim_snprintf(buf, sizeof(buf), " - %d equal item%s omitted", omitted,
|
||||
omitted == 1 ? "" : "s");
|
||||
ga_concat(gap, buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (did_copy) {
|
||||
tv_clear(exp_tv);
|
||||
tv_clear(got_tv);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user