changeset 21765:08940efa6b4e v8.2.1432

patch 8.2.1432: various inconsistencies in test files Commit: https://github.com/vim/vim/commit/6d91bcb4d23b5c6a0be72c384beaf385e2d9d606 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 12 18:50:36 2020 +0200 patch 8.2.1432: various inconsistencies in test files Problem: Various inconsistencies in test files. Solution: Add modelines where they were missing. Use Check commands instead of silently skipping over tests. Adjust indents and comments. (Ken Takata, closes #6695)
author Bram Moolenaar <Bram@vim.org>
date Wed, 12 Aug 2020 19:00:08 +0200
parents 476b6faad407
children 283490dee44d
files src/testdir/test_arglist.vim src/testdir/test_assert.vim src/testdir/test_autochdir.vim src/testdir/test_autocmd.vim src/testdir/test_autoload.vim src/testdir/test_balloon.vim src/testdir/test_balloon_gui.vim src/testdir/test_behave.vim src/testdir/test_blockedit.vim src/testdir/test_breakindent.vim src/testdir/test_bufline.vim src/testdir/test_bufwintabinfo.vim src/testdir/test_cd.vim src/testdir/test_changedtick.vim src/testdir/test_changelist.vim src/testdir/test_channel.vim src/testdir/test_checkpath.vim src/testdir/test_cindent.vim src/testdir/test_cjk_linebreak.vim src/testdir/test_clientserver.vim src/testdir/test_close_count.vim src/testdir/test_cmdline.vim src/testdir/test_command_count.vim src/testdir/test_comparators.vim src/testdir/test_compiler.vim src/testdir/test_crypt.vim src/testdir/test_cursorline.vim src/testdir/test_curswant.vim src/testdir/test_debugger.vim src/testdir/test_delete.vim src/testdir/test_diffmode.vim src/testdir/test_digraph.vim src/testdir/test_display.vim src/testdir/test_edit.vim src/testdir/test_environ.vim src/testdir/test_erasebackword.vim src/testdir/test_escaped_glob.vim src/testdir/test_ex_equal.vim src/testdir/test_ex_undo.vim src/testdir/test_ex_z.vim src/testdir/test_exec_while_if.vim src/testdir/test_exists.vim src/testdir/test_exists_autocmd.vim src/testdir/test_exit.vim src/testdir/test_expand_dllpath.vim src/testdir/test_expr_utf8.vim src/testdir/test_feedkeys.vim src/testdir/test_file_size.vim src/testdir/test_fileformat.vim src/testdir/test_filter_cmd.vim src/testdir/test_find_complete.vim src/testdir/test_findfile.vim src/testdir/test_fixeol.vim src/testdir/test_flatten.vim src/testdir/test_fnameescape.vim src/testdir/test_fold.vim src/testdir/test_functions.vim src/testdir/test_ga.vim src/testdir/test_getcwd.vim src/testdir/test_getvar.vim src/testdir/test_glob2regpat.vim src/testdir/test_global.vim src/testdir/test_gui.vim src/testdir/test_gui_init.vim src/testdir/test_highlight.vim src/testdir/test_hlsearch.vim src/testdir/test_iminsert.vim src/testdir/test_increment_dbcs.vim src/testdir/test_ins_complete.vim src/testdir/test_interrupt.vim src/testdir/test_job_fails.vim src/testdir/test_join.vim src/testdir/test_json.vim src/testdir/test_jumplist.vim src/testdir/test_jumps.vim src/testdir/test_lambda.vim src/testdir/test_langmap.vim src/testdir/test_largefile.vim src/testdir/test_lineending.vim src/testdir/test_listchars.vim src/testdir/test_listener.vim src/testdir/test_listlbr.vim src/testdir/test_listlbr_utf8.vim src/testdir/test_makeencoding.vim src/testdir/test_man.vim src/testdir/test_mapping.vim src/testdir/test_marks.vim src/testdir/test_matchadd_conceal.vim src/testdir/test_matchadd_conceal_utf8.vim src/testdir/test_memory_usage.vim src/testdir/test_menu.vim src/testdir/test_messages.vim src/testdir/test_mksession.vim src/testdir/test_modeline.vim src/testdir/test_nested_function.vim src/testdir/test_number.vim src/testdir/test_options.vim src/testdir/test_packadd.vim src/testdir/test_partial.vim src/testdir/test_paste.vim src/testdir/test_plus_arg_edit.vim src/testdir/test_preview.vim src/testdir/test_profile.vim src/testdir/test_prompt_buffer.vim src/testdir/test_quickfix.vim src/testdir/test_quotestar.vim src/testdir/test_random.vim src/testdir/test_recover.vim src/testdir/test_regex_char_classes.vim src/testdir/test_regexp_latin.vim src/testdir/test_registers.vim src/testdir/test_rename.vim src/testdir/test_retab.vim src/testdir/test_scriptnames.vim src/testdir/test_scroll_opt.vim src/testdir/test_scrollbind.vim src/testdir/test_search_stat.vim src/testdir/test_searchpos.vim src/testdir/test_set.vim src/testdir/test_sha256.vim src/testdir/test_shift.vim src/testdir/test_shortpathname.vim src/testdir/test_signs.vim src/testdir/test_sort.vim src/testdir/test_sound.vim src/testdir/test_source_utf8.vim src/testdir/test_spellfile.vim src/testdir/test_startup.vim src/testdir/test_startup_utf8.vim src/testdir/test_stat.vim src/testdir/test_suspend.vim src/testdir/test_swap.vim src/testdir/test_syntax.vim src/testdir/test_tab.vim src/testdir/test_tabline.vim src/testdir/test_tagcase.vim src/testdir/test_tagjump.vim src/testdir/test_taglist.vim src/testdir/test_termcodes.vim src/testdir/test_termencoding.vim src/testdir/test_terminal.vim src/testdir/test_terminal2.vim src/testdir/test_terminal3.vim src/testdir/test_terminal_fail.vim src/testdir/test_true_false.vim src/testdir/test_utf8_comparisons.vim src/testdir/test_vartabs.vim src/testdir/test_version.vim src/testdir/test_vim9_expr.vim src/testdir/test_winbar.vim src/testdir/test_winbuf_close.vim src/testdir/test_window_cmd.vim src/testdir/test_window_id.vim src/testdir/test_windows_home.vim src/testdir/test_wnext.vim src/testdir/test_wordcount.vim src/testdir/test_writefile.vim src/testdir/test_xxd.vim src/version.c
diffstat 159 files changed, 972 insertions(+), 903 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -242,11 +242,11 @@ endfunc
 
 func Test_args_with_quote()
   " Only on Unix can a file name include a double quote.
-  if has('unix')
-    args \"foobar
-    call assert_equal('"foobar', argv(0))
-    %argdelete
-  endif
+  CheckUnix
+
+  args \"foobar
+  call assert_equal('"foobar', argv(0))
+  %argdelete
 endfunc
 
 " Test for 0argadd and 0argedit
--- a/src/testdir/test_assert.vim
+++ b/src/testdir/test_assert.vim
@@ -374,3 +374,5 @@ func Test_zz_quit_detected()
   " Verify that if a test function ends Vim the test script detects this.
   quit
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_autochdir.vim
+++ b/src/testdir/test_autochdir.vim
@@ -24,3 +24,5 @@ func Test_set_filename()
   call chdir(cwd)
   call delete('samples/Xtest')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -70,9 +70,7 @@ if has('timers')
   endfunc
 
   func Test_cursorhold_insert_with_timer_interrupt()
-    if !has('job')
-      return
-    endif
+    CheckFeature job
     " Need to move the cursor.
     call feedkeys("ggG", "xt")
 
@@ -535,9 +533,7 @@ func s:AutoCommandOptionSet(match)
 endfunc
 
 func Test_OptionSet()
-  if !has("eval") || !exists("+autochdir")
-    return
-  endif
+  CheckOption autochdir
 
   badd test_autocmd.vim
 
@@ -1778,12 +1774,11 @@ func Test_nocatch_wipe_all_buffers()
 endfunc
 
 func Test_nocatch_wipe_dummy_buffer()
-  if has('quickfix')
-    " Nasty autocommand: wipe buffer on any event.
-    au * x bwipe
-    call assert_fails('lv½ /x', 'E937')
-    au!
-  endif
+  CheckFeature quickfix
+  " Nasty autocommand: wipe buffer on any event.
+  au * x bwipe
+  call assert_fails('lv½ /x', 'E937')
+  au!
 endfunc
 
 function s:Before_test_dirchanged()
@@ -1834,9 +1829,7 @@ function Test_dirchanged_local()
 endfunc
 
 function Test_dirchanged_auto()
-  if !exists('+autochdir')
-    return
-  endif
+  CheckOption autochdir
   call s:Before_test_dirchanged()
   call test_autochdir()
   autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
@@ -2087,9 +2080,8 @@ endfunc
 " - FileReadPost	decompress the file
 func Test_ReadWrite_Autocmds()
   " Run this test only on Unix-like systems and if gzip is available
-  if !has('unix') || !executable("gzip")
-    return
-  endif
+  CheckUnix
+  CheckExecutable gzip
 
   " Make $GZIP empty, "-v" would cause trouble.
   let $GZIP = ""
