xref: /vim-8.2.3635/src/testdir/test_gui.vim (revision 214641f7)
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_getfontname_with_arg()
34  let skipped = ''
35
36  if !g:x11_based_gui
37    let skipped = g:not_implemented
38  elseif has('gui_athena') || has('gui_motif')
39    " Invalid font name. The result should be an empty string.
40    call assert_equal('', getfontname('notexist'))
41
42    " Valid font name. This is usually the real name of 7x13 by default.
43    let fname = '-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1'
44    call assert_equal(fname, getfontname(fname))
45
46  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
47    " Invalid font name. The result should be the name plus the default size.
48    call assert_equal('notexist 10', getfontname('notexist'))
49
50    " Valid font name. This is usually the real name of Monospace by default.
51    let fname = 'Bitstream Vera Sans Mono 12'
52    call assert_equal(fname, getfontname(fname))
53  endif
54
55  if !empty(skipped)
56    throw skipped
57  endif
58endfunc
59
60func Test_getfontname_without_arg()
61  let skipped = ''
62
63  let fname = getfontname()
64
65  if !g:x11_based_gui
66    let skipped = g:not_implemented
67  elseif has('gui_kde')
68    " 'expected' is the value specified by SetUp() above.
69    call assert_equal('Courier 10 Pitch/8/-1/5/50/0/0/0/0/0', fname)
70  elseif has('gui_athena') || has('gui_motif')
71    " 'expected' is DFLT_FONT of gui_x11.c.
72    call assert_equal('7x13', fname)
73  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
74    " 'expected' is DEFAULT_FONT of gui_gtk_x11.c.
75    call assert_equal('Monospace 10', fname)
76  endif
77
78  if !empty(skipped)
79    throw skipped
80  endif
81endfunc
82
83func Test_quoteplus()
84  let skipped = ''
85
86  if !g:x11_based_gui
87    let skipped = g:not_supported . 'quoteplus'
88  else
89    let quoteplus_saved = @+
90
91    let test_call     = 'Can you hear me?'
92    let test_response = 'Yes, I can.'
93    let vim_exe = exepath(v:progpath)
94    let testee = 'VIMRUNTIME=' . $VIMRUNTIME . '; export VIMRUNTIME;'
95          \ . vim_exe
96	  \ . ' -u NONE -U NONE --noplugin --not-a-term -c ''%s'''
97    " Ignore the "failed to create input context" error.
98    let cmd = 'call test_ignore_error("E285") | '
99	  \ . 'gui -f | '
100	  \ . 'call feedkeys("'
101          \ . '\"+p'
102          \ . ':s/' . test_call . '/' . test_response . '/\<CR>'
103          \ . '\"+yis'
104          \ . ':q!\<CR>", "tx")'
105    let run_vimtest = printf(testee, cmd)
106
107    " Set the quoteplus register to test_call, and another gvim will launched.
108    " Then, it first tries to paste the content of its own quotedplus register
109    " onto it.  Second, it tries to substitute test_responce for the pasted
110    " sentence.  If the sentence is identical to test_call, the substitution
111    " should succeed.  Third, it tries to yank the result of the substitution
112    " to its own quoteplus register, and last it quits.  When system()
113    " returns, the content of the quoteplus register should be identical to
114    " test_response if those quoteplus registers are synchronized properly
115    " with/through the X11 clipboard.
116    let @+ = test_call
117    call system(run_vimtest)
118    call assert_equal(test_response, @+)
119
120    let @+ = quoteplus_saved
121  endif
122
123  if !empty(skipped)
124    throw skipped
125  endif
126endfunc
127
128func Test_set_balloondelay()
129  if !exists('+balloondelay')
130    return
131  endif
132
133  let balloondelay_saved = &balloondelay
134
135  " Check if the default value is identical to that described in the manual.
136  set balloondelay&
137  call assert_equal(600, &balloondelay)
138
139  " Edge cases
140
141  " XXX This fact should be hidden so that people won't be tempted to write
142  " plugin/TimeMachine.vim.  TODO Add reasonable range checks to the source
143  " code.
144  set balloondelay=-1
145  call assert_equal(-1, &balloondelay)
146
147  " Though it's possible to interpret the zero delay to be 'as soon as
148  " possible' or even 'indefinite', its actual meaning depends on the GUI
149  " toolkit in use after all.
150  set balloondelay=0
151  call assert_equal(0, &balloondelay)
152
153  set balloondelay=1
154  call assert_equal(1, &balloondelay)
155
156  " Since p_bdelay is of type long currently, the upper bound can be
157  " impractically huge and machine-dependent.  Practically, it's sufficient
158  " to check if balloondelay works with 0x7fffffff (32 bits) for now.
159  set balloondelay=2147483647
160  call assert_equal(2147483647, &balloondelay)
161
162  let &balloondelay = balloondelay_saved
163endfunc
164
165func Test_set_ballooneval()
166  if !exists('+ballooneval')
167    return
168  endif
169
170  let ballooneval_saved = &ballooneval
171
172  set ballooneval&
173  call assert_equal(0, &ballooneval)
174
175  set ballooneval
176  call assert_notequal(0, &ballooneval)
177
178  set noballooneval
179  call assert_equal(0, &ballooneval)
180
181  let &ballooneval = ballooneval_saved
182endfunc
183
184func Test_set_balloonexpr()
185  if !exists('+balloonexpr')
186    return
187  endif
188
189  let balloonexpr_saved = &balloonexpr
190
191  " Default value
192  set balloonexpr&
193  call assert_equal('', &balloonexpr)
194
195  " User-defined function
196  new
197  func MyBalloonExpr()
198      return 'Cursor is at line ' . v:beval_lnum .
199	      \', column ' . v:beval_col .
200	      \ ' of file ' .  bufname(v:beval_bufnr) .
201	      \ ' on word "' . v:beval_text . '"' .
202	      \ ' in window ' . v:beval_winid . ' (#' . v:beval_winnr . ')'
203  endfunc
204  setl balloonexpr=MyBalloonExpr()
205  setl ballooneval
206  call assert_equal('MyBalloonExpr()', &balloonexpr)
207  " TODO Read non-empty text, place the pointer at a character of a word,
208  " and check if the content of the balloon is the smae as what is expected.
209  " Also, check if textlock works as expected.
210  setl balloonexpr&
211  call assert_equal('', &balloonexpr)
212  delfunc MyBalloonExpr
213  bwipe!
214
215  " Multiline support
216  if has('balloon_multiline')
217    " Multiline balloon using NL
218    new
219    func MyBalloonFuncForMultilineUsingNL()
220      return "Multiline\nSuppported\nBalloon\nusing NL"
221    endfunc
222    setl balloonexpr=MyBalloonFuncForMultilineUsingNL()
223    setl ballooneval
224    call assert_equal('MyBalloonFuncForMultilineUsingNL()', &balloonexpr)
225    " TODO Read non-empty text, place the pointer at a character of a word,
226    " and check if the content of the balloon is the smae as what is
227    " expected.  Also, check if textlock works as expected.
228    setl balloonexpr&
229    delfunc MyBalloonFuncForMultilineUsingNL
230    bwipe!
231
232    " Multiline balloon using List
233    new
234    func MyBalloonFuncForMultilineUsingList()
235      return [ 'Multiline', 'Suppported', 'Balloon', 'using List' ]
236    endfunc
237    setl balloonexpr=MyBalloonFuncForMultilineUsingList()
238    setl ballooneval
239    call assert_equal('MyBalloonFuncForMultilineUsingList()', &balloonexpr)
240    " TODO Read non-empty text, place the pointer at a character of a word,
241    " and check if the content of the balloon is the smae as what is
242    " expected.  Also, check if textlock works as expected.
243    setl balloonexpr&
244    delfunc MyBalloonFuncForMultilineUsingList
245    bwipe!
246  endif
247
248  let &balloonexpr = balloonexpr_saved
249endfunc
250
251func Test_set_guifont()
252  let skipped = ''
253
254  let guifont_saved = &guifont
255  if has('xfontset')
256    " Prevent 'guifontset' from canceling 'guifont'.
257    let guifontset_saved = &guifontset
258    set guifontset=
259  endif
260
261  if !g:x11_based_gui
262    let skipped = g:not_implemented
263  elseif has('gui_athena') || has('gui_motif')
264    " Non-empty font list with invalid font names.
265    "
266    " This test is twofold: (1) It checks if the command fails as expected
267    " when there are no loadable fonts found in the list. (2) It checks if
268    " 'guifont' remains the same after the command loads none of the fonts
269    " listed.
270    let flist = &guifont
271    call assert_fails('set guifont=-notexist1-*,-notexist2-*')
272    call assert_equal(flist, &guifont)
273
274    " Non-empty font list with a valid font name.  Should pick up the first
275    " valid font.
276    set guifont=-notexist1-*,fixed,-notexist2-*
277    call assert_equal('fixed', getfontname())
278
279    " Empty list. Should fallback to the built-in default.
280    set guifont=
281    call assert_equal('7x13', getfontname())
282
283  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
284    " For GTK, what we refer to as 'font names' in our manual are actually
285    " 'initial font patterns'.  A valid font which matches the 'canonical font
286    " pattern' constructed from a given 'initial pattern' is to be looked up
287    " and loaded.  That explains why the GTK GUIs appear to accept 'invalid
288    " font names'.
289    "
290    " Non-empty list.  Should always pick up the first element, no matter how
291    " strange it is, as explained above.
292    set guifont=(´・ω・`)\ 12,Courier\ 12
293    call assert_equal('(´・ω・`) 12', getfontname())
294
295    " Empty list. Should fallback to the built-in default.
296    set guifont=
297    call assert_equal('Monospace 10', getfontname())
298  endif
299
300  if has('xfontset')
301    let &guifontset = guifontset_saved
302  endif
303  let &guifont = guifont_saved
304
305  if !empty(skipped)
306    throw skipped
307  endif
308endfunc
309
310func Test_set_guifontset()
311  let skipped = ''
312
313  if !has('xfontset')
314    let skipped = g:not_supported . 'xfontset'
315  else
316    let ctype_saved = v:ctype
317
318    " First, since XCreateFontSet(3) is very sensitive to locale, fonts must
319    " be chosen meticulously.
320    let font_head = '-misc-fixed-medium-r-normal--14'
321
322    let font_aw70 = font_head . '-130-75-75-c-70'
323    let font_aw140 = font_head . '-130-75-75-c-140'
324
325    let font_jisx0201 = font_aw70 . '-jisx0201.1976-0'
326    let font_jisx0208 = font_aw140 . '-jisx0208.1983-0'
327
328    let full_XLFDs = join([ font_jisx0208, font_jisx0201 ], ',')
329    let short_XLFDs = join([ font_aw140, font_aw70 ], ',')
330    let singleton = font_head . '-*'
331    let aliases = 'k14,r14'
332
333    " Second, among 'locales', look up such a locale that gets 'set
334    " guifontset=' to work successfully with every fontset specified with
335    " 'fontsets'.
336    let locales = [ 'ja_JP.UTF-8', 'ja_JP.eucJP', 'ja_JP.SJIS' ]
337    let fontsets = [ full_XLFDs, short_XLFDs, singleton, aliases ]
338
339    let feasible = 0
340    for locale in locales
341      try
342        exec 'language ctype' locale
343      catch /^Vim\%((\a\+)\)\=:E197/
344        continue
345      endtry
346      let done = 0
347      for fontset in fontsets
348        try
349          exec 'set guifontset=' . fontset
350        catch /^Vim\%((\a\+)\)\=:E\%(250\|252\|234\|597\|598\)/
351          break
352        endtry
353        let done += 1
354      endfor
355      if done == len(fontsets)
356        let feasible = 1
357        break
358      endif
359    endfor
360
361    " Third, give a set of tests if it is found feasible.
362    if !feasible
363      let skipped = g:not_hosted
364    else
365      " N.B. 'v:ctype' has already been set to an appropriate value in the
366      " previous loop.
367      for fontset in fontsets
368        exec 'set guifontset=' . fontset
369        call assert_equal(fontset, &guifontset)
370      endfor
371    endif
372
373    " Finally, restore ctype.
374    exec 'language ctype' ctype_saved
375  endif
376
377  if !empty(skipped)
378    throw skipped
379  endif
380endfunc
381
382func Test_set_guifontwide()
383  let skipped = ''
384
385  if !g:x11_based_gui
386    let skipped = g:not_implemented
387  elseif has('gui_gtk')
388    let guifont_saved = &guifont
389    let guifontwide_saved = &guifontwide
390
391    let fc_match = exepath('fc-match')
392    if empty(fc_match)
393      let skipped = g:not_hosted
394    else
395      let &guifont = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=en')
396      let wide = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=ja')
397      exec 'set guifontwide=' . fnameescape(wide)
398      call assert_equal(wide, &guifontwide)
399    endif
400
401    let &guifontwide = guifontwide_saved
402    let &guifont = guifont_saved
403
404  elseif has('gui_athena') || has('gui_motif')
405    " guifontwide is premised upon the xfontset feature.
406    if !has('xfontset')
407      let skipped = g:not_supported . 'xfontset'
408    else
409      let encoding_saved    = &encoding
410      let guifont_saved     = &guifont
411      let guifontset_saved  = &guifontset
412      let guifontwide_saved = &guifontwide
413
414      let nfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-90-iso10646-1'
415      let wfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-180-iso10646-1'
416
417      set encoding=utf-8
418
419      " Case 1: guifontset is empty
420      set guifontset=
421
422      " Case 1-1: Automatic selection
423      set guifontwide=
424      exec 'set guifont=' . nfont
425      call assert_equal(wfont, &guifontwide)
426
427      " Case 1-2: Manual selection
428      exec 'set guifontwide=' . wfont
429      exec 'set guifont=' . nfont
430      call assert_equal(wfont, &guifontwide)
431
432      " Case 2: guifontset is invalid
433      try
434        set guifontset=-*-notexist-*
435        call assert_false(1, "'set guifontset=-*-notexist-*' should have failed")
436      catch
437        call assert_exception('E598')
438      endtry
439      " Set it to an invalid value brutally for preparation.
440      let &guifontset = '-*-notexist-*'
441
442      " Case 2-1: Automatic selection
443      set guifontwide=
444      exec 'set guifont=' . nfont
445      call assert_equal(wfont, &guifontwide)
446
447      " Case 2-2: Manual selection
448      exec 'set guifontwide=' . wfont
449      exec 'set guifont=' . nfont
450      call assert_equal(wfont, &guifontwide)
451
452      let &guifontwide = guifontwide_saved
453      let &guifontset  = guifontset_saved
454      let &guifont     = guifont_saved
455      let &encoding    = encoding_saved
456    endif
457  endif
458
459  if !empty(skipped)
460    throw skipped
461  endif
462endfunc
463
464func Test_set_guiheadroom()
465  let skipped = ''
466
467  if !g:x11_based_gui
468    let skipped = g:not_supported . 'guiheadroom'
469  else
470    " Since this script is to be read together with '-U NONE', the default
471    " value must be preserved.
472    call assert_equal(50, &guiheadroom)
473  endif
474
475  if !empty(skipped)
476    throw skipped
477  endif
478endfunc
479
480func Test_getwinpos()
481  call assert_match('Window position: X \d\+, Y \d\+', execute('winpos'))
482  call assert_true(getwinposx() >= 0)
483  call assert_true(getwinposy() >= 0)
484endfunc
485
486func Test_shell_command()
487  new
488  r !echo hello
489  call assert_equal('hello', substitute(getline(2), '\W', '', 'g'))
490  bwipe!
491endfunc
492
493func Test_windowid_variable()
494  if g:x11_based_gui || has('win32')
495    call assert_true(v:windowid > 0)
496  else
497    call assert_equal(0, v:windowid)
498  endif
499endfunc
500