xref: /vim-8.2.3635/src/testdir/test_gui.vim (revision cd5c8f82)
1" Tests specifically for the GUI
2
3if !has('gui') || ($DISPLAY == "" && !has('gui_running'))
4  finish
5endif
6
7source setup_gui.vim
8
9func Setup()
10  call GUISetUpCommon()
11endfunc
12
13func TearDown()
14  call GUITearDownCommon()
15endfunc
16
17" Test for resetting "secure" flag after GUI has started.
18" Must be run first.
19func Test_1_set_secure()
20  set exrc secure
21  gui -f
22  call assert_equal(1, has('gui_running'))
23endfunc
24
25" As for non-GUI, a balloon_show() test was already added with patch 8.0.0401
26func Test_balloon_show()
27  if has('balloon_eval')
28    " This won't do anything but must not crash either.
29    call balloon_show('hi!')
30  endif
31endfunc
32
33func Test_colorscheme()
34  let colorscheme_saved = exists('g:colors_name') ? g:colors_name : 'default'
35
36  colorscheme torte
37  redraw!
38  sleep 200m
39  call assert_equal('dark', &background)
40
41  exec 'colorscheme' colorscheme_saved
42  redraw!
43endfunc
44
45func Test_getfontname_with_arg()
46  let skipped = ''
47
48  if !g:x11_based_gui
49    let skipped = g:not_implemented
50  elseif has('gui_athena') || has('gui_motif')
51    " Invalid font name. The result should be an empty string.
52    call assert_equal('', getfontname('notexist'))
53
54    " Valid font name. This is usually the real name of 7x13 by default.
55    let fname = '-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1'
56    call assert_match(fname, getfontname(fname))
57
58  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
59    " Invalid font name. The result should be the name plus the default size.
60    call assert_equal('notexist 10', getfontname('notexist'))
61
62    " Valid font name. This is usually the real name of Monospace by default.
63    let fname = 'Bitstream Vera Sans Mono 12'
64    call assert_equal(fname, getfontname(fname))
65  endif
66
67  if !empty(skipped)
68    throw skipped
69  endif
70endfunc
71
72func Test_getfontname_without_arg()
73  let skipped = ''
74
75  let fname = getfontname()
76
77  if !g:x11_based_gui
78    let skipped = g:not_implemented
79  elseif has('gui_kde')
80    " 'expected' is the value specified by SetUp() above.
81    call assert_equal('Courier 10 Pitch/8/-1/5/50/0/0/0/0/0', fname)
82  elseif has('gui_athena') || has('gui_motif')
83    " 'expected' is DFLT_FONT of gui_x11.c or its real name.
84    let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
85    call assert_match(pat, fname)
86  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
87    " 'expected' is DEFAULT_FONT of gui_gtk_x11.c.
88    call assert_equal('Monospace 10', fname)
89  endif
90
91  if !empty(skipped)
92    throw skipped
93  endif
94endfunc
95
96func Test_getwinpos()
97  call assert_match('Window position: X \d\+, Y \d\+', execute('winpos'))
98  call assert_true(getwinposx() >= 0)
99  call assert_true(getwinposy() >= 0)
100endfunc
101
102func Test_quoteplus()
103  let skipped = ''
104
105  if !g:x11_based_gui
106    let skipped = g:not_supported . 'quoteplus'
107  else
108    let quoteplus_saved = @+
109
110    let test_call     = 'Can you hear me?'
111    let test_response = 'Yes, I can.'
112    let vim_exe = exepath(v:progpath)
113    let testee = 'VIMRUNTIME=' . $VIMRUNTIME . '; export VIMRUNTIME;'
114          \ . vim_exe
115	  \ . ' -u NONE -U NONE --noplugin --not-a-term -c ''%s'''
116    " Ignore the "failed to create input context" error.
117    let cmd = 'call test_ignore_error("E285") | '
118	  \ . 'gui -f | '
119	  \ . 'call feedkeys("'
120          \ . '\"+p'
121          \ . ':s/' . test_call . '/' . test_response . '/\<CR>'
122          \ . '\"+yis'
123          \ . ':q!\<CR>", "tx")'
124    let run_vimtest = printf(testee, cmd)
125
126    " Set the quoteplus register to test_call, and another gvim will launched.
127    " Then, it first tries to paste the content of its own quotedplus register
128    " onto it.  Second, it tries to substitute test_responce for the pasted
129    " sentence.  If the sentence is identical to test_call, the substitution
130    " should succeed.  Third, it tries to yank the result of the substitution
131    " to its own quoteplus register, and last it quits.  When system()
132    " returns, the content of the quoteplus register should be identical to
133    " test_response if those quoteplus registers are synchronized properly
134    " with/through the X11 clipboard.
135    let @+ = test_call
136    call system(run_vimtest)
137    call assert_equal(test_response, @+)
138
139    let @+ = quoteplus_saved
140  endif
141
142  if !empty(skipped)
143    throw skipped
144  endif
145endfunc
146
147func Test_set_background()
148  let background_saved = &background
149
150  set background&
151  call assert_equal('light', &background)
152
153  set background=dark
154  call assert_equal('dark', &background)
155
156  let &background = background_saved
157endfunc
158
159func Test_set_balloondelay()
160  if !exists('+balloondelay')
161    return
162  endif
163
164  let balloondelay_saved = &balloondelay
165
166  " Check if the default value is identical to that described in the manual.
167  set balloondelay&
168  call assert_equal(600, &balloondelay)
169
170  " Edge cases
171
172  " XXX This fact should be hidden so that people won't be tempted to write
173  " plugin/TimeMachine.vim.  TODO Add reasonable range checks to the source
174  " code.
175  set balloondelay=-1
176  call assert_equal(-1, &balloondelay)
177
178  " Though it's possible to interpret the zero delay to be 'as soon as
179  " possible' or even 'indefinite', its actual meaning depends on the GUI
180  " toolkit in use after all.
181  set balloondelay=0
182  call assert_equal(0, &balloondelay)
183
184  set balloondelay=1
185  call assert_equal(1, &balloondelay)
186
187  " Since p_bdelay is of type long currently, the upper bound can be
188  " impractically huge and machine-dependent.  Practically, it's sufficient
189  " to check if balloondelay works with 0x7fffffff (32 bits) for now.
190  set balloondelay=2147483647
191  call assert_equal(2147483647, &balloondelay)
192
193  let &balloondelay = balloondelay_saved
194endfunc
195
196func Test_set_ballooneval()
197  if !exists('+ballooneval')
198    return
199  endif
200
201  let ballooneval_saved = &ballooneval
202
203  set ballooneval&
204  call assert_equal(0, &ballooneval)
205
206  set ballooneval
207  call assert_notequal(0, &ballooneval)
208
209  set noballooneval
210  call assert_equal(0, &ballooneval)
211
212  let &ballooneval = ballooneval_saved
213endfunc
214
215func Test_set_balloonexpr()
216  if !exists('+balloonexpr')
217    return
218  endif
219
220  let balloonexpr_saved = &balloonexpr
221
222  " Default value
223  set balloonexpr&
224  call assert_equal('', &balloonexpr)
225
226  " User-defined function
227  new
228  func MyBalloonExpr()
229      return 'Cursor is at line ' . v:beval_lnum .
230	      \', column ' . v:beval_col .
231	      \ ' of file ' .  bufname(v:beval_bufnr) .
232	      \ ' on word "' . v:beval_text . '"' .
233	      \ ' in window ' . v:beval_winid . ' (#' . v:beval_winnr . ')'
234  endfunc
235  setl balloonexpr=MyBalloonExpr()
236  setl ballooneval
237  call assert_equal('MyBalloonExpr()', &balloonexpr)
238  " TODO Read non-empty text, place the pointer at a character of a word,
239  " and check if the content of the balloon is the smae as what is expected.
240  " Also, check if textlock works as expected.
241  setl balloonexpr&
242  call assert_equal('', &balloonexpr)
243  delfunc MyBalloonExpr
244  bwipe!
245
246  " Multiline support
247  if has('balloon_multiline')
248    " Multiline balloon using NL
249    new
250    func MyBalloonFuncForMultilineUsingNL()
251      return "Multiline\nSuppported\nBalloon\nusing NL"
252    endfunc
253    setl balloonexpr=MyBalloonFuncForMultilineUsingNL()
254    setl ballooneval
255    call assert_equal('MyBalloonFuncForMultilineUsingNL()', &balloonexpr)
256    " TODO Read non-empty text, place the pointer at a character of a word,
257    " and check if the content of the balloon is the smae as what is
258    " expected.  Also, check if textlock works as expected.
259    setl balloonexpr&
260    delfunc MyBalloonFuncForMultilineUsingNL
261    bwipe!
262
263    " Multiline balloon using List
264    new
265    func MyBalloonFuncForMultilineUsingList()
266      return [ 'Multiline', 'Suppported', 'Balloon', 'using List' ]
267    endfunc
268    setl balloonexpr=MyBalloonFuncForMultilineUsingList()
269    setl ballooneval
270    call assert_equal('MyBalloonFuncForMultilineUsingList()', &balloonexpr)
271    " TODO Read non-empty text, place the pointer at a character of a word,
272    " and check if the content of the balloon is the smae as what is
273    " expected.  Also, check if textlock works as expected.
274    setl balloonexpr&
275    delfunc MyBalloonFuncForMultilineUsingList
276    bwipe!
277  endif
278
279  let &balloonexpr = balloonexpr_saved
280endfunc
281
282" Invalid arguments are tested with test_options in conjunction with segfaults
283" caused by them (Patch 8.0.0357, 24922ec233).
284func Test_set_guicursor()
285  let guicursor_saved = &guicursor
286
287  let default = [
288        \ "n-v-c:block-Cursor/lCursor",
289        \ "ve:ver35-Cursor",
290        \ "o:hor50-Cursor",
291        \ "i-ci:ver25-Cursor/lCursor",
292        \ "r-cr:hor20-Cursor/lCursor",
293        \ "sm:block-Cursor-blinkwait175-blinkoff150-blinkon175"
294        \ ]
295
296  " Default Value
297  set guicursor&
298  call assert_equal(join(default, ','), &guicursor)
299
300  " Argument List Example 1
301  let opt_list = copy(default)
302  let opt_list[0] = "n-c-v:block-nCursor"
303  exec "set guicursor=" . join(opt_list, ',')
304  call assert_equal(join(opt_list, ','), &guicursor)
305  unlet opt_list
306
307  " Argument List Example 2
308  let opt_list = copy(default)
309  let opt_list[3] = "i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150"
310  exec "set guicursor=" . join(opt_list, ',')
311  call assert_equal(join(opt_list, ','), &guicursor)
312  unlet opt_list
313
314  " 'a' Mode
315  set guicursor&
316  let &guicursor .= ',a:blinkon0'
317  call assert_equal(join(default, ',') . ",a:blinkon0", &guicursor)
318
319  let &guicursor = guicursor_saved
320endfunc
321
322func Test_set_guifont()
323  let skipped = ''
324
325  let guifont_saved = &guifont
326  if has('xfontset')
327    " Prevent 'guifontset' from canceling 'guifont'.
328    let guifontset_saved = &guifontset
329    set guifontset=
330  endif
331
332  if !g:x11_based_gui
333    let skipped = g:not_implemented
334  elseif has('gui_athena') || has('gui_motif')
335    " Non-empty font list with invalid font names.
336    "
337    " This test is twofold: (1) It checks if the command fails as expected
338    " when there are no loadable fonts found in the list. (2) It checks if
339    " 'guifont' remains the same after the command loads none of the fonts
340    " listed.
341    let flist = &guifont
342    call assert_fails('set guifont=-notexist1-*,-notexist2-*')
343    call assert_equal(flist, &guifont)
344
345    " Non-empty font list with a valid font name.  Should pick up the first
346    " valid font.
347    set guifont=-notexist1-*,fixed,-notexist2-*
348    let pat = '\(fixed\)\|\(\c-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO8859-1\)'
349    call assert_match(pat, getfontname())
350
351    " Empty list. Should fallback to the built-in default.
352    set guifont=
353    let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
354    call assert_match(pat, getfontname())
355
356  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
357    " For GTK, what we refer to as 'font names' in our manual are actually
358    " 'initial font patterns'.  A valid font which matches the 'canonical font
359    " pattern' constructed from a given 'initial pattern' is to be looked up
360    " and loaded.  That explains why the GTK GUIs appear to accept 'invalid
361    " font names'.
362    "
363    " Non-empty list.  Should always pick up the first element, no matter how
364    " strange it is, as explained above.
365    set guifont=(´・ω・`)\ 12,Courier\ 12
366    call assert_equal('(´・ω・`) 12', getfontname())
367
368    " Empty list. Should fallback to the built-in default.
369    set guifont=
370    call assert_equal('Monospace 10', getfontname())
371  endif
372
373  if has('xfontset')
374    let &guifontset = guifontset_saved
375  endif
376  let &guifont = guifont_saved
377
378  if !empty(skipped)
379    throw skipped
380  endif
381endfunc
382
383func Test_set_guifontset()
384  let skipped = ''
385
386  if !has('xfontset')
387    let skipped = g:not_supported . 'xfontset'
388  else
389    let ctype_saved = v:ctype
390
391    " First, since XCreateFontSet(3) is very sensitive to locale, fonts must
392    " be chosen meticulously.
393    let font_head = '-misc-fixed-medium-r-normal--14'
394
395    let font_aw70 = font_head . '-130-75-75-c-70'
396    let font_aw140 = font_head . '-130-75-75-c-140'
397
398    let font_jisx0201 = font_aw70 . '-jisx0201.1976-0'
399    let font_jisx0208 = font_aw140 . '-jisx0208.1983-0'
400
401    let full_XLFDs = join([ font_jisx0208, font_jisx0201 ], ',')
402    let short_XLFDs = join([ font_aw140, font_aw70 ], ',')
403    let singleton = font_head . '-*'
404    let aliases = 'k14,r14'
405
406    " Second, among 'locales', look up such a locale that gets 'set
407    " guifontset=' to work successfully with every fontset specified with
408    " 'fontsets'.
409    let locales = [ 'ja_JP.UTF-8', 'ja_JP.eucJP', 'ja_JP.SJIS' ]
410    let fontsets = [ full_XLFDs, short_XLFDs, singleton, aliases ]
411
412    let feasible = 0
413    for locale in locales
414      try
415        exec 'language ctype' locale
416      catch /^Vim\%((\a\+)\)\=:E197/
417        continue
418      endtry
419      let done = 0
420      for fontset in fontsets
421        try
422          exec 'set guifontset=' . fontset
423        catch /^Vim\%((\a\+)\)\=:E\%(250\|252\|234\|597\|598\)/
424          break
425        endtry
426        let done += 1
427      endfor
428      if done == len(fontsets)
429        let feasible = 1
430        break
431      endif
432    endfor
433
434    " Third, give a set of tests if it is found feasible.
435    if !feasible
436      let skipped = g:not_hosted
437    else
438      " N.B. 'v:ctype' has already been set to an appropriate value in the
439      " previous loop.
440      for fontset in fontsets
441        exec 'set guifontset=' . fontset
442        call assert_equal(fontset, &guifontset)
443      endfor
444    endif
445
446    " Finally, restore ctype.
447    exec 'language ctype' ctype_saved
448  endif
449
450  if !empty(skipped)
451    throw skipped
452  endif
453endfunc
454
455func Test_set_guifontwide()
456  let skipped = ''
457
458  if !g:x11_based_gui
459    let skipped = g:not_implemented
460  elseif has('gui_gtk')
461    let guifont_saved = &guifont
462    let guifontwide_saved = &guifontwide
463
464    let fc_match = exepath('fc-match')
465    if empty(fc_match)
466      let skipped = g:not_hosted
467    else
468      let &guifont = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=en')
469      let wide = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=ja')
470      exec 'set guifontwide=' . fnameescape(wide)
471      call assert_equal(wide, &guifontwide)
472    endif
473
474    let &guifontwide = guifontwide_saved
475    let &guifont = guifont_saved
476
477  elseif has('gui_athena') || has('gui_motif')
478    " guifontwide is premised upon the xfontset feature.
479    if !has('xfontset')
480      let skipped = g:not_supported . 'xfontset'
481    else
482      let encoding_saved    = &encoding
483      let guifont_saved     = &guifont
484      let guifontset_saved  = &guifontset
485      let guifontwide_saved = &guifontwide
486
487      let nfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-90-iso10646-1'
488      let wfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-180-iso10646-1'
489
490      set encoding=utf-8
491
492      " Case 1: guifontset is empty
493      set guifontset=
494
495      " Case 1-1: Automatic selection
496      set guifontwide=
497      exec 'set guifont=' . nfont
498      call assert_equal(wfont, &guifontwide)
499
500      " Case 1-2: Manual selection
501      exec 'set guifontwide=' . wfont
502      exec 'set guifont=' . nfont
503      call assert_equal(wfont, &guifontwide)
504
505      " Case 2: guifontset is invalid
506      try
507        set guifontset=-*-notexist-*
508        call assert_report("'set guifontset=-*-notexist-*' should have failed")
509      catch
510        call assert_exception('E598')
511      endtry
512      " Set it to an invalid value brutally for preparation.
513      let &guifontset = '-*-notexist-*'
514
515      " Case 2-1: Automatic selection
516      set guifontwide=
517      exec 'set guifont=' . nfont
518      call assert_equal(wfont, &guifontwide)
519
520      " Case 2-2: Manual selection
521      exec 'set guifontwide=' . wfont
522      exec 'set guifont=' . nfont
523      call assert_equal(wfont, &guifontwide)
524
525      let &guifontwide = guifontwide_saved
526      let &guifontset  = guifontset_saved
527      let &guifont     = guifont_saved
528      let &encoding    = encoding_saved
529    endif
530  endif
531
532  if !empty(skipped)
533    throw skipped
534  endif
535endfunc
536
537func Test_set_guiheadroom()
538  let skipped = ''
539
540  if !g:x11_based_gui
541    let skipped = g:not_supported . 'guiheadroom'
542  else
543    " Since this script is to be read together with '-U NONE', the default
544    " value must be preserved.
545    call assert_equal(50, &guiheadroom)
546  endif
547
548  if !empty(skipped)
549    throw skipped
550  endif
551endfunc
552
553func Test_set_guioptions()
554  let guioptions_saved = &guioptions
555  let duration = '200m'
556
557  if has('win32')
558    " Default Value
559    set guioptions&
560    call assert_equal('egmrLtT', &guioptions)
561
562  else
563    " Default Value
564    set guioptions&
565    call assert_equal('aegimrLtT', &guioptions)
566
567    " To activate scrollbars of type 'L' or 'R'.
568    wincmd v
569    redraw!
570
571    " Remove all default GUI ornaments
572    set guioptions-=T
573    exec 'sleep' . duration
574    call assert_equal('aegimrLt', &guioptions)
575    set guioptions-=t
576    exec 'sleep' . duration
577    call assert_equal('aegimrL', &guioptions)
578    set guioptions-=L
579    exec 'sleep' . duration
580    call assert_equal('aegimr', &guioptions)
581    set guioptions-=r
582    exec 'sleep' . duration
583    call assert_equal('aegim', &guioptions)
584    set guioptions-=m
585    exec 'sleep' . duration
586    call assert_equal('aegi', &guioptions)
587
588    " Try non-default GUI ornaments
589    set guioptions+=l
590    exec 'sleep' . duration
591    call assert_equal('aegil', &guioptions)
592    set guioptions-=l
593    exec 'sleep' . duration
594    call assert_equal('aegi', &guioptions)
595
596    set guioptions+=R
597    exec 'sleep' . duration
598    call assert_equal('aegiR', &guioptions)
599    set guioptions-=R
600    exec 'sleep' . duration
601    call assert_equal('aegi', &guioptions)
602
603    set guioptions+=b
604    exec 'sleep' . duration
605    call assert_equal('aegib', &guioptions)
606    set guioptions+=h
607    exec 'sleep' . duration
608    call assert_equal('aegibh', &guioptions)
609    set guioptions-=h
610    exec 'sleep' . duration
611    call assert_equal('aegib', &guioptions)
612    set guioptions-=b
613    exec 'sleep' . duration
614    call assert_equal('aegi', &guioptions)
615
616    set guioptions+=v
617    exec 'sleep' . duration
618    call assert_equal('aegiv', &guioptions)
619    set guioptions-=v
620    exec 'sleep' . duration
621    call assert_equal('aegi', &guioptions)
622
623    if has('gui_motif')
624      set guioptions+=F
625      exec 'sleep' . duration
626      call assert_equal('aegiF', &guioptions)
627      set guioptions-=F
628      exec 'sleep' . duration
629      call assert_equal('aegi', &guioptions)
630    endif
631
632    " Restore GUI ornaments to the default state.
633    set guioptions+=m
634    exec 'sleep' . duration
635    call assert_equal('aegim', &guioptions)
636    set guioptions+=r
637    exec 'sleep' . duration
638    call assert_equal('aegimr', &guioptions)
639    set guioptions+=L
640    exec 'sleep' . duration
641    call assert_equal('aegimrL', &guioptions)
642    set guioptions+=t
643    exec 'sleep' . duration
644    call assert_equal('aegimrLt', &guioptions)
645    set guioptions+=T
646    exec 'sleep' . duration
647    call assert_equal("aegimrLtT", &guioptions)
648
649    wincmd o
650    redraw!
651  endif
652
653  let &guioptions = guioptions_saved
654endfunc
655
656func Test_set_guipty()
657  let guipty_saved = &guipty
658
659  " Default Value
660  set guipty&
661  call assert_equal(1, &guipty)
662
663  set noguipty
664  call assert_equal(0, &guipty)
665
666  let &guipty = guipty_saved
667endfunc
668
669func Test_shell_command()
670  new
671  r !echo hello
672  call assert_equal('hello', substitute(getline(2), '\W', '', 'g'))
673  bwipe!
674endfunc
675
676func Test_syntax_colortest()
677  runtime syntax/colortest.vim
678  redraw!
679  sleep 200m
680  bwipe!
681endfunc
682
683func Test_set_term()
684  " It's enough to check the current value since setting 'term' to anything
685  " other than builtin_gui makes no sense at all.
686  call assert_equal('builtin_gui', &term)
687endfunc
688
689func Test_windowid_variable()
690  if g:x11_based_gui || has('win32')
691    call assert_true(v:windowid > 0)
692  else
693    call assert_equal(0, v:windowid)
694  endif
695endfunc
696