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