blob: 740923735c0d60bfb170fb2e66d457653707b1fd [file] [log] [blame]
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001/* vi:set ts=8 sts=4 sw=4 noet:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * testing.c: Support for tests.
12 */
13
14#include "vim.h"
15
16#if defined(FEAT_EVAL) || defined(PROTO)
17
18/*
19 * Prepare "gap" for an assert error and add the sourcing position.
20 */
21 static void
22prepare_assert_error(garray_T *gap)
23{
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010024 char buf[NUMBUFLEN];
Bram Moolenaar4f25b1a2020-09-10 19:25:05 +020025 char_u *sname = estack_sfile(ESTACK_NONE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020026
27 ga_init2(gap, 1, 100);
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010028 if (sname != NULL)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020029 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010030 ga_concat(gap, sname);
31 if (SOURCING_LNUM > 0)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020032 ga_concat(gap, (char_u *)" ");
33 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010034 if (SOURCING_LNUM > 0)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020035 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010036 sprintf(buf, "line %ld", (long)SOURCING_LNUM);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020037 ga_concat(gap, (char_u *)buf);
38 }
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010039 if (sname != NULL || SOURCING_LNUM > 0)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020040 ga_concat(gap, (char_u *)": ");
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010041 vim_free(sname);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020042}
43
44/*
45 * Append "p[clen]" to "gap", escaping unprintable characters.
46 * Changes NL to \n, CR to \r, etc.
47 */
48 static void
49ga_concat_esc(garray_T *gap, char_u *p, int clen)
50{
51 char_u buf[NUMBUFLEN];
52
53 if (clen > 1)
54 {
55 mch_memmove(buf, p, clen);
56 buf[clen] = NUL;
57 ga_concat(gap, buf);
58 }
59 else switch (*p)
60 {
61 case BS: ga_concat(gap, (char_u *)"\\b"); break;
62 case ESC: ga_concat(gap, (char_u *)"\\e"); break;
63 case FF: ga_concat(gap, (char_u *)"\\f"); break;
64 case NL: ga_concat(gap, (char_u *)"\\n"); break;
65 case TAB: ga_concat(gap, (char_u *)"\\t"); break;
66 case CAR: ga_concat(gap, (char_u *)"\\r"); break;
67 case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
68 default:
Bram Moolenaar7177da92020-07-12 23:09:20 +020069 if (*p < ' ' || *p == 0x7f)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +020070 {
71 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
72 ga_concat(gap, buf);
73 }
74 else
75 ga_append(gap, *p);
76 break;
77 }
78}
79
80/*
81 * Append "str" to "gap", escaping unprintable characters.
82 * Changes NL to \n, CR to \r, etc.
83 */
84 static void
85ga_concat_shorten_esc(garray_T *gap, char_u *str)
86{
87 char_u *p;
88 char_u *s;
89 int c;
90 int clen;
91 char_u buf[NUMBUFLEN];
92 int same_len;
93
94 if (str == NULL)
95 {
96 ga_concat(gap, (char_u *)"NULL");
97 return;
98 }
99
100 for (p = str; *p != NUL; ++p)
101 {
102 same_len = 1;
103 s = p;
104 c = mb_ptr2char_adv(&s);
105 clen = s - p;
106 while (*s != NUL && c == mb_ptr2char(s))
107 {
108 ++same_len;
109 s += clen;
110 }
111 if (same_len > 20)
112 {
113 ga_concat(gap, (char_u *)"\\[");
114 ga_concat_esc(gap, p, clen);
115 ga_concat(gap, (char_u *)" occurs ");
116 vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
117 ga_concat(gap, buf);
118 ga_concat(gap, (char_u *)" times]");
119 p = s - 1;
120 }
121 else
122 ga_concat_esc(gap, p, clen);
123 }
124}
125
126/*
127 * Fill "gap" with information about an assert error.
128 */
129 static void
130fill_assert_error(
131 garray_T *gap,
132 typval_T *opt_msg_tv,
133 char_u *exp_str,
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200134 typval_T *exp_tv_arg,
135 typval_T *got_tv_arg,
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200136 assert_type_T atype)
137{
138 char_u numbuf[NUMBUFLEN];
139 char_u *tofree;
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200140 typval_T *exp_tv = exp_tv_arg;
141 typval_T *got_tv = got_tv_arg;
142 int did_copy = FALSE;
143 int omitted = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200144
Bram Moolenaar1d634542020-08-18 13:41:50 +0200145 if (opt_msg_tv->v_type != VAR_UNKNOWN
146 && !(opt_msg_tv->v_type == VAR_STRING
147 && (opt_msg_tv->vval.v_string == NULL
148 || *opt_msg_tv->vval.v_string == NUL)))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200149 {
150 ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
151 vim_free(tofree);
152 ga_concat(gap, (char_u *)": ");
153 }
154
155 if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
156 ga_concat(gap, (char_u *)"Pattern ");
157 else if (atype == ASSERT_NOTEQUAL)
158 ga_concat(gap, (char_u *)"Expected not equal to ");
159 else
160 ga_concat(gap, (char_u *)"Expected ");
161 if (exp_str == NULL)
162 {
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200163 // When comparing dictionaries, drop the items that are equal, so that
164 // it's a lot easier to see what differs.
165 if (atype != ASSERT_NOTEQUAL
166 && exp_tv->v_type == VAR_DICT && got_tv->v_type == VAR_DICT
167 && exp_tv->vval.v_dict != NULL && got_tv->vval.v_dict != NULL)
168 {
169 dict_T *exp_d = exp_tv->vval.v_dict;
170 dict_T *got_d = got_tv->vval.v_dict;
171 hashitem_T *hi;
172 dictitem_T *item2;
173 int todo;
174
175 did_copy = TRUE;
176 exp_tv->vval.v_dict = dict_alloc();
177 got_tv->vval.v_dict = dict_alloc();
178 if (exp_tv->vval.v_dict == NULL || got_tv->vval.v_dict == NULL)
179 return;
180
181 todo = (int)exp_d->dv_hashtab.ht_used;
182 for (hi = exp_d->dv_hashtab.ht_array; todo > 0; ++hi)
183 {
184 if (!HASHITEM_EMPTY(hi))
185 {
186 item2 = dict_find(got_d, hi->hi_key, -1);
187 if (item2 == NULL || !tv_equal(&HI2DI(hi)->di_tv,
188 &item2->di_tv, FALSE, FALSE))
189 {
190 // item of exp_d not present in got_d or values differ.
191 dict_add_tv(exp_tv->vval.v_dict,
192 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
193 if (item2 != NULL)
194 dict_add_tv(got_tv->vval.v_dict,
195 (char *)hi->hi_key, &item2->di_tv);
196 }
197 else
198 ++omitted;
199 --todo;
200 }
201 }
202
203 // Add items only present in got_d.
204 todo = (int)got_d->dv_hashtab.ht_used;
205 for (hi = got_d->dv_hashtab.ht_array; todo > 0; ++hi)
206 {
207 if (!HASHITEM_EMPTY(hi))
208 {
209 item2 = dict_find(exp_d, hi->hi_key, -1);
210 if (item2 == NULL)
211 // item of got_d not present in exp_d
212 dict_add_tv(got_tv->vval.v_dict,
213 (char *)hi->hi_key, &HI2DI(hi)->di_tv);
214 --todo;
215 }
216 }
217 }
218
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200219 ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
220 vim_free(tofree);
221 }
222 else
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100223 {
224 ga_concat(gap, (char_u *)"'");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200225 ga_concat_shorten_esc(gap, exp_str);
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100226 ga_concat(gap, (char_u *)"'");
227 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200228 if (atype != ASSERT_NOTEQUAL)
229 {
230 if (atype == ASSERT_MATCH)
231 ga_concat(gap, (char_u *)" does not match ");
232 else if (atype == ASSERT_NOTMATCH)
233 ga_concat(gap, (char_u *)" does match ");
234 else
235 ga_concat(gap, (char_u *)" but got ");
236 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
237 vim_free(tofree);
Bram Moolenaar4a021df2020-06-13 15:13:38 +0200238
239 if (omitted != 0)
240 {
241 char buf[100];
242
243 vim_snprintf(buf, 100, " - %d equal item%s omitted",
244 omitted, omitted == 1 ? "" : "s");
245 ga_concat(gap, (char_u *)buf);
246 }
247 }
248
249 if (did_copy)
250 {
251 clear_tv(exp_tv);
252 clear_tv(got_tv);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200253 }
254}
255
256 static int
257assert_equal_common(typval_T *argvars, assert_type_T atype)
258{
259 garray_T ga;
260
261 if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
262 != (atype == ASSERT_EQUAL))
263 {
264 prepare_assert_error(&ga);
265 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
266 atype);
267 assert_error(&ga);
268 ga_clear(&ga);
269 return 1;
270 }
271 return 0;
272}
273
274 static int
275assert_match_common(typval_T *argvars, assert_type_T atype)
276{
277 garray_T ga;
278 char_u buf1[NUMBUFLEN];
279 char_u buf2[NUMBUFLEN];
Bram Moolenaar7177da92020-07-12 23:09:20 +0200280 int called_emsg_before = called_emsg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200281 char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
282 char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
283
Bram Moolenaar7177da92020-07-12 23:09:20 +0200284 if (called_emsg == called_emsg_before
285 && pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200286 {
287 prepare_assert_error(&ga);
288 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
289 atype);
290 assert_error(&ga);
291 ga_clear(&ga);
292 return 1;
293 }
294 return 0;
295}
296
297/*
298 * Common for assert_true() and assert_false().
299 * Return non-zero for failure.
300 */
301 static int
302assert_bool(typval_T *argvars, int isTrue)
303{
304 int error = FALSE;
305 garray_T ga;
306
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +0100307 if (argvars[0].v_type == VAR_BOOL
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200308 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
309 return 0;
310 if (argvars[0].v_type != VAR_NUMBER
311 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
312 || error)
313 {
314 prepare_assert_error(&ga);
315 fill_assert_error(&ga, &argvars[1],
316 (char_u *)(isTrue ? "True" : "False"),
317 NULL, &argvars[0], ASSERT_OTHER);
318 assert_error(&ga);
319 ga_clear(&ga);
320 return 1;
321 }
322 return 0;
323}
324
325 static void
326assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
327{
328 char_u *tofree;
329 char_u numbuf[NUMBUFLEN];
330
331 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
332 {
333 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
334 vim_free(tofree);
335 }
336 else
337 ga_concat(gap, cmd);
338}
339
340 static int
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200341assert_beeps(typval_T *argvars, int no_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200342{
343 char_u *cmd = tv_get_string_chk(&argvars[0]);
344 garray_T ga;
345 int ret = 0;
346
347 called_vim_beep = FALSE;
348 suppress_errthrow = TRUE;
349 emsg_silent = FALSE;
350 do_cmdline_cmd(cmd);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200351 if (no_beep ? called_vim_beep : !called_vim_beep)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200352 {
353 prepare_assert_error(&ga);
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200354 if (no_beep)
355 ga_concat(&ga, (char_u *)"command did beep: ");
356 else
357 ga_concat(&ga, (char_u *)"command did not beep: ");
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200358 ga_concat(&ga, cmd);
359 assert_error(&ga);
360 ga_clear(&ga);
361 ret = 1;
362 }
363
364 suppress_errthrow = FALSE;
365 emsg_on_display = FALSE;
366 return ret;
367}
368
369/*
370 * "assert_beeps(cmd [, error])" function
371 */
372 void
373f_assert_beeps(typval_T *argvars, typval_T *rettv)
374{
Bram Moolenaar5b8cabf2021-04-02 18:55:57 +0200375 rettv->vval.v_number = assert_beeps(argvars, FALSE);
376}
377
378/*
379 * "assert_nobeep(cmd [, error])" function
380 */
381 void
382f_assert_nobeep(typval_T *argvars, typval_T *rettv)
383{
384 rettv->vval.v_number = assert_beeps(argvars, TRUE);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200385}
386
387/*
388 * "assert_equal(expected, actual[, msg])" function
389 */
390 void
391f_assert_equal(typval_T *argvars, typval_T *rettv)
392{
393 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
394}
395
396 static int
397assert_equalfile(typval_T *argvars)
398{
399 char_u buf1[NUMBUFLEN];
400 char_u buf2[NUMBUFLEN];
Bram Moolenaar7177da92020-07-12 23:09:20 +0200401 int called_emsg_before = called_emsg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200402 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
403 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
404 garray_T ga;
405 FILE *fd1;
406 FILE *fd2;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200407 char line1[200];
408 char line2[200];
409 int lineidx = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200410
Bram Moolenaar7177da92020-07-12 23:09:20 +0200411 if (called_emsg > called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200412 return 0;
413
414 IObuff[0] = NUL;
415 fd1 = mch_fopen((char *)fname1, READBIN);
416 if (fd1 == NULL)
417 {
418 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1);
419 }
420 else
421 {
422 fd2 = mch_fopen((char *)fname2, READBIN);
423 if (fd2 == NULL)
424 {
425 fclose(fd1);
426 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2);
427 }
428 else
429 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200430 int c1, c2;
431 long count = 0;
432 long linecount = 1;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200433
434 for (;;)
435 {
436 c1 = fgetc(fd1);
437 c2 = fgetc(fd2);
438 if (c1 == EOF)
439 {
440 if (c2 != EOF)
441 STRCPY(IObuff, "first file is shorter");
442 break;
443 }
444 else if (c2 == EOF)
445 {
446 STRCPY(IObuff, "second file is shorter");
447 break;
448 }
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200449 else
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200450 {
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200451 line1[lineidx] = c1;
452 line2[lineidx] = c2;
453 ++lineidx;
454 if (c1 != c2)
455 {
456 vim_snprintf((char *)IObuff, IOSIZE,
457 "difference at byte %ld, line %ld",
458 count, linecount);
459 break;
460 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200461 }
462 ++count;
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200463 if (c1 == NL)
464 {
465 ++linecount;
466 lineidx = 0;
467 }
468 else if (lineidx + 2 == (int)sizeof(line1))
469 {
470 mch_memmove(line1, line1 + 100, lineidx - 100);
471 mch_memmove(line2, line2 + 100, lineidx - 100);
472 lineidx -= 100;
473 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200474 }
475 fclose(fd1);
476 fclose(fd2);
477 }
478 }
479 if (IObuff[0] != NUL)
480 {
481 prepare_assert_error(&ga);
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200482 if (argvars[2].v_type != VAR_UNKNOWN)
483 {
484 char_u numbuf[NUMBUFLEN];
485 char_u *tofree;
486
487 ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
488 vim_free(tofree);
489 ga_concat(&ga, (char_u *)": ");
490 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200491 ga_concat(&ga, IObuff);
Bram Moolenaar30cc44a2020-06-04 16:52:40 +0200492 if (lineidx > 0)
493 {
494 line1[lineidx] = NUL;
495 line2[lineidx] = NUL;
496 ga_concat(&ga, (char_u *)" after \"");
497 ga_concat(&ga, (char_u *)line1);
498 if (STRCMP(line1, line2) != 0)
499 {
500 ga_concat(&ga, (char_u *)"\" vs \"");
501 ga_concat(&ga, (char_u *)line2);
502 }
503 ga_concat(&ga, (char_u *)"\"");
504 }
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200505 assert_error(&ga);
506 ga_clear(&ga);
507 return 1;
508 }
509 return 0;
510}
511
512/*
Bram Moolenaarfb517ba2020-06-03 19:55:35 +0200513 * "assert_equalfile(fname-one, fname-two[, msg])" function
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200514 */
515 void
516f_assert_equalfile(typval_T *argvars, typval_T *rettv)
517{
518 rettv->vval.v_number = assert_equalfile(argvars);
519}
520
521/*
522 * "assert_notequal(expected, actual[, msg])" function
523 */
524 void
525f_assert_notequal(typval_T *argvars, typval_T *rettv)
526{
527 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
528}
529
530/*
531 * "assert_exception(string[, msg])" function
532 */
533 void
534f_assert_exception(typval_T *argvars, typval_T *rettv)
535{
536 garray_T ga;
537 char_u *error = tv_get_string_chk(&argvars[0]);
538
539 if (*get_vim_var_str(VV_EXCEPTION) == NUL)
540 {
541 prepare_assert_error(&ga);
542 ga_concat(&ga, (char_u *)"v:exception is not set");
543 assert_error(&ga);
544 ga_clear(&ga);
545 rettv->vval.v_number = 1;
546 }
547 else if (error != NULL
548 && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
549 {
550 prepare_assert_error(&ga);
551 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
552 get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
553 assert_error(&ga);
554 ga_clear(&ga);
555 rettv->vval.v_number = 1;
556 }
557}
558
559/*
560 * "assert_fails(cmd [, error[, msg]])" function
561 */
562 void
563f_assert_fails(typval_T *argvars, typval_T *rettv)
564{
565 char_u *cmd = tv_get_string_chk(&argvars[0]);
566 garray_T ga;
567 int save_trylevel = trylevel;
Bram Moolenaar53989552019-12-23 22:59:18 +0100568 int called_emsg_before = called_emsg;
Bram Moolenaar44d66522020-09-06 22:26:57 +0200569 char *wrong_arg_msg = NULL;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200570
571 // trylevel must be zero for a ":throw" command to be considered failed
572 trylevel = 0;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200573 suppress_errthrow = TRUE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100574 in_assert_fails = TRUE;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200575
576 do_cmdline_cmd(cmd);
Bram Moolenaar53989552019-12-23 22:59:18 +0100577 if (called_emsg == called_emsg_before)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200578 {
579 prepare_assert_error(&ga);
580 ga_concat(&ga, (char_u *)"command did not fail: ");
581 assert_append_cmd_or_arg(&ga, argvars, cmd);
582 assert_error(&ga);
583 ga_clear(&ga);
584 rettv->vval.v_number = 1;
585 }
586 else if (argvars[1].v_type != VAR_UNKNOWN)
587 {
588 char_u buf[NUMBUFLEN];
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200589 char_u *expected;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100590 char_u *expected_str = NULL;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200591 int error_found = FALSE;
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200592 int error_found_index = 1;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200593 char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]"
594 : emsg_assert_fails_msg;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200595
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200596 if (argvars[1].v_type == VAR_STRING)
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200597 {
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200598 expected = tv_get_string_buf_chk(&argvars[1], buf);
599 error_found = expected == NULL
600 || strstr((char *)actual, (char *)expected) == NULL;
601 }
602 else if (argvars[1].v_type == VAR_LIST)
603 {
604 list_T *list = argvars[1].vval.v_list;
605 typval_T *tv;
606
607 if (list == NULL || list->lv_len < 1 || list->lv_len > 2)
608 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200609 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200610 goto theend;
611 }
612 CHECK_LIST_MATERIALIZE(list);
613 tv = &list->lv_first->li_tv;
614 expected = tv_get_string_buf_chk(tv, buf);
615 if (!pattern_match(expected, actual, FALSE))
616 {
617 error_found = TRUE;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100618 expected_str = expected;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200619 }
620 else if (list->lv_len == 2)
621 {
622 tv = &list->lv_u.mat.lv_last->li_tv;
623 actual = get_vim_var_str(VV_ERRMSG);
624 expected = tv_get_string_buf_chk(tv, buf);
625 if (!pattern_match(expected, actual, FALSE))
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100626 {
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200627 error_found = TRUE;
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100628 expected_str = expected;
629 }
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200630 }
631 }
632 else
633 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200634 wrong_arg_msg = e_assert_fails_second_arg;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200635 goto theend;
636 }
637
Bram Moolenaar9b02d642020-08-18 23:24:13 +0200638 if (!error_found && argvars[2].v_type != VAR_UNKNOWN
Bram Moolenaar44d66522020-09-06 22:26:57 +0200639 && argvars[3].v_type != VAR_UNKNOWN)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200640 {
Bram Moolenaar44d66522020-09-06 22:26:57 +0200641 if (argvars[3].v_type != VAR_NUMBER)
642 {
643 wrong_arg_msg = e_assert_fails_fourth_argument;
644 goto theend;
645 }
646 else if (argvars[3].vval.v_number >= 0
647 && argvars[3].vval.v_number != emsg_assert_fails_lnum)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200648 {
649 error_found = TRUE;
650 error_found_index = 3;
651 }
Bram Moolenaar44d66522020-09-06 22:26:57 +0200652 if (!error_found && argvars[4].v_type != VAR_UNKNOWN)
653 {
654 if (argvars[4].v_type != VAR_STRING)
655 {
656 wrong_arg_msg = e_assert_fails_fifth_argument;
657 goto theend;
658 }
659 else if (argvars[4].vval.v_string != NULL
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200660 && !pattern_match(argvars[4].vval.v_string,
661 emsg_assert_fails_context, FALSE))
Bram Moolenaar44d66522020-09-06 22:26:57 +0200662 {
663 error_found = TRUE;
664 error_found_index = 4;
665 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200666 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200667 }
668
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200669 if (error_found)
670 {
671 typval_T actual_tv;
672
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200673 prepare_assert_error(&ga);
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200674 if (error_found_index == 3)
Bram Moolenaar1d634542020-08-18 13:41:50 +0200675 {
676 actual_tv.v_type = VAR_NUMBER;
677 actual_tv.vval.v_number = emsg_assert_fails_lnum;
678 }
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200679 else if (error_found_index == 4)
680 {
681 actual_tv.v_type = VAR_STRING;
682 actual_tv.vval.v_string = emsg_assert_fails_context;
683 }
Bram Moolenaar1d634542020-08-18 13:41:50 +0200684 else
685 {
686 actual_tv.v_type = VAR_STRING;
687 actual_tv.vval.v_string = actual;
688 }
Bram Moolenaar631e8f92020-11-04 15:07:16 +0100689 fill_assert_error(&ga, &argvars[2], expected_str,
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200690 &argvars[error_found_index], &actual_tv, ASSERT_OTHER);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200691 ga_concat(&ga, (char_u *)": ");
692 assert_append_cmd_or_arg(&ga, argvars, cmd);
693 assert_error(&ga);
694 ga_clear(&ga);
695 rettv->vval.v_number = 1;
696 }
697 }
698
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200699theend:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200700 trylevel = save_trylevel;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200701 suppress_errthrow = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100702 in_assert_fails = FALSE;
703 did_emsg = FALSE;
704 msg_col = 0;
705 need_wait_return = FALSE;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200706 emsg_on_display = FALSE;
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100707 msg_scrolled = 0;
708 lines_left = Rows;
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200709 VIM_CLEAR(emsg_assert_fails_msg);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200710 set_vim_var_string(VV_ERRMSG, NULL, 0);
Bram Moolenaar44d66522020-09-06 22:26:57 +0200711 if (wrong_arg_msg != NULL)
712 emsg(_(wrong_arg_msg));
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200713}
714
715/*
716 * "assert_false(actual[, msg])" function
717 */
718 void
719f_assert_false(typval_T *argvars, typval_T *rettv)
720{
721 rettv->vval.v_number = assert_bool(argvars, FALSE);
722}
723
724 static int
725assert_inrange(typval_T *argvars)
726{
727 garray_T ga;
728 int error = FALSE;
729 char_u *tofree;
730 char msg[200];
731 char_u numbuf[NUMBUFLEN];
732
733#ifdef FEAT_FLOAT
734 if (argvars[0].v_type == VAR_FLOAT
735 || argvars[1].v_type == VAR_FLOAT
736 || argvars[2].v_type == VAR_FLOAT)
737 {
738 float_T flower = tv_get_float(&argvars[0]);
739 float_T fupper = tv_get_float(&argvars[1]);
740 float_T factual = tv_get_float(&argvars[2]);
741
742 if (factual < flower || factual > fupper)
743 {
744 prepare_assert_error(&ga);
745 if (argvars[3].v_type != VAR_UNKNOWN)
746 {
747 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
748 vim_free(tofree);
749 }
750 else
751 {
752 vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
753 flower, fupper, factual);
754 ga_concat(&ga, (char_u *)msg);
755 }
756 assert_error(&ga);
757 ga_clear(&ga);
758 return 1;
759 }
760 }
761 else
762#endif
763 {
764 varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
765 varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
766 varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
767
768 if (error)
769 return 0;
770 if (actual < lower || actual > upper)
771 {
772 prepare_assert_error(&ga);
773 if (argvars[3].v_type != VAR_UNKNOWN)
774 {
775 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
776 vim_free(tofree);
777 }
778 else
779 {
780 vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
781 (long)lower, (long)upper, (long)actual);
782 ga_concat(&ga, (char_u *)msg);
783 }
784 assert_error(&ga);
785 ga_clear(&ga);
786 return 1;
787 }
788 }
789 return 0;
790}
791
792/*
793 * "assert_inrange(lower, upper[, msg])" function
794 */
795 void
796f_assert_inrange(typval_T *argvars, typval_T *rettv)
797{
798 rettv->vval.v_number = assert_inrange(argvars);
799}
800
801/*
802 * "assert_match(pattern, actual[, msg])" function
803 */
804 void
805f_assert_match(typval_T *argvars, typval_T *rettv)
806{
807 rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
808}
809
810/*
811 * "assert_notmatch(pattern, actual[, msg])" function
812 */
813 void
814f_assert_notmatch(typval_T *argvars, typval_T *rettv)
815{
816 rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
817}
818
819/*
820 * "assert_report(msg)" function
821 */
822 void
823f_assert_report(typval_T *argvars, typval_T *rettv)
824{
825 garray_T ga;
826
827 prepare_assert_error(&ga);
828 ga_concat(&ga, tv_get_string(&argvars[0]));
829 assert_error(&ga);
830 ga_clear(&ga);
831 rettv->vval.v_number = 1;
832}
833
834/*
835 * "assert_true(actual[, msg])" function
836 */
837 void
838f_assert_true(typval_T *argvars, typval_T *rettv)
839{
840 rettv->vval.v_number = assert_bool(argvars, TRUE);
841}
842
843/*
844 * "test_alloc_fail(id, countdown, repeat)" function
845 */
846 void
847f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
848{
849 if (argvars[0].v_type != VAR_NUMBER
850 || argvars[0].vval.v_number <= 0
851 || argvars[1].v_type != VAR_NUMBER
852 || argvars[1].vval.v_number < 0
853 || argvars[2].v_type != VAR_NUMBER)
854 emsg(_(e_invarg));
855 else
856 {
857 alloc_fail_id = argvars[0].vval.v_number;
858 if (alloc_fail_id >= aid_last)
859 emsg(_(e_invarg));
860 alloc_fail_countdown = argvars[1].vval.v_number;
861 alloc_fail_repeat = argvars[2].vval.v_number;
862 did_outofmem_msg = FALSE;
863 }
864}
865
866/*
867 * "test_autochdir()"
868 */
869 void
870f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
871{
872#if defined(FEAT_AUTOCHDIR)
873 test_autochdir = TRUE;
874#endif
875}
876
877/*
878 * "test_feedinput()"
879 */
880 void
881f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
882{
883#ifdef USE_INPUT_BUF
884 char_u *val = tv_get_string_chk(&argvars[0]);
885
Bram Moolenaar272ca952020-01-28 20:49:11 +0100886# ifdef VIMDLL
887 // this doesn't work in the console
888 if (!gui.in_use)
889 return;
890# endif
891
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200892 if (val != NULL)
893 {
894 trash_input_buf();
895 add_to_input_buf_csi(val, (int)STRLEN(val));
896 }
897#endif
898}
899
900/*
901 * "test_getvalue({name})" function
902 */
903 void
904f_test_getvalue(typval_T *argvars, typval_T *rettv)
905{
906 if (argvars[0].v_type != VAR_STRING)
907 emsg(_(e_invarg));
908 else
909 {
910 char_u *name = tv_get_string(&argvars[0]);
911
912 if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
913 rettv->vval.v_number = need_fileinfo;
914 else
915 semsg(_(e_invarg2), name);
916 }
917}
918
919/*
920 * "test_option_not_set({name})" function
921 */
922 void
923f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
924{
925 char_u *name = (char_u *)"";
926
927 if (argvars[0].v_type != VAR_STRING)
928 emsg(_(e_invarg));
929 else
930 {
931 name = tv_get_string(&argvars[0]);
932 if (reset_option_was_set(name) == FAIL)
933 semsg(_(e_invarg2), name);
934 }
935}
936
937/*
938 * "test_override({name}, {val})" function
939 */
940 void
941f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
942{
943 char_u *name = (char_u *)"";
944 int val;
945 static int save_starting = -1;
946
947 if (argvars[0].v_type != VAR_STRING
948 || (argvars[1].v_type) != VAR_NUMBER)
949 emsg(_(e_invarg));
950 else
951 {
952 name = tv_get_string(&argvars[0]);
953 val = (int)tv_get_number(&argvars[1]);
954
955 if (STRCMP(name, (char_u *)"redraw") == 0)
956 disable_redraw_for_testing = val;
957 else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
958 ignore_redraw_flag_for_testing = val;
959 else if (STRCMP(name, (char_u *)"char_avail") == 0)
960 disable_char_avail_for_testing = val;
961 else if (STRCMP(name, (char_u *)"starting") == 0)
962 {
963 if (val)
964 {
965 if (save_starting < 0)
966 save_starting = starting;
967 starting = 0;
968 }
969 else
970 {
971 starting = save_starting;
972 save_starting = -1;
973 }
974 }
975 else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
976 nfa_fail_for_testing = val;
977 else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
978 no_query_mouse_for_testing = val;
979 else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
980 no_wait_return = val;
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200981 else if (STRCMP(name, (char_u *)"ui_delay") == 0)
982 ui_delay_for_testing = val;
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +0200983 else if (STRCMP(name, (char_u *)"term_props") == 0)
984 reset_term_props_on_termresponse = val;
Bram Moolenaarf52f0602021-03-10 21:26:37 +0100985 else if (STRCMP(name, (char_u *)"uptime") == 0)
986 override_sysinfo_uptime = val;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200987 else if (STRCMP(name, (char_u *)"ALL") == 0)
988 {
989 disable_char_avail_for_testing = FALSE;
990 disable_redraw_for_testing = FALSE;
991 ignore_redraw_flag_for_testing = FALSE;
992 nfa_fail_for_testing = FALSE;
993 no_query_mouse_for_testing = FALSE;
Bram Moolenaarb340bae2020-06-15 19:51:56 +0200994 ui_delay_for_testing = 0;
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +0200995 reset_term_props_on_termresponse = FALSE;
Bram Moolenaarf52f0602021-03-10 21:26:37 +0100996 override_sysinfo_uptime = -1;
Bram Moolenaarecaa70e2019-07-14 14:55:39 +0200997 if (save_starting >= 0)
998 {
999 starting = save_starting;
1000 save_starting = -1;
1001 }
1002 }
1003 else
1004 semsg(_(e_invarg2), name);
1005 }
1006}
1007
1008/*
1009 * "test_refcount({expr})" function
1010 */
1011 void
1012f_test_refcount(typval_T *argvars, typval_T *rettv)
1013{
1014 int retval = -1;
1015
1016 switch (argvars[0].v_type)
1017 {
1018 case VAR_UNKNOWN:
Bram Moolenaar4c683752020-04-05 21:38:23 +02001019 case VAR_ANY:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001020 case VAR_VOID:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001021 case VAR_NUMBER:
Bram Moolenaar9b4a15d2020-01-11 16:05:23 +01001022 case VAR_BOOL:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001023 case VAR_FLOAT:
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001024 case VAR_SPECIAL:
1025 case VAR_STRING:
1026 break;
1027 case VAR_JOB:
1028#ifdef FEAT_JOB_CHANNEL
1029 if (argvars[0].vval.v_job != NULL)
1030 retval = argvars[0].vval.v_job->jv_refcount - 1;
1031#endif
1032 break;
1033 case VAR_CHANNEL:
1034#ifdef FEAT_JOB_CHANNEL
1035 if (argvars[0].vval.v_channel != NULL)
1036 retval = argvars[0].vval.v_channel->ch_refcount - 1;
1037#endif
1038 break;
1039 case VAR_FUNC:
1040 if (argvars[0].vval.v_string != NULL)
1041 {
1042 ufunc_T *fp;
1043
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001044 fp = find_func(argvars[0].vval.v_string, FALSE, NULL);
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001045 if (fp != NULL)
1046 retval = fp->uf_refcount;
1047 }
1048 break;
1049 case VAR_PARTIAL:
1050 if (argvars[0].vval.v_partial != NULL)
1051 retval = argvars[0].vval.v_partial->pt_refcount - 1;
1052 break;
1053 case VAR_BLOB:
1054 if (argvars[0].vval.v_blob != NULL)
1055 retval = argvars[0].vval.v_blob->bv_refcount - 1;
1056 break;
1057 case VAR_LIST:
1058 if (argvars[0].vval.v_list != NULL)
1059 retval = argvars[0].vval.v_list->lv_refcount - 1;
1060 break;
1061 case VAR_DICT:
1062 if (argvars[0].vval.v_dict != NULL)
1063 retval = argvars[0].vval.v_dict->dv_refcount - 1;
1064 break;
1065 }
1066
1067 rettv->v_type = VAR_NUMBER;
1068 rettv->vval.v_number = retval;
1069
1070}
1071
1072/*
1073 * "test_garbagecollect_now()" function
1074 */
1075 void
1076f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1077{
Bram Moolenaar0d6f5d92019-12-05 21:33:15 +01001078 // This is dangerous, any Lists and Dicts used internally may be freed
1079 // while still in use.
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001080 garbage_collect(TRUE);
1081}
1082
1083/*
1084 * "test_garbagecollect_soon()" function
1085 */
1086 void
1087f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1088{
1089 may_garbage_collect = TRUE;
1090}
1091
1092/*
1093 * "test_ignore_error()" function
1094 */
1095 void
1096f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
1097{
1098 ignore_error_for_testing(tv_get_string(&argvars[0]));
1099}
1100
1101 void
1102f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
1103{
1104 rettv->v_type = VAR_BLOB;
1105 rettv->vval.v_blob = NULL;
1106}
1107
1108#ifdef FEAT_JOB_CHANNEL
1109 void
1110f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
1111{
1112 rettv->v_type = VAR_CHANNEL;
1113 rettv->vval.v_channel = NULL;
1114}
1115#endif
1116
1117 void
1118f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
1119{
1120 rettv_dict_set(rettv, NULL);
1121}
1122
1123#ifdef FEAT_JOB_CHANNEL
1124 void
1125f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
1126{
1127 rettv->v_type = VAR_JOB;
1128 rettv->vval.v_job = NULL;
1129}
1130#endif
1131
1132 void
1133f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
1134{
1135 rettv_list_set(rettv, NULL);
1136}
1137
1138 void
Bram Moolenaare69f6d02020-04-01 22:11:01 +02001139f_test_null_function(typval_T *argvars UNUSED, typval_T *rettv)
1140{
1141 rettv->v_type = VAR_FUNC;
1142 rettv->vval.v_string = NULL;
1143}
1144
1145 void
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001146f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
1147{
1148 rettv->v_type = VAR_PARTIAL;
1149 rettv->vval.v_partial = NULL;
1150}
1151
1152 void
1153f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
1154{
1155 rettv->v_type = VAR_STRING;
1156 rettv->vval.v_string = NULL;
1157}
1158
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001159 void
1160f_test_unknown(typval_T *argvars UNUSED, typval_T *rettv)
1161{
1162 rettv->v_type = VAR_UNKNOWN;
1163}
1164
1165 void
1166f_test_void(typval_T *argvars UNUSED, typval_T *rettv)
1167{
1168 rettv->v_type = VAR_VOID;
1169}
1170
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001171#ifdef FEAT_GUI
1172 void
1173f_test_scrollbar(typval_T *argvars, typval_T *rettv UNUSED)
1174{
1175 char_u *which;
1176 long value;
1177 int dragging;
1178 scrollbar_T *sb = NULL;
1179
1180 if (argvars[0].v_type != VAR_STRING
1181 || (argvars[1].v_type) != VAR_NUMBER
1182 || (argvars[2].v_type) != VAR_NUMBER)
1183 {
1184 emsg(_(e_invarg));
1185 return;
1186 }
1187 which = tv_get_string(&argvars[0]);
1188 value = tv_get_number(&argvars[1]);
1189 dragging = tv_get_number(&argvars[2]);
1190
1191 if (STRCMP(which, "left") == 0)
1192 sb = &curwin->w_scrollbars[SBAR_LEFT];
1193 else if (STRCMP(which, "right") == 0)
1194 sb = &curwin->w_scrollbars[SBAR_RIGHT];
1195 else if (STRCMP(which, "hor") == 0)
1196 sb = &gui.bottom_sbar;
1197 if (sb == NULL)
1198 {
1199 semsg(_(e_invarg2), which);
1200 return;
1201 }
1202 gui_drag_scrollbar(sb, value, dragging);
1203# ifndef USE_ON_FLY_SCROLL
1204 // need to loop through normal_cmd() to handle the scroll events
1205 exec_normal(FALSE, TRUE, FALSE);
1206# endif
1207}
1208#endif
1209
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001210 void
1211f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
1212{
1213 mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
1214 mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
1215}
Bram Moolenaarecaa70e2019-07-14 14:55:39 +02001216
1217 void
1218f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
1219{
1220 time_for_testing = (time_t)tv_get_number(&argvars[0]);
1221}
1222
1223
1224#endif // defined(FEAT_EVAL)