# HG changeset patch # User Christian Brabandt # Date 1464104706 -7200 # Node ID d319453f62b35a9ffc4144a2ed92c90dca6c781c # Parent b2301e342fc5984aa17127c29ad9e7af13615d53 commit https://github.com/vim/vim/commit/574860b5ee9da281c875dad07a607454e135eaee Author: Bram Moolenaar Date: Tue May 24 17:33:34 2016 +0200 patch 7.4.1838 Problem: Functions specifically for testing do not sort together. Solution: Rename garbagecollect_for_testing() to test_garbagecollect_now(). Add test_null_list(), test_null_dict(), etc. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1955,7 +1955,6 @@ foreground() Number bring the Vim wind function({name} [, {arglist}] [, {dict}]) Funcref reference to function {name} garbagecollect([{atexit}]) none free memory, breaking cyclic references -garbagecollect_for_testing() none free memory right now get({list}, {idx} [, {def}]) any get item {idx} from {list} or {def} get({dict}, {key} [, {def}]) any get item {key} from {dict} or {def} getbufline({expr}, {lnum} [, {end}]) @@ -2203,6 +2202,13 @@ tagfiles() List tags files used tan({expr}) Float tangent of {expr} tanh({expr}) Float hyperbolic tangent of {expr} tempname() String name for a temporary file +test_garbagecollect_now() none free memory right now for testing +test_null_channel() Channel null value for testing +test_null_dict() Dict null value for testing +test_null_job() Job null value for testing +test_null_list() List null value for testing +test_null_partial() Funcref null value for testing +test_null_string() String null value for testing timer_start({time}, {callback} [, {options}]) Number create a timer timer_stop({timer}) none stop a timer @@ -3752,11 +3758,10 @@ garbagecollect([{atexit}]) *garbageco collection will also be done when exiting Vim, if it wasn't done before. This is useful when checking for memory leaks. -garbagecollect_for_testing() *garbagecollect_for_testing()* - Like garbagecollect(), but executed right away. This must - only be called directly to avoid any structure to exist - internally, and |v:testing| must have been set before calling - any function. + The garbage collection is not done immediately but only when + it's safe to perform. This is when waiting for the user to + type a character. To force garbage collection immediately use + |test_garbagecollect_now()|. get({list}, {idx} [, {default}]) *get()* Get item {idx} from |List| {list}. When this item is not @@ -7165,17 +7170,6 @@ taglist({expr}) *taglist()* located by Vim. Refer to |tags-file-format| for the format of the tags file generated by the different ctags tools. -tempname() *tempname()* *temp-file-name* - The result is a String, which is the name of a file that - doesn't exist. It can be used for a temporary file. The name - is different for at least 26 consecutive calls. Example: > - :let tmpfile = tempname() - :exe "redir > " . tmpfile -< For Unix, the file will be in a private directory |tempfile|. - For MS-Windows forward slashes are used when the 'shellslash' - option is set or when 'shellcmdflag' starts with '-'. - - tan({expr}) *tan()* Return the tangent of {expr}, measured in radians, as a |Float| in the range [-inf, inf]. @@ -7200,6 +7194,44 @@ tanh({expr}) *tanh()* {only available when compiled with the |+float| feature} +tempname() *tempname()* *temp-file-name* + The result is a String, which is the name of a file that + doesn't exist. It can be used for a temporary file. The name + is different for at least 26 consecutive calls. Example: > + :let tmpfile = tempname() + :exe "redir > " . tmpfile +< For Unix, the file will be in a private directory |tempfile|. + For MS-Windows forward slashes are used when the 'shellslash' + option is set or when 'shellcmdflag' starts with '-'. + + +test_garbagecollect_now() *test_garbagecollect_now()* + Like garbagecollect(), but executed right away. This must + only be called directly to avoid any structure to exist + internally, and |v:testing| must have been set before calling + any function. + +test_null_channel() *test_null_channel()* + Return a Channel that is null. Only useful for testing. + {only available when compiled with the +channel feature} + +test_null_dict() *test_null_dict()* + Return a Dict that is null. Only useful for testing. + +test_null_job() *test_null_job()* + Return a Job that is null. Only useful for testing. + {only available when compiled with the +job feature} + +test_null_list() *test_null_list()* + Return a List that is null. Only useful for testing. + +test_null_partial() *test_null_partial()* + Return a Partial that is null. Only useful for testing. + +test_null_string() *test_null_string()* + Return a String that is null. Only useful for testing. + + *timer_start()* timer_start({time}, {callback} [, {options}]) Create a timer and return the timer ID. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -583,7 +583,6 @@ static void f_foldtextresult(typval_T *a static void f_foreground(typval_T *argvars, typval_T *rettv); static void f_function(typval_T *argvars, typval_T *rettv); static void f_garbagecollect(typval_T *argvars, typval_T *rettv); -static void f_garbagecollect_for_testing(typval_T *argvars, typval_T *rettv); static void f_get(typval_T *argvars, typval_T *rettv); static void f_getbufline(typval_T *argvars, typval_T *rettv); static void f_getbufvar(typval_T *argvars, typval_T *rettv); @@ -806,7 +805,17 @@ static void f_tabpagewinnr(typval_T *arg static void f_taglist(typval_T *argvars, typval_T *rettv); static void f_tagfiles(typval_T *argvars, typval_T *rettv); static void f_tempname(typval_T *argvars, typval_T *rettv); -static void f_test(typval_T *argvars, typval_T *rettv); +static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv); +#ifdef FEAT_JOB_CHANNEL +static void f_test_null_channel(typval_T *argvars, typval_T *rettv); +#endif +static void f_test_null_dict(typval_T *argvars, typval_T *rettv); +#ifdef FEAT_JOB_CHANNEL +static void f_test_null_job(typval_T *argvars, typval_T *rettv); +#endif +static void f_test_null_list(typval_T *argvars, typval_T *rettv); +static void f_test_null_partial(typval_T *argvars, typval_T *rettv); +static void f_test_null_string(typval_T *argvars, typval_T *rettv); #ifdef FEAT_FLOAT static void f_tan(typval_T *argvars, typval_T *rettv); static void f_tanh(typval_T *argvars, typval_T *rettv); @@ -6925,7 +6934,7 @@ static garray_T funcargs = GA_EMPTY; /* * Do garbage collection for lists and dicts. - * When "testing" is TRUE this is called from garbagecollect_for_testing(). + * When "testing" is TRUE this is called from test_garbagecollect_now(). * Return TRUE if some memory was freed. */ int @@ -8451,7 +8460,6 @@ static struct fst {"foreground", 0, 0, f_foreground}, {"function", 1, 3, f_function}, {"garbagecollect", 0, 1, f_garbagecollect}, - {"garbagecollect_for_testing", 0, 0, f_garbagecollect_for_testing}, {"get", 2, 3, f_get}, {"getbufline", 2, 3, f_getbufline}, {"getbufvar", 2, 3, f_getbufvar}, @@ -8681,7 +8689,17 @@ static struct fst {"tanh", 1, 1, f_tanh}, #endif {"tempname", 0, 0, f_tempname}, - {"test", 1, 1, f_test}, + {"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now}, +#ifdef FEAT_JOB_CHANNEL + {"test_null_channel", 0, 0, f_test_null_channel}, +#endif + {"test_null_dict", 0, 0, f_test_null_dict}, +#ifdef FEAT_JOB_CHANNEL + {"test_null_job", 0, 0, f_test_null_job}, +#endif + {"test_null_list", 0, 0, f_test_null_list}, + {"test_null_partial", 0, 0, f_test_null_partial}, + {"test_null_string", 0, 0, f_test_null_string}, #ifdef FEAT_TIMERS {"timer_start", 2, 3, f_timer_start}, {"timer_stop", 1, 1, f_timer_stop}, @@ -12374,17 +12392,6 @@ f_garbagecollect(typval_T *argvars, typv } /* - * "garbagecollect_for_testing()" function - */ - static void -f_garbagecollect_for_testing(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ - /* This is dangerous, any Lists and Dicts used internally may be freed - * while still in use. */ - garbage_collect(TRUE); -} - -/* * "get()" function */ static void @@ -20602,35 +20609,6 @@ f_tempname(typval_T *argvars UNUSED, typ } while (x == 'I' || x == 'O'); } -/* - * "test(list)" function: Just checking the walls... - */ - static void -f_test(typval_T *argvars UNUSED, typval_T *rettv UNUSED) -{ - /* Used for unit testing. Change the code below to your liking. */ -#if 0 - listitem_T *li; - list_T *l; - char_u *bad, *good; - - if (argvars[0].v_type != VAR_LIST) - return; - l = argvars[0].vval.v_list; - if (l == NULL) - return; - li = l->lv_first; - if (li == NULL) - return; - bad = get_tv_string(&li->li_tv); - li = li->li_next; - if (li == NULL) - return; - good = get_tv_string(&li->li_tv); - rettv->vval.v_number = test_edit_score(bad, good); -#endif -} - #ifdef FEAT_FLOAT /* * "tan()" function @@ -20663,6 +20641,63 @@ f_tanh(typval_T *argvars, typval_T *rett } #endif +/* + * "test_garbagecollect_now()" function + */ + static void +f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + /* This is dangerous, any Lists and Dicts used internally may be freed + * while still in use. */ + garbage_collect(TRUE); +} + +#ifdef FEAT_JOB_CHANNEL + static void +f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + rettv->v_type = VAR_CHANNEL; + rettv->vval.v_channel = NULL; +} +#endif + + static void +f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + rettv->v_type = VAR_DICT; + rettv->vval.v_dict = NULL; +} + +#ifdef FEAT_JOB_CHANNEL + static void +f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + rettv->v_type = VAR_JOB; + rettv->vval.v_job = NULL; +} +#endif + + static void +f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + rettv->v_type = VAR_LIST; + rettv->vval.v_list = NULL; +} + + static void +f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + rettv->v_type = VAR_PARTIAL; + rettv->vval.v_partial = NULL; +} + + static void +f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; +} + #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO) /* * Get a callback from "arg". It can be a Funcref or a function name. diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -183,7 +183,7 @@ func s:communicate(port) call assert_equal('got it', s:responseMsg) " Collect garbage, tests that our handle isn't collected. - call garbagecollect_for_testing() + call test_garbagecollect_now() " check setting options (without testing the effect) call ch_setoptions(handle, {'callback': 's:NotUsed'}) @@ -1302,7 +1302,7 @@ endfunc func Test_using_freed_memory() let g:a = job_start(['ls']) sleep 10m - call garbagecollect_for_testing() + call test_garbagecollect_now() endfunc diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim --- a/src/testdir/test_expr.vim +++ b/src/testdir/test_expr.vim @@ -85,7 +85,7 @@ func Test_getreg_empty_list() endfunc func Test_loop_over_null_list() - let null_list = submatch(1, 1) + let null_list = test_null_list() for i in null_list call assert_true(0, 'should not get here') endfor diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1838, +/**/ 1837, /**/ 1836,