blob: 3f4387c4989d7f1691449c9bed466df87b02e1a9 [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);
Yegappan Lakshmanan032713f2023-01-25 21:05:38 +000058 return;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020059 }
Yegappan Lakshmanan032713f2023-01-25 21:05:38 +000060
61 switch (*p)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020062 {
63 case BS: ga_concat(gap, (char_u *)"\\b"); break;
64 case ESC: ga_concat(gap, (char_u *)"\\e"); break;
65 case FF: ga_concat(gap, (char_u *)"\\f"); break;
66 case NL: ga_concat(gap, (char_u *)"\\n"); break;
67 case TAB: ga_concat(gap, (char_u *)"\\t"); break;
68 case CAR: ga_concat(gap, (char_u *)"\\r"); break;
69 case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
70 default:
Bram Moolenaar7177da92020-07-12 23:09:20 +020071 if (*p < ' ' || *p == 0x7f)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020072 {
73 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
74 ga_concat(gap, buf);
75 }
76 else
77 ga_append(gap, *p);
78 break;
79 }
80}
81
82/*
83 * Append "str" to "gap", escaping unprintable characters.
84 * Changes NL to \n, CR to \r, etc.
85 */
86 static void
87ga_concat_shorten_esc(garray_T *gap, char_u *str)
88{
89 char_u *p;
90 char_u *s;
91 int c;
92 int clen;
93 char_u buf[NUMBUFLEN];
94 int same_len;
95
96 if (str == NULL)
97 {
98 ga_concat(gap, (char_u *)"NULL");
99 return;
100 }
101
102 for (p = str; *p != NUL; ++p)
103 {
104 same_len = 1;
105 s = p;
Bram Moolenaar34f81172022-02-16 12:16:19 +0000106 c = mb_cptr2char_adv(&s);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200107 clen = s - p;
108 while (*s != NUL && c == mb_ptr2char(s))
109 {
110 ++same_len;
111 s += clen;
112 }
113 if (same_len > 20)
114 {
115 ga_concat(gap, (char_u *)"\\[");
116 ga_concat_esc(gap, p, clen);
117 ga_concat(gap, (char_u *)" occurs ");
118 vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
119 ga_concat(gap, buf);
120 ga_concat(gap, (char_u *)" times]");
121 p = s - 1;
122 }
123 else
124 ga_concat_esc(gap, p, clen);
125 }
126}
127
128/*
129 * Fill "gap" with information about an assert error.
130 */
131 static void
132fill_assert_error(
133 garray_T *gap,
134 typval_T *opt_msg_tv,
135 char_u *exp_str,
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200136 typval_T *exp_tv_arg,
137 typval_T *got_tv_arg,
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200138 assert_type_T atype)
139{
140 char_u numbuf[NUMBUFLEN];
141 char_u *tofree;
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200142 typval_T *exp_tv = exp_tv_arg;
143 typval_T *got_tv = got_tv_arg;
144 int did_copy = FALSE;
145 int omitted = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200146
Bram Moolenaar1d634542020-08-18 13:41:50 +0200147 if (opt_msg_tv->v_type != VAR_UNKNOWN
148 && !(opt_msg_tv->v_type == VAR_STRING
149 && (opt_msg_tv->vval.v_string == NULL
150 || *opt_msg_tv->vval.v_string == NUL)))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200151 {
152 ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
153 vim_free(tofree);
154 ga_concat(gap, (char_u *)": ");
155 }
156
157 if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
158 ga_concat(gap, (char_u *)"Pattern ");
159 else if (atype == ASSERT_NOTEQUAL)
160 ga_concat(gap, (char_u *)"Expected not equal to ");
161 else
162 ga_concat(gap, (char_u *)"Expected ");
163 if (exp_str == NULL)
164 {
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200165 // When comparing dictionaries, drop the items that are equal, so that
166 // it's a lot easier to see what differs.
167 if (atype != ASSERT_NOTEQUAL
168 && exp_tv->v_type == VAR_DICT && got_tv->v_type == VAR_DICT
169 && exp_tv->vval.v_dict != NULL && got_tv->vval.v_dict != NULL)
170 {
171 dict_T *exp_d = exp_tv->vval.v_dict;
172 dict_T *got_d = got_tv->vval.v_dict;
173 hashitem_T *hi;
174 dictitem_T *item2;
175 int todo;
176
177 did_copy = TRUE;
178 exp_tv->vval.v_dict = dict_alloc();
179 got_tv->vval.v_dict = dict_alloc();
180 if (exp_tv->vval.v_dict == NULL || got_tv->vval.v_dict == NULL)
181 return;
182
183 todo = (int)exp_d->dv_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +0000184 FOR_ALL_HASHTAB_ITEMS(&exp_d->dv_hashtab, hi, todo)
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200185 {
186 if (!HASHITEM_EMPTY(hi))
187 {
188 item2 = dict_find(got_d, hi->hi_key, -1);
189 if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv,
190 &item2->di_tv, FALSE, FALSE))
191 {
192 // item of exp_d not present in got_d or values differ.
193 dict_add_tv(exp_tv->vval.v_dict,
194 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
195 if (item2 != NULL)
196 dict_add_tv(got_tv->vval.v_dict,
197 (char *)hi->hi_key, &item2->di_tv);
198 }
199 else
200 ++omitted;
201 --todo;
202 }
203 }
204
205 // Add items only present in got_d.
206 todo = (int)got_d->dv_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +0000207 FOR_ALL_HASHTAB_ITEMS(&got_d->dv_hashtab, hi, todo)
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200208 {
209 if (!HASHITEM_EMPTY(hi))
210 {
211 item2 = dict_find(exp_d, hi->hi_key, -1);
212 if (item2 == NULL)
213 // item of got_d not present in exp_d
214 dict_add_tv(got_tv->vval.v_dict,
215 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
216 --todo;
217 }
218 }
219 }
220
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200221 ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
222 vim_free(tofree);
223 }
224 else
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100225 {
226 ga_concat(gap, (char_u *)"'");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200227 ga_concat_shorten_esc(gap, exp_str);
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100228 ga_concat(gap, (char_u *)"'");
229 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200230 if (atype != ASSERT_NOTEQUAL)
231 {
232 if (atype == ASSERT_MATCH)
233 ga_concat(gap, (char_u *)" does not match ");
234 else if (atype == ASSERT_NOTMATCH)
235 ga_concat(gap, (char_u *)" does match ");
236 else
237 ga_concat(gap, (char_u *)" but got ");
238 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
239 vim_free(tofree);
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200240
241 if (omitted != 0)
242 {
243 char buf[100];
244
245 vim_snprintf(buf, 100, " - %d equal item%s omitted",
246 omitted, omitted == 1 ? "" : "s");
247 ga_concat(gap, (char_u *)buf);
248 }
249 }
250
251 if (did_copy)
252 {
253 clear_tv(exp_tv);
254 clear_tv(got_tv);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200255 }
256}
257
258 static int
259assert_equal_common(typval_T *argvars, assert_type_T atype)
260{
261 garray_T ga;
262
263 if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
264 != (atype == ASSERT_EQUAL))
265 {
266 prepare_assert_error(&ga);
267 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
268 atype);
269 assert_error(&ga);
270 ga_clear(&ga);
271 return 1;
272 }
273 return 0;
274}
275
276 static int
277assert_match_common(typval_T *argvars, assert_type_T atype)
278{
279 garray_T ga;
280 char_u buf1[NUMBUFLEN];
281 char_u buf2[NUMBUFLEN];
Bram Moolenaar7177da92020-07-12 23:09:20 +0200282 int called_emsg_before = called_emsg;
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200283 char_u *pat;
284 char_u *text;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200285
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200286 if (in_vim9script()
287 && (check_for_string_arg(argvars, 0) == FAIL
288 || check_for_string_arg(argvars, 1) == FAIL
289 || check_for_opt_string_arg(argvars, 2) == FAIL))
290 return 1;
291
292 pat = tv_get_string_buf_chk(&argvars[0], buf1);
293 text = tv_get_string_buf_chk(&argvars[1], buf2);
Bram Moolenaar7177da92020-07-12 23:09:20 +0200294 if (called_emsg == called_emsg_before
295 && pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200296 {
297 prepare_assert_error(&ga);
298 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
299 atype);
300 assert_error(&ga);
301 ga_clear(&ga);
302 return 1;
303 }
304 return 0;
305}
306
307/*
308 * Common for assert_true() and assert_false().
309 * Return non-zero for failure.
310 */
311 static int
312assert_bool(typval_T *argvars, int isTrue)
313{
314 int error = FALSE;
315 garray_T ga;
316
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +0100317 if (argvars[0].v_type == VAR_BOOL
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200318 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
319 return 0;
320 if (argvars[0].v_type != VAR_NUMBER
321 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
322 || error)
323 {
324 prepare_assert_error(&ga);
325 fill_assert_error(&ga, &argvars[1],
326 (char_u *)(isTrue ? "True" : "False"),
327 NULL, &argvars[0], ASSERT_OTHER);
328 assert_error(&ga);
329 ga_clear(&ga);
330 return 1;
331 }
332 return 0;
333}
334
335 static void
336assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
337{
338 char_u *tofree;
339 char_u numbuf[NUMBUFLEN];
340
341 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
342 {
343 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
344 vim_free(tofree);
345 }
346 else
347 ga_concat(gap, cmd);
348}
349
350 static int
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200351assert_beeps(typval_T *argvars, int no_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200352{
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200353 char_u *cmd;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200354 garray_T ga;
355 int ret = 0;
356
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200357 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
358 return 0;
359
360 cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200361 called_vim_beep = FALSE;
362 suppress_errthrow = TRUE;
363 emsg_silent = FALSE;
364 do_cmdline_cmd(cmd);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200365 if (no_beep ? called_vim_beep : !called_vim_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200366 {
367 prepare_assert_error(&ga);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200368 if (no_beep)
369 ga_concat(&ga, (char_u *)"command did beep: ");
370 else
371 ga_concat(&ga, (char_u *)"command did not beep: ");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200372 ga_concat(&ga, cmd);
373 assert_error(&ga);
374 ga_clear(&ga);
375 ret = 1;
376 }
377
378 suppress_errthrow = FALSE;
379 emsg_on_display = FALSE;
380 return ret;
381}
382
383/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200384 * "assert_beeps(cmd)" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200385 */
386 void
387f_assert_beeps(typval_T *argvars, typval_T *rettv)
388{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200389 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
390 return;
391
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200392 rettv->vval.v_number = assert_beeps(argvars, FALSE);
393}
394
395/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200396 * "assert_nobeep(cmd)" function
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200397 */
398 void
399f_assert_nobeep(typval_T *argvars, typval_T *rettv)
400{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200401 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
402 return;
403
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200404 rettv->vval.v_number = assert_beeps(argvars, TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200405}
406
407/*
408 * "assert_equal(expected, actual[, msg])" function
409 */
410 void
411f_assert_equal(typval_T *argvars, typval_T *rettv)
412{
413 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
414}
415
416 static int
417assert_equalfile(typval_T *argvars)
418{
419 char_u buf1[NUMBUFLEN];
420 char_u buf2[NUMBUFLEN];
Bram Moolenaar7177da92020-07-12 23:09:20 +0200421 int called_emsg_before = called_emsg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200422 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
423 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
424 garray_T ga;
425 FILE *fd1;
426 FILE *fd2;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200427 char line1[200];
428 char line2[200];
429 int lineidx = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200430
Bram Moolenaar7177da92020-07-12 23:09:20 +0200431 if (called_emsg > called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200432 return 0;
433
434 IObuff[0] = NUL;
435 fd1 = mch_fopen((char *)fname1, READBIN);
436 if (fd1 == NULL)
437 {
Bram Moolenaar460ae5d2022-01-01 14:19:49 +0000438 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str, fname1);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200439 }
440 else
441 {
442 fd2 = mch_fopen((char *)fname2, READBIN);
443 if (fd2 == NULL)
444 {
445 fclose(fd1);
Bram Moolenaar460ae5d2022-01-01 14:19:49 +0000446 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str, fname2);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200447 }
448 else
449 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200450 int c1, c2;
451 long count = 0;
452 long linecount = 1;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200453
454 for (;;)
455 {
456 c1 = fgetc(fd1);
457 c2 = fgetc(fd2);
458 if (c1 == EOF)
459 {
460 if (c2 != EOF)
461 STRCPY(IObuff, "first file is shorter");
462 break;
463 }
464 else if (c2 == EOF)
465 {
466 STRCPY(IObuff, "second file is shorter");
467 break;
468 }
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200469 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200470 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200471 line1[lineidx] = c1;
472 line2[lineidx] = c2;
473 ++lineidx;
474 if (c1 != c2)
475 {
476 vim_snprintf((char *)IObuff, IOSIZE,
477 "difference at byte %ld, line %ld",
478 count, linecount);
479 break;
480 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200481 }
482 ++count;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200483 if (c1 == NL)
484 {
485 ++linecount;
486 lineidx = 0;
487 }
488 else if (lineidx + 2 == (int)sizeof(line1))
489 {
490 mch_memmove(line1, line1 + 100, lineidx - 100);
491 mch_memmove(line2, line2 + 100, lineidx - 100);
492 lineidx -= 100;
493 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200494 }
495 fclose(fd1);
496 fclose(fd2);
497 }
498 }
499 if (IObuff[0] != NUL)
500 {
501 prepare_assert_error(&ga);
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200502 if (argvars[2].v_type != VAR_UNKNOWN)
503 {
504 char_u numbuf[NUMBUFLEN];
505 char_u *tofree;
506
507 ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
508 vim_free(tofree);
509 ga_concat(&ga, (char_u *)": ");
510 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200511 ga_concat(&ga, IObuff);
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200512 if (lineidx > 0)
513 {
514 line1[lineidx] = NUL;
515 line2[lineidx] = NUL;
516 ga_concat(&ga, (char_u *)" after \"");
517 ga_concat(&ga, (char_u *)line1);
518 if (STRCMP(line1, line2) != 0)
519 {
520 ga_concat(&ga, (char_u *)"\" vs \"");
521 ga_concat(&ga, (char_u *)line2);
522 }
523 ga_concat(&ga, (char_u *)"\"");
524 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200525 assert_error(&ga);
526 ga_clear(&ga);
527 return 1;
528 }
529 return 0;
530}
531
532/*
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200533 * "assert_equalfile(fname-one, fname-two[, msg])" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200534 */
535 void
536f_assert_equalfile(typval_T *argvars, typval_T *rettv)
537{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200538 if (in_vim9script()
539 && (check_for_string_arg(argvars, 0) == FAIL
540 || check_for_string_arg(argvars, 1) == FAIL
541 || check_for_opt_string_arg(argvars, 2) == FAIL))
542 return;
543
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200544 rettv->vval.v_number = assert_equalfile(argvars);
545}
546
547/*
548 * "assert_notequal(expected, actual[, msg])" function
549 */
550 void
551f_assert_notequal(typval_T *argvars, typval_T *rettv)
552{
553 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
554}
555
556/*
557 * "assert_exception(string[, msg])" function
558 */
559 void
560f_assert_exception(typval_T *argvars, typval_T *rettv)
561{
562 garray_T ga;
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200563 char_u *error;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200564
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200565 if (in_vim9script()
566 && (check_for_string_arg(argvars, 0) == FAIL
567 || check_for_opt_string_arg(argvars, 1) == FAIL))
568 return;
569
570 error = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200571 if (*get_vim_var_str(VV_EXCEPTION) == NUL)
572 {
573 prepare_assert_error(&ga);
574 ga_concat(&ga, (char_u *)"v:exception is not set");
575 assert_error(&ga);
576 ga_clear(&ga);
577 rettv->vval.v_number = 1;
578 }
579 else if (error != NULL
580 && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
581 {
582 prepare_assert_error(&ga);
583 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
584 get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
585 assert_error(&ga);
586 ga_clear(&ga);
587 rettv->vval.v_number = 1;
588 }
589}
590
591/*
592 * "assert_fails(cmd [, error[, msg]])" function
593 */
594 void
595f_assert_fails(typval_T *argvars, typval_T *rettv)
596{
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200597 garray_T ga;
598 int save_trylevel = trylevel;
Bram Moolenaar53989552019-12-23 22:59:18 +0100599 int called_emsg_before = called_emsg;
Bram Moolenaar44d66522020-09-06 22:26:57 +0200600 char *wrong_arg_msg = NULL;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100601 char_u *tofree = NULL;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200602
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200603 if (check_for_string_or_number_arg(argvars, 0) == FAIL
604 || check_for_opt_string_or_list_arg(argvars, 1) == FAIL
605 || (argvars[1].v_type != VAR_UNKNOWN
606 && (argvars[2].v_type != VAR_UNKNOWN
607 && (check_for_opt_number_arg(argvars, 3) == FAIL
608 || (argvars[3].v_type != VAR_UNKNOWN
609 && check_for_opt_string_arg(argvars, 4) == FAIL)))))
610 return;
611
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200612 // trylevel must be zero for a ":throw" command to be considered failed
613 trylevel = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200614 suppress_errthrow = TRUE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100615 in_assert_fails = TRUE;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000616 ++no_wait_return;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200617
Bram Moolenaarf2206432022-11-09 00:44:30 +0000618 char_u *cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200619 do_cmdline_cmd(cmd);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100620
621 // reset here for any errors reported below
622 trylevel = save_trylevel;
623 suppress_errthrow = FALSE;
624
Bram Moolenaar53989552019-12-23 22:59:18 +0100625 if (called_emsg == called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200626 {
627 prepare_assert_error(&ga);
628 ga_concat(&ga, (char_u *)"command did not fail: ");
629 assert_append_cmd_or_arg(&ga, argvars, cmd);
630 assert_error(&ga);
631 ga_clear(&ga);
632 rettv->vval.v_number = 1;
633 }
634 else if (argvars[1].v_type != VAR_UNKNOWN)
635 {
636 char_u buf[NUMBUFLEN];
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200637 char_u *expected;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100638 char_u *expected_str = NULL;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200639 int error_found = FALSE;
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200640 int error_found_index = 1;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200641 char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]"
642 : emsg_assert_fails_msg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200643
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200644 if (argvars[1].v_type == VAR_STRING)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200645 {
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200646 expected = tv_get_string_buf_chk(&argvars[1], buf);
647 error_found = expected == NULL
648 || strstr((char *)actual, (char *)expected) == NULL;
649 }
650 else if (argvars[1].v_type == VAR_LIST)
651 {
652 list_T *list = argvars[1].vval.v_list;
653 typval_T *tv;
654
655 if (list == NULL || list->lv_len < 1 || list->lv_len > 2)
656 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200657 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200658 goto theend;
659 }
660 CHECK_LIST_MATERIALIZE(list);
661 tv = &list->lv_first->li_tv;
662 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100663 if (expected == NULL)
664 goto theend;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200665 if (!pattern_match(expected, actual, FALSE))
666 {
667 error_found = TRUE;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100668 expected_str = expected;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200669 }
670 else if (list->lv_len == 2)
671 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100672 // make a copy, an error in pattern_match() may free it
673 tofree = actual = vim_strsave(get_vim_var_str(VV_ERRMSG));
674 if (actual != NULL)
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100675 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100676 tv = &list->lv_u.mat.lv_last->li_tv;
677 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100678 if (expected == NULL)
679 goto theend;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100680 if (!pattern_match(expected, actual, FALSE))
681 {
682 error_found = TRUE;
683 expected_str = expected;
684 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100685 }
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200686 }
687 }
688 else
689 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200690 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200691 goto theend;
692 }
693
Bram Moolenaar9b02d642020-08-18 23:24:13 +0200694 if (!error_found && argvars[2].v_type != VAR_UNKNOWN
Bram Moolenaar44d66522020-09-06 22:26:57 +0200695 && argvars[3].v_type != VAR_UNKNOWN)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200696 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200697 if (argvars[3].v_type != VAR_NUMBER)
698 {
699 wrong_arg_msg = e_assert_fails_fourth_argument;
700 goto theend;
701 }
702 else if (argvars[3].vval.v_number >= 0
703 && argvars[3].vval.v_number != emsg_assert_fails_lnum)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200704 {
705 error_found = TRUE;
706 error_found_index = 3;
707 }
Bram Moolenaar44d66522020-09-06 22:26:57 +0200708 if (!error_found && argvars[4].v_type != VAR_UNKNOWN)
709 {
710 if (argvars[4].v_type != VAR_STRING)
711 {
712 wrong_arg_msg = e_assert_fails_fifth_argument;
713 goto theend;
714 }
715 else if (argvars[4].vval.v_string != NULL
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200716 && !pattern_match(argvars[4].vval.v_string,
717 emsg_assert_fails_context, FALSE))
Bram Moolenaar44d66522020-09-06 22:26:57 +0200718 {
719 error_found = TRUE;
720 error_found_index = 4;
721 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200722 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200723 }
724
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200725 if (error_found)
726 {
727 typval_T actual_tv;
728
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200729 prepare_assert_error(&ga);
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200730 if (error_found_index == 3)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200731 {
732 actual_tv.v_type = VAR_NUMBER;
733 actual_tv.vval.v_number = emsg_assert_fails_lnum;
734 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200735 else if (error_found_index == 4)
736 {
737 actual_tv.v_type = VAR_STRING;
738 actual_tv.vval.v_string = emsg_assert_fails_context;
739 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200740 else
741 {
742 actual_tv.v_type = VAR_STRING;
743 actual_tv.vval.v_string = actual;
744 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100745 fill_assert_error(&ga, &argvars[2], expected_str,
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200746 &argvars[error_found_index], &actual_tv, ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200747 ga_concat(&ga, (char_u *)": ");
748 assert_append_cmd_or_arg(&ga, argvars, cmd);
749 assert_error(&ga);
750 ga_clear(&ga);
751 rettv->vval.v_number = 1;
752 }
753 }
754
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200755theend:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200756 trylevel = save_trylevel;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200757 suppress_errthrow = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100758 in_assert_fails = FALSE;
759 did_emsg = FALSE;
Bram Moolenaar8bea1712022-06-15 20:49:35 +0100760 got_int = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100761 msg_col = 0;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000762 --no_wait_return;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100763 need_wait_return = FALSE;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200764 emsg_on_display = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100765 msg_scrolled = 0;
766 lines_left = Rows;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200767 VIM_CLEAR(emsg_assert_fails_msg);
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100768 vim_free(tofree);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200769 set_vim_var_string(VV_ERRMSG, NULL, 0);
Bram Moolenaar44d66522020-09-06 22:26:57 +0200770 if (wrong_arg_msg != NULL)
771 emsg(_(wrong_arg_msg));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200772}
773
774/*
775 * "assert_false(actual[, msg])" function
776 */
777 void
778f_assert_false(typval_T *argvars, typval_T *rettv)
779{
780 rettv->vval.v_number = assert_bool(argvars, FALSE);
781}
782
783 static int
784assert_inrange(typval_T *argvars)
785{
786 garray_T ga;
787 int error = FALSE;
788 char_u *tofree;
789 char msg[200];
790 char_u numbuf[NUMBUFLEN];
791
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200792 if (argvars[0].v_type == VAR_FLOAT
793 || argvars[1].v_type == VAR_FLOAT
794 || argvars[2].v_type == VAR_FLOAT)
795 {
796 float_T flower = tv_get_float(&argvars[0]);
797 float_T fupper = tv_get_float(&argvars[1]);
798 float_T factual = tv_get_float(&argvars[2]);
799
800 if (factual < flower || factual > fupper)
801 {
802 prepare_assert_error(&ga);
803 if (argvars[3].v_type != VAR_UNKNOWN)
804 {
805 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
806 vim_free(tofree);
807 }
808 else
809 {
810 vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
811 flower, fupper, factual);
812 ga_concat(&ga, (char_u *)msg);
813 }
814 assert_error(&ga);
815 ga_clear(&ga);
816 return 1;
817 }
818 }
819 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200820 {
821 varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
822 varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
823 varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
824
825 if (error)
826 return 0;
827 if (actual < lower || actual > upper)
828 {
829 prepare_assert_error(&ga);
830 if (argvars[3].v_type != VAR_UNKNOWN)
831 {
832 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
833 vim_free(tofree);
834 }
835 else
836 {
837 vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
838 (long)lower, (long)upper, (long)actual);
839 ga_concat(&ga, (char_u *)msg);
840 }
841 assert_error(&ga);
842 ga_clear(&ga);
843 return 1;
844 }
845 }
846 return 0;
847}
848
849/*
850 * "assert_inrange(lower, upper[, msg])" function
851 */
852 void
853f_assert_inrange(typval_T *argvars, typval_T *rettv)
854{
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200855 if (check_for_float_or_nr_arg(argvars, 0) == FAIL
856 || check_for_float_or_nr_arg(argvars, 1) == FAIL
857 || check_for_float_or_nr_arg(argvars, 2) == FAIL
858 || check_for_opt_string_arg(argvars, 3) == FAIL)
859 return;
860
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200861 rettv->vval.v_number = assert_inrange(argvars);
862}
863
864/*
865 * "assert_match(pattern, actual[, msg])" function
866 */
867 void
868f_assert_match(typval_T *argvars, typval_T *rettv)
869{
870 rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
871}
872
873/*
874 * "assert_notmatch(pattern, actual[, msg])" function
875 */
876 void
877f_assert_notmatch(typval_T *argvars, typval_T *rettv)
878{
879 rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
880}
881
882/*
883 * "assert_report(msg)" function
884 */
885 void
886f_assert_report(typval_T *argvars, typval_T *rettv)
887{
888 garray_T ga;
889
Yegappan Lakshmananc72bdd22021-07-11 19:44:18 +0200890 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
891 return;
892
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200893 prepare_assert_error(&ga);
894 ga_concat(&ga, tv_get_string(&argvars[0]));
895 assert_error(&ga);
896 ga_clear(&ga);
897 rettv->vval.v_number = 1;
898}
899
900/*
901 * "assert_true(actual[, msg])" function
902 */
903 void
904f_assert_true(typval_T *argvars, typval_T *rettv)
905{
906 rettv->vval.v_number = assert_bool(argvars, TRUE);
907}
908
909/*
910 * "test_alloc_fail(id, countdown, repeat)" function
911 */
912 void
913f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
914{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200915 if (in_vim9script()
916 && (check_for_number_arg(argvars, 0) == FAIL
917 || check_for_number_arg(argvars, 1) == FAIL
918 || check_for_number_arg(argvars, 2) == FAIL))
919 return;
920
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200921 if (argvars[0].v_type != VAR_NUMBER
922 || argvars[0].vval.v_number <= 0
923 || argvars[1].v_type != VAR_NUMBER
924 || argvars[1].vval.v_number < 0
925 || argvars[2].v_type != VAR_NUMBER)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000926 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200927 else
928 {
929 alloc_fail_id = argvars[0].vval.v_number;
930 if (alloc_fail_id >= aid_last)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000931 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200932 alloc_fail_countdown = argvars[1].vval.v_number;
933 alloc_fail_repeat = argvars[2].vval.v_number;
934 did_outofmem_msg = FALSE;
935 }
936}
937
938/*
939 * "test_autochdir()"
940 */
941 void
942f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
943{
944#if defined(FEAT_AUTOCHDIR)
945 test_autochdir = TRUE;
946#endif
947}
948
949/*
950 * "test_feedinput()"
951 */
952 void
953f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
954{
955#ifdef USE_INPUT_BUF
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200956 char_u *val;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200957
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200958 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
959 return;
960
961 val = tv_get_string_chk(&argvars[0]);
Bram Moolenaar272ca952020-01-28 20:49:11 +0100962# ifdef VIMDLL
963 // this doesn't work in the console
964 if (!gui.in_use)
965 return;
966# endif
967
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200968 if (val != NULL)
969 {
970 trash_input_buf();
971 add_to_input_buf_csi(val, (int)STRLEN(val));
972 }
973#endif
974}
975
976/*
977 * "test_getvalue({name})" function
978 */
979 void
980f_test_getvalue(typval_T *argvars, typval_T *rettv)
981{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100982 char_u *name;
983
984 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200985 return;
986
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100987 name = tv_get_string(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200988
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100989 if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
990 rettv->vval.v_number = need_fileinfo;
991 else
992 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200993}
994
995/*
996 * "test_option_not_set({name})" function
997 */
998 void
999f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
1000{
1001 char_u *name = (char_u *)"";
1002
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001003 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001004 return;
1005
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001006 name = tv_get_string(&argvars[0]);
1007 if (reset_option_was_set(name) == FAIL)
1008 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001009}
1010
1011/*
1012 * "test_override({name}, {val})" function
1013 */
1014 void
1015f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
1016{
1017 char_u *name = (char_u *)"";
1018 int val;
1019 static int save_starting = -1;
1020
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001021 if (check_for_string_arg(argvars, 0) == FAIL
1022 || check_for_number_arg(argvars, 1) == FAIL)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02001023 return;
1024
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001025 name = tv_get_string(&argvars[0]);
1026 val = (int)tv_get_number(&argvars[1]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001027
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001028 if (STRCMP(name, (char_u *)"redraw") == 0)
1029 disable_redraw_for_testing = val;
1030 else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
1031 ignore_redraw_flag_for_testing = val;
1032 else if (STRCMP(name, (char_u *)"char_avail") == 0)
1033 disable_char_avail_for_testing = val;
1034 else if (STRCMP(name, (char_u *)"starting") == 0)
1035 {
1036 if (val)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001037 {
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001038 if (save_starting < 0)
1039 save_starting = starting;
1040 starting = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001041 }
1042 else
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001043 {
1044 starting = save_starting;
1045 save_starting = -1;
1046 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001047 }
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001048 else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
1049 nfa_fail_for_testing = val;
1050 else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
1051 no_query_mouse_for_testing = val;
1052 else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
1053 no_wait_return = val;
1054 else if (STRCMP(name, (char_u *)"ui_delay") == 0)
1055 ui_delay_for_testing = val;
1056 else if (STRCMP(name, (char_u *)"term_props") == 0)
1057 reset_term_props_on_termresponse = val;
1058 else if (STRCMP(name, (char_u *)"vterm_title") == 0)
1059 disable_vterm_title_for_testing = val;
1060 else if (STRCMP(name, (char_u *)"uptime") == 0)
1061 override_sysinfo_uptime = val;
1062 else if (STRCMP(name, (char_u *)"alloc_lines") == 0)
1063 ml_get_alloc_lines = val;
1064 else if (STRCMP(name, (char_u *)"autoload") == 0)
1065 override_autoload = val;
1066 else if (STRCMP(name, (char_u *)"ALL") == 0)
1067 {
1068 disable_char_avail_for_testing = FALSE;
1069 disable_redraw_for_testing = FALSE;
1070 ignore_redraw_flag_for_testing = FALSE;
1071 nfa_fail_for_testing = FALSE;
1072 no_query_mouse_for_testing = FALSE;
1073 ui_delay_for_testing = 0;
1074 reset_term_props_on_termresponse = FALSE;
1075 override_sysinfo_uptime = -1;
1076 // ml_get_alloc_lines is not reset by "ALL"
1077 if (save_starting >= 0)
1078 {
1079 starting = save_starting;
1080 save_starting = -1;
1081 }
1082 }
1083 else
1084 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001085}
1086
1087/*
1088 * "test_refcount({expr})" function
1089 */
1090 void
1091f_test_refcount(typval_T *argvars, typval_T *rettv)
1092{
1093 int retval = -1;
1094
1095 switch (argvars[0].v_type)
1096 {
1097 case VAR_UNKNOWN:
Bram Moolenaar4c683752020-04-05 21:38:23 +02001098 case VAR_ANY:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001099 case VAR_VOID:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001100 case VAR_NUMBER:
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +01001101 case VAR_BOOL:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001102 case VAR_FLOAT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001103 case VAR_SPECIAL:
1104 case VAR_STRING:
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001105 case VAR_INSTR:
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001106 case VAR_CLASS:
1107 case VAR_OBJECT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001108 break;
1109 case VAR_JOB:
1110#ifdef FEAT_JOB_CHANNEL
1111 if (argvars[0].vval.v_job != NULL)
1112 retval = argvars[0].vval.v_job->jv_refcount - 1;
1113#endif
1114 break;
1115 case VAR_CHANNEL:
1116#ifdef FEAT_JOB_CHANNEL
1117 if (argvars[0].vval.v_channel != NULL)
1118 retval = argvars[0].vval.v_channel->ch_refcount - 1;
1119#endif
1120 break;
1121 case VAR_FUNC:
1122 if (argvars[0].vval.v_string != NULL)
1123 {
1124 ufunc_T *fp;
1125
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00001126 fp = find_func(argvars[0].vval.v_string, FALSE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001127 if (fp != NULL)
1128 retval = fp->uf_refcount;
1129 }
1130 break;
1131 case VAR_PARTIAL:
1132 if (argvars[0].vval.v_partial != NULL)
1133 retval = argvars[0].vval.v_partial->pt_refcount - 1;
1134 break;
1135 case VAR_BLOB:
1136 if (argvars[0].vval.v_blob != NULL)
1137 retval = argvars[0].vval.v_blob->bv_refcount - 1;
1138 break;
1139 case VAR_LIST:
1140 if (argvars[0].vval.v_list != NULL)
1141 retval = argvars[0].vval.v_list->lv_refcount - 1;
1142 break;
1143 case VAR_DICT:
1144 if (argvars[0].vval.v_dict != NULL)
1145 retval = argvars[0].vval.v_dict->dv_refcount - 1;
1146 break;
1147 }
1148
1149 rettv->v_type = VAR_NUMBER;
1150 rettv->vval.v_number = retval;
1151
1152}
1153
1154/*
1155 * "test_garbagecollect_now()" function
1156 */
1157 void
1158f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1159{
Bram Moolenaar0d6f5d92019-12-05 21:33:15 +01001160 // This is dangerous, any Lists and Dicts used internally may be freed
1161 // while still in use.
Bram Moolenaarb3d83982022-01-27 19:59:47 +00001162 if (!get_vim_var_nr(VV_TESTING))
1163 emsg(_(e_calling_test_garbagecollect_now_while_v_testing_is_not_set));
1164 else
1165 garbage_collect(TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001166}
1167
1168/*
1169 * "test_garbagecollect_soon()" function
1170 */
1171 void
1172f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1173{
1174 may_garbage_collect = TRUE;
1175}
1176
1177/*
1178 * "test_ignore_error()" function
1179 */
1180 void
1181f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
1182{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001183 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001184 return;
1185
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001186 ignore_error_for_testing(tv_get_string(&argvars[0]));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001187}
1188
1189 void
1190f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
1191{
1192 rettv->v_type = VAR_BLOB;
1193 rettv->vval.v_blob = NULL;
1194}
1195
1196#ifdef FEAT_JOB_CHANNEL
1197 void
1198f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
1199{
1200 rettv->v_type = VAR_CHANNEL;
1201 rettv->vval.v_channel = NULL;
1202}
1203#endif
1204
1205 void
1206f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
1207{
1208 rettv_dict_set(rettv, NULL);
1209}
1210
1211#ifdef FEAT_JOB_CHANNEL
1212 void
1213f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
1214{
1215 rettv->v_type = VAR_JOB;
1216 rettv->vval.v_job = NULL;
1217}
1218#endif
1219
1220 void
1221f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
1222{
1223 rettv_list_set(rettv, NULL);
1224}
1225
1226 void
Bram Moolenaare69f6d02020-04-01 22:11:01 +02001227f_test_null_function(typval_T *argvars UNUSED, typval_T *rettv)
1228{
1229 rettv->v_type = VAR_FUNC;
1230 rettv->vval.v_string = NULL;
1231}
1232
1233 void
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001234f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
1235{
1236 rettv->v_type = VAR_PARTIAL;
1237 rettv->vval.v_partial = NULL;
1238}
1239
1240 void
1241f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
1242{
1243 rettv->v_type = VAR_STRING;
1244 rettv->vval.v_string = NULL;
1245}
1246
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001247 void
1248f_test_unknown(typval_T *argvars UNUSED, typval_T *rettv)
1249{
1250 rettv->v_type = VAR_UNKNOWN;
1251}
1252
1253 void
1254f_test_void(typval_T *argvars UNUSED, typval_T *rettv)
1255{
1256 rettv->v_type = VAR_VOID;
1257}
1258
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001259 void
1260f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
1261{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001262 if (in_vim9script()
1263 && (check_for_number_arg(argvars, 0) == FAIL
1264 || check_for_number_arg(argvars, 1) == FAIL))
1265 return;
1266
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001267 if (argvars[0].v_type != VAR_NUMBER || argvars[1].v_type != VAR_NUMBER)
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001268 {
Bram Moolenaar436b5ad2021-12-31 22:49:24 +00001269 emsg(_(e_invalid_argument));
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001270 return;
1271 }
1272
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001273 mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
1274 mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
1275}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001276
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001277# ifdef FEAT_GUI
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001278 static int
1279test_gui_drop_files(dict_T *args UNUSED)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001280{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001281# if defined(HAVE_DROP_FILE)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001282 int row;
1283 int col;
1284 int_u mods;
1285 char_u **fnames;
1286 int count = 0;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001287 typval_T t;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001288 list_T *l;
1289 listitem_T *li;
1290
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001291 if (!dict_has_key(args, "files")
1292 || !dict_has_key(args, "row")
1293 || !dict_has_key(args, "col")
1294 || !dict_has_key(args, "modifiers"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001295 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001296
Bram Moolenaard61efa52022-07-23 09:52:04 +01001297 (void)dict_get_tv(args, "files", &t);
1298 row = (int)dict_get_number(args, "row");
1299 col = (int)dict_get_number(args, "col");
1300 mods = (int)dict_get_number(args, "modifiers");
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001301
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001302 if (t.v_type != VAR_LIST || list_len(t.vval.v_list) == 0)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001303 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001304
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001305 l = t.vval.v_list;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001306 fnames = ALLOC_MULT(char_u *, list_len(l));
1307 if (fnames == NULL)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001308 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001309
1310 FOR_ALL_LIST_ITEMS(l, li)
1311 {
1312 // ignore non-string items
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001313 if (li->li_tv.v_type != VAR_STRING
1314 || li->li_tv.vval.v_string == NULL)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001315 continue;
1316
1317 fnames[count] = vim_strsave(li->li_tv.vval.v_string);
1318 if (fnames[count] == NULL)
1319 {
1320 while (--count >= 0)
1321 vim_free(fnames[count]);
1322 vim_free(fnames);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001323 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001324 }
1325 count++;
1326 }
1327
1328 if (count > 0)
1329 gui_handle_drop(TEXT_X(col - 1), TEXT_Y(row - 1), mods, fnames, count);
1330 else
1331 vim_free(fnames);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001332# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001333
1334 return TRUE;
1335}
1336
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001337#if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001338 static int
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001339test_gui_find_repl(dict_T *args)
1340{
1341 int flags;
1342 char_u *find_text;
1343 char_u *repl_text;
1344 int forward;
1345 int retval;
1346
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001347 if (!dict_has_key(args, "find_text")
1348 || !dict_has_key(args, "repl_text")
1349 || !dict_has_key(args, "flags")
1350 || !dict_has_key(args, "forward"))
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001351 return FALSE;
1352
Bram Moolenaard61efa52022-07-23 09:52:04 +01001353 find_text = dict_get_string(args, "find_text", TRUE);
1354 repl_text = dict_get_string(args, "repl_text", TRUE);
1355 flags = (int)dict_get_number(args, "flags");
1356 forward = (int)dict_get_number(args, "forward");
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001357
1358 retval = gui_do_findrepl(flags, find_text, repl_text, forward);
1359 vim_free(find_text);
1360 vim_free(repl_text);
1361
1362 return retval;
1363}
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001364#endif
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001365
1366 static int
1367test_gui_mouse_event(dict_T *args)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001368{
1369 int button;
1370 int row;
1371 int col;
1372 int repeated_click;
1373 int_u mods;
Ernie Raelc4cb5442022-04-03 15:47:28 +01001374 int move;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001375
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001376 if (!dict_has_key(args, "row")
1377 || !dict_has_key(args, "col"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001378 return FALSE;
1379
Ernie Raelc4cb5442022-04-03 15:47:28 +01001380 // Note: "move" is optional, requires fewer arguments
Bram Moolenaard61efa52022-07-23 09:52:04 +01001381 move = (int)dict_get_bool(args, "move", FALSE);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001382
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001383 if (!move && (!dict_has_key(args, "button")
1384 || !dict_has_key(args, "multiclick")
1385 || !dict_has_key(args, "modifiers")))
Ernie Raelc4cb5442022-04-03 15:47:28 +01001386 return FALSE;
1387
Bram Moolenaard61efa52022-07-23 09:52:04 +01001388 row = (int)dict_get_number(args, "row");
1389 col = (int)dict_get_number(args, "col");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001390
Ernie Raelc4cb5442022-04-03 15:47:28 +01001391 if (move)
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001392 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001393 int pY = row;
1394 int pX = col;
1395 // the "move" argument expects row and col coordnates to be in pixels,
1396 // unless "cell" is specified and is TRUE.
Bram Moolenaard61efa52022-07-23 09:52:04 +01001397 if (dict_get_bool(args, "cell", FALSE))
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001398 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001399 // calculate the middle of the character cell
1400 // Note: Cell coordinates are 1-based from vimscript
1401 pY = (row - 1) * gui.char_height + gui.char_height / 2;
1402 pX = (col - 1) * gui.char_width + gui.char_width / 2;
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001403 }
Christopher Plewright20b795e2022-12-20 20:01:58 +00001404 gui_mouse_moved(pX, pY);
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001405 }
Ernie Raelc4cb5442022-04-03 15:47:28 +01001406 else
1407 {
Bram Moolenaard61efa52022-07-23 09:52:04 +01001408 button = (int)dict_get_number(args, "button");
1409 repeated_click = (int)dict_get_number(args, "multiclick");
1410 mods = (int)dict_get_number(args, "modifiers");
Ernie Raelc4cb5442022-04-03 15:47:28 +01001411
LemonBoyc27747e2022-05-07 12:25:40 +01001412 // Reset the scroll values to known values.
1413 // XXX: Remove this when/if the scroll step is made configurable.
1414 mouse_set_hor_scroll_step(6);
1415 mouse_set_vert_scroll_step(3);
1416
Ernie Raelc4cb5442022-04-03 15:47:28 +01001417 gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1),
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001418 repeated_click, mods);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001419 }
1420
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001421 return TRUE;
1422}
1423
1424 static int
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001425test_gui_scrollbar(dict_T *args)
1426{
1427 char_u *which;
1428 long value;
1429 int dragging;
1430 scrollbar_T *sb = NULL;
1431
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001432 if (!dict_has_key(args, "which")
1433 || !dict_has_key(args, "value")
1434 || !dict_has_key(args, "dragging"))
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001435 return FALSE;
1436
Bram Moolenaard61efa52022-07-23 09:52:04 +01001437 which = dict_get_string(args, "which", FALSE);
1438 value = (long)dict_get_number(args, "value");
1439 dragging = (int)dict_get_number(args, "dragging");
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001440
1441 if (STRCMP(which, "left") == 0)
1442 sb = &curwin->w_scrollbars[SBAR_LEFT];
1443 else if (STRCMP(which, "right") == 0)
1444 sb = &curwin->w_scrollbars[SBAR_RIGHT];
1445 else if (STRCMP(which, "hor") == 0)
1446 sb = &gui.bottom_sbar;
1447 if (sb == NULL)
1448 {
1449 semsg(_(e_invalid_argument_str), which);
1450 return FALSE;
1451 }
1452 gui_drag_scrollbar(sb, value, dragging);
1453# ifndef USE_ON_FLY_SCROLL
1454 // need to loop through normal_cmd() to handle the scroll events
1455 exec_normal(FALSE, TRUE, FALSE);
1456# endif
1457
1458 return TRUE;
1459}
1460
1461 static int
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001462test_gui_tabline_event(dict_T *args UNUSED)
1463{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001464# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001465 int tabnr;
1466
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001467 if (!dict_has_key(args, "tabnr"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001468 return FALSE;
1469
Bram Moolenaard61efa52022-07-23 09:52:04 +01001470 tabnr = (int)dict_get_number(args, "tabnr");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001471
1472 return send_tabline_event(tabnr);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001473# else
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001474 return FALSE;
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001475# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001476}
1477
1478 static int
1479test_gui_tabmenu_event(dict_T *args UNUSED)
1480{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001481# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001482 int tabnr;
1483 int item;
1484
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001485 if (!dict_has_key(args, "tabnr")
1486 || !dict_has_key(args, "item"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001487 return FALSE;
1488
Bram Moolenaard61efa52022-07-23 09:52:04 +01001489 tabnr = (int)dict_get_number(args, "tabnr");
1490 item = (int)dict_get_number(args, "item");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001491
1492 send_tabline_menu_event(tabnr, item);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001493# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001494 return TRUE;
1495}
1496# endif
1497
1498 void
Christopher Plewright20b795e2022-12-20 20:01:58 +00001499f_test_mswin_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1500{
1501# ifdef MSWIN
1502 rettv->v_type = VAR_BOOL;
1503 rettv->vval.v_number = FALSE;
1504
1505 if (sandbox != 0)
1506 {
1507 emsg(_(e_not_allowed_in_sandbox));
1508 return;
1509 }
1510
1511 if (check_for_string_arg(argvars, 0) == FAIL
1512 || check_for_dict_arg(argvars, 1) == FAIL
1513 || argvars[1].vval.v_dict == NULL)
1514 return;
1515
1516 char_u *event = tv_get_string(&argvars[0]);
1517 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1518
1519# endif
1520}
1521
1522 void
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001523f_test_gui_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1524{
1525# ifdef FEAT_GUI
1526 char_u *event;
1527
1528 rettv->v_type = VAR_BOOL;
1529 rettv->vval.v_number = FALSE;
1530
Yegappan Lakshmanan81a3ff92022-07-23 05:04:16 +01001531 if (sandbox != 0)
1532 {
1533 emsg(_(e_not_allowed_in_sandbox));
1534 return;
1535 }
1536
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001537 if (check_for_string_arg(argvars, 0) == FAIL
1538 || check_for_dict_arg(argvars, 1) == FAIL
1539 || argvars[1].vval.v_dict == NULL)
1540 return;
1541
1542 event = tv_get_string(&argvars[0]);
1543 if (STRCMP(event, "dropfiles") == 0)
1544 rettv->vval.v_number = test_gui_drop_files(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001545# if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001546 else if (STRCMP(event, "findrepl") == 0)
1547 rettv->vval.v_number = test_gui_find_repl(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001548# endif
Christopher Plewright20b795e2022-12-20 20:01:58 +00001549# ifdef MSWIN
1550 else if (STRCMP(event, "key") == 0 || STRCMP(event, "mouse") == 0)
1551 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1552# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001553 else if (STRCMP(event, "mouse") == 0)
1554 rettv->vval.v_number = test_gui_mouse_event(argvars[1].vval.v_dict);
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001555 else if (STRCMP(event, "scrollbar") == 0)
1556 rettv->vval.v_number = test_gui_scrollbar(argvars[1].vval.v_dict);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001557 else if (STRCMP(event, "tabline") == 0)
1558 rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict);
1559 else if (STRCMP(event, "tabmenu") == 0)
1560 rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict);
1561 else
1562 {
1563 semsg(_(e_invalid_argument_str), event);
1564 return;
1565 }
1566# endif
1567}
1568
1569 void
1570f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
1571{
1572 if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
1573 return;
1574
1575 time_for_testing = (time_t)tv_get_number(&argvars[0]);
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001576}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001577
1578#endif // defined(FEAT_EVAL)