blob: cfa01ff9e79247adf529789894812b243c3afd4f [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
zeertzjq9c4b2462024-08-09 19:52:10 +0200102 for (p = str; *p != NUL; )
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200103 {
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]");
zeertzjq9c4b2462024-08-09 19:52:10 +0200121 p = s;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200122 }
123 else
zeertzjq9c4b2462024-08-09 19:52:10 +0200124 {
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200125 ga_concat_esc(gap, p, clen);
zeertzjq9c4b2462024-08-09 19:52:10 +0200126 p += clen;
127 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200128 }
129}
130
131/*
132 * Fill "gap" with information about an assert error.
133 */
134 static void
135fill_assert_error(
136 garray_T *gap,
137 typval_T *opt_msg_tv,
138 char_u *exp_str,
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200139 typval_T *exp_tv_arg,
140 typval_T *got_tv_arg,
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200141 assert_type_T atype)
142{
143 char_u numbuf[NUMBUFLEN];
144 char_u *tofree;
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200145 typval_T *exp_tv = exp_tv_arg;
146 typval_T *got_tv = got_tv_arg;
147 int did_copy = FALSE;
148 int omitted = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200149
Bram Moolenaar1d634542020-08-18 13:41:50 +0200150 if (opt_msg_tv->v_type != VAR_UNKNOWN
151 && !(opt_msg_tv->v_type == VAR_STRING
152 && (opt_msg_tv->vval.v_string == NULL
153 || *opt_msg_tv->vval.v_string == NUL)))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200154 {
155 ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
156 vim_free(tofree);
157 ga_concat(gap, (char_u *)": ");
158 }
159
160 if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
161 ga_concat(gap, (char_u *)"Pattern ");
162 else if (atype == ASSERT_NOTEQUAL)
163 ga_concat(gap, (char_u *)"Expected not equal to ");
164 else
165 ga_concat(gap, (char_u *)"Expected ");
166 if (exp_str == NULL)
167 {
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200168 // When comparing dictionaries, drop the items that are equal, so that
169 // it's a lot easier to see what differs.
170 if (atype != ASSERT_NOTEQUAL
171 && exp_tv->v_type == VAR_DICT && got_tv->v_type == VAR_DICT
172 && exp_tv->vval.v_dict != NULL && got_tv->vval.v_dict != NULL)
173 {
174 dict_T *exp_d = exp_tv->vval.v_dict;
175 dict_T *got_d = got_tv->vval.v_dict;
176 hashitem_T *hi;
177 dictitem_T *item2;
178 int todo;
179
180 did_copy = TRUE;
181 exp_tv->vval.v_dict = dict_alloc();
182 got_tv->vval.v_dict = dict_alloc();
183 if (exp_tv->vval.v_dict == NULL || got_tv->vval.v_dict == NULL)
184 return;
185
186 todo = (int)exp_d->dv_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +0000187 FOR_ALL_HASHTAB_ITEMS(&exp_d->dv_hashtab, hi, todo)
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200188 {
189 if (!HASHITEM_EMPTY(hi))
190 {
191 item2 = dict_find(got_d, hi->hi_key, -1);
192 if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv,
Yinzuo Jiang7ccd1a22024-07-04 17:20:53 +0200193 &item2->di_tv, FALSE))
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200194 {
195 // item of exp_d not present in got_d or values differ.
196 dict_add_tv(exp_tv->vval.v_dict,
197 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
198 if (item2 != NULL)
199 dict_add_tv(got_tv->vval.v_dict,
200 (char *)hi->hi_key, &item2->di_tv);
201 }
202 else
203 ++omitted;
204 --todo;
205 }
206 }
207
208 // Add items only present in got_d.
209 todo = (int)got_d->dv_hashtab.ht_used;
Yegappan Lakshmanan14113fd2023-03-07 17:13:51 +0000210 FOR_ALL_HASHTAB_ITEMS(&got_d->dv_hashtab, hi, todo)
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200211 {
212 if (!HASHITEM_EMPTY(hi))
213 {
214 item2 = dict_find(exp_d, hi->hi_key, -1);
215 if (item2 == NULL)
216 // item of got_d not present in exp_d
217 dict_add_tv(got_tv->vval.v_dict,
218 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
219 --todo;
220 }
221 }
222 }
223
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200224 ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
225 vim_free(tofree);
226 }
227 else
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100228 {
zeertzjq53f5e512023-05-04 18:58:22 +0100229 if (atype == ASSERT_FAILS)
230 ga_concat(gap, (char_u *)"'");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200231 ga_concat_shorten_esc(gap, exp_str);
zeertzjq53f5e512023-05-04 18:58:22 +0100232 if (atype == ASSERT_FAILS)
233 ga_concat(gap, (char_u *)"'");
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100234 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200235 if (atype != ASSERT_NOTEQUAL)
236 {
237 if (atype == ASSERT_MATCH)
238 ga_concat(gap, (char_u *)" does not match ");
239 else if (atype == ASSERT_NOTMATCH)
240 ga_concat(gap, (char_u *)" does match ");
241 else
242 ga_concat(gap, (char_u *)" but got ");
243 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
244 vim_free(tofree);
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200245
246 if (omitted != 0)
247 {
248 char buf[100];
249
250 vim_snprintf(buf, 100, " - %d equal item%s omitted",
251 omitted, omitted == 1 ? "" : "s");
252 ga_concat(gap, (char_u *)buf);
253 }
254 }
255
256 if (did_copy)
257 {
258 clear_tv(exp_tv);
259 clear_tv(got_tv);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200260 }
261}
262
263 static int
264assert_equal_common(typval_T *argvars, assert_type_T atype)
265{
266 garray_T ga;
267
Yinzuo Jiang7ccd1a22024-07-04 17:20:53 +0200268 if (tv_equal(&argvars[0], &argvars[1], FALSE)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200269 != (atype == ASSERT_EQUAL))
270 {
271 prepare_assert_error(&ga);
272 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
273 atype);
274 assert_error(&ga);
275 ga_clear(&ga);
276 return 1;
277 }
278 return 0;
279}
280
281 static int
282assert_match_common(typval_T *argvars, assert_type_T atype)
283{
284 garray_T ga;
285 char_u buf1[NUMBUFLEN];
286 char_u buf2[NUMBUFLEN];
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200287
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200288 if (in_vim9script()
289 && (check_for_string_arg(argvars, 0) == FAIL
290 || check_for_string_arg(argvars, 1) == FAIL
291 || check_for_opt_string_arg(argvars, 2) == FAIL))
292 return 1;
293
zeertzjq12e7a1f2023-05-06 12:20:05 +0100294 char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
295 char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
296 if (pat != NULL && text != NULL
Bram Moolenaar7177da92020-07-12 23:09:20 +0200297 && pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200298 {
299 prepare_assert_error(&ga);
300 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
301 atype);
302 assert_error(&ga);
303 ga_clear(&ga);
304 return 1;
305 }
306 return 0;
307}
308
309/*
310 * Common for assert_true() and assert_false().
311 * Return non-zero for failure.
312 */
313 static int
314assert_bool(typval_T *argvars, int isTrue)
315{
316 int error = FALSE;
317 garray_T ga;
318
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +0100319 if (argvars[0].v_type == VAR_BOOL
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200320 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
321 return 0;
322 if (argvars[0].v_type != VAR_NUMBER
323 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
324 || error)
325 {
326 prepare_assert_error(&ga);
327 fill_assert_error(&ga, &argvars[1],
328 (char_u *)(isTrue ? "True" : "False"),
329 NULL, &argvars[0], ASSERT_OTHER);
330 assert_error(&ga);
331 ga_clear(&ga);
332 return 1;
333 }
334 return 0;
335}
336
337 static void
338assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
339{
340 char_u *tofree;
341 char_u numbuf[NUMBUFLEN];
342
343 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
344 {
345 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
346 vim_free(tofree);
347 }
348 else
349 ga_concat(gap, cmd);
350}
351
352 static int
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200353assert_beeps(typval_T *argvars, int no_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200354{
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200355 char_u *cmd;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200356 garray_T ga;
357 int ret = 0;
358
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200359 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
360 return 0;
361
362 cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200363 called_vim_beep = FALSE;
364 suppress_errthrow = TRUE;
365 emsg_silent = FALSE;
366 do_cmdline_cmd(cmd);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200367 if (no_beep ? called_vim_beep : !called_vim_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200368 {
369 prepare_assert_error(&ga);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200370 if (no_beep)
371 ga_concat(&ga, (char_u *)"command did beep: ");
372 else
373 ga_concat(&ga, (char_u *)"command did not beep: ");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200374 ga_concat(&ga, cmd);
375 assert_error(&ga);
376 ga_clear(&ga);
377 ret = 1;
378 }
379
380 suppress_errthrow = FALSE;
381 emsg_on_display = FALSE;
382 return ret;
383}
384
385/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200386 * "assert_beeps(cmd)" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200387 */
388 void
389f_assert_beeps(typval_T *argvars, typval_T *rettv)
390{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200391 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
392 return;
393
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200394 rettv->vval.v_number = assert_beeps(argvars, FALSE);
395}
396
397/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200398 * "assert_nobeep(cmd)" function
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200399 */
400 void
401f_assert_nobeep(typval_T *argvars, typval_T *rettv)
402{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200403 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
404 return;
405
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200406 rettv->vval.v_number = assert_beeps(argvars, TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200407}
408
409/*
410 * "assert_equal(expected, actual[, msg])" function
411 */
412 void
413f_assert_equal(typval_T *argvars, typval_T *rettv)
414{
415 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
416}
417
418 static int
419assert_equalfile(typval_T *argvars)
420{
421 char_u buf1[NUMBUFLEN];
422 char_u buf2[NUMBUFLEN];
423 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
424 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200425 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
zeertzjq12e7a1f2023-05-06 12:20:05 +0100431 if (fname1 == NULL || fname2 == NULL)
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 {
zeertzjq12e7a1f2023-05-06 12:20:05 +0100438 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str,
439 fname1);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200440 }
441 else
442 {
443 fd2 = mch_fopen((char *)fname2, READBIN);
444 if (fd2 == NULL)
445 {
446 fclose(fd1);
zeertzjq12e7a1f2023-05-06 12:20:05 +0100447 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str,
448 fname2);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200449 }
450 else
451 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200452 int c1, c2;
453 long count = 0;
454 long linecount = 1;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200455
456 for (;;)
457 {
458 c1 = fgetc(fd1);
459 c2 = fgetc(fd2);
460 if (c1 == EOF)
461 {
462 if (c2 != EOF)
463 STRCPY(IObuff, "first file is shorter");
464 break;
465 }
466 else if (c2 == EOF)
467 {
468 STRCPY(IObuff, "second file is shorter");
469 break;
470 }
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200471 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200472 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200473 line1[lineidx] = c1;
474 line2[lineidx] = c2;
475 ++lineidx;
476 if (c1 != c2)
477 {
478 vim_snprintf((char *)IObuff, IOSIZE,
479 "difference at byte %ld, line %ld",
480 count, linecount);
481 break;
482 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200483 }
484 ++count;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200485 if (c1 == NL)
486 {
487 ++linecount;
488 lineidx = 0;
489 }
490 else if (lineidx + 2 == (int)sizeof(line1))
491 {
492 mch_memmove(line1, line1 + 100, lineidx - 100);
493 mch_memmove(line2, line2 + 100, lineidx - 100);
494 lineidx -= 100;
495 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200496 }
497 fclose(fd1);
498 fclose(fd2);
499 }
500 }
zeertzjq12e7a1f2023-05-06 12:20:05 +0100501
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200502 if (IObuff[0] != NUL)
503 {
zeertzjq12e7a1f2023-05-06 12:20:05 +0100504 garray_T ga;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200505 prepare_assert_error(&ga);
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200506 if (argvars[2].v_type != VAR_UNKNOWN)
507 {
508 char_u numbuf[NUMBUFLEN];
509 char_u *tofree;
510
511 ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
512 vim_free(tofree);
513 ga_concat(&ga, (char_u *)": ");
514 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200515 ga_concat(&ga, IObuff);
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200516 if (lineidx > 0)
517 {
518 line1[lineidx] = NUL;
519 line2[lineidx] = NUL;
520 ga_concat(&ga, (char_u *)" after \"");
521 ga_concat(&ga, (char_u *)line1);
522 if (STRCMP(line1, line2) != 0)
523 {
524 ga_concat(&ga, (char_u *)"\" vs \"");
525 ga_concat(&ga, (char_u *)line2);
526 }
527 ga_concat(&ga, (char_u *)"\"");
528 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200529 assert_error(&ga);
530 ga_clear(&ga);
531 return 1;
532 }
zeertzjq12e7a1f2023-05-06 12:20:05 +0100533
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200534 return 0;
535}
536
537/*
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200538 * "assert_equalfile(fname-one, fname-two[, msg])" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200539 */
540 void
541f_assert_equalfile(typval_T *argvars, typval_T *rettv)
542{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200543 if (in_vim9script()
544 && (check_for_string_arg(argvars, 0) == FAIL
545 || check_for_string_arg(argvars, 1) == FAIL
546 || check_for_opt_string_arg(argvars, 2) == FAIL))
547 return;
548
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200549 rettv->vval.v_number = assert_equalfile(argvars);
550}
551
552/*
553 * "assert_notequal(expected, actual[, msg])" function
554 */
555 void
556f_assert_notequal(typval_T *argvars, typval_T *rettv)
557{
558 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
559}
560
561/*
562 * "assert_exception(string[, msg])" function
563 */
564 void
565f_assert_exception(typval_T *argvars, typval_T *rettv)
566{
567 garray_T ga;
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200568 char_u *error;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200569
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200570 if (in_vim9script()
571 && (check_for_string_arg(argvars, 0) == FAIL
572 || check_for_opt_string_arg(argvars, 1) == FAIL))
573 return;
574
575 error = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200576 if (*get_vim_var_str(VV_EXCEPTION) == NUL)
577 {
578 prepare_assert_error(&ga);
579 ga_concat(&ga, (char_u *)"v:exception is not set");
580 assert_error(&ga);
581 ga_clear(&ga);
582 rettv->vval.v_number = 1;
583 }
584 else if (error != NULL
585 && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
586 {
587 prepare_assert_error(&ga);
588 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
589 get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
590 assert_error(&ga);
591 ga_clear(&ga);
592 rettv->vval.v_number = 1;
593 }
594}
595
596/*
597 * "assert_fails(cmd [, error[, msg]])" function
598 */
599 void
600f_assert_fails(typval_T *argvars, typval_T *rettv)
601{
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200602 garray_T ga;
603 int save_trylevel = trylevel;
Bram Moolenaar53989552019-12-23 22:59:18 +0100604 int called_emsg_before = called_emsg;
Bram Moolenaar44d66522020-09-06 22:26:57 +0200605 char *wrong_arg_msg = NULL;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100606 char_u *tofree = NULL;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200607
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200608 if (check_for_string_or_number_arg(argvars, 0) == FAIL
609 || check_for_opt_string_or_list_arg(argvars, 1) == FAIL
610 || (argvars[1].v_type != VAR_UNKNOWN
611 && (argvars[2].v_type != VAR_UNKNOWN
612 && (check_for_opt_number_arg(argvars, 3) == FAIL
613 || (argvars[3].v_type != VAR_UNKNOWN
614 && check_for_opt_string_arg(argvars, 4) == FAIL)))))
615 return;
616
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200617 // trylevel must be zero for a ":throw" command to be considered failed
618 trylevel = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200619 suppress_errthrow = TRUE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100620 in_assert_fails = TRUE;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000621 ++no_wait_return;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200622
Bram Moolenaarf2206432022-11-09 00:44:30 +0000623 char_u *cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200624 do_cmdline_cmd(cmd);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100625
626 // reset here for any errors reported below
627 trylevel = save_trylevel;
628 suppress_errthrow = FALSE;
629
Bram Moolenaar53989552019-12-23 22:59:18 +0100630 if (called_emsg == called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200631 {
632 prepare_assert_error(&ga);
633 ga_concat(&ga, (char_u *)"command did not fail: ");
634 assert_append_cmd_or_arg(&ga, argvars, cmd);
635 assert_error(&ga);
636 ga_clear(&ga);
637 rettv->vval.v_number = 1;
638 }
639 else if (argvars[1].v_type != VAR_UNKNOWN)
640 {
641 char_u buf[NUMBUFLEN];
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200642 char_u *expected;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100643 char_u *expected_str = NULL;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200644 int error_found = FALSE;
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200645 int error_found_index = 1;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200646 char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]"
647 : emsg_assert_fails_msg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200648
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200649 if (argvars[1].v_type == VAR_STRING)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200650 {
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200651 expected = tv_get_string_buf_chk(&argvars[1], buf);
652 error_found = expected == NULL
653 || strstr((char *)actual, (char *)expected) == NULL;
654 }
655 else if (argvars[1].v_type == VAR_LIST)
656 {
657 list_T *list = argvars[1].vval.v_list;
658 typval_T *tv;
659
660 if (list == NULL || list->lv_len < 1 || list->lv_len > 2)
661 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200662 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200663 goto theend;
664 }
665 CHECK_LIST_MATERIALIZE(list);
666 tv = &list->lv_first->li_tv;
667 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100668 if (expected == NULL)
669 goto theend;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200670 if (!pattern_match(expected, actual, FALSE))
671 {
672 error_found = TRUE;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100673 expected_str = expected;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200674 }
675 else if (list->lv_len == 2)
676 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100677 // make a copy, an error in pattern_match() may free it
678 tofree = actual = vim_strsave(get_vim_var_str(VV_ERRMSG));
679 if (actual != NULL)
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100680 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100681 tv = &list->lv_u.mat.lv_last->li_tv;
682 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100683 if (expected == NULL)
684 goto theend;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100685 if (!pattern_match(expected, actual, FALSE))
686 {
687 error_found = TRUE;
688 expected_str = expected;
689 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100690 }
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200691 }
692 }
693 else
694 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200695 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200696 goto theend;
697 }
698
Bram Moolenaar9b02d642020-08-18 23:24:13 +0200699 if (!error_found && argvars[2].v_type != VAR_UNKNOWN
Bram Moolenaar44d66522020-09-06 22:26:57 +0200700 && argvars[3].v_type != VAR_UNKNOWN)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200701 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200702 if (argvars[3].v_type != VAR_NUMBER)
703 {
704 wrong_arg_msg = e_assert_fails_fourth_argument;
705 goto theend;
706 }
707 else if (argvars[3].vval.v_number >= 0
708 && argvars[3].vval.v_number != emsg_assert_fails_lnum)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200709 {
710 error_found = TRUE;
711 error_found_index = 3;
712 }
Bram Moolenaar44d66522020-09-06 22:26:57 +0200713 if (!error_found && argvars[4].v_type != VAR_UNKNOWN)
714 {
715 if (argvars[4].v_type != VAR_STRING)
716 {
717 wrong_arg_msg = e_assert_fails_fifth_argument;
718 goto theend;
719 }
720 else if (argvars[4].vval.v_string != NULL
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200721 && !pattern_match(argvars[4].vval.v_string,
722 emsg_assert_fails_context, FALSE))
Bram Moolenaar44d66522020-09-06 22:26:57 +0200723 {
724 error_found = TRUE;
725 error_found_index = 4;
726 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200727 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200728 }
729
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200730 if (error_found)
731 {
732 typval_T actual_tv;
733
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200734 prepare_assert_error(&ga);
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200735 if (error_found_index == 3)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200736 {
737 actual_tv.v_type = VAR_NUMBER;
738 actual_tv.vval.v_number = emsg_assert_fails_lnum;
739 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200740 else if (error_found_index == 4)
741 {
742 actual_tv.v_type = VAR_STRING;
743 actual_tv.vval.v_string = emsg_assert_fails_context;
744 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200745 else
746 {
747 actual_tv.v_type = VAR_STRING;
748 actual_tv.vval.v_string = actual;
749 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100750 fill_assert_error(&ga, &argvars[2], expected_str,
zeertzjq53f5e512023-05-04 18:58:22 +0100751 &argvars[error_found_index], &actual_tv, ASSERT_FAILS);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200752 ga_concat(&ga, (char_u *)": ");
753 assert_append_cmd_or_arg(&ga, argvars, cmd);
754 assert_error(&ga);
755 ga_clear(&ga);
756 rettv->vval.v_number = 1;
757 }
758 }
759
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200760theend:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200761 trylevel = save_trylevel;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200762 suppress_errthrow = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100763 in_assert_fails = FALSE;
764 did_emsg = FALSE;
Bram Moolenaar8bea1712022-06-15 20:49:35 +0100765 got_int = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100766 msg_col = 0;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000767 --no_wait_return;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100768 need_wait_return = FALSE;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200769 emsg_on_display = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100770 msg_scrolled = 0;
771 lines_left = Rows;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200772 VIM_CLEAR(emsg_assert_fails_msg);
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100773 vim_free(tofree);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200774 set_vim_var_string(VV_ERRMSG, NULL, 0);
Bram Moolenaar44d66522020-09-06 22:26:57 +0200775 if (wrong_arg_msg != NULL)
776 emsg(_(wrong_arg_msg));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200777}
778
779/*
780 * "assert_false(actual[, msg])" function
781 */
782 void
783f_assert_false(typval_T *argvars, typval_T *rettv)
784{
785 rettv->vval.v_number = assert_bool(argvars, FALSE);
786}
787
788 static int
789assert_inrange(typval_T *argvars)
790{
791 garray_T ga;
792 int error = FALSE;
zeertzjq53f5e512023-05-04 18:58:22 +0100793 char_u expected_str[200];
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200794
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200795 if (argvars[0].v_type == VAR_FLOAT
796 || argvars[1].v_type == VAR_FLOAT
797 || argvars[2].v_type == VAR_FLOAT)
798 {
799 float_T flower = tv_get_float(&argvars[0]);
800 float_T fupper = tv_get_float(&argvars[1]);
801 float_T factual = tv_get_float(&argvars[2]);
802
803 if (factual < flower || factual > fupper)
804 {
805 prepare_assert_error(&ga);
zeertzjq53f5e512023-05-04 18:58:22 +0100806 vim_snprintf((char *)expected_str, 200, "range %g - %g,",
807 flower, fupper);
808 fill_assert_error(&ga, &argvars[3], expected_str, NULL,
809 &argvars[2], ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200810 assert_error(&ga);
811 ga_clear(&ga);
812 return 1;
813 }
814 }
815 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200816 {
817 varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
818 varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
819 varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
820
821 if (error)
822 return 0;
823 if (actual < lower || actual > upper)
824 {
825 prepare_assert_error(&ga);
zeertzjq53f5e512023-05-04 18:58:22 +0100826 vim_snprintf((char *)expected_str, 200, "range %ld - %ld,",
827 (long)lower, (long)upper);
828 fill_assert_error(&ga, &argvars[3], expected_str, NULL,
829 &argvars[2], ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200830 assert_error(&ga);
831 ga_clear(&ga);
832 return 1;
833 }
834 }
835 return 0;
836}
837
838/*
839 * "assert_inrange(lower, upper[, msg])" function
840 */
841 void
842f_assert_inrange(typval_T *argvars, typval_T *rettv)
843{
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200844 if (check_for_float_or_nr_arg(argvars, 0) == FAIL
845 || check_for_float_or_nr_arg(argvars, 1) == FAIL
846 || check_for_float_or_nr_arg(argvars, 2) == FAIL
847 || check_for_opt_string_arg(argvars, 3) == FAIL)
848 return;
849
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200850 rettv->vval.v_number = assert_inrange(argvars);
851}
852
853/*
854 * "assert_match(pattern, actual[, msg])" function
855 */
856 void
857f_assert_match(typval_T *argvars, typval_T *rettv)
858{
859 rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
860}
861
862/*
863 * "assert_notmatch(pattern, actual[, msg])" function
864 */
865 void
866f_assert_notmatch(typval_T *argvars, typval_T *rettv)
867{
868 rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
869}
870
871/*
872 * "assert_report(msg)" function
873 */
874 void
875f_assert_report(typval_T *argvars, typval_T *rettv)
876{
877 garray_T ga;
878
Yegappan Lakshmananc72bdd22021-07-11 19:44:18 +0200879 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
880 return;
881
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200882 prepare_assert_error(&ga);
883 ga_concat(&ga, tv_get_string(&argvars[0]));
884 assert_error(&ga);
885 ga_clear(&ga);
886 rettv->vval.v_number = 1;
887}
888
889/*
890 * "assert_true(actual[, msg])" function
891 */
892 void
893f_assert_true(typval_T *argvars, typval_T *rettv)
894{
895 rettv->vval.v_number = assert_bool(argvars, TRUE);
896}
897
898/*
899 * "test_alloc_fail(id, countdown, repeat)" function
900 */
901 void
902f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
903{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200904 if (in_vim9script()
905 && (check_for_number_arg(argvars, 0) == FAIL
906 || check_for_number_arg(argvars, 1) == FAIL
907 || check_for_number_arg(argvars, 2) == FAIL))
908 return;
909
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200910 if (argvars[0].v_type != VAR_NUMBER
911 || argvars[0].vval.v_number <= 0
912 || argvars[1].v_type != VAR_NUMBER
913 || argvars[1].vval.v_number < 0
914 || argvars[2].v_type != VAR_NUMBER)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000915 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200916 else
917 {
918 alloc_fail_id = argvars[0].vval.v_number;
919 if (alloc_fail_id >= aid_last)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000920 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200921 alloc_fail_countdown = argvars[1].vval.v_number;
922 alloc_fail_repeat = argvars[2].vval.v_number;
923 did_outofmem_msg = FALSE;
924 }
925}
926
927/*
928 * "test_autochdir()"
929 */
930 void
931f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
932{
933#if defined(FEAT_AUTOCHDIR)
934 test_autochdir = TRUE;
935#endif
936}
937
938/*
939 * "test_feedinput()"
940 */
941 void
942f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
943{
944#ifdef USE_INPUT_BUF
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200945 char_u *val;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200946
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200947 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
948 return;
949
950 val = tv_get_string_chk(&argvars[0]);
Bram Moolenaar272ca952020-01-28 20:49:11 +0100951# ifdef VIMDLL
952 // this doesn't work in the console
953 if (!gui.in_use)
954 return;
955# endif
956
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200957 if (val != NULL)
958 {
959 trash_input_buf();
960 add_to_input_buf_csi(val, (int)STRLEN(val));
961 }
962#endif
963}
964
965/*
966 * "test_getvalue({name})" function
967 */
968 void
969f_test_getvalue(typval_T *argvars, typval_T *rettv)
970{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100971 char_u *name;
972
973 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200974 return;
975
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100976 name = tv_get_string(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200977
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100978 if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
979 rettv->vval.v_number = need_fileinfo;
980 else
981 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200982}
983
984/*
985 * "test_option_not_set({name})" function
986 */
987 void
988f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
989{
990 char_u *name = (char_u *)"";
991
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100992 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200993 return;
994
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100995 name = tv_get_string(&argvars[0]);
996 if (reset_option_was_set(name) == FAIL)
997 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200998}
999
1000/*
1001 * "test_override({name}, {val})" function
1002 */
1003 void
1004f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
1005{
1006 char_u *name = (char_u *)"";
1007 int val;
1008 static int save_starting = -1;
1009
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001010 if (check_for_string_arg(argvars, 0) == FAIL
1011 || check_for_number_arg(argvars, 1) == FAIL)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02001012 return;
1013
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001014 name = tv_get_string(&argvars[0]);
1015 val = (int)tv_get_number(&argvars[1]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001016
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001017 if (STRCMP(name, (char_u *)"redraw") == 0)
1018 disable_redraw_for_testing = val;
1019 else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
1020 ignore_redraw_flag_for_testing = val;
1021 else if (STRCMP(name, (char_u *)"char_avail") == 0)
1022 disable_char_avail_for_testing = val;
1023 else if (STRCMP(name, (char_u *)"starting") == 0)
1024 {
1025 if (val)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001026 {
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001027 if (save_starting < 0)
1028 save_starting = starting;
1029 starting = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001030 }
1031 else
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001032 {
1033 starting = save_starting;
1034 save_starting = -1;
1035 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001036 }
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001037 else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
1038 nfa_fail_for_testing = val;
1039 else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
1040 no_query_mouse_for_testing = val;
1041 else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
1042 no_wait_return = val;
1043 else if (STRCMP(name, (char_u *)"ui_delay") == 0)
1044 ui_delay_for_testing = val;
Bram Moolenaar9d383f32023-05-14 21:38:12 +01001045 else if (STRCMP(name, (char_u *)"unreachable") == 0)
1046 ignore_unreachable_code_for_testing = val;
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001047 else if (STRCMP(name, (char_u *)"term_props") == 0)
1048 reset_term_props_on_termresponse = val;
1049 else if (STRCMP(name, (char_u *)"vterm_title") == 0)
1050 disable_vterm_title_for_testing = val;
1051 else if (STRCMP(name, (char_u *)"uptime") == 0)
1052 override_sysinfo_uptime = val;
1053 else if (STRCMP(name, (char_u *)"alloc_lines") == 0)
1054 ml_get_alloc_lines = val;
1055 else if (STRCMP(name, (char_u *)"autoload") == 0)
1056 override_autoload = val;
Yegappan Lakshmanan5715a722024-05-03 18:24:07 +02001057 else if (STRCMP(name, (char_u *)"defcompile") == 0)
1058 override_defcompile = val;
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001059 else if (STRCMP(name, (char_u *)"ALL") == 0)
1060 {
1061 disable_char_avail_for_testing = FALSE;
1062 disable_redraw_for_testing = FALSE;
1063 ignore_redraw_flag_for_testing = FALSE;
1064 nfa_fail_for_testing = FALSE;
1065 no_query_mouse_for_testing = FALSE;
1066 ui_delay_for_testing = 0;
1067 reset_term_props_on_termresponse = FALSE;
1068 override_sysinfo_uptime = -1;
1069 // ml_get_alloc_lines is not reset by "ALL"
1070 if (save_starting >= 0)
1071 {
1072 starting = save_starting;
1073 save_starting = -1;
1074 }
1075 }
1076 else
1077 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001078}
1079
1080/*
1081 * "test_refcount({expr})" function
1082 */
1083 void
1084f_test_refcount(typval_T *argvars, typval_T *rettv)
1085{
1086 int retval = -1;
1087
1088 switch (argvars[0].v_type)
1089 {
1090 case VAR_UNKNOWN:
Bram Moolenaar4c683752020-04-05 21:38:23 +02001091 case VAR_ANY:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001092 case VAR_VOID:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001093 case VAR_NUMBER:
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +01001094 case VAR_BOOL:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001095 case VAR_FLOAT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001096 case VAR_SPECIAL:
1097 case VAR_STRING:
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001098 case VAR_INSTR:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001099 break;
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01001100
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001101 case VAR_JOB:
1102#ifdef FEAT_JOB_CHANNEL
1103 if (argvars[0].vval.v_job != NULL)
1104 retval = argvars[0].vval.v_job->jv_refcount - 1;
1105#endif
1106 break;
1107 case VAR_CHANNEL:
1108#ifdef FEAT_JOB_CHANNEL
1109 if (argvars[0].vval.v_channel != NULL)
1110 retval = argvars[0].vval.v_channel->ch_refcount - 1;
1111#endif
1112 break;
1113 case VAR_FUNC:
1114 if (argvars[0].vval.v_string != NULL)
1115 {
1116 ufunc_T *fp;
1117
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00001118 fp = find_func(argvars[0].vval.v_string, FALSE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001119 if (fp != NULL)
1120 retval = fp->uf_refcount;
1121 }
1122 break;
1123 case VAR_PARTIAL:
1124 if (argvars[0].vval.v_partial != NULL)
1125 retval = argvars[0].vval.v_partial->pt_refcount - 1;
1126 break;
1127 case VAR_BLOB:
1128 if (argvars[0].vval.v_blob != NULL)
1129 retval = argvars[0].vval.v_blob->bv_refcount - 1;
1130 break;
1131 case VAR_LIST:
1132 if (argvars[0].vval.v_list != NULL)
1133 retval = argvars[0].vval.v_list->lv_refcount - 1;
1134 break;
Yegappan Lakshmanan9cb865e2025-03-23 16:42:16 +01001135 case VAR_TUPLE:
1136 if (argvars[0].vval.v_tuple != NULL)
1137 retval = argvars[0].vval.v_tuple->tv_refcount - 1;
1138 break;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001139 case VAR_DICT:
1140 if (argvars[0].vval.v_dict != NULL)
1141 retval = argvars[0].vval.v_dict->dv_refcount - 1;
1142 break;
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01001143 case VAR_CLASS:
1144 if (argvars[0].vval.v_class != NULL)
1145 retval = argvars[0].vval.v_class->class_refcount - 1;
1146 break;
1147 case VAR_OBJECT:
1148 if (argvars[0].vval.v_object != NULL)
1149 retval = argvars[0].vval.v_object->obj_refcount - 1;
1150 break;
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +02001151 case VAR_TYPEALIAS:
1152 if (argvars[0].vval.v_typealias != NULL)
1153 retval = argvars[0].vval.v_typealias->ta_refcount - 1;
1154 break;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001155 }
1156
1157 rettv->v_type = VAR_NUMBER;
1158 rettv->vval.v_number = retval;
1159
1160}
1161
1162/*
1163 * "test_garbagecollect_now()" function
1164 */
1165 void
1166f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1167{
Bram Moolenaar0d6f5d92019-12-05 21:33:15 +01001168 // This is dangerous, any Lists and Dicts used internally may be freed
1169 // while still in use.
Bram Moolenaarb3d83982022-01-27 19:59:47 +00001170 if (!get_vim_var_nr(VV_TESTING))
1171 emsg(_(e_calling_test_garbagecollect_now_while_v_testing_is_not_set));
1172 else
1173 garbage_collect(TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001174}
1175
1176/*
1177 * "test_garbagecollect_soon()" function
1178 */
1179 void
1180f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1181{
1182 may_garbage_collect = TRUE;
1183}
1184
1185/*
1186 * "test_ignore_error()" function
1187 */
1188 void
1189f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
1190{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001191 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001192 return;
1193
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001194 ignore_error_for_testing(tv_get_string(&argvars[0]));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001195}
1196
1197 void
1198f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
1199{
1200 rettv->v_type = VAR_BLOB;
1201 rettv->vval.v_blob = NULL;
1202}
1203
1204#ifdef FEAT_JOB_CHANNEL
1205 void
1206f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
1207{
1208 rettv->v_type = VAR_CHANNEL;
1209 rettv->vval.v_channel = NULL;
1210}
1211#endif
1212
1213 void
1214f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
1215{
1216 rettv_dict_set(rettv, NULL);
1217}
1218
1219#ifdef FEAT_JOB_CHANNEL
1220 void
1221f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
1222{
1223 rettv->v_type = VAR_JOB;
1224 rettv->vval.v_job = NULL;
1225}
1226#endif
1227
1228 void
1229f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
1230{
1231 rettv_list_set(rettv, NULL);
1232}
1233
1234 void
Bram Moolenaare69f6d02020-04-01 22:11:01 +02001235f_test_null_function(typval_T *argvars UNUSED, typval_T *rettv)
1236{
1237 rettv->v_type = VAR_FUNC;
1238 rettv->vval.v_string = NULL;
1239}
1240
1241 void
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001242f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
1243{
1244 rettv->v_type = VAR_PARTIAL;
1245 rettv->vval.v_partial = NULL;
1246}
1247
1248 void
1249f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
1250{
1251 rettv->v_type = VAR_STRING;
1252 rettv->vval.v_string = NULL;
1253}
1254
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001255 void
Yegappan Lakshmanan9cb865e2025-03-23 16:42:16 +01001256f_test_null_tuple(typval_T *argvars UNUSED, typval_T *rettv)
1257{
1258 rettv_tuple_set(rettv, NULL);
1259}
1260
1261 void
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001262f_test_unknown(typval_T *argvars UNUSED, typval_T *rettv)
1263{
1264 rettv->v_type = VAR_UNKNOWN;
1265}
1266
1267 void
1268f_test_void(typval_T *argvars UNUSED, typval_T *rettv)
1269{
1270 rettv->v_type = VAR_VOID;
1271}
1272
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001273 void
1274f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
1275{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001276 if (in_vim9script()
1277 && (check_for_number_arg(argvars, 0) == FAIL
1278 || check_for_number_arg(argvars, 1) == FAIL))
1279 return;
1280
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001281 if (argvars[0].v_type != VAR_NUMBER || argvars[1].v_type != VAR_NUMBER)
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001282 {
Bram Moolenaar436b5ad2021-12-31 22:49:24 +00001283 emsg(_(e_invalid_argument));
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001284 return;
1285 }
1286
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001287 mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
1288 mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
1289}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001290
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001291# ifdef FEAT_GUI
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001292 static int
1293test_gui_drop_files(dict_T *args UNUSED)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001294{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001295# if defined(HAVE_DROP_FILE)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001296 int row;
1297 int col;
1298 int_u mods;
1299 char_u **fnames;
1300 int count = 0;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001301 typval_T t;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001302 list_T *l;
1303 listitem_T *li;
1304
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001305 if (!dict_has_key(args, "files")
1306 || !dict_has_key(args, "row")
1307 || !dict_has_key(args, "col")
1308 || !dict_has_key(args, "modifiers"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001309 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001310
Bram Moolenaard61efa52022-07-23 09:52:04 +01001311 (void)dict_get_tv(args, "files", &t);
1312 row = (int)dict_get_number(args, "row");
1313 col = (int)dict_get_number(args, "col");
1314 mods = (int)dict_get_number(args, "modifiers");
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001315
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001316 if (t.v_type != VAR_LIST || list_len(t.vval.v_list) == 0)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001317 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001318
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001319 l = t.vval.v_list;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001320 fnames = ALLOC_MULT(char_u *, list_len(l));
1321 if (fnames == NULL)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001322 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001323
1324 FOR_ALL_LIST_ITEMS(l, li)
1325 {
1326 // ignore non-string items
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001327 if (li->li_tv.v_type != VAR_STRING
1328 || li->li_tv.vval.v_string == NULL)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001329 continue;
1330
1331 fnames[count] = vim_strsave(li->li_tv.vval.v_string);
1332 if (fnames[count] == NULL)
1333 {
1334 while (--count >= 0)
1335 vim_free(fnames[count]);
1336 vim_free(fnames);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001337 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001338 }
1339 count++;
1340 }
1341
1342 if (count > 0)
1343 gui_handle_drop(TEXT_X(col - 1), TEXT_Y(row - 1), mods, fnames, count);
1344 else
1345 vim_free(fnames);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001346# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001347
1348 return TRUE;
1349}
1350
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001351#if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001352 static int
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001353test_gui_find_repl(dict_T *args)
1354{
1355 int flags;
1356 char_u *find_text;
1357 char_u *repl_text;
1358 int forward;
1359 int retval;
1360
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001361 if (!dict_has_key(args, "find_text")
1362 || !dict_has_key(args, "repl_text")
1363 || !dict_has_key(args, "flags")
1364 || !dict_has_key(args, "forward"))
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001365 return FALSE;
1366
Bram Moolenaard61efa52022-07-23 09:52:04 +01001367 find_text = dict_get_string(args, "find_text", TRUE);
1368 repl_text = dict_get_string(args, "repl_text", TRUE);
1369 flags = (int)dict_get_number(args, "flags");
1370 forward = (int)dict_get_number(args, "forward");
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001371
1372 retval = gui_do_findrepl(flags, find_text, repl_text, forward);
1373 vim_free(find_text);
1374 vim_free(repl_text);
1375
1376 return retval;
1377}
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001378#endif
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001379
1380 static int
1381test_gui_mouse_event(dict_T *args)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001382{
1383 int button;
1384 int row;
1385 int col;
1386 int repeated_click;
1387 int_u mods;
Ernie Raelc4cb5442022-04-03 15:47:28 +01001388 int move;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001389
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001390 if (!dict_has_key(args, "row")
1391 || !dict_has_key(args, "col"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001392 return FALSE;
1393
Ernie Raelc4cb5442022-04-03 15:47:28 +01001394 // Note: "move" is optional, requires fewer arguments
Bram Moolenaard61efa52022-07-23 09:52:04 +01001395 move = (int)dict_get_bool(args, "move", FALSE);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001396
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001397 if (!move && (!dict_has_key(args, "button")
1398 || !dict_has_key(args, "multiclick")
1399 || !dict_has_key(args, "modifiers")))
Ernie Raelc4cb5442022-04-03 15:47:28 +01001400 return FALSE;
1401
Bram Moolenaard61efa52022-07-23 09:52:04 +01001402 row = (int)dict_get_number(args, "row");
1403 col = (int)dict_get_number(args, "col");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001404
Ernie Raelc4cb5442022-04-03 15:47:28 +01001405 if (move)
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001406 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001407 int pY = row;
1408 int pX = col;
1409 // the "move" argument expects row and col coordnates to be in pixels,
1410 // unless "cell" is specified and is TRUE.
Bram Moolenaard61efa52022-07-23 09:52:04 +01001411 if (dict_get_bool(args, "cell", FALSE))
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001412 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001413 // calculate the middle of the character cell
Hirohito Higashifbe4a8f2025-04-27 15:28:30 +02001414 // Note: Cell coordinates are 1-based from Vim script
Christopher Plewright20b795e2022-12-20 20:01:58 +00001415 pY = (row - 1) * gui.char_height + gui.char_height / 2;
1416 pX = (col - 1) * gui.char_width + gui.char_width / 2;
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001417 }
Christopher Plewright20b795e2022-12-20 20:01:58 +00001418 gui_mouse_moved(pX, pY);
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001419 }
Ernie Raelc4cb5442022-04-03 15:47:28 +01001420 else
1421 {
Bram Moolenaard61efa52022-07-23 09:52:04 +01001422 button = (int)dict_get_number(args, "button");
1423 repeated_click = (int)dict_get_number(args, "multiclick");
1424 mods = (int)dict_get_number(args, "modifiers");
Ernie Raelc4cb5442022-04-03 15:47:28 +01001425
LemonBoyc27747e2022-05-07 12:25:40 +01001426 // Reset the scroll values to known values.
1427 // XXX: Remove this when/if the scroll step is made configurable.
1428 mouse_set_hor_scroll_step(6);
1429 mouse_set_vert_scroll_step(3);
1430
Ernie Raelc4cb5442022-04-03 15:47:28 +01001431 gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1),
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001432 repeated_click, mods);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001433 }
1434
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001435 return TRUE;
1436}
1437
1438 static int
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001439test_gui_scrollbar(dict_T *args)
1440{
1441 char_u *which;
1442 long value;
1443 int dragging;
1444 scrollbar_T *sb = NULL;
1445
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001446 if (!dict_has_key(args, "which")
1447 || !dict_has_key(args, "value")
1448 || !dict_has_key(args, "dragging"))
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001449 return FALSE;
1450
Bram Moolenaard61efa52022-07-23 09:52:04 +01001451 which = dict_get_string(args, "which", FALSE);
1452 value = (long)dict_get_number(args, "value");
1453 dragging = (int)dict_get_number(args, "dragging");
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001454
1455 if (STRCMP(which, "left") == 0)
1456 sb = &curwin->w_scrollbars[SBAR_LEFT];
1457 else if (STRCMP(which, "right") == 0)
1458 sb = &curwin->w_scrollbars[SBAR_RIGHT];
1459 else if (STRCMP(which, "hor") == 0)
1460 sb = &gui.bottom_sbar;
1461 if (sb == NULL)
1462 {
1463 semsg(_(e_invalid_argument_str), which);
1464 return FALSE;
1465 }
1466 gui_drag_scrollbar(sb, value, dragging);
1467# ifndef USE_ON_FLY_SCROLL
1468 // need to loop through normal_cmd() to handle the scroll events
1469 exec_normal(FALSE, TRUE, FALSE);
1470# endif
1471
1472 return TRUE;
1473}
1474
1475 static int
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001476test_gui_tabline_event(dict_T *args UNUSED)
1477{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001478# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001479 int tabnr;
1480
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001481 if (!dict_has_key(args, "tabnr"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001482 return FALSE;
1483
Bram Moolenaard61efa52022-07-23 09:52:04 +01001484 tabnr = (int)dict_get_number(args, "tabnr");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001485
1486 return send_tabline_event(tabnr);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001487# else
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001488 return FALSE;
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001489# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001490}
1491
1492 static int
1493test_gui_tabmenu_event(dict_T *args UNUSED)
1494{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001495# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001496 int tabnr;
1497 int item;
1498
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001499 if (!dict_has_key(args, "tabnr")
1500 || !dict_has_key(args, "item"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001501 return FALSE;
1502
Bram Moolenaard61efa52022-07-23 09:52:04 +01001503 tabnr = (int)dict_get_number(args, "tabnr");
1504 item = (int)dict_get_number(args, "item");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001505
1506 send_tabline_menu_event(tabnr, item);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001507# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001508 return TRUE;
1509}
1510# endif
1511
1512 void
Christopher Plewright20b795e2022-12-20 20:01:58 +00001513f_test_mswin_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1514{
1515# ifdef MSWIN
1516 rettv->v_type = VAR_BOOL;
1517 rettv->vval.v_number = FALSE;
1518
1519 if (sandbox != 0)
1520 {
1521 emsg(_(e_not_allowed_in_sandbox));
1522 return;
1523 }
1524
1525 if (check_for_string_arg(argvars, 0) == FAIL
1526 || check_for_dict_arg(argvars, 1) == FAIL
1527 || argvars[1].vval.v_dict == NULL)
1528 return;
1529
1530 char_u *event = tv_get_string(&argvars[0]);
1531 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1532
1533# endif
1534}
1535
1536 void
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001537f_test_gui_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1538{
1539# ifdef FEAT_GUI
1540 char_u *event;
1541
1542 rettv->v_type = VAR_BOOL;
1543 rettv->vval.v_number = FALSE;
1544
Yegappan Lakshmanan81a3ff92022-07-23 05:04:16 +01001545 if (sandbox != 0)
1546 {
1547 emsg(_(e_not_allowed_in_sandbox));
1548 return;
1549 }
1550
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001551 if (check_for_string_arg(argvars, 0) == FAIL
1552 || check_for_dict_arg(argvars, 1) == FAIL
1553 || argvars[1].vval.v_dict == NULL)
1554 return;
1555
1556 event = tv_get_string(&argvars[0]);
1557 if (STRCMP(event, "dropfiles") == 0)
1558 rettv->vval.v_number = test_gui_drop_files(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001559# if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001560 else if (STRCMP(event, "findrepl") == 0)
1561 rettv->vval.v_number = test_gui_find_repl(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001562# endif
Christopher Plewright20b795e2022-12-20 20:01:58 +00001563# ifdef MSWIN
Anton Sharonov68d94722024-01-23 23:19:02 +01001564 else if (STRCMP(event, "key") == 0 || STRCMP(event, "mouse") == 0 || STRCMP(event, "set_keycode_trans_strategy") == 0)
Christopher Plewright20b795e2022-12-20 20:01:58 +00001565 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1566# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001567 else if (STRCMP(event, "mouse") == 0)
1568 rettv->vval.v_number = test_gui_mouse_event(argvars[1].vval.v_dict);
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001569 else if (STRCMP(event, "scrollbar") == 0)
1570 rettv->vval.v_number = test_gui_scrollbar(argvars[1].vval.v_dict);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001571 else if (STRCMP(event, "tabline") == 0)
1572 rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict);
1573 else if (STRCMP(event, "tabmenu") == 0)
1574 rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict);
1575 else
1576 {
1577 semsg(_(e_invalid_argument_str), event);
1578 return;
1579 }
1580# endif
1581}
1582
1583 void
1584f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
1585{
1586 if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
1587 return;
1588
1589 time_for_testing = (time_t)tv_get_number(&argvars[0]);
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001590}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001591
1592#endif // defined(FEAT_EVAL)