blob: 3e9e07704b1bedf24156a1b7f0c63a4073bf4b81 [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 {
zeertzjq53f5e512023-05-04 18:58:22 +0100226 if (atype == ASSERT_FAILS)
227 ga_concat(gap, (char_u *)"'");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200228 ga_concat_shorten_esc(gap, exp_str);
zeertzjq53f5e512023-05-04 18:58:22 +0100229 if (atype == ASSERT_FAILS)
230 ga_concat(gap, (char_u *)"'");
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100231 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200232 if (atype != ASSERT_NOTEQUAL)
233 {
234 if (atype == ASSERT_MATCH)
235 ga_concat(gap, (char_u *)" does not match ");
236 else if (atype == ASSERT_NOTMATCH)
237 ga_concat(gap, (char_u *)" does match ");
238 else
239 ga_concat(gap, (char_u *)" but got ");
240 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
241 vim_free(tofree);
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200242
243 if (omitted != 0)
244 {
245 char buf[100];
246
247 vim_snprintf(buf, 100, " - %d equal item%s omitted",
248 omitted, omitted == 1 ? "" : "s");
249 ga_concat(gap, (char_u *)buf);
250 }
251 }
252
253 if (did_copy)
254 {
255 clear_tv(exp_tv);
256 clear_tv(got_tv);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200257 }
258}
259
260 static int
261assert_equal_common(typval_T *argvars, assert_type_T atype)
262{
263 garray_T ga;
264
265 if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
266 != (atype == ASSERT_EQUAL))
267 {
268 prepare_assert_error(&ga);
269 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
270 atype);
271 assert_error(&ga);
272 ga_clear(&ga);
273 return 1;
274 }
275 return 0;
276}
277
278 static int
279assert_match_common(typval_T *argvars, assert_type_T atype)
280{
281 garray_T ga;
282 char_u buf1[NUMBUFLEN];
283 char_u buf2[NUMBUFLEN];
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200284
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200285 if (in_vim9script()
286 && (check_for_string_arg(argvars, 0) == FAIL
287 || check_for_string_arg(argvars, 1) == FAIL
288 || check_for_opt_string_arg(argvars, 2) == FAIL))
289 return 1;
290
zeertzjq12e7a1f2023-05-06 12:20:05 +0100291 char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
292 char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
293 if (pat != NULL && text != NULL
Bram Moolenaar7177da92020-07-12 23:09:20 +0200294 && pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200295 {
296 prepare_assert_error(&ga);
297 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
298 atype);
299 assert_error(&ga);
300 ga_clear(&ga);
301 return 1;
302 }
303 return 0;
304}
305
306/*
307 * Common for assert_true() and assert_false().
308 * Return non-zero for failure.
309 */
310 static int
311assert_bool(typval_T *argvars, int isTrue)
312{
313 int error = FALSE;
314 garray_T ga;
315
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +0100316 if (argvars[0].v_type == VAR_BOOL
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200317 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
318 return 0;
319 if (argvars[0].v_type != VAR_NUMBER
320 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
321 || error)
322 {
323 prepare_assert_error(&ga);
324 fill_assert_error(&ga, &argvars[1],
325 (char_u *)(isTrue ? "True" : "False"),
326 NULL, &argvars[0], ASSERT_OTHER);
327 assert_error(&ga);
328 ga_clear(&ga);
329 return 1;
330 }
331 return 0;
332}
333
334 static void
335assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
336{
337 char_u *tofree;
338 char_u numbuf[NUMBUFLEN];
339
340 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
341 {
342 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
343 vim_free(tofree);
344 }
345 else
346 ga_concat(gap, cmd);
347}
348
349 static int
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200350assert_beeps(typval_T *argvars, int no_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200351{
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200352 char_u *cmd;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200353 garray_T ga;
354 int ret = 0;
355
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200356 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
357 return 0;
358
359 cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200360 called_vim_beep = FALSE;
361 suppress_errthrow = TRUE;
362 emsg_silent = FALSE;
363 do_cmdline_cmd(cmd);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200364 if (no_beep ? called_vim_beep : !called_vim_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200365 {
366 prepare_assert_error(&ga);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200367 if (no_beep)
368 ga_concat(&ga, (char_u *)"command did beep: ");
369 else
370 ga_concat(&ga, (char_u *)"command did not beep: ");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200371 ga_concat(&ga, cmd);
372 assert_error(&ga);
373 ga_clear(&ga);
374 ret = 1;
375 }
376
377 suppress_errthrow = FALSE;
378 emsg_on_display = FALSE;
379 return ret;
380}
381
382/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200383 * "assert_beeps(cmd)" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200384 */
385 void
386f_assert_beeps(typval_T *argvars, typval_T *rettv)
387{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200388 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
389 return;
390
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200391 rettv->vval.v_number = assert_beeps(argvars, FALSE);
392}
393
394/*
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +0200395 * "assert_nobeep(cmd)" function
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200396 */
397 void
398f_assert_nobeep(typval_T *argvars, typval_T *rettv)
399{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200400 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
401 return;
402
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200403 rettv->vval.v_number = assert_beeps(argvars, TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200404}
405
406/*
407 * "assert_equal(expected, actual[, msg])" function
408 */
409 void
410f_assert_equal(typval_T *argvars, typval_T *rettv)
411{
412 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
413}
414
415 static int
416assert_equalfile(typval_T *argvars)
417{
418 char_u buf1[NUMBUFLEN];
419 char_u buf2[NUMBUFLEN];
420 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
421 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200422 FILE *fd1;
423 FILE *fd2;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200424 char line1[200];
425 char line2[200];
426 int lineidx = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200427
zeertzjq12e7a1f2023-05-06 12:20:05 +0100428 if (fname1 == NULL || fname2 == NULL)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200429 return 0;
430
431 IObuff[0] = NUL;
432 fd1 = mch_fopen((char *)fname1, READBIN);
433 if (fd1 == NULL)
434 {
zeertzjq12e7a1f2023-05-06 12:20:05 +0100435 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str,
436 fname1);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200437 }
438 else
439 {
440 fd2 = mch_fopen((char *)fname2, READBIN);
441 if (fd2 == NULL)
442 {
443 fclose(fd1);
zeertzjq12e7a1f2023-05-06 12:20:05 +0100444 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str,
445 fname2);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200446 }
447 else
448 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200449 int c1, c2;
450 long count = 0;
451 long linecount = 1;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200452
453 for (;;)
454 {
455 c1 = fgetc(fd1);
456 c2 = fgetc(fd2);
457 if (c1 == EOF)
458 {
459 if (c2 != EOF)
460 STRCPY(IObuff, "first file is shorter");
461 break;
462 }
463 else if (c2 == EOF)
464 {
465 STRCPY(IObuff, "second file is shorter");
466 break;
467 }
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200468 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200469 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200470 line1[lineidx] = c1;
471 line2[lineidx] = c2;
472 ++lineidx;
473 if (c1 != c2)
474 {
475 vim_snprintf((char *)IObuff, IOSIZE,
476 "difference at byte %ld, line %ld",
477 count, linecount);
478 break;
479 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200480 }
481 ++count;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200482 if (c1 == NL)
483 {
484 ++linecount;
485 lineidx = 0;
486 }
487 else if (lineidx + 2 == (int)sizeof(line1))
488 {
489 mch_memmove(line1, line1 + 100, lineidx - 100);
490 mch_memmove(line2, line2 + 100, lineidx - 100);
491 lineidx -= 100;
492 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200493 }
494 fclose(fd1);
495 fclose(fd2);
496 }
497 }
zeertzjq12e7a1f2023-05-06 12:20:05 +0100498
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200499 if (IObuff[0] != NUL)
500 {
zeertzjq12e7a1f2023-05-06 12:20:05 +0100501 garray_T ga;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200502 prepare_assert_error(&ga);
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200503 if (argvars[2].v_type != VAR_UNKNOWN)
504 {
505 char_u numbuf[NUMBUFLEN];
506 char_u *tofree;
507
508 ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
509 vim_free(tofree);
510 ga_concat(&ga, (char_u *)": ");
511 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200512 ga_concat(&ga, IObuff);
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200513 if (lineidx > 0)
514 {
515 line1[lineidx] = NUL;
516 line2[lineidx] = NUL;
517 ga_concat(&ga, (char_u *)" after \"");
518 ga_concat(&ga, (char_u *)line1);
519 if (STRCMP(line1, line2) != 0)
520 {
521 ga_concat(&ga, (char_u *)"\" vs \"");
522 ga_concat(&ga, (char_u *)line2);
523 }
524 ga_concat(&ga, (char_u *)"\"");
525 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200526 assert_error(&ga);
527 ga_clear(&ga);
528 return 1;
529 }
zeertzjq12e7a1f2023-05-06 12:20:05 +0100530
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200531 return 0;
532}
533
534/*
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200535 * "assert_equalfile(fname-one, fname-two[, msg])" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200536 */
537 void
538f_assert_equalfile(typval_T *argvars, typval_T *rettv)
539{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200540 if (in_vim9script()
541 && (check_for_string_arg(argvars, 0) == FAIL
542 || check_for_string_arg(argvars, 1) == FAIL
543 || check_for_opt_string_arg(argvars, 2) == FAIL))
544 return;
545
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200546 rettv->vval.v_number = assert_equalfile(argvars);
547}
548
549/*
550 * "assert_notequal(expected, actual[, msg])" function
551 */
552 void
553f_assert_notequal(typval_T *argvars, typval_T *rettv)
554{
555 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
556}
557
558/*
559 * "assert_exception(string[, msg])" function
560 */
561 void
562f_assert_exception(typval_T *argvars, typval_T *rettv)
563{
564 garray_T ga;
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200565 char_u *error;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200566
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200567 if (in_vim9script()
568 && (check_for_string_arg(argvars, 0) == FAIL
569 || check_for_opt_string_arg(argvars, 1) == FAIL))
570 return;
571
572 error = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200573 if (*get_vim_var_str(VV_EXCEPTION) == NUL)
574 {
575 prepare_assert_error(&ga);
576 ga_concat(&ga, (char_u *)"v:exception is not set");
577 assert_error(&ga);
578 ga_clear(&ga);
579 rettv->vval.v_number = 1;
580 }
581 else if (error != NULL
582 && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
583 {
584 prepare_assert_error(&ga);
585 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
586 get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
587 assert_error(&ga);
588 ga_clear(&ga);
589 rettv->vval.v_number = 1;
590 }
591}
592
593/*
594 * "assert_fails(cmd [, error[, msg]])" function
595 */
596 void
597f_assert_fails(typval_T *argvars, typval_T *rettv)
598{
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200599 garray_T ga;
600 int save_trylevel = trylevel;
Bram Moolenaar53989552019-12-23 22:59:18 +0100601 int called_emsg_before = called_emsg;
Bram Moolenaar44d66522020-09-06 22:26:57 +0200602 char *wrong_arg_msg = NULL;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100603 char_u *tofree = NULL;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200604
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200605 if (check_for_string_or_number_arg(argvars, 0) == FAIL
606 || check_for_opt_string_or_list_arg(argvars, 1) == FAIL
607 || (argvars[1].v_type != VAR_UNKNOWN
608 && (argvars[2].v_type != VAR_UNKNOWN
609 && (check_for_opt_number_arg(argvars, 3) == FAIL
610 || (argvars[3].v_type != VAR_UNKNOWN
611 && check_for_opt_string_arg(argvars, 4) == FAIL)))))
612 return;
613
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200614 // trylevel must be zero for a ":throw" command to be considered failed
615 trylevel = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200616 suppress_errthrow = TRUE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100617 in_assert_fails = TRUE;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000618 ++no_wait_return;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200619
Bram Moolenaarf2206432022-11-09 00:44:30 +0000620 char_u *cmd = tv_get_string_chk(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200621 do_cmdline_cmd(cmd);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100622
623 // reset here for any errors reported below
624 trylevel = save_trylevel;
625 suppress_errthrow = FALSE;
626
Bram Moolenaar53989552019-12-23 22:59:18 +0100627 if (called_emsg == called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200628 {
629 prepare_assert_error(&ga);
630 ga_concat(&ga, (char_u *)"command did not fail: ");
631 assert_append_cmd_or_arg(&ga, argvars, cmd);
632 assert_error(&ga);
633 ga_clear(&ga);
634 rettv->vval.v_number = 1;
635 }
636 else if (argvars[1].v_type != VAR_UNKNOWN)
637 {
638 char_u buf[NUMBUFLEN];
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200639 char_u *expected;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100640 char_u *expected_str = NULL;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200641 int error_found = FALSE;
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200642 int error_found_index = 1;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200643 char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]"
644 : emsg_assert_fails_msg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200645
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200646 if (argvars[1].v_type == VAR_STRING)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200647 {
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200648 expected = tv_get_string_buf_chk(&argvars[1], buf);
649 error_found = expected == NULL
650 || strstr((char *)actual, (char *)expected) == NULL;
651 }
652 else if (argvars[1].v_type == VAR_LIST)
653 {
654 list_T *list = argvars[1].vval.v_list;
655 typval_T *tv;
656
657 if (list == NULL || list->lv_len < 1 || list->lv_len > 2)
658 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200659 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200660 goto theend;
661 }
662 CHECK_LIST_MATERIALIZE(list);
663 tv = &list->lv_first->li_tv;
664 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100665 if (expected == NULL)
666 goto theend;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200667 if (!pattern_match(expected, actual, FALSE))
668 {
669 error_found = TRUE;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100670 expected_str = expected;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200671 }
672 else if (list->lv_len == 2)
673 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100674 // make a copy, an error in pattern_match() may free it
675 tofree = actual = vim_strsave(get_vim_var_str(VV_ERRMSG));
676 if (actual != NULL)
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100677 {
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100678 tv = &list->lv_u.mat.lv_last->li_tv;
679 expected = tv_get_string_buf_chk(tv, buf);
Bram Moolenaar1540d332022-09-07 15:20:26 +0100680 if (expected == NULL)
681 goto theend;
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100682 if (!pattern_match(expected, actual, FALSE))
683 {
684 error_found = TRUE;
685 expected_str = expected;
686 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100687 }
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200688 }
689 }
690 else
691 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200692 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200693 goto theend;
694 }
695
Bram Moolenaar9b02d642020-08-18 23:24:13 +0200696 if (!error_found && argvars[2].v_type != VAR_UNKNOWN
Bram Moolenaar44d66522020-09-06 22:26:57 +0200697 && argvars[3].v_type != VAR_UNKNOWN)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200698 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200699 if (argvars[3].v_type != VAR_NUMBER)
700 {
701 wrong_arg_msg = e_assert_fails_fourth_argument;
702 goto theend;
703 }
704 else if (argvars[3].vval.v_number >= 0
705 && argvars[3].vval.v_number != emsg_assert_fails_lnum)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200706 {
707 error_found = TRUE;
708 error_found_index = 3;
709 }
Bram Moolenaar44d66522020-09-06 22:26:57 +0200710 if (!error_found && argvars[4].v_type != VAR_UNKNOWN)
711 {
712 if (argvars[4].v_type != VAR_STRING)
713 {
714 wrong_arg_msg = e_assert_fails_fifth_argument;
715 goto theend;
716 }
717 else if (argvars[4].vval.v_string != NULL
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200718 && !pattern_match(argvars[4].vval.v_string,
719 emsg_assert_fails_context, FALSE))
Bram Moolenaar44d66522020-09-06 22:26:57 +0200720 {
721 error_found = TRUE;
722 error_found_index = 4;
723 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200724 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200725 }
726
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200727 if (error_found)
728 {
729 typval_T actual_tv;
730
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200731 prepare_assert_error(&ga);
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200732 if (error_found_index == 3)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200733 {
734 actual_tv.v_type = VAR_NUMBER;
735 actual_tv.vval.v_number = emsg_assert_fails_lnum;
736 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200737 else if (error_found_index == 4)
738 {
739 actual_tv.v_type = VAR_STRING;
740 actual_tv.vval.v_string = emsg_assert_fails_context;
741 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200742 else
743 {
744 actual_tv.v_type = VAR_STRING;
745 actual_tv.vval.v_string = actual;
746 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100747 fill_assert_error(&ga, &argvars[2], expected_str,
zeertzjq53f5e512023-05-04 18:58:22 +0100748 &argvars[error_found_index], &actual_tv, ASSERT_FAILS);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200749 ga_concat(&ga, (char_u *)": ");
750 assert_append_cmd_or_arg(&ga, argvars, cmd);
751 assert_error(&ga);
752 ga_clear(&ga);
753 rettv->vval.v_number = 1;
754 }
755 }
756
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200757theend:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200758 trylevel = save_trylevel;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200759 suppress_errthrow = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100760 in_assert_fails = FALSE;
761 did_emsg = FALSE;
Bram Moolenaar8bea1712022-06-15 20:49:35 +0100762 got_int = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100763 msg_col = 0;
Bram Moolenaarf2206432022-11-09 00:44:30 +0000764 --no_wait_return;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100765 need_wait_return = FALSE;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200766 emsg_on_display = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100767 msg_scrolled = 0;
768 lines_left = Rows;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200769 VIM_CLEAR(emsg_assert_fails_msg);
Bram Moolenaar249e1b92022-08-14 22:23:02 +0100770 vim_free(tofree);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200771 set_vim_var_string(VV_ERRMSG, NULL, 0);
Bram Moolenaar44d66522020-09-06 22:26:57 +0200772 if (wrong_arg_msg != NULL)
773 emsg(_(wrong_arg_msg));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200774}
775
776/*
777 * "assert_false(actual[, msg])" function
778 */
779 void
780f_assert_false(typval_T *argvars, typval_T *rettv)
781{
782 rettv->vval.v_number = assert_bool(argvars, FALSE);
783}
784
785 static int
786assert_inrange(typval_T *argvars)
787{
788 garray_T ga;
789 int error = FALSE;
zeertzjq53f5e512023-05-04 18:58:22 +0100790 char_u expected_str[200];
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200791
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);
zeertzjq53f5e512023-05-04 18:58:22 +0100803 vim_snprintf((char *)expected_str, 200, "range %g - %g,",
804 flower, fupper);
805 fill_assert_error(&ga, &argvars[3], expected_str, NULL,
806 &argvars[2], ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200807 assert_error(&ga);
808 ga_clear(&ga);
809 return 1;
810 }
811 }
812 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200813 {
814 varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
815 varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
816 varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
817
818 if (error)
819 return 0;
820 if (actual < lower || actual > upper)
821 {
822 prepare_assert_error(&ga);
zeertzjq53f5e512023-05-04 18:58:22 +0100823 vim_snprintf((char *)expected_str, 200, "range %ld - %ld,",
824 (long)lower, (long)upper);
825 fill_assert_error(&ga, &argvars[3], expected_str, NULL,
826 &argvars[2], ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200827 assert_error(&ga);
828 ga_clear(&ga);
829 return 1;
830 }
831 }
832 return 0;
833}
834
835/*
836 * "assert_inrange(lower, upper[, msg])" function
837 */
838 void
839f_assert_inrange(typval_T *argvars, typval_T *rettv)
840{
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200841 if (check_for_float_or_nr_arg(argvars, 0) == FAIL
842 || check_for_float_or_nr_arg(argvars, 1) == FAIL
843 || check_for_float_or_nr_arg(argvars, 2) == FAIL
844 || check_for_opt_string_arg(argvars, 3) == FAIL)
845 return;
846
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200847 rettv->vval.v_number = assert_inrange(argvars);
848}
849
850/*
851 * "assert_match(pattern, actual[, msg])" function
852 */
853 void
854f_assert_match(typval_T *argvars, typval_T *rettv)
855{
856 rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
857}
858
859/*
860 * "assert_notmatch(pattern, actual[, msg])" function
861 */
862 void
863f_assert_notmatch(typval_T *argvars, typval_T *rettv)
864{
865 rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
866}
867
868/*
869 * "assert_report(msg)" function
870 */
871 void
872f_assert_report(typval_T *argvars, typval_T *rettv)
873{
874 garray_T ga;
875
Yegappan Lakshmananc72bdd22021-07-11 19:44:18 +0200876 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
877 return;
878
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200879 prepare_assert_error(&ga);
880 ga_concat(&ga, tv_get_string(&argvars[0]));
881 assert_error(&ga);
882 ga_clear(&ga);
883 rettv->vval.v_number = 1;
884}
885
886/*
887 * "assert_true(actual[, msg])" function
888 */
889 void
890f_assert_true(typval_T *argvars, typval_T *rettv)
891{
892 rettv->vval.v_number = assert_bool(argvars, TRUE);
893}
894
895/*
896 * "test_alloc_fail(id, countdown, repeat)" function
897 */
898 void
899f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
900{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200901 if (in_vim9script()
902 && (check_for_number_arg(argvars, 0) == FAIL
903 || check_for_number_arg(argvars, 1) == FAIL
904 || check_for_number_arg(argvars, 2) == FAIL))
905 return;
906
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200907 if (argvars[0].v_type != VAR_NUMBER
908 || argvars[0].vval.v_number <= 0
909 || argvars[1].v_type != VAR_NUMBER
910 || argvars[1].vval.v_number < 0
911 || argvars[2].v_type != VAR_NUMBER)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000912 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200913 else
914 {
915 alloc_fail_id = argvars[0].vval.v_number;
916 if (alloc_fail_id >= aid_last)
Bram Moolenaar436b5ad2021-12-31 22:49:24 +0000917 emsg(_(e_invalid_argument));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200918 alloc_fail_countdown = argvars[1].vval.v_number;
919 alloc_fail_repeat = argvars[2].vval.v_number;
920 did_outofmem_msg = FALSE;
921 }
922}
923
924/*
925 * "test_autochdir()"
926 */
927 void
928f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
929{
930#if defined(FEAT_AUTOCHDIR)
931 test_autochdir = TRUE;
932#endif
933}
934
935/*
936 * "test_feedinput()"
937 */
938 void
939f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
940{
941#ifdef USE_INPUT_BUF
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200942 char_u *val;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200943
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200944 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
945 return;
946
947 val = tv_get_string_chk(&argvars[0]);
Bram Moolenaar272ca952020-01-28 20:49:11 +0100948# ifdef VIMDLL
949 // this doesn't work in the console
950 if (!gui.in_use)
951 return;
952# endif
953
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200954 if (val != NULL)
955 {
956 trash_input_buf();
957 add_to_input_buf_csi(val, (int)STRLEN(val));
958 }
959#endif
960}
961
962/*
963 * "test_getvalue({name})" function
964 */
965 void
966f_test_getvalue(typval_T *argvars, typval_T *rettv)
967{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100968 char_u *name;
969
970 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200971 return;
972
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100973 name = tv_get_string(&argvars[0]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200974
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100975 if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
976 rettv->vval.v_number = need_fileinfo;
977 else
978 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200979}
980
981/*
982 * "test_option_not_set({name})" function
983 */
984 void
985f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
986{
987 char_u *name = (char_u *)"";
988
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100989 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200990 return;
991
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100992 name = tv_get_string(&argvars[0]);
993 if (reset_option_was_set(name) == FAIL)
994 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200995}
996
997/*
998 * "test_override({name}, {val})" function
999 */
1000 void
1001f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
1002{
1003 char_u *name = (char_u *)"";
1004 int val;
1005 static int save_starting = -1;
1006
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001007 if (check_for_string_arg(argvars, 0) == FAIL
1008 || check_for_number_arg(argvars, 1) == FAIL)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02001009 return;
1010
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001011 name = tv_get_string(&argvars[0]);
1012 val = (int)tv_get_number(&argvars[1]);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001013
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001014 if (STRCMP(name, (char_u *)"redraw") == 0)
1015 disable_redraw_for_testing = val;
1016 else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
1017 ignore_redraw_flag_for_testing = val;
1018 else if (STRCMP(name, (char_u *)"char_avail") == 0)
1019 disable_char_avail_for_testing = val;
1020 else if (STRCMP(name, (char_u *)"starting") == 0)
1021 {
1022 if (val)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001023 {
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001024 if (save_starting < 0)
1025 save_starting = starting;
1026 starting = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001027 }
1028 else
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001029 {
1030 starting = save_starting;
1031 save_starting = -1;
1032 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001033 }
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001034 else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
1035 nfa_fail_for_testing = val;
1036 else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
1037 no_query_mouse_for_testing = val;
1038 else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
1039 no_wait_return = val;
1040 else if (STRCMP(name, (char_u *)"ui_delay") == 0)
1041 ui_delay_for_testing = val;
Bram Moolenaar9d383f32023-05-14 21:38:12 +01001042 else if (STRCMP(name, (char_u *)"unreachable") == 0)
1043 ignore_unreachable_code_for_testing = val;
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001044 else if (STRCMP(name, (char_u *)"term_props") == 0)
1045 reset_term_props_on_termresponse = val;
1046 else if (STRCMP(name, (char_u *)"vterm_title") == 0)
1047 disable_vterm_title_for_testing = val;
1048 else if (STRCMP(name, (char_u *)"uptime") == 0)
1049 override_sysinfo_uptime = val;
1050 else if (STRCMP(name, (char_u *)"alloc_lines") == 0)
1051 ml_get_alloc_lines = val;
1052 else if (STRCMP(name, (char_u *)"autoload") == 0)
1053 override_autoload = val;
Yegappan Lakshmanan5715a722024-05-03 18:24:07 +02001054 else if (STRCMP(name, (char_u *)"defcompile") == 0)
1055 override_defcompile = val;
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001056 else if (STRCMP(name, (char_u *)"ALL") == 0)
1057 {
1058 disable_char_avail_for_testing = FALSE;
1059 disable_redraw_for_testing = FALSE;
1060 ignore_redraw_flag_for_testing = FALSE;
1061 nfa_fail_for_testing = FALSE;
1062 no_query_mouse_for_testing = FALSE;
1063 ui_delay_for_testing = 0;
1064 reset_term_props_on_termresponse = FALSE;
1065 override_sysinfo_uptime = -1;
1066 // ml_get_alloc_lines is not reset by "ALL"
1067 if (save_starting >= 0)
1068 {
1069 starting = save_starting;
1070 save_starting = -1;
1071 }
1072 }
1073 else
1074 semsg(_(e_invalid_argument_str), name);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001075}
1076
1077/*
1078 * "test_refcount({expr})" function
1079 */
1080 void
1081f_test_refcount(typval_T *argvars, typval_T *rettv)
1082{
1083 int retval = -1;
1084
1085 switch (argvars[0].v_type)
1086 {
1087 case VAR_UNKNOWN:
Bram Moolenaar4c683752020-04-05 21:38:23 +02001088 case VAR_ANY:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001089 case VAR_VOID:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001090 case VAR_NUMBER:
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +01001091 case VAR_BOOL:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001092 case VAR_FLOAT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001093 case VAR_SPECIAL:
1094 case VAR_STRING:
Bram Moolenaarf18332f2021-05-07 17:55:55 +02001095 case VAR_INSTR:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001096 break;
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01001097
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001098 case VAR_JOB:
1099#ifdef FEAT_JOB_CHANNEL
1100 if (argvars[0].vval.v_job != NULL)
1101 retval = argvars[0].vval.v_job->jv_refcount - 1;
1102#endif
1103 break;
1104 case VAR_CHANNEL:
1105#ifdef FEAT_JOB_CHANNEL
1106 if (argvars[0].vval.v_channel != NULL)
1107 retval = argvars[0].vval.v_channel->ch_refcount - 1;
1108#endif
1109 break;
1110 case VAR_FUNC:
1111 if (argvars[0].vval.v_string != NULL)
1112 {
1113 ufunc_T *fp;
1114
Bram Moolenaard9d2fd02022-01-13 21:15:21 +00001115 fp = find_func(argvars[0].vval.v_string, FALSE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001116 if (fp != NULL)
1117 retval = fp->uf_refcount;
1118 }
1119 break;
1120 case VAR_PARTIAL:
1121 if (argvars[0].vval.v_partial != NULL)
1122 retval = argvars[0].vval.v_partial->pt_refcount - 1;
1123 break;
1124 case VAR_BLOB:
1125 if (argvars[0].vval.v_blob != NULL)
1126 retval = argvars[0].vval.v_blob->bv_refcount - 1;
1127 break;
1128 case VAR_LIST:
1129 if (argvars[0].vval.v_list != NULL)
1130 retval = argvars[0].vval.v_list->lv_refcount - 1;
1131 break;
1132 case VAR_DICT:
1133 if (argvars[0].vval.v_dict != NULL)
1134 retval = argvars[0].vval.v_dict->dv_refcount - 1;
1135 break;
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01001136 case VAR_CLASS:
1137 if (argvars[0].vval.v_class != NULL)
1138 retval = argvars[0].vval.v_class->class_refcount - 1;
1139 break;
1140 case VAR_OBJECT:
1141 if (argvars[0].vval.v_object != NULL)
1142 retval = argvars[0].vval.v_object->obj_refcount - 1;
1143 break;
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +02001144 case VAR_TYPEALIAS:
1145 if (argvars[0].vval.v_typealias != NULL)
1146 retval = argvars[0].vval.v_typealias->ta_refcount - 1;
1147 break;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001148 }
1149
1150 rettv->v_type = VAR_NUMBER;
1151 rettv->vval.v_number = retval;
1152
1153}
1154
1155/*
1156 * "test_garbagecollect_now()" function
1157 */
1158 void
1159f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1160{
Bram Moolenaar0d6f5d92019-12-05 21:33:15 +01001161 // This is dangerous, any Lists and Dicts used internally may be freed
1162 // while still in use.
Bram Moolenaarb3d83982022-01-27 19:59:47 +00001163 if (!get_vim_var_nr(VV_TESTING))
1164 emsg(_(e_calling_test_garbagecollect_now_while_v_testing_is_not_set));
1165 else
1166 garbage_collect(TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001167}
1168
1169/*
1170 * "test_garbagecollect_soon()" function
1171 */
1172 void
1173f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1174{
1175 may_garbage_collect = TRUE;
1176}
1177
1178/*
1179 * "test_ignore_error()" function
1180 */
1181 void
1182f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
1183{
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001184 if (check_for_string_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001185 return;
1186
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001187 ignore_error_for_testing(tv_get_string(&argvars[0]));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001188}
1189
1190 void
1191f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
1192{
1193 rettv->v_type = VAR_BLOB;
1194 rettv->vval.v_blob = NULL;
1195}
1196
1197#ifdef FEAT_JOB_CHANNEL
1198 void
1199f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
1200{
1201 rettv->v_type = VAR_CHANNEL;
1202 rettv->vval.v_channel = NULL;
1203}
1204#endif
1205
1206 void
1207f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
1208{
1209 rettv_dict_set(rettv, NULL);
1210}
1211
1212#ifdef FEAT_JOB_CHANNEL
1213 void
1214f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
1215{
1216 rettv->v_type = VAR_JOB;
1217 rettv->vval.v_job = NULL;
1218}
1219#endif
1220
1221 void
1222f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
1223{
1224 rettv_list_set(rettv, NULL);
1225}
1226
1227 void
Bram Moolenaare69f6d02020-04-01 22:11:01 +02001228f_test_null_function(typval_T *argvars UNUSED, typval_T *rettv)
1229{
1230 rettv->v_type = VAR_FUNC;
1231 rettv->vval.v_string = NULL;
1232}
1233
1234 void
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001235f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
1236{
1237 rettv->v_type = VAR_PARTIAL;
1238 rettv->vval.v_partial = NULL;
1239}
1240
1241 void
1242f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
1243{
1244 rettv->v_type = VAR_STRING;
1245 rettv->vval.v_string = NULL;
1246}
1247
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001248 void
1249f_test_unknown(typval_T *argvars UNUSED, typval_T *rettv)
1250{
1251 rettv->v_type = VAR_UNKNOWN;
1252}
1253
1254 void
1255f_test_void(typval_T *argvars UNUSED, typval_T *rettv)
1256{
1257 rettv->v_type = VAR_VOID;
1258}
1259
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001260 void
1261f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
1262{
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02001263 if (in_vim9script()
1264 && (check_for_number_arg(argvars, 0) == FAIL
1265 || check_for_number_arg(argvars, 1) == FAIL))
1266 return;
1267
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +01001268 if (argvars[0].v_type != VAR_NUMBER || argvars[1].v_type != VAR_NUMBER)
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001269 {
Bram Moolenaar436b5ad2021-12-31 22:49:24 +00001270 emsg(_(e_invalid_argument));
Yegappan Lakshmanan7237cab2021-06-22 19:52:27 +02001271 return;
1272 }
1273
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001274 mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
1275 mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
1276}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001277
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001278# ifdef FEAT_GUI
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001279 static int
1280test_gui_drop_files(dict_T *args UNUSED)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001281{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001282# if defined(HAVE_DROP_FILE)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001283 int row;
1284 int col;
1285 int_u mods;
1286 char_u **fnames;
1287 int count = 0;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001288 typval_T t;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001289 list_T *l;
1290 listitem_T *li;
1291
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001292 if (!dict_has_key(args, "files")
1293 || !dict_has_key(args, "row")
1294 || !dict_has_key(args, "col")
1295 || !dict_has_key(args, "modifiers"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001296 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001297
Bram Moolenaard61efa52022-07-23 09:52:04 +01001298 (void)dict_get_tv(args, "files", &t);
1299 row = (int)dict_get_number(args, "row");
1300 col = (int)dict_get_number(args, "col");
1301 mods = (int)dict_get_number(args, "modifiers");
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001302
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001303 if (t.v_type != VAR_LIST || list_len(t.vval.v_list) == 0)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001304 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001305
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001306 l = t.vval.v_list;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001307 fnames = ALLOC_MULT(char_u *, list_len(l));
1308 if (fnames == NULL)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001309 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001310
1311 FOR_ALL_LIST_ITEMS(l, li)
1312 {
1313 // ignore non-string items
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001314 if (li->li_tv.v_type != VAR_STRING
1315 || li->li_tv.vval.v_string == NULL)
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001316 continue;
1317
1318 fnames[count] = vim_strsave(li->li_tv.vval.v_string);
1319 if (fnames[count] == NULL)
1320 {
1321 while (--count >= 0)
1322 vim_free(fnames[count]);
1323 vim_free(fnames);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001324 return FALSE;
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001325 }
1326 count++;
1327 }
1328
1329 if (count > 0)
1330 gui_handle_drop(TEXT_X(col - 1), TEXT_Y(row - 1), mods, fnames, count);
1331 else
1332 vim_free(fnames);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001333# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001334
1335 return TRUE;
1336}
1337
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001338#if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001339 static int
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001340test_gui_find_repl(dict_T *args)
1341{
1342 int flags;
1343 char_u *find_text;
1344 char_u *repl_text;
1345 int forward;
1346 int retval;
1347
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001348 if (!dict_has_key(args, "find_text")
1349 || !dict_has_key(args, "repl_text")
1350 || !dict_has_key(args, "flags")
1351 || !dict_has_key(args, "forward"))
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001352 return FALSE;
1353
Bram Moolenaard61efa52022-07-23 09:52:04 +01001354 find_text = dict_get_string(args, "find_text", TRUE);
1355 repl_text = dict_get_string(args, "repl_text", TRUE);
1356 flags = (int)dict_get_number(args, "flags");
1357 forward = (int)dict_get_number(args, "forward");
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001358
1359 retval = gui_do_findrepl(flags, find_text, repl_text, forward);
1360 vim_free(find_text);
1361 vim_free(repl_text);
1362
1363 return retval;
1364}
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001365#endif
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001366
1367 static int
1368test_gui_mouse_event(dict_T *args)
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001369{
1370 int button;
1371 int row;
1372 int col;
1373 int repeated_click;
1374 int_u mods;
Ernie Raelc4cb5442022-04-03 15:47:28 +01001375 int move;
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001376
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001377 if (!dict_has_key(args, "row")
1378 || !dict_has_key(args, "col"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001379 return FALSE;
1380
Ernie Raelc4cb5442022-04-03 15:47:28 +01001381 // Note: "move" is optional, requires fewer arguments
Bram Moolenaard61efa52022-07-23 09:52:04 +01001382 move = (int)dict_get_bool(args, "move", FALSE);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001383
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001384 if (!move && (!dict_has_key(args, "button")
1385 || !dict_has_key(args, "multiclick")
1386 || !dict_has_key(args, "modifiers")))
Ernie Raelc4cb5442022-04-03 15:47:28 +01001387 return FALSE;
1388
Bram Moolenaard61efa52022-07-23 09:52:04 +01001389 row = (int)dict_get_number(args, "row");
1390 col = (int)dict_get_number(args, "col");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001391
Ernie Raelc4cb5442022-04-03 15:47:28 +01001392 if (move)
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001393 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001394 int pY = row;
1395 int pX = col;
1396 // the "move" argument expects row and col coordnates to be in pixels,
1397 // unless "cell" is specified and is TRUE.
Bram Moolenaard61efa52022-07-23 09:52:04 +01001398 if (dict_get_bool(args, "cell", FALSE))
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001399 {
Christopher Plewright20b795e2022-12-20 20:01:58 +00001400 // calculate the middle of the character cell
1401 // Note: Cell coordinates are 1-based from vimscript
1402 pY = (row - 1) * gui.char_height + gui.char_height / 2;
1403 pX = (col - 1) * gui.char_width + gui.char_width / 2;
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001404 }
Christopher Plewright20b795e2022-12-20 20:01:58 +00001405 gui_mouse_moved(pX, pY);
Bram Moolenaar7add8d32022-05-16 15:27:46 +01001406 }
Ernie Raelc4cb5442022-04-03 15:47:28 +01001407 else
1408 {
Bram Moolenaard61efa52022-07-23 09:52:04 +01001409 button = (int)dict_get_number(args, "button");
1410 repeated_click = (int)dict_get_number(args, "multiclick");
1411 mods = (int)dict_get_number(args, "modifiers");
Ernie Raelc4cb5442022-04-03 15:47:28 +01001412
LemonBoyc27747e2022-05-07 12:25:40 +01001413 // Reset the scroll values to known values.
1414 // XXX: Remove this when/if the scroll step is made configurable.
1415 mouse_set_hor_scroll_step(6);
1416 mouse_set_vert_scroll_step(3);
1417
Ernie Raelc4cb5442022-04-03 15:47:28 +01001418 gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1),
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001419 repeated_click, mods);
Ernie Raelc4cb5442022-04-03 15:47:28 +01001420 }
1421
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001422 return TRUE;
1423}
1424
1425 static int
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001426test_gui_scrollbar(dict_T *args)
1427{
1428 char_u *which;
1429 long value;
1430 int dragging;
1431 scrollbar_T *sb = NULL;
1432
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001433 if (!dict_has_key(args, "which")
1434 || !dict_has_key(args, "value")
1435 || !dict_has_key(args, "dragging"))
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001436 return FALSE;
1437
Bram Moolenaard61efa52022-07-23 09:52:04 +01001438 which = dict_get_string(args, "which", FALSE);
1439 value = (long)dict_get_number(args, "value");
1440 dragging = (int)dict_get_number(args, "dragging");
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001441
1442 if (STRCMP(which, "left") == 0)
1443 sb = &curwin->w_scrollbars[SBAR_LEFT];
1444 else if (STRCMP(which, "right") == 0)
1445 sb = &curwin->w_scrollbars[SBAR_RIGHT];
1446 else if (STRCMP(which, "hor") == 0)
1447 sb = &gui.bottom_sbar;
1448 if (sb == NULL)
1449 {
1450 semsg(_(e_invalid_argument_str), which);
1451 return FALSE;
1452 }
1453 gui_drag_scrollbar(sb, value, dragging);
1454# ifndef USE_ON_FLY_SCROLL
1455 // need to loop through normal_cmd() to handle the scroll events
1456 exec_normal(FALSE, TRUE, FALSE);
1457# endif
1458
1459 return TRUE;
1460}
1461
1462 static int
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001463test_gui_tabline_event(dict_T *args UNUSED)
1464{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001465# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001466 int tabnr;
1467
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001468 if (!dict_has_key(args, "tabnr"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001469 return FALSE;
1470
Bram Moolenaard61efa52022-07-23 09:52:04 +01001471 tabnr = (int)dict_get_number(args, "tabnr");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001472
1473 return send_tabline_event(tabnr);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001474# else
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001475 return FALSE;
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001476# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001477}
1478
1479 static int
1480test_gui_tabmenu_event(dict_T *args UNUSED)
1481{
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001482# ifdef FEAT_GUI_TABLINE
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001483 int tabnr;
1484 int item;
1485
Yegappan Lakshmanan4829c1c2022-04-04 15:16:54 +01001486 if (!dict_has_key(args, "tabnr")
1487 || !dict_has_key(args, "item"))
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001488 return FALSE;
1489
Bram Moolenaard61efa52022-07-23 09:52:04 +01001490 tabnr = (int)dict_get_number(args, "tabnr");
1491 item = (int)dict_get_number(args, "item");
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001492
1493 send_tabline_menu_event(tabnr, item);
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001494# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001495 return TRUE;
1496}
1497# endif
1498
1499 void
Christopher Plewright20b795e2022-12-20 20:01:58 +00001500f_test_mswin_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1501{
1502# ifdef MSWIN
1503 rettv->v_type = VAR_BOOL;
1504 rettv->vval.v_number = FALSE;
1505
1506 if (sandbox != 0)
1507 {
1508 emsg(_(e_not_allowed_in_sandbox));
1509 return;
1510 }
1511
1512 if (check_for_string_arg(argvars, 0) == FAIL
1513 || check_for_dict_arg(argvars, 1) == FAIL
1514 || argvars[1].vval.v_dict == NULL)
1515 return;
1516
1517 char_u *event = tv_get_string(&argvars[0]);
1518 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1519
1520# endif
1521}
1522
1523 void
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001524f_test_gui_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1525{
1526# ifdef FEAT_GUI
1527 char_u *event;
1528
1529 rettv->v_type = VAR_BOOL;
1530 rettv->vval.v_number = FALSE;
1531
Yegappan Lakshmanan81a3ff92022-07-23 05:04:16 +01001532 if (sandbox != 0)
1533 {
1534 emsg(_(e_not_allowed_in_sandbox));
1535 return;
1536 }
1537
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001538 if (check_for_string_arg(argvars, 0) == FAIL
1539 || check_for_dict_arg(argvars, 1) == FAIL
1540 || argvars[1].vval.v_dict == NULL)
1541 return;
1542
1543 event = tv_get_string(&argvars[0]);
1544 if (STRCMP(event, "dropfiles") == 0)
1545 rettv->vval.v_number = test_gui_drop_files(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001546# if defined(FIND_REPLACE_DIALOG)
Yegappan Lakshmananec3637c2022-01-30 18:01:24 +00001547 else if (STRCMP(event, "findrepl") == 0)
1548 rettv->vval.v_number = test_gui_find_repl(argvars[1].vval.v_dict);
Bram Moolenaar4e3b3182022-02-01 10:16:00 +00001549# endif
Christopher Plewright20b795e2022-12-20 20:01:58 +00001550# ifdef MSWIN
Anton Sharonov68d94722024-01-23 23:19:02 +01001551 else if (STRCMP(event, "key") == 0 || STRCMP(event, "mouse") == 0 || STRCMP(event, "set_keycode_trans_strategy") == 0)
Christopher Plewright20b795e2022-12-20 20:01:58 +00001552 rettv->vval.v_number = test_mswin_event(event, argvars[1].vval.v_dict);
1553# endif
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001554 else if (STRCMP(event, "mouse") == 0)
1555 rettv->vval.v_number = test_gui_mouse_event(argvars[1].vval.v_dict);
Yegappan Lakshmanan9e0208f2022-01-31 17:40:55 +00001556 else if (STRCMP(event, "scrollbar") == 0)
1557 rettv->vval.v_number = test_gui_scrollbar(argvars[1].vval.v_dict);
Yegappan Lakshmanan06011e12022-01-30 12:37:29 +00001558 else if (STRCMP(event, "tabline") == 0)
1559 rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict);
1560 else if (STRCMP(event, "tabmenu") == 0)
1561 rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict);
1562 else
1563 {
1564 semsg(_(e_invalid_argument_str), event);
1565 return;
1566 }
1567# endif
1568}
1569
1570 void
1571f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
1572{
1573 if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
1574 return;
1575
1576 time_for_testing = (time_t)tv_get_number(&argvars[0]);
Yegappan Lakshmanan18d46582021-06-23 20:46:52 +02001577}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001578
1579#endif // defined(FEAT_EVAL)