--- a/src/testdir/test_autoload.vim
+++ b/src/testdir/test_autoload.vim
@@ -22,3 +22,5 @@ func Test_autoload_vim9script()
   call assert_equal('some', auto9#getsome())
   call assert_equal(49, auto9#add42(7))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_balloon.vim
+++ b/src/testdir/test_balloon.vim
@@ -64,3 +64,5 @@ func Test_balloon_eval_term_visual()
   call StopVimInTerminal(buf)
   call delete('XTest_beval_visual')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_balloon_gui.vim
+++ b/src/testdir/test_balloon_gui.vim
@@ -17,3 +17,5 @@ func Test_balloon_show_gui()
   sleep 10m
   call balloon_show('')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_behave.vim
+++ b/src/testdir/test_behave.vim
@@ -27,3 +27,5 @@ endfunc
 func Test_behave_error()
   call assert_fails('behave x', 'E475:')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_blockedit.vim
+++ b/src/testdir/test_blockedit.vim
@@ -1,5 +1,4 @@
 " Test for block inserting
-"
 
 func Test_blockinsert_indent()
   new
--- a/src/testdir/test_breakindent.vim
+++ b/src/testdir/test_breakindent.vim
@@ -46,9 +46,7 @@ endfunc
 
 func Test_breakindent01_vartabs()
   " like 01 but with vartabs feature
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   call s:test_windows('setl briopt=min:0 vts=4')
   let lines = s:screen_lines(line('.'),8)
   let expect = [
@@ -75,9 +73,7 @@ func Test_breakindent02()
 endfunc
 
 func Test_breakindent02_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " simple breakindent test with showbreak set
   call s:test_windows('setl briopt=min:0 sbr=>> vts=4')
   let lines = s:screen_lines(line('.'),8)
@@ -106,9 +102,7 @@ endfunc
 
 func Test_breakindent03_vartabs()
   " simple breakindent test with showbreak set and briopt including sbr
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   call s:test_windows('setl briopt=sbr,min:0 sbr=++ vts=4')
   let lines = s:screen_lines(line('.'),8)
   let expect = [
@@ -139,9 +133,7 @@ endfunc
 
 func Test_breakindent04_vartabs()
   " breakindent set with min width 18
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   call s:test_windows('setl sbr= briopt=min:18 vts=4')
   let lines = s:screen_lines(line('.'),8)
   let expect = [
@@ -169,9 +161,7 @@ endfunc
 
 func Test_breakindent05_vartabs()
   " breakindent set and shift by 2
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   call s:test_windows('setl briopt=shift:2,min:0 vts=4')
   let lines = s:screen_lines(line('.'),8)
   let expect = [
@@ -198,9 +188,7 @@ endfunc
 
 func Test_breakindent06_vartabs()
   " breakindent set and shift by -1
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   call s:test_windows('setl briopt=shift:-1,min:0 vts=4')
   let lines = s:screen_lines(line('.'),8)
   let expect = [
@@ -227,9 +215,7 @@ func Test_breakindent07()
 endfunc
 
 func Test_breakindent07_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " breakindent set and shift by 1, Number  set sbr=? and briopt:sbr
   call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n vts=4')
   let lines = s:screen_lines(line('.'),10)
@@ -258,9 +244,7 @@ func Test_breakindent07a()
 endfunc
 
 func Test_breakindent07a_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " breakindent set and shift by 1, Number  set sbr=? and briopt:sbr
   call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 vts=4')
   let lines = s:screen_lines(line('.'),10)
@@ -293,9 +277,7 @@ func Test_breakindent08()
 endfunc
 
 func Test_breakindent08_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
   call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4 vts=4')
   " make sure, cache is invalidated!
@@ -327,9 +309,7 @@ func Test_breakindent08a()
 endfunc
 
 func Test_breakindent08a_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
   call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list vts=4')
   let lines = s:screen_lines(line('.'),10)
@@ -356,9 +336,7 @@ func Test_breakindent09()
 endfunc
 
 func Test_breakindent09_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " breakindent set and shift by 1, Number and list set sbr=#
   call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list vts=4')
   let lines = s:screen_lines(line('.'),10)
@@ -390,9 +368,7 @@ func Test_breakindent10()
 endfunc
 
 func Test_breakindent10_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " breakindent set, Number set sbr=~
   call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0 vts=4')
   " make sure, cache is invalidated!
@@ -421,9 +397,7 @@ func Test_breakindent11()
 endfunc
 
 func Test_breakindent11_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " test strdisplaywidth()
   call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4 vts=4')
   let text = getline(2)
@@ -447,9 +421,7 @@ func Test_breakindent12()
 endfunc
 
 func Test_breakindent12_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " test breakindent with long indent
   let s:input = "\t\t\t\t\t{"
   call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>- vts=4')
@@ -478,9 +450,7 @@ func Test_breakindent13()
 endfunc
 
 func Test_breakindent13_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   let s:input = ""
   call s:test_windows('setl breakindent briopt=min:10 ts=8 vts=8')
   vert resize 20
@@ -512,9 +482,7 @@ func Test_breakindent14()
 endfunc
 
 func Test_breakindent14_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   let s:input = ""
   call s:test_windows('setl breakindent briopt= ts=8 vts=8')
   vert resize 30
@@ -548,9 +516,7 @@ func Test_breakindent15()
 endfunc
 
 func Test_breakindent15_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   let s:input = ""
   call s:test_windows('setl breakindent briopt= ts=8 sw=8 vts=8')
   vert resize 30
@@ -592,9 +558,7 @@ func Test_breakindent16()
 endfunc
 
 func Test_breakindent16_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   " Check that overlong lines are indented correctly.
   let s:input = ""
   call s:test_windows('setl breakindent briopt=min:0 ts=4 vts=4')
@@ -620,9 +584,7 @@ func Test_breakindent16_vartabs()
 endfunc
 
 func Test_breakindent17_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   let s:input = ""
   call s:test_windows('setl breakindent list listchars=tab:<-> showbreak=+++')
   call setline(1, "\t" . repeat('a', 63))
@@ -640,9 +602,7 @@ func Test_breakindent17_vartabs()
 endfunc
 
 func Test_breakindent18_vartabs()
-  if !has("vartabs")
-    return
-  endif
+  CheckFeature vartabs
   let s:input = ""
   call s:test_windows('setl breakindent list listchars=tab:<->')
   call setline(1, "\t" . repeat('a', 63))
--- a/src/testdir/test_bufline.vim
+++ b/src/testdir/test_bufline.vim
@@ -202,3 +202,5 @@ func Test_appendbufline_redraw()
   call StopVimInTerminal(buf)
   call delete('XscriptMatchCommon')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_bufwintabinfo.vim
+++ b/src/testdir/test_bufwintabinfo.vim
@@ -1,4 +1,5 @@
 " Tests for the getbufinfo(), getwininfo() and gettabinfo() functions
+
 source check.vim
 
 func Test_getbufwintabinfo()
@@ -168,3 +169,5 @@ func Test_getbufinfo_lines()
   edit Xfoo
   bw!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_cd.vim
+++ b/src/testdir/test_cd.vim
@@ -191,3 +191,5 @@ func Test_cd_completion()
   call delete('XComplDir2', 'd')
   call delete('XComplFile')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_changedtick.vim
+++ b/src/testdir/test_changedtick.vim
@@ -93,3 +93,5 @@ func Test_changedtick_not_incremented_wi
   bwipe
   call delete(fname)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_changelist.vim
+++ b/src/testdir/test_changelist.vim
@@ -1,10 +1,10 @@
 " Tests for the changelist functionality
 
+source check.vim
+
 " Tests for the getchangelist() function
 func Test_getchangelist()
-  if !has("jumplist")
-    return
-  endif
+  CheckFeature jumplist
 
   bwipe!
   enew
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -1348,9 +1348,7 @@ endfunction
 " This caused a crash, because messages were handled while peeking for a
 " character.
 func Test_exit_cb_wipes_buf()
-  if !has('timers')
-    return
-  endif
+  CheckFeature timers
   set cursorline lazyredraw
   call test_override('redraw_flag', 1)
   new
--- a/src/testdir/test_checkpath.vim
+++ b/src/testdir/test_checkpath.vim
@@ -102,3 +102,5 @@ func Test_checkpath3()
   set include&
   set includeexpr&
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_cindent.vim
+++ b/src/testdir/test_cindent.vim
@@ -1,5 +1,4 @@
 " Test for cinoptions and cindent
-"
 
 func Test_cino_hash()
   " Test that curbuf->b_ind_hash_comment is correctly reset
--- a/src/testdir/test_cjk_linebreak.vim
+++ b/src/testdir/test_cjk_linebreak.vim
@@ -1,3 +1,5 @@
+" Test for CJK linebreak
+
 scriptencoding utf-8
 
 func Run_cjk_linebreak_after(rigorous)
@@ -95,3 +97,5 @@ func Test_cjk_linebreak_join_punct()
     %d_
   endfor
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_clientserver.vim
+++ b/src/testdir/test_clientserver.vim
@@ -30,7 +30,7 @@ endfunc
 func Test_client_server()
   let cmd = GetVimCommand()
   if cmd == ''
-    return
+    throw 'GetVimCommand() failed'
   endif
   call Check_X11_Connection()
 
--- a/src/testdir/test_close_count.vim
+++ b/src/testdir/test_close_count.vim
@@ -1,5 +1,5 @@
+" Tests for :[count]close! command
 
-" Tests for :[count]close! command
 func Test_close_count()
   enew! | only
 
@@ -172,3 +172,5 @@ func Test_winclose_command()
   set nohidden
   only!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -86,9 +86,7 @@ func Test_complete_wildmenu()
 endfunc
 
 func Test_map_completion()
-  if !has('cmdline_compl')
-    return
-  endif
+  CheckFeature cmdline_compl
   call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt')
   call assert_equal('"map <unique> <silent>', getreg(':'))
   call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt')
@@ -164,9 +162,7 @@ func Test_map_completion()
 endfunc
 
 func Test_match_completion()
-  if !has('cmdline_compl')
-    return
-  endif
+  CheckFeature cmdline_compl
   hi Aardig ctermfg=green
   call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
   call assert_equal('"match Aardig', getreg(':'))
@@ -175,9 +171,7 @@ func Test_match_completion()
 endfunc
 
 func Test_highlight_completion()
-  if !has('cmdline_compl')
-    return
-  endif
+  CheckFeature cmdline_compl
   hi Aardig ctermfg=green
   call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
   call assert_equal('"hi Aardig', getreg(':'))
@@ -214,9 +208,7 @@ func Test_highlight_easter_egg()
 endfunc
 
 func Test_getcompletion()
-  if !has('cmdline_compl')
-    return
-  endif
+  CheckFeature cmdline_compl
   let groupcount = len(getcompletion('', 'event'))
   call assert_true(groupcount > 0)
   let matchcount = len('File'->getcompletion('event'))
@@ -527,9 +519,7 @@ func Test_cmdline_remove_char()
 endfunc
 
 func Test_cmdline_keymap_ctrl_hat()
-  if !has('keymap')
-    return
-  endif
+  CheckFeature keymap
 
   set keymap=esperanto
   call feedkeys(":\"Jxauxdo \<C-^>Jxauxdo \<C-^>Jxauxdo\<CR>", 'tx')
@@ -596,8 +586,7 @@ func Test_cmdline_complete_user_names()
       call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx')
       call assert_match('^"e \~.*\<' . whoami . '\>', @:)
     endif
-  endif
-  if has('win32')
+  elseif has('win32')
     " Just in case: check that the system has an Administrator account.
     let names = system('net user')
     if names =~ 'Administrator'
@@ -606,14 +595,15 @@ func Test_cmdline_complete_user_names()
       call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx')
       call assert_match('^"e \~.*Administrator', @:)
     endif
+  else
+    throw 'Skipped: does not work on this platform'
   endif
 endfunc
 
 func Test_cmdline_complete_bang()
-  if executable('whoami')
-    call feedkeys(":!whoam\<C-A>\<C-B>\"\<CR>", 'tx')
-    call assert_match('^".*\<whoami\>', @:)
-  endif
+  CheckExecutable whoami
+  call feedkeys(":!whoam\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_match('^".*\<whoami\>', @:)
 endfunc
 
 func Test_cmdline_complete_languages()
@@ -1256,9 +1246,7 @@ endfunc
 
 " Test for the :! command
 func Test_cmd_bang()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
 
   let lines =<< trim [SCRIPT]
     " Test for no previous command
--- a/src/testdir/test_command_count.vim
+++ b/src/testdir/test_command_count.vim
@@ -194,3 +194,5 @@ func Test_command_count_4()
   tabonly!
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_comparators.vim
+++ b/src/testdir/test_comparators.vim
@@ -1,3 +1,5 @@
+" Test for comparators
+
 function Test_Comparators()
   try
     let oldisident=&isident
@@ -7,3 +9,5 @@ function Test_Comparators()
     let &isident=oldisident
   endtry
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_compiler.vim
+++ b/src/testdir/test_compiler.vim
@@ -76,3 +76,5 @@ func Test_compiler_error()
   call assert_fails('compiler! doesnotexist', 'E666:')
   unlet! g:current_compiler
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_crypt.vim
+++ b/src/testdir/test_crypt.vim
@@ -136,3 +136,5 @@ func Test_crypt_set_key_changes_buffer()
   bwipe!
   call delete('Xtest1.txt')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_cursorline.vim
+++ b/src/testdir/test_cursorline.vim
@@ -196,3 +196,5 @@ func Test_cursorline_screenline()
   call StopVimInTerminal(buf)
   call delete(filename)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_curswant.vim
+++ b/src/testdir/test_curswant.vim
@@ -21,3 +21,5 @@ func Test_curswant()
 
   enew!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_debugger.vim
+++ b/src/testdir/test_debugger.vim
@@ -1019,3 +1019,5 @@ func Test_debug_backtrace_level()
   call delete('Xtest1.vim')
   call delete('Xtest2.vim')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_delete.vim
+++ b/src/testdir/test_delete.vim
@@ -110,3 +110,5 @@ func Test_delete_errors()
   call assert_fails('call delete('''')', 'E474:')
   call assert_fails('call delete(''foo'', 0)', 'E15:')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -1,4 +1,5 @@
 " Tests for diff mode
+
 source shared.vim
 source screendump.vim
 source check.vim
@@ -654,9 +655,8 @@ endfunc
 
 func Test_diffpatch()
   " The patch program on MS-Windows may fail or hang.
-  if !executable('patch') || !has('unix')
-    return
-  endif
+  CheckExecutable patch
+  CheckUnix
   new
   insert
 ***************
--- a/src/testdir/test_digraph.vim
+++ b/src/testdir/test_digraph.vim
@@ -453,9 +453,7 @@ func Test_digraphs_output()
 endfunc
 
 func Test_loadkeymap()
-  if !has('keymap')
-    return
-  endif
+  CheckFeature keymap
   new
   set keymap=czech
   set iminsert=0
@@ -494,9 +492,7 @@ endfunc
 
 " Test for error in a keymap file
 func Test_loadkeymap_error()
-  if !has('keymap')
-    return
-  endif
+  CheckFeature keymap
   call assert_fails('loadkeymap', 'E105:')
   call writefile(['loadkeymap', 'a'], 'Xkeymap')
   call assert_fails('source Xkeymap', 'E791:')
--- a/src/testdir/test_display.vim
+++ b/src/testdir/test_display.vim
@@ -1,4 +1,5 @@
 " Test for displaying stuff
+
 if !has('gui_running') && has('unix')
   set term=ansi
 endif
@@ -243,3 +244,5 @@ func Test_visual_block_scroll()
   call StopVimInTerminal(buf)
   call delete(filename)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -156,9 +156,8 @@ endfunc
 
 func Test_edit_06()
   " Test in diff mode
-  if !has("diff") || !executable("diff")
-    return
-  endif
+  CheckFeature diff
+  CheckExecutable diff
   new
   call setline(1, ['abc', 'xxx', 'yyy'])
   vnew
@@ -416,9 +415,7 @@ func Test_edit_CR()
   " Test for <CR> in insert mode
   " basically only in quickfix mode ist tested, the rest
   " has been taken care of by other tests
-  if !has("quickfix")
-    return
-  endif
+  CheckFeature quickfix
   botright new
   call writefile(range(1, 10), 'Xqflist.txt')
   call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
@@ -446,10 +443,9 @@ func Test_edit_CR()
 endfunc
 
 func Test_edit_CTRL_()
+  CheckFeature rightleft
   " disabled for Windows builds, why?
-  if !has("rightleft") || has("win32")
-    return
-  endif
+  CheckNotMSWindows
   let _encoding=&encoding
   set encoding=utf-8
   " Test for CTRL-_
@@ -951,9 +947,7 @@ func Test_edit_CTRL_Z()
 endfunc
 
 func Test_edit_DROP()
-  if !has("dnd")
-    return
-  endif
+  CheckFeature dnd
   new
   call setline(1, ['abc def ghi'])
   call cursor(1, 1)
@@ -967,9 +961,7 @@ func Test_edit_DROP()
 endfunc
 
 func Test_edit_CTRL_V()
-  if has("ebcdic")
-    return
-  endif
+  CheckFeature ebcdic
   new
   call setline(1, ['abc'])
   call cursor(2, 1)
@@ -1009,12 +1001,11 @@ endfunc
 func Test_edit_F21()
   " Pressing <f21>
   " sends a netbeans command
-  if has("netbeans_intg")
-    new
-    " I have no idea what this is supposed to do :)
-    call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
-    bw
-  endif
+  CheckFeature netbeans_intg
+  new
+  " I have no idea what this is supposed to do :)
+  call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
+  bw
 endfunc
 
 func Test_edit_HOME_END()
@@ -1095,9 +1086,7 @@ endfunc
 
 func Test_edit_MOUSE()
   " This is a simple test, since we not really using the mouse here
-  if !has("mouse")
-    return
-  endif
+  CheckFeature mouse
   10new
   call setline(1, range(1, 100))
   call cursor(1, 1)
@@ -1366,10 +1355,8 @@ func Test_edit_rightleft()
 endfunc
 
 func Test_edit_complete_very_long_name()
-  if !has('unix')
-    " Long directory names only work on Unix.
-    return
-  endif
+  " Long directory names only work on Unix.
+  CheckUnix
 
   let dirname = getcwd() . "/Xdir"
   let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
@@ -1710,8 +1697,7 @@ endfunc
 func Test_edit_hkmap()
   CheckFeature rightleft
   if has('win32') && !has('gui')
-    " Test fails on the MS-Windows terminal version
-    return
+    throw 'Skipped: fails on the MS-Windows terminal version'
   endif
   new
 
--- a/src/testdir/test_environ.vim
+++ b/src/testdir/test_environ.vim
@@ -1,3 +1,5 @@
+" Test for environment variables.
+
 scriptencoding utf-8
 
 func Test_environ()
@@ -42,3 +44,5 @@ func Test_external_env()
   endif
   call assert_equal('', result)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_erasebackword.vim
+++ b/src/testdir/test_erasebackword.vim
@@ -1,3 +1,4 @@
+" Test for i_CTRL-W
 
 func Test_erasebackword()
   enew
@@ -17,3 +18,5 @@ func Test_erasebackword()
 
   enew!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_escaped_glob.vim
+++ b/src/testdir/test_escaped_glob.vim
@@ -1,17 +1,17 @@
 " Test whether glob()/globpath() return correct results with certain escaped
 " characters.
 
+source check.vim
+
 func SetUp()
   " consistent sorting of file names
   set nofileignorecase
 endfunction
 
 function Test_glob()
-  if !has('unix')
-    " This test fails on Windows because of the special characters in the
-    " filenames. Disable the test on non-Unix systems for now.
-    return
-  endif
+  " This test fails on Windows because of the special characters in the
+  " filenames. Disable the test on non-Unix systems for now.
+  CheckUnix
 
   " Execute these commands in the sandbox, so that using the shell fails.
   " Setting 'shell' to an invalid name causes a memory leak.
@@ -31,3 +31,5 @@ function Test_globpath()
   sandbox call assert_equal(['sautest/autoload/globone.vim', 'sautest/autoload/globtwo.vim'],
         \ 'glob*.vim'->globpath('sautest/autoload', 0, 1))
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_ex_equal.vim
+++ b/src/testdir/test_ex_equal.vim
@@ -30,3 +30,5 @@ func Test_ex_equal()
 
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_ex_undo.vim
+++ b/src/testdir/test_ex_undo.vim
@@ -17,3 +17,5 @@ func Test_ex_undo()
   call assert_equal(1, line('$'))
   quit!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_ex_z.vim
+++ b/src/testdir/test_ex_z.vim
@@ -83,3 +83,5 @@ func Test_z_negative_lnum()
   call assert_equal(1, line('.'))
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_exec_while_if.vim
+++ b/src/testdir/test_exec_while_if.vim
@@ -51,3 +51,5 @@ function Test_exec_while_if()
         \ "8",
         \ "9x"], getline(1, 10))
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_exists.vim
+++ b/src/testdir/test_exists.vim
@@ -1,4 +1,5 @@
 " Tests for the exists() function
+
 func Test_exists()
   augroup myagroup
       autocmd! BufEnter       *.my     echo "myfile edited"
--- a/src/testdir/test_exists_autocmd.vim
+++ b/src/testdir/test_exists_autocmd.vim
@@ -24,3 +24,5 @@ function Test_AutoCommands()
   edit testfile2.test
   call assert_false(exists("#BufEnter#<buffer>"))
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_exit.vim
+++ b/src/testdir/test_exit.vim
@@ -81,3 +81,5 @@ func Test_exiting()
   endif
   call delete('Xtestout')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_expand_dllpath.vim
+++ b/src/testdir/test_expand_dllpath.vim
@@ -1,3 +1,5 @@
+" Test for expanding dllpath options
+
 func s:test_expand_dllpath(optname)
   let $TEST_EXPAND_DLLPATH = '/dllpath/lib' . substitute(a:optname, '\zedll$', '.', '')
   execute 'let dllpath_save = &' . a:optname
@@ -30,3 +32,5 @@ call s:generate_test_if_exists('pythondl
 call s:generate_test_if_exists('pythonthreedll')
 call s:generate_test_if_exists('rubydll')
 call s:generate_test_if_exists('tcldll')
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_expr_utf8.vim
+++ b/src/testdir/test_expr_utf8.vim
@@ -32,3 +32,5 @@ func Test_strcharpart()
   call assert_equal('̀', strcharpart('àxb', 1, 1))
   call assert_equal('x', strcharpart('àxb', 2, 1))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_feedkeys.vim
+++ b/src/testdir/test_feedkeys.vim
@@ -12,3 +12,5 @@ func Test_feedkeys_x_with_empty_string()
   call assert_equal('foo', getline('.'))
   quit!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_file_size.vim
+++ b/src/testdir/test_file_size.vim
@@ -7,15 +7,16 @@
 "
 " cksum is part of POSIX and so should be available on most Unixes.
 " If it isn't available then the test will be skipped.
+
+source check.vim
+
 func Test_File_Size()
-  if !executable('cksum')
-      return
-  endif
+  CheckExecutable cksum
 
   new
   set fileformat=unix undolevels=-1
   for i in range(1, 2000000, 100)
-      call append(i, range(i, i + 99))
+    call append(i, range(i, i + 99))
   endfor
 
   1delete
@@ -56,3 +57,5 @@ func Test_File_Read_Write()
   enew!
   call delete("Xtest")
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_fileformat.vim
+++ b/src/testdir/test_fileformat.vim
@@ -1,3 +1,4 @@
+" Test for 'fileformat'
 
 " Test behavior of fileformat after bwipeout of last buffer
 func Test_fileformat_after_bw()
--- a/src/testdir/test_filter_cmd.vim
+++ b/src/testdir/test_filter_cmd.vim
@@ -189,3 +189,5 @@ func Test_filter_display()
 
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_find_complete.vim
+++ b/src/testdir/test_find_complete.vim
@@ -161,3 +161,5 @@ func Test_find_complete()
   call delete('Xfind', 'rf')
   set path&
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_findfile.vim
+++ b/src/testdir/test_findfile.vim
@@ -227,3 +227,5 @@ func Test_find_cmd()
   call assert_fails('sfind', 'E471:')
   call assert_fails('tabfind', 'E471:')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_fixeol.vim
+++ b/src/testdir/test_fixeol.vim
@@ -1,4 +1,5 @@
 " Tests for 'fixeol' and 'eol'
+
 func Test_fixeol()
   " first write two test files – with and without trailing EOL
   " use Unix fileformat for consistency
@@ -46,3 +47,5 @@ func Test_fixeol()
   set ff& fixeol& eol&
   enew!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_flatten.vim
+++ b/src/testdir/test_flatten.vim
@@ -1,4 +1,5 @@
 " Test for flatting list.
+
 func Test_flatten()
   call assert_fails('call flatten(1)', 'E686:')
   call assert_fails('call flatten({})', 'E686:')
@@ -79,3 +80,5 @@ func Test_flatten()
   call assert_equal([1, 2, 1, 2], flatten(l:x, 2))
   call assert_equal([2, l:x], l:y)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_fnameescape.vim
+++ b/src/testdir/test_fnameescape.vim
@@ -1,5 +1,5 @@
+" Test if fnameescape is correct for special chars like !
 
-" Test if fnameescape is correct for special chars like !
 func Test_fnameescape()
   let fname = 'Xspa ce'
   let status = v:false
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -557,9 +557,7 @@ endfunc
 
 " test syntax folding
 func Test_fold_syntax()
-  if !has('syntax')
-    return
-  endif
+  CheckFeature syntax
 
   enew!
   set fdm=syntax fdl=0
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -1,4 +1,5 @@
 " Tests for various functions.
+
 source shared.vim
 source check.vim
 source term_util.vim
@@ -297,9 +298,7 @@ func Test_strptime()
 endfunc
 
 func Test_resolve_unix()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
 
   " Xlink1 -> Xlink2
   " Xlink2 -> Xlink3
@@ -349,9 +348,7 @@ func s:normalize_fname(fname)
 endfunc
 
 func Test_resolve_win32()
-  if !has('win32')
-    return
-  endif
+  CheckMSWindows
 
   " test for shortcut file
   if executable('cscript')
@@ -1243,13 +1240,13 @@ func Test_Executable()
     call assert_equal(1, executable(catcmd))
     call assert_equal('/' .. catcmd, catcmd->exepath())
     bwipe
+  else
+    throw 'Skipped: does not work on this platform'
   endif
 endfunc
 
 func Test_executable_longname()
-  if !has('win32')
-    return
-  endif
+  CheckMSWindows
 
   let fname = 'X' . repeat('あ', 200) . '.bat'
   call writefile([], fname)
@@ -1418,13 +1415,12 @@ func Test_inputlist()
 endfunc
 
 func Test_balloon_show()
-  if has('balloon_eval')
-    " This won't do anything but must not crash either.
-    call balloon_show('hi!')
-    if !has('gui_running')
-      call balloon_show(range(3))
-      call balloon_show([])
-    endif
+  CheckFeature balloon_eval
+  " This won't do anything but must not crash either.
+  call balloon_show('hi!')
+  if !has('gui_running')
+    call balloon_show(range(3))
+    call balloon_show([])
   endif
 endfunc
 
@@ -1654,9 +1650,7 @@ func Test_getchar()
 endfunc
 
 func Test_libcall_libcallnr()
-  if !has('libcall')
-    return
-  endif
+  CheckFeature libcall
 
   if has('win32')
     let libc = 'msvcrt.dll'
--- a/src/testdir/test_ga.vim
+++ b/src/testdir/test_ga.vim
@@ -1,4 +1,5 @@
 " Test ga normal command, and :ascii Ex command.
+
 func Do_ga(c)
   call setline(1, a:c)
   let l:a = execute("norm 1goga")
--- a/src/testdir/test_getcwd.vim
+++ b/src/testdir/test_getcwd.vim
@@ -1,3 +1,5 @@
+" Test for getcwd()
+
 func GetCwdInfo(win, tab)
   let tab_changed = 0
   let mod = ":t"
@@ -262,3 +264,5 @@ function Test_Tab_Local_Cwd()
   enew | only | tabonly
   new
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_getvar.vim
+++ b/src/testdir/test_getvar.vim
@@ -150,3 +150,5 @@ func Test_get_func()
 endfunc
 
 " get({partial}, {what} [, {default}]) - in test_partial.vim
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_glob2regpat.vim
+++ b/src/testdir/test_glob2regpat.vim
@@ -30,3 +30,5 @@ func Test_glob2regpat_valid()
     call assert_equal('^\\\(foo\|bar\\\)$', glob2regpat('\\{foo,bar\\}'))
   endif
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_global.vim
+++ b/src/testdir/test_global.vim
@@ -1,3 +1,5 @@
+" Test for :global and :vglobal
+
 source check.vim
 
 func Test_yank_put_clipboard()
--- a/src/testdir/test_gui.vim
+++ b/src/testdir/test_gui.vim
@@ -24,10 +24,9 @@ endfunc
 
 " As for non-GUI, a balloon_show() test was already added with patch 8.0.0401
 func Test_balloon_show()
-  if has('balloon_eval')
-    " This won't do anything but must not crash either.
-    call balloon_show('hi!')
-  endif
+  CheckFeature balloon_eval
+  " This won't do anything but must not crash either.
+  call balloon_show('hi!')
 endfunc
 
 func Test_colorscheme()
@@ -177,9 +176,7 @@ func Test_set_background()
 endfunc
 
 func Test_set_balloondelay()
-  if !exists('+balloondelay')
-    return
-  endif
+  CheckOption balloondelay
 
   let balloondelay_saved = &balloondelay
 
@@ -214,9 +211,7 @@ func Test_set_balloondelay()
 endfunc
 
 func Test_set_ballooneval()
-  if !exists('+ballooneval')
-    return
-  endif
+  CheckOption ballooneval
 
   let ballooneval_saved = &ballooneval
 
@@ -233,9 +228,7 @@ func Test_set_ballooneval()
 endfunc
 
 func Test_set_balloonexpr()
-  if !exists('+balloonexpr')
-    return
-  endif
+  CheckOption balloonexpr
 
   let balloonexpr_saved = &balloonexpr
 
@@ -764,17 +757,16 @@ endfunc
 
 func Test_encoding_conversion()
   " GTK supports conversion between 'encoding' and "utf-8"
-  if has('gui_gtk')
-    let encoding_saved = &encoding
-    set encoding=latin1
+  CheckFeature gui_gtk
+  let encoding_saved = &encoding
+  set encoding=latin1
 
-    " would be nice if we could take a screenshot
-    intro
-    " sets the window title
-    edit SomeFile
+  " would be nice if we could take a screenshot
+  intro
+  " sets the window title
+  edit SomeFile
 
-    let &encoding = encoding_saved
-  endif
+  let &encoding = encoding_saved
 endfunc
 
 func Test_shell_command()
--- a/src/testdir/test_gui_init.vim
+++ b/src/testdir/test_gui_init.vim
@@ -58,3 +58,5 @@ func Test_set_guioptions_for_p()
     throw skipped
   endif
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_highlight.vim
+++ b/src/testdir/test_highlight.vim
@@ -207,9 +207,7 @@ func Test_highlight_eol_with_cursorline_
 endfunc
 
 func Test_highlight_eol_with_cursorline_rightleft()
-  if !has('rightleft')
-    return
-  endif
+  CheckFeature rightleft
 
   let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
 
@@ -358,9 +356,7 @@ func Test_highlight_eol_with_cursorline_
 endfunc
 
 func Test_highlight_eol_with_cursorline_sign()
-  if !has('signs')
-    return
-  endif
+  CheckFeature signs
 
   let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
 
@@ -418,9 +414,7 @@ func Test_highlight_eol_with_cursorline_
 endfunc
 
 func Test_highlight_eol_with_cursorline_breakindent()
-  if !has('linebreak')
-    return
-  endif
+  CheckFeature linebreak
 
   let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
 
@@ -516,9 +510,7 @@ func Test_highlight_eol_on_diff()
 endfunc
 
 func Test_termguicolors()
-  if !exists('+termguicolors')
-    return
-  endif
+  CheckOption termguicolors
   if has('vtp') && !has('vcon') && !has('gui_running')
     " Win32: 'guicolors' doesn't work without virtual console.
     call assert_fails('set termguicolors', 'E954:')
--- a/src/testdir/test_hlsearch.vim
+++ b/src/testdir/test_hlsearch.vim
@@ -1,5 +1,7 @@
 " Test for v:hlsearch
 
+source check.vim
+
 func Test_hlsearch()
   new
   call setline(1, repeat(['aaa'], 10))
@@ -33,9 +35,7 @@ func Test_hlsearch()
 endfunc
 
 func Test_hlsearch_hangs()
-  if !has('reltime') || !has('float')
-    return
-  endif
+  CheckFunction reltimefloat
 
   " This pattern takes a long time to match, it should timeout.
   new
@@ -63,3 +63,5 @@ func Test_hlsearch_eol_highlight()
   set nohlsearch
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_iminsert.vim
+++ b/src/testdir/test_iminsert.vim
@@ -1,3 +1,5 @@
+" Test for 'iminsert'
+
 source view_util.vim
 source check.vim
 
@@ -89,8 +91,7 @@ func Test_iminsert_toggle()
     CheckFeature xim
   endif
   if has('gui_running') && !has('win32')
-    " this works only in Win32 GUI version (for some reason)
-    return
+    throw 'Skipped: works only in Win32 GUI version (for some reason)'
   endif
   new
   let save_imdisable = &imdisable
--- a/src/testdir/test_increment_dbcs.vim
+++ b/src/testdir/test_increment_dbcs.vim
@@ -1,4 +1,5 @@
 " Tests for using Ctrl-A/Ctrl-X using DBCS.
+
 set encoding=cp932
 scriptencoding cp932
 
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -1,3 +1,5 @@
+" Test for insert completion
+
 source screendump.vim
 source check.vim
 
--- a/src/testdir/test_interrupt.vim
+++ b/src/testdir/test_interrupt.vim
@@ -25,3 +25,5 @@ func Test_interrupt()
   call assert_equal(0, s:bufwritepost_called)
   call assert_equal(0, filereadable('Xfile'))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_job_fails.vim
+++ b/src/testdir/test_job_fails.vim
@@ -2,16 +2,15 @@
 " leaks under valgrind.  That is because when fork/exec fails memory is not
 " freed.  Since the process exits right away it's not a real leak.
 
-source shared.vim
+source check.vim
 
 func Test_job_start_fails()
-  if has('job')
-    let job = job_start('axdfxsdf')
-    if has('unix')
-      call WaitForAssert({-> assert_equal("dead", job_status(job))})
-    else
-      call WaitForAssert({-> assert_equal("fail", job_status(job))})
-    endif
+  CheckFeature job
+  let job = job_start('axdfxsdf')
+  if has('unix')
+    call WaitForAssert({-> assert_equal("dead", job_status(job))})
+  else
+    call WaitForAssert({-> assert_equal("fail", job_status(job))})
   endif
 endfunc
 
--- a/src/testdir/test_join.vim
+++ b/src/testdir/test_join.vim
@@ -444,3 +444,5 @@ func Test_join_lines()
   call assert_equal(['a', 'b c'], getline(1, '$'))
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_json.vim
+++ b/src/testdir/test_json.vim
@@ -323,3 +323,5 @@ func Test_json_encode_long()
   let json = json_encode([repeat('a', 3996)])
   call assert_equal(4000, len(json))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_jumplist.vim
+++ b/src/testdir/test_jumplist.vim
@@ -1,10 +1,10 @@
 " Tests for the jumplist functionality
 
+source check.vim
+
 " Tests for the getjumplist() function
 func Test_getjumplist()
-  if !has("jumplist")
-    return
-  endif
+  CheckFeature jumplist
 
   %bwipe
   clearjumps
@@ -64,3 +64,5 @@ func Test_getjumplist()
 
   call delete("Xtest")
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_jumps.vim
+++ b/src/testdir/test_jumps.vim
@@ -1,3 +1,5 @@
+" Test for '' mark in an empty buffer
+
 func Test_empty_buffer()
   new
   insert
@@ -9,3 +11,5 @@ d
   call assert_equal(1, line("''"))
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_lambda.vim
+++ b/src/testdir/test_lambda.vim
@@ -1,5 +1,7 @@
 " Test for lambda and closure
 
+source check.vim
+
 func Test_lambda_feature()
   call assert_equal(1, has('lambda'))
 endfunc
@@ -19,9 +21,7 @@ func Test_lambda_with_sort()
 endfunc
 
 func Test_lambda_with_timer()
-  if !has('timers')
-    return
-  endif
+  CheckFeature timers
 
   let s:n = 0
   let s:timer_id = 0
--- a/src/testdir/test_langmap.vim
+++ b/src/testdir/test_langmap.vim
@@ -52,3 +52,5 @@ func Test_langmap()
   set langmap&
   quit!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_largefile.vim
+++ b/src/testdir/test_largefile.vim
@@ -27,3 +27,5 @@ func Test_largefile()
   call assert_true(fsize == 4000000000)
   call delete(fname)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_lineending.vim
+++ b/src/testdir/test_lineending.vim
@@ -1,5 +1,6 @@
 " Tests for saving/loading a file with some lines ending in
 " CTRL-M, some not
+
 func Test_lineending()
   let l = ["this line ends in a\<CR>",
 	      \ "this one doesn't",
@@ -17,3 +18,5 @@ func Test_lineending()
   new | only
   call delete('Xfile1')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_listchars.vim
+++ b/src/testdir/test_listchars.vim
@@ -204,3 +204,5 @@ func Test_listchars_composing()
   enew!
   set listchars& ff&
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_listener.vim
+++ b/src/testdir/test_listener.vim
@@ -358,14 +358,16 @@ func Test_listener_cleared_newbuf()
 endfunc
 
 func Test_col_after_deletion_moved_cur()
-	func Listener(bufnr, start, end, added, changes)
+  func Listener(bufnr, start, end, added, changes)
     call assert_equal([#{lnum: 1, end: 2, added: 0, col: 2}], a:changes)
-	endfunc
-	new
-	call setline(1, ['foo'])
-	let lid = listener_add('Listener')
-	call feedkeys("lD", 'xt')
+  endfunc
+  new
+  call setline(1, ['foo'])
+  let lid = listener_add('Listener')
+  call feedkeys("lD", 'xt')
   call listener_flush()
-	bwipe!
-	delfunc Listener
+  bwipe!
+  delfunc Listener
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_listlbr.vim
+++ b/src/testdir/test_listlbr.vim
@@ -263,4 +263,6 @@ func Test_list_with_tab_and_skipping_fir
 \ ]
   call s:compare_lines(expect, lines)
   call s:close_windows()
-endfu
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_listlbr_utf8.vim
+++ b/src/testdir/test_listlbr_utf8.vim
@@ -269,4 +269,6 @@ func Test_chinese_char_on_wrap_column()
   let lines = s:screen_lines([1, 10], winwidth(0))
   call s:compare_lines(expect, lines)
   call s:close_windows()
-endfu
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_makeencoding.vim
+++ b/src/testdir/test_makeencoding.vim
@@ -102,3 +102,5 @@ func Test_make()
     lclose
   endfor
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_man.vim
+++ b/src/testdir/test_man.vim
@@ -131,3 +131,5 @@ func Test_keep_unnamed_register()
 
   %bw!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -92,9 +92,7 @@ func Test_map_ctrl_c_visual()
 endfunc
 
 func Test_map_langmap()
-  if !has('langmap')
-    return
-  endif
+  CheckFeature langmap
 
   " check langmap applies in normal mode
   set langmap=+- nolangremap
@@ -259,9 +257,7 @@ func Test_abbr_after_line_join()
 endfunc
 
 func Test_map_timeout()
-  if !has('timers')
-    return
-  endif
+  CheckFeature timers
   nnoremap aaaa :let got_aaaa = 1<CR>
   nnoremap bb :let got_bb = 1<CR>
   nmap b aaa
@@ -290,9 +286,8 @@ func Test_map_timeout()
 endfunc
 
 func Test_map_timeout_with_timer_interrupt()
-  if !has('job') || !has('timers')
-    return
-  endif
+  CheckFeature job
+  CheckFeature timers
 
   " Confirm the timer invoked in exit_cb of the job doesn't disturb mapped key
   " sequence.
--- a/src/testdir/test_marks.vim
+++ b/src/testdir/test_marks.vim
@@ -1,3 +1,4 @@
+" Test for marks
 
 " Test that a deleted mark is restored after delete-undo-redo-undo.
 func Test_Restore_DelMark()
--- a/src/testdir/test_matchadd_conceal.vim
+++ b/src/testdir/test_matchadd_conceal.vim
@@ -405,3 +405,5 @@ func Test_cursor_column_in_concealed_lin
   call StopVimInTerminal(buf)
   call delete('Xcurs-columns')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_matchadd_conceal_utf8.vim
+++ b/src/testdir/test_matchadd_conceal_utf8.vim
@@ -41,3 +41,5 @@ func Test_match_using_multibyte_conceal_
 
   quit!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_memory_usage.vim
+++ b/src/testdir/test_memory_usage.vim
@@ -162,3 +162,5 @@ func Test_memory_func_capture_lvars()
   call vim.stop()
   call delete(testfile)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_menu.vim
+++ b/src/testdir/test_menu.vim
@@ -62,9 +62,7 @@ func Test_buffer_menu_special_buffers()
 endfunc
 
 func Test_translate_menu()
-  if !has('multi_lang')
-    return
-  endif
+  CheckFeature multi_lang
   if !filereadable($VIMRUNTIME . '/lang/menu_de_de.latin1.vim')
     throw 'Skipped: translated menu not found'
   endif
--- a/src/testdir/test_messages.vim
+++ b/src/testdir/test_messages.vim
@@ -94,9 +94,8 @@ func Test_echoerr()
 endfunc
 
 func Test_mode_message_at_leaving_insert_by_ctrl_c()
-  if !has('terminal') || has('gui_running')
-    return
-  endif
+  CheckFeature terminal
+  CheckNotGui
 
   " Set custom statusline built by user-defined function.
   let testfile = 'Xtest.vim'
@@ -126,9 +125,8 @@ func Test_mode_message_at_leaving_insert
 endfunc
 
 func Test_mode_message_at_leaving_insert_with_esc_mapped()
-  if !has('terminal') || has('gui_running')
-    return
-  endif
+  CheckFeature terminal
+  CheckNotGui
 
   " Set custom statusline built by user-defined function.
   let testfile = 'Xtest.vim'
--- a/src/testdir/test_mksession.vim
+++ b/src/testdir/test_mksession.vim
@@ -150,10 +150,9 @@ func Test_mksession_large_winheight()
 endfunc
 
 func Test_mksession_rtp()
-  if has('win32')
-    " TODO: fix problem with backslashes
-    return
-  endif
+  " TODO: fix problem with backslashes on Win32
+  CheckNotMSWindows
+
   new
   let _rtp=&rtp
   " Make a real long (invalid) runtimepath value,
@@ -552,10 +551,9 @@ func Test_mksession_no_errmsg()
 endfunc
 
 func Test_mksession_quote_in_filename()
-  if !has('unix')
-    " only Unix can handle this weird filename
-    return
-  endif
+  " only Unix can handle this weird filename
+  CheckUnix
+
   let v:errmsg = ''
   %bwipe!
   split another
@@ -721,10 +719,9 @@ endfunc
 
 " Test for mksession with window position
 func Test_mksession_winpos()
-  if !has('gui_running')
-    " Only applicable in GUI Vim
-    return
-  endif
+  " Only applicable in GUI Vim
+  CheckGui
+
   set sessionoptions+=winpos
   mksession! Xtest_mks.out
   let found_winpos = v:false
--- a/src/testdir/test_modeline.vim
+++ b/src/testdir/test_modeline.vim
@@ -1,5 +1,7 @@
 " Tests for parsing the modeline.
 
+source check.vim
+
 func Test_modeline_invalid()
   " This was reading allocated memory in the past.
   call writefile(['vi:0', 'nothing'], 'Xmodeline')
@@ -62,9 +64,7 @@ func Test_modeline_syntax()
 endfunc
 
 func Test_modeline_keymap()
-  if !has('keymap')
-    return
-  endif
+  CheckFeature keymap
   call writefile(['vim: set keymap=greek :', 'nothing'], 'Xmodeline_keymap')
   let modeline = &modeline
   set modeline
@@ -170,9 +170,7 @@ func Test_modeline_colon()
 endfunc
 
 func s:modeline_fails(what, text, error)
-  if !exists('+' .. a:what)
-    return
-  endif
+  call CheckOption(a:what)
   let fname = "Xmodeline_fails_" . a:what
   call writefile(['vim: set ' . a:text . ' :', 'nothing'], fname)
   let modeline = &modeline
@@ -335,3 +333,5 @@ func Test_modeline_setoption_verbose()
   let &modeline = modeline
   call delete('Xmodeline')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_nested_function.vim
+++ b/src/testdir/test_nested_function.vim
@@ -1,5 +1,7 @@
-"Tests for nested functions
-"
+" Tests for nested functions
+
+source check.vim
+
 func NestedFunc()
   func! Func1()
     let g:text .= 'Func1 '
@@ -49,9 +51,8 @@ endfunc
 
 func Test_max_nesting()
   " TODO: why does this fail on Windows?  Runs out of stack perhaps?
-  if has('win32')
-    return
-  endif
+  CheckNotMSWindows
+
   let call_depth_here = 2
   let ex_depth_here = 5
   set mfd&
@@ -65,3 +66,5 @@ func Test_max_nesting()
 
   set mfd&
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_number.vim
+++ b/src/testdir/test_number.vim
@@ -297,3 +297,5 @@ func Test_relativenumber_colors()
   call StopVimInTerminal(buf)
   call delete('XTest_relnr')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -136,12 +136,11 @@ func Test_path_keep_commas()
 endfunc
 
 func Test_signcolumn()
-  if has('signs')
-    call assert_equal("auto", &signcolumn)
-    set signcolumn=yes
-    set signcolumn=no
-    call assert_fails('set signcolumn=nope')
-  endif
+  CheckFeature signs
+  call assert_equal("auto", &signcolumn)
+  set signcolumn=yes
+  set signcolumn=no
+  call assert_fails('set signcolumn=nope')
 endfunc
 
 func Test_filetype_valid()
@@ -162,9 +161,7 @@ func Test_filetype_valid()
 endfunc
 
 func Test_syntax_valid()
-  if !has('syntax')
-    return
-  endif
+  CheckFeature syntax
   set syn=valid_name
   call assert_equal("valid_name", &syntax)
   set syn=valid-name
@@ -182,9 +179,7 @@ func Test_syntax_valid()
 endfunc
 
 func Test_keymap_valid()
-  if !has('keymap')
-    return
-  endif
+  CheckFeature keymap
   call assert_fails(":set kmp=valid_name", "E544:")
   call assert_fails(":set kmp=valid_name", "valid_name")
   call assert_fails(":set kmp=valid-name", "E544:")
--- a/src/testdir/test_packadd.vim
+++ b/src/testdir/test_packadd.vim
@@ -1,5 +1,6 @@
 " Tests for 'packpath' and :packadd
 
+source check.vim
 
 func SetUp()
   let s:topdir = getcwd() . '/Xdir'
@@ -115,9 +116,7 @@ func Test_packadd_noload()
 endfunc
 
 func Test_packadd_symlink_dir()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
   let top2_dir = s:topdir . '/Xdir2'
   let real_dir = s:topdir . '/Xsym'
   call mkdir(real_dir, 'p')
@@ -150,9 +149,7 @@ func Test_packadd_symlink_dir()
 endfunc
 
 func Test_packadd_symlink_dir2()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
   let top2_dir = s:topdir . '/Xdir2'
   let real_dir = s:topdir . '/Xsym/pack'
   call mkdir(top2_dir, 'p')
--- a/src/testdir/test_partial.vim
+++ b/src/testdir/test_partial.vim
@@ -1,5 +1,7 @@
 " Test binding arguments to a Funcref.
  
+source check.vim
+
 func MyFunc(arg1, arg2, arg3)
   return a:arg1 . '/' . a:arg2 . '/' . a:arg3
 endfunc
@@ -235,17 +237,16 @@ func Test_redefine_dict_func()
 endfunc
 
 func Test_bind_in_python()
-  if has('python')
-    let g:d = {}
-    function g:d.test2()
-    endfunction
-    python import vim
-    try
-      call assert_equal(pyeval('vim.bindeval("g:d.test2")'), g:d.test2)
-    catch
-      call assert_true(v:false, v:exception)
-    endtry
-  endif
+  CheckFeature python
+  let g:d = {}
+  function g:d.test2()
+  endfunction
+  python import vim
+  try
+    call assert_equal(pyeval('vim.bindeval("g:d.test2")'), g:d.test2)
+  catch
+    call assert_true(v:false, v:exception)
+  endtry
 endfunc
 
 " This caused double free on exit if EXITFREE is defined.
@@ -270,23 +271,21 @@ func Ignored3(job1, job2, status)
 endfunc
 
 func Test_cycle_partial_job()
-  if has('job')
-    let job = job_start('echo')
-    call job_setoptions(job, {'exit_cb': function('Ignored3', [job])})
-    unlet job
-  endif
+  CheckFeature job
+  let job = job_start('echo')
+  call job_setoptions(job, {'exit_cb': function('Ignored3', [job])})
+  unlet job
 endfunc
 
 func Ignored2(job, status)
 endfunc
 
 func Test_ref_job_partial_dict()
-  if has('job')
-    let g:ref_job = job_start('echo')
-    let d = {'a': 'b'}
-    call job_setoptions(g:ref_job, {'exit_cb': function('Ignored2', [], d)})
-    call test_garbagecollect_now()
-  endif
+  CheckFeature job
+  let g:ref_job = job_start('echo')
+  let d = {'a': 'b'}
+  call job_setoptions(g:ref_job, {'exit_cb': function('Ignored2', [], d)})
+  call test_garbagecollect_now()
 endfunc
 
 func Test_auto_partial_rebind()
--- a/src/testdir/test_paste.vim
+++ b/src/testdir/test_paste.vim
@@ -135,9 +135,7 @@ func CheckCopyPaste()
 endfunc
 
 func Test_xrestore()
-  if !has('xterm_clipboard')
-    return
-  endif
+  CheckFeature xterm_clipboard
   let display = $DISPLAY
   new
   call CheckCopyPaste()
--- a/src/testdir/test_plus_arg_edit.vim
+++ b/src/testdir/test_plus_arg_edit.vim
@@ -1,4 +1,5 @@
 " Tests for complicated + argument to :edit command
+
 function Test_edit()
   call writefile(["foo|bar"], "Xfile1")
   call writefile(["foo/bar"], "Xfile2")
--- a/src/testdir/test_preview.vim
+++ b/src/testdir/test_preview.vim
@@ -1,4 +1,5 @@
 " Tests for the preview window
+
 source check.vim
 CheckFeature quickfix
 
--- a/src/testdir/test_profile.vim
+++ b/src/testdir/test_profile.vim
@@ -551,3 +551,5 @@ func Test_profile_typed_func()
   call delete('XprofileTypedFunc')
   call delete('XtestProfile')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_prompt_buffer.vim
+++ b/src/testdir/test_prompt_buffer.vim
@@ -9,14 +9,10 @@ source screendump.vim
 func CanTestPromptBuffer()
   " We need to use a terminal window to be able to feed keys without leaving
   " Insert mode.
-  if !has('terminal')
-    return 0
-  endif
-  if has('win32')
-    " TODO: make the tests work on MS-Windows
-    return 0
-  endif
-  return 1
+  CheckFeature terminal
+
+  " TODO: make the tests work on MS-Windows
+  CheckNotMSWindows
 endfunc
 
 func WriteScript(name)
@@ -54,9 +50,7 @@ func WriteScript(name)
 endfunc
 
 func Test_prompt_basic()
-  if !CanTestPromptBuffer()
-    return
-  endif
+  call CanTestPromptBuffer()
   let scriptName = 'XpromptscriptBasic'
   call WriteScript(scriptName)
 
@@ -76,9 +70,7 @@ func Test_prompt_basic()
 endfunc
 
 func Test_prompt_editing()
-  if !CanTestPromptBuffer()
-    return
-  endif
+  call CanTestPromptBuffer()
   let scriptName = 'XpromptscriptEditing'
   call WriteScript(scriptName)
 
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -808,101 +808,101 @@ func ReadTestProtocol(name)
 endfunc
 
 func Test_locationlist()
-    enew
-
-    augroup testgroup
-      au!
-      autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
-    augroup END
-
-    let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
-
-    let qflist = []
-    for word in words
-      call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
-      " NOTE: problem 1:
-      " intentionally not setting 'lnum' so that the quickfix entries are not
-      " valid
-      eval qflist->setloclist(0, ' ')
-    endfor
-
-    " Test A
-    lrewind
-    enew
-    lopen
-    4lnext
-    vert split
-    wincmd L
-    lopen
-    wincmd p
-    lnext
-    let fileName = expand("%")
-    wincmd p
-    let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
-    let fileName = substitute(fileName, '\\', '/', 'g')
-    let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
-    call assert_equal("test://bar.txt", fileName)
-    call assert_equal("test://bar.txt", locationListFileName)
-
-    wincmd n | only
-
-    " Test B:
-    lrewind
-    lopen
-    2
-    exe "normal \<CR>"
-    wincmd p
-    3
-    exe "normal \<CR>"
-    wincmd p
-    4
-    exe "normal \<CR>"
-    call assert_equal(2, winnr('$'))
-    wincmd n | only
-
-    " Test C:
-    lrewind
-    lopen
-    " Let's move the location list window to the top to check whether it (the
-    " first window found) will be reused when we try to open new windows:
-    wincmd K
-    2
-    exe "normal \<CR>"
-    wincmd p
-    3
-    exe "normal \<CR>"
-    wincmd p
-    4
-    exe "normal \<CR>"
-    1wincmd w
-    call assert_equal('quickfix', &buftype)
-    2wincmd w
-    let bufferName = expand("%")
-    let bufferName = substitute(bufferName, '\\', '/', 'g')
-    call assert_equal('test://quux.txt', bufferName)
-
-    wincmd n | only
-
-    augroup! testgroup
+  enew
+
+  augroup testgroup
+    au!
+    autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
+  augroup END
+
+  let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
+
+  let qflist = []
+  for word in words
+    call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
+    " NOTE: problem 1:
+    " intentionally not setting 'lnum' so that the quickfix entries are not
+    " valid
+    eval qflist->setloclist(0, ' ')
+  endfor
+
+  " Test A
+  lrewind
+  enew
+  lopen
+  4lnext
+  vert split
+  wincmd L
+  lopen
+  wincmd p
+  lnext
+  let fileName = expand("%")
+  wincmd p
+  let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
+  let fileName = substitute(fileName, '\\', '/', 'g')
+  let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
+  call assert_equal("test://bar.txt", fileName)
+  call assert_equal("test://bar.txt", locationListFileName)
+
+  wincmd n | only
+
+  " Test B:
+  lrewind
+  lopen
+  2
+  exe "normal \<CR>"
+  wincmd p
+  3
+  exe "normal \<CR>"
+  wincmd p
+  4
+  exe "normal \<CR>"
+  call assert_equal(2, winnr('$'))
+  wincmd n | only
+
+  " Test C:
+  lrewind
+  lopen
+  " Let's move the location list window to the top to check whether it (the
+  " first window found) will be reused when we try to open new windows:
+  wincmd K
+  2
+  exe "normal \<CR>"
+  wincmd p
+  3
+  exe "normal \<CR>"
+  wincmd p
+  4
+  exe "normal \<CR>"
+  1wincmd w
+  call assert_equal('quickfix', &buftype)
+  2wincmd w
+  let bufferName = expand("%")
+  let bufferName = substitute(bufferName, '\\', '/', 'g')
+  call assert_equal('test://quux.txt', bufferName)
+
+  wincmd n | only
+
+  augroup! testgroup
 endfunc
 
 func Test_locationlist_curwin_was_closed()
-    augroup testgroup
-      au!
-      autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
-    augroup END
-
-    func! R(n)
-      quit
-    endfunc
-
-    new
-    let q = []
-    call add(q, {'filename': 'test_curwin.txt' })
-    call setloclist(0, q)
-    call assert_fails('lrewind', 'E924:')
-
-    augroup! testgroup
+  augroup testgroup
+    au!
+    autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
+  augroup END
+
+  func! R(n)
+    quit
+  endfunc
+
+  new
+  let q = []
+  call add(q, {'filename': 'test_curwin.txt' })
+  call setloclist(0, q)
+  call assert_fails('lrewind', 'E924:')
+
+  augroup! testgroup
 endfunc
 
 func Test_locationlist_cross_tab_jump()
@@ -923,52 +923,50 @@ endfunc
 
 " More tests for 'errorformat'
 func Test_efm1()
-    if !has('unix')
-	" The 'errorformat' setting is different on non-Unix systems.
-	" This test works only on Unix-like systems.
-	return
-    endif
-
-    let l =<< trim [DATA]
-      "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
-      "Xtestfile", line 6 col 19; this is an error
-      gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c
-      Xtestfile:9: parse error before `asd'
-      make: *** [vim] Error 1
-      in file "Xtestfile" linenr 10: there is an error
-  
-      2 returned
-      "Xtestfile", line 11 col 1; this is an error
-      "Xtestfile", line 12 col 2; this is another error
-      "Xtestfile", line 14:10; this is an error in column 10
-      =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
-      "Xtestfile", linenr 16: yet another problem
-      Error in "Xtestfile" at line 17:
-      x should be a dot
-      	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17
-                  ^
-      Error in "Xtestfile" at line 18:
-      x should be a dot
-      	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18
-      .............^
-      Error in "Xtestfile" at line 19:
-      x should be a dot
-      	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19
-      --------------^
-      Error in "Xtestfile" at line 20:
-      x should be a dot
-      	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20
-      	       ^
-  
-      Does anyone know what is the problem and how to correction it?
-      "Xtestfile", line 21 col 9: What is the title of the quickfix window?
-      "Xtestfile", line 22 col 9: What is the title of the quickfix window?
-    [DATA]
-
-    call writefile(l, 'Xerrorfile1')
-    call writefile(l[:-2], 'Xerrorfile2')
-
-    let m =<< [DATA]
+  " The 'errorformat' setting is different on non-Unix systems.
+  " This test works only on Unix-like systems.
+  CheckUnix
+
+  let l =<< trim [DATA]
+    "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
+    "Xtestfile", line 6 col 19; this is an error
+    gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c
+    Xtestfile:9: parse error before `asd'
+    make: *** [vim] Error 1
+    in file "Xtestfile" linenr 10: there is an error
+
+    2 returned
+    "Xtestfile", line 11 col 1; this is an error
+    "Xtestfile", line 12 col 2; this is another error
+    "Xtestfile", line 14:10; this is an error in column 10
+    =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
+    "Xtestfile", linenr 16: yet another problem
+    Error in "Xtestfile" at line 17:
+    x should be a dot
+    	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17
+                ^
+    Error in "Xtestfile" at line 18:
+    x should be a dot
+    	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18
+    .............^
+    Error in "Xtestfile" at line 19:
+    x should be a dot
+    	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19
+    --------------^
+    Error in "Xtestfile" at line 20:
+    x should be a dot
+    	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20
+    	       ^
+
+    Does anyone know what is the problem and how to correction it?
+    "Xtestfile", line 21 col 9: What is the title of the quickfix window?
+    "Xtestfile", line 22 col 9: What is the title of the quickfix window?
+  [DATA]
+
+  call writefile(l, 'Xerrorfile1')
+  call writefile(l[:-2], 'Xerrorfile2')
+
+  let m =<< [DATA]
 	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2
 	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3
 	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4
@@ -991,55 +989,55 @@ func Test_efm1()
 	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21
 	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22
 [DATA]
-    call writefile(m, 'Xtestfile')
-
-    let save_efm = &efm
-    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
-    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
-
-    exe 'cf Xerrorfile2'
-    clast
-    copen
-    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
-    wincmd p
-
-    exe 'cf Xerrorfile1'
-    call assert_equal([4, 12], [line('.'), col('.')])
-    cn
-    call assert_equal([6, 19], [line('.'), col('.')])
-    cn
-    call assert_equal([9, 2], [line('.'), col('.')])
-    cn
-    call assert_equal([10, 2], [line('.'), col('.')])
-    cn
-    call assert_equal([11, 1], [line('.'), col('.')])
-    cn
-    call assert_equal([12, 2], [line('.'), col('.')])
-    cn
-    call assert_equal([14, 10], [line('.'), col('.')])
-    cn
-    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
-    cn
-    call assert_equal([16, 2], [line('.'), col('.')])
-    cn
-    call assert_equal([17, 6], [line('.'), col('.')])
-    cn
-    call assert_equal([18, 7], [line('.'), col('.')])
-    cn
-    call assert_equal([19, 8], [line('.'), col('.')])
-    cn
-    call assert_equal([20, 9], [line('.'), col('.')])
-    clast
-    cprev
-    cprev
-    wincmd w
-    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
-    wincmd p
-
-    let &efm = save_efm
-    call delete('Xerrorfile1')
-    call delete('Xerrorfile2')
-    call delete('Xtestfile')
+  call writefile(m, 'Xtestfile')
+
+  let save_efm = &efm
+  set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
+  set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
+
+  exe 'cf Xerrorfile2'
+  clast
+  copen
+  call assert_equal(':cf Xerrorfile2', w:quickfix_title)
+  wincmd p
+
+  exe 'cf Xerrorfile1'
+  call assert_equal([4, 12], [line('.'), col('.')])
+  cn
+  call assert_equal([6, 19], [line('.'), col('.')])
+  cn
+  call assert_equal([9, 2], [line('.'), col('.')])
+  cn
+  call assert_equal([10, 2], [line('.'), col('.')])
+  cn
+  call assert_equal([11, 1], [line('.'), col('.')])
+  cn
+  call assert_equal([12, 2], [line('.'), col('.')])
+  cn
+  call assert_equal([14, 10], [line('.'), col('.')])
+  cn
+  call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
+  cn
+  call assert_equal([16, 2], [line('.'), col('.')])
+  cn
+  call assert_equal([17, 6], [line('.'), col('.')])
+  cn
+  call assert_equal([18, 7], [line('.'), col('.')])
+  cn
+  call assert_equal([19, 8], [line('.'), col('.')])
+  cn
+  call assert_equal([20, 9], [line('.'), col('.')])
+  clast
+  cprev
+  cprev
+  wincmd w
+  call assert_equal(':cf Xerrorfile1', w:quickfix_title)
+  wincmd p
+
+  let &efm = save_efm
+  call delete('Xerrorfile1')
+  call delete('Xerrorfile2')
+  call delete('Xtestfile')
 endfunc
 
 " Test for quickfix directory stack support
@@ -1981,10 +1979,8 @@ func s:test_xgrep(cchar)
 endfunc
 
 func Test_grep()
-  if !has('unix')
-    " The grepprg may not be set on non-Unix systems
-    return
-  endif
+  " The grepprg may not be set on non-Unix systems
+  CheckUnix
 
   call s:test_xgrep('c')
   call s:test_xgrep('l')
@@ -2122,252 +2118,252 @@ endfunc
 
 " Quickfix/Location list set/get properties tests
 func Xproperty_tests(cchar)
-    call s:setup_commands(a:cchar)
-
-    " Error cases
-    call assert_fails('call g:Xgetlist(99)', 'E715:')
-    call assert_fails('call g:Xsetlist(99)', 'E714:')
-    call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
-
-    " Set and get the title
-    call g:Xsetlist([])
-    Xopen
-    wincmd p
-    call g:Xsetlist([{'filename':'foo', 'lnum':27}])
-    let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
-    call assert_equal(0, s)
-    let d = g:Xgetlist({"title":1})
-    call assert_equal('Sample', d.title)
-    " Try setting title to a non-string value
-    call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
-    call assert_equal('Sample', g:Xgetlist({"title":1}).title)
-
+  call s:setup_commands(a:cchar)
+
+  " Error cases
+  call assert_fails('call g:Xgetlist(99)', 'E715:')
+  call assert_fails('call g:Xsetlist(99)', 'E714:')
+  call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
+
+  " Set and get the title
+  call g:Xsetlist([])
+  Xopen
+  wincmd p
+  call g:Xsetlist([{'filename':'foo', 'lnum':27}])
+  let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
+  call assert_equal(0, s)
+  let d = g:Xgetlist({"title":1})
+  call assert_equal('Sample', d.title)
+  " Try setting title to a non-string value
+  call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
+  call assert_equal('Sample', g:Xgetlist({"title":1}).title)
+
+  Xopen
+  call assert_equal('Sample', w:quickfix_title)
+  Xclose
+
+  " Tests for action argument
+  silent! Xolder 999
+  let qfnr = g:Xgetlist({'all':1}).nr
+  call g:Xsetlist([], 'r', {'title' : 'N1'})
+  call assert_equal('N1', g:Xgetlist({'all':1}).title)
+  call g:Xsetlist([], ' ', {'title' : 'N2'})
+  call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
+
+  let res = g:Xgetlist({'nr': 0})
+  call assert_equal(qfnr + 1, res.nr)
+  call assert_equal(['nr'], keys(res))
+
+  call g:Xsetlist([], ' ', {'title' : 'N3'})
+  call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
+
+  " Changing the title of an earlier quickfix list
+  call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
+  call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
+
+  " Changing the title of an invalid quickfix list
+  call assert_equal(-1, g:Xsetlist([], ' ',
+        \ {'title' : 'SomeTitle', 'nr' : 99}))
+  call assert_equal(-1, g:Xsetlist([], ' ',
+        \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
+
+  if a:cchar == 'c'
+    copen
+    call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
+    cclose
+  endif
+
+  " Invalid arguments
+  call assert_fails('call g:Xgetlist([])', 'E715')
+  call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
+  let s = g:Xsetlist([], 'a', {'abc':1})
+  call assert_equal(-1, s)
+
+  call assert_equal({}, g:Xgetlist({'abc':1}))
+  call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
+  call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
+
+  if a:cchar == 'l'
+    call assert_equal({}, getloclist(99, {'title': 1}))
+  endif
+
+  " Context related tests
+  let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
+  call assert_equal(0, s)
+  call test_garbagecollect_now()
+  let d = g:Xgetlist({'context':1})
+  call assert_equal([1,2,3], d.context)
+  call g:Xsetlist([], 'a', {'context':{'color':'green'}})
+  let d = g:Xgetlist({'context':1})
+  call assert_equal({'color':'green'}, d.context)
+  call g:Xsetlist([], 'a', {'context':"Context info"})
+  let d = g:Xgetlist({'context':1})
+  call assert_equal("Context info", d.context)
+  call g:Xsetlist([], 'a', {'context':246})
+  let d = g:Xgetlist({'context':1})
+  call assert_equal(246, d.context)
+  " set other Vim data types as context
+  call g:Xsetlist([], 'a', {'context' : test_null_blob()})
+  if has('channel')
+    call g:Xsetlist([], 'a', {'context' : test_null_channel()})
+  endif
+  if has('job')
+    call g:Xsetlist([], 'a', {'context' : test_null_job()})
+  endif
+  call g:Xsetlist([], 'a', {'context' : test_null_function()})
+  call g:Xsetlist([], 'a', {'context' : test_null_partial()})
+  call g:Xsetlist([], 'a', {'context' : ''})
+  call test_garbagecollect_now()
+  if a:cchar == 'l'
+    " Test for copying context across two different location lists
+    new | only
+    let w1_id = win_getid()
+    let l = [1]
+    call setloclist(0, [], 'a', {'context':l})
+    new
+    let w2_id = win_getid()
+    call add(l, 2)
+    call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
+    call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
+    unlet! l
+    call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
+    only
+    call setloclist(0, [], 'f')
+    call assert_equal('', getloclist(0, {'context':1}).context)
+  endif
+
+  " Test for changing the context of previous quickfix lists
+  call g:Xsetlist([], 'f')
+  Xexpr "One"
+  Xexpr "Two"
+  Xexpr "Three"
+  call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
+  call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
+  " Also, check for setting the context using quickfix list number zero.
+  call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
+  call test_garbagecollect_now()
+  let l = g:Xgetlist({'nr' : 1, 'context' : 1})
+  call assert_equal([1], l.context)
+  let l = g:Xgetlist({'nr' : 2, 'context' : 1})
+  call assert_equal([2], l.context)
+  let l = g:Xgetlist({'nr' : 3, 'context' : 1})
+  call assert_equal([3], l.context)
+
+  " Test for changing the context through reference and for garbage
+  " collection of quickfix context
+  let l = ["red"]
+  call g:Xsetlist([], ' ', {'context' : l})
+  call add(l, "blue")
+  let x = g:Xgetlist({'context' : 1})
+  call add(x.context, "green")
+  call assert_equal(["red", "blue", "green"], l)
+  call assert_equal(["red", "blue", "green"], x.context)
+  unlet l
+  call test_garbagecollect_now()
+  let m = g:Xgetlist({'context' : 1})
+  call assert_equal(["red", "blue", "green"], m.context)
+
+  " Test for setting/getting items
+  Xexpr ""
+  let qfprev = g:Xgetlist({'nr':0})
+  let s = g:Xsetlist([], ' ', {'title':'Green',
+        \ 'items' : [{'filename':'F1', 'lnum':10}]})
+  call assert_equal(0, s)
+  let qfcur = g:Xgetlist({'nr':0})
+  call assert_true(qfcur.nr == qfprev.nr + 1)
+  let l = g:Xgetlist({'items':1})
+  call assert_equal('F1', bufname(l.items[0].bufnr))
+  call assert_equal(10, l.items[0].lnum)
+  call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
+        \  {'filename':'F2', 'lnum':30}]})
+  let l = g:Xgetlist({'items':1})
+  call assert_equal('F2', bufname(l.items[2].bufnr))
+  call assert_equal(30, l.items[2].lnum)
+  call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
+  let l = g:Xgetlist({'items':1})
+  call assert_equal('F3', bufname(l.items[0].bufnr))
+  call assert_equal(40, l.items[0].lnum)
+  call g:Xsetlist([], 'r', {'items' : []})
+  let l = g:Xgetlist({'items':1})
+  call assert_equal(0, len(l.items))
+
+  call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
+  call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
+  call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
+  call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
+
+  " Test for getting id of window associated with a location list window
+  if a:cchar == 'l'
+    only
+    call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
+    let wid = win_getid()
     Xopen
-    call assert_equal('Sample', w:quickfix_title)
-    Xclose
-
-    " Tests for action argument
-    silent! Xolder 999
-    let qfnr = g:Xgetlist({'all':1}).nr
-    call g:Xsetlist([], 'r', {'title' : 'N1'})
-    call assert_equal('N1', g:Xgetlist({'all':1}).title)
-    call g:Xsetlist([], ' ', {'title' : 'N2'})
-    call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
-
-    let res = g:Xgetlist({'nr': 0})
-    call assert_equal(qfnr + 1, res.nr)
-    call assert_equal(['nr'], keys(res))
-
-    call g:Xsetlist([], ' ', {'title' : 'N3'})
-    call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
-
-    " Changing the title of an earlier quickfix list
-    call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
-    call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
-
-    " Changing the title of an invalid quickfix list
-    call assert_equal(-1, g:Xsetlist([], ' ',
-		\ {'title' : 'SomeTitle', 'nr' : 99}))
-    call assert_equal(-1, g:Xsetlist([], ' ',
-		\ {'title' : 'SomeTitle', 'nr' : 'abc'}))
-
-    if a:cchar == 'c'
-	copen
-	call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
-	cclose
-    endif
-
-    " Invalid arguments
-    call assert_fails('call g:Xgetlist([])', 'E715')
-    call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
-    let s = g:Xsetlist([], 'a', {'abc':1})
-    call assert_equal(-1, s)
-
-    call assert_equal({}, g:Xgetlist({'abc':1}))
-    call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
-    call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
-
-    if a:cchar == 'l'
-	call assert_equal({}, getloclist(99, {'title': 1}))
-    endif
-
-    " Context related tests
-    let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
-    call assert_equal(0, s)
-    call test_garbagecollect_now()
-    let d = g:Xgetlist({'context':1})
-    call assert_equal([1,2,3], d.context)
-    call g:Xsetlist([], 'a', {'context':{'color':'green'}})
-    let d = g:Xgetlist({'context':1})
-    call assert_equal({'color':'green'}, d.context)
-    call g:Xsetlist([], 'a', {'context':"Context info"})
-    let d = g:Xgetlist({'context':1})
-    call assert_equal("Context info", d.context)
-    call g:Xsetlist([], 'a', {'context':246})
-    let d = g:Xgetlist({'context':1})
-    call assert_equal(246, d.context)
-    " set other Vim data types as context
-    call g:Xsetlist([], 'a', {'context' : test_null_blob()})
-    if has('channel')
-      call g:Xsetlist([], 'a', {'context' : test_null_channel()})
-    endif
-    if has('job')
-      call g:Xsetlist([], 'a', {'context' : test_null_job()})
-    endif
-    call g:Xsetlist([], 'a', {'context' : test_null_function()})
-    call g:Xsetlist([], 'a', {'context' : test_null_partial()})
-    call g:Xsetlist([], 'a', {'context' : ''})
-    call test_garbagecollect_now()
-    if a:cchar == 'l'
-	" Test for copying context across two different location lists
-	new | only
-	let w1_id = win_getid()
-	let l = [1]
-	call setloclist(0, [], 'a', {'context':l})
-	new
-	let w2_id = win_getid()
-	call add(l, 2)
-	call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
-	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
-	unlet! l
-	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
-	only
-	call setloclist(0, [], 'f')
-	call assert_equal('', getloclist(0, {'context':1}).context)
-    endif
-
-    " Test for changing the context of previous quickfix lists
-    call g:Xsetlist([], 'f')
-    Xexpr "One"
-    Xexpr "Two"
-    Xexpr "Three"
-    call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
-    call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
-    " Also, check for setting the context using quickfix list number zero.
-    call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
-    call test_garbagecollect_now()
-    let l = g:Xgetlist({'nr' : 1, 'context' : 1})
-    call assert_equal([1], l.context)
-    let l = g:Xgetlist({'nr' : 2, 'context' : 1})
-    call assert_equal([2], l.context)
-    let l = g:Xgetlist({'nr' : 3, 'context' : 1})
-    call assert_equal([3], l.context)
-
-    " Test for changing the context through reference and for garbage
-    " collection of quickfix context
-    let l = ["red"]
-    call g:Xsetlist([], ' ', {'context' : l})
-    call add(l, "blue")
-    let x = g:Xgetlist({'context' : 1})
-    call add(x.context, "green")
-    call assert_equal(["red", "blue", "green"], l)
-    call assert_equal(["red", "blue", "green"], x.context)
-    unlet l
-    call test_garbagecollect_now()
-    let m = g:Xgetlist({'context' : 1})
-    call assert_equal(["red", "blue", "green"], m.context)
-
-    " Test for setting/getting items
-    Xexpr ""
-    let qfprev = g:Xgetlist({'nr':0})
-    let s = g:Xsetlist([], ' ', {'title':'Green',
-		\ 'items' : [{'filename':'F1', 'lnum':10}]})
-    call assert_equal(0, s)
-    let qfcur = g:Xgetlist({'nr':0})
-    call assert_true(qfcur.nr == qfprev.nr + 1)
-    let l = g:Xgetlist({'items':1})
-    call assert_equal('F1', bufname(l.items[0].bufnr))
-    call assert_equal(10, l.items[0].lnum)
-    call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
-		\  {'filename':'F2', 'lnum':30}]})
-    let l = g:Xgetlist({'items':1})
-    call assert_equal('F2', bufname(l.items[2].bufnr))
-    call assert_equal(30, l.items[2].lnum)
-    call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
-    let l = g:Xgetlist({'items':1})
-    call assert_equal('F3', bufname(l.items[0].bufnr))
-    call assert_equal(40, l.items[0].lnum)
-    call g:Xsetlist([], 'r', {'items' : []})
-    let l = g:Xgetlist({'items':1})
-    call assert_equal(0, len(l.items))
-
-    call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
-    call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
-    call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
-    call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
-
-    " Test for getting id of window associated with a location list window
-    if a:cchar == 'l'
-      only
-      call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
-      let wid = win_getid()
-      Xopen
-      call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
-      wincmd w
-      call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
-      only
-    endif
-
-    " The following used to crash Vim with address sanitizer
-    call g:Xsetlist([], 'f')
-    call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
-    call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
-
-    " Try setting the items using a string
-    call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
-
-    " Save and restore the quickfix stack
-    call g:Xsetlist([], 'f')
-    call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
-    Xexpr "File1:10:Line1"
-    Xexpr "File2:20:Line2"
-    Xexpr "File3:30:Line3"
-    let last_qf = g:Xgetlist({'nr':'$'}).nr
-    call assert_equal(3, last_qf)
-    let qstack = []
-    for i in range(1, last_qf)
-	let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
-    endfor
-    call g:Xsetlist([], 'f')
-    for i in range(len(qstack))
-	call g:Xsetlist([], ' ', qstack[i])
-    endfor
-    call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
-    call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
-    call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
-    call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
-    call g:Xsetlist([], 'f')
-
-    " Swap two quickfix lists
-    Xexpr "File1:10:Line10"
-    Xexpr "File2:20:Line20"
-    Xexpr "File3:30:Line30"
-    call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
-    call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
-    let l1=g:Xgetlist({'nr':1,'all':1})
-    let l2=g:Xgetlist({'nr':2,'all':1})
-    let save_id = l1.id
-    let l1.id=l2.id
-    let l2.id=save_id
-    call g:Xsetlist([], 'r', l1)
-    call g:Xsetlist([], 'r', l2)
-    let newl1=g:Xgetlist({'nr':1,'all':1})
-    let newl2=g:Xgetlist({'nr':2,'all':1})
-    call assert_equal('Fruits', newl1.title)
-    call assert_equal(['Fruits'], newl1.context)
-    call assert_equal('Line20', newl1.items[0].text)
-    call assert_equal('Colors', newl2.title)
-    call assert_equal(['Colors'], newl2.context)
-    call assert_equal('Line10', newl2.items[0].text)
-    call g:Xsetlist([], 'f')
-
-    " Cannot specify both a non-empty list argument and a dict argument
-    call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
+    call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
+    wincmd w
+    call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
+    only
+  endif
+
+  " The following used to crash Vim with address sanitizer
+  call g:Xsetlist([], 'f')
+  call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
+  call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
+
+  " Try setting the items using a string
+  call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
+
+  " Save and restore the quickfix stack
+  call g:Xsetlist([], 'f')
+  call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
+  Xexpr "File1:10:Line1"
+  Xexpr "File2:20:Line2"
+  Xexpr "File3:30:Line3"
+  let last_qf = g:Xgetlist({'nr':'$'}).nr
+  call assert_equal(3, last_qf)
+  let qstack = []
+  for i in range(1, last_qf)
+    let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
+  endfor
+  call g:Xsetlist([], 'f')
+  for i in range(len(qstack))
+    call g:Xsetlist([], ' ', qstack[i])
+  endfor
+  call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
+  call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
+  call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
+  call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
+  call g:Xsetlist([], 'f')
+
+  " Swap two quickfix lists
+  Xexpr "File1:10:Line10"
+  Xexpr "File2:20:Line20"
+  Xexpr "File3:30:Line30"
+  call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
+  call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
+  let l1=g:Xgetlist({'nr':1,'all':1})
+  let l2=g:Xgetlist({'nr':2,'all':1})
+  let save_id = l1.id
+  let l1.id=l2.id
+  let l2.id=save_id
+  call g:Xsetlist([], 'r', l1)
+  call g:Xsetlist([], 'r', l2)
+  let newl1=g:Xgetlist({'nr':1,'all':1})
+  let newl2=g:Xgetlist({'nr':2,'all':1})
+  call assert_equal('Fruits', newl1.title)
+  call assert_equal(['Fruits'], newl1.context)
+  call assert_equal('Line20', newl1.items[0].text)
+  call assert_equal('Colors', newl2.title)
+  call assert_equal(['Colors'], newl2.context)
+  call assert_equal('Line10', newl2.items[0].text)
+  call g:Xsetlist([], 'f')
+
+  " Cannot specify both a non-empty list argument and a dict argument
+  call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
 endfunc
 
 func Test_qf_property()
-    call Xproperty_tests('c')
-    call Xproperty_tests('l')
+  call Xproperty_tests('c')
+  call Xproperty_tests('l')
 endfunc
 
 " Test for setting the current index in the location/quickfix list
@@ -2850,7 +2846,7 @@ func Test_vimgrep_existing_swapfile()
   call assert_match('.Xapple.swo', swapname(''))
 
   call delete('Xapple')
-  call delete('Xapple.swp')
+  call delete('.Xapple.swp')
   augroup grep
     au! SwapExists
   augroup END
@@ -3022,20 +3018,20 @@ func Test_file_from_copen()
 endfunc
 
 func Test_resize_from_copen()
+  augroup QF_Test
+    au!
+    au FileType qf resize 5
+  augroup END
+  try
+    " This should succeed without any exception.  No other buffers are
+    " involved in the autocmd.
+    copen
+  finally
     augroup QF_Test
-	au!
-        au FileType qf resize 5
+      au!
     augroup END
-    try
-	" This should succeed without any exception.  No other buffers are
-	" involved in the autocmd.
-	copen
-    finally
-	augroup QF_Test
-	    au!
-	augroup END
-	augroup! QF_Test
-    endtry
+    augroup! QF_Test
+  endtry
 endfunc
 
 " Tests for the quickfix buffer b:changedtick variable
@@ -3227,15 +3223,15 @@ endfunc
 " Open multiple help windows using ":lhelpgrep
 " This test used to crash Vim
 func Test_Multi_LL_Help()
-    new | only
-    lhelpgrep window
-    lopen
-    e#
-    lhelpgrep buffer
-    call assert_equal(3, winnr('$'))
-    call assert_true(len(getloclist(1)) != 0)
-    call assert_true(len(getloclist(2)) != 0)
-    new | only
+  new | only
+  lhelpgrep window
+  lopen
+  e#
+  lhelpgrep buffer
+  call assert_equal(3, winnr('$'))
+  call assert_true(len(getloclist(1)) != 0)
+  call assert_true(len(getloclist(2)) != 0)
+  new | only
 endfunc
 
 " Tests for adding new quickfix lists using setqflist()
@@ -3926,9 +3922,7 @@ endfunc
 " Test for shortening/simplifying the file name when opening the
 " quickfix window or when displaying the quickfix list
 func Test_shorten_fname()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
   %bwipe
   " Create a quickfix list with a absolute path filename
   let fname = getcwd() . '/test_quickfix.vim'
--- a/src/testdir/test_quotestar.vim
+++ b/src/testdir/test_quotestar.vim
@@ -36,7 +36,7 @@ func Do_test_quotestar_for_x11()
 
   let cmd = GetVimCommand()
   if cmd == ''
-    return 'GetVimCommand() failed'
+    throw 'GetVimCommand() failed'
   endif
   try
     call remote_send('xxx', '')
@@ -152,3 +152,5 @@ func Test_quotestar()
     throw 'Skipped: ' . skipped
   endif
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_random.vim
+++ b/src/testdir/test_random.vim
@@ -45,3 +45,5 @@ func Test_issue_5587()
   call garbagecollect()
   call rand()
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_recover.vim
+++ b/src/testdir/test_recover.vim
@@ -66,3 +66,5 @@ func Test_swap_file()
   set undolevels&
   enew! | only
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_regex_char_classes.vim
+++ b/src/testdir/test_regex_char_classes.vim
@@ -293,3 +293,5 @@ func Test_regex_char_classes()
   enew!
   close
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_regexp_latin.vim
+++ b/src/testdir/test_regexp_latin.vim
@@ -1,4 +1,5 @@
 " Tests for regexp in latin1 encoding
+
 set encoding=latin1
 scriptencoding latin1
 
--- a/src/testdir/test_registers.vim
+++ b/src/testdir/test_registers.vim
@@ -1,6 +1,4 @@
-"
 " Tests for register operations
-"
 
 source check.vim
 source view_util.vim
--- a/src/testdir/test_rename.vim
+++ b/src/testdir/test_rename.vim
@@ -118,3 +118,5 @@ func Test_rename_fails()
 
   call delete('Xrenamefile')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_retab.vim
+++ b/src/testdir/test_retab.vim
@@ -1,4 +1,5 @@
 " Test :retab
+
 func SetUp()
   new
   call setline(1, "\ta  \t    b        c    ")
@@ -75,3 +76,5 @@ func Test_retab_error()
   call assert_fails('retab -1',  'E487:')
   call assert_fails('retab! -1', 'E487:')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_scriptnames.vim
+++ b/src/testdir/test_scriptnames.vim
@@ -24,3 +24,5 @@ func Test_scriptnames()
   bwipe
   call delete('Xscripting')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -1,5 +1,4 @@
 " Test for reset 'scroll'
-"
 
 func Test_reset_scroll()
   let scr = &l:scroll
@@ -34,3 +33,5 @@ func Test_reset_scroll()
 
   quit!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_scrollbind.vim
+++ b/src/testdir/test_scrollbind.vim
@@ -1,4 +1,5 @@
 " Test for 'scrollbind' causing an unexpected scroll of one of the windows.
+
 func Test_scrollbind()
   " We don't want the status line to cause problems:
   set laststatus=0
@@ -270,3 +271,5 @@ end of window 2
   new | only!
   set scrollbind& scrollopt& scrolloff& wrap& equalalways& splitbelow&
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_search_stat.vim
+++ b/src/testdir/test_search_stat.vim
@@ -346,3 +346,5 @@ func! Test_search_stat_screendump()
   call StopVimInTerminal(buf)
   call delete('Xsearchstat')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_searchpos.vim
+++ b/src/testdir/test_searchpos.vim
@@ -26,3 +26,5 @@ func Test_searchpos()
   q!
 
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_set.vim
+++ b/src/testdir/test_set.vim
@@ -25,3 +25,5 @@ function Test_set_add()
 
   let &wig = wig_save
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_sha256.vim
+++ b/src/testdir/test_sha256.vim
@@ -20,3 +20,5 @@ function Test_sha256()
   " test for contains non-ascii char:
   call assert_equal('5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953', sha256("\xde\xad\xbe\xef"))
 endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_shift.vim
+++ b/src/testdir/test_shift.vim
@@ -111,3 +111,5 @@ func Test_ex_shift_errors()
   call assert_fails('2,1>', 'E493:')
   call assert_fails('2,1<', 'E493:')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_shortpathname.vim
+++ b/src/testdir/test_shortpathname.vim
@@ -87,3 +87,5 @@ func Test_ColonEight_MultiByte()
   call delete(file)
   call delete(dir, 'd')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_signs.vim
+++ b/src/testdir/test_signs.vim
@@ -1997,3 +1997,5 @@ func Test_sign_funcs_multi()
   enew!
   call delete("Xsign")
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_sort.vim
+++ b/src/testdir/test_sort.vim
@@ -3,12 +3,12 @@
 source check.vim
 
 func Compare1(a, b) abort
-    call sort(range(3), 'Compare2')
-    return a:a - a:b
+  call sort(range(3), 'Compare2')
+  return a:a - a:b
 endfunc
 
 func Compare2(a, b) abort
-    return a:a - a:b
+  return a:a - a:b
 endfunc
 
 func Test_sort_strings()
--- a/src/testdir/test_sound.vim
+++ b/src/testdir/test_sound.vim
@@ -62,3 +62,5 @@ func Test_play_silent()
   sleep 30m
   call assert_true(g:id_again > 0)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_source_utf8.vim
+++ b/src/testdir/test_source_utf8.vim
@@ -1,4 +1,5 @@
 " Test the :source! command
+
 source check.vim
 
 func Test_source_utf8()
@@ -59,3 +60,5 @@ func Test_source_ctrl_v()
   unmap __4
   unmap __5
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_spellfile.vim
+++ b/src/testdir/test_spellfile.vim
@@ -170,3 +170,5 @@ func Test_spell_normal()
   set spellfile=
   bw!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_startup.vim
+++ b/src/testdir/test_startup.vim
@@ -21,9 +21,7 @@ endfunc
 " 2. packages
 " 3. plugins in after directories
 func Test_after_comes_later()
-  if !has('packages')
-    return
-  endif
+  CheckFeature packages
   let before =<< trim [CODE]
     set nocp viminfo+=nviminfo
     set guioptions+=M
@@ -80,9 +78,7 @@ func Test_after_comes_later()
 endfunc
 
 func Test_pack_in_rtp_when_plugins_run()
-  if !has('packages')
-    return
-  endif
+  CheckFeature packages
   let before =<< trim [CODE]
     set nocp viminfo+=nviminfo
     set guioptions+=M
@@ -113,9 +109,8 @@ func Test_pack_in_rtp_when_plugins_run()
 endfunc
 
 func Test_help_arg()
-  if !has('unix') && has('gui')
-    " this doesn't work with gvim on MS-Windows
-    return
+  if !has('unix') && has('gui_running')
+    throw 'Skipped: does not work with gvim on MS-Windows'
   endif
   if RunVim([], [], '--help >Xtestout')
     let lines = readfile('Xtestout')
@@ -554,9 +549,7 @@ func Test_file_args()
 endfunc
 
 func Test_startuptime()
-  if !has('startuptime')
-    return
-  endif
+  CheckFeature startuptime
   let after = ['qall']
   if RunVim([], after, '--startuptime Xtestout one')
     let lines = readfile('Xtestout')
--- a/src/testdir/test_startup_utf8.vim
+++ b/src/testdir/test_startup_utf8.vim
@@ -31,16 +31,14 @@ func Test_read_stdin_utf8()
 endfunc
 
 func Test_read_fifo_utf8()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
   " Using bash/zsh's process substitution.
   if executable('bash')
     set shell=bash
   elseif executable('zsh')
     set shell=zsh
   else
-    return
+    throw 'Skipped: bash or zsh is required'
   endif
   let linesin = ['テスト', '€ÀÈÌÒÙ']
   call writefile(linesin, 'Xtestin')
@@ -80,3 +78,5 @@ func Test_detect_ambiwidth()
   call StopVimInTerminal(buf)
   call delete('Xscript')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_stat.vim
+++ b/src/testdir/test_stat.vim
@@ -1,5 +1,7 @@
 " Tests for stat functions and checktime
 
+source check.vim
+
 func CheckFileTime(doSleep)
   let fnames = ['Xtest1.tmp', 'Xtest2.tmp', 'Xtest3.tmp']
   let times = []
@@ -177,12 +179,15 @@ endfunc
 func Test_win32_symlink_dir()
   " On Windows, non-admin users cannot create symlinks.
   " So we use an existing symlink for this test.
-  if has('win32')
-    " Check if 'C:\Users\All Users' is a symlink to a directory.
-    let res = system('dir C:\Users /a')
-    if match(res, '\C<SYMLINKD> *All Users') >= 0
-      " Get the filetype of the symlink.
-      call assert_equal('dir', getftype('C:\Users\All Users'))
-    endif
+  CheckMSWindows
+  " Check if 'C:\Users\All Users' is a symlink to a directory.
+  let res = system('dir C:\Users /a')
+  if match(res, '\C<SYMLINKD> *All Users') >= 0
+    " Get the filetype of the symlink.
+    call assert_equal('dir', getftype('C:\Users\All Users'))
+  else
+    throw 'Skipped: cannot find an existing symlink'
   endif
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_suspend.vim
+++ b/src/testdir/test_suspend.vim
@@ -1,6 +1,6 @@
 " Test :suspend
 
-source shared.vim
+source check.vim
 source term_util.vim
 
 func CheckSuspended(buf, fileExists)
@@ -18,9 +18,8 @@ func CheckSuspended(buf, fileExists)
 endfunc
 
 func Test_suspend()
-  if !has('terminal') || !executable('/bin/sh')
-    return
-  endif
+  CheckFeature terminal
+  CheckExecutable /bin/sh
 
   let buf = term_start('/bin/sh')
   " Wait for shell prompt.
@@ -61,3 +60,5 @@ func Test_suspend()
   exe buf . 'bwipe!'
   call delete('Xfoo')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_swap.vim
+++ b/src/testdir/test_swap.vim
@@ -10,9 +10,8 @@ endfunc
 
 " Tests for 'directory' option.
 func Test_swap_directory()
-  if !has("unix")
-    return
-  endif
+  CheckUnix
+
   let content = ['start of testfile',
 	      \ 'line 2 Abcdefghij',
 	      \ 'line 3 Abcdefghij',
@@ -56,9 +55,8 @@ func Test_swap_directory()
 endfunc
 
 func Test_swap_group()
-  if !has("unix")
-    return
-  endif
+  CheckUnix
+
   let groups = split(system('groups'))
   if len(groups) <= 1
     throw 'Skipped: need at least two groups, got ' . string(groups)
@@ -378,9 +376,7 @@ func Test_swap_prompt_splitwin()
 endfunc
 
 func Test_swap_symlink()
-  if !has("unix")
-    return
-  endif
+  CheckUnix
 
   call writefile(['text'], 'Xtestfile')
   silent !ln -s -f Xtestfile Xtestlink
--- a/src/testdir/test_syntax.vim
+++ b/src/testdir/test_syntax.vim
@@ -84,9 +84,7 @@ func Test_syntax_after_reload()
 endfunc
 
 func Test_syntime()
-  if !has('profile')
-    return
-  endif
+  CheckFeature profile
 
   syntax on
   syntime on
@@ -119,9 +117,7 @@ func Test_syntime()
 endfunc
 
 func Test_syntime_completion()
-  if !has('profile')
-    return
-  endif
+  CheckFeature profile
 
   call feedkeys(":syntime \<C-A>\<C-B>\"\<CR>", 'tx')
   call assert_equal('"syntime clear off on report', @:)
@@ -498,9 +494,8 @@ func Test_bg_detection()
 endfunc
 
 func Test_syntax_hangs()
-  if !has('reltime') || !has('float') || !has('syntax')
-    return
-  endif
+  CheckFunction reltimefloat
+  CheckFeature syntax
 
   " This pattern takes a long time to match, it should timeout.
   new
@@ -532,9 +527,7 @@ func Test_syntax_hangs()
 endfunc
 
 func Test_conceal()
-  if !has('conceal')
-    return
-  endif
+  CheckFeature conceal
 
   new
   call setline(1, ['', '123456'])
--- a/src/testdir/test_tab.vim
+++ b/src/testdir/test_tab.vim
@@ -88,3 +88,5 @@ func Test_softtabstop()
   set sts=0 sw=0 backspace& nosmarttab
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_tabline.vim
+++ b/src/testdir/test_tabline.vim
@@ -1,3 +1,4 @@
+" Test for tabline
 
 source shared.vim
 
--- a/src/testdir/test_tagcase.vim
+++ b/src/testdir/test_tagcase.vim
@@ -72,3 +72,5 @@ func Test_set_tagcase()
   setg tc&
   setl tc&
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -192,9 +192,8 @@ endfunction
 " Test for jumping to a tag with 'hidden' set, with symbolic link in path of
 " tag.  This only works for Unix, because of the symbolic link.
 func Test_tag_symbolic()
-  if !has('unix')
-    return
-  endif
+  CheckUnix
+
   set hidden
   call delete("Xtest.dir", "rf")
   call system("ln -s . Xtest.dir")
@@ -230,11 +229,11 @@ endfunc
 " Depends on the test83-tags2 and test83-tags3 files.
 func Test_tag_file_encoding()
   if has('vms')
-    return
+    throw 'Skipped: does not work on VMS'
   endif
 
   if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
-    return
+    throw 'Skipped: iconv does not work'
   endif
 
   let save_enc = &encoding
@@ -283,9 +282,8 @@ endfunc
 
 " Test for emacs-style tags file (TAGS)
 func Test_tagjump_etags()
-  if !has('emacs_tags')
-    return
-  endif
+  CheckFeature emacs_tags
+
   call writefile([
         \ "void foo() {}",
         \ "int main(int argc, char **argv)",
--- a/src/testdir/test_taglist.vim
+++ b/src/testdir/test_taglist.vim
@@ -1,5 +1,6 @@
 " test taglist(), tagfiles() functions and :tags command
 
+source check.vim
 source view_util.vim
 
 func Test_taglist()
@@ -44,9 +45,8 @@ func Test_taglist()
 endfunc
 
 func Test_taglist_native_etags()
-  if !has('emacs_tags')
-    return
-  endif
+  CheckFeature emacs_tags
+
   call writefile([
 	\ "\x0c",
 	\ "src/os_unix.c,13491",
@@ -64,9 +64,8 @@ func Test_taglist_native_etags()
 endfunc
 
 func Test_taglist_ctags_etags()
-  if !has('emacs_tags')
-    return
-  endif
+  CheckFeature emacs_tags
+
   call writefile([
 	\ "\x0c",
 	\ "src/os_unix.c,13491",
--- a/src/testdir/test_termcodes.vim
+++ b/src/testdir/test_termcodes.vim
@@ -270,7 +270,6 @@ endfunc
 func Test_term_mouse_middle_click_no_clipboard()
   if has('clipboard_working')
     throw 'Skipped: clipboard support works'
-    return
   endif
   new
   let save_mouse = &mouse
--- a/src/testdir/test_termencoding.vim
+++ b/src/testdir/test_termencoding.vim
@@ -35,3 +35,5 @@ func Test_termencoding_euc_jp()
   call delete('Xeuc_jp.txt')
   call delete('XTest_tenc_euc_jp')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -605,9 +605,7 @@ func Test_terminal_cwd_failure()
 endfunc
 
 func Test_terminal_servername()
-  if !has('clientserver')
-    return
-  endif
+  CheckFeature clientserver
   call s:test_environment("VIM_SERVERNAME", v:servername)
 endfunc
 
--- a/src/testdir/test_terminal2.vim
+++ b/src/testdir/test_terminal2.vim
@@ -370,9 +370,8 @@ func Test_terminal_hidden_and_close()
 endfunc
 
 func Test_terminal_does_not_truncate_last_newlines()
-  " This test does not pass through ConPTY.
   if has('conpty')
-    return
+    throw 'Skipped: fail on ConPTY'
   endif
   let contents = [
   \   [ 'One', '', 'X' ],
--- a/src/testdir/test_terminal3.vim
+++ b/src/testdir/test_terminal3.vim
@@ -57,6 +57,8 @@ func Test_terminal_shell_option()
     term ++shell dir.com /b runtest.vim
     call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))})
     bwipe!
+  else
+    throw 'Skipped: does not work on this platform'
   endif
 endfunc
 
--- a/src/testdir/test_terminal_fail.vim
+++ b/src/testdir/test_terminal_fail.vim
@@ -1,6 +1,6 @@
 " This test is in a separate file, because it usually causes reports for memory
 " leaks under valgrind.  That is because when fork/exec fails memory is not
-" freed.  Since the process exists right away it's not a real leak.
+" freed.  Since the process exits right away it's not a real leak.
 
 source check.vim
 CheckFeature terminal
@@ -8,13 +8,15 @@ CheckFeature terminal
 source shared.vim
 
 func Test_terminal_redir_fails()
-  if has('unix')
-    let buf = term_start('xyzabc', {'err_io': 'file', 'err_name': 'Xfile'})
-    call TermWait(buf)
-    call WaitFor('len(readfile("Xfile")) > 0')
-    call assert_match('executing job failed', readfile('Xfile')[0])
-    call WaitFor('!&modified')
-    call delete('Xfile')
-    bwipe
-  endif
+  CheckUnix
+
+  let buf = term_start('xyzabc', {'err_io': 'file', 'err_name': 'Xfile'})
+  call TermWait(buf)
+  call WaitFor('len(readfile("Xfile")) > 0')
+  call assert_match('executing job failed', readfile('Xfile')[0])
+  call WaitFor('!&modified')
+  call delete('Xfile')
+  bwipe
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_true_false.vim
+++ b/src/testdir/test_true_false.vim
@@ -153,3 +153,5 @@ func Test_non_zero_arg()
     call assert_equal('', r, 'result for ' . v . ' is not "" but ' . r)
   endfor
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_utf8_comparisons.vim
+++ b/src/testdir/test_utf8_comparisons.vim
@@ -92,3 +92,5 @@ func Test_gap()
   call feedkeys("gg0g~ap", "tx")
   call assert_equal(["ABCD", "", "defg"], getline(1,3))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_vartabs.vim
+++ b/src/testdir/test_vartabs.vim
@@ -147,9 +147,7 @@ func Test_vartabs()
 endfunc
 
 func Test_vartabs_breakindent()
-  if !exists("+breakindent")
-    return
-  endif
+  CheckOption breakindent
   new
   %d
 
--- a/src/testdir/test_version.vim
+++ b/src/testdir/test_version.vim
@@ -8,3 +8,5 @@ func Test_version()
 
   call assert_match("^\n\nVIM - Vi IMproved .*", v1)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -2009,3 +2009,5 @@ func Test_expr_fails()
   call CheckDefFailure(["echo Func0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789()"], 'E1011:')
   call CheckDefFailure(["echo doesnotexist()"], 'E117:')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_winbar.vim
+++ b/src/testdir/test_winbar.vim
@@ -121,3 +121,4 @@ func Test_redraw_after_scroll()
   bwipe!
 endfunc
 
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_winbuf_close.vim
+++ b/src/testdir/test_winbuf_close.vim
@@ -213,3 +213,4 @@ func Test_window_close_splitright_noequa
   call assert_equal(w, win_getid(), "Did not return to original window after opening and closing a window")
 endfunc
 
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -1,6 +1,6 @@
 " Tests for window cmd (:wincmd, :split, :vsplit, :resize and etc...)
 
-so check.vim
+source check.vim
 
 func Test_window_cmd_ls0_with_split()
   set ls=0
@@ -655,9 +655,7 @@ endfunc
 
 func Test_window_prevwin()
   " Can we make this work on MS-Windows?
-  if !has('unix')
-    return
-  endif
+  CheckUnix
 
   set hidden autoread
   call writefile(['2'], 'tmp.txt')
--- a/src/testdir/test_window_id.vim
+++ b/src/testdir/test_window_id.vim
@@ -1,4 +1,5 @@
 " Test using the window ID.
+
 source check.vim
 
 func Test_win_getid()
--- a/src/testdir/test_windows_home.vim
+++ b/src/testdir/test_windows_home.vim
@@ -118,3 +118,5 @@ func Test_WindowsHome()
     delcommand UnletEnv
   endtry
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_wnext.vim
+++ b/src/testdir/test_wnext.vim
@@ -99,3 +99,5 @@ func Test_wprevious()
   call delete('X3')
   call delete('X4')
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_wordcount.vim
+++ b/src/testdir/test_wordcount.vim
@@ -102,3 +102,5 @@ func Test_wordcount()
   enew!
   close
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_writefile.vim
+++ b/src/testdir/test_writefile.vim
@@ -43,8 +43,9 @@ func Test_writefile_fails_gently()
 endfunc
 
 func Test_writefile_fails_conversion()
-  if !has('iconv') || has('sun')
-    return
+  CheckFeature iconv
+  if has('sun')
+    throw 'Skipped: does not work on SunOS'
   endif
   " Without a backup file the write won't happen if there is a conversion
   " error.
@@ -63,8 +64,9 @@ func Test_writefile_fails_conversion()
 endfunc
 
 func Test_writefile_fails_conversion2()
-  if !has('iconv') || has('sun')
-    return
+  CheckFeature iconv
+  if has('sun')
+    throw 'Skipped: does not work on SunOS'
   endif
   " With a backup file the write happens even if there is a conversion error,
   " but then the backup file must remain
--- a/src/testdir/test_xxd.vim
+++ b/src/testdir/test_xxd.vim
@@ -1,4 +1,5 @@
 " Test for the xxd command
+
 if empty($XXD) && executable('..\xxd\xxd.exe')
   let s:xxd_cmd = '..\xxd\xxd.exe'
 elseif empty($XXD) || !executable($XXD)
@@ -228,3 +229,5 @@ func Test_xxd_version()
   call assert_match("xxd V1.10 .* by Juergen Weigert", join(getline(1, 3)))
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1432,
+/**/
     1431,
 /**/
     1430,