To: vim_dev@googlegroups.com Subject: Patch 8.0.1770 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1770 Problem: Assert functions don't return anything. Solution: Return non-zero when the assertion fails. Files: src/evalfunc.c, src/eval.c, src/proto/eval.pro, src/testdir/test_assert.vim, runtime/doc/eval.txt *** ../vim-8.0.1769/src/evalfunc.c 2018-04-24 15:19:00.499068802 +0200 --- src/evalfunc.c 2018-04-28 15:41:00.025389067 +0200 *************** *** 1300,1407 **** * "assert_beeps(cmd [, error])" function */ static void ! f_assert_beeps(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_beeps(argvars); } /* * "assert_equal(expected, actual[, msg])" function */ static void ! f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_equal_common(argvars, ASSERT_EQUAL); } /* * "assert_equalfile(fname-one, fname-two)" function */ static void ! f_assert_equalfile(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_equalfile(argvars); } /* * "assert_notequal(expected, actual[, msg])" function */ static void ! f_assert_notequal(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_equal_common(argvars, ASSERT_NOTEQUAL); } /* * "assert_exception(string[, msg])" function */ static void ! f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_exception(argvars); } /* * "assert_fails(cmd [, error])" function */ static void ! f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_fails(argvars); } /* * "assert_false(actual[, msg])" function */ static void ! f_assert_false(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_bool(argvars, FALSE); } /* * "assert_inrange(lower, upper[, msg])" function */ static void ! f_assert_inrange(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_inrange(argvars); } /* * "assert_match(pattern, actual[, msg])" function */ static void ! f_assert_match(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_match_common(argvars, ASSERT_MATCH); } /* * "assert_notmatch(pattern, actual[, msg])" function */ static void ! f_assert_notmatch(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_match_common(argvars, ASSERT_NOTMATCH); } /* * "assert_report(msg)" function */ static void ! f_assert_report(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_report(argvars); } /* * "assert_true(actual[, msg])" function */ static void ! f_assert_true(typval_T *argvars, typval_T *rettv UNUSED) { ! assert_bool(argvars, TRUE); } #ifdef FEAT_FLOAT --- 1300,1407 ---- * "assert_beeps(cmd [, error])" function */ static void ! f_assert_beeps(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_beeps(argvars); } /* * "assert_equal(expected, actual[, msg])" function */ static void ! f_assert_equal(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL); } /* * "assert_equalfile(fname-one, fname-two)" function */ static void ! f_assert_equalfile(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_equalfile(argvars); } /* * "assert_notequal(expected, actual[, msg])" function */ static void ! f_assert_notequal(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL); } /* * "assert_exception(string[, msg])" function */ static void ! f_assert_exception(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_exception(argvars); } /* * "assert_fails(cmd [, error])" function */ static void ! f_assert_fails(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_fails(argvars); } /* * "assert_false(actual[, msg])" function */ static void ! f_assert_false(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_bool(argvars, FALSE); } /* * "assert_inrange(lower, upper[, msg])" function */ static void ! f_assert_inrange(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_inrange(argvars); } /* * "assert_match(pattern, actual[, msg])" function */ static void ! f_assert_match(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH); } /* * "assert_notmatch(pattern, actual[, msg])" function */ static void ! f_assert_notmatch(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH); } /* * "assert_report(msg)" function */ static void ! f_assert_report(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_report(argvars); } /* * "assert_true(actual[, msg])" function */ static void ! f_assert_true(typval_T *argvars, typval_T *rettv) { ! rettv->vval.v_number = assert_bool(argvars, TRUE); } #ifdef FEAT_FLOAT *** ../vim-8.0.1769/src/eval.c 2018-04-08 13:07:18.742034802 +0200 --- src/eval.c 2018-04-28 15:47:43.486924209 +0200 *************** *** 8815,8821 **** list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } ! void assert_equal_common(typval_T *argvars, assert_type_T atype) { garray_T ga; --- 8815,8821 ---- list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } ! int assert_equal_common(typval_T *argvars, assert_type_T atype) { garray_T ga; *************** *** 8828,8837 **** atype); assert_error(&ga); ga_clear(&ga); } } ! void assert_equalfile(typval_T *argvars) { char_u buf1[NUMBUFLEN]; --- 8828,8839 ---- atype); assert_error(&ga); ga_clear(&ga); + return 1; } + return 0; } ! int assert_equalfile(typval_T *argvars) { char_u buf1[NUMBUFLEN]; *************** *** 8843,8849 **** FILE *fd2; if (fname1 == NULL || fname2 == NULL) ! return; IObuff[0] = NUL; fd1 = mch_fopen((char *)fname1, READBIN); --- 8845,8851 ---- FILE *fd2; if (fname1 == NULL || fname2 == NULL) ! return 0; IObuff[0] = NUL; fd1 = mch_fopen((char *)fname1, READBIN); *************** *** 8897,8906 **** ga_concat(&ga, IObuff); assert_error(&ga); ga_clear(&ga); } } ! void assert_match_common(typval_T *argvars, assert_type_T atype) { garray_T ga; --- 8899,8910 ---- ga_concat(&ga, IObuff); assert_error(&ga); ga_clear(&ga); + return 1; } + return 0; } ! int assert_match_common(typval_T *argvars, assert_type_T atype) { garray_T ga; *************** *** 8918,8927 **** atype); assert_error(&ga); ga_clear(&ga); } } ! void assert_inrange(typval_T *argvars) { garray_T ga; --- 8922,8933 ---- atype); assert_error(&ga); ga_clear(&ga); + return 1; } + return 0; } ! int assert_inrange(typval_T *argvars) { garray_T ga; *************** *** 8934,8940 **** char_u numbuf[NUMBUFLEN]; if (error) ! return; if (actual < lower || actual > upper) { prepare_assert_error(&ga); --- 8940,8946 ---- char_u numbuf[NUMBUFLEN]; if (error) ! return 0; if (actual < lower || actual > upper) { prepare_assert_error(&ga); *************** *** 8951,8963 **** } assert_error(&ga); ga_clear(&ga); } } /* * Common for assert_true() and assert_false(). */ ! void assert_bool(typval_T *argvars, int isTrue) { int error = FALSE; --- 8957,8972 ---- } assert_error(&ga); ga_clear(&ga); + return 1; } + return 0; } /* * Common for assert_true() and assert_false(). + * Return non-zero for failure. */ ! int assert_bool(typval_T *argvars, int isTrue) { int error = FALSE; *************** *** 8965,8971 **** if (argvars[0].v_type == VAR_SPECIAL && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) ! return; if (argvars[0].v_type != VAR_NUMBER || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue || error) --- 8974,8980 ---- if (argvars[0].v_type == VAR_SPECIAL && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) ! return 0; if (argvars[0].v_type != VAR_NUMBER || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue || error) *************** *** 8976,8985 **** NULL, &argvars[0], ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); } } ! void assert_report(typval_T *argvars) { garray_T ga; --- 8985,8996 ---- NULL, &argvars[0], ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); + return 1; } + return 0; } ! int assert_report(typval_T *argvars) { garray_T ga; *************** *** 8988,8996 **** ga_concat(&ga, get_tv_string(&argvars[0])); assert_error(&ga); ga_clear(&ga); } ! void assert_exception(typval_T *argvars) { garray_T ga; --- 8999,9008 ---- ga_concat(&ga, get_tv_string(&argvars[0])); assert_error(&ga); ga_clear(&ga); + return 1; } ! int assert_exception(typval_T *argvars) { garray_T ga; *************** *** 9002,9007 **** --- 9014,9020 ---- ga_concat(&ga, (char_u *)"v:exception is not set"); assert_error(&ga); ga_clear(&ga); + return 1; } else if (error != NULL && strstr((char *)vimvars[VV_EXCEPTION].vv_str, (char *)error) == NULL) *************** *** 9011,9024 **** &vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); } } ! void assert_beeps(typval_T *argvars) { char_u *cmd = get_tv_string_chk(&argvars[0]); garray_T ga; called_vim_beep = FALSE; suppress_errthrow = TRUE; --- 9024,9040 ---- &vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); + return 1; } + return 0; } ! int assert_beeps(typval_T *argvars) { char_u *cmd = get_tv_string_chk(&argvars[0]); garray_T ga; + int ret = 0; called_vim_beep = FALSE; suppress_errthrow = TRUE; *************** *** 9031,9047 **** ga_concat(&ga, cmd); assert_error(&ga); ga_clear(&ga); } suppress_errthrow = FALSE; emsg_on_display = FALSE; } ! void assert_fails(typval_T *argvars) { char_u *cmd = get_tv_string_chk(&argvars[0]); garray_T ga; called_emsg = FALSE; suppress_errthrow = TRUE; --- 9047,9066 ---- ga_concat(&ga, cmd); assert_error(&ga); ga_clear(&ga); + ret = 1; } suppress_errthrow = FALSE; emsg_on_display = FALSE; + return ret; } ! int assert_fails(typval_T *argvars) { char_u *cmd = get_tv_string_chk(&argvars[0]); garray_T ga; + int ret = 0; called_emsg = FALSE; suppress_errthrow = TRUE; *************** *** 9054,9059 **** --- 9073,9079 ---- ga_concat(&ga, cmd); assert_error(&ga); ga_clear(&ga); + ret = 1; } else if (argvars[1].v_type != VAR_UNKNOWN) { *************** *** 9068,9073 **** --- 9088,9094 ---- &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); + ret = 1; } } *************** *** 9076,9081 **** --- 9097,9103 ---- emsg_silent = FALSE; emsg_on_display = FALSE; set_vim_var_string(VV_ERRMSG, NULL, 0); + return ret; } /* *** ../vim-8.0.1769/src/proto/eval.pro 2018-02-18 22:13:06.265057933 +0100 --- src/proto/eval.pro 2018-04-28 15:47:50.834879464 +0200 *************** *** 121,135 **** void reset_v_option_vars(void); void prepare_assert_error(garray_T *gap); void assert_error(garray_T *gap); ! void assert_equal_common(typval_T *argvars, assert_type_T atype); ! void assert_equalfile(typval_T *argvars); ! void assert_match_common(typval_T *argvars, assert_type_T atype); ! void assert_inrange(typval_T *argvars); ! void assert_bool(typval_T *argvars, int isTrue); ! void assert_report(typval_T *argvars); ! void assert_exception(typval_T *argvars); ! void assert_beeps(typval_T *argvars); ! void assert_fails(typval_T *argvars); 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); int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic); char_u *typval_tostring(typval_T *arg); --- 121,135 ---- void reset_v_option_vars(void); void prepare_assert_error(garray_T *gap); void assert_error(garray_T *gap); ! int assert_equal_common(typval_T *argvars, assert_type_T atype); ! int assert_equalfile(typval_T *argvars); ! int assert_match_common(typval_T *argvars, assert_type_T atype); ! int assert_inrange(typval_T *argvars); ! int assert_bool(typval_T *argvars, int isTrue); ! int assert_report(typval_T *argvars); ! int assert_exception(typval_T *argvars); ! int assert_beeps(typval_T *argvars); ! int assert_fails(typval_T *argvars); 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); int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic); char_u *typval_tostring(typval_T *arg); *** ../vim-8.0.1769/src/testdir/test_assert.vim 2018-02-18 22:13:06.269057906 +0100 --- src/testdir/test_assert.vim 2018-04-28 16:44:49.748997867 +0200 *************** *** 1,58 **** " Test that the methods used for testing work. func Test_assert_false() ! call assert_false(0) ! call assert_false(v:false) endfunc func Test_assert_true() ! call assert_true(1) ! call assert_true(123) ! call assert_true(v:true) endfunc func Test_assert_equal() let s = 'foo' ! call assert_equal('foo', s) let n = 4 ! call assert_equal(4, n) let l = [1, 2, 3] ! call assert_equal([1, 2, 3], l) let s = 'foo' ! call assert_equal('bar', s) call assert_match("Expected 'bar' but got 'foo'", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_equalfile() ! call assert_equalfile('abcabc', 'xyzxyz') call assert_match("E485: Can't read file abcabc", v:errors[0]) call remove(v:errors, 0) let goodtext = ["one", "two", "three"] call writefile(goodtext, 'Xone') ! call assert_equalfile('Xone', 'xyzxyz') call assert_match("E485: Can't read file xyzxyz", v:errors[0]) call remove(v:errors, 0) call writefile(goodtext, 'Xtwo') ! call assert_equalfile('Xone', 'Xtwo') call writefile([goodtext[0]], 'Xone') ! call assert_equalfile('Xone', 'Xtwo') call assert_match("first file is shorter", v:errors[0]) call remove(v:errors, 0) call writefile(goodtext, 'Xone') call writefile([goodtext[0]], 'Xtwo') ! call assert_equalfile('Xone', 'Xtwo') call assert_match("second file is shorter", v:errors[0]) call remove(v:errors, 0) call writefile(['1234X89'], 'Xone') call writefile(['1234Y89'], 'Xtwo') ! call assert_equalfile('Xone', 'Xtwo') call assert_match("difference at byte 4", v:errors[0]) call remove(v:errors, 0) --- 1,66 ---- " Test that the methods used for testing work. func Test_assert_false() ! call assert_equal(0, assert_false(0)) ! call assert_equal(0, assert_false(v:false)) ! ! call assert_equal(1, assert_false(123)) ! call assert_match("Expected False but got 123", v:errors[0]) ! call remove(v:errors, 0) endfunc func Test_assert_true() ! call assert_equal(0, assert_true(1)) ! call assert_equal(0, assert_true(123)) ! call assert_equal(0, assert_true(v:true)) ! ! call assert_equal(1, assert_true(0)) ! call assert_match("Expected True but got 0", v:errors[0]) ! call remove(v:errors, 0) endfunc func Test_assert_equal() let s = 'foo' ! call assert_equal(0, assert_equal('foo', s)) let n = 4 ! call assert_equal(0, assert_equal(4, n)) let l = [1, 2, 3] ! call assert_equal(0, assert_equal([1, 2, 3], l)) let s = 'foo' ! call assert_equal(1, assert_equal('bar', s)) call assert_match("Expected 'bar' but got 'foo'", 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]) call remove(v:errors, 0) let goodtext = ["one", "two", "three"] call writefile(goodtext, 'Xone') ! call assert_equal(1, assert_equalfile('Xone', 'xyzxyz')) call assert_match("E485: Can't read file xyzxyz", v:errors[0]) call remove(v:errors, 0) call writefile(goodtext, 'Xtwo') ! call assert_equal(0, assert_equalfile('Xone', 'Xtwo')) call writefile([goodtext[0]], 'Xone') ! call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) call assert_match("first file is shorter", v:errors[0]) call remove(v:errors, 0) call writefile(goodtext, 'Xone') call writefile([goodtext[0]], 'Xtwo') ! call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) call assert_match("second file is shorter", v:errors[0]) call remove(v:errors, 0) call writefile(['1234X89'], 'Xone') call writefile(['1234Y89'], 'Xtwo') ! call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) call assert_match("difference at byte 4", v:errors[0]) call remove(v:errors, 0) *************** *** 62,78 **** func Test_assert_notequal() let n = 4 ! call assert_notequal('foo', n) let s = 'foo' ! call assert_notequal([1, 2, 3], s) ! call assert_notequal('foo', s) call assert_match("Expected not equal to 'foo'", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_report() ! call assert_report('something is wrong') call assert_match('something is wrong', v:errors[0]) call remove(v:errors, 0) endfunc --- 70,86 ---- func Test_assert_notequal() let n = 4 ! call assert_equal(0, assert_notequal('foo', n)) let s = 'foo' ! call assert_equal(0, assert_notequal([1, 2, 3], s)) ! call assert_equal(1, assert_notequal('foo', s)) call assert_match("Expected not equal to 'foo'", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_report() ! call assert_equal(1, assert_report('something is wrong')) call assert_match('something is wrong', v:errors[0]) call remove(v:errors, 0) endfunc *************** *** 81,87 **** try nocommand catch ! call assert_exception('E492:') endtry try --- 89,95 ---- try nocommand catch ! call assert_equal(0, assert_exception('E492:')) endtry try *************** *** 89,97 **** catch try " illegal argument, get NULL for error ! call assert_exception([]) catch ! call assert_exception('E730:') endtry endtry endfunc --- 97,105 ---- catch try " illegal argument, get NULL for error ! call assert_equal(1, assert_exception([])) catch ! call assert_equal(0, assert_exception('E730:')) endtry endtry endfunc *************** *** 113,171 **** try call assert_equal(s:w, '') catch ! call assert_exception('E724:') call assert_match("Expected NULL but got ''", v:errors[0]) call remove(v:errors, 0) endtry endfunc func Test_match() ! call assert_match('^f.*b.*r$', 'foobar') ! call assert_match('bar.*foo', 'foobar') call assert_match("Pattern 'bar.*foo' does not match 'foobar'", v:errors[0]) call remove(v:errors, 0) ! call assert_match('bar.*foo', 'foobar', 'wrong') call assert_match('wrong', v:errors[0]) call remove(v:errors, 0) endfunc func Test_notmatch() ! call assert_notmatch('foo', 'bar') ! call assert_notmatch('^foobar$', 'foobars') ! call assert_notmatch('foo', 'foobar') call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_fail_fails() ! call assert_fails('xxx', {}) call assert_match("Expected {} but got 'E731:", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_beeps() new ! call assert_beeps('normal h') ! call assert_beeps('normal 0') call assert_match("command did not beep: normal 0", v:errors[0]) call remove(v:errors, 0) bwipe endfunc func Test_assert_inrange() ! call assert_inrange(7, 7, 7) ! call assert_inrange(5, 7, 5) ! call assert_inrange(5, 7, 6) ! call assert_inrange(5, 7, 7) ! call assert_inrange(5, 7, 4) call assert_match("Expected range 5 - 7, but got 4", v:errors[0]) call remove(v:errors, 0) ! call assert_inrange(5, 7, 8) call assert_match("Expected range 5 - 7, but got 8", v:errors[0]) call remove(v:errors, 0) --- 121,179 ---- try call assert_equal(s:w, '') catch ! call assert_equal(0, assert_exception('E724:')) call assert_match("Expected NULL but got ''", v:errors[0]) call remove(v:errors, 0) endtry endfunc func Test_match() ! call assert_equal(0, assert_match('^f.*b.*r$', 'foobar')) ! call assert_equal(1, assert_match('bar.*foo', 'foobar')) call assert_match("Pattern 'bar.*foo' does not match 'foobar'", v:errors[0]) call remove(v:errors, 0) ! call assert_equal(1, assert_match('bar.*foo', 'foobar', 'wrong')) call assert_match('wrong', v:errors[0]) call remove(v:errors, 0) endfunc func Test_notmatch() ! call assert_equal(0, assert_notmatch('foo', 'bar')) ! call assert_equal(0, assert_notmatch('^foobar$', 'foobars')) ! call assert_equal(1, assert_notmatch('foo', 'foobar')) call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_fail_fails() ! call assert_equal(1, assert_fails('xxx', {})) call assert_match("Expected {} but got 'E731:", v:errors[0]) call remove(v:errors, 0) endfunc func Test_assert_beeps() new ! call assert_equal(0, assert_beeps('normal h')) ! call assert_equal(1, assert_beeps('normal 0')) call assert_match("command did not beep: normal 0", v:errors[0]) call remove(v:errors, 0) bwipe endfunc func Test_assert_inrange() ! call assert_equal(0, assert_inrange(7, 7, 7)) ! call assert_equal(0, assert_inrange(5, 7, 5)) ! call assert_equal(0, assert_inrange(5, 7, 6)) ! call assert_equal(0, assert_inrange(5, 7, 7)) ! call assert_equal(1, assert_inrange(5, 7, 4)) call assert_match("Expected range 5 - 7, but got 4", v:errors[0]) call remove(v:errors, 0) ! call assert_equal(1, assert_inrange(5, 7, 8)) call assert_match("Expected range 5 - 7, but got 8", v:errors[0]) call remove(v:errors, 0) *** ../vim-8.0.1769/runtime/doc/eval.txt 2018-04-21 19:49:02.524104569 +0200 --- runtime/doc/eval.txt 2018-04-28 16:54:30.845049107 +0200 *************** *** 1545,1554 **** : ... handle error < "errmsg" also works, for backwards compatibility. ! *v:errors* *errors-variable* v:errors Errors found by assert functions, such as |assert_true()|. This is a list of strings. The assert functions append an item when an assert fails. To remove old results make it empty: > :let v:errors = [] < If v:errors is set to anything but a list it is made an empty --- 1548,1559 ---- : ... handle error < "errmsg" also works, for backwards compatibility. ! *v:errors* *errors-variable* *assert-return* v:errors Errors found by assert functions, such as |assert_true()|. This is a list of strings. The assert functions append an item when an assert fails. + The return value indicates this: a one is returned if an item + was added to v:errors, otherwise zero is returned. To remove old results make it empty: > :let v:errors = [] < If v:errors is set to anything but a list it is made an empty *************** *** 2017,2046 **** arglistid([{winnr} [, {tabnr}]]) Number argument list id argv({nr}) String {nr} entry of the argument list argv() List the argument list ! assert_beeps({cmd}) none assert {cmd} causes a beep assert_equal({exp}, {act} [, {msg}]) ! none assert {exp} is equal to {act} assert_equalfile({fname-one}, {fname-two}) ! none assert file contents is equal assert_exception({error} [, {msg}]) ! none assert {error} is in v:exception ! assert_fails({cmd} [, {error}]) none assert {cmd} fails assert_false({actual} [, {msg}]) ! none assert {actual} is false assert_inrange({lower}, {upper}, {actual} [, {msg}]) ! none assert {actual} is inside the range assert_match({pat}, {text} [, {msg}]) ! none assert {pat} matches {text} assert_notequal({exp}, {act} [, {msg}]) ! none assert {exp} is not equal {act} assert_notmatch({pat}, {text} [, {msg}]) ! none assert {pat} not matches {text} ! assert_report({msg}) none report a test failure ! assert_true({actual} [, {msg}]) none assert {actual} is true asin({expr}) Float arc sine of {expr} atan({expr}) Float arc tangent of {expr} atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2} ! balloon_show({msg}) none show {msg} inside the balloon balloon_split({msg}) List split {msg} as used for a balloon browse({save}, {title}, {initdir}, {default}) String put up a file requester --- 2022,2051 ---- arglistid([{winnr} [, {tabnr}]]) Number argument list id argv({nr}) String {nr} entry of the argument list argv() List the argument list ! assert_beeps({cmd}) Number assert {cmd} causes a beep assert_equal({exp}, {act} [, {msg}]) ! Number assert {exp} is equal to {act} assert_equalfile({fname-one}, {fname-two}) ! Number assert file contents is equal assert_exception({error} [, {msg}]) ! Number assert {error} is in v:exception ! assert_fails({cmd} [, {error}]) Number assert {cmd} fails assert_false({actual} [, {msg}]) ! Number assert {actual} is false assert_inrange({lower}, {upper}, {actual} [, {msg}]) ! Number assert {actual} is inside the range assert_match({pat}, {text} [, {msg}]) ! Number assert {pat} matches {text} assert_notequal({exp}, {act} [, {msg}]) ! Number assert {exp} is not equal {act} assert_notmatch({pat}, {text} [, {msg}]) ! Number assert {pat} not matches {text} ! assert_report({msg}) Number report a test failure ! assert_true({actual} [, {msg}]) Number assert {actual} is true asin({expr}) Float arc sine of {expr} atan({expr}) Float arc tangent of {expr} atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2} ! balloon_show({expr}) none show {expr} inside the balloon balloon_split({msg}) List split {msg} as used for a balloon browse({save}, {title}, {initdir}, {default}) String put up a file requester *************** *** 2586,2597 **** assert_beeps({cmd}) *assert_beeps()* Run {cmd} and add an error message to |v:errors| if it does NOT produce a beep or visual bell. ! Also see |assert_fails()|. *assert_equal()* assert_equal({expected}, {actual} [, {msg}]) When {expected} and {actual} are not equal an error message is ! added to |v:errors|. There is no automatic conversion, the String "4" is different from the Number 4. And the number 4 is different from the Float 4.0. The value of 'ignorecase' is not used here, case --- 2595,2607 ---- assert_beeps({cmd}) *assert_beeps()* Run {cmd} and add an error message to |v:errors| if it does NOT produce a beep or visual bell. ! Also see |assert_fails()| and |assert-return|. *assert_equal()* assert_equal({expected}, {actual} [, {msg}]) When {expected} and {actual} are not equal an error message is ! added to |v:errors| and 1 is returned. Otherwise zero is ! returned |assert-return|. There is no automatic conversion, the String "4" is different from the Number 4. And the number 4 is different from the Float 4.0. The value of 'ignorecase' is not used here, case *************** *** 2607,2619 **** assert_equalfile({fname-one}, {fname-two}) When the files {fname-one} and {fname-two} do not contain exactly the same text an error message is added to |v:errors|. When {fname-one} or {fname-two} does not exist the error will mention that. Mainly useful with |terminal-diff|. assert_exception({error} [, {msg}]) *assert_exception()* When v:exception does not contain the string {error} an error ! message is added to |v:errors|. This can be used to assert that a command throws an exception. Using the error number, followed by a colon, avoids problems with translations: > --- 2617,2630 ---- assert_equalfile({fname-one}, {fname-two}) When the files {fname-one} and {fname-two} do not contain exactly the same text an error message is added to |v:errors|. + Also see |assert-return|. When {fname-one} or {fname-two} does not exist the error will mention that. Mainly useful with |terminal-diff|. assert_exception({error} [, {msg}]) *assert_exception()* When v:exception does not contain the string {error} an error ! message is added to |v:errors|. Also see |assert-return|. This can be used to assert that a command throws an exception. Using the error number, followed by a colon, avoids problems with translations: > *************** *** 2626,2639 **** assert_fails({cmd} [, {error}]) *assert_fails()* Run {cmd} and add an error message to |v:errors| if it does ! NOT produce an error. When {error} is given it must match in |v:errmsg|. Note that beeping is not considered an error, and some failing commands only beep. Use |assert_beeps()| for those. assert_false({actual} [, {msg}]) *assert_false()* When {actual} is not false an error message is added to ! |v:errors|, like with |assert_equal()|. A value is false when it is zero. When {actual} is not a number the assert fails. When {msg} is omitted an error in the form --- 2637,2651 ---- assert_fails({cmd} [, {error}]) *assert_fails()* Run {cmd} and add an error message to |v:errors| if it does ! NOT produce an error. Also see |assert-return|. When {error} is given it must match in |v:errmsg|. Note that beeping is not considered an error, and some failing commands only beep. Use |assert_beeps()| for those. assert_false({actual} [, {msg}]) *assert_false()* When {actual} is not false an error message is added to ! |v:errors|, like with |assert_equal()|. ! Also see |assert-return|. A value is false when it is zero. When {actual} is not a number the assert fails. When {msg} is omitted an error in the form *************** *** 2642,2648 **** assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()* This asserts number values. When {actual} is lower than {lower} or higher than {upper} an error message is added to ! |v:errors|. When {msg} is omitted an error in the form "Expected range {lower} - {upper}, but got {actual}" is produced. --- 2654,2660 ---- assert_inrange({lower}, {upper}, {actual} [, {msg}]) *assert_inrange()* This asserts number values. When {actual} is lower than {lower} or higher than {upper} an error message is added to ! |v:errors|. Also see |assert-return|. When {msg} is omitted an error in the form "Expected range {lower} - {upper}, but got {actual}" is produced. *************** *** 2650,2656 **** *assert_match()* assert_match({pattern}, {actual} [, {msg}]) When {pattern} does not match {actual} an error message is ! added to |v:errors|. {pattern} is used as with |=~|: The matching is always done like 'magic' was set and 'cpoptions' is empty, no matter what --- 2662,2668 ---- *assert_match()* assert_match({pattern}, {actual} [, {msg}]) When {pattern} does not match {actual} an error message is ! added to |v:errors|. Also see |assert-return|. {pattern} is used as with |=~|: The matching is always done like 'magic' was set and 'cpoptions' is empty, no matter what *************** *** 2671,2688 **** --- 2683,2704 ---- assert_notequal({expected}, {actual} [, {msg}]) The opposite of `assert_equal()`: add an error message to |v:errors| when {expected} and {actual} are equal. + Also see |assert-return|. *assert_notmatch()* assert_notmatch({pattern}, {actual} [, {msg}]) The opposite of `assert_match()`: add an error message to |v:errors| when {pattern} matches {actual}. + Also see |assert-return|. assert_report({msg}) *assert_report()* Report a test failure directly, using {msg}. + Always returns one. assert_true({actual} [, {msg}]) *assert_true()* When {actual} is not true an error message is added to |v:errors|, like with |assert_equal()|. + Also see |assert-return|. A value is TRUE when it is a non-zero number. When {actual} is not a number the assert fails. When {msg} is omitted an error in the form "Expected True but *** ../vim-8.0.1769/src/version.c 2018-04-28 13:56:04.835260625 +0200 --- src/version.c 2018-04-28 16:45:59.404510174 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1770, /**/ -- If I tell you "you have a beautiful body", would you hold it against me? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///