mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.1.1687: the evalfunc.c file is too big
Problem: The evalfunc.c file is too big. Solution: Move testing support to a separate file.
This commit is contained in:
parent
2898ebb44c
commit
ecaa70ea29
2
Filelist
2
Filelist
@ -100,6 +100,7 @@ SRC_ALL = \
|
|||||||
src/terminal.c \
|
src/terminal.c \
|
||||||
src/term.h \
|
src/term.h \
|
||||||
src/termlib.c \
|
src/termlib.c \
|
||||||
|
src/testing.c \
|
||||||
src/textprop.c \
|
src/textprop.c \
|
||||||
src/ui.c \
|
src/ui.c \
|
||||||
src/undo.c \
|
src/undo.c \
|
||||||
@ -224,6 +225,7 @@ SRC_ALL = \
|
|||||||
src/proto/term.pro \
|
src/proto/term.pro \
|
||||||
src/proto/terminal.pro \
|
src/proto/terminal.pro \
|
||||||
src/proto/termlib.pro \
|
src/proto/termlib.pro \
|
||||||
|
src/proto/testing.pro \
|
||||||
src/proto/textprop.pro \
|
src/proto/textprop.pro \
|
||||||
src/proto/ui.pro \
|
src/proto/ui.pro \
|
||||||
src/proto/undo.pro \
|
src/proto/undo.pro \
|
||||||
|
@ -764,6 +764,7 @@ OBJ = \
|
|||||||
$(OUTDIR)/syntax.o \
|
$(OUTDIR)/syntax.o \
|
||||||
$(OUTDIR)/tag.o \
|
$(OUTDIR)/tag.o \
|
||||||
$(OUTDIR)/term.o \
|
$(OUTDIR)/term.o \
|
||||||
|
$(OUTDIR)/testing.o \
|
||||||
$(OUTDIR)/textprop.o \
|
$(OUTDIR)/textprop.o \
|
||||||
$(OUTDIR)/ui.o \
|
$(OUTDIR)/ui.o \
|
||||||
$(OUTDIR)/undo.o \
|
$(OUTDIR)/undo.o \
|
||||||
|
@ -81,6 +81,8 @@ SRC = arabic.c \
|
|||||||
syntax.c \
|
syntax.c \
|
||||||
tag.c \
|
tag.c \
|
||||||
term.c \
|
term.c \
|
||||||
|
testing.c \
|
||||||
|
textprop.c \
|
||||||
ui.c \
|
ui.c \
|
||||||
undo.c \
|
undo.c \
|
||||||
usercmd.c \
|
usercmd.c \
|
||||||
|
@ -773,6 +773,7 @@ OBJ = \
|
|||||||
$(OUTDIR)\syntax.obj \
|
$(OUTDIR)\syntax.obj \
|
||||||
$(OUTDIR)\tag.obj \
|
$(OUTDIR)\tag.obj \
|
||||||
$(OUTDIR)\term.obj \
|
$(OUTDIR)\term.obj \
|
||||||
|
$(OUTDIR)\testing.obj \
|
||||||
$(OUTDIR)\textprop.obj \
|
$(OUTDIR)\textprop.obj \
|
||||||
$(OUTDIR)\ui.obj \
|
$(OUTDIR)\ui.obj \
|
||||||
$(OUTDIR)\undo.obj \
|
$(OUTDIR)\undo.obj \
|
||||||
@ -1620,6 +1621,8 @@ $(OUTDIR)/tag.obj: $(OUTDIR) tag.c $(INCL)
|
|||||||
|
|
||||||
$(OUTDIR)/term.obj: $(OUTDIR) term.c $(INCL)
|
$(OUTDIR)/term.obj: $(OUTDIR) term.c $(INCL)
|
||||||
|
|
||||||
|
$(OUTDIR)/term.obj: $(OUTDIR) testing.c $(INCL)
|
||||||
|
|
||||||
$(OUTDIR)/textprop.obj: $(OUTDIR) textprop.c $(INCL)
|
$(OUTDIR)/textprop.obj: $(OUTDIR) textprop.c $(INCL)
|
||||||
|
|
||||||
$(OUTDIR)/ui.obj: $(OUTDIR) ui.c $(INCL)
|
$(OUTDIR)/ui.obj: $(OUTDIR) ui.c $(INCL)
|
||||||
@ -1778,6 +1781,7 @@ proto.h: \
|
|||||||
proto/syntax.pro \
|
proto/syntax.pro \
|
||||||
proto/tag.pro \
|
proto/tag.pro \
|
||||||
proto/term.pro \
|
proto/term.pro \
|
||||||
|
proto/testing.pro \
|
||||||
proto/textprop.pro \
|
proto/textprop.pro \
|
||||||
proto/ui.pro \
|
proto/ui.pro \
|
||||||
proto/undo.pro \
|
proto/undo.pro \
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Makefile for Vim on OpenVMS
|
# Makefile for Vim on OpenVMS
|
||||||
#
|
#
|
||||||
# Maintainer: Zoltan Arpadffy <arpadffy@polarhome.com>
|
# Maintainer: Zoltan Arpadffy <arpadffy@polarhome.com>
|
||||||
# Last change: 2019 May 24
|
# Last change: 2019 Jul 14
|
||||||
#
|
#
|
||||||
# This has script been tested on VMS 6.2 to 8.2 on DEC Alpha, VAX and IA64
|
# This has script been tested on VMS 6.2 to 8.2 on DEC Alpha, VAX and IA64
|
||||||
# with MMS and MMK
|
# with MMS and MMK
|
||||||
@ -315,7 +315,7 @@ SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c change.c charset.c \
|
|||||||
menu.c mbyte.c memfile.c memline.c message.c misc1.c misc2.c move.c \
|
menu.c mbyte.c memfile.c memline.c message.c misc1.c misc2.c move.c \
|
||||||
normal.c ops.c option.c popupmnu.c popupwin.c profiler.c quickfix.c \
|
normal.c ops.c option.c popupmnu.c popupwin.c profiler.c quickfix.c \
|
||||||
regexp.c search.c sha256.c sign.c spell.c spellfile.c syntax.c tag.c \
|
regexp.c search.c sha256.c sign.c spell.c spellfile.c syntax.c tag.c \
|
||||||
term.c termlib.c textprop.c ui.c undo.c usercmd.c userfunc.c \
|
term.c termlib.c testing.c textprop.c ui.c undo.c usercmd.c userfunc.c \
|
||||||
version.c screen.c window.c os_unix.c os_vms.c pathdef.c \
|
version.c screen.c window.c os_unix.c os_vms.c pathdef.c \
|
||||||
$(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \
|
$(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \
|
||||||
$(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC)
|
$(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC)
|
||||||
@ -330,7 +330,7 @@ OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj change.
|
|||||||
move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj \
|
move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj \
|
||||||
popupwin.obj profiler.obj quickfix.obj regexp.obj search.obj \
|
popupwin.obj profiler.obj quickfix.obj regexp.obj search.obj \
|
||||||
sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj \
|
sha256.obj sign.obj spell.obj spellfile.obj syntax.obj tag.obj \
|
||||||
term.obj termlib.obj textprop.obj ui.obj undo.obj usercmd.obj \
|
term.obj termlib.obj testing.obj textprop.obj ui.obj undo.obj usercmd.obj \
|
||||||
userfunc.obj screen.obj version.obj window.obj os_unix.obj os_vms.obj \
|
userfunc.obj screen.obj version.obj window.obj os_unix.obj os_vms.obj \
|
||||||
pathdef.obj if_mzsch.obj \
|
pathdef.obj if_mzsch.obj \
|
||||||
$(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \
|
$(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \
|
||||||
@ -745,6 +745,10 @@ termlib.obj : termlib.c vim.h [.auto]config.h feature.h os_unix.h \
|
|||||||
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
|
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
|
||||||
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \
|
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \
|
||||||
|
|
||||||
|
testing.obj : testing.c vim.h [.auto]config.h feature.h os_unix.h \
|
||||||
|
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
|
||||||
|
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \
|
||||||
|
|
||||||
textprop.obj : textprop.c vim.h [.auto]config.h feature.h os_unix.h \
|
textprop.obj : textprop.c vim.h [.auto]config.h feature.h os_unix.h \
|
||||||
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
|
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
|
||||||
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \
|
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \
|
||||||
|
10
src/Makefile
10
src/Makefile
@ -1642,6 +1642,7 @@ BASIC_SRC = \
|
|||||||
tag.c \
|
tag.c \
|
||||||
term.c \
|
term.c \
|
||||||
terminal.c \
|
terminal.c \
|
||||||
|
testing.c \
|
||||||
textprop.c \
|
textprop.c \
|
||||||
ui.c \
|
ui.c \
|
||||||
undo.c \
|
undo.c \
|
||||||
@ -1759,6 +1760,7 @@ OBJ_COMMON = \
|
|||||||
objects/tag.o \
|
objects/tag.o \
|
||||||
objects/term.o \
|
objects/term.o \
|
||||||
objects/terminal.o \
|
objects/terminal.o \
|
||||||
|
objects/testing.o \
|
||||||
objects/textprop.o \
|
objects/textprop.o \
|
||||||
objects/ui.o \
|
objects/ui.o \
|
||||||
objects/undo.o \
|
objects/undo.o \
|
||||||
@ -1902,6 +1904,7 @@ PRO_AUTO = \
|
|||||||
term.pro \
|
term.pro \
|
||||||
terminal.pro \
|
terminal.pro \
|
||||||
termlib.pro \
|
termlib.pro \
|
||||||
|
testing.pro \
|
||||||
textprop.pro \
|
textprop.pro \
|
||||||
ui.pro \
|
ui.pro \
|
||||||
undo.pro \
|
undo.pro \
|
||||||
@ -3271,6 +3274,9 @@ objects/term.o: term.c
|
|||||||
objects/terminal.o: terminal.c $(TERM_DEPS)
|
objects/terminal.o: terminal.c $(TERM_DEPS)
|
||||||
$(CCC) -o $@ terminal.c
|
$(CCC) -o $@ terminal.c
|
||||||
|
|
||||||
|
objects/testing.o: testing.c
|
||||||
|
$(CCC) -o $@ testing.c
|
||||||
|
|
||||||
objects/textprop.o: textprop.c
|
objects/textprop.o: textprop.c
|
||||||
$(CCC) -o $@ textprop.c
|
$(CCC) -o $@ textprop.c
|
||||||
|
|
||||||
@ -3702,6 +3708,10 @@ objects/terminal.o: terminal.c vim.h protodef.h auto/config.h feature.h os_unix.
|
|||||||
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
||||||
proto.h globals.h libvterm/include/vterm.h \
|
proto.h globals.h libvterm/include/vterm.h \
|
||||||
libvterm/include/vterm_keycodes.h
|
libvterm/include/vterm_keycodes.h
|
||||||
|
objects/testing.o: testing.c vim.h protodef.h auto/config.h feature.h os_unix.h \
|
||||||
|
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
|
||||||
|
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
||||||
|
proto.h globals.h
|
||||||
objects/textprop.o: textprop.c vim.h protodef.h auto/config.h feature.h os_unix.h \
|
objects/textprop.o: textprop.c vim.h protodef.h auto/config.h feature.h os_unix.h \
|
||||||
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
|
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
|
||||||
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
|
||||||
|
@ -21,8 +21,8 @@ To jump to a file, move the cursor on its name and use the `gf` command.
|
|||||||
|
|
||||||
Most code can be found in a file with an obvious name (incomplete list):
|
Most code can be found in a file with an obvious name (incomplete list):
|
||||||
|
|
||||||
File name | Description
|
File name | Description
|
||||||
--------- | -----------
|
--------------- | -----------
|
||||||
autocmd.c | autocommands
|
autocmd.c | autocommands
|
||||||
buffer.c | manipulating buffers (loaded files)
|
buffer.c | manipulating buffers (loaded files)
|
||||||
change.c | handling changes to text
|
change.c | handling changes to text
|
||||||
@ -44,6 +44,8 @@ menu.c | menus
|
|||||||
message.c | (error) messages
|
message.c | (error) messages
|
||||||
ops.c | handling operators ("d", "y", "p")
|
ops.c | handling operators ("d", "y", "p")
|
||||||
option.c | options
|
option.c | options
|
||||||
|
popupmnu.c | popup menu
|
||||||
|
popupwin.c | popup window
|
||||||
profiler.c | vim script profiler
|
profiler.c | vim script profiler
|
||||||
quickfix.c | quickfix commands (":make", ":cn")
|
quickfix.c | quickfix commands (":make", ":cn")
|
||||||
regexp.c | pattern matching
|
regexp.c | pattern matching
|
||||||
@ -54,6 +56,8 @@ spell.c | spell checking
|
|||||||
syntax.c | syntax and other highlighting
|
syntax.c | syntax and other highlighting
|
||||||
tag.c | tags
|
tag.c | tags
|
||||||
term.c | terminal handling, termcap codes
|
term.c | terminal handling, termcap codes
|
||||||
|
testing.c | testing: assert and test functions
|
||||||
|
textprop.c | text properties
|
||||||
undo.c | undo and redo
|
undo.c | undo and redo
|
||||||
usercmd.c | user defined commands
|
usercmd.c | user defined commands
|
||||||
userfunc.c | user defined functions
|
userfunc.c | user defined functions
|
||||||
|
506
src/eval.c
506
src/eval.c
@ -3621,7 +3621,7 @@ get_user_var_name(expand_T *xp, int idx)
|
|||||||
* Return TRUE if "pat" matches "text".
|
* Return TRUE if "pat" matches "text".
|
||||||
* Does not use 'cpo' and always uses 'magic'.
|
* Does not use 'cpo' and always uses 'magic'.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
pattern_match(char_u *pat, char_u *text, int ic)
|
pattern_match(char_u *pat, char_u *text, int ic)
|
||||||
{
|
{
|
||||||
int matches = FALSE;
|
int matches = FALSE;
|
||||||
@ -6989,6 +6989,15 @@ set_vim_var_nr(int idx, varnumber_T val)
|
|||||||
vimvars[idx].vv_nr = val;
|
vimvars[idx].vv_nr = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get typval_T v: variable value.
|
||||||
|
*/
|
||||||
|
typval_T *
|
||||||
|
get_vim_var_tv(int idx)
|
||||||
|
{
|
||||||
|
return &vimvars[idx].vv_tv;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get number v: variable value.
|
* Get number v: variable value.
|
||||||
*/
|
*/
|
||||||
@ -9591,30 +9600,6 @@ reset_v_option_vars(void)
|
|||||||
set_vim_var_string(VV_OPTION_COMMAND, NULL, -1);
|
set_vim_var_string(VV_OPTION_COMMAND, NULL, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepare "gap" for an assert error and add the sourcing position.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
prepare_assert_error(garray_T *gap)
|
|
||||||
{
|
|
||||||
char buf[NUMBUFLEN];
|
|
||||||
|
|
||||||
ga_init2(gap, 1, 100);
|
|
||||||
if (sourcing_name != NULL)
|
|
||||||
{
|
|
||||||
ga_concat(gap, sourcing_name);
|
|
||||||
if (sourcing_lnum > 0)
|
|
||||||
ga_concat(gap, (char_u *)" ");
|
|
||||||
}
|
|
||||||
if (sourcing_lnum > 0)
|
|
||||||
{
|
|
||||||
sprintf(buf, "line %ld", (long)sourcing_lnum);
|
|
||||||
ga_concat(gap, (char_u *)buf);
|
|
||||||
}
|
|
||||||
if (sourcing_name != NULL || sourcing_lnum > 0)
|
|
||||||
ga_concat(gap, (char_u *)": ");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add an assert error to v:errors.
|
* Add an assert error to v:errors.
|
||||||
*/
|
*/
|
||||||
@ -9628,477 +9613,6 @@ assert_error(garray_T *gap)
|
|||||||
set_vim_var_list(VV_ERRORS, list_alloc());
|
set_vim_var_list(VV_ERRORS, list_alloc());
|
||||||
list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
|
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;
|
|
||||||
|
|
||||||
if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
|
|
||||||
!= (atype == ASSERT_EQUAL))
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
|
||||||
atype);
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
assert_equalfile(typval_T *argvars)
|
|
||||||
{
|
|
||||||
char_u buf1[NUMBUFLEN];
|
|
||||||
char_u buf2[NUMBUFLEN];
|
|
||||||
char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
|
|
||||||
char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
|
|
||||||
garray_T ga;
|
|
||||||
FILE *fd1;
|
|
||||||
FILE *fd2;
|
|
||||||
|
|
||||||
if (fname1 == NULL || fname2 == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
IObuff[0] = NUL;
|
|
||||||
fd1 = mch_fopen((char *)fname1, READBIN);
|
|
||||||
if (fd1 == NULL)
|
|
||||||
{
|
|
||||||
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fd2 = mch_fopen((char *)fname2, READBIN);
|
|
||||||
if (fd2 == NULL)
|
|
||||||
{
|
|
||||||
fclose(fd1);
|
|
||||||
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int c1, c2;
|
|
||||||
long count = 0;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
c1 = fgetc(fd1);
|
|
||||||
c2 = fgetc(fd2);
|
|
||||||
if (c1 == EOF)
|
|
||||||
{
|
|
||||||
if (c2 != EOF)
|
|
||||||
STRCPY(IObuff, "first file is shorter");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (c2 == EOF)
|
|
||||||
{
|
|
||||||
STRCPY(IObuff, "second file is shorter");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (c1 != c2)
|
|
||||||
{
|
|
||||||
vim_snprintf((char *)IObuff, IOSIZE,
|
|
||||||
"difference at byte %ld", count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
fclose(fd1);
|
|
||||||
fclose(fd2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IObuff[0] != NUL)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
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;
|
|
||||||
char_u buf1[NUMBUFLEN];
|
|
||||||
char_u buf2[NUMBUFLEN];
|
|
||||||
char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
|
|
||||||
char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
|
|
||||||
|
|
||||||
if (pat == NULL || text == NULL)
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
|
||||||
atype);
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
assert_inrange(typval_T *argvars)
|
|
||||||
{
|
|
||||||
garray_T ga;
|
|
||||||
int error = FALSE;
|
|
||||||
char_u *tofree;
|
|
||||||
char msg[200];
|
|
||||||
char_u numbuf[NUMBUFLEN];
|
|
||||||
|
|
||||||
#ifdef FEAT_FLOAT
|
|
||||||
if (argvars[0].v_type == VAR_FLOAT
|
|
||||||
|| argvars[1].v_type == VAR_FLOAT
|
|
||||||
|| argvars[2].v_type == VAR_FLOAT)
|
|
||||||
{
|
|
||||||
float_T flower = tv_get_float(&argvars[0]);
|
|
||||||
float_T fupper = tv_get_float(&argvars[1]);
|
|
||||||
float_T factual = tv_get_float(&argvars[2]);
|
|
||||||
|
|
||||||
if (factual < flower || factual > fupper)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
if (argvars[3].v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
|
|
||||||
vim_free(tofree);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
|
|
||||||
flower, fupper, factual);
|
|
||||||
ga_concat(&ga, (char_u *)msg);
|
|
||||||
}
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
|
|
||||||
varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
|
|
||||||
varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
return 0;
|
|
||||||
if (actual < lower || actual > upper)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
if (argvars[3].v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
|
|
||||||
vim_free(tofree);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
|
|
||||||
(long)lower, (long)upper, (long)actual);
|
|
||||||
ga_concat(&ga, (char_u *)msg);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
garray_T ga;
|
|
||||||
|
|
||||||
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
|
|
||||||
|| (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
|
|
||||||
|| error)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
fill_assert_error(&ga, &argvars[1],
|
|
||||||
(char_u *)(isTrue ? "True" : "False"),
|
|
||||||
NULL, &argvars[0], ASSERT_OTHER);
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
assert_report(typval_T *argvars)
|
|
||||||
{
|
|
||||||
garray_T ga;
|
|
||||||
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
ga_concat(&ga, tv_get_string(&argvars[0]));
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
assert_exception(typval_T *argvars)
|
|
||||||
{
|
|
||||||
garray_T ga;
|
|
||||||
char_u *error = tv_get_string_chk(&argvars[0]);
|
|
||||||
|
|
||||||
if (vimvars[VV_EXCEPTION].vv_str == NULL)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
|
|
||||||
&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 = tv_get_string_chk(&argvars[0]);
|
|
||||||
garray_T ga;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
called_vim_beep = FALSE;
|
|
||||||
suppress_errthrow = TRUE;
|
|
||||||
emsg_silent = FALSE;
|
|
||||||
do_cmdline_cmd(cmd);
|
|
||||||
if (!called_vim_beep)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
ga_concat(&ga, (char_u *)"command did not beep: ");
|
|
||||||
ga_concat(&ga, cmd);
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
suppress_errthrow = FALSE;
|
|
||||||
emsg_on_display = FALSE;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
|
|
||||||
{
|
|
||||||
char_u *tofree;
|
|
||||||
char_u numbuf[NUMBUFLEN];
|
|
||||||
|
|
||||||
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
|
|
||||||
vim_free(tofree);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ga_concat(gap, cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
assert_fails(typval_T *argvars)
|
|
||||||
{
|
|
||||||
char_u *cmd = tv_get_string_chk(&argvars[0]);
|
|
||||||
garray_T ga;
|
|
||||||
int ret = 0;
|
|
||||||
int save_trylevel = trylevel;
|
|
||||||
|
|
||||||
// trylevel must be zero for a ":throw" command to be considered failed
|
|
||||||
trylevel = 0;
|
|
||||||
called_emsg = FALSE;
|
|
||||||
suppress_errthrow = TRUE;
|
|
||||||
emsg_silent = TRUE;
|
|
||||||
|
|
||||||
do_cmdline_cmd(cmd);
|
|
||||||
if (!called_emsg)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
ga_concat(&ga, (char_u *)"command did not fail: ");
|
|
||||||
assert_append_cmd_or_arg(&ga, argvars, cmd);
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
else if (argvars[1].v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
char_u buf[NUMBUFLEN];
|
|
||||||
char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf);
|
|
||||||
|
|
||||||
if (error == NULL
|
|
||||||
|| strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL)
|
|
||||||
{
|
|
||||||
prepare_assert_error(&ga);
|
|
||||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
|
|
||||||
&vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER);
|
|
||||||
ga_concat(&ga, (char_u *)": ");
|
|
||||||
assert_append_cmd_or_arg(&ga, argvars, cmd);
|
|
||||||
assert_error(&ga);
|
|
||||||
ga_clear(&ga);
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trylevel = save_trylevel;
|
|
||||||
called_emsg = FALSE;
|
|
||||||
suppress_errthrow = FALSE;
|
|
||||||
emsg_silent = FALSE;
|
|
||||||
emsg_on_display = FALSE;
|
|
||||||
set_vim_var_string(VV_ERRMSG, NULL, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Append "p[clen]" to "gap", escaping unprintable characters.
|
|
||||||
* Changes NL to \n, CR to \r, etc.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ga_concat_esc(garray_T *gap, char_u *p, int clen)
|
|
||||||
{
|
|
||||||
char_u buf[NUMBUFLEN];
|
|
||||||
|
|
||||||
if (clen > 1)
|
|
||||||
{
|
|
||||||
mch_memmove(buf, p, clen);
|
|
||||||
buf[clen] = NUL;
|
|
||||||
ga_concat(gap, buf);
|
|
||||||
}
|
|
||||||
else switch (*p)
|
|
||||||
{
|
|
||||||
case BS: ga_concat(gap, (char_u *)"\\b"); break;
|
|
||||||
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
|
|
||||||
case FF: ga_concat(gap, (char_u *)"\\f"); break;
|
|
||||||
case NL: ga_concat(gap, (char_u *)"\\n"); break;
|
|
||||||
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
|
|
||||||
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
|
|
||||||
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
|
|
||||||
default:
|
|
||||||
if (*p < ' ')
|
|
||||||
{
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
|
|
||||||
ga_concat(gap, buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ga_append(gap, *p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Append "str" to "gap", escaping unprintable characters.
|
|
||||||
* Changes NL to \n, CR to \r, etc.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ga_concat_shorten_esc(garray_T *gap, char_u *str)
|
|
||||||
{
|
|
||||||
char_u *p;
|
|
||||||
char_u *s;
|
|
||||||
int c;
|
|
||||||
int clen;
|
|
||||||
char_u buf[NUMBUFLEN];
|
|
||||||
int same_len;
|
|
||||||
|
|
||||||
if (str == NULL)
|
|
||||||
{
|
|
||||||
ga_concat(gap, (char_u *)"NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (p = str; *p != NUL; ++p)
|
|
||||||
{
|
|
||||||
same_len = 1;
|
|
||||||
s = p;
|
|
||||||
c = mb_ptr2char_adv(&s);
|
|
||||||
clen = s - p;
|
|
||||||
while (*s != NUL && c == mb_ptr2char(s))
|
|
||||||
{
|
|
||||||
++same_len;
|
|
||||||
s += clen;
|
|
||||||
}
|
|
||||||
if (same_len > 20)
|
|
||||||
{
|
|
||||||
ga_concat(gap, (char_u *)"\\[");
|
|
||||||
ga_concat_esc(gap, p, clen);
|
|
||||||
ga_concat(gap, (char_u *)" occurs ");
|
|
||||||
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
|
|
||||||
ga_concat(gap, buf);
|
|
||||||
ga_concat(gap, (char_u *)" times]");
|
|
||||||
p = s - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ga_concat_esc(gap, p, clen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill "gap" with information about an assert error.
|
|
||||||
*/
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
char_u numbuf[NUMBUFLEN];
|
|
||||||
char_u *tofree;
|
|
||||||
|
|
||||||
if (opt_msg_tv->v_type != VAR_UNKNOWN)
|
|
||||||
{
|
|
||||||
ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
|
|
||||||
vim_free(tofree);
|
|
||||||
ga_concat(gap, (char_u *)": ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
|
|
||||||
ga_concat(gap, (char_u *)"Pattern ");
|
|
||||||
else if (atype == ASSERT_NOTEQUAL)
|
|
||||||
ga_concat(gap, (char_u *)"Expected not equal to ");
|
|
||||||
else
|
|
||||||
ga_concat(gap, (char_u *)"Expected ");
|
|
||||||
if (exp_str == NULL)
|
|
||||||
{
|
|
||||||
ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
|
|
||||||
vim_free(tofree);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ga_concat_shorten_esc(gap, exp_str);
|
|
||||||
if (atype != ASSERT_NOTEQUAL)
|
|
||||||
{
|
|
||||||
if (atype == ASSERT_MATCH)
|
|
||||||
ga_concat(gap, (char_u *)" does not match ");
|
|
||||||
else if (atype == ASSERT_NOTMATCH)
|
|
||||||
ga_concat(gap, (char_u *)" does match ");
|
|
||||||
else
|
|
||||||
ga_concat(gap, (char_u *)" but got ");
|
|
||||||
ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
|
|
||||||
vim_free(tofree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare "typ1" and "typ2". Put the result in "typ1".
|
* Compare "typ1" and "typ2". Put the result in "typ1".
|
||||||
*/
|
*/
|
||||||
|
493
src/evalfunc.c
493
src/evalfunc.c
@ -41,18 +41,6 @@ static void f_argc(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_argidx(typval_T *argvars, typval_T *rettv);
|
static void f_argidx(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_arglistid(typval_T *argvars, typval_T *rettv);
|
static void f_arglistid(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_argv(typval_T *argvars, typval_T *rettv);
|
static void f_argv(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_assert_beeps(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_equal(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_equalfile(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_exception(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_fails(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_false(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_inrange(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_match(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_notequal(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_notmatch(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_report(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_assert_true(typval_T *argvars, typval_T *rettv);
|
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
static void f_asin(typval_T *argvars, typval_T *rettv);
|
static void f_asin(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_atan(typval_T *argvars, typval_T *rettv);
|
static void f_atan(typval_T *argvars, typval_T *rettv);
|
||||||
@ -396,34 +384,6 @@ static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_taglist(typval_T *argvars, typval_T *rettv);
|
static void f_taglist(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_tagfiles(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_tempname(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_autochdir(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_feedinput(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_getvalue(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_option_not_set(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_override(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_refcount(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_garbagecollect_soon(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
|
|
||||||
static void f_test_null_blob(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_GUI
|
|
||||||
static void f_test_scrollbar(typval_T *argvars, typval_T *rettv);
|
|
||||||
#endif
|
|
||||||
#ifdef FEAT_MOUSE
|
|
||||||
static void f_test_setmouse(typval_T *argvars, typval_T *rettv);
|
|
||||||
#endif
|
|
||||||
static void f_test_settime(typval_T *argvars, typval_T *rettv);
|
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
static void f_tan(typval_T *argvars, typval_T *rettv);
|
static void f_tan(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_tanh(typval_T *argvars, typval_T *rettv);
|
static void f_tanh(typval_T *argvars, typval_T *rettv);
|
||||||
@ -1609,114 +1569,6 @@ f_argv(typval_T *argvars, typval_T *rettv)
|
|||||||
get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv);
|
get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* "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[, msg]])" 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
|
#ifdef FEAT_FLOAT
|
||||||
/*
|
/*
|
||||||
* "asin()" function
|
* "asin()" function
|
||||||
@ -13546,351 +13398,6 @@ f_tanh(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_alloc_fail(id, countdown, repeat)" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
if (argvars[0].v_type != VAR_NUMBER
|
|
||||||
|| argvars[0].vval.v_number <= 0
|
|
||||||
|| argvars[1].v_type != VAR_NUMBER
|
|
||||||
|| argvars[1].vval.v_number < 0
|
|
||||||
|| argvars[2].v_type != VAR_NUMBER)
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alloc_fail_id = argvars[0].vval.v_number;
|
|
||||||
if (alloc_fail_id >= aid_last)
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
alloc_fail_countdown = argvars[1].vval.v_number;
|
|
||||||
alloc_fail_repeat = argvars[2].vval.v_number;
|
|
||||||
did_outofmem_msg = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_autochdir()"
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
#if defined(FEAT_AUTOCHDIR)
|
|
||||||
test_autochdir = TRUE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_feedinput()"
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
#ifdef USE_INPUT_BUF
|
|
||||||
char_u *val = tv_get_string_chk(&argvars[0]);
|
|
||||||
|
|
||||||
if (val != NULL)
|
|
||||||
{
|
|
||||||
trash_input_buf();
|
|
||||||
add_to_input_buf_csi(val, (int)STRLEN(val));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_getvalue({name})" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_getvalue(typval_T *argvars, typval_T *rettv)
|
|
||||||
{
|
|
||||||
if (argvars[0].v_type != VAR_STRING)
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char_u *name = tv_get_string(&argvars[0]);
|
|
||||||
|
|
||||||
if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
|
|
||||||
rettv->vval.v_number = need_fileinfo;
|
|
||||||
else
|
|
||||||
semsg(_(e_invarg2), name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_option_not_set({name})" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
char_u *name = (char_u *)"";
|
|
||||||
|
|
||||||
if (argvars[0].v_type != VAR_STRING)
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name = tv_get_string(&argvars[0]);
|
|
||||||
if (reset_option_was_set(name) == FAIL)
|
|
||||||
semsg(_(e_invarg2), name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_override({name}, {val})" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
char_u *name = (char_u *)"";
|
|
||||||
int val;
|
|
||||||
static int save_starting = -1;
|
|
||||||
|
|
||||||
if (argvars[0].v_type != VAR_STRING
|
|
||||||
|| (argvars[1].v_type) != VAR_NUMBER)
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name = tv_get_string(&argvars[0]);
|
|
||||||
val = (int)tv_get_number(&argvars[1]);
|
|
||||||
|
|
||||||
if (STRCMP(name, (char_u *)"redraw") == 0)
|
|
||||||
disable_redraw_for_testing = val;
|
|
||||||
else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
|
|
||||||
ignore_redraw_flag_for_testing = val;
|
|
||||||
else if (STRCMP(name, (char_u *)"char_avail") == 0)
|
|
||||||
disable_char_avail_for_testing = val;
|
|
||||||
else if (STRCMP(name, (char_u *)"starting") == 0)
|
|
||||||
{
|
|
||||||
if (val)
|
|
||||||
{
|
|
||||||
if (save_starting < 0)
|
|
||||||
save_starting = starting;
|
|
||||||
starting = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
starting = save_starting;
|
|
||||||
save_starting = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
|
|
||||||
nfa_fail_for_testing = val;
|
|
||||||
else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
|
|
||||||
no_query_mouse_for_testing = val;
|
|
||||||
else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
|
|
||||||
no_wait_return = val;
|
|
||||||
else if (STRCMP(name, (char_u *)"ALL") == 0)
|
|
||||||
{
|
|
||||||
disable_char_avail_for_testing = FALSE;
|
|
||||||
disable_redraw_for_testing = FALSE;
|
|
||||||
ignore_redraw_flag_for_testing = FALSE;
|
|
||||||
nfa_fail_for_testing = FALSE;
|
|
||||||
no_query_mouse_for_testing = FALSE;
|
|
||||||
if (save_starting >= 0)
|
|
||||||
{
|
|
||||||
starting = save_starting;
|
|
||||||
save_starting = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
semsg(_(e_invarg2), name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_refcount({expr})" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_refcount(typval_T *argvars, typval_T *rettv)
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
|
|
||||||
switch (argvars[0].v_type)
|
|
||||||
{
|
|
||||||
case VAR_UNKNOWN:
|
|
||||||
case VAR_NUMBER:
|
|
||||||
case VAR_FLOAT:
|
|
||||||
case VAR_SPECIAL:
|
|
||||||
case VAR_STRING:
|
|
||||||
break;
|
|
||||||
case VAR_JOB:
|
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
|
||||||
if (argvars[0].vval.v_job != NULL)
|
|
||||||
retval = argvars[0].vval.v_job->jv_refcount - 1;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VAR_CHANNEL:
|
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
|
||||||
if (argvars[0].vval.v_channel != NULL)
|
|
||||||
retval = argvars[0].vval.v_channel->ch_refcount - 1;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VAR_FUNC:
|
|
||||||
if (argvars[0].vval.v_string != NULL)
|
|
||||||
{
|
|
||||||
ufunc_T *fp;
|
|
||||||
|
|
||||||
fp = find_func(argvars[0].vval.v_string);
|
|
||||||
if (fp != NULL)
|
|
||||||
retval = fp->uf_refcount;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VAR_PARTIAL:
|
|
||||||
if (argvars[0].vval.v_partial != NULL)
|
|
||||||
retval = argvars[0].vval.v_partial->pt_refcount - 1;
|
|
||||||
break;
|
|
||||||
case VAR_BLOB:
|
|
||||||
if (argvars[0].vval.v_blob != NULL)
|
|
||||||
retval = argvars[0].vval.v_blob->bv_refcount - 1;
|
|
||||||
break;
|
|
||||||
case VAR_LIST:
|
|
||||||
if (argvars[0].vval.v_list != NULL)
|
|
||||||
retval = argvars[0].vval.v_list->lv_refcount - 1;
|
|
||||||
break;
|
|
||||||
case VAR_DICT:
|
|
||||||
if (argvars[0].vval.v_dict != NULL)
|
|
||||||
retval = argvars[0].vval.v_dict->dv_refcount - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rettv->v_type = VAR_NUMBER;
|
|
||||||
rettv->vval.v_number = retval;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_garbagecollect_soon()" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
may_garbage_collect = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "test_ignore_error()" function
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
ignore_error_for_testing(tv_get_string(&argvars[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv->v_type = VAR_BLOB;
|
|
||||||
rettv->vval.v_blob = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
|
||||||
static void
|
|
||||||
f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv->v_type = VAR_CHANNEL;
|
|
||||||
rettv->vval.v_channel = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv_dict_set(rettv, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FEAT_JOB_CHANNEL
|
|
||||||
static void
|
|
||||||
f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv->v_type = VAR_JOB;
|
|
||||||
rettv->vval.v_job = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv_list_set(rettv, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv->v_type = VAR_PARTIAL;
|
|
||||||
rettv->vval.v_partial = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
|
|
||||||
{
|
|
||||||
rettv->v_type = VAR_STRING;
|
|
||||||
rettv->vval.v_string = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FEAT_GUI
|
|
||||||
static void
|
|
||||||
f_test_scrollbar(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
char_u *which;
|
|
||||||
long value;
|
|
||||||
int dragging;
|
|
||||||
scrollbar_T *sb = NULL;
|
|
||||||
|
|
||||||
if (argvars[0].v_type != VAR_STRING
|
|
||||||
|| (argvars[1].v_type) != VAR_NUMBER
|
|
||||||
|| (argvars[2].v_type) != VAR_NUMBER)
|
|
||||||
{
|
|
||||||
emsg(_(e_invarg));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
which = tv_get_string(&argvars[0]);
|
|
||||||
value = tv_get_number(&argvars[1]);
|
|
||||||
dragging = tv_get_number(&argvars[2]);
|
|
||||||
|
|
||||||
if (STRCMP(which, "left") == 0)
|
|
||||||
sb = &curwin->w_scrollbars[SBAR_LEFT];
|
|
||||||
else if (STRCMP(which, "right") == 0)
|
|
||||||
sb = &curwin->w_scrollbars[SBAR_RIGHT];
|
|
||||||
else if (STRCMP(which, "hor") == 0)
|
|
||||||
sb = &gui.bottom_sbar;
|
|
||||||
if (sb == NULL)
|
|
||||||
{
|
|
||||||
semsg(_(e_invarg2), which);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gui_drag_scrollbar(sb, value, dragging);
|
|
||||||
# ifndef USE_ON_FLY_SCROLL
|
|
||||||
// need to loop through normal_cmd() to handle the scroll events
|
|
||||||
exec_normal(FALSE, TRUE, FALSE);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FEAT_MOUSE
|
|
||||||
static void
|
|
||||||
f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
|
|
||||||
mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
|
|
||||||
{
|
|
||||||
time_for_testing = (time_t)tv_get_number(&argvars[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a callback from "arg". It can be a Funcref or a function name.
|
* Get a callback from "arg". It can be a Funcref or a function name.
|
||||||
* When "arg" is zero return an empty string.
|
* When "arg" is zero return an empty string.
|
||||||
|
@ -202,6 +202,7 @@ void qsort(void *base, size_t elm_count, size_t elm_size, int (*cmp)(const void
|
|||||||
# include "popupwin.pro"
|
# include "popupwin.pro"
|
||||||
# include "textprop.pro"
|
# include "textprop.pro"
|
||||||
# endif
|
# endif
|
||||||
|
# include "testing.pro"
|
||||||
# include "ui.pro"
|
# include "ui.pro"
|
||||||
# include "undo.pro"
|
# include "undo.pro"
|
||||||
# include "usercmd.pro"
|
# include "usercmd.pro"
|
||||||
|
@ -41,6 +41,7 @@ void ex_lockvar(exarg_T *eap);
|
|||||||
int do_unlet(char_u *name, int forceit);
|
int do_unlet(char_u *name, int forceit);
|
||||||
void del_menutrans_vars(void);
|
void del_menutrans_vars(void);
|
||||||
char_u *get_user_var_name(expand_T *xp, int idx);
|
char_u *get_user_var_name(expand_T *xp, int idx);
|
||||||
|
int pattern_match(char_u *pat, char_u *text, int ic);
|
||||||
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate);
|
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate);
|
||||||
int eval1(char_u **arg, typval_T *rettv, int evaluate);
|
int eval1(char_u **arg, typval_T *rettv, int evaluate);
|
||||||
int get_option_tv(char_u **arg, typval_T *rettv, int evaluate);
|
int get_option_tv(char_u **arg, typval_T *rettv, int evaluate);
|
||||||
@ -67,6 +68,7 @@ char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int f
|
|||||||
int eval_isnamec(int c);
|
int eval_isnamec(int c);
|
||||||
int eval_isnamec1(int c);
|
int eval_isnamec1(int c);
|
||||||
void set_vim_var_nr(int idx, varnumber_T val);
|
void set_vim_var_nr(int idx, varnumber_T val);
|
||||||
|
typval_T *get_vim_var_tv(int idx);
|
||||||
varnumber_T get_vim_var_nr(int idx);
|
varnumber_T get_vim_var_nr(int idx);
|
||||||
char_u *get_vim_var_str(int idx);
|
char_u *get_vim_var_str(int idx);
|
||||||
list_T *get_vim_var_list(int idx);
|
list_T *get_vim_var_list(int idx);
|
||||||
@ -129,18 +131,7 @@ void write_viminfo_varlist(FILE *fp);
|
|||||||
int store_session_globals(FILE *fd);
|
int store_session_globals(FILE *fd);
|
||||||
void last_set_msg(sctx_T script_ctx);
|
void last_set_msg(sctx_T script_ctx);
|
||||||
void reset_v_option_vars(void);
|
void reset_v_option_vars(void);
|
||||||
void prepare_assert_error(garray_T *gap);
|
|
||||||
void 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);
|
int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic);
|
||||||
char_u *typval_tostring(typval_T *arg);
|
char_u *typval_tostring(typval_T *arg);
|
||||||
int var_exists(char_u *var);
|
int var_exists(char_u *var);
|
||||||
|
34
src/proto/testing.pro
Normal file
34
src/proto/testing.pro
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* testing.c */
|
||||||
|
void f_assert_beeps(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_equal(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_equalfile(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_notequal(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_exception(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_fails(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_false(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_inrange(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_match(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_notmatch(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_report(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_assert_true(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_alloc_fail(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_autochdir(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_feedinput(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_getvalue(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_option_not_set(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_override(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_refcount(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_garbagecollect_soon(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_blob(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_channel(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_dict(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_job(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_list(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_partial(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_null_string(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_scrollbar(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_setmouse(typval_T *argvars, typval_T *rettv);
|
||||||
|
void f_test_settime(typval_T *argvars, typval_T *rettv);
|
||||||
|
/* vim: set ft=c : */
|
945
src/testing.c
Normal file
945
src/testing.c
Normal file
@ -0,0 +1,945 @@
|
|||||||
|
/* vi:set ts=8 sts=4 sw=4 noet:
|
||||||
|
*
|
||||||
|
* VIM - Vi IMproved by Bram Moolenaar
|
||||||
|
*
|
||||||
|
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||||
|
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||||
|
* See README.txt for an overview of the Vim source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* testing.c: Support for tests.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vim.h"
|
||||||
|
|
||||||
|
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare "gap" for an assert error and add the sourcing position.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
prepare_assert_error(garray_T *gap)
|
||||||
|
{
|
||||||
|
char buf[NUMBUFLEN];
|
||||||
|
|
||||||
|
ga_init2(gap, 1, 100);
|
||||||
|
if (sourcing_name != NULL)
|
||||||
|
{
|
||||||
|
ga_concat(gap, sourcing_name);
|
||||||
|
if (sourcing_lnum > 0)
|
||||||
|
ga_concat(gap, (char_u *)" ");
|
||||||
|
}
|
||||||
|
if (sourcing_lnum > 0)
|
||||||
|
{
|
||||||
|
sprintf(buf, "line %ld", (long)sourcing_lnum);
|
||||||
|
ga_concat(gap, (char_u *)buf);
|
||||||
|
}
|
||||||
|
if (sourcing_name != NULL || sourcing_lnum > 0)
|
||||||
|
ga_concat(gap, (char_u *)": ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append "p[clen]" to "gap", escaping unprintable characters.
|
||||||
|
* Changes NL to \n, CR to \r, etc.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ga_concat_esc(garray_T *gap, char_u *p, int clen)
|
||||||
|
{
|
||||||
|
char_u buf[NUMBUFLEN];
|
||||||
|
|
||||||
|
if (clen > 1)
|
||||||
|
{
|
||||||
|
mch_memmove(buf, p, clen);
|
||||||
|
buf[clen] = NUL;
|
||||||
|
ga_concat(gap, buf);
|
||||||
|
}
|
||||||
|
else switch (*p)
|
||||||
|
{
|
||||||
|
case BS: ga_concat(gap, (char_u *)"\\b"); break;
|
||||||
|
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
|
||||||
|
case FF: ga_concat(gap, (char_u *)"\\f"); break;
|
||||||
|
case NL: ga_concat(gap, (char_u *)"\\n"); break;
|
||||||
|
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
|
||||||
|
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
|
||||||
|
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
|
||||||
|
default:
|
||||||
|
if (*p < ' ')
|
||||||
|
{
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
|
||||||
|
ga_concat(gap, buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ga_append(gap, *p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append "str" to "gap", escaping unprintable characters.
|
||||||
|
* Changes NL to \n, CR to \r, etc.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ga_concat_shorten_esc(garray_T *gap, char_u *str)
|
||||||
|
{
|
||||||
|
char_u *p;
|
||||||
|
char_u *s;
|
||||||
|
int c;
|
||||||
|
int clen;
|
||||||
|
char_u buf[NUMBUFLEN];
|
||||||
|
int same_len;
|
||||||
|
|
||||||
|
if (str == NULL)
|
||||||
|
{
|
||||||
|
ga_concat(gap, (char_u *)"NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = str; *p != NUL; ++p)
|
||||||
|
{
|
||||||
|
same_len = 1;
|
||||||
|
s = p;
|
||||||
|
c = mb_ptr2char_adv(&s);
|
||||||
|
clen = s - p;
|
||||||
|
while (*s != NUL && c == mb_ptr2char(s))
|
||||||
|
{
|
||||||
|
++same_len;
|
||||||
|
s += clen;
|
||||||
|
}
|
||||||
|
if (same_len > 20)
|
||||||
|
{
|
||||||
|
ga_concat(gap, (char_u *)"\\[");
|
||||||
|
ga_concat_esc(gap, p, clen);
|
||||||
|
ga_concat(gap, (char_u *)" occurs ");
|
||||||
|
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
|
||||||
|
ga_concat(gap, buf);
|
||||||
|
ga_concat(gap, (char_u *)" times]");
|
||||||
|
p = s - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ga_concat_esc(gap, p, clen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
char_u numbuf[NUMBUFLEN];
|
||||||
|
char_u *tofree;
|
||||||
|
|
||||||
|
if (opt_msg_tv->v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
|
||||||
|
vim_free(tofree);
|
||||||
|
ga_concat(gap, (char_u *)": ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
|
||||||
|
ga_concat(gap, (char_u *)"Pattern ");
|
||||||
|
else if (atype == ASSERT_NOTEQUAL)
|
||||||
|
ga_concat(gap, (char_u *)"Expected not equal to ");
|
||||||
|
else
|
||||||
|
ga_concat(gap, (char_u *)"Expected ");
|
||||||
|
if (exp_str == NULL)
|
||||||
|
{
|
||||||
|
ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
|
||||||
|
vim_free(tofree);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ga_concat_shorten_esc(gap, exp_str);
|
||||||
|
if (atype != ASSERT_NOTEQUAL)
|
||||||
|
{
|
||||||
|
if (atype == ASSERT_MATCH)
|
||||||
|
ga_concat(gap, (char_u *)" does not match ");
|
||||||
|
else if (atype == ASSERT_NOTMATCH)
|
||||||
|
ga_concat(gap, (char_u *)" does match ");
|
||||||
|
else
|
||||||
|
ga_concat(gap, (char_u *)" but got ");
|
||||||
|
ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
|
||||||
|
vim_free(tofree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
assert_equal_common(typval_T *argvars, assert_type_T atype)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
|
||||||
|
if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
|
||||||
|
!= (atype == ASSERT_EQUAL))
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
||||||
|
atype);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
assert_match_common(typval_T *argvars, assert_type_T atype)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
char_u buf1[NUMBUFLEN];
|
||||||
|
char_u buf2[NUMBUFLEN];
|
||||||
|
char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
|
||||||
|
char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
|
||||||
|
|
||||||
|
if (pat == NULL || text == NULL)
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
||||||
|
atype);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common for assert_true() and assert_false().
|
||||||
|
* Return non-zero for failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
assert_bool(typval_T *argvars, int isTrue)
|
||||||
|
{
|
||||||
|
int error = FALSE;
|
||||||
|
garray_T ga;
|
||||||
|
|
||||||
|
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
|
||||||
|
|| (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
|
||||||
|
|| error)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
fill_assert_error(&ga, &argvars[1],
|
||||||
|
(char_u *)(isTrue ? "True" : "False"),
|
||||||
|
NULL, &argvars[0], ASSERT_OTHER);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
|
||||||
|
{
|
||||||
|
char_u *tofree;
|
||||||
|
char_u numbuf[NUMBUFLEN];
|
||||||
|
|
||||||
|
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
|
||||||
|
vim_free(tofree);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ga_concat(gap, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
assert_beeps(typval_T *argvars)
|
||||||
|
{
|
||||||
|
char_u *cmd = tv_get_string_chk(&argvars[0]);
|
||||||
|
garray_T ga;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
called_vim_beep = FALSE;
|
||||||
|
suppress_errthrow = TRUE;
|
||||||
|
emsg_silent = FALSE;
|
||||||
|
do_cmdline_cmd(cmd);
|
||||||
|
if (!called_vim_beep)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
ga_concat(&ga, (char_u *)"command did not beep: ");
|
||||||
|
ga_concat(&ga, cmd);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
suppress_errthrow = FALSE;
|
||||||
|
emsg_on_display = FALSE;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_beeps(cmd [, error])" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_beeps(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_beeps(argvars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_equal(expected, actual[, msg])" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_equal(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
assert_equalfile(typval_T *argvars)
|
||||||
|
{
|
||||||
|
char_u buf1[NUMBUFLEN];
|
||||||
|
char_u buf2[NUMBUFLEN];
|
||||||
|
char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
|
||||||
|
char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
|
||||||
|
garray_T ga;
|
||||||
|
FILE *fd1;
|
||||||
|
FILE *fd2;
|
||||||
|
|
||||||
|
if (fname1 == NULL || fname2 == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
IObuff[0] = NUL;
|
||||||
|
fd1 = mch_fopen((char *)fname1, READBIN);
|
||||||
|
if (fd1 == NULL)
|
||||||
|
{
|
||||||
|
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fd2 = mch_fopen((char *)fname2, READBIN);
|
||||||
|
if (fd2 == NULL)
|
||||||
|
{
|
||||||
|
fclose(fd1);
|
||||||
|
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int c1, c2;
|
||||||
|
long count = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
c1 = fgetc(fd1);
|
||||||
|
c2 = fgetc(fd2);
|
||||||
|
if (c1 == EOF)
|
||||||
|
{
|
||||||
|
if (c2 != EOF)
|
||||||
|
STRCPY(IObuff, "first file is shorter");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c2 == EOF)
|
||||||
|
{
|
||||||
|
STRCPY(IObuff, "second file is shorter");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c1 != c2)
|
||||||
|
{
|
||||||
|
vim_snprintf((char *)IObuff, IOSIZE,
|
||||||
|
"difference at byte %ld", count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
fclose(fd1);
|
||||||
|
fclose(fd2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IObuff[0] != NUL)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
ga_concat(&ga, IObuff);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_equalfile(fname-one, fname-two)" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_equalfile(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_equalfile(argvars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_notequal(expected, actual[, msg])" function
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_exception(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
char_u *error = tv_get_string_chk(&argvars[0]);
|
||||||
|
|
||||||
|
if (*get_vim_var_str(VV_EXCEPTION) == NUL)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
ga_concat(&ga, (char_u *)"v:exception is not set");
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
rettv->vval.v_number = 1;
|
||||||
|
}
|
||||||
|
else if (error != NULL
|
||||||
|
&& strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
|
||||||
|
get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
rettv->vval.v_number = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_fails(cmd [, error[, msg]])" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_fails(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u *cmd = tv_get_string_chk(&argvars[0]);
|
||||||
|
garray_T ga;
|
||||||
|
int save_trylevel = trylevel;
|
||||||
|
|
||||||
|
// trylevel must be zero for a ":throw" command to be considered failed
|
||||||
|
trylevel = 0;
|
||||||
|
called_emsg = FALSE;
|
||||||
|
suppress_errthrow = TRUE;
|
||||||
|
emsg_silent = TRUE;
|
||||||
|
|
||||||
|
do_cmdline_cmd(cmd);
|
||||||
|
if (!called_emsg)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
ga_concat(&ga, (char_u *)"command did not fail: ");
|
||||||
|
assert_append_cmd_or_arg(&ga, argvars, cmd);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
rettv->vval.v_number = 1;
|
||||||
|
}
|
||||||
|
else if (argvars[1].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
char_u buf[NUMBUFLEN];
|
||||||
|
char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf);
|
||||||
|
|
||||||
|
if (error == NULL
|
||||||
|
|| strstr((char *)get_vim_var_str(VV_ERRMSG), error) == NULL)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
|
||||||
|
get_vim_var_tv(VV_ERRMSG), ASSERT_OTHER);
|
||||||
|
ga_concat(&ga, (char_u *)": ");
|
||||||
|
assert_append_cmd_or_arg(&ga, argvars, cmd);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
rettv->vval.v_number = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trylevel = save_trylevel;
|
||||||
|
called_emsg = FALSE;
|
||||||
|
suppress_errthrow = FALSE;
|
||||||
|
emsg_silent = FALSE;
|
||||||
|
emsg_on_display = FALSE;
|
||||||
|
set_vim_var_string(VV_ERRMSG, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_false(actual[, msg])" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_false(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_bool(argvars, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
assert_inrange(typval_T *argvars)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
int error = FALSE;
|
||||||
|
char_u *tofree;
|
||||||
|
char msg[200];
|
||||||
|
char_u numbuf[NUMBUFLEN];
|
||||||
|
|
||||||
|
#ifdef FEAT_FLOAT
|
||||||
|
if (argvars[0].v_type == VAR_FLOAT
|
||||||
|
|| argvars[1].v_type == VAR_FLOAT
|
||||||
|
|| argvars[2].v_type == VAR_FLOAT)
|
||||||
|
{
|
||||||
|
float_T flower = tv_get_float(&argvars[0]);
|
||||||
|
float_T fupper = tv_get_float(&argvars[1]);
|
||||||
|
float_T factual = tv_get_float(&argvars[2]);
|
||||||
|
|
||||||
|
if (factual < flower || factual > fupper)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
if (argvars[3].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
|
||||||
|
vim_free(tofree);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
|
||||||
|
flower, fupper, factual);
|
||||||
|
ga_concat(&ga, (char_u *)msg);
|
||||||
|
}
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
|
||||||
|
varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
|
||||||
|
varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
return 0;
|
||||||
|
if (actual < lower || actual > upper)
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
if (argvars[3].v_type != VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
|
||||||
|
vim_free(tofree);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
|
||||||
|
(long)lower, (long)upper, (long)actual);
|
||||||
|
ga_concat(&ga, (char_u *)msg);
|
||||||
|
}
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_inrange(lower, upper[, msg])" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_inrange(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_inrange(argvars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_match(pattern, actual[, msg])" function
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_notmatch(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_report(msg)" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_report(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
ga_concat(&ga, tv_get_string(&argvars[0]));
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
rettv->vval.v_number = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_true(actual[, msg])" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_assert_true(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->vval.v_number = assert_bool(argvars, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_alloc_fail(id, countdown, repeat)" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
if (argvars[0].v_type != VAR_NUMBER
|
||||||
|
|| argvars[0].vval.v_number <= 0
|
||||||
|
|| argvars[1].v_type != VAR_NUMBER
|
||||||
|
|| argvars[1].vval.v_number < 0
|
||||||
|
|| argvars[2].v_type != VAR_NUMBER)
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alloc_fail_id = argvars[0].vval.v_number;
|
||||||
|
if (alloc_fail_id >= aid_last)
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
alloc_fail_countdown = argvars[1].vval.v_number;
|
||||||
|
alloc_fail_repeat = argvars[2].vval.v_number;
|
||||||
|
did_outofmem_msg = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_autochdir()"
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
#if defined(FEAT_AUTOCHDIR)
|
||||||
|
test_autochdir = TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_feedinput()"
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
#ifdef USE_INPUT_BUF
|
||||||
|
char_u *val = tv_get_string_chk(&argvars[0]);
|
||||||
|
|
||||||
|
if (val != NULL)
|
||||||
|
{
|
||||||
|
trash_input_buf();
|
||||||
|
add_to_input_buf_csi(val, (int)STRLEN(val));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_getvalue({name})" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_getvalue(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
if (argvars[0].v_type != VAR_STRING)
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char_u *name = tv_get_string(&argvars[0]);
|
||||||
|
|
||||||
|
if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
|
||||||
|
rettv->vval.v_number = need_fileinfo;
|
||||||
|
else
|
||||||
|
semsg(_(e_invarg2), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_option_not_set({name})" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
char_u *name = (char_u *)"";
|
||||||
|
|
||||||
|
if (argvars[0].v_type != VAR_STRING)
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = tv_get_string(&argvars[0]);
|
||||||
|
if (reset_option_was_set(name) == FAIL)
|
||||||
|
semsg(_(e_invarg2), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_override({name}, {val})" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
char_u *name = (char_u *)"";
|
||||||
|
int val;
|
||||||
|
static int save_starting = -1;
|
||||||
|
|
||||||
|
if (argvars[0].v_type != VAR_STRING
|
||||||
|
|| (argvars[1].v_type) != VAR_NUMBER)
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = tv_get_string(&argvars[0]);
|
||||||
|
val = (int)tv_get_number(&argvars[1]);
|
||||||
|
|
||||||
|
if (STRCMP(name, (char_u *)"redraw") == 0)
|
||||||
|
disable_redraw_for_testing = val;
|
||||||
|
else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
|
||||||
|
ignore_redraw_flag_for_testing = val;
|
||||||
|
else if (STRCMP(name, (char_u *)"char_avail") == 0)
|
||||||
|
disable_char_avail_for_testing = val;
|
||||||
|
else if (STRCMP(name, (char_u *)"starting") == 0)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
if (save_starting < 0)
|
||||||
|
save_starting = starting;
|
||||||
|
starting = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
starting = save_starting;
|
||||||
|
save_starting = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
|
||||||
|
nfa_fail_for_testing = val;
|
||||||
|
else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
|
||||||
|
no_query_mouse_for_testing = val;
|
||||||
|
else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
|
||||||
|
no_wait_return = val;
|
||||||
|
else if (STRCMP(name, (char_u *)"ALL") == 0)
|
||||||
|
{
|
||||||
|
disable_char_avail_for_testing = FALSE;
|
||||||
|
disable_redraw_for_testing = FALSE;
|
||||||
|
ignore_redraw_flag_for_testing = FALSE;
|
||||||
|
nfa_fail_for_testing = FALSE;
|
||||||
|
no_query_mouse_for_testing = FALSE;
|
||||||
|
if (save_starting >= 0)
|
||||||
|
{
|
||||||
|
starting = save_starting;
|
||||||
|
save_starting = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
semsg(_(e_invarg2), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_refcount({expr})" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_refcount(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
switch (argvars[0].v_type)
|
||||||
|
{
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
case VAR_NUMBER:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_SPECIAL:
|
||||||
|
case VAR_STRING:
|
||||||
|
break;
|
||||||
|
case VAR_JOB:
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (argvars[0].vval.v_job != NULL)
|
||||||
|
retval = argvars[0].vval.v_job->jv_refcount - 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case VAR_CHANNEL:
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (argvars[0].vval.v_channel != NULL)
|
||||||
|
retval = argvars[0].vval.v_channel->ch_refcount - 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case VAR_FUNC:
|
||||||
|
if (argvars[0].vval.v_string != NULL)
|
||||||
|
{
|
||||||
|
ufunc_T *fp;
|
||||||
|
|
||||||
|
fp = find_func(argvars[0].vval.v_string);
|
||||||
|
if (fp != NULL)
|
||||||
|
retval = fp->uf_refcount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VAR_PARTIAL:
|
||||||
|
if (argvars[0].vval.v_partial != NULL)
|
||||||
|
retval = argvars[0].vval.v_partial->pt_refcount - 1;
|
||||||
|
break;
|
||||||
|
case VAR_BLOB:
|
||||||
|
if (argvars[0].vval.v_blob != NULL)
|
||||||
|
retval = argvars[0].vval.v_blob->bv_refcount - 1;
|
||||||
|
break;
|
||||||
|
case VAR_LIST:
|
||||||
|
if (argvars[0].vval.v_list != NULL)
|
||||||
|
retval = argvars[0].vval.v_list->lv_refcount - 1;
|
||||||
|
break;
|
||||||
|
case VAR_DICT:
|
||||||
|
if (argvars[0].vval.v_dict != NULL)
|
||||||
|
retval = argvars[0].vval.v_dict->dv_refcount - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rettv->v_type = VAR_NUMBER;
|
||||||
|
rettv->vval.v_number = retval;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_garbagecollect_now()" function
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_garbagecollect_soon()" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
may_garbage_collect = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_ignore_error()" function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
ignore_error_for_testing(tv_get_string(&argvars[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_BLOB;
|
||||||
|
rettv->vval.v_blob = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
void
|
||||||
|
f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_CHANNEL;
|
||||||
|
rettv->vval.v_channel = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv_dict_set(rettv, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
void
|
||||||
|
f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_JOB;
|
||||||
|
rettv->vval.v_job = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv_list_set(rettv, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_PARTIAL;
|
||||||
|
rettv->vval.v_partial = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_GUI
|
||||||
|
void
|
||||||
|
f_test_scrollbar(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
char_u *which;
|
||||||
|
long value;
|
||||||
|
int dragging;
|
||||||
|
scrollbar_T *sb = NULL;
|
||||||
|
|
||||||
|
if (argvars[0].v_type != VAR_STRING
|
||||||
|
|| (argvars[1].v_type) != VAR_NUMBER
|
||||||
|
|| (argvars[2].v_type) != VAR_NUMBER)
|
||||||
|
{
|
||||||
|
emsg(_(e_invarg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
which = tv_get_string(&argvars[0]);
|
||||||
|
value = tv_get_number(&argvars[1]);
|
||||||
|
dragging = tv_get_number(&argvars[2]);
|
||||||
|
|
||||||
|
if (STRCMP(which, "left") == 0)
|
||||||
|
sb = &curwin->w_scrollbars[SBAR_LEFT];
|
||||||
|
else if (STRCMP(which, "right") == 0)
|
||||||
|
sb = &curwin->w_scrollbars[SBAR_RIGHT];
|
||||||
|
else if (STRCMP(which, "hor") == 0)
|
||||||
|
sb = &gui.bottom_sbar;
|
||||||
|
if (sb == NULL)
|
||||||
|
{
|
||||||
|
semsg(_(e_invarg2), which);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gui_drag_scrollbar(sb, value, dragging);
|
||||||
|
# ifndef USE_ON_FLY_SCROLL
|
||||||
|
// need to loop through normal_cmd() to handle the scroll events
|
||||||
|
exec_normal(FALSE, TRUE, FALSE);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_MOUSE
|
||||||
|
void
|
||||||
|
f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
|
||||||
|
mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
time_for_testing = (time_t)tv_get_number(&argvars[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // defined(FEAT_EVAL)
|
@ -777,6 +777,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1687,
|
||||||
/**/
|
/**/
|
||||||
1686,
|
1686,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user