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)
|
call remove(v:errors, 0)
|
||||||
endfunc
|
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()
|
func Test_assert_equalfile()
|
||||||
call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz'))
|
call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz'))
|
||||||
call assert_match("E485: Can't read file abcabc", v:errors[0])
|
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.
|
/// 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,
|
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;
|
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) {
|
if (opt_msg_tv->v_type != VAR_UNKNOWN) {
|
||||||
tofree = (char_u *)encode_tv2echo(opt_msg_tv, NULL);
|
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) {
|
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);
|
tofree = (char_u *)encode_tv2string(exp_tv, NULL);
|
||||||
ga_concat_shorten_esc(gap, tofree);
|
ga_concat_shorten_esc(gap, tofree);
|
||||||
xfree(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);
|
tofree = (char_u *)encode_tv2string(got_tv, NULL);
|
||||||
ga_concat_shorten_esc(gap, tofree);
|
ga_concat_shorten_esc(gap, tofree);
|
||||||
xfree(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