diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-06-13 15:13:38 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-06-13 15:13:38 +0200 |
commit | 4a021dfbeee88ac09d07e257912485314ecdcabe (patch) | |
tree | adc3fb1dd7e608e136a1daf5f698cb519d418bf2 /src/testing.c | |
parent | c9630d2658af9dcaa01913e899b201bfdef7b536 (diff) | |
download | vim-git-4a021dfbeee88ac09d07e257912485314ecdcabe.tar.gz |
patch 8.2.0969: assert_equal() output for dicts is hard to figure outv8.2.0969
Problem: Assert_equal() output for dicts is hard to figure out.
Solution: Only show the different items.
Diffstat (limited to 'src/testing.c')
-rw-r--r-- | src/testing.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/src/testing.c b/src/testing.c index 0eee72a83..c01ae3db7 100644 --- a/src/testing.c +++ b/src/testing.c @@ -131,12 +131,16 @@ fill_assert_error( garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, - typval_T *exp_tv, - typval_T *got_tv, + typval_T *exp_tv_arg, + typval_T *got_tv_arg, assert_type_T atype) { char_u numbuf[NUMBUFLEN]; char_u *tofree; + typval_T *exp_tv = exp_tv_arg; + typval_T *got_tv = got_tv_arg; + int did_copy = FALSE; + int omitted = 0; if (opt_msg_tv->v_type != VAR_UNKNOWN) { @@ -153,6 +157,62 @@ fill_assert_error( ga_concat(gap, (char_u *)"Expected "); 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; + hashitem_T *hi; + dictitem_T *item2; + int todo; + + did_copy = TRUE; + exp_tv->vval.v_dict = dict_alloc(); + got_tv->vval.v_dict = dict_alloc(); + if (exp_tv->vval.v_dict == NULL || got_tv->vval.v_dict == NULL) + return; + + todo = (int)exp_d->dv_hashtab.ht_used; + for (hi = exp_d->dv_hashtab.ht_array; todo > 0; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + item2 = dict_find(got_d, hi->hi_key, -1); + if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv, + &item2->di_tv, FALSE, FALSE)) + { + // item of exp_d not present in got_d or values differ. + dict_add_tv(exp_tv->vval.v_dict, + (char *)hi->hi_key, &HI2DI(hi)->di_tv); + if (item2 != NULL) + dict_add_tv(got_tv->vval.v_dict, + (char *)hi->hi_key, &item2->di_tv); + } + else + ++omitted; + --todo; + } + } + + // Add items only present in got_d. + todo = (int)got_d->dv_hashtab.ht_used; + for (hi = got_d->dv_hashtab.ht_array; todo > 0; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + item2 = dict_find(exp_d, hi->hi_key, -1); + if (item2 == NULL) + // item of got_d not present in exp_d + dict_add_tv(got_tv->vval.v_dict, + (char *)hi->hi_key, &HI2DI(hi)->di_tv); + --todo; + } + } + } + ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); vim_free(tofree); } @@ -168,6 +228,21 @@ fill_assert_error( ga_concat(gap, (char_u *)" but got "); ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); vim_free(tofree); + + if (omitted != 0) + { + char buf[100]; + + vim_snprintf(buf, 100, " - %d equal item%s omitted", + omitted, omitted == 1 ? "" : "s"); + ga_concat(gap, (char_u *)buf); + } + } + + if (did_copy) + { + clear_tv(exp_tv); + clear_tv(got_tv); } } |