blob: 039ee0c9b0b6de53d52f6b68a360e371a295b17f [file] [log] [blame]
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001/* vi:set ts=8 sts=4 sw=4 noet:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * testing.c: Support for tests.
12 */
13
14#include "vim.h"
15
16#if defined(FEAT_EVAL) || defined(PROTO)
17
18/*
19 * Prepare "gap" for an assert error and add the sourcing position.
20 */
21 static void
22prepare_assert_error(garray_T *gap)
23{
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010024 char buf[NUMBUFLEN];
Bram Moolenaar4f25b1a2020-09-10 19:25:05 +020025 char_u *sname = estack_sfile(ESTACK_NONE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020026
27 ga_init2(gap, 1, 100);
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010028 if (sname != NULL)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020029 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010030 ga_concat(gap, sname);
31 if (SOURCING_LNUM > 0)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020032 ga_concat(gap, (char_u *)" ");
33 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010034 if (SOURCING_LNUM > 0)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020035 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010036 sprintf(buf, "line %ld", (long)SOURCING_LNUM);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020037 ga_concat(gap, (char_u *)buf);
38 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010039 if (sname != NULL || SOURCING_LNUM > 0)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020040 ga_concat(gap, (char_u *)": ");
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010041 vim_free(sname);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020042}
43
44/*
45 * Append "p[clen]" to "gap", escaping unprintable characters.
46 * Changes NL to \n, CR to \r, etc.
47 */
48 static void
49ga_concat_esc(garray_T *gap, char_u *p, int clen)
50{
51 char_u buf[NUMBUFLEN];
52
53 if (clen > 1)
54 {
55 mch_memmove(buf, p, clen);
56 buf[clen] = NUL;
57 ga_concat(gap, buf);
58 }
59 else switch (*p)
60 {
61 case BS: ga_concat(gap, (char_u *)"\\b"); break;
62 case ESC: ga_concat(gap, (char_u *)"\\e"); break;
63 case FF: ga_concat(gap, (char_u *)"\\f"); break;
64 case NL: ga_concat(gap, (char_u *)"\\n"); break;
65 case TAB: ga_concat(gap, (char_u *)"\\t"); break;
66 case CAR: ga_concat(gap, (char_u *)"\\r"); break;
67 case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
68 default:
Bram Moolenaar7177da92020-07-12 23:09:20 +020069 if (*p < ' ' || *p == 0x7f)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020070 {
71 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
72 ga_concat(gap, buf);
73 }
74 else
75 ga_append(gap, *p);
76 break;
77 }
78}
79
80/*
81 * Append "str" to "gap", escaping unprintable characters.
82 * Changes NL to \n, CR to \r, etc.
83 */
84 static void
85ga_concat_shorten_esc(garray_T *gap, char_u *str)
86{
87 char_u *p;
88 char_u *s;
89 int c;
90 int clen;
91 char_u buf[NUMBUFLEN];
92 int same_len;
93
94 if (str == NULL)
95 {
96 ga_concat(gap, (char_u *)"NULL");
97 return;
98 }
99
100 for (p = str; *p != NUL; ++p)
101 {
102 same_len = 1;
103 s = p;
Bram Moolenaar34f81172022-02-16 12:16:19 +0000104 c = mb_cptr2char_adv(&s);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200105 clen = s - p;
106 while (*s != NUL && c == mb_ptr2char(s))
107 {
108 ++same_len;
109 s += clen;
110 }
111 if (same_len > 20)
112 {
113 ga_concat(gap, (char_u *)"\\[");
114 ga_concat_esc(gap, p, clen);
115 ga_concat(gap, (char_u *)" occurs ");
116 vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
117 ga_concat(gap, buf);
118 ga_concat(gap, (char_u *)" times]");
119 p = s - 1;
120 }
121 else
122 ga_concat_esc(gap, p, clen);
123 }
124}
125
126/*
127 * Fill "gap" with information about an assert error.
128 */
129 static void
130fill_assert_error(
131 garray_T *gap,
132 typval_T *opt_msg_tv,
133 char_u *exp_str,
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200134 typval_T *exp_tv_arg,
135 typval_T *got_tv_arg,
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200136 assert_type_T atype)
137{
138 char_u numbuf[NUMBUFLEN];
139 char_u *tofree;
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200140 typval_T *exp_tv = exp_tv_arg;
141 typval_T *got_tv = got_tv_arg;
142 int did_copy = FALSE;
143 int omitted = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200144
Bram Moolenaar1d634542020-08-18 13:41:50 +0200145 if (opt_msg_tv->v_type != VAR_UNKNOWN
146 && !(opt_msg_tv->v_type == VAR_STRING
147 && (opt_msg_tv->vval.v_string == NULL
148 || *opt_msg_tv->vval.v_string == NUL)))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200149 {
150 ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
151 vim_free(tofree);
152 ga_concat(gap, (char_u *)": ");
153 }
154
155 if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
156 ga_concat(gap, (char_u *)"Pattern ");
157 else if (atype == ASSERT_NOTEQUAL)
158 ga_concat(gap, (char_u *)"Expected not equal to ");
159 else
160 ga_concat(gap, (char_u *)"Expected ");
161 if (exp_str == NULL)
162 {
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200163 // When comparing dictionaries, drop the items that are equal, so that
164 // it's a lot easier to see what differs.
165 if (atype != ASSERT_NOTEQUAL
166 && exp_tv->v_type == VAR_DICT && got_tv->v_type == VAR_DICT
167 && exp_tv->vval.v_dict != NULL && got_tv->vval.v_dict != NULL)
168 {
169 dict_T *exp_d = exp_tv->vval.v_dict;
170 dict_T *got_d = got_tv->vval.v_dict;
171 hashitem_T *hi;
172 dictitem_T *item2;
173 int todo;
174
175 did_copy = TRUE;
176 exp_tv->vval.v_dict = dict_alloc();
177 got_tv->vval.v_dict = dict_alloc();
178 if (exp_tv->vval.v_dict == NULL || got_tv->vval.v_dict == NULL)
179 return;
180
181 todo = (int)exp_d->dv_hashtab.ht_used;
182 for (hi = exp_d->dv_hashtab.ht_array; todo > 0; ++hi)
183 {
184 if (!HASHITEM_EMPTY(hi))
185 {
186 item2 = dict_find(got_d, hi->hi_key, -1);
187 if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv,
188 &item2->di_tv, FALSE, FALSE))
189 {
190 // item of exp_d not present in got_d or values differ.
191 dict_add_tv(exp_tv->vval.v_dict,
192 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
193 if (item2 != NULL)
194 dict_add_tv(got_tv->vval.v_dict,
195 (char *)hi->hi_key, &item2->di_tv);
196 }
197 else
198 ++omitted;
199 --todo;
200 }
201 }
202
203 // Add items only present in got_d.
204 todo = (int)got_d->dv_hashtab.ht_used;
205 for (hi = got_d->dv_hashtab.ht_array; todo > 0; ++hi)
206 {
207 if (!HASHITEM_EMPTY(hi))
208 {
209 item2 = dict_find(exp_d, hi->hi_key, -1);
210 if (item2 == NULL)
211 // item of got_d not present in exp_d
212 dict_add_tv(got_tv->vval.v_dict,
213 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
214 --todo;
215 }
216 }
217 }
218
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200219 ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
220 vim_free(tofree);
221 }
222 else
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100223 {
224 ga_concat(gap, (char_u *)"'");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200225 ga_concat_shorten_esc(gap, exp_str);
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100226 ga_concat(gap, (char_u *)"'");
227 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200228 if (atype != ASSERT_NOTEQUAL)
229 {
230 if (atype == ASSERT_MATCH)
231 ga_concat(gap, (char_u *)" does not match ");
232 else if (atype == ASSERT_NOTMATCH)
233 ga_concat(gap, (char_u *)" does match ");
234 else
235 ga_concat(gap, (char_u *)" but got ");
236 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
237 vim_free(tofree);
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200238
239 if (omitted != 0)
240 {
241 char buf[100];
242
243 vim_snprintf(buf, 100, " - %d equal item%s omitted",
244 omitted, omitted == 1 ? "" : "s");
245 ga_concat(gap, (char_u *)buf);
246 }
247 }
248
249 if (did_copy)
250 {
251 clear_tv(exp_tv);
252 clear_tv(got_tv);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200253 }
254}
255
256 static int
257assert_equal_common(typval_T *argvars, assert_type_T atype)
258{
259 garray_T ga;
260
261 if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
262 != (atype == ASSERT_EQUAL))
263 {
264 prepare_assert_error(&ga);
265 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
266 atype);
267 assert_error(&ga);
268 ga_clear(&ga);
269 return 1;
270 }
271 return 0;
272}
273
274 static int
275assert_match_common(typval_T *argvars, assert_type_T atype)
276{
277 garray_T ga;
278 char_u buf1[NUMBUFLEN];
279 char_u buf2[NUMBUFLEN];
Bram Moolenaar7177da92020-07-12 23:09:20 +0200280 int called_emsg_before = called_emsg;
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200281 char_u *pat;
282 char_u *text;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200283
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200284 if (in_vim9script()
285 && (check_for_string_arg(argvars, 0) == FAIL
286 || check_for_string_arg(argvars, 1) == FAIL
287 || check_for_opt_string_arg(argvars, 2) == FAIL))
288 return 1;
289
290 pat = tv_get_string_buf_chk(&argvars[0], buf1);
291 text = tv_get_string_buf_chk(&argvars[1], buf2);
Bram Moolenaar7177da92020-07-12 23:09:20 +0200292 if (called_emsg == called_emsg_before
293 && pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200294 {
295 prepare_assert_error(&ga);
296 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
297 atype);
298 assert_error(&ga);
299 ga_clear(&ga);
300 return 1;
301 }
302 return 0;
303}
304
305/*
306 * Common for assert_true() and assert_false().
307 * Return non-zero for failure.
308 */
309 static int
310assert_bool(typval_T *argvars, int isTrue)
311{
312 int error = FALSE;
313 garray_T ga;
314
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +0100315 if (argvars[0].v_type == VAR_BOOL
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200316 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
317 return 0;
318 if (argvars[0].v_type != VAR_NUMBER
319 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
320 || error)
321 {
322 prepare_assert_error(&ga);
323 fill_assert_error(&ga, &argvars[1],
324 (char_u *)(isTrue ? "True" : "False"),
325 NULL, &argvars[0], ASSERT_OTHER);
326 assert_error(&ga);
327 ga_clear(&ga);
328 return 1;
329 }
330 return 0;
331}
332
333 static void
334assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
335{
336 char_u *tofree;
337 char_u numbuf[NUMBUFLEN];
338
339 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
340 {
341 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
342 vim_free(tofree);
343 }
344 else
345 ga_concat(gap, cmd);
346}
347
348 static int
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200349assert_beeps(typval_T *argvars, int no_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200350{
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200351 char_u *cmd;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200352 garray_T ga;
353 int ret = 0;
354
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200355 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
356 return 0;
357
358 cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200359 called_vim_beep = FALSE;
360 suppress_errthrow = TRUE;
361 emsg_silent = FALSE;
362 do_cmdline_cmd(cmd);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200363 if (no_beep ? called_vim_beep : !called_vim_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200364 {
365 prepare_assert_error(&ga);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200366 if (no_beep)
367 ga_concat(&ga, (char_u *)"command did beep: ");
368 else
369 ga_concat(&ga, (char_u *)"command did not beep: ");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200370 ga_concat(&ga, cmd);
371 assert_error(&ga);
372 ga_clear(&ga);
373 ret = 1;
374 }
375
376 suppress_errthrow = FALSE;
377 emsg_on_display = FALSE;
378 return ret;
379}
380
381/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200382 * "assert_beeps(cmd)" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200383 */
384 void
385f_assert_beeps(typval_T *argvars, typval_T *rettv)
386{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200387 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
388 return;
389
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200390 rettv->vval.v_number = assert_beeps(argvars, FALSE);
391}
392
393/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200394 * "assert_nobeep(cmd)" function
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200395 */
396 void
397f_assert_nobeep(typval_T *argvars, typval_T *rettv)
398{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200399 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
400 return;
401
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200402 rettv->vval.v_number = assert_beeps(argvars, TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200403}
404
405/*
406 * "assert_equal(expected, actual[, msg])" function
407 */
408 void
409f_assert_equal(typval_T *argvars, typval_T *rettv)
410{
411 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
412}
413
414 static int
415assert_equalfile(typval_T *argvars)
416{
417 char_u buf1[NUMBUFLEN];
418 char_u buf2[NUMBUFLEN];
Bram Moolenaar7177da92020-07-12 23:09:20 +0200419 int called_emsg_before = called_emsg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200420 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
421 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
422 garray_T ga;
423 FILE *fd1;
424 FILE *fd2;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200425 char line1[200];
426 char line2[200];
427 int lineidx = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200428
Bram Moolenaar7177da92020-07-12 23:09:20 +0200429 if (called_emsg > called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200430 return 0;
431
432 IObuff[0] = NUL;
433 fd1 = mch_fopen((char *)fname1, READBIN);
434 if (fd1 == NULL)
435 {
Bram Moolenaar460ae5d2022-01-01 14:19:49 +0000436 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str, fname1);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200437 }
438 else
439 {
440 fd2 = mch_fopen((char *)fname2, READBIN);
441 if (fd2 == NULL)
442 {
443 fclose(fd1);
Bram Moolenaar460ae5d2022-01-01 14:19:49 +0000444 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str, fname2);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200445 }
446 else
447 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200448 int c1, c2;
449 long count = 0;
450 long linecount = 1;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200451
452 for (;;)
453 {
454 c1 = fgetc(fd1);
455 c2 = fgetc(fd2);
456 if (c1 == EOF)
457 {
458 if (c2 != EOF)
459 STRCPY(IObuff, "first file is shorter");
460 break;
461 }
462 else if (c2 == EOF)
463 {
464 STRCPY(IObuff, "second file is shorter");
465 break;
466 }
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200467 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200468 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200469 line1[lineidx] = c1;
470 line2[lineidx] = c2;
471 ++lineidx;
472 if (c1 != c2)
473 {
474 vim_snprintf((char *)IObuff, IOSIZE,
475 "difference at byte %ld, line %ld",
476 count, linecount);
477 break;
478 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200479 }
480 ++count;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200481 if (c1 == NL)
482 {
483 ++linecount;
484 lineidx = 0;
485 }
486 else if (lineidx + 2 == (int)sizeof(line1))
487 {
488 mch_memmove(line1, line1 + 100, lineidx - 100);
489 mch_memmove(line2, line2 + 100, lineidx - 100);
490 lineidx -= 100;
491 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200492 }
493 fclose(fd1);
494 fclose(fd2);
495 }
496 }
497 if (IObuff[0] != NUL)
498 {
499 prepare_assert_error(&ga);
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200500 if (argvars[2].v_type != VAR_UNKNOWN)
501 {
502 char_u numbuf[NUMBUFLEN];
503 char_u *tofree;
504
505 ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
506 vim_free(tofree);
507 ga_concat(&ga, (char_u *)": ");
508 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200509 ga_concat(&ga, IObuff);
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200510 if (lineidx > 0)
511 {
512 line1[lineidx] = NUL;
513 line2[lineidx] = NUL;
514 ga_concat(&ga, (char_u *)" after \"");
515 ga_concat(&ga, (char_u *)line1);
516 if (STRCMP(line1, line2) != 0)
517 {
518 ga_concat(&ga, (char_u *)"\" vs \"");
519 ga_concat(&ga, (char_u *)line2);
520 }
521 ga_concat(&ga, (char_u *)"\"");
522 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200523 assert_error(&ga);
524 ga_clear(&ga);
525 return 1;
526 }
527 return 0;
528}
529
530/*
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200531 * "assert_equalfile(fname-one, fname-two[, msg])" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200532 */
533 void
534f_assert_equalfile(typval_T *argvars, typval_T *rettv)
535{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200536 if (in_vim9script()
537 && (check_for_string_arg(argvars, 0) == FAIL
538 || check_for_string_arg(argvars, 1) == FAIL
539 || check_for_opt_string_arg(argvars, 2) == FAIL))
540 return;
541
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200542 rettv->vval.v_number = assert_equalfile(argvars);
543}
544
545/*
546 * "assert_notequal(expected, actual[, msg])" function
547 */
548 void
549f_assert_notequal(typval_T *argvars, typval_T *rettv)
550{
551 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
552}
553
554/*
555 * "assert_exception(string[, msg])" function
556 */
557 void
558f_assert_exception(typval_T *argvars, typval_T *rettv)
559{
560 garray_T ga;
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200561 char_u *error;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200562
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200563 if (in_vim9script()
564 && (check_for_string_arg(argvars, 0) == FAIL
565 || check_for_opt_string_arg(argvars, 1) == FAIL))
566 return;
567
568 error = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200569 if (*get_vim_var_str(VV_EXCEPTION) == NUL)
570 {
571 prepare_assert_error(&ga);
572 ga_concat(&ga, (char_u *)"v:exception is not set");
573 assert_error(&ga);
574 ga_clear(&ga);
575 rettv->vval.v_number = 1;
576 }
577 else if (error != NULL
578 && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
579 {
580 prepare_assert_error(&ga);
581 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
582 get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
583 assert_error(&ga);
584 ga_clear(&ga);
585 rettv->vval.v_number = 1;
586 }
587}
588
589/*
590 * "assert_fails(cmd [, error[, msg]])" function
591 */
592 void
593f_assert_fails(typval_T *argvars, typval_T *rettv)
594{
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200595 garray_T ga;
596 int save_trylevel = trylevel;
Bram Moolenaar53989552019-12-23 22:59:18 +0100597 int called_emsg_before = called_emsg;
Bram Moolenaar44d66522020-09-06 22:26:57 +0200598 char *wrong_arg_msg = NULL;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100599 char_u *tofree = NULL;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200600
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200601 if (check_for_string_or_number_arg(argvars, 0) == FAIL
602 || check_for_opt_string_or_list_arg(argvars, 1) == FAIL
603 || (argvars[1].v_type != VAR_UNKNOWN
604 && (argvars[2].v_type != VAR_UNKNOWN
605 && (check_for_opt_number_arg(argvars, 3) == FAIL
606 || (argvars[3].v_type != VAR_UNKNOWN
607 && check_for_opt_string_arg(argvars, 4) == FAIL)))))
608 return;
609
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200610 // trylevel must be zero for a ":throw" command to be considered failed
611 trylevel = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200612 suppress_errthrow = TRUE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100613 in_assert_fails = TRUE;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000614 ++no_wait_return;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200615
Bram Moolenaarf2206432022-11-09 00:44:30 +0000616 char_u *cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200617 do_cmdline_cmd(cmd);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100618
619 // reset here for any errors reported below
620 trylevel = save_trylevel;
621 suppress_errthrow = FALSE;
622
Bram Moolenaar53989552019-12-23 22:59:18 +0100623 if (called_emsg == called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200624 {
625 prepare_assert_error(&ga);
626 ga_concat(&ga, (char_u *)"command did not fail: ");
627 assert_append_cmd_or_arg(&ga, argvars, cmd);
628 assert_error(&ga);
629 ga_clear(&ga);
630 rettv->vval.v_number = 1;
631 }
632 else if (argvars[1].v_type != VAR_UNKNOWN)
633 {
634 char_u buf[NUMBUFLEN];
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200635 char_u *expected;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100636 char_u *expected_str = NULL;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200637 int error_found = FALSE;
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200638 int error_found_index = 1;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200639 char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]"
640 : emsg_assert_fails_msg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200641
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200642 if (argvars[1].v_type == VAR_STRING)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200643 {
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200644 expected = tv_get_string_buf_chk(&argvars[1], buf);
645 error_found = expected == NULL
646 || strstr((char *)actual, (char *)expected) == NULL;
647 }
648 else if (argvars[1].v_type == VAR_LIST)
649 {
650 list_T *list = argvars[1].vval.v_list;
651 typval_T *tv;
652
653 if (list == NULL || list->lv_len < 1 || list->lv_len > 2)
654 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200655 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200656 goto theend;
657 }
658 CHECK_LIST_MATERIALIZE(list);
659 tv = &list->lv_first->li_tv;
660 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100661 if (expected == NULL)
662 goto theend;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200663 if (!pattern_match(expected, actual, FALSE))
664 {
665 error_found = TRUE;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100666 expected_str = expected;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200667 }
668 else if (list->lv_len == 2)
669 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100670 // make a copy, an error in pattern_match() may free it
671 tofree = actual = vim_strsave(get_vim_var_str(VV_ERRMSG));
672 if (actual != NULL)
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100673 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100674 tv = &list->lv_u.mat.lv_last->li_tv;
675 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100676 if (expected == NULL)
677 goto theend;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100678 if (!pattern_match(expected, actual, FALSE))
679 {
680 error_found = TRUE;
681 expected_str = expected;
682 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100683 }
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200684 }
685 }
686 else
687 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200688 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200689 goto theend;
690 }
691
Bram Moolenaar9b02d642020-08-18 23:24:13 +0200692 if (!error_found && argvars[2].v_type != VAR_UNKNOWN
Bram Moolenaar44d66522020-09-06 22:26:57 +0200693 && argvars[3].v_type != VAR_UNKNOWN)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200694 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200695 if (argvars[3].v_type != VAR_NUMBER)
696 {
697 wrong_arg_msg = e_assert_fails_fourth_argument;
698 goto theend;
699 }
700 else if (argvars[3].vval.v_number >= 0
701 && argvars[3].vval.v_number != emsg_assert_fails_lnum)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200702 {
703 error_found = TRUE;
704 error_found_index = 3;
705 }
Bram Moolenaar44d66522020-09-06 22:26:57 +0200706 if (!error_found && argvars[4].v_type != VAR_UNKNOWN)
707 {
708 if (argvars[4].v_type != VAR_STRING)
709 {
710 wrong_arg_msg = e_assert_fails_fifth_argument;
711 goto theend;
712 }
713 else if (argvars[4].vval.v_string != NULL
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200714 && !pattern_match(argvars[4].vval.v_string,
715 emsg_assert_fails_context, FALSE))
Bram Moolenaar44d66522020-09-06 22:26:57 +0200716 {
717 error_found = TRUE;
718 error_found_index = 4;
719 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200720 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200721 }
722
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200723 if (error_found)
724 {
725 typval_T actual_tv;
726
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200727 prepare_assert_error(&ga);
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200728 if (error_found_index == 3)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200729 {
730 actual_tv.v_type = VAR_NUMBER;
731 actual_tv.vval.v_number = emsg_assert_fails_lnum;
732 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200733 else if (error_found_index == 4)
734 {
735 actual_tv.v_type = VAR_STRING;
736 actual_tv.vval.v_string = emsg_assert_fails_context;
737 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200738 else
739 {
740 actual_tv.v_type = VAR_STRING;
741 actual_tv.vval.v_string = actual;
742 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100743 fill_assert_error(&ga, &argvars[2], expected_str,
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200744 &argvars[error_found_index], &actual_tv, ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200745 ga_concat(&ga, (char_u *)": ");
746 assert_append_cmd_or_arg(&ga, argvars, cmd);
747 assert_error(&ga);
748 ga_clear(&ga);
749 rettv->vval.v_number = 1;
750 }
751 }
752
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200753theend:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200754 trylevel = save_trylevel;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200755 suppress_errthrow = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100756 in_assert_fails = FALSE;
757 did_emsg = FALSE;
Bram Moolenaar8bea1712022-06-15 20:49:35 +0100758 got_int = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100759 msg_col = 0;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000760 --no_wait_return;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100761 need_wait_return = FALSE;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200762 emsg_on_display = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100763 msg_scrolled = 0;
764 lines_left = Rows;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200765 VIM_CLEAR(emsg_assert_fails_msg);
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100766 vim_free(tofree);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200767 set_vim_var_string(VV_ERRMSG, NULL, 0);
Bram Moolenaar44d66522020-09-06 22:26:57 +0200768 if (wrong_arg_msg != NULL)
769 emsg(_(wrong_arg_msg));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200770}
771
772/*
773 * "assert_false(actual[, msg])" function
774 */
775 void
776f_assert_false(typval_T *argvars, typval_T *rettv)
777{
778 rettv->vval.v_number = assert_bool(argvars, FALSE);
779}
780
781 static int
782assert_inrange(typval_T *argvars)
783{
784 garray_T ga;
785 int error = FALSE;
786 char_u *tofree;
787 char msg[200];
788 char_u numbuf[NUMBUFLEN];
789
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200790 if (argvars[0].v_type == VAR_FLOAT
791 || argvars[1].v_type == VAR_FLOAT
792 || argvars[2].v_type == VAR_FLOAT)
793 {
794 float_T flower = tv_get_float(&argvars[0]);
795 float_T fupper = tv_get_float(&argvars[1]);
796 float_T factual = tv_get_float(&argvars[2]);
797
798 if (factual < flower || factual > fupper)
799 {
800 prepare_assert_error(&ga);
801 if (argvars[3].v_type != VAR_UNKNOWN)
802 {
803 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
804 vim_free(tofree);
805 }
806 else
807 {
808 vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
809 flower, fupper, factual);
810 ga_concat(&ga, (char_u *)msg);
811 }
812 assert_error(&ga);
813 ga_clear(&ga);
814 return 1;
815 }
816 }
817 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200818 {
819 varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
820 varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
821 varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
822
823 if (error)
824 return 0;
825 if (actual < lower || actual > upper)
826 {
827 prepare_assert_error(&ga);
828 if (argvars[3].v_type != VAR_UNKNOWN)
829 {
830 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
831 vim_free(tofree);
832 }
833 else
834 {
835 vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
836 (long)lower, (long)upper, (long)actual);
837 ga_concat(&ga, (char_u *)msg);
838 }
839 assert_error(&ga);
840 ga_clear(&ga);
841 return 1;
842 }
843 }
844 return 0;
845}
846
847/*
848 * "assert_inrange(lower, upper[, msg])" function
849 */
850 void
851f_assert_inrange(typval_T *argvars, typval_T *rettv)
852{
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200853 if (check_for_float_or_nr_arg(argvars, 0) == FAIL
854 || check_for_float_or_nr_arg(argvars, 1) == FAIL
855 || check_for_float_or_nr_arg(argvars, 2) == FAIL
856 || check_for_opt_string_arg(argvars, 3) == FAIL)
857 return;
858
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200859 rettv->vval.v_number = assert_inrange(argvars);
860}
861
862/*
863 * "assert_match(pattern, actual[, msg])" function
864 */
865 void
866f_assert_match(typval_T *argvars, typval_T *rettv)
867{
868 rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
869}
870
871/*
872 * "assert_notmatch(pattern, actual[, msg])" function
873 */
874 void
875f_assert_notmatch(typval_T *argvars, typval_T *rettv)
876{
877 rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
878}
879
880/*
881 * "assert_report(msg)" function
882 */
883 void
884f_assert_report(typval_T *argvars, typval_T *rettv)
885{
886 garray_T ga;
887
Yegappan Lakshmananc72bdd22021-07-11 19:44:18 +0200888 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
889 return;
890
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200891 prepare_assert_error(&ga);
892 ga_concat(&ga, tv_get_string(&argvars[0]));
893 assert_error(&ga);
894 ga_clear(&ga);
895 rettv->vval.v_number = 1;
896}
897
898/*
899 * "assert_true(actual[, msg])" function
900 */
901 void
902f_assert_true(typval_T *argvars, typval_T *rettv)
903{
904 rettv->vval.v_number = assert_bool(argvars, TRUE);
905}
906
907/*
908 * "test_alloc_fail(id, countdown, repeat)" function
909 */
910 void
911f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
912{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200913 if (in_vim9script()
914 && (check_for_number_arg(argvars, 0) == FAIL
915 || check_for_number_arg(argvars, 1) == FAIL
916 || check_for_number_arg(argvars, 2) == FAIL))
917 return;
918
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200919 if (argvars[0].v_type != VAR_NUMBER
920 || argvars[0].vval.v_number <= 0
921 || argvars[1].v_type != VAR_NUMBER
922 || argvars[1].vval.v_number < 0
923 || argvars[2].v_type != VAR_NUMBER)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000924 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200925 else
926 {
927 alloc_fail_id = argvars[0].vval.v_number;
928 if (alloc_fail_id >= aid_last)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000929 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200930 alloc_fail_countdown = argvars[1].vval.v_number;
931 alloc_fail_repeat = argvars[2].vval.v_number;
932 did_outofmem_msg = FALSE;
933 }
934}
935
936/*
937 * "test_autochdir()"
938 */
939 void
940f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
941{
942#if defined(FEAT_AUTOCHDIR)
943 test_autochdir = TRUE;
944#endif
945}
946
947/*
948 * "test_feedinput()"
949 */
950 void
951f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
952{
953#ifdef USE_INPUT_BUF
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200954 char_u *val;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200955
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200956 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
957 return;
958
959 val = tv_get_string_chk(&argvars[0]);
Bram Moolenaar272ca952020-01-28 20:49:11 +0100960# ifdef VIMDLL
961 // this doesn't work in the console
962 if (!gui.in_use)
963 return;
964# endif
965
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200966 if (val != NULL)
967 {
968 trash_input_buf();
969 add_to_input_buf_csi(val, (int)STRLEN(val));
970 }
971#endif
972}
973
974/*
975 * "test_getvalue({name})" function
976 */
977 void
978f_test_getvalue(typval_T *argvars, typval_T *rettv)
979{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100980 char_u *name;
981
982 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200983 return;
984
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100985 name = tv_get_string(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200986
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100987 if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
988 rettv->vval.v_number = need_fileinfo;
989 else
990 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200991}
992
993/*
994 * "test_option_not_set({name})" function
995 */
996 void
997f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
998{
999 char_u *name = (char_u *)"";
1000
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001001 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001002 return;
1003
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001004 name = tv_get_string(&argvars[0]);
1005 if (reset_option_was_set(name) == FAIL)
1006 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001007}
1008
1009/*
1010 * "test_override({name}, {val})" function
1011 */
1012 void
1013f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
1014{
1015 char_u *name = (char_u *)"";
1016 int val;
1017 static int save_starting = -1;
1018
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001019 if (check_for_string_arg(argvars, 0) == FAIL
1020 || check_for_number_arg(argvars, 1) == FAIL)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02001021 return;
1022
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001023 name = tv_get_string(&argvars[0]);
1024 val = (int)tv_get_number(&argvars[1]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001025
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001026 if (STRCMP(name, (char_u *)"redraw") == 0)
1027 disable_redraw_for_testing = val;
1028 else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
1029 ignore_redraw_flag_for_testing = val;
1030 else if (STRCMP(name, (char_u *)"char_avail") == 0)
1031 disable_char_avail_for_testing = val;
1032 else if (STRCMP(name, (char_u *)"starting") == 0)
1033 {
1034 if (val)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001035 {
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001036 if (save_starting < 0)
1037 save_starting = starting;
1038 starting = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001039 }
1040 else
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001041 {
1042 starting = save_starting;
1043 save_starting = -1;
1044 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001045 }
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001046 else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
1047 nfa_fail_for_testing = val;
1048 else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
1049 no_query_mouse_for_testing = val;
1050 else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
1051 no_wait_return = val;
1052 else if (STRCMP(name, (char_u *)"ui_delay") == 0)
1053 ui_delay_for_testing = val;
1054 else if (STRCMP(name, (char_u *)"term_props") == 0)
1055 reset_term_props_on_termresponse = val;
1056 else if (STRCMP(name, (char_u *)"vterm_title") == 0)
1057 disable_vterm_title_for_testing = val;
1058 else if (STRCMP(name, (char_u *)"uptime") == 0)
1059 override_sysinfo_uptime = val;
1060 else if (STRCMP(name, (char_u *)"alloc_lines") == 0)
1061 ml_get_alloc_lines = val;
1062 else if (STRCMP(name, (char_u *)"autoload") == 0)
1063 override_autoload = val;
1064 else if (STRCMP(name, (char_u *)"ALL") == 0)
1065 {
1066 disable_char_avail_for_testing = FALSE;
1067 disable_redraw_for_testing = FALSE;
1068 ignore_redraw_flag_for_testing = FALSE;
1069 nfa_fail_for_testing = FALSE;
1070 no_query_mouse_for_testing = FALSE;
1071 ui_delay_for_testing = 0;
1072 reset_term_props_on_termresponse = FALSE;
1073 override_sysinfo_uptime = -1;
1074 // ml_get_alloc_lines is not reset by "ALL"
1075 if (save_starting >= 0)
1076 {
1077 starting = save_starting;
1078 save_starting = -1;
1079 }
1080 }
1081 else
1082 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001083}
1084
1085/*
1086 * "test_refcount({expr})" function
1087 */
1088 void
1089f_test_refcount(typval_T *argvars, typval_T *rettv)
1090{
1091 int retval = -1;
1092
1093 switch (argvars[0].v_type)
1094 {
1095 case VAR_UNKNOWN:
Bram Moolenaar4c683752020-04-05 21:38:23 +02001096 case VAR_ANY:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001097 case VAR_VOID:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001098 case VAR_NUMBER:
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +01001099 case VAR_BOOL:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001100 case VAR_FLOAT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001101 case VAR_SPECIAL:
1102 case VAR_STRING:
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001103 case VAR_INSTR:
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001104 case VAR_CLASS:
1105 case VAR_OBJECT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001106 break;
1107 case VAR_JOB:
1108#ifdef FEAT_JOB_CHANNEL
1109 if (argvars[0].vval.v_job != NULL)
1110 retval = argvars[0].vval.v_job->jv_refcount - 1;
1111#endif
1112 break;
1113 case VAR_CHANNEL:
1114#ifdef FEAT_JOB_CHANNEL
1115 if (argvars[0].vval.v_channel != NULL)
1116 retval = argvars[0].vval.v_channel->ch_refcount - 1;
1117#endif
1118 break;
1119 case VAR_FUNC:
1120 if (argvars[0].vval.v_string != NULL)
1121 {
1122 ufunc_T *fp;
1123
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00001124 fp = find_func(argvars[0].vval.v_string, FALSE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001125 if (fp != NULL)
1126 retval = fp->uf_refcount;
1127 }
1128 break;
1129 case VAR_PARTIAL:
1130 if (argvars[0].vval.v_partial != NULL)
1131 retval = argvars[0].vval.v_partial->pt_refcount - 1;
1132 break;
1133 case VAR_BLOB:
1134 if (argvars[0].vval.v_blob != NULL)
1135 retval = argvars[0].vval.v_blob->bv_refcount - 1;
1136 break;
1137 case VAR_LIST:
1138 if (argvars[0].vval.v_list != NULL)
1139 retval = argvars[0].vval.v_list->lv_refcount - 1;
1140 break;
1141 case VAR_DICT:
1142 if (argvars[0].vval.v_dict != NULL)
1143 retval = argvars[0].vval.v_dict->dv_refcount - 1;
1144 break;
1145 }
1146
1147 rettv->v_type = VAR_NUMBER;
1148 rettv->vval.v_number = retval;
1149
1150}
1151
1152/*
1153 * "test_garbagecollect_now()" function
1154 */
1155 void
1156f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1157{
Bram Moolenaar0d6f5d92019-12-05 21:33:15 +01001158 // This is dangerous, any Lists and Dicts used internally may be freed
1159 // while still in use.
Bram Moolenaarb3d83982022-01-27 19:59:47 +00001160 if (!get_vim_var_nr(VV_TESTING))
1161 emsg(_(e_calling_test_garbagecollect_now_while_v_testing_is_not_set));
1162 else
1163 garbage_collect(TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001164}
1165
1166/*
1167 * "test_garbagecollect_soon()" function
1168 */
1169 void
1170f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1171{
1172 may_garbage_collect = TRUE;
1173}
1174
1175/*
1176 * "test_ignore_error()" function
1177 */
1178 void
1179f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
1180{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001181 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001182 return;
1183
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001184 ignore_error_for_testing(tv_get_string(&argvars[0]));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001185}
1186
1187 void
1188f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
1189{
1190 rettv->v_type = VAR_BLOB;
1191 rettv->vval.v_blob = NULL;
1192}
1193
1194#ifdef FEAT_JOB_CHANNEL
1195 void
1196f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
1197{
1198 rettv->v_type = VAR_CHANNEL;
1199 rettv->vval.v_channel = NULL;
1200}
1201#endif
1202
1203 void
1204f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
1205{
1206 rettv_dict_set(rettv, NULL);
1207}
1208
1209#ifdef FEAT_JOB_CHANNEL
1210 void
1211f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
1212{
1213 rettv->v_type = VAR_JOB;
1214 rettv->vval.v_job = NULL;
1215}
1216#endif
1217
1218 void
1219f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
1220{
1221 rettv_list_set(rettv, NULL);
1222}
1223
1224 void
Bram Moolenaare69f6d02020-04-01 22:11:01 +02001225f_test_null_function(typval_T *argvars UNUSED, typval_T *rettv)
1226{
1227 rettv->v_type = VAR_FUNC;
1228 rettv->vval.v_string = NULL;
1229}
1230
1231 void
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001232f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
1233{
1234 rettv->v_type = VAR_PARTIAL;
1235 rettv->vval.v_partial = NULL;
1236}
1237
1238 void
1239f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
1240{
1241 rettv->v_type = VAR_STRING;
1242 rettv->vval.v_string = NULL;
1243}
1244
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001245 void
1246f_test_unknown(typval_T *argvars UNUSED, typval_T *rettv)
1247{
1248 rettv->v_type = VAR_UNKNOWN;
1249}
1250
1251 void
1252f_test_void(typval_T *argvars UNUSED, typval_T *rettv)
1253{
1254 rettv->v_type = VAR_VOID;
1255}
1256
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001257 void
1258f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
1259{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001260 if (in_vim9script()
1261 && (check_for_number_arg(argvars, 0) == FAIL
1262 || check_for_number_arg(argvars, 1) == FAIL))
1263 return;
1264
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001265 if (argvars[0].v_type != VAR_NUMBER || argvars[1].v_type != VAR_NUMBER)
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001266 {
Bram Moolenaar436b5ad2021-12-31 22:49:24 +00001267 emsg(_(e_invalid_argument));
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001268 return;
1269 }
1270
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001271 mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
1272 mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
1273}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001274
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001275# ifdef FEAT_GUI
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001276 static int
1277test_gui_drop_files(dict_T *args UNUSED)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001278{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001279# if defined(HAVE_DROP_FILE)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001280 int row;
1281 int col;
1282 int_u mods;
1283 char_u **fnames;
1284 int count = 0;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001285 typval_T t;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001286 list_T *l;
1287 listitem_T *li;
1288
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001289 if (!dict_has_key(args, "files")
1290 || !dict_has_key(args, "row")
1291 || !dict_has_key(args, "col")
1292 || !dict_has_key(args, "modifiers"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001293 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001294
Bram Moolenaard61efa52022-07-23 09:52:04 +01001295 (void)dict_get_tv(args, "files", &t);
1296 row = (int)dict_get_number(args, "row");
1297 col = (int)dict_get_number(args, "col");
1298 mods = (int)dict_get_number(args, "modifiers");
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001299
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001300 if (t.v_type != VAR_LIST || list_len(t.vval.v_list) == 0)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001301 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001302
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001303 l = t.vval.v_list;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001304 fnames = ALLOC_MULT(char_u *, list_len(l));
1305 if (fnames == NULL)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001306 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001307
1308 FOR_ALL_LIST_ITEMS(l, li)
1309 {
1310 // ignore non-string items
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001311 if (li->li_tv.v_type != VAR_STRING
1312 || li->li_tv.vval.v_string == NULL)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001313 continue;
1314
1315 fnames[count] = vim_strsave(li->li_tv.vval.v_string);
1316 if (fnames[count] == NULL)
1317 {
1318 while (--count >= 0)
1319 vim_free(fnames[count]);
1320 vim_free(fnames);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001321 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001322 }
1323 count++;
1324 }
1325
1326 if (count > 0)
1327 gui_handle_drop(TEXT_X(col - 1), TEXT_Y(row - 1), mods, fnames, count);
1328 else
1329 vim_free(fnames);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001330# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001331
1332 return TRUE;
1333}
1334
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001335#if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001336 static int
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001337test_gui_find_repl(dict_T *args)
1338{
1339 int flags;
1340 char_u *find_text;
1341 char_u *repl_text;
1342 int forward;
1343 int retval;
1344
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001345 if (!dict_has_key(args, "find_text")
1346 || !dict_has_key(args, "repl_text")
1347 || !dict_has_key(args, "flags")
1348 || !dict_has_key(args, "forward"))
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001349 return FALSE;
1350
Bram Moolenaard61efa52022-07-23 09:52:04 +01001351 find_text = dict_get_string(args, "find_text", TRUE);
1352 repl_text = dict_get_string(args, "repl_text", TRUE);
1353 flags = (int)dict_get_number(args, "flags");
1354 forward = (int)dict_get_number(args, "forward");
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001355
1356 retval = gui_do_findrepl(flags, find_text, repl_text, forward);
1357 vim_free(find_text);
1358 vim_free(repl_text);
1359
1360 return retval;
1361}
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001362#endif
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001363
1364 static int
1365test_gui_mouse_event(dict_T *args)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001366{
1367 int button;
1368 int row;
1369 int col;
1370 int repeated_click;
1371 int_u mods;
Ernie Raelc4cb5442022-04-03 15:47:28 +01001372 int move;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001373
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001374 if (!dict_has_key(args, "row")
1375 || !dict_has_key(args, "col"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001376 return FALSE;
1377
Ernie Raelc4cb5442022-04-03 15:47:28 +01001378 // Note: "move" is optional, requires fewer arguments
Bram Moolenaard61efa52022-07-23 09:52:04 +01001379 move = (int)dict_get_bool(args, "move", FALSE);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001380
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001381 if (!move && (!dict_has_key(args, "button")
1382 || !dict_has_key(args, "multiclick")
1383 || !dict_has_key(args, "modifiers")))
Ernie Raelc4cb5442022-04-03 15:47:28 +01001384 return FALSE;
1385
Bram Moolenaard61efa52022-07-23 09:52:04 +01001386 row = (int)dict_get_number(args, "row");
1387 col = (int)dict_get_number(args, "col");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001388
Ernie Raelc4cb5442022-04-03 15:47:28 +01001389 if (move)
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001390 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001391 int pY = row;
1392 int pX = col;
1393 // the "move" argument expects row and col coordnates to be in pixels,
1394 // unless "cell" is specified and is TRUE.
Bram Moolenaard61efa52022-07-23 09:52:04 +01001395 if (dict_get_bool(args, "cell", FALSE))
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001396 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001397 // calculate the middle of the character cell
1398 // Note: Cell coordinates are 1-based from vimscript
1399 pY = (row - 1) * gui.char_height + gui.char_height / 2;
1400 pX = (col - 1) * gui.char_width + gui.char_width / 2;
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001401 }
Christopher Plewright20b795e2022-12-20 20:01:58 +00001402 gui_mouse_moved(pX, pY);
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001403 }
Ernie Raelc4cb5442022-04-03 15:47:28 +01001404 else
1405 {
Bram Moolenaard61efa52022-07-23 09:52:04 +01001406 button = (int)dict_get_number(args, "button");
1407 repeated_click = (int)dict_get_number(args, "multiclick");
1408 mods = (int)dict_get_number(args, "modifiers");
Ernie Raelc4cb5442022-04-03 15:47:28 +01001409
LemonBoyc27747e2022-05-07 12:25:40 +01001410 // Reset the scroll values to known values.
1411 // XXX: Remove this when/if the scroll step is made configurable.
1412 mouse_set_hor_scroll_step(6);
1413 mouse_set_vert_scroll_step(3);
1414
Ernie Raelc4cb5442022-04-03 15:47:28 +01001415 gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1),
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001416 repeated_click, mods);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001417 }
1418
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001419 return TRUE;
1420}
1421
1422 static int
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001423test_gui_scrollbar(dict_T *args)
1424{
1425 char_u *which;
1426 long value;
1427 int dragging;
1428 scrollbar_T *sb = NULL;
1429
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001430 if (!dict_has_key(args, "which")
1431 || !dict_has_key(args, "value")
1432 || !dict_has_key(args, "dragging"))
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001433 return FALSE;
1434
Bram Moolenaard61efa52022-07-23 09:52:04 +01001435 which = dict_get_string(args, "which", FALSE);
1436 value = (long)dict_get_number(args, "value");
1437 dragging = (int)dict_get_number(args, "dragging");
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001438
1439 if (STRCMP(which, "left") == 0)
1440 sb = &curwin->w_scrollbars[SBAR_LEFT];
1441 else if (STRCMP(which, "right") == 0)
1442 sb = &curwin->w_scrollbars[SBAR_RIGHT];
1443 else if (STRCMP(which, "hor") == 0)
1444 sb = &gui.bottom_sbar;
1445 if (sb == NULL)
1446 {
1447 semsg(_(e_invalid_argument_str), which);
1448 return FALSE;
1449 }
1450 gui_drag_scrollbar(sb, value, dragging);
1451# ifndef USE_ON_FLY_SCROLL
1452 // need to loop through normal_cmd() to handle the scroll events
1453 exec_normal(FALSE, TRUE, FALSE);
1454# endif
1455
1456 return TRUE;
1457}
1458
1459 static int
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001460test_gui_tabline_event(dict_T *args UNUSED)
1461{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001462# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001463 int tabnr;
1464
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001465 if (!dict_has_key(args, "tabnr"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001466 return FALSE;
1467
Bram Moolenaard61efa52022-07-23 09:52:04 +01001468 tabnr = (int)dict_get_number(args, "tabnr");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001469
1470 return send_tabline_event(tabnr);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001471# else
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001472 return FALSE;
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001473# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001474}
1475
1476 static int
1477test_gui_tabmenu_event(dict_T *args UNUSED)
1478{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001479# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001480 int tabnr;
1481 int item;
1482
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001483 if (!dict_has_key(args, "tabnr")
1484 || !dict_has_key(args, "item"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001485 return FALSE;
1486
Bram Moolenaard61efa52022-07-23 09:52:04 +01001487 tabnr = (int)dict_get_number(args, "tabnr");
1488 item = (int)dict_get_number(args, "item");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001489
1490 send_tabline_menu_event(tabnr, item);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001491# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001492 return TRUE;
1493}
1494# endif
1495
1496 void
Christopher Plewright20b795e2022-12-20 20:01:58 +00001497f_test_mswin_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1498{
1499# ifdef MSWIN
1500 rettv->v_type = VAR_BOOL;
1501 rettv->vval.v_number = FALSE;
1502
1503 if (sandbox != 0)
1504 {
1505 emsg(_(e_not_allowed_in_sandbox));
1506 return;
1507 }
1508
1509 if (check_for_string_arg(argvars, 0) == FAIL
1510 || check_for_dict_arg(argvars, 1) == FAIL
1511 || argvars[1].vval.v_dict == NULL)
1512 return;
1513
1514 char_u *event = tv_get_string(&argvars[0]);
1515 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1516
1517# endif
1518}
1519
1520 void
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001521f_test_gui_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1522{
1523# ifdef FEAT_GUI
1524 char_u *event;
1525
1526 rettv->v_type = VAR_BOOL;
1527 rettv->vval.v_number = FALSE;
1528
Yegappan Lakshmanan81a3ff92022-07-23 05:04:16 +01001529 if (sandbox != 0)
1530 {
1531 emsg(_(e_not_allowed_in_sandbox));
1532 return;
1533 }
1534
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001535 if (check_for_string_arg(argvars, 0) == FAIL
1536 || check_for_dict_arg(argvars, 1) == FAIL
1537 || argvars[1].vval.v_dict == NULL)
1538 return;
1539
1540 event = tv_get_string(&argvars[0]);
1541 if (STRCMP(event, "dropfiles") == 0)
1542 rettv->vval.v_number = test_gui_drop_files(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001543# if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001544 else if (STRCMP(event, "findrepl") == 0)
1545 rettv->vval.v_number = test_gui_find_repl(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001546# endif
Christopher Plewright20b795e2022-12-20 20:01:58 +00001547# ifdef MSWIN
1548 else if (STRCMP(event, "key") == 0 || STRCMP(event, "mouse") == 0)
1549 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1550# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001551 else if (STRCMP(event, "mouse") == 0)
1552 rettv->vval.v_number = test_gui_mouse_event(argvars[1].vval.v_dict);
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001553 else if (STRCMP(event, "scrollbar") == 0)
1554 rettv->vval.v_number = test_gui_scrollbar(argvars[1].vval.v_dict);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001555 else if (STRCMP(event, "tabline") == 0)
1556 rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict);
1557 else if (STRCMP(event, "tabmenu") == 0)
1558 rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict);
1559 else
1560 {
1561 semsg(_(e_invalid_argument_str), event);
1562 return;
1563 }
1564# endif
1565}
1566
1567 void
1568f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
1569{
1570 if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
1571 return;
1572
1573 time_for_testing = (time_t)tv_get_number(&argvars[0]);
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001574}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001575
1576#endif // defined(FEAT_EVAL)