comparison src/testing.c @ 17377:cb008de2a6ec v8.1.1687

patch 8.1.1687: the evalfunc.c file is too big commit https://github.com/vim/vim/commit/ecaa70ea29c269dd0dabd3cd5acdfa0ce42ccd54 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 14 14:55:39 2019 +0200 patch 8.1.1687: the evalfunc.c file is too big Problem: The evalfunc.c file is too big. Solution: Move testing support to a separate file.
author Bram Moolenaar <Bram@vim.org>
date Sun, 14 Jul 2019 15:00:05 +0200
parents
children 9f51d0cef8da
comparison
equal deleted inserted replaced
17376:da3299b8b5c0 17377:cb008de2a6ec
1 /* 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
22 prepare_assert_error(garray_T *gap)
23 {
24 char buf[NUMBUFLEN];
25
26 ga_init2(gap, 1, 100);
27 if (sourcing_name != NULL)
28 {
29 ga_concat(gap, sourcing_name);
30 if (sourcing_lnum > 0)
31 ga_concat(gap, (char_u *)" ");
32 }
33 if (sourcing_lnum > 0)
34 {
35 sprintf(buf, "line %ld", (long)sourcing_lnum);
36 ga_concat(gap, (char_u *)buf);
37 }
38 if (sourcing_name != NULL || sourcing_lnum > 0)
39 ga_concat(gap, (char_u *)": ");
40 }
41
42 /*
43 * Append "p[clen]" to "gap", escaping unprintable characters.
44 * Changes NL to \n, CR to \r, etc.
45 */
46 static void
47 ga_concat_esc(garray_T *gap, char_u *p, int clen)
48 {
49 char_u buf[NUMBUFLEN];
50
51 if (clen > 1)
52 {
53 mch_memmove(buf, p, clen);
54 buf[clen] = NUL;
55 ga_concat(gap, buf);
56 }
57 else switch (*p)
58 {
59 case BS: ga_concat(gap, (char_u *)"\\b"); break;
60 case ESC: ga_concat(gap, (char_u *)"\\e"); break;
61 case FF: ga_concat(gap, (char_u *)"\\f"); break;
62 case NL: ga_concat(gap, (char_u *)"\\n"); break;
63 case TAB: ga_concat(gap, (char_u *)"\\t"); break;
64 case CAR: ga_concat(gap, (char_u *)"\\r"); break;
65 case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
66 default:
67 if (*p < ' ')
68 {
69 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
70 ga_concat(gap, buf);
71 }
72 else
73 ga_append(gap, *p);
74 break;
75 }
76 }
77
78 /*
79 * Append "str" to "gap", escaping unprintable characters.
80 * Changes NL to \n, CR to \r, etc.
81 */
82 static void
83 ga_concat_shorten_esc(garray_T *gap, char_u *str)
84 {
85 char_u *p;
86 char_u *s;
87 int c;
88 int clen;
89 char_u buf[NUMBUFLEN];
90 int same_len;
91
92 if (str == NULL)
93 {
94 ga_concat(gap, (char_u *)"NULL");
95 return;
96 }
97
98 for (p = str; *p != NUL; ++p)
99 {
100 same_len = 1;
101 s = p;
102 c = mb_ptr2char_adv(&s);
103 clen = s - p;
104 while (*s != NUL && c == mb_ptr2char(s))
105 {
106 ++same_len;
107 s += clen;
108 }
109 if (same_len > 20)
110 {
111 ga_concat(gap, (char_u *)"\\[");
112 ga_concat_esc(gap, p, clen);
113 ga_concat(gap, (char_u *)" occurs ");
114 vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
115 ga_concat(gap, buf);
116 ga_concat(gap, (char_u *)" times]");
117 p = s - 1;
118 }
119 else
120 ga_concat_esc(gap, p, clen);
121 }
122 }
123
124 /*
125 * Fill "gap" with information about an assert error.
126 */
127 static void
128 fill_assert_error(
129 garray_T *gap,
130 typval_T *opt_msg_tv,
131 char_u *exp_str,
132 typval_T *exp_tv,
133 typval_T *got_tv,
134 assert_type_T atype)
135 {
136 char_u numbuf[NUMBUFLEN];
137 char_u *tofree;
138
139 if (opt_msg_tv->v_type != VAR_UNKNOWN)
140 {
141 ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
142 vim_free(tofree);
143 ga_concat(gap, (char_u *)": ");
144 }
145
146 if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
147 ga_concat(gap, (char_u *)"Pattern ");
148 else if (atype == ASSERT_NOTEQUAL)
149 ga_concat(gap, (char_u *)"Expected not equal to ");
150 else
151 ga_concat(gap, (char_u *)"Expected ");
152 if (exp_str == NULL)
153 {
154 ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
155 vim_free(tofree);
156 }
157 else
158 ga_concat_shorten_esc(gap, exp_str);
159 if (atype != ASSERT_NOTEQUAL)
160 {
161 if (atype == ASSERT_MATCH)
162 ga_concat(gap, (char_u *)" does not match ");
163 else if (atype == ASSERT_NOTMATCH)
164 ga_concat(gap, (char_u *)" does match ");
165 else
166 ga_concat(gap, (char_u *)" but got ");
167 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
168 vim_free(tofree);
169 }
170 }
171
172 static int
173 assert_equal_common(typval_T *argvars, assert_type_T atype)
174 {
175 garray_T ga;
176
177 if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)
178 != (atype == ASSERT_EQUAL))
179 {
180 prepare_assert_error(&ga);
181 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
182 atype);
183 assert_error(&ga);
184 ga_clear(&ga);
185 return 1;
186 }
187 return 0;
188 }
189
190 static int
191 assert_match_common(typval_T *argvars, assert_type_T atype)
192 {
193 garray_T ga;
194 char_u buf1[NUMBUFLEN];
195 char_u buf2[NUMBUFLEN];
196 char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1);
197 char_u *text = tv_get_string_buf_chk(&argvars[1], buf2);
198
199 if (pat == NULL || text == NULL)
200 emsg(_(e_invarg));
201 else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH))
202 {
203 prepare_assert_error(&ga);
204 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
205 atype);
206 assert_error(&ga);
207 ga_clear(&ga);
208 return 1;
209 }
210 return 0;
211 }
212
213 /*
214 * Common for assert_true() and assert_false().
215 * Return non-zero for failure.
216 */
217 static int
218 assert_bool(typval_T *argvars, int isTrue)
219 {
220 int error = FALSE;
221 garray_T ga;
222
223 if (argvars[0].v_type == VAR_SPECIAL
224 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
225 return 0;
226 if (argvars[0].v_type != VAR_NUMBER
227 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue
228 || error)
229 {
230 prepare_assert_error(&ga);
231 fill_assert_error(&ga, &argvars[1],
232 (char_u *)(isTrue ? "True" : "False"),
233 NULL, &argvars[0], ASSERT_OTHER);
234 assert_error(&ga);
235 ga_clear(&ga);
236 return 1;
237 }
238 return 0;
239 }
240
241 static void
242 assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
243 {
244 char_u *tofree;
245 char_u numbuf[NUMBUFLEN];
246
247 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
248 {
249 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
250 vim_free(tofree);
251 }
252 else
253 ga_concat(gap, cmd);
254 }
255
256 static int
257 assert_beeps(typval_T *argvars)
258 {
259 char_u *cmd = tv_get_string_chk(&argvars[0]);
260 garray_T ga;
261 int ret = 0;
262
263 called_vim_beep = FALSE;
264 suppress_errthrow = TRUE;
265 emsg_silent = FALSE;
266 do_cmdline_cmd(cmd);
267 if (!called_vim_beep)
268 {
269 prepare_assert_error(&ga);
270 ga_concat(&ga, (char_u *)"command did not beep: ");
271 ga_concat(&ga, cmd);
272 assert_error(&ga);
273 ga_clear(&ga);
274 ret = 1;
275 }
276
277 suppress_errthrow = FALSE;
278 emsg_on_display = FALSE;
279 return ret;
280 }
281
282 /*
283 * "assert_beeps(cmd [, error])" function
284 */
285 void
286 f_assert_beeps(typval_T *argvars, typval_T *rettv)
287 {
288 rettv->vval.v_number = assert_beeps(argvars);
289 }
290
291 /*
292 * "assert_equal(expected, actual[, msg])" function
293 */
294 void
295 f_assert_equal(typval_T *argvars, typval_T *rettv)
296 {
297 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
298 }
299
300 static int
301 assert_equalfile(typval_T *argvars)
302 {
303 char_u buf1[NUMBUFLEN];
304 char_u buf2[NUMBUFLEN];
305 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1);
306 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2);
307 garray_T ga;
308 FILE *fd1;
309 FILE *fd2;
310
311 if (fname1 == NULL || fname2 == NULL)
312 return 0;
313
314 IObuff[0] = NUL;
315 fd1 = mch_fopen((char *)fname1, READBIN);
316 if (fd1 == NULL)
317 {
318 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1);
319 }
320 else
321 {
322 fd2 = mch_fopen((char *)fname2, READBIN);
323 if (fd2 == NULL)
324 {
325 fclose(fd1);
326 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2);
327 }
328 else
329 {
330 int c1, c2;
331 long count = 0;
332
333 for (;;)
334 {
335 c1 = fgetc(fd1);
336 c2 = fgetc(fd2);
337 if (c1 == EOF)
338 {
339 if (c2 != EOF)
340 STRCPY(IObuff, "first file is shorter");
341 break;
342 }
343 else if (c2 == EOF)
344 {
345 STRCPY(IObuff, "second file is shorter");
346 break;
347 }
348 else if (c1 != c2)
349 {
350 vim_snprintf((char *)IObuff, IOSIZE,
351 "difference at byte %ld", count);
352 break;
353 }
354 ++count;
355 }
356 fclose(fd1);
357 fclose(fd2);
358 }
359 }
360 if (IObuff[0] != NUL)
361 {
362 prepare_assert_error(&ga);
363 ga_concat(&ga, IObuff);
364 assert_error(&ga);
365 ga_clear(&ga);
366 return 1;
367 }
368 return 0;
369 }
370
371 /*
372 * "assert_equalfile(fname-one, fname-two)" function
373 */
374 void
375 f_assert_equalfile(typval_T *argvars, typval_T *rettv)
376 {
377 rettv->vval.v_number = assert_equalfile(argvars);
378 }
379
380 /*
381 * "assert_notequal(expected, actual[, msg])" function
382 */
383 void
384 f_assert_notequal(typval_T *argvars, typval_T *rettv)
385 {
386 rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
387 }
388
389 /*
390 * "assert_exception(string[, msg])" function
391 */
392 void
393 f_assert_exception(typval_T *argvars, typval_T *rettv)
394 {
395 garray_T ga;
396 char_u *error = tv_get_string_chk(&argvars[0]);
397
398 if (*get_vim_var_str(VV_EXCEPTION) == NUL)
399 {
400 prepare_assert_error(&ga);
401 ga_concat(&ga, (char_u *)"v:exception is not set");
402 assert_error(&ga);
403 ga_clear(&ga);
404 rettv->vval.v_number = 1;
405 }
406 else if (error != NULL
407 && strstr((char *)get_vim_var_str(VV_EXCEPTION), (char *)error) == NULL)
408 {
409 prepare_assert_error(&ga);
410 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
411 get_vim_var_tv(VV_EXCEPTION), ASSERT_OTHER);
412 assert_error(&ga);
413 ga_clear(&ga);
414 rettv->vval.v_number = 1;
415 }
416 }
417
418 /*
419 * "assert_fails(cmd [, error[, msg]])" function
420 */
421 void
422 f_assert_fails(typval_T *argvars, typval_T *rettv)
423 {
424 char_u *cmd = tv_get_string_chk(&argvars[0]);
425 garray_T ga;
426 int save_trylevel = trylevel;
427
428 // trylevel must be zero for a ":throw" command to be considered failed
429 trylevel = 0;
430 called_emsg = FALSE;
431 suppress_errthrow = TRUE;
432 emsg_silent = TRUE;
433
434 do_cmdline_cmd(cmd);
435 if (!called_emsg)
436 {
437 prepare_assert_error(&ga);
438 ga_concat(&ga, (char_u *)"command did not fail: ");
439 assert_append_cmd_or_arg(&ga, argvars, cmd);
440 assert_error(&ga);
441 ga_clear(&ga);
442 rettv->vval.v_number = 1;
443 }
444 else if (argvars[1].v_type != VAR_UNKNOWN)
445 {
446 char_u buf[NUMBUFLEN];
447 char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf);
448
449 if (error == NULL
450 || strstr((char *)get_vim_var_str(VV_ERRMSG), error) == NULL)
451 {
452 prepare_assert_error(&ga);
453 fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
454 get_vim_var_tv(VV_ERRMSG), ASSERT_OTHER);
455 ga_concat(&ga, (char_u *)": ");
456 assert_append_cmd_or_arg(&ga, argvars, cmd);
457 assert_error(&ga);
458 ga_clear(&ga);
459 rettv->vval.v_number = 1;
460 }
461 }
462
463 trylevel = save_trylevel;
464 called_emsg = FALSE;
465 suppress_errthrow = FALSE;
466 emsg_silent = FALSE;
467 emsg_on_display = FALSE;
468 set_vim_var_string(VV_ERRMSG, NULL, 0);
469 }
470
471 /*
472 * "assert_false(actual[, msg])" function
473 */
474 void
475 f_assert_false(typval_T *argvars, typval_T *rettv)
476 {
477 rettv->vval.v_number = assert_bool(argvars, FALSE);
478 }
479
480 static int
481 assert_inrange(typval_T *argvars)
482 {
483 garray_T ga;
484 int error = FALSE;
485 char_u *tofree;
486 char msg[200];
487 char_u numbuf[NUMBUFLEN];
488
489 #ifdef FEAT_FLOAT
490 if (argvars[0].v_type == VAR_FLOAT
491 || argvars[1].v_type == VAR_FLOAT
492 || argvars[2].v_type == VAR_FLOAT)
493 {
494 float_T flower = tv_get_float(&argvars[0]);
495 float_T fupper = tv_get_float(&argvars[1]);
496 float_T factual = tv_get_float(&argvars[2]);
497
498 if (factual < flower || factual > fupper)
499 {
500 prepare_assert_error(&ga);
501 if (argvars[3].v_type != VAR_UNKNOWN)
502 {
503 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
504 vim_free(tofree);
505 }
506 else
507 {
508 vim_snprintf(msg, 200, "Expected range %g - %g, but got %g",
509 flower, fupper, factual);
510 ga_concat(&ga, (char_u *)msg);
511 }
512 assert_error(&ga);
513 ga_clear(&ga);
514 return 1;
515 }
516 }
517 else
518 #endif
519 {
520 varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
521 varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
522 varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
523
524 if (error)
525 return 0;
526 if (actual < lower || actual > upper)
527 {
528 prepare_assert_error(&ga);
529 if (argvars[3].v_type != VAR_UNKNOWN)
530 {
531 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0));
532 vim_free(tofree);
533 }
534 else
535 {
536 vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld",
537 (long)lower, (long)upper, (long)actual);
538 ga_concat(&ga, (char_u *)msg);
539 }
540 assert_error(&ga);
541 ga_clear(&ga);
542 return 1;
543 }
544 }
545 return 0;
546 }
547
548 /*
549 * "assert_inrange(lower, upper[, msg])" function
550 */
551 void
552 f_assert_inrange(typval_T *argvars, typval_T *rettv)
553 {
554 rettv->vval.v_number = assert_inrange(argvars);
555 }
556
557 /*
558 * "assert_match(pattern, actual[, msg])" function
559 */
560 void
561 f_assert_match(typval_T *argvars, typval_T *rettv)
562 {
563 rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
564 }
565
566 /*
567 * "assert_notmatch(pattern, actual[, msg])" function
568 */
569 void
570 f_assert_notmatch(typval_T *argvars, typval_T *rettv)
571 {
572 rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
573 }
574
575 /*
576 * "assert_report(msg)" function
577 */
578 void
579 f_assert_report(typval_T *argvars, typval_T *rettv)
580 {
581 garray_T ga;
582
583 prepare_assert_error(&ga);
584 ga_concat(&ga, tv_get_string(&argvars[0]));
585 assert_error(&ga);
586 ga_clear(&ga);
587 rettv->vval.v_number = 1;
588 }
589
590 /*
591 * "assert_true(actual[, msg])" function
592 */
593 void
594 f_assert_true(typval_T *argvars, typval_T *rettv)
595 {
596 rettv->vval.v_number = assert_bool(argvars, TRUE);
597 }
598
599 /*
600 * "test_alloc_fail(id, countdown, repeat)" function
601 */
602 void
603 f_test_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
604 {
605 if (argvars[0].v_type != VAR_NUMBER
606 || argvars[0].vval.v_number <= 0
607 || argvars[1].v_type != VAR_NUMBER
608 || argvars[1].vval.v_number < 0
609 || argvars[2].v_type != VAR_NUMBER)
610 emsg(_(e_invarg));
611 else
612 {
613 alloc_fail_id = argvars[0].vval.v_number;
614 if (alloc_fail_id >= aid_last)
615 emsg(_(e_invarg));
616 alloc_fail_countdown = argvars[1].vval.v_number;
617 alloc_fail_repeat = argvars[2].vval.v_number;
618 did_outofmem_msg = FALSE;
619 }
620 }
621
622 /*
623 * "test_autochdir()"
624 */
625 void
626 f_test_autochdir(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
627 {
628 #if defined(FEAT_AUTOCHDIR)
629 test_autochdir = TRUE;
630 #endif
631 }
632
633 /*
634 * "test_feedinput()"
635 */
636 void
637 f_test_feedinput(typval_T *argvars, typval_T *rettv UNUSED)
638 {
639 #ifdef USE_INPUT_BUF
640 char_u *val = tv_get_string_chk(&argvars[0]);
641
642 if (val != NULL)
643 {
644 trash_input_buf();
645 add_to_input_buf_csi(val, (int)STRLEN(val));
646 }
647 #endif
648 }
649
650 /*
651 * "test_getvalue({name})" function
652 */
653 void
654 f_test_getvalue(typval_T *argvars, typval_T *rettv)
655 {
656 if (argvars[0].v_type != VAR_STRING)
657 emsg(_(e_invarg));
658 else
659 {
660 char_u *name = tv_get_string(&argvars[0]);
661
662 if (STRCMP(name, (char_u *)"need_fileinfo") == 0)
663 rettv->vval.v_number = need_fileinfo;
664 else
665 semsg(_(e_invarg2), name);
666 }
667 }
668
669 /*
670 * "test_option_not_set({name})" function
671 */
672 void
673 f_test_option_not_set(typval_T *argvars, typval_T *rettv UNUSED)
674 {
675 char_u *name = (char_u *)"";
676
677 if (argvars[0].v_type != VAR_STRING)
678 emsg(_(e_invarg));
679 else
680 {
681 name = tv_get_string(&argvars[0]);
682 if (reset_option_was_set(name) == FAIL)
683 semsg(_(e_invarg2), name);
684 }
685 }
686
687 /*
688 * "test_override({name}, {val})" function
689 */
690 void
691 f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
692 {
693 char_u *name = (char_u *)"";
694 int val;
695 static int save_starting = -1;
696
697 if (argvars[0].v_type != VAR_STRING
698 || (argvars[1].v_type) != VAR_NUMBER)
699 emsg(_(e_invarg));
700 else
701 {
702 name = tv_get_string(&argvars[0]);
703 val = (int)tv_get_number(&argvars[1]);
704
705 if (STRCMP(name, (char_u *)"redraw") == 0)
706 disable_redraw_for_testing = val;
707 else if (STRCMP(name, (char_u *)"redraw_flag") == 0)
708 ignore_redraw_flag_for_testing = val;
709 else if (STRCMP(name, (char_u *)"char_avail") == 0)
710 disable_char_avail_for_testing = val;
711 else if (STRCMP(name, (char_u *)"starting") == 0)
712 {
713 if (val)
714 {
715 if (save_starting < 0)
716 save_starting = starting;
717 starting = 0;
718 }
719 else
720 {
721 starting = save_starting;
722 save_starting = -1;
723 }
724 }
725 else if (STRCMP(name, (char_u *)"nfa_fail") == 0)
726 nfa_fail_for_testing = val;
727 else if (STRCMP(name, (char_u *)"no_query_mouse") == 0)
728 no_query_mouse_for_testing = val;
729 else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
730 no_wait_return = val;
731 else if (STRCMP(name, (char_u *)"ALL") == 0)
732 {
733 disable_char_avail_for_testing = FALSE;
734 disable_redraw_for_testing = FALSE;
735 ignore_redraw_flag_for_testing = FALSE;
736 nfa_fail_for_testing = FALSE;
737 no_query_mouse_for_testing = FALSE;
738 if (save_starting >= 0)
739 {
740 starting = save_starting;
741 save_starting = -1;
742 }
743 }
744 else
745 semsg(_(e_invarg2), name);
746 }
747 }
748
749 /*
750 * "test_refcount({expr})" function
751 */
752 void
753 f_test_refcount(typval_T *argvars, typval_T *rettv)
754 {
755 int retval = -1;
756
757 switch (argvars[0].v_type)
758 {
759 case VAR_UNKNOWN:
760 case VAR_NUMBER:
761 case VAR_FLOAT:
762 case VAR_SPECIAL:
763 case VAR_STRING:
764 break;
765 case VAR_JOB:
766 #ifdef FEAT_JOB_CHANNEL
767 if (argvars[0].vval.v_job != NULL)
768 retval = argvars[0].vval.v_job->jv_refcount - 1;
769 #endif
770 break;
771 case VAR_CHANNEL:
772 #ifdef FEAT_JOB_CHANNEL
773 if (argvars[0].vval.v_channel != NULL)
774 retval = argvars[0].vval.v_channel->ch_refcount - 1;
775 #endif
776 break;
777 case VAR_FUNC:
778 if (argvars[0].vval.v_string != NULL)
779 {
780 ufunc_T *fp;
781
782 fp = find_func(argvars[0].vval.v_string);
783 if (fp != NULL)
784 retval = fp->uf_refcount;
785 }
786 break;
787 case VAR_PARTIAL:
788 if (argvars[0].vval.v_partial != NULL)
789 retval = argvars[0].vval.v_partial->pt_refcount - 1;
790 break;
791 case VAR_BLOB:
792 if (argvars[0].vval.v_blob != NULL)
793 retval = argvars[0].vval.v_blob->bv_refcount - 1;
794 break;
795 case VAR_LIST:
796 if (argvars[0].vval.v_list != NULL)
797 retval = argvars[0].vval.v_list->lv_refcount - 1;
798 break;
799 case VAR_DICT:
800 if (argvars[0].vval.v_dict != NULL)
801 retval = argvars[0].vval.v_dict->dv_refcount - 1;
802 break;
803 }
804
805 rettv->v_type = VAR_NUMBER;
806 rettv->vval.v_number = retval;
807
808 }
809
810 /*
811 * "test_garbagecollect_now()" function
812 */
813 void
814 f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
815 {
816 /* This is dangerous, any Lists and Dicts used internally may be freed
817 * while still in use. */
818 garbage_collect(TRUE);
819 }
820
821 /*
822 * "test_garbagecollect_soon()" function
823 */
824 void
825 f_test_garbagecollect_soon(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
826 {
827 may_garbage_collect = TRUE;
828 }
829
830 /*
831 * "test_ignore_error()" function
832 */
833 void
834 f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
835 {
836 ignore_error_for_testing(tv_get_string(&argvars[0]));
837 }
838
839 void
840 f_test_null_blob(typval_T *argvars UNUSED, typval_T *rettv)
841 {
842 rettv->v_type = VAR_BLOB;
843 rettv->vval.v_blob = NULL;
844 }
845
846 #ifdef FEAT_JOB_CHANNEL
847 void
848 f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
849 {
850 rettv->v_type = VAR_CHANNEL;
851 rettv->vval.v_channel = NULL;
852 }
853 #endif
854
855 void
856 f_test_null_dict(typval_T *argvars UNUSED, typval_T *rettv)
857 {
858 rettv_dict_set(rettv, NULL);
859 }
860
861 #ifdef FEAT_JOB_CHANNEL
862 void
863 f_test_null_job(typval_T *argvars UNUSED, typval_T *rettv)
864 {
865 rettv->v_type = VAR_JOB;
866 rettv->vval.v_job = NULL;
867 }
868 #endif
869
870 void
871 f_test_null_list(typval_T *argvars UNUSED, typval_T *rettv)
872 {
873 rettv_list_set(rettv, NULL);
874 }
875
876 void
877 f_test_null_partial(typval_T *argvars UNUSED, typval_T *rettv)
878 {
879 rettv->v_type = VAR_PARTIAL;
880 rettv->vval.v_partial = NULL;
881 }
882
883 void
884 f_test_null_string(typval_T *argvars UNUSED, typval_T *rettv)
885 {
886 rettv->v_type = VAR_STRING;
887 rettv->vval.v_string = NULL;
888 }
889
890 #ifdef FEAT_GUI
891 void
892 f_test_scrollbar(typval_T *argvars, typval_T *rettv UNUSED)
893 {
894 char_u *which;
895 long value;
896 int dragging;
897 scrollbar_T *sb = NULL;
898
899 if (argvars[0].v_type != VAR_STRING
900 || (argvars[1].v_type) != VAR_NUMBER
901 || (argvars[2].v_type) != VAR_NUMBER)
902 {
903 emsg(_(e_invarg));
904 return;
905 }
906 which = tv_get_string(&argvars[0]);
907 value = tv_get_number(&argvars[1]);
908 dragging = tv_get_number(&argvars[2]);
909
910 if (STRCMP(which, "left") == 0)
911 sb = &curwin->w_scrollbars[SBAR_LEFT];
912 else if (STRCMP(which, "right") == 0)
913 sb = &curwin->w_scrollbars[SBAR_RIGHT];
914 else if (STRCMP(which, "hor") == 0)
915 sb = &gui.bottom_sbar;
916 if (sb == NULL)
917 {
918 semsg(_(e_invarg2), which);
919 return;
920 }
921 gui_drag_scrollbar(sb, value, dragging);
922 # ifndef USE_ON_FLY_SCROLL
923 // need to loop through normal_cmd() to handle the scroll events
924 exec_normal(FALSE, TRUE, FALSE);
925 # endif
926 }
927 #endif
928
929 #ifdef FEAT_MOUSE
930 void
931 f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
932 {
933 mouse_row = (time_t)tv_get_number(&argvars[0]) - 1;
934 mouse_col = (time_t)tv_get_number(&argvars[1]) - 1;
935 }
936 #endif
937
938 void
939 f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
940 {
941 time_for_testing = (time_t)tv_get_number(&argvars[0]);
942 }
943
944
945 #endif // defined(FEAT_EVAL)