aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/buffer_spec.lua2
-rw-r--r--test/functional/api/menu_spec.lua2
-rw-r--r--test/functional/api/server_notifications_spec.lua31
-rw-r--r--test/functional/api/server_requests_spec.lua2
-rw-r--r--test/functional/api/tabpage_spec.lua2
-rw-r--r--test/functional/api/vim_spec.lua2
-rw-r--r--test/functional/api/window_spec.lua2
-rw-r--r--test/functional/autocmd/autocmd_spec.lua2
-rw-r--r--test/functional/autocmd/tabclose_spec.lua2
-rw-r--r--test/functional/autocmd/tabnew_spec.lua2
-rw-r--r--test/functional/autocmd/tabnewentered_spec.lua43
-rw-r--r--test/functional/autocmd/termclose_spec.lua2
-rw-r--r--test/functional/autocmd/textyankpost_spec.lua2
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua4
-rw-r--r--test/functional/core/job_spec.lua (renamed from test/functional/job/job_spec.lua)81
-rw-r--r--test/functional/dict_notifications_spec.lua2
-rw-r--r--test/functional/eval/capture_spec.lua86
-rw-r--r--test/functional/eval/glob_spec.lua2
-rw-r--r--test/functional/eval/json_functions_spec.lua14
-rw-r--r--test/functional/eval/msgpack_functions_spec.lua2
-rw-r--r--test/functional/eval/operators_spec.lua2
-rw-r--r--test/functional/eval/printf_spec.lua2
-rw-r--r--test/functional/eval/reltime_spec.lua2
-rw-r--r--test/functional/eval/server_spec.lua2
-rw-r--r--test/functional/eval/special_vars_spec.lua2
-rw-r--r--test/functional/eval/string_spec.lua2
-rw-r--r--test/functional/eval/timer_spec.lua144
-rw-r--r--test/functional/eval/vvar_event_spec.lua2
-rw-r--r--test/functional/ex_cmds/append_spec.lua2
-rw-r--r--test/functional/ex_cmds/cd_spec.lua162
-rw-r--r--test/functional/ex_cmds/drop_spec.lua80
-rw-r--r--test/functional/ex_cmds/encoding_spec.lua6
-rw-r--r--test/functional/ex_cmds/grep_spec.lua2
-rw-r--r--test/functional/ex_cmds/menu_spec.lua4
-rw-r--r--test/functional/ex_cmds/oldfiles_spec.lua2
-rw-r--r--test/functional/ex_cmds/profile_spec.lua2
-rw-r--r--test/functional/ex_cmds/quit_spec.lua4
-rw-r--r--test/functional/ex_cmds/recover_spec.lua2
-rw-r--r--test/functional/ex_cmds/sign_spec.lua2
-rw-r--r--test/functional/ex_cmds/write_spec.lua13
-rw-r--r--test/functional/ex_cmds/wundo_spec.lua2
-rw-r--r--test/functional/ex_cmds/wviminfo_spec.lua3
-rw-r--r--test/functional/ex_getln/history_spec.lua2
-rw-r--r--test/functional/fixtures/autoload/provider/clipboard.vim5
-rw-r--r--test/functional/helpers.lua164
-rw-r--r--test/functional/legacy/002_filename_recognition_spec.lua2
-rw-r--r--test/functional/legacy/003_cindent_spec.lua2
-rw-r--r--test/functional/legacy/004_bufenter_with_modelines_spec.lua2
-rw-r--r--test/functional/legacy/005_bufleave_delete_buffer_spec.lua2
-rw-r--r--test/functional/legacy/006_argument_list_spec.lua2
-rw-r--r--test/functional/legacy/007_ball_buffer_list_spec.lua2
-rw-r--r--test/functional/legacy/009_bufleave_autocommand_spec.lua2
-rw-r--r--test/functional/legacy/010_errorformat_spec.lua156
-rw-r--r--test/functional/legacy/011_autocommands_spec.lua3
-rw-r--r--test/functional/legacy/015_alignment_spec.lua2
-rw-r--r--test/functional/legacy/018_unset_smart_indenting_spec.lua2
-rw-r--r--test/functional/legacy/019_smarttab_expandtab_spec.lua2
-rw-r--r--test/functional/legacy/020_blockwise_visual_spec.lua2
-rw-r--r--test/functional/legacy/021_control_wi_spec.lua2
-rw-r--r--test/functional/legacy/022_line_ending_spec.lua2
-rw-r--r--test/functional/legacy/023_edit_arguments_spec.lua2
-rw-r--r--test/functional/legacy/025_jump_tag_hidden_spec.lua2
-rw-r--r--test/functional/legacy/026_execute_while_if_spec.lua2
-rw-r--r--test/functional/legacy/027_expand_file_names_spec.lua37
-rw-r--r--test/functional/legacy/028_source_ctrl_v_spec.lua2
-rw-r--r--test/functional/legacy/029_join_spec.lua2
-rw-r--r--test/functional/legacy/031_close_commands_spec.lua11
-rw-r--r--test/functional/legacy/033_lisp_indent_spec.lua2
-rw-r--r--test/functional/legacy/034_user_function_spec.lua102
-rw-r--r--test/functional/legacy/035_increment_and_decrement_spec.lua2
-rw-r--r--test/functional/legacy/036_regexp_character_classes_spec.lua2
-rw-r--r--test/functional/legacy/038_virtual_replace_spec.lua2
-rw-r--r--test/functional/legacy/039_visual_block_mode_commands_spec.lua2
-rw-r--r--test/functional/legacy/041_writing_and_reading_hundred_kbyte_spec.lua2
-rw-r--r--test/functional/legacy/043_magic_settings_spec.lua2
-rw-r--r--test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua2
-rw-r--r--test/functional/legacy/045_folding_spec.lua2
-rw-r--r--test/functional/legacy/046_multi_line_regexps_spec.lua2
-rw-r--r--test/functional/legacy/051_highlight_spec.lua2
-rw-r--r--test/functional/legacy/054_buffer_local_autocommands_spec.lua2
-rw-r--r--test/functional/legacy/055_list_and_dict_types_spec.lua926
-rw-r--r--test/functional/legacy/056_script_local_function_spec.lua2
-rw-r--r--test/functional/legacy/057_sort_spec.lua2
-rw-r--r--test/functional/legacy/059_utf8_spell_checking_spec.lua2
-rw-r--r--test/functional/legacy/060_exists_and_has_functions_spec.lua2
-rw-r--r--test/functional/legacy/061_undo_tree_spec.lua21
-rw-r--r--test/functional/legacy/062_tab_pages_spec.lua2
-rw-r--r--test/functional/legacy/063_match_and_matchadd_spec.lua2
-rw-r--r--test/functional/legacy/065_float_and_logic_operators_spec.lua2
-rw-r--r--test/functional/legacy/066_visual_block_tab_spec.lua2
-rw-r--r--test/functional/legacy/067_augroup_exists_spec.lua2
-rw-r--r--test/functional/legacy/068_text_formatting_spec.lua10
-rw-r--r--test/functional/legacy/072_undo_file_spec.lua2
-rw-r--r--test/functional/legacy/074_global_var_in_viminfo_spec.lua3
-rw-r--r--test/functional/legacy/075_maparg_spec.lua2
-rw-r--r--test/functional/legacy/076_completefunc_spec.lua2
-rw-r--r--test/functional/legacy/077_mf_hash_grow_spec.lua2
-rw-r--r--test/functional/legacy/078_swapfile_recover_spec.lua2
-rw-r--r--test/functional/legacy/080_substitute_spec.lua2
-rw-r--r--test/functional/legacy/081_coptions_movement_spec.lua2
-rw-r--r--test/functional/legacy/082_string_comparison_spec.lua2
-rw-r--r--test/functional/legacy/083_tag_search_with_file_encoding_spec.lua2
-rw-r--r--test/functional/legacy/084_curswant_spec.lua2
-rw-r--r--test/functional/legacy/088_conceal_tabs_spec.lua2
-rw-r--r--test/functional/legacy/089_number_relnumber_findfile_spec.lua2
-rw-r--r--test/functional/legacy/090_sha256_spec.lua2
-rw-r--r--test/functional/legacy/091_context_variables_spec.lua2
-rw-r--r--test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua2
-rw-r--r--test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua2
-rw-r--r--test/functional/legacy/094_visual_mode_operators_spec.lua2
-rw-r--r--test/functional/legacy/095_regexp_multibyte_spec.lua2
-rw-r--r--test/functional/legacy/096_location_list_spec.lua2
-rw-r--r--test/functional/legacy/097_glob_path_spec.lua2
-rw-r--r--test/functional/legacy/098_scrollbind_spec.lua2
-rw-r--r--test/functional/legacy/101_hlsearch_spec.lua4
-rw-r--r--test/functional/legacy/102_fnameescape_spec.lua2
-rw-r--r--test/functional/legacy/103_visual_mode_reset_spec.lua2
-rw-r--r--test/functional/legacy/104_let_assignment_spec.lua2
-rw-r--r--test/functional/legacy/106_errorformat_spec.lua2
-rw-r--r--test/functional/legacy/107_adjust_window_and_contents_spec.lua2
-rw-r--r--test/functional/legacy/108_backtrace_debug_commands_spec.lua2
-rw-r--r--test/functional/legacy/arglist_spec.lua268
-rw-r--r--test/functional/legacy/argument_0count_spec.lua28
-rw-r--r--test/functional/legacy/argument_count_spec.lua47
-rw-r--r--test/functional/legacy/assert_spec.lua109
-rw-r--r--test/functional/legacy/autocmd_option_spec.lua2
-rw-r--r--test/functional/legacy/autoformat_join_spec.lua2
-rw-r--r--test/functional/legacy/backspace_opt_spec.lua2
-rw-r--r--test/functional/legacy/breakindent_spec.lua2
-rw-r--r--test/functional/legacy/cdo_spec.lua2
-rw-r--r--test/functional/legacy/changelist_spec.lua2
-rw-r--r--test/functional/legacy/charsearch_spec.lua2
-rw-r--r--test/functional/legacy/close_count_spec.lua2
-rw-r--r--test/functional/legacy/command_count_spec.lua22
-rw-r--r--test/functional/legacy/comparators_spec.lua2
-rw-r--r--test/functional/legacy/delete_spec.lua2
-rw-r--r--test/functional/legacy/erasebackword_spec.lua2
-rw-r--r--test/functional/legacy/eval_spec.lua20
-rw-r--r--test/functional/legacy/expand_spec.lua77
-rw-r--r--test/functional/legacy/file_perm_spec.lua2
-rw-r--r--test/functional/legacy/fixeol_spec.lua2
-rw-r--r--test/functional/legacy/fnamemodify_spec.lua2
-rw-r--r--test/functional/legacy/function_sort_spec.lua26
-rw-r--r--test/functional/legacy/getcwd_spec.lua86
-rw-r--r--test/functional/legacy/glob2regpat_spec.lua2
-rw-r--r--test/functional/legacy/increment_spec.lua2
-rw-r--r--test/functional/legacy/insertcount_spec.lua2
-rw-r--r--test/functional/legacy/join_spec.lua2
-rw-r--r--test/functional/legacy/lispwords_spec.lua2
-rw-r--r--test/functional/legacy/listchars_spec.lua2
-rw-r--r--test/functional/legacy/listlbr_spec.lua195
-rw-r--r--test/functional/legacy/listlbr_utf8_spec.lua2
-rw-r--r--test/functional/legacy/mapping_spec.lua2
-rw-r--r--test/functional/legacy/marks_spec.lua2
-rw-r--r--test/functional/legacy/match_conceal_spec.lua2
-rw-r--r--test/functional/legacy/nested_function_spec.lua2
-rw-r--r--test/functional/legacy/options_spec.lua2
-rw-r--r--test/functional/legacy/packadd_spec.lua350
-rw-r--r--test/functional/legacy/qf_title_spec.lua2
-rw-r--r--test/functional/legacy/quickfix_spec.lua331
-rw-r--r--test/functional/legacy/search_mbyte_spec.lua2
-rw-r--r--test/functional/legacy/searchpos_spec.lua2
-rw-r--r--test/functional/legacy/set_spec.lua2
-rw-r--r--test/functional/legacy/signs_spec.lua2
-rw-r--r--test/functional/legacy/tagcase_spec.lua2
-rw-r--r--test/functional/legacy/textobjects_spec.lua2
-rw-r--r--test/functional/legacy/undolevels_spec.lua2
-rw-r--r--test/functional/legacy/utf8_spec.lua2
-rw-r--r--test/functional/legacy/wordcount_spec.lua2
-rw-r--r--test/functional/legacy/writefile_spec.lua3
-rw-r--r--test/functional/normal/K_spec.lua2
-rw-r--r--test/functional/options/autochdir_spec.lua18
-rw-r--r--test/functional/options/defaults_spec.lua8
-rw-r--r--test/functional/options/shortmess_spec.lua2
-rw-r--r--test/functional/plugin/helpers.lua2
-rw-r--r--test/functional/plugin/matchparen_spec.lua17
-rw-r--r--test/functional/plugin/msgpack_spec.lua2
-rw-r--r--test/functional/plugin/shada_spec.lua2
-rw-r--r--test/functional/preload.lua2
-rw-r--r--test/functional/provider/define_spec.lua2
-rw-r--r--test/functional/provider/python3_spec.lua2
-rw-r--r--test/functional/provider/python_spec.lua84
-rw-r--r--test/functional/provider/ruby_spec.lua96
-rw-r--r--test/functional/shada/buffers_spec.lua2
-rw-r--r--test/functional/shada/compatibility_spec.lua2
-rw-r--r--test/functional/shada/errors_spec.lua2
-rw-r--r--test/functional/shada/helpers.lua2
-rw-r--r--test/functional/shada/history_spec.lua2
-rw-r--r--test/functional/shada/marks_spec.lua2
-rw-r--r--test/functional/shada/merging_spec.lua2
-rw-r--r--test/functional/shada/registers_spec.lua2
-rw-r--r--test/functional/shada/shada_spec.lua2
-rw-r--r--test/functional/shada/variables_spec.lua2
-rw-r--r--test/functional/shell/bang_filter_spec.lua2
-rw-r--r--test/functional/shell/viml_system_spec.lua10
-rw-r--r--test/functional/terminal/altscreen_spec.lua2
-rw-r--r--test/functional/terminal/buffer_spec.lua2
-rw-r--r--test/functional/terminal/cursor_spec.lua2
-rw-r--r--test/functional/terminal/edit_spec.lua2
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua2
-rw-r--r--test/functional/terminal/helpers.lua2
-rw-r--r--test/functional/terminal/highlight_spec.lua41
-rw-r--r--test/functional/terminal/mouse_spec.lua30
-rw-r--r--test/functional/terminal/scrollback_spec.lua2
-rw-r--r--test/functional/terminal/tui_spec.lua71
-rw-r--r--test/functional/terminal/window_spec.lua21
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua129
-rw-r--r--test/functional/ui/bufhl_spec.lua2
-rw-r--r--test/functional/ui/highlight_spec.lua3
-rw-r--r--test/functional/ui/input_spec.lua2
-rw-r--r--test/functional/ui/mouse_spec.lua319
-rw-r--r--test/functional/ui/output_spec.lua39
-rw-r--r--test/functional/ui/screen.lua8
-rw-r--r--test/functional/ui/screen_basic_spec.lua2
-rw-r--r--test/functional/ui/searchhl_spec.lua2
-rw-r--r--test/functional/ui/sign_spec.lua2
-rw-r--r--test/functional/ui/syntax_conceal_spec.lua2
-rw-r--r--test/functional/ui/wildmode_spec.lua2
-rw-r--r--test/functional/viml/completion_spec.lua2
-rw-r--r--test/functional/viml/errorlist_spec.lua2
-rw-r--r--test/functional/viml/function_spec.lua11
-rw-r--r--test/functional/viml/lang_spec.lua22
-rw-r--r--test/helpers.lua60
-rw-r--r--test/unit/api/helpers.lua156
-rw-r--r--test/unit/api/private_helpers_spec.lua88
-rw-r--r--test/unit/buffer_spec.lua310
-rw-r--r--test/unit/eval/encode_spec.lua34
-rw-r--r--test/unit/eval/helpers.lua165
-rw-r--r--test/unit/helpers.lua18
-rw-r--r--test/unit/os/fileio_spec.lua365
-rw-r--r--test/unit/os/fs_spec.lua278
-rw-r--r--test/unit/os/shell_spec.lua4
-rw-r--r--test/unit/strings_spec.lua32
-rw-r--r--test/unit/tempfile_spec.lua2
234 files changed, 5660 insertions, 790 deletions
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index 0eefa25a13..cf8a83ad81 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -1,5 +1,5 @@
-- Sanity checks for buffer_* API calls via msgpack-rpc
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, buffer = helpers.clear, helpers.nvim, helpers.buffer
local curbuf, curwin, eq = helpers.curbuf, helpers.curwin, helpers.eq
local curbufmeths, ok = helpers.curbufmeths, helpers.ok
diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua
index 5b414fb559..d55b7b118a 100644
--- a/test/functional/api/menu_spec.lua
+++ b/test/functional/api/menu_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
diff --git a/test/functional/api/server_notifications_spec.lua b/test/functional/api/server_notifications_spec.lua
index 6791fbb4ba..88e8c60560 100644
--- a/test/functional/api/server_notifications_spec.lua
+++ b/test/functional/api/server_notifications_spec.lua
@@ -1,8 +1,9 @@
-- Tests for nvim notifications
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq, clear, eval, execute, nvim, next_message =
helpers.eq, helpers.clear, helpers.eval, helpers.execute, helpers.nvim,
helpers.next_message
+local meths = helpers.meths
describe('notify', function()
local channel
@@ -36,5 +37,33 @@ describe('notify', function()
eval('rpcnotify(0, "event1", 13, 14, 15)')
eq({'notification', 'event1', {13, 14, 15}}, next_message())
end)
+
+ it('does not crash for deeply nested variable', function()
+ meths.set_var('l', {})
+ local nest_level = 1000
+ meths.command(('call map(range(%u), "extend(g:, {\'l\': [g:l]})")'):format(nest_level - 1))
+ eval('rpcnotify('..channel..', "event", g:l)')
+ local msg = next_message()
+ eq('notification', msg[1])
+ eq('event', msg[2])
+ local act_ret = msg[3]
+ local act_nest_level = 0
+ while act_ret do
+ if type(act_ret) == 'table' then
+ local cur_act_ret = nil
+ for k, v in pairs(act_ret) do
+ eq(1, k)
+ cur_act_ret = v
+ end
+ if cur_act_ret then
+ act_nest_level = act_nest_level + 1
+ end
+ act_ret = cur_act_ret
+ else
+ eq(nil, act_ret)
+ end
+ end
+ eq(nest_level, act_nest_level)
+ end)
end)
end)
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 1b33275803..54095112fb 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -1,7 +1,7 @@
-- Tests for some server->client RPC scenarios. Note that unlike with
-- `rpcnotify`, to evaluate `rpcrequest` calls we need the client event loop to
-- be running.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, eval = helpers.clear, helpers.nvim, helpers.eval
local eq, neq, run, stop = helpers.eq, helpers.neq, helpers.run, helpers.stop
local nvim_prog = helpers.nvim_prog
diff --git a/test/functional/api/tabpage_spec.lua b/test/functional/api/tabpage_spec.lua
index c782107714..7b97c7f067 100644
--- a/test/functional/api/tabpage_spec.lua
+++ b/test/functional/api/tabpage_spec.lua
@@ -1,5 +1,5 @@
-- Sanity checks for tabpage_* API calls via msgpack-rpc
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, tabpage, curtab, eq, ok =
helpers.clear, helpers.nvim, helpers.tabpage, helpers.curtab, helpers.eq,
helpers.ok
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 20de6d0072..c4976ea06b 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,5 +1,5 @@
-- Sanity checks for vim_* API calls via msgpack-rpc
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local NIL = helpers.NIL
local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index 92a33b4cdb..d90323181c 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -1,5 +1,5 @@
-- Sanity checks for window_* API calls via msgpack-rpc
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq,
ok, feed, insert, eval = helpers.clear, helpers.nvim, helpers.curbuf,
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua
index 3c813abc2e..72aff58d73 100644
--- a/test/functional/autocmd/autocmd_spec.lua
+++ b/test/functional/autocmd/autocmd_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local command = helpers.command
diff --git a/test/functional/autocmd/tabclose_spec.lua b/test/functional/autocmd/tabclose_spec.lua
index bf609d1846..65182ad859 100644
--- a/test/functional/autocmd/tabclose_spec.lua
+++ b/test/functional/autocmd/tabclose_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('TabClosed', function()
diff --git a/test/functional/autocmd/tabnew_spec.lua b/test/functional/autocmd/tabnew_spec.lua
index aaf9db0a99..8c94dee49b 100644
--- a/test/functional/autocmd/tabnew_spec.lua
+++ b/test/functional/autocmd/tabnew_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local command = helpers.command
diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua
index 64b9a22f41..7044307399 100644
--- a/test/functional/autocmd/tabnewentered_spec.lua
+++ b/test/functional/autocmd/tabnewentered_spec.lua
@@ -1,22 +1,31 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('TabNewEntered', function()
- describe('au TabNewEntered', function()
- describe('with * as <afile>', function()
- it('matches when entering any new tab', function()
- clear()
- nvim('command', 'au! TabNewEntered * echom "tabnewentered:".tabpagenr().":".bufnr("")')
- eq("\ntabnewentered:2:2", nvim('command_output', 'tabnew'))
- eq("\n\"test.x2\" [New File]\ntabnewentered:3:3", nvim('command_output', 'tabnew test.x2'))
- end)
- end)
- describe('with FILE as <afile>', function()
- it('matches when opening a new tab for FILE', function()
- local tmp_path = nvim('eval', 'tempname()')
- nvim('command', 'au! TabNewEntered '..tmp_path..' echom "tabnewentered:match"')
- eq("\n\""..tmp_path.."\" [New File]\ntabnewentered:4:4\ntabnewentered:match", nvim('command_output', 'tabnew '..tmp_path))
- end)
- end)
+ describe('au TabNewEntered', function()
+ describe('with * as <afile>', function()
+ it('matches when entering any new tab', function()
+ clear()
+ nvim('command', 'au! TabNewEntered * echom "tabnewentered:".tabpagenr().":".bufnr("")')
+ eq("\ntabnewentered:2:2", nvim('command_output', 'tabnew'))
+ eq("\n\"test.x2\" [New File]\ntabnewentered:3:3", nvim('command_output', 'tabnew test.x2'))
+ end)
end)
+ describe('with FILE as <afile>', function()
+ it('matches when opening a new tab for FILE', function()
+ local tmp_path = nvim('eval', 'tempname()')
+ nvim('command', 'au! TabNewEntered '..tmp_path..' echom "tabnewentered:match"')
+ eq("\n\""..tmp_path.."\" [New File]\ntabnewentered:4:4\ntabnewentered:match", nvim('command_output', 'tabnew '..tmp_path))
+ end)
+ end)
+ describe('with CTRL-W T', function()
+ it('works when opening a new tab with CTRL-W T', function()
+ clear()
+ nvim('command', 'au! TabNewEntered * echom "entered"')
+ nvim('command', 'tabnew test.x2')
+ nvim('command', 'split')
+ eq('\nentered', nvim('command_output', 'execute "normal \\<C-W>T"'))
+ end)
+ end)
+ end)
end)
diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua
index 4de3f039c1..02ea0dbd95 100644
--- a/test/functional/autocmd/termclose_spec.lua
+++ b/test/functional/autocmd/termclose_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, execute, feed, nvim, nvim_dir = helpers.clear,
diff --git a/test/functional/autocmd/textyankpost_spec.lua b/test/functional/autocmd/textyankpost_spec.lua
index c26ceeaedc..bd5f1912c5 100644
--- a/test/functional/autocmd/textyankpost_spec.lua
+++ b/test/functional/autocmd/textyankpost_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
local feed, execute, expect, command = helpers.feed, helpers.execute, helpers.expect, helpers.command
local curbufmeths, funcs, neq = helpers.curbufmeths, helpers.funcs, helpers.neq
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index 898ec556a2..15977b9777 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -1,6 +1,6 @@
-- Test clipboard provider support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect, eq, eval = helpers.execute, helpers.expect, helpers.eq, helpers.eval
@@ -308,6 +308,7 @@ describe('clipboard usage', function()
end)
it('links the "+ and unnamed registers', function()
+ eq('+', eval('v:register'))
insert("one two")
feed('^"+dwdw"+P')
expect('two')
@@ -335,6 +336,7 @@ describe('clipboard usage', function()
eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['*']"))
-- unnamedplus takes predecence when pasting
+ eq('+', eval('v:register'))
execute("let g:test_clip['+'] = ['the plus','']")
execute("let g:test_clip['*'] = ['the star','']")
feed("p")
diff --git a/test/functional/job/job_spec.lua b/test/functional/core/job_spec.lua
index d21b9051e2..61ecdd1835 100644
--- a/test/functional/job/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -1,11 +1,10 @@
-
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, eq, eval, execute, feed, insert, neq, next_msg, nvim,
- nvim_dir, ok, source, write_file = helpers.clear,
+ nvim_dir, ok, source, write_file, mkdir, rmdir = helpers.clear,
helpers.eq, helpers.eval, helpers.execute, helpers.feed,
helpers.insert, helpers.neq, helpers.next_message, helpers.nvim,
helpers.nvim_dir, helpers.ok, helpers.source,
- helpers.write_file
+ helpers.write_file, helpers.mkdir, helpers.rmdir
local Screen = require('test.functional.ui.screen')
@@ -37,6 +36,32 @@ describe('jobs', function()
eq({'notification', 'exit', {0, 0}}, next_msg())
end)
+ it('changes to given / directory', function()
+ nvim('command', "let g:job_opts.cwd = '/'")
+ nvim('command', "let j = jobstart('pwd', g:job_opts)")
+ eq({'notification', 'stdout', {0, {'/', ''}}}, next_msg())
+ eq({'notification', 'exit', {0, 0}}, next_msg())
+ end)
+
+ it('changes to given `cwd` directory', function()
+ local dir = eval('resolve(tempname())')
+ mkdir(dir)
+ nvim('command', "let g:job_opts.cwd = '" .. dir .. "'")
+ nvim('command', "let j = jobstart('pwd', g:job_opts)")
+ eq({'notification', 'stdout', {0, {dir, ''}}}, next_msg())
+ eq({'notification', 'exit', {0, 0}}, next_msg())
+ rmdir(dir)
+ end)
+
+ it('fails to change to invalid `cwd`', function()
+ local dir = eval('resolve(tempname())."-bogus"')
+ local _, err = pcall(function()
+ nvim('command', "let g:job_opts.cwd = '" .. dir .. "'")
+ nvim('command', "let j = jobstart('pwd', g:job_opts)")
+ end)
+ ok(string.find(err, "E475: Invalid argument: expected valid directory$") ~= nil)
+ end)
+
it('returns 0 when it fails to start', function()
local status, rv = pcall(eval, "jobstart([])")
eq(false, status)
@@ -94,7 +119,7 @@ describe('jobs', function()
{0, {'a', '', 'c', '', '', '', 'b', '', ''}}}, next_msg())
end)
- it('can preserve nuls', function()
+ it('can preserve NULs', function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
nvim('command', 'call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])')
eq({'notification', 'stdout', {0, {'\n123\n', 'abc\nxyz\n', ''}}},
@@ -118,7 +143,7 @@ describe('jobs', function()
eq({'notification', 'exit', {0, 0}}, next_msg())
end)
- it("won't allow jobsend with a job that closed stdin", function()
+ it("disallows jobsend on a job that closed stdin", function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
nvim('command', 'call jobclose(j, "stdin")')
eq(false, pcall(function()
@@ -126,12 +151,12 @@ describe('jobs', function()
end))
end)
- it('will not allow jobsend/stop on a non-existent job', function()
+ it('disallows jobsend/stop on a non-existent job', function()
eq(false, pcall(eval, "jobsend(-1, 'lol')"))
eq(false, pcall(eval, "jobstop(-1)"))
end)
- it('will not allow jobstop twice on the same job', function()
+ it('disallows jobstop twice on the same job', function()
nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
neq(0, eval('j'))
eq(true, pcall(eval, "jobstop(j)"))
@@ -218,7 +243,7 @@ describe('jobs', function()
eq({'notification', 'exit', {45, 10}}, next_msg())
end)
- it('cant redefine callbacks being used by a job', function()
+ it('cannot redefine callbacks being used by a job', function()
local screen = Screen.new()
screen:attach()
local script = [[
@@ -441,3 +466,41 @@ describe('jobs', function()
end)
end)
end)
+
+describe("pty process teardown", function()
+ local screen
+ before_each(function()
+ clear()
+ screen = Screen.new(30, 6)
+ screen:attach()
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ end)
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("does not prevent/delay exit. #4798 #4900", function()
+ -- Use a nested nvim (in :term) to test without --headless.
+ execute(":terminal '"..helpers.nvim_prog
+ -- Use :term again in the _nested_ nvim to get a PTY process.
+ -- Use `sleep` to simulate a long-running child of the PTY.
+ .."' +terminal +'!(sleep 300 &)' +qa")
+
+ -- Exiting should terminate all descendants (PTY, its children, ...).
+ screen:expect([[
+ |
+ [Process exited 0] |
+ |
+ |
+ |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)
diff --git a/test/functional/dict_notifications_spec.lua b/test/functional/dict_notifications_spec.lua
index 2540929126..dc87312911 100644
--- a/test/functional/dict_notifications_spec.lua
+++ b/test/functional/dict_notifications_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, source = helpers.clear, helpers.nvim, helpers.source
local eq, next_msg = helpers.eq, helpers.next_message
local exc_exec = helpers.exc_exec
diff --git a/test/functional/eval/capture_spec.lua b/test/functional/eval/capture_spec.lua
new file mode 100644
index 0000000000..d9265f1b5b
--- /dev/null
+++ b/test/functional/eval/capture_spec.lua
@@ -0,0 +1,86 @@
+local helpers = require('test.functional.helpers')(after_each)
+local eq = helpers.eq
+local eval = helpers.eval
+local clear = helpers.clear
+local source = helpers.source
+local redir_exec = helpers.redir_exec
+local exc_exec = helpers.exc_exec
+local funcs = helpers.funcs
+local Screen = require('test.functional.ui.screen')
+local feed = helpers.feed
+
+describe('capture()', function()
+ before_each(clear)
+
+ it('returns the same result with :redir', function()
+ eq(redir_exec('messages'), funcs.capture('messages'))
+ end)
+
+ it('returns the output of the commands if the argument is List', function()
+ eq("foobar", funcs.capture({'echon "foo"', 'echon "bar"'}))
+ eq("\nfoo\nbar", funcs.capture({'echo "foo"', 'echo "bar"'}))
+ end)
+
+ it('supports the nested redirection', function()
+ source([[
+ function! g:Foo()
+ let a = ''
+ redir => a
+ silent echon "foo"
+ redir END
+ return a
+ endfunction
+ function! g:Bar()
+ let a = ''
+ redir => a
+ call g:Foo()
+ redir END
+ return a
+ endfunction
+ ]])
+ eq('foo', funcs.capture('call g:Bar()'))
+
+ eq('42', funcs.capture([[echon capture("echon capture('echon 42')")]]))
+ end)
+
+ it('returns the transformed string', function()
+ eq('^A', funcs.capture('echon "\\<C-a>"'))
+ end)
+
+ it('returns the empty string if the argument list is empty', function()
+ eq('', funcs.capture({}))
+ eq(0, exc_exec('let g:ret = capture(v:_null_list)'))
+ eq('', eval('g:ret'))
+ end)
+
+ it('returns the errors', function()
+ local ret
+ ret = exc_exec('call capture(0.0)')
+ eq('Vim(call):E806: using Float as a String', ret)
+ ret = exc_exec('call capture(v:_null_dict)')
+ eq('Vim(call):E731: using Dictionary as a String', ret)
+ ret = exc_exec('call capture(function("tr"))')
+ eq('Vim(call):E729: using Funcref as a String', ret)
+ ret = exc_exec('call capture(["echo 42", 0.0, "echo 44"])')
+ eq('Vim(call):E806: using Float as a String', ret)
+ ret = exc_exec('call capture(["echo 42", v:_null_dict, "echo 44"])')
+ eq('Vim(call):E731: using Dictionary as a String', ret)
+ ret = exc_exec('call capture(["echo 42", function("tr"), "echo 44"])')
+ eq('Vim(call):E729: using Funcref as a String', ret)
+ end)
+
+ it('silences command run inside', function()
+ local screen = Screen.new(20, 5)
+ screen:attach()
+ screen:set_default_attr_ignore({{bold=true, foreground=255}})
+ feed(':let g:mes = capture("echon 42")<CR>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ eq('42', eval('g:mes'))
+ end)
+end)
diff --git a/test/functional/eval/glob_spec.lua b/test/functional/eval/glob_spec.lua
index c6bba46424..599b3dcdc3 100644
--- a/test/functional/eval/glob_spec.lua
+++ b/test/functional/eval/glob_spec.lua
@@ -1,5 +1,5 @@
local lfs = require('lfs')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, eval, eq = helpers.clear, helpers.execute, helpers.eval, helpers.eq
before_each(function()
diff --git a/test/functional/eval/json_functions_spec.lua b/test/functional/eval/json_functions_spec.lua
index b32688a9d2..159d775ff1 100644
--- a/test/functional/eval/json_functions_spec.lua
+++ b/test/functional/eval/json_functions_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local funcs = helpers.funcs
local meths = helpers.meths
@@ -10,8 +10,8 @@ local redir_exec = helpers.redir_exec
local NIL = helpers.NIL
describe('json_decode() function', function()
- local restart = function(cmd)
- clear(cmd)
+ local restart = function(...)
+ clear(...)
execute('language C')
execute([[
function Eq(exp, act)
@@ -490,13 +490,13 @@ describe('json_decode() function', function()
end)
it('converts strings to latin1 when &encoding is latin1', function()
- restart('set encoding=latin1')
+ restart('--cmd', 'set encoding=latin1')
eq('\171', funcs.json_decode('"\\u00AB"'))
sp_decode_eq({_TYPE='string', _VAL={'\n\171\n'}}, '"\\u0000\\u00AB\\u0000"')
end)
it('fails to convert string to latin1 if it is impossible', function()
- restart('set encoding=latin1')
+ restart('--cmd', 'set encoding=latin1')
eq('Vim(call):E474: Failed to convert string "ꯍ" from UTF-8',
exc_exec('call json_decode(\'"\\uABCD"\')'))
end)
@@ -532,7 +532,7 @@ describe('json_decode() function', function()
-- When &encoding is latin1 string "«" is U+00C2 U+00AB U+00C2: «Â. So if
-- '"«"' was parsed as latin1 json_decode would return three characters, and
-- only one U+00AB when this string is parsed as latin1.
- restart('set encoding=latin1')
+ restart('--cmd', 'set encoding=latin1')
eq(('%c'):format(0xAB), funcs.json_decode('"«"'))
end)
@@ -763,7 +763,7 @@ describe('json_encode() function', function()
end)
it('converts strings from latin1 when &encoding is latin1', function()
- clear('set encoding=latin1')
+ clear('--cmd', 'set encoding=latin1')
eq('"\\u00AB"', funcs.json_encode('\171'))
eq('"\\u0000\\u00AB\\u0000"', eval('json_encode({"_TYPE": v:msgpack_types.string, "_VAL": ["\\n\171\\n"]})'))
end)
diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua
index 9e501353a5..5b87b05652 100644
--- a/test/functional/eval/msgpack_functions_spec.lua
+++ b/test/functional/eval/msgpack_functions_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local funcs = helpers.funcs
local eval, eq = helpers.eval, helpers.eq
diff --git a/test/functional/eval/operators_spec.lua b/test/functional/eval/operators_spec.lua
index bc9a17935c..4d07bc1b05 100644
--- a/test/functional/eval/operators_spec.lua
+++ b/test/functional/eval/operators_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local eval = helpers.eval
local clear = helpers.clear
diff --git a/test/functional/eval/printf_spec.lua b/test/functional/eval/printf_spec.lua
index 6180f4156a..c84290ceef 100644
--- a/test/functional/eval/printf_spec.lua
+++ b/test/functional/eval/printf_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local funcs = helpers.funcs
diff --git a/test/functional/eval/reltime_spec.lua b/test/functional/eval/reltime_spec.lua
index da55a3fac3..0b19d372ec 100644
--- a/test/functional/eval/reltime_spec.lua
+++ b/test/functional/eval/reltime_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok
local neq, execute, funcs = helpers.neq, helpers.execute, helpers.funcs
local reltime, reltimestr, reltimefloat = funcs.reltime, funcs.reltimestr, funcs.reltimefloat
diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua
index 7f53522c08..0fd55ce2f9 100644
--- a/test/functional/eval/server_spec.lua
+++ b/test/functional/eval/server_spec.lua
@@ -1,5 +1,5 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim, eq, neq, eval = helpers.nvim, helpers.eq, helpers.neq, helpers.eval
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
local os_name = helpers.os_name
diff --git a/test/functional/eval/special_vars_spec.lua b/test/functional/eval/special_vars_spec.lua
index 2526483830..4c5d63ce23 100644
--- a/test/functional/eval/special_vars_spec.lua
+++ b/test/functional/eval/special_vars_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local exc_exec = helpers.exc_exec
local execute = helpers.execute
local funcs = helpers.funcs
diff --git a/test/functional/eval/string_spec.lua b/test/functional/eval/string_spec.lua
index abda2c59cb..9e2dc4e111 100644
--- a/test/functional/eval/string_spec.lua
+++ b/test/functional/eval/string_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local command = helpers.command
diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua
new file mode 100644
index 0000000000..2f83edb9e4
--- /dev/null
+++ b/test/functional/eval/timer_spec.lua
@@ -0,0 +1,144 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local ok, feed, eq, eval = helpers.ok, helpers.feed, helpers.eq, helpers.eval
+local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
+local clear, execute, funcs = helpers.clear, helpers.execute, helpers.funcs
+
+describe('timers', function()
+ before_each(function()
+ clear()
+ source([[
+ let g:val = 0
+ func MyHandler(timer)
+ let g:val += 1
+ endfunc
+ ]])
+ end)
+
+ it('works one-shot', function()
+ execute("call timer_start(50, 'MyHandler')")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 200)
+ eq(1,eval("g:val"))
+ end)
+
+ it('works one-shot when repeat=0', function()
+ execute("call timer_start(50, 'MyHandler', {'repeat': 0})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 200)
+ eq(1,eval("g:val"))
+ end)
+
+
+ it('works with repeat two', function()
+ execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(2,eval("g:val"))
+ end)
+
+ it('are triggered during sleep', function()
+ execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ nvim_async("command", "sleep 10")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(2,eval("g:val"))
+ end)
+
+ it('works with zero timeout', function()
+ -- timer_start does still not invoke the callback immediately
+ eq(0,eval("[timer_start(0, 'MyHandler', {'repeat': 1000}), g:val][1]"))
+ run(nil, nil, nil, 300)
+ eq(1000,eval("g:val"))
+ end)
+
+ it('can be started during sleep', function()
+ nvim_async("command", "sleep 10")
+ -- this also tests that remote requests works during sleep
+ eval("timer_start(50, 'MyHandler', {'repeat': 2})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(2,eval("g:val"))
+ end)
+
+ it('are paused when event processing is disabled', function()
+ -- this is not the intended behavior, but at least there will
+ -- not be a burst of queued up callbacks
+ execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ run(nil, nil, nil, 100)
+ local count = eval("g:val")
+ nvim_async("command", "let g:c = getchar()")
+ run(nil, nil, nil, 300)
+ feed("c")
+ local diff = eval("g:val") - count
+ ok(0 <= diff and diff <= 2)
+ eq(99, eval("g:c"))
+ end)
+
+ it('can be stopped', function()
+ local t = eval("timer_start(50, 'MyHandler', {'repeat': -1})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ funcs.timer_stop(t)
+ local count = eval("g:val")
+ run(nil, nil, nil, 300)
+ local count2 = eval("g:val")
+ ok(4 <= count and count <= 7)
+ -- when count is eval:ed after timer_stop this should be non-racy
+ eq(count, count2)
+ end)
+
+ it('can be stopped from the handler', function()
+ source([[
+ func! MyHandler(timer)
+ let g:val += 1
+ if g:val == 3
+ call timer_stop(a:timer)
+ " check double stop is ignored
+ call timer_stop(a:timer)
+ endif
+ endfunc
+ ]])
+ execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(3,eval("g:val"))
+ end)
+
+ it('can have two timers', function()
+ source([[
+ let g:val2 = 0
+ func! MyHandler2(timer)
+ let g:val2 += 1
+ endfunc
+ ]])
+ execute("call timer_start(50, 'MyHandler', {'repeat': 3})")
+ execute("call timer_start(100, 'MyHandler2', {'repeat': 2})")
+ run(nil, nil, nil, 300)
+ eq(3,eval("g:val"))
+ eq(2,eval("g:val2"))
+ end)
+
+ it("doesn't mess up the cmdline", function()
+ local screen = Screen.new(40, 6)
+ screen:attach()
+ screen:set_default_attr_ignore({{bold=true, foreground=Screen.colors.Blue}})
+ source([[
+ func! MyHandler(timer)
+ echo "evil"
+ endfunc
+ ]])
+ execute("call timer_start(100, 'MyHandler', {'repeat': 1})")
+ feed(":good")
+ screen:sleep(200)
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ :good^ |
+ ]])
+ end)
+
+end)
diff --git a/test/functional/eval/vvar_event_spec.lua b/test/functional/eval/vvar_event_spec.lua
index bbac86524f..eec8aa917a 100644
--- a/test/functional/eval/vvar_event_spec.lua
+++ b/test/functional/eval/vvar_event_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
local command = helpers.command
describe('v:event', function()
diff --git a/test/functional/ex_cmds/append_spec.lua b/test/functional/ex_cmds/append_spec.lua
index 2d5ab8e8c8..3e326d9460 100644
--- a/test/functional/ex_cmds/append_spec.lua
+++ b/test/functional/ex_cmds/append_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local feed = helpers.feed
diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua
index 69467632a4..fcd826c25d 100644
--- a/test/functional/ex_cmds/cd_spec.lua
+++ b/test/functional/ex_cmds/cd_spec.lua
@@ -1,49 +1,145 @@
-- Specs for :cd, :tcd, :lcd and getcwd()
-local helpers = require('test.functional.helpers')
-local execute, eq, clear, eval, exc_exec =
- helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.exc_exec
local lfs = require('lfs')
+local helpers = require('test.functional.helpers')(after_each)
+
+local eq = helpers.eq
+local call = helpers.call
+local clear = helpers.clear
+local execute = helpers.execute
+local exc_exec = helpers.exc_exec
-- These directories will be created for testing
local directories = {
- 'Xtest-functional-ex_cmds-cd_spec.1', -- Tab
- 'Xtest-functional-ex_cmds-cd_spec.2', -- Window
- 'Xtest-functional-ex_cmds-cd_spec.3', -- New global
+ tab = 'Xtest-functional-ex_cmds-cd_spec.tab', -- Tab
+ window = 'Xtest-functional-ex_cmds-cd_spec.window', -- Window
+ global = 'Xtest-functional-ex_cmds-cd_spec.global', -- New global
}
-- Shorthand writing to get the current working directory
-local cwd = function() return eval('getcwd( )') end -- effective working dir
-local wcwd = function() return eval('getcwd( 0 )') end -- window dir
-local tcwd = function() return eval('getcwd(-1, 0)') end -- tab dir
---local gcwd = function() return eval('getcwd(-1, -1)') end -- global dir
+local cwd = function(...) return call('getcwd', ...) end -- effective working dir
+local wcwd = function() return cwd(0) end -- window dir
+local tcwd = function() return cwd(-1, 0) end -- tab dir
-- Same, except these tell us if there is a working directory at all
---local lwd = function() return eval('haslocaldir( )') end -- effective working dir
-local wlwd = function() return eval('haslocaldir( 0 )') end -- window dir
-local tlwd = function() return eval('haslocaldir(-1, 0)') end -- tab dir
+local lwd = function(...) return call('haslocaldir', ...) end -- effective working dir
+local wlwd = function() return lwd(0) end -- window dir
+local tlwd = function() return lwd(-1, 0) end -- tab dir
--local glwd = function() return eval('haslocaldir(-1, -1)') end -- global dir
-- Test both the `cd` and `chdir` variants
for _, cmd in ipairs {'cd', 'chdir'} do
- describe(':*' .. cmd, function()
+ describe(':' .. cmd, function()
before_each(function()
clear()
- for _, d in ipairs(directories) do
+ for _, d in pairs(directories) do
lfs.mkdir(d)
end
+ directories.start = cwd()
end)
after_each(function()
- for _, d in ipairs(directories) do
+ for _, d in pairs(directories) do
lfs.rmdir(d)
end
end)
- it('works', function()
- -- Store the initial working directory
- local globalDir = cwd()
+ describe('using explicit scope', function()
+ it('for window', function()
+ local globalDir = directories.start
+ local globalwin = call('winnr')
+ local tabnr = call('tabpagenr')
+
+ -- Everything matches globalDir to start
+ eq(globalDir, cwd(globalwin))
+ eq(globalDir, cwd(globalwin, tabnr))
+ eq(0, lwd(globalwin))
+ eq(0, lwd(globalwin, tabnr))
+
+ execute('bot split')
+ local localwin = call('winnr')
+ -- Initial window is still using globalDir
+ eq(globalDir, cwd(localwin))
+ eq(globalDir, cwd(localwin, tabnr))
+ eq(0, lwd(globalwin))
+ eq(0, lwd(globalwin, tabnr))
+
+ execute('silent l' .. cmd .. ' ' .. directories.window)
+ -- From window with local dir, the original window
+ -- is still reporting the global dir
+ eq(globalDir, cwd(globalwin))
+ eq(globalDir, cwd(globalwin, tabnr))
+ eq(0, lwd(globalwin))
+ eq(0, lwd(globalwin, tabnr))
+
+ -- Window with local dir reports as such
+ eq(globalDir .. '/' .. directories.window, cwd(localwin))
+ eq(globalDir .. '/' .. directories.window, cwd(localwin, tabnr))
+ eq(1, lwd(localwin))
+ eq(1, lwd(localwin, tabnr))
+
+ execute('tabnew')
+ -- From new tab page, original window reports global dir
+ eq(globalDir, cwd(globalwin, tabnr))
+ eq(0, lwd(globalwin, tabnr))
+
+ -- From new tab page, local window reports as such
+ eq(globalDir .. '/' .. directories.window, cwd(localwin, tabnr))
+ eq(1, lwd(localwin, tabnr))
+ end)
+
+ it('for tab page', function()
+ local globalDir = directories.start
+ local globaltab = call('tabpagenr')
+
+ -- Everything matches globalDir to start
+ eq(globalDir, cwd(-1, 0))
+ eq(globalDir, cwd(-1, globaltab))
+ eq(0, lwd(-1, 0))
+ eq(0, lwd(-1, globaltab))
+
+ execute('tabnew')
+ execute('silent t' .. cmd .. ' ' .. directories.tab)
+ local localtab = call('tabpagenr')
+
+ -- From local tab page, original tab reports globalDir
+ eq(globalDir, cwd(-1, globaltab))
+ eq(0, lwd(-1, globaltab))
+
+ -- new tab reports local
+ eq(globalDir .. '/' .. directories.tab, cwd(-1, 0))
+ eq(globalDir .. '/' .. directories.tab, cwd(-1, localtab))
+ eq(1, lwd(-1, 0))
+ eq(1, lwd(-1, localtab))
+
+ execute('tabnext')
+ -- From original tab page, local reports as such
+ eq(globalDir .. '/' .. directories.tab, cwd(-1, localtab))
+ eq(1, lwd(-1, localtab))
+ end)
+ end)
+ describe('getcwd(-1, -1)', function()
+ it('works', function()
+ eq(directories.start, cwd(-1, -1))
+ eq(0, lwd(-1, -1))
+ end)
+
+ it('works with tab-local pwd', function()
+ execute('silent t' .. cmd .. ' ' .. directories.tab)
+ eq(directories.start, cwd(-1, -1))
+ eq(0, lwd(-1, -1))
+ end)
+
+ it('works with window-local pwd', function()
+ execute('silent l' .. cmd .. ' ' .. directories.window)
+ eq(directories.start, cwd(-1, -1))
+ eq(0, lwd(-1, -1))
+ end)
+ end)
+
+ it('works', function()
+ local globalDir = directories.start
-- Create a new tab first and verify that is has the same working dir
execute('tabnew')
eq(globalDir, cwd())
@@ -53,8 +149,8 @@ for _, cmd in ipairs {'cd', 'chdir'} do
eq(0, wlwd())
-- Change tab-local working directory and verify it is different
- execute('silent t' .. cmd .. ' ' .. directories[1])
- eq(globalDir .. '/' .. directories[1], cwd())
+ execute('silent t' .. cmd .. ' ' .. directories.tab)
+ eq(globalDir .. '/' .. directories.tab, cwd())
eq(cwd(), tcwd()) -- working directory maches tab directory
eq(1, tlwd())
eq(cwd(), wcwd()) -- still no window-directory
@@ -64,16 +160,16 @@ for _, cmd in ipairs {'cd', 'chdir'} do
execute('new')
eq(1, tlwd()) -- Still tab-local working directory
eq(0, wlwd()) -- Still no window-local working directory
- eq(globalDir .. '/' .. directories[1], cwd())
- execute('silent l' .. cmd .. ' ../' .. directories[2])
- eq(globalDir .. '/' .. directories[2], cwd())
- eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(globalDir .. '/' .. directories.tab, cwd())
+ execute('silent l' .. cmd .. ' ../' .. directories.window)
+ eq(globalDir .. '/' .. directories.window, cwd())
+ eq(globalDir .. '/' .. directories.tab, tcwd())
eq(1, wlwd())
-- Verify the first window still has the tab local directory
execute('wincmd w')
- eq(globalDir .. '/' .. directories[1], cwd())
- eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(globalDir .. '/' .. directories.tab, cwd())
+ eq(globalDir .. '/' .. directories.tab, tcwd())
eq(0, wlwd()) -- No window-local directory
-- Change back to initial tab and verify working directory has stayed
@@ -83,11 +179,11 @@ for _, cmd in ipairs {'cd', 'chdir'} do
eq(0, wlwd())
-- Verify global changes don't affect local ones
- execute('silent ' .. cmd .. ' ' .. directories[3])
- eq(globalDir .. '/' .. directories[3], cwd())
+ execute('silent ' .. cmd .. ' ' .. directories.global)
+ eq(globalDir .. '/' .. directories.global, cwd())
execute('tabnext')
- eq(globalDir .. '/' .. directories[1], cwd())
- eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(globalDir .. '/' .. directories.tab, cwd())
+ eq(globalDir .. '/' .. directories.tab, tcwd())
eq(0, wlwd()) -- Still no window-local directory in this window
-- Unless the global change happened in a tab with local directory
@@ -101,9 +197,9 @@ for _, cmd in ipairs {'cd', 'chdir'} do
-- But not in a window with its own local directory
execute('tabnext | wincmd w')
- eq(globalDir .. '/' .. directories[2], cwd() )
+ eq(globalDir .. '/' .. directories.window, cwd() )
eq(0 , tlwd())
- eq(globalDir .. '/' .. directories[2], wcwd())
+ eq(globalDir .. '/' .. directories.window, wcwd())
end)
end)
end
diff --git a/test/functional/ex_cmds/drop_spec.lua b/test/functional/ex_cmds/drop_spec.lua
new file mode 100644
index 0000000000..16b194dd7d
--- /dev/null
+++ b/test/functional/ex_cmds/drop_spec.lua
@@ -0,0 +1,80 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+
+describe(":drop", function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(35, 10)
+ screen:attach()
+ screen:set_default_attr_ignore({{bold=true, foreground=Screen.colors.Blue}})
+ screen:set_default_attr_ids({
+ [1] = {bold = true, reverse = true},
+ [2] = {reverse = true},
+ [3] = {bold = true},
+ })
+ execute("set laststatus=2")
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("works like :e when called with only one window open", function()
+ execute("drop tmp1.vim")
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ {1:tmp1.vim }|
+ "tmp1.vim" [New File] |
+ ]])
+ end)
+
+ it("switches to an open window showing the buffer", function()
+ execute("edit tmp1")
+ execute("vsplit")
+ execute("edit tmp2")
+ execute("drop tmp1")
+ screen:expect([[
+ {2:|}^ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ {2:tmp2 }{1:tmp1 }|
+ :drop tmp1 |
+ ]])
+ end)
+
+ it("splits off a new window when a buffer can't be abandoned", function()
+ execute("edit tmp1")
+ execute("vsplit")
+ execute("edit tmp2")
+ feed("iABC<esc>")
+ execute("drop tmp3")
+ screen:expect([[
+ ^ {2:|} |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ {1:tmp3 }{2:|}~ |
+ ABC {2:|}~ |
+ ~ {2:|}~ |
+ ~ {2:|}~ |
+ {2:tmp2 [+] tmp1 }|
+ "tmp3" [New File] |
+ ]])
+ end)
+
+end)
diff --git a/test/functional/ex_cmds/encoding_spec.lua b/test/functional/ex_cmds/encoding_spec.lua
index 6d402b7974..e2b3e7e31d 100644
--- a/test/functional/ex_cmds/encoding_spec.lua
+++ b/test/functional/ex_cmds/encoding_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, feed = helpers.clear, helpers.execute, helpers.feed
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
@@ -22,7 +22,7 @@ describe('&encoding', function()
end)
it('can be changed before startup', function()
- clear('set enc=latin1')
+ clear('--cmd', 'set enc=latin1')
execute('set encoding=utf-8')
-- error message expected
feed('<cr>')
@@ -32,7 +32,7 @@ describe('&encoding', function()
it('is not changed by `set all&`', function()
-- we need to set &encoding to something non-default. Use 'latin1'
- clear('set enc=latin1')
+ clear('--cmd', 'set enc=latin1')
execute('set all&')
eq('latin1', eval('&encoding'))
eq(4, eval('strwidth("Bär")'))
diff --git a/test/functional/ex_cmds/grep_spec.lua b/test/functional/ex_cmds/grep_spec.lua
index f3ff0a3817..13f88b7e03 100644
--- a/test/functional/ex_cmds/grep_spec.lua
+++ b/test/functional/ex_cmds/grep_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, feed, ok, eval =
helpers.clear, helpers.execute, helpers.feed, helpers.ok, helpers.eval
diff --git a/test/functional/ex_cmds/menu_spec.lua b/test/functional/ex_cmds/menu_spec.lua
index f5fd30465d..52df9e1592 100644
--- a/test/functional/ex_cmds/menu_spec.lua
+++ b/test/functional/ex_cmds/menu_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, nvim = helpers.clear, helpers.execute, helpers.nvim
local expect, feed, command = helpers.expect, helpers.feed, helpers.command
local eq, eval = helpers.eq, helpers.eval
@@ -39,7 +39,7 @@ describe(':emenu', function()
end)
it('executes correct bindings in command mode', function()
- feed('ithis is a sentence<esc>^"+yiwo<esc>')
+ feed('ithis is a sentence<esc>^yiwo<esc>')
-- Invoke "Edit.Paste" in normal-mode.
nvim('command', 'emenu Edit.Paste')
diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua
index 5bba1a0e7c..b7109f2f98 100644
--- a/test/functional/ex_cmds/oldfiles_spec.lua
+++ b/test/functional/ex_cmds/oldfiles_spec.lua
@@ -1,5 +1,5 @@
local Screen = require('test.functional.ui.screen')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local buf, eq, execute = helpers.curbufmeths, helpers.eq, helpers.execute
local feed, nvim_prog, wait = helpers.feed, helpers.nvim_prog, helpers.wait
diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua
index 744b22621f..d390806679 100644
--- a/test/functional/ex_cmds/profile_spec.lua
+++ b/test/functional/ex_cmds/profile_spec.lua
@@ -1,7 +1,7 @@
require('os')
local lfs = require('lfs')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eval = helpers.eval
local command = helpers.command
local eq, neq = helpers.eq, helpers.neq
diff --git a/test/functional/ex_cmds/quit_spec.lua b/test/functional/ex_cmds/quit_spec.lua
index a8156228d3..016a607743 100644
--- a/test/functional/ex_cmds/quit_spec.lua
+++ b/test/functional/ex_cmds/quit_spec.lua
@@ -1,9 +1,9 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
describe(':qa', function()
before_each(function()
- clear('qa')
+ clear('--cmd', 'qa')
end)
it('verify #3334', function()
diff --git a/test/functional/ex_cmds/recover_spec.lua b/test/functional/ex_cmds/recover_spec.lua
index e1d01f6896..60673d25ef 100644
--- a/test/functional/ex_cmds/recover_spec.lua
+++ b/test/functional/ex_cmds/recover_spec.lua
@@ -1,6 +1,6 @@
-- Tests for :recover
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local lfs = require('lfs')
local execute, eq, clear, eval, feed, expect, source =
helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.feed,
diff --git a/test/functional/ex_cmds/sign_spec.lua b/test/functional/ex_cmds/sign_spec.lua
index c50704504d..b37e6e8563 100644
--- a/test/functional/ex_cmds/sign_spec.lua
+++ b/test/functional/ex_cmds/sign_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('sign', function()
diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua
index d90b297ca8..b38ae29f7d 100644
--- a/test/functional/ex_cmds/write_spec.lua
+++ b/test/functional/ex_cmds/write_spec.lua
@@ -1,15 +1,18 @@
-- Specs for :write
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq, eval, clear, write_file, execute, source =
helpers.eq, helpers.eval, helpers.clear, helpers.write_file,
helpers.execute, helpers.source
describe(':write', function()
- it('&backupcopy=auto preserves symlinks', function()
- clear('set backupcopy=auto')
+ after_each(function()
os.remove('test_bkc_file.txt')
os.remove('test_bkc_link.txt')
+ end)
+
+ it('&backupcopy=auto preserves symlinks', function()
+ clear('--cmd', 'set backupcopy=auto')
write_file('test_bkc_file.txt', 'content0')
execute("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
source([[
@@ -22,9 +25,7 @@ describe(':write', function()
end)
it('&backupcopy=no replaces symlink with new file', function()
- clear('set backupcopy=no')
- os.remove('test_bkc_file.txt')
- os.remove('test_bkc_link.txt')
+ clear('--cmd', 'set backupcopy=no')
write_file('test_bkc_file.txt', 'content0')
execute("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
source([[
diff --git a/test/functional/ex_cmds/wundo_spec.lua b/test/functional/ex_cmds/wundo_spec.lua
index 969dfea3d9..e1216fa5d4 100644
--- a/test/functional/ex_cmds/wundo_spec.lua
+++ b/test/functional/ex_cmds/wundo_spec.lua
@@ -1,6 +1,6 @@
-- Specs for :wundo and underlying functions
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local execute, clear, eval, feed, spawn, nvim_prog, set_session =
helpers.execute, helpers.clear, helpers.eval, helpers.feed, helpers.spawn,
helpers.nvim_prog, helpers.set_session
diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua
index 21f14be62c..37f45da2d4 100644
--- a/test/functional/ex_cmds/wviminfo_spec.lua
+++ b/test/functional/ex_cmds/wviminfo_spec.lua
@@ -1,4 +1,5 @@
-local helpers, lfs = require('test.functional.helpers'), require('lfs')
+local helpers = require('test.functional.helpers')(after_each)
+local lfs = require('lfs')
local execute, eq, neq, spawn, nvim_prog, set_session, wait, write_file
= helpers.execute, helpers.eq, helpers.neq, helpers.spawn,
helpers.nvim_prog, helpers.set_session, helpers.wait, helpers.write_file
diff --git a/test/functional/ex_getln/history_spec.lua b/test/functional/ex_getln/history_spec.lua
index 532c81dab9..c1d2ffda53 100644
--- a/test/functional/ex_getln/history_spec.lua
+++ b/test/functional/ex_getln/history_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, meths, funcs, eq =
helpers.clear, helpers.meths, helpers.funcs, helpers.eq
diff --git a/test/functional/fixtures/autoload/provider/clipboard.vim b/test/functional/fixtures/autoload/provider/clipboard.vim
index 0935ea45ff..411e095c71 100644
--- a/test/functional/fixtures/autoload/provider/clipboard.vim
+++ b/test/functional/fixtures/autoload/provider/clipboard.vim
@@ -9,13 +9,12 @@ function! s:methods.get(reg)
if g:cliperror
return 0
end
- let reg = a:reg == '"' ? '+' : a:reg
if g:cliplossy
" behave like pure text clipboard
- return g:test_clip[reg][0]
+ return g:test_clip[a:reg][0]
else
" behave like VIMENC clipboard
- return g:test_clip[reg]
+ return g:test_clip[a:reg]
end
endfunction
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 37b7bf664c..02109d0889 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -1,8 +1,13 @@
require('coxpcall')
local lfs = require('lfs')
-local assert = require('luassert')
local ChildProcessStream = require('nvim.child_process_stream')
local Session = require('nvim.session')
+local global_helpers = require('test.helpers')
+
+local check_logs = global_helpers.check_logs
+local neq = global_helpers.neq
+local eq = global_helpers.eq
+local ok = global_helpers.ok
local nvim_prog = os.getenv('NVIM_PROG') or 'build/bin/nvim'
local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N',
@@ -30,7 +35,7 @@ if os.getenv('VALGRIND') then
prepend_argv = {'valgrind', '-q', '--tool=memcheck',
'--leak-check=yes', '--track-origins=yes',
'--show-possibly-lost=no',
- '--suppressions=.valgrind.supp',
+ '--suppressions=src/.valgrind.supp',
'--log-file='..log_file}
if os.getenv('GDB') then
table.insert(prepend_argv, '--vgdb=yes')
@@ -216,11 +221,10 @@ local function spawn(argv, merge)
return Session.new(child_stream)
end
-local function clear(extra_cmd)
+local function clear(...)
local args = {unpack(nvim_argv)}
- if extra_cmd ~= nil then
- table.insert(args, '--cmd')
- table.insert(args, extra_cmd)
+ for _, arg in ipairs({...}) do
+ table.insert(args, arg)
end
set_session(spawn(args))
end
@@ -267,18 +271,6 @@ local function source(code)
return tmpname
end
-local function eq(expected, actual)
- return assert.are.same(expected, actual)
-end
-
-local function neq(expected, actual)
- return assert.are_not.same(expected, actual)
-end
-
-local function ok(expr)
- assert.is_true(expr)
-end
-
local function nvim(method, ...)
return request('vim_'..method, ...)
end
@@ -308,14 +300,18 @@ local function curbuf(method, ...)
end
local function wait()
+ -- Execute 'vim_eval' (a deferred function) to block
+ -- until all pending input is processed.
session:request('vim_eval', '1')
end
+-- sleeps the test runner (_not_ the nvim instance)
+local function sleep(timeout)
+ run(nil, nil, nil, timeout)
+end
+
local function curbuf_contents()
- -- Before inspecting the buffer, execute 'vim_eval' to wait until all
- -- previously sent keys are processed(vim_eval is a deferred function, and
- -- only processed after all input)
- wait()
+ wait() -- Before inspecting the buffer, process all input.
return table.concat(curbuf('get_lines', 0, -1, true), '\n')
end
@@ -345,10 +341,18 @@ local function rmdir(path)
end
for file in lfs.dir(path) do
if file ~= '.' and file ~= '..' then
- local ret, err = os.remove(path..'/'..file)
- if not ret then
- error('os.remove: '..err)
- return nil
+ local abspath = path..'/'..file
+ if lfs.attributes(abspath, 'mode') == 'directory' then
+ local ret = rmdir(abspath) -- recurse
+ if not ret then
+ return nil
+ end
+ else
+ local ret, err = os.remove(abspath)
+ if not ret then
+ error('os.remove: '..err)
+ return nil
+ end
end
end
end
@@ -404,54 +408,60 @@ local curbufmeths = create_callindex(curbuf)
local curwinmeths = create_callindex(curwin)
local curtabmeths = create_callindex(curtab)
-return {
- prepend_argv = prepend_argv,
- clear = clear,
- spawn = spawn,
- dedent = dedent,
- source = source,
- rawfeed = rawfeed,
- insert = insert,
- feed = feed,
- execute = execute,
- eval = nvim_eval,
- call = nvim_call,
- command = nvim_command,
- request = request,
- next_message = next_message,
- run = run,
- stop = stop,
- eq = eq,
- neq = neq,
- expect = expect,
- ok = ok,
- nvim = nvim,
- nvim_async = nvim_async,
- nvim_prog = nvim_prog,
- nvim_dir = nvim_dir,
- buffer = buffer,
- window = window,
- tabpage = tabpage,
- curbuf = curbuf,
- curwin = curwin,
- curtab = curtab,
- curbuf_contents = curbuf_contents,
- wait = wait,
- set_session = set_session,
- write_file = write_file,
- os_name = os_name,
- rmdir = rmdir,
- mkdir = lfs.mkdir,
- exc_exec = exc_exec,
- redir_exec = redir_exec,
- merge_args = merge_args,
- funcs = funcs,
- meths = meths,
- bufmeths = bufmeths,
- winmeths = winmeths,
- tabmeths = tabmeths,
- curbufmeths = curbufmeths,
- curwinmeths = curwinmeths,
- curtabmeths = curtabmeths,
- NIL = mpack.NIL
-}
+return function(after_each)
+ if after_each then
+ after_each(check_logs)
+ end
+ return {
+ prepend_argv = prepend_argv,
+ clear = clear,
+ spawn = spawn,
+ dedent = dedent,
+ source = source,
+ rawfeed = rawfeed,
+ insert = insert,
+ feed = feed,
+ execute = execute,
+ eval = nvim_eval,
+ call = nvim_call,
+ command = nvim_command,
+ request = request,
+ next_message = next_message,
+ run = run,
+ stop = stop,
+ eq = eq,
+ neq = neq,
+ expect = expect,
+ ok = ok,
+ nvim = nvim,
+ nvim_async = nvim_async,
+ nvim_prog = nvim_prog,
+ nvim_dir = nvim_dir,
+ buffer = buffer,
+ window = window,
+ tabpage = tabpage,
+ curbuf = curbuf,
+ curwin = curwin,
+ curtab = curtab,
+ curbuf_contents = curbuf_contents,
+ wait = wait,
+ sleep = sleep,
+ set_session = set_session,
+ write_file = write_file,
+ os_name = os_name,
+ rmdir = rmdir,
+ mkdir = lfs.mkdir,
+ exc_exec = exc_exec,
+ redir_exec = redir_exec,
+ merge_args = merge_args,
+ funcs = funcs,
+ meths = meths,
+ bufmeths = bufmeths,
+ winmeths = winmeths,
+ tabmeths = tabmeths,
+ curbufmeths = curbufmeths,
+ curwinmeths = curwinmeths,
+ curtabmeths = curtabmeths,
+ NIL = mpack.NIL,
+ }
+end
diff --git a/test/functional/legacy/002_filename_recognition_spec.lua b/test/functional/legacy/002_filename_recognition_spec.lua
index 569e748631..5a833281e7 100644
--- a/test/functional/legacy/002_filename_recognition_spec.lua
+++ b/test/functional/legacy/002_filename_recognition_spec.lua
@@ -1,7 +1,7 @@
-- Test if URLs are recognized as filenames by commands such as "gf". Here
-- we'll use `expand("<cfile>")` since "gf" would need to open the file.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/003_cindent_spec.lua b/test/functional/legacy/003_cindent_spec.lua
index 4b838eda1d..83388bd1eb 100644
--- a/test/functional/legacy/003_cindent_spec.lua
+++ b/test/functional/legacy/003_cindent_spec.lua
@@ -3,7 +3,7 @@
-- There are 50+ test command blocks (the stuff between STARTTEST and ENDTEST)
-- in the original test. These have been converted to "it" test cases here.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/004_bufenter_with_modelines_spec.lua b/test/functional/legacy/004_bufenter_with_modelines_spec.lua
index 34e702b798..3e5cdd2ff2 100644
--- a/test/functional/legacy/004_bufenter_with_modelines_spec.lua
+++ b/test/functional/legacy/004_bufenter_with_modelines_spec.lua
@@ -2,7 +2,7 @@
-- Test for autocommand that changes current buffer on BufEnter event.
-- Check if modelines are interpreted for the correct buffer.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/005_bufleave_delete_buffer_spec.lua b/test/functional/legacy/005_bufleave_delete_buffer_spec.lua
index e6989a6674..895f4ad181 100644
--- a/test/functional/legacy/005_bufleave_delete_buffer_spec.lua
+++ b/test/functional/legacy/005_bufleave_delete_buffer_spec.lua
@@ -1,7 +1,7 @@
-- Test for autocommand that deletes the current buffer on BufLeave event.
-- Also test deleting the last buffer, should give a new, empty buffer.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/006_argument_list_spec.lua b/test/functional/legacy/006_argument_list_spec.lua
index 1266a876d4..764854314f 100644
--- a/test/functional/legacy/006_argument_list_spec.lua
+++ b/test/functional/legacy/006_argument_list_spec.lua
@@ -1,6 +1,6 @@
-- Test for autocommand that redefines the argument list, when doing ":all".
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, dedent, eq = helpers.execute, helpers.dedent, helpers.eq
local curbuf_contents = helpers.curbuf_contents
diff --git a/test/functional/legacy/007_ball_buffer_list_spec.lua b/test/functional/legacy/007_ball_buffer_list_spec.lua
index 295f63f044..07e3fe6e7a 100644
--- a/test/functional/legacy/007_ball_buffer_list_spec.lua
+++ b/test/functional/legacy/007_ball_buffer_list_spec.lua
@@ -1,6 +1,6 @@
-- Test for autocommand that changes the buffer list, when doing ":ball".
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/009_bufleave_autocommand_spec.lua b/test/functional/legacy/009_bufleave_autocommand_spec.lua
index 8c18639c8f..7481c639cf 100644
--- a/test/functional/legacy/009_bufleave_autocommand_spec.lua
+++ b/test/functional/legacy/009_bufleave_autocommand_spec.lua
@@ -1,6 +1,6 @@
-- Test for Bufleave autocommand that deletes the buffer we are about to edit.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, insert = helpers.clear, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/010_errorformat_spec.lua b/test/functional/legacy/010_errorformat_spec.lua
new file mode 100644
index 0000000000..785bf136b5
--- /dev/null
+++ b/test/functional/legacy/010_errorformat_spec.lua
@@ -0,0 +1,156 @@
+-- Test for 'errorformat'. This will fail if the quickfix feature was
+-- disabled.
+
+local helpers = require('test.functional.helpers')(after_each)
+local feed, clear, execute = helpers.feed, helpers.clear, helpers.execute
+local expect, write_file = helpers.expect, helpers.write_file
+
+describe('errorformat', function()
+ setup(function()
+ clear()
+ local error_file_text = [[
+ start of errorfile
+ "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?
+ ]]
+ write_file('Xerrorfile1', error_file_text .. 'end of errorfile\n')
+ write_file('Xerrorfile2', error_file_text)
+ write_file('Xtestfile', [[
+ start of testfile
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
+ end of testfile
+ ]])
+ end)
+ teardown(function()
+ os.remove('Xerrorfile1')
+ os.remove('Xerrorfile2')
+ os.remove('Xtestfile')
+ end)
+
+ it('is working', function()
+ -- Also test a BOM is ignored.
+ execute(
+ 'set encoding=utf-8',
+ [[set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m]],
+ [[set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m]],
+ 'cf Xerrorfile2',
+ 'clast',
+ 'copen',
+ 'let a=w:quickfix_title',
+ 'wincmd p'
+ )
+ feed('lgR<C-R>=a<CR><esc>')
+ execute('cf Xerrorfile1')
+ feed('grA<cr>')
+ execute('cn')
+ feed('gRLINE 6, COL 19<esc>')
+ execute('cn')
+ feed('gRNO COLUMN SPECIFIED<esc>')
+ execute('cn')
+ feed('gRAGAIN NO COLUMN<esc>')
+ execute('cn')
+ feed('gRCOL 1<esc>')
+ execute('cn')
+ feed('gRCOL 2<esc>')
+ execute('cn')
+ feed('gRCOL 10<esc>')
+ execute('cn')
+ feed('gRVCOL 10<esc>')
+ execute('cn')
+ feed('grI<cr>')
+ execute('cn')
+ feed('gR. SPACE POINTER<esc>')
+ execute('cn')
+ feed('gR. DOT POINTER<esc>')
+ execute('cn')
+ feed('gR. DASH POINTER<esc>')
+ execute('cn')
+ feed('gR. TAB-SPACE POINTER<esc>')
+ execute(
+ 'clast',
+ 'cprev',
+ 'cprev',
+ 'wincmd w',
+ 'let a=w:quickfix_title',
+ 'wincmd p'
+ )
+ feed('lgR<C-R>=a<CR><esc>')
+
+ -- Assert buffer contents.
+ expect([[
+ start of testfile
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
+ xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx line 4
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
+ xxxxxxxxxxxxxxxxxLINE 6, COL 19 line 6
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
+ NO COLUMN SPECIFIEDxxxxxxxxxxx line 9
+ AGAIN NO COLUMNxxxxxxxxxxxxxxx line 10
+ COL 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
+ COL 2xxxxxxxxxxxxxxxxxxxxxxxxx line 12
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
+ xxxxxxxxCOL 10xxxxxxxxxxxxxxxx line 14
+ xVCOL 10xxxxxxxxxxxxxxxxxxxxxx line 15
+ Ixxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
+ xxxx. SPACE POINTERxxxxxxxxxxx line 17
+ xxxxx. DOT POINTERxxxxxxxxxxxx line 18
+ xxxxxx. DASH POINTERxxxxxxxxxx line 19
+ xxxxxxx. TAB-SPACE POINTERxxxx line 20
+ xxxxxxxx:cf Xerrorfile1xxxxxxx line 21
+ xxxxxxxx:cf Xerrorfile2xxxxxxx line 22
+ end of testfile]])
+ end)
+end)
diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua
index 483e465cee..6e613c85df 100644
--- a/test/functional/legacy/011_autocommands_spec.lua
+++ b/test/functional/legacy/011_autocommands_spec.lua
@@ -12,7 +12,8 @@
-- Use a FileChangedShell autocommand to avoid a prompt for "Xtestfile.gz"
-- being modified outside of Vim (noticed on Solaris).
-local helpers, lfs = require('test.functional.helpers'), require('lfs')
+local helpers= require('test.functional.helpers')(after_each)
+local lfs = require('lfs')
local clear, execute, expect, eq, neq, dedent, write_file, feed =
helpers.clear, helpers.execute, helpers.expect, helpers.eq, helpers.neq,
helpers.dedent, helpers.write_file, helpers.feed
diff --git a/test/functional/legacy/015_alignment_spec.lua b/test/functional/legacy/015_alignment_spec.lua
index 3b19f4ff42..48d4042ff2 100644
--- a/test/functional/legacy/015_alignment_spec.lua
+++ b/test/functional/legacy/015_alignment_spec.lua
@@ -2,7 +2,7 @@
-- Also test formatting a paragraph.
-- Also test undo after ":%s" and formatting.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/018_unset_smart_indenting_spec.lua b/test/functional/legacy/018_unset_smart_indenting_spec.lua
index 6975cb7f26..ba1eac02cb 100644
--- a/test/functional/legacy/018_unset_smart_indenting_spec.lua
+++ b/test/functional/legacy/018_unset_smart_indenting_spec.lua
@@ -1,6 +1,6 @@
-- Tests for not doing smart indenting when it isn't set.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/019_smarttab_expandtab_spec.lua b/test/functional/legacy/019_smarttab_expandtab_spec.lua
index a33bd0c3ae..2287a9f786 100644
--- a/test/functional/legacy/019_smarttab_expandtab_spec.lua
+++ b/test/functional/legacy/019_smarttab_expandtab_spec.lua
@@ -1,7 +1,7 @@
-- Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
-- Also test that dv_ works correctly
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/020_blockwise_visual_spec.lua b/test/functional/legacy/020_blockwise_visual_spec.lua
index 95574a0957..660348a792 100644
--- a/test/functional/legacy/020_blockwise_visual_spec.lua
+++ b/test/functional/legacy/020_blockwise_visual_spec.lua
@@ -3,7 +3,7 @@
-- First test for undo working properly when executing commands from a register.
-- Also test this in an empty buffer.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/021_control_wi_spec.lua b/test/functional/legacy/021_control_wi_spec.lua
index 9fd83fec5f..787a384fca 100644
--- a/test/functional/legacy/021_control_wi_spec.lua
+++ b/test/functional/legacy/021_control_wi_spec.lua
@@ -1,7 +1,7 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Tests for [ CTRL-I with a count and CTRL-W CTRL-I with a count
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/022_line_ending_spec.lua b/test/functional/legacy/022_line_ending_spec.lua
index a841378a82..092440bb16 100644
--- a/test/functional/legacy/022_line_ending_spec.lua
+++ b/test/functional/legacy/022_line_ending_spec.lua
@@ -1,6 +1,6 @@
-- Tests for file with some lines ending in CTRL-M, some not
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/023_edit_arguments_spec.lua b/test/functional/legacy/023_edit_arguments_spec.lua
index 15b30bfa3a..95ab983d24 100644
--- a/test/functional/legacy/023_edit_arguments_spec.lua
+++ b/test/functional/legacy/023_edit_arguments_spec.lua
@@ -1,6 +1,6 @@
-- Tests for complicated + argument to :edit command
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, insert = helpers.clear, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/025_jump_tag_hidden_spec.lua b/test/functional/legacy/025_jump_tag_hidden_spec.lua
index bd434c013c..7b7ddb07b9 100644
--- a/test/functional/legacy/025_jump_tag_hidden_spec.lua
+++ b/test/functional/legacy/025_jump_tag_hidden_spec.lua
@@ -1,7 +1,7 @@
-- 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.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/026_execute_while_if_spec.lua b/test/functional/legacy/026_execute_while_if_spec.lua
index f17bb79702..74ef34bb20 100644
--- a/test/functional/legacy/026_execute_while_if_spec.lua
+++ b/test/functional/legacy/026_execute_while_if_spec.lua
@@ -1,6 +1,6 @@
-- Test for :execute, :while and :if
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
local source = helpers.source
diff --git a/test/functional/legacy/027_expand_file_names_spec.lua b/test/functional/legacy/027_expand_file_names_spec.lua
deleted file mode 100644
index 4778d16d43..0000000000
--- a/test/functional/legacy/027_expand_file_names_spec.lua
+++ /dev/null
@@ -1,37 +0,0 @@
--- Test for expanding file names
-
-local helpers = require('test.functional.helpers')
-local clear, feed = helpers.clear, helpers.feed
-local execute = helpers.execute
-local curbuf_contents = helpers.curbuf_contents
-local eq = helpers.eq
-
-describe('expand file name', function()
- setup(clear)
-
- it('is working', function()
- execute('!mkdir Xdir1')
- execute('!mkdir Xdir2')
- execute('!mkdir Xdir3')
- execute('cd Xdir3')
- execute('!mkdir Xdir4')
- execute('cd ..')
- execute('w Xdir1/file')
- execute('w Xdir3/Xdir4/file')
- execute('n Xdir?/*/file')
-
- -- Yank current file path to @a register
- feed('i<C-R>%<Esc>V"ad')
-
- -- Put @a and current file path in the current buffer
- execute('n! Xdir?/*/nofile')
- feed('V"ap')
- feed('o<C-R>%<Esc>')
-
- eq("Xdir3/Xdir4/file\nXdir?/*/nofile", curbuf_contents())
- end)
-
- teardown(function()
- os.execute('rm -rf Xdir1 Xdir2 Xdir3')
- end)
-end)
diff --git a/test/functional/legacy/028_source_ctrl_v_spec.lua b/test/functional/legacy/028_source_ctrl_v_spec.lua
index fc36b436ef..a8c43260be 100644
--- a/test/functional/legacy/028_source_ctrl_v_spec.lua
+++ b/test/functional/legacy/028_source_ctrl_v_spec.lua
@@ -1,6 +1,6 @@
-- Test for sourcing a file with CTRL-V's at the end of the line
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/029_join_spec.lua b/test/functional/legacy/029_join_spec.lua
index 25a072ad6e..7a183fcbec 100644
--- a/test/functional/legacy/029_join_spec.lua
+++ b/test/functional/legacy/029_join_spec.lua
@@ -1,6 +1,6 @@
-- Test for joining lines with marks in them (and with 'joinspaces' set/reset)
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/031_close_commands_spec.lua b/test/functional/legacy/031_close_commands_spec.lua
index b79b1903ba..eaf4e2982f 100644
--- a/test/functional/legacy/031_close_commands_spec.lua
+++ b/test/functional/legacy/031_close_commands_spec.lua
@@ -9,9 +9,14 @@
-- :buf
-- :edit
-local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
-local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+local helpers = require('test.functional.helpers')(after_each)
+
+local feed = helpers.feed
+local clear = helpers.clear
+local source = helpers.source
+local insert = helpers.insert
+local expect = helpers.expect
+local execute = helpers.execute
describe('Commands that close windows and/or buffers', function()
setup(clear)
diff --git a/test/functional/legacy/033_lisp_indent_spec.lua b/test/functional/legacy/033_lisp_indent_spec.lua
index 0a5577fad3..b4abb02ac2 100644
--- a/test/functional/legacy/033_lisp_indent_spec.lua
+++ b/test/functional/legacy/033_lisp_indent_spec.lua
@@ -2,7 +2,7 @@
-- Test for 'lisp'
-- If the lisp feature is not enabled, this will fail!
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/034_user_function_spec.lua b/test/functional/legacy/034_user_function_spec.lua
new file mode 100644
index 0000000000..38989cd982
--- /dev/null
+++ b/test/functional/legacy/034_user_function_spec.lua
@@ -0,0 +1,102 @@
+-- Test for user functions.
+-- Also test an <expr> mapping calling a function.
+-- Also test that a builtin function cannot be replaced.
+-- Also test for regression when calling arbitrary expression.
+
+local helpers = require('test.functional.helpers')(after_each)
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('user functions, expr-mappings, overwrite protected builtin functions and regression on calling expressions', function()
+ setup(clear)
+
+ it('are working', function()
+ insert('here')
+
+ source([[
+ function Table(title, ...)
+ let ret = a:title
+ let idx = 1
+ while idx <= a:0
+ exe "let ret = ret . a:" . idx
+ let idx = idx + 1
+ endwhile
+ return ret
+ endfunction
+ function Compute(n1, n2, divname)
+ if a:n2 == 0
+ return "fail"
+ endif
+ exe "let g:" . a:divname . " = ". a:n1 / a:n2
+ return "ok"
+ endfunction
+ func Expr1()
+ normal! v
+ return "111"
+ endfunc
+ func Expr2()
+ call search('XX', 'b')
+ return "222"
+ endfunc
+ func ListItem()
+ let g:counter += 1
+ return g:counter . '. '
+ endfunc
+ func ListReset()
+ let g:counter = 0
+ return ''
+ endfunc
+ func FuncWithRef(a)
+ unlet g:FuncRef
+ return a:a
+ endfunc
+ let g:FuncRef=function("FuncWithRef")
+ let counter = 0
+ inoremap <expr> ( ListItem()
+ inoremap <expr> [ ListReset()
+ imap <expr> + Expr1()
+ imap <expr> * Expr2()
+ let retval = "nop"
+ /^here
+ ]])
+ feed('C<C-R>=Table("xxx", 4, "asdf")<cr>')
+ -- Using a actual space will not work as feed() calls dedent on the input.
+ feed('<space><C-R>=Compute(45, 0, "retval")<cr>')
+ feed('<space><C-R>=retval<cr>')
+ feed('<space><C-R>=Compute(45, 5, "retval")<cr>')
+ feed('<space><C-R>=retval<cr>')
+ feed('<space><C-R>=g:FuncRef(333)<cr>')
+ feed('<cr>')
+ feed('XX+-XX<cr>')
+ feed('---*---<cr>')
+ feed('(one<cr>')
+ feed('(two<cr>')
+ feed('[(one again<esc>')
+ execute('call append(line("$"), max([1, 2, 3]))')
+ execute('call extend(g:, {"max": function("min")})')
+ execute('call append(line("$"), max([1, 2, 3]))')
+ execute('try')
+ -- Regression: the first line below used to throw "E110: Missing ')'"
+ -- Second is here just to prove that this line is correct when not
+ -- skipping rhs of &&.
+ execute([[ $put =(0&&(function('tr'))(1, 2, 3))]])
+ execute([[ $put =(1&&(function('tr'))(1, 2, 3))]])
+ execute('catch')
+ execute([[ $put ='!!! Unexpected exception:']])
+ execute(' $put =v:exception')
+ execute('endtry')
+
+ -- Assert buffer contents.
+ expect([[
+ xxx4asdf fail nop ok 9 333
+ XX111-XX
+ ---222---
+ 1. one
+ 2. two
+ 1. one again
+ 3
+ 3
+ 0
+ 1]])
+ end)
+end)
diff --git a/test/functional/legacy/035_increment_and_decrement_spec.lua b/test/functional/legacy/035_increment_and_decrement_spec.lua
index e6252c384b..3b9f7a9d85 100644
--- a/test/functional/legacy/035_increment_and_decrement_spec.lua
+++ b/test/functional/legacy/035_increment_and_decrement_spec.lua
@@ -1,7 +1,7 @@
-- Test Ctrl-A and Ctrl-X, which increment and decrement decimal, hexadecimal,
-- and octal numbers.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/036_regexp_character_classes_spec.lua b/test/functional/legacy/036_regexp_character_classes_spec.lua
index de080f4b43..3d5e69d1e5 100644
--- a/test/functional/legacy/036_regexp_character_classes_spec.lua
+++ b/test/functional/legacy/036_regexp_character_classes_spec.lua
@@ -1,6 +1,6 @@
-- Test character classes in regexp using regexpengine 0, 1, 2.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
local source, write_file = helpers.source, helpers.write_file
local os_name = helpers.os_name
diff --git a/test/functional/legacy/038_virtual_replace_spec.lua b/test/functional/legacy/038_virtual_replace_spec.lua
index 10d42f0cea..dcbc9c39f7 100644
--- a/test/functional/legacy/038_virtual_replace_spec.lua
+++ b/test/functional/legacy/038_virtual_replace_spec.lua
@@ -1,6 +1,6 @@
-- Test Virtual replace mode.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed = helpers.feed
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/039_visual_block_mode_commands_spec.lua b/test/functional/legacy/039_visual_block_mode_commands_spec.lua
index 7195d7d11d..63335985cc 100644
--- a/test/functional/legacy/039_visual_block_mode_commands_spec.lua
+++ b/test/functional/legacy/039_visual_block_mode_commands_spec.lua
@@ -1,7 +1,7 @@
-- Test Visual block mode commands
-- And test "U" in Visual mode, also on German sharp S.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim, eq = helpers.meths, helpers.eq
local insert, feed = helpers.insert, helpers.feed
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/041_writing_and_reading_hundred_kbyte_spec.lua b/test/functional/legacy/041_writing_and_reading_hundred_kbyte_spec.lua
index 42fb5ed2b3..b6451eb720 100644
--- a/test/functional/legacy/041_writing_and_reading_hundred_kbyte_spec.lua
+++ b/test/functional/legacy/041_writing_and_reading_hundred_kbyte_spec.lua
@@ -1,6 +1,6 @@
-- Test for writing and reading a file of over 100 Kbyte
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/043_magic_settings_spec.lua b/test/functional/legacy/043_magic_settings_spec.lua
index 27694e3754..f174751de2 100644
--- a/test/functional/legacy/043_magic_settings_spec.lua
+++ b/test/functional/legacy/043_magic_settings_spec.lua
@@ -1,7 +1,7 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Tests for regexp with various magic settings.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
index 2a4c0149fa..4189e8a33a 100644
--- a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
+++ b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
@@ -3,7 +3,7 @@
--
-- This test contains both "test44" and "test99" from the old test suite.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/045_folding_spec.lua b/test/functional/legacy/045_folding_spec.lua
index 04b623ff3b..cefd7c0d42 100644
--- a/test/functional/legacy/045_folding_spec.lua
+++ b/test/functional/legacy/045_folding_spec.lua
@@ -1,6 +1,6 @@
-- Tests for folding.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, clear, execute, expect =
helpers.feed, helpers.insert, helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/046_multi_line_regexps_spec.lua b/test/functional/legacy/046_multi_line_regexps_spec.lua
index b17ab42fe3..30ec76ea3e 100644
--- a/test/functional/legacy/046_multi_line_regexps_spec.lua
+++ b/test/functional/legacy/046_multi_line_regexps_spec.lua
@@ -1,7 +1,7 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Tests for multi-line regexps with ":s"
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local expect = helpers.expect
diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua
index 94c42b73e5..5bf3b51b90 100644
--- a/test/functional/legacy/051_highlight_spec.lua
+++ b/test/functional/legacy/051_highlight_spec.lua
@@ -2,7 +2,7 @@
-- Tests for ":highlight".
local Screen = require('test.functional.ui.screen')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
local wait = helpers.wait
diff --git a/test/functional/legacy/054_buffer_local_autocommands_spec.lua b/test/functional/legacy/054_buffer_local_autocommands_spec.lua
index bcedb26b7e..494ea8f927 100644
--- a/test/functional/legacy/054_buffer_local_autocommands_spec.lua
+++ b/test/functional/legacy/054_buffer_local_autocommands_spec.lua
@@ -1,6 +1,6 @@
-- Some tests for buffer-local autocommands
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, eq = helpers.clear, helpers.execute, helpers.eq
local curbuf_contents = helpers.curbuf_contents
diff --git a/test/functional/legacy/055_list_and_dict_types_spec.lua b/test/functional/legacy/055_list_and_dict_types_spec.lua
new file mode 100644
index 0000000000..b9e5a8bc03
--- /dev/null
+++ b/test/functional/legacy/055_list_and_dict_types_spec.lua
@@ -0,0 +1,926 @@
+-- Tests for List and Dictionary types.
+
+local helpers = require('test.functional.helpers')(after_each)
+local feed, source = helpers.feed, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('list and dictionary types', function()
+ before_each(clear)
+
+ it('creating list directly with different types', function()
+ source([[
+ lang C
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ $put =string(l)
+ $put =string(l[-1])
+ $put =string(l[-4])
+ try
+ $put =string(l[-5])
+ catch
+ $put =v:exception[:14]
+ endtry]])
+ expect([[
+
+ [1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+ {'a': 1}
+ 1
+ Vim(put):E684: ]])
+ end)
+
+ it('list slices', function()
+ source([[
+ lang C
+ " The list from the first test repeated after splitting the tests.
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ $put =string(l[:])
+ $put =string(l[1:])
+ $put =string(l[:-2])
+ $put =string(l[0:8])
+ $put =string(l[8:-1])]])
+ expect([=[
+
+ [1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+ ['as''d', [1, 2, function('strlen')], {'a': 1}]
+ [1, 'as''d', [1, 2, function('strlen')]]
+ [1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+ []]=])
+ end)
+
+ it('list identity', function()
+ source([[
+ lang C
+ " The list from the first test repeated after splitting the tests.
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ let ll = l
+ let lx = copy(l)
+ try
+ $put =(l == ll) . (l isnot ll) . (l is ll) . (l == lx) .
+ \ (l is lx) . (l isnot lx)
+ catch
+ $put =v:exception
+ endtry]])
+ expect('\n101101')
+ end)
+
+ it('creating dictionary directly with different types', function()
+ source([[
+ lang C
+ let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
+ $put =string(d) . d.1
+ $put =string(sort(keys(d)))
+ $put =string (values(d))
+ for [key, val] in items(d)
+ $put =key . ':' . string(val)
+ unlet key val
+ endfor
+ call extend (d, {3:33, 1:99})
+ call extend(d, {'b':'bbb', 'c':'ccc'}, "keep")
+ try
+ call extend(d, {3:333,4:444}, "error")
+ catch
+ $put =v:exception[:15] . v:exception[-1:-1]
+ endtry
+ $put =string(d)
+ call filter(d, 'v:key =~ ''[ac391]''')
+ $put =string(d)]])
+ expect([[
+
+ {'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}asd
+ ['-1', '1', 'b']
+ ['asd', [1, 2, function('strlen')], {'a': 1}]
+ 1:'asd'
+ b:[1, 2, function('strlen')]
+ -1:{'a': 1}
+ Vim(call):E737: 3
+ {'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}
+ {'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}]])
+ end)
+
+ it('dictionary identity', function()
+ source([[
+ lang C
+ " The dict from the first test repeated after splitting the tests.
+ let d = {'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}
+ let dd = d
+ let dx = copy(d)
+ try
+ $put =(d == dd) . (d isnot dd) . (d is dd) . (d == dx) . (d is dx) .
+ \ (d isnot dx)
+ catch
+ $put =v:exception
+ endtry]])
+ expect('\n101101')
+ end)
+
+ it('removing items with :unlet', function()
+ source([[
+ lang C
+ " The list from the first test repeated after splitting the tests.
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ " The dict from the first test repeated after splitting the tests.
+ let d = {'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}
+ unlet l[2]
+ $put =string(l)
+ let l = range(8)
+ try
+ unlet l[:3]
+ unlet l[1:]
+ catch
+ $put =v:exception
+ endtry
+ $put =string(l)
+
+ unlet d.c
+ unlet d[-1]
+ $put =string(d)]])
+ expect([[
+
+ [1, 'as''d', {'a': 1}]
+ [4]
+ {'1': 99, '3': 33}]])
+ end)
+
+ it("removing items out of range: silently skip items that don't exist", function()
+ -- We can not use source() here as we want to ignore all errors.
+ execute('lang C')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[2:1]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[2:2]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[2:3]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[2:4]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[2:5]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[-1:2]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[-2:2]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[-3:2]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[-4:2]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[-5:2]')
+ execute('$put =string(l)')
+ execute('let l = [0, 1, 2, 3]')
+ execute('unlet l[-6:2]')
+ execute('$put =string(l)')
+ expect([=[
+
+ [0, 1, 2, 3]
+ [0, 1, 3]
+ [0, 1]
+ [0, 1]
+ [0, 1]
+ [0, 1, 2, 3]
+ [0, 1, 3]
+ [0, 3]
+ [3]
+ [3]
+ [3]]=])
+ end)
+
+ it('assignment to a list', function()
+ source([[
+ let l = [0, 1, 2, 3]
+ let [va, vb] = l[2:3]
+ $put =va
+ $put =vb
+ try
+ let [va, vb] = l
+ catch
+ $put =v:exception[:14]
+ endtry
+ try
+ let [va, vb] = l[1:1]
+ catch
+ $put =v:exception[:14]
+ endtry]])
+ expect([[
+
+ 2
+ 3
+ Vim(let):E687:
+ Vim(let):E688: ]])
+ end)
+
+ it('manipulating a big dictionary', function()
+ -- Manipulating a big Dictionary (hashtable.c has a border of 1000
+ -- entries).
+ source([[
+ let d = {}
+ for i in range(1500)
+ let d[i] = 3000 - i
+ endfor
+ $put =d[0] . ' ' . d[100] . ' ' . d[999] . ' ' . d[1400] . ' ' .
+ \ d[1499]
+ try
+ let n = d[1500]
+ catch
+ $put =substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '')
+ endtry
+ " Lookup each items.
+ for i in range(1500)
+ if d[i] != 3000 - i
+ $put =d[i]
+ endif
+ endfor
+ let i += 1
+ " Delete even items.
+ while i >= 2
+ let i -= 2
+ unlet d[i]
+ endwhile
+ $put =get(d, 1500 - 100, 'NONE') . ' ' . d[1]
+ " Delete odd items, checking value, one intentionally wrong.
+ let d[33] = 999
+ let i = 1
+ while i < 1500
+ if d[i] != 3000 - i
+ $put =i . '=' . d[i]
+ else
+ unlet d[i]
+ endif
+ let i += 2
+ endwhile
+ " Must be almost empty now.
+ $put =string(d)]])
+ expect([[
+
+ 3000 2900 2001 1600 1501
+ Vim(let):E716: 1500
+ NONE 2999
+ 33=999
+ {'33': 999}]])
+ end)
+
+ it('dictionary function', function()
+ source([[
+ let dict = {}
+ func dict.func(a) dict
+ $put =a:a . len(self.data)
+ endfunc
+ let dict.data = [1,2,3]
+ call dict.func("len: ")
+ let x = dict.func("again: ")
+ try
+ let Fn = dict.func
+ call Fn('xxx')
+ catch
+ $put =v:exception[:15]
+ endtry]])
+ expect([[
+
+ len: 3
+ again: 3
+ Vim(call):E725: ]])
+ end)
+
+ it('Function in script-local List or Dict', function()
+ source([[
+ let g:dict = {}
+ function g:dict.func() dict
+ $put ='g:dict.func'.self.foo[1].self.foo[0]('asdf')
+ endfunc
+ let g:dict.foo = ['-', 2, 3]
+ call insert(g:dict.foo, function('strlen'))
+ call g:dict.func()]])
+ expect('\ng:dict.func-4')
+ end)
+
+ it("remove func from dict that's being called (works)", function()
+ source([[
+ let d = {1:1}
+ func d.func(a)
+ return "a:". a:a
+ endfunc
+ $put =d.func(string(remove(d, 'func')))]])
+ -- The function number changed from 3 to 1 because we split the test.
+ -- There were two other functions in the old test before this.
+ expect("\na:function('1')")
+ end)
+
+ it('deepcopy() dict that refers to itself', function()
+ -- Nasty: deepcopy() dict that refers to itself (fails when noref used).
+ source([[
+ let d = {1:1, 2:2}
+ let l = [4, d, 6]
+ let d[3] = l
+ let dc = deepcopy(d)
+ try
+ let dc = deepcopy(d, 1)
+ catch
+ $put =v:exception[:14]
+ endtry
+ let l2 = [0, l, l, 3]
+ let l[1] = l2
+ let l3 = deepcopy(l2)
+ $put ='same list: ' . (l3[1] is l3[2])]])
+ expect([[
+
+ Vim(let):E698:
+ same list: 1]])
+ end)
+
+ it('locked variables (part 1)', function()
+ source([=[
+ let l = []
+ for depth in range(5)
+ $put ='depth is ' . depth
+ for u in range(3)
+ unlet l
+ let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
+ exe "lockvar " . depth . " l"
+ if u == 1
+ exe "unlockvar l"
+ elseif u == 2
+ exe "unlockvar " . depth . " l"
+ endif
+ let ps = islocked("l") . islocked("l[1]") . islocked("l[1][1]") .
+ \ islocked("l[1][1][0]") . '-' . islocked("l[2]") .
+ \ islocked("l[2]['6']") . islocked("l[2]['6'][7]")
+ $put =ps
+ let ps = ''
+ try
+ let l[1][1][0] = 99
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[1][1] = [99]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[1] = [99]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[2]['6'][7] = 99
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[2][6] = {99: 99}
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[2] = {99: 99}
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l = [99]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ $put =ps
+ endfor
+ endfor]=])
+ expect([[
+
+ depth is 0
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ depth is 1
+ 1000-000
+ ppppppF
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ depth is 2
+ 1100-100
+ ppFppFF
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ depth is 3
+ 1110-110
+ pFFpFFF
+ 0010-010
+ pFppFpp
+ 0000-000
+ ppppppp
+ depth is 4
+ 1111-111
+ FFFFFFF
+ 0011-011
+ FFpFFpp
+ 0000-000
+ ppppppp]])
+ end)
+
+ -- TODO In the original test the 5th line of this source() call was used.
+ -- But now the test only passes if I comment it.
+ it('unletting locked variables', function()
+ source([=[
+ let l = []
+ for depth in range(5)
+ $put ='depth is ' . depth
+ for u in range(3)
+ "unlet l
+ let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
+ exe "lockvar " . depth . " l"
+ if u == 1
+ exe "unlockvar l"
+ elseif u == 2
+ exe "unlockvar " . depth . " l"
+ endif
+ let ps = islocked("l") . islocked("l[1]") . islocked("l[1][1]") .
+ \ islocked("l[1][1][0]") . '-' . islocked("l[2]") .
+ \ islocked("l[2]['6']") . islocked("l[2]['6'][7]")
+ $put =ps
+ let ps = ''
+ try
+ unlet l[2]['6'][7]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[2][6]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[2]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[1][1][0]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[1][1]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[1]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ $put =ps
+ endfor
+ endfor]=])
+ expect([[
+
+ depth is 0
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ depth is 1
+ 1000-000
+ ppFppFp
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ depth is 2
+ 1100-100
+ pFFpFFp
+ 0000-000
+ ppppppp
+ 0000-000
+ ppppppp
+ depth is 3
+ 1110-110
+ FFFFFFp
+ 0010-010
+ FppFppp
+ 0000-000
+ ppppppp
+ depth is 4
+ 1111-111
+ FFFFFFp
+ 0011-011
+ FppFppp
+ 0000-000
+ ppppppp]])
+ end)
+
+ it('locked variables and :unlet or list / dict functions', function()
+ source([[
+ $put ='Locks and commands or functions:'
+
+ $put ='No :unlet after lock on dict:'
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar 1 d
+ try
+ unlet d.a
+ $put ='did :unlet'
+ catch
+ $put =v:exception[:16]
+ endtry
+ $put =string(d)
+
+ $put =':unlet after lock on dict item:'
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar d.a
+ try
+ unlet d.a
+ $put ='did :unlet'
+ catch
+ $put =v:exception[:16]
+ endtry
+ $put =string(d)
+
+ $put ='filter() after lock on dict item:'
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar d.a
+ try
+ call filter(d, 'v:key != "a"')
+ $put ='did filter()'
+ catch
+ $put =v:exception[:16]
+ endtry
+ $put =string(d)
+
+ $put ='map() after lock on dict:'
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar 1 d
+ try
+ call map(d, 'v:val + 200')
+ $put ='did map()'
+ catch
+ $put =v:exception[:16]
+ endtry
+ $put =string(d)
+
+ $put ='No extend() after lock on dict item:'
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar d.a
+ try
+ $put =string(extend(d, {'a': 123}))
+ $put ='did extend()'
+ catch
+ $put =v:exception[:14]
+ endtry
+ $put =string(d)
+
+ $put ='No remove() of write-protected scope-level variable:'
+ fun! Tfunc(this_is_a_loooooooooong_parameter_name)
+ try
+ $put =string(remove(a:, 'this_is_a_loooooooooong_parameter_name'))
+ $put ='did remove()'
+ catch
+ $put =v:exception[:14]
+ endtry
+ endfun
+ call Tfunc('testval')
+
+ $put ='No extend() of write-protected scope-level variable:'
+ fun! Tfunc(this_is_a_loooooooooong_parameter_name)
+ try
+ $put =string(extend(a:, {'this_is_a_loooooooooong_parameter_name': 1234}))
+ $put ='did extend()'
+ catch
+ $put =v:exception[:14]
+ endtry
+ endfun
+ call Tfunc('testval')
+
+ $put ='No :unlet of variable in locked scope:'
+ let b:testvar = 123
+ lockvar 1 b:
+ try
+ unlet b:testvar
+ $put ='b:testvar was :unlet: '. (!exists('b:testvar'))
+ catch
+ $put =v:exception[:16]
+ endtry
+ unlockvar 1 b:
+ unlet! b:testvar
+
+ $put ='No :let += of locked list variable:'
+ let l = ['a', 'b', 3]
+ lockvar 1 l
+ try
+ let l += ['x']
+ $put ='did :let +='
+ catch
+ $put =v:exception[:14]
+ endtry
+ $put =string(l)]])
+
+ expect([=[
+
+ Locks and commands or functions:
+ No :unlet after lock on dict:
+ Vim(unlet):E741:
+ {'a': 99, 'b': 100}
+ :unlet after lock on dict item:
+ did :unlet
+ {'b': 100}
+ filter() after lock on dict item:
+ did filter()
+ {'b': 100}
+ map() after lock on dict:
+ did map()
+ {'a': 299, 'b': 300}
+ No extend() after lock on dict item:
+ Vim(put):E741:
+ {'a': 99, 'b': 100}
+ No remove() of write-protected scope-level variable:
+ Vim(put):E795:
+ No extend() of write-protected scope-level variable:
+ Vim(put):E742:
+ No :unlet of variable in locked scope:
+ Vim(unlet):E741:
+ No :let += of locked list variable:
+ Vim(let):E741:
+ ['a', 'b', 3]]=])
+ end)
+
+ it('locked variables (part 2)', function()
+ execute(
+ 'let l = [1, 2, 3, 4]',
+ 'lockvar! l',
+ '$put =string(l)',
+ 'unlockvar l[1]',
+ 'unlet l[0:1]',
+ '$put =string(l)',
+ 'unlet l[1:2]',
+ '$put =string(l)',
+ 'unlockvar l[1]',
+ 'let l[0:1] = [0, 1]',
+ '$put =string(l)',
+ 'let l[1:2] = [0, 1]',
+ '$put =string(l)')
+ expect([=[
+
+ [1, 2, 3, 4]
+ [1, 2, 3, 4]
+ [1, 2, 3, 4]
+ [1, 2, 3, 4]
+ [1, 2, 3, 4]]=])
+ end)
+
+ it(':lockvar/islocked() triggering script autoloading.', function()
+ source([[
+ set rtp+=test/functional/fixtures
+ lockvar g:footest#x
+ unlockvar g:footest#x
+ $put ='locked g:footest#x:'.islocked('g:footest#x')
+ $put ='exists g:footest#x:'.exists('g:footest#x')
+ $put ='g:footest#x: '.g:footest#x]])
+ expect([[
+
+ locked g:footest#x:-1
+ exists g:footest#x:0
+ g:footest#x: 1]])
+ end)
+
+ it('a:000 function argument', function()
+ source([[
+ function Test(...)
+ " First the tests that should fail.
+ try
+ let a:000 = [1, 2]
+ catch
+ $put ='caught a:000'
+ endtry
+ try
+ let a:000[0] = 9
+ catch
+ $put ='caught a:000[0]'
+ endtry
+ try
+ let a:000[2] = [9, 10]
+ catch
+ $put ='caught a:000[2]'
+ endtry
+ try
+ let a:000[3] = {9: 10}
+ catch
+ $put ='caught a:000[3]'
+ endtry
+ " Now the tests that should pass.
+ try
+ let a:000[2][1] = 9
+ call extend(a:000[2], [5, 6])
+ let a:000[3][5] = 8
+ let a:000[3]['a'] = 12
+ $put =string(a:000)
+ catch
+ $put ='caught ' . v:exception
+ endtry
+ endfunction]])
+ execute('call Test(1, 2, [3, 4], {5: 6})')
+ expect([=[
+
+ caught a:000
+ caught a:000[0]
+ caught a:000[2]
+ caught a:000[3]
+ [1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]]=])
+ end)
+
+ it('reverse(), sort(), uniq()', function()
+ source([=[
+ let l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo',
+ \ [0, 1, 2], 'x8', [0, 1, 2], 1.5]
+ $put =string(uniq(copy(l)))
+ $put =string(reverse(l))
+ $put =string(reverse(reverse(l)))
+ $put =string(sort(l))
+ $put =string(reverse(sort(l)))
+ $put =string(sort(reverse(sort(l))))
+ $put =string(uniq(sort(l)))
+ let l=[7, 9, 'one', 18, 12, 22, 'two', 10.0e-16, -1, 'three', 0xff,
+ \ 0.22, 'four']
+ $put =string(sort(copy(l), 'n'))
+ let l=[7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'bar',
+ \ 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', {}, []]
+ $put =string(sort(copy(l), 1))
+ $put =string(sort(copy(l), 'i'))
+ $put =string(sort(copy(l)))]=])
+ expect([=[
+
+ ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5]
+ [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0']
+ [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0']
+ ['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]]
+ [[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 'A11', '-0']
+ ['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]]
+ ['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]]
+ [-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255]
+ ['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]
+ ['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]
+ ['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]]=])
+ end)
+
+ it('splitting a string to a list', function()
+ source([[
+ $put =string(split(' aa bb '))
+ $put =string(split(' aa bb ', '\W\+', 0))
+ $put =string(split(' aa bb ', '\W\+', 1))
+ $put =string(split(' aa bb ', '\W', 1))
+ $put =string(split(':aa::bb:', ':', 0))
+ $put =string(split(':aa::bb:', ':', 1))
+ $put =string(split('aa,,bb, cc,', ',\s*', 1))
+ $put =string(split('abc', '\zs'))
+ $put =string(split('abc', '\zs', 1))]])
+ expect([=[
+
+ ['aa', 'bb']
+ ['aa', 'bb']
+ ['', 'aa', 'bb', '']
+ ['', '', 'aa', '', 'bb', '', '']
+ ['aa', '', 'bb']
+ ['', 'aa', '', 'bb', '']
+ ['aa', '', 'bb', 'cc', '']
+ ['a', 'b', 'c']
+ ['', 'a', '', 'b', '', 'c', '']]=])
+ end)
+
+ it('compare recursively linked list and dict', function()
+ source([[
+ let l = [1, 2, 3, 4]
+ let d = {'1': 1, '2': l, '3': 3}
+ let l[1] = d
+ $put =(l == l)
+ $put =(d == d)
+ $put =(l != deepcopy(l))
+ $put =(d != deepcopy(d))]])
+ expect([[
+
+ 1
+ 1
+ 0
+ 0]])
+ end)
+
+ it('compare complex recursively linked list and dict', function()
+ source([[
+ let l = []
+ call add(l, l)
+ let dict4 = {"l": l}
+ call add(dict4.l, dict4)
+ let lcopy = deepcopy(l)
+ let dict4copy = deepcopy(dict4)
+ $put =(l == lcopy)
+ $put =(dict4 == dict4copy)]])
+ expect([[
+
+ 1
+ 1]])
+ end)
+
+ it('pass the same list to extend()', function()
+ source([[
+ let l = [1, 2, 3, 4, 5]
+ call extend(l, l)
+ $put =string(l)]])
+ expect([=[
+
+ [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]]=])
+ end)
+
+ it('pass the same dict to extend()', function()
+ source([[
+ let d = { 'a': {'b': 'B'}}
+ call extend(d, d)
+ $put =string(d)]])
+ expect([[
+
+ {'a': {'b': 'B'}}]])
+ end)
+
+ it('pass the same dict to extend() with "error"', function()
+ source([[
+ " Copy dict from previous test.
+ let d = { 'a': {'b': 'B'}}
+ try
+ call extend(d, d, "error")
+ catch
+ $put =v:exception[:15] . v:exception[-1:-1]
+ endtry
+ $put =string(d)]])
+ expect([[
+
+ Vim(call):E737: a
+ {'a': {'b': 'B'}}]])
+ end)
+
+ it('test for range assign', function()
+ source([[
+ let l = [0]
+ let l[:] = [1, 2]
+ $put =string(l)]])
+ expect([=[
+
+ [1, 2]]=])
+ end)
+
+ it('vim patch 7.3.637', function()
+ execute('let a = "No error caught"')
+ execute('try')
+ execute(' foldopen')
+ execute('catch')
+ execute(" let a = matchstr(v:exception,'^[^ ]*')")
+ execute('endtry')
+ feed('o<C-R>=a<CR><esc>')
+ execute('lang C')
+ execute('redir => a')
+ -- The test failes if this is not in one line.
+ execute("try|foobar|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry")
+ execute('redir END')
+ feed('o<C-R>=a<CR><esc>')
+ expect([[
+
+ Vim(foldopen):E490:
+
+
+ Error detected while processing :
+ E492: Not an editor command: foobar|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry
+ ]])
+ end)
+end)
diff --git a/test/functional/legacy/056_script_local_function_spec.lua b/test/functional/legacy/056_script_local_function_spec.lua
index dec88e8001..084817ad7a 100644
--- a/test/functional/legacy/056_script_local_function_spec.lua
+++ b/test/functional/legacy/056_script_local_function_spec.lua
@@ -1,7 +1,7 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Test for script-local function.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local expect = helpers.expect
diff --git a/test/functional/legacy/057_sort_spec.lua b/test/functional/legacy/057_sort_spec.lua
index 36062ded3a..6984ad0de2 100644
--- a/test/functional/legacy/057_sort_spec.lua
+++ b/test/functional/legacy/057_sort_spec.lua
@@ -1,6 +1,6 @@
-- Tests for :sort command.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, execute, clear, expect, eq, eval, source = helpers.insert,
helpers.execute, helpers.clear, helpers.expect, helpers.eq, helpers.eval,
helpers.source
diff --git a/test/functional/legacy/059_utf8_spell_checking_spec.lua b/test/functional/legacy/059_utf8_spell_checking_spec.lua
index 63df387be3..c44ab44b3c 100644
--- a/test/functional/legacy/059_utf8_spell_checking_spec.lua
+++ b/test/functional/legacy/059_utf8_spell_checking_spec.lua
@@ -1,6 +1,6 @@
-- Tests for spell checking with 'encoding' set to "utf-8".
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
local write_file, call = helpers.write_file, helpers.call
diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua
index 7f44b35a4e..cbd857c524 100644
--- a/test/functional/legacy/060_exists_and_has_functions_spec.lua
+++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua
@@ -1,6 +1,6 @@
-- Tests for the exists() and has() functions.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source = helpers.source
local clear, expect = helpers.clear, helpers.expect
local write_file = helpers.write_file
diff --git a/test/functional/legacy/061_undo_tree_spec.lua b/test/functional/legacy/061_undo_tree_spec.lua
index 6db37bf1ff..9bf69ccba1 100644
--- a/test/functional/legacy/061_undo_tree_spec.lua
+++ b/test/functional/legacy/061_undo_tree_spec.lua
@@ -1,10 +1,15 @@
-- Tests for undo tree and :earlier and :later.
+local helpers = require('test.functional.helpers')(after_each)
-local helpers = require('test.functional.helpers')
-local feed, source, eq, eval, clear, execute, expect, wait, write_file =
- helpers.feed, helpers.source, helpers.eq, helpers.eval,
- helpers.clear, helpers.execute, helpers.expect, helpers.wait,
- helpers.write_file
+local write_file = helpers.write_file
+local execute = helpers.execute
+local command = helpers.command
+local source = helpers.source
+local expect = helpers.expect
+local clear = helpers.clear
+local feed = helpers.feed
+local eval = helpers.eval
+local eq = helpers.eq
local function expect_empty_buffer()
-- The space will be removed by helpers.dedent but is needed because dedent
@@ -57,8 +62,7 @@ describe('undo tree:', function()
-- Delete three other characters and go back in time step by step.
feed('$xxx')
expect_line('123456')
- execute('sleep 1')
- wait()
+ command('sleep 1')
feed('g-')
expect_line('1234567')
feed('g-')
@@ -79,8 +83,7 @@ describe('undo tree:', function()
expect_line('123456')
-- Delay for two seconds and go some seconds forward and backward.
- execute('sleep 2')
- wait()
+ command('sleep 2')
feed('Aa<esc>')
feed('Ab<esc>')
feed('Ac<esc>')
diff --git a/test/functional/legacy/062_tab_pages_spec.lua b/test/functional/legacy/062_tab_pages_spec.lua
index f1c8b8d58b..d5b10b160e 100644
--- a/test/functional/legacy/062_tab_pages_spec.lua
+++ b/test/functional/legacy/062_tab_pages_spec.lua
@@ -1,6 +1,6 @@
-- Tests for tab pages
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source, clear, execute, expect, eval, eq =
helpers.feed, helpers.insert, helpers.source, helpers.clear,
helpers.execute, helpers.expect, helpers.eval, helpers.eq
diff --git a/test/functional/legacy/063_match_and_matchadd_spec.lua b/test/functional/legacy/063_match_and_matchadd_spec.lua
index 23b4f4551b..298e0a31ea 100644
--- a/test/functional/legacy/063_match_and_matchadd_spec.lua
+++ b/test/functional/legacy/063_match_and_matchadd_spec.lua
@@ -1,6 +1,6 @@
-- Tests for adjusting window and contents
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local feed, insert = helpers.feed, helpers.insert
local eval, clear, execute = helpers.eval, helpers.clear, helpers.execute
diff --git a/test/functional/legacy/065_float_and_logic_operators_spec.lua b/test/functional/legacy/065_float_and_logic_operators_spec.lua
index e78b230956..d12ea502f3 100644
--- a/test/functional/legacy/065_float_and_logic_operators_spec.lua
+++ b/test/functional/legacy/065_float_and_logic_operators_spec.lua
@@ -1,6 +1,6 @@
-- Test for floating point and logical operators.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source = helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/066_visual_block_tab_spec.lua b/test/functional/legacy/066_visual_block_tab_spec.lua
index 82bb988c67..72fa7d881b 100644
--- a/test/functional/legacy/066_visual_block_tab_spec.lua
+++ b/test/functional/legacy/066_visual_block_tab_spec.lua
@@ -1,7 +1,7 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Test for visual block shift and tab characters.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/067_augroup_exists_spec.lua b/test/functional/legacy/067_augroup_exists_spec.lua
index dc4c9c7eeb..8f6b881ed8 100644
--- a/test/functional/legacy/067_augroup_exists_spec.lua
+++ b/test/functional/legacy/067_augroup_exists_spec.lua
@@ -1,7 +1,7 @@
-- Test that groups and patterns are tested correctly when calling exists() for
-- autocommands.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/068_text_formatting_spec.lua b/test/functional/legacy/068_text_formatting_spec.lua
index cac8be77f3..e232e5073d 100644
--- a/test/functional/legacy/068_text_formatting_spec.lua
+++ b/test/functional/legacy/068_text_formatting_spec.lua
@@ -1,6 +1,10 @@
-local helpers = require('test.functional.helpers')
-local feed, insert = helpers.feed, helpers.insert
-local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+local helpers = require('test.functional.helpers')(after_each)
+
+local feed = helpers.feed
+local clear = helpers.clear
+local insert = helpers.insert
+local execute = helpers.execute
+local expect = helpers.expect
describe('text formatting', function()
setup(clear)
diff --git a/test/functional/legacy/072_undo_file_spec.lua b/test/functional/legacy/072_undo_file_spec.lua
index efcc2f2cc3..4682a82008 100644
--- a/test/functional/legacy/072_undo_file_spec.lua
+++ b/test/functional/legacy/072_undo_file_spec.lua
@@ -2,7 +2,7 @@
-- Since this script is sourced we need to explicitly break changes up in
-- undo-able pieces. Do that by setting 'undolevels'.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/074_global_var_in_viminfo_spec.lua b/test/functional/legacy/074_global_var_in_viminfo_spec.lua
index 49c4827613..2fc30c9d83 100644
--- a/test/functional/legacy/074_global_var_in_viminfo_spec.lua
+++ b/test/functional/legacy/074_global_var_in_viminfo_spec.lua
@@ -1,6 +1,7 @@
-- Tests for storing global variables in the .shada file
-local helpers, lfs = require('test.functional.helpers'), require('lfs')
+local helpers = require('test.functional.helpers')(after_each)
+local lfs = require('lfs')
local clear, execute, eq, neq, eval, wait, spawn =
helpers.clear, helpers.execute, helpers.eq, helpers.neq, helpers.eval,
helpers.wait, helpers.spawn
diff --git a/test/functional/legacy/075_maparg_spec.lua b/test/functional/legacy/075_maparg_spec.lua
index 82965f5cb2..e9d2acdaf5 100644
--- a/test/functional/legacy/075_maparg_spec.lua
+++ b/test/functional/legacy/075_maparg_spec.lua
@@ -1,7 +1,7 @@
-- Tests for maparg().
-- Also test utf8 map with a 0x80 byte.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/076_completefunc_spec.lua b/test/functional/legacy/076_completefunc_spec.lua
index 8af3be003e..bf3f56eb84 100644
--- a/test/functional/legacy/076_completefunc_spec.lua
+++ b/test/functional/legacy/076_completefunc_spec.lua
@@ -1,6 +1,6 @@
-- Tests for completefunc/omnifunc.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, expect, execute = helpers.clear, helpers.expect, helpers.execute
diff --git a/test/functional/legacy/077_mf_hash_grow_spec.lua b/test/functional/legacy/077_mf_hash_grow_spec.lua
index 029fe98fe9..b43263300d 100644
--- a/test/functional/legacy/077_mf_hash_grow_spec.lua
+++ b/test/functional/legacy/077_mf_hash_grow_spec.lua
@@ -6,7 +6,7 @@
-- cksum is part of POSIX and so should be available on most Unixes.
-- If it isn't available then the test will be skipped.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed = helpers.feed
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/078_swapfile_recover_spec.lua b/test/functional/legacy/078_swapfile_recover_spec.lua
index e48fddaac1..4390ba2ca8 100644
--- a/test/functional/legacy/078_swapfile_recover_spec.lua
+++ b/test/functional/legacy/078_swapfile_recover_spec.lua
@@ -3,7 +3,7 @@
-- restored. We need about 10000 lines of 100 characters to get two levels of
-- pointer blocks.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, expect, source = helpers.clear, helpers.expect, helpers.source
describe('78', function()
diff --git a/test/functional/legacy/080_substitute_spec.lua b/test/functional/legacy/080_substitute_spec.lua
index 96082364e0..1bdae9be59 100644
--- a/test/functional/legacy/080_substitute_spec.lua
+++ b/test/functional/legacy/080_substitute_spec.lua
@@ -2,7 +2,7 @@
-- Test for submatch() on substitue().
-- Test for *:s%* on :substitute.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
local eq, eval = helpers.eq, helpers.eval
diff --git a/test/functional/legacy/081_coptions_movement_spec.lua b/test/functional/legacy/081_coptions_movement_spec.lua
index f27667b976..2ac1332687 100644
--- a/test/functional/legacy/081_coptions_movement_spec.lua
+++ b/test/functional/legacy/081_coptions_movement_spec.lua
@@ -1,6 +1,6 @@
-- Test for t movement command and 'cpo-;' setting
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/082_string_comparison_spec.lua b/test/functional/legacy/082_string_comparison_spec.lua
index 933c6c8fa3..d6f3c45e1f 100644
--- a/test/functional/legacy/082_string_comparison_spec.lua
+++ b/test/functional/legacy/082_string_comparison_spec.lua
@@ -1,7 +1,7 @@
-- Tests for case-insensitive UTF-8 comparisons (utf_strnicmp() in mbyte.c)
-- Also test "g~ap".
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, source = helpers.feed, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua b/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua
index 6b5ee60568..e94b46ca66 100644
--- a/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua
+++ b/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua
@@ -1,6 +1,6 @@
-- Tests for tag search with !_TAG_FILE_ENCODING.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source, clear, expect, write_file = helpers.insert,
helpers.source, helpers.clear, helpers.expect, helpers.write_file
diff --git a/test/functional/legacy/084_curswant_spec.lua b/test/functional/legacy/084_curswant_spec.lua
index 946dd5e501..818914eeb9 100644
--- a/test/functional/legacy/084_curswant_spec.lua
+++ b/test/functional/legacy/084_curswant_spec.lua
@@ -1,6 +1,6 @@
-- Tests for curswant not changing when setting an option.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source = helpers.insert, helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/088_conceal_tabs_spec.lua b/test/functional/legacy/088_conceal_tabs_spec.lua
index c78f4e5c3e..00e7312bf8 100644
--- a/test/functional/legacy/088_conceal_tabs_spec.lua
+++ b/test/functional/legacy/088_conceal_tabs_spec.lua
@@ -1,7 +1,7 @@
-- Tests for correct display (cursor column position) with +conceal and
-- tabulators.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, clear, execute =
helpers.feed, helpers.insert, helpers.clear, helpers.execute
diff --git a/test/functional/legacy/089_number_relnumber_findfile_spec.lua b/test/functional/legacy/089_number_relnumber_findfile_spec.lua
index f72ebf3f72..7a87fc8603 100644
--- a/test/functional/legacy/089_number_relnumber_findfile_spec.lua
+++ b/test/functional/legacy/089_number_relnumber_findfile_spec.lua
@@ -2,7 +2,7 @@
-- This is not all that useful now that the options are no longer reset when
-- setting the other.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed = helpers.feed
local clear, expect, source = helpers.clear, helpers.expect, helpers.source
diff --git a/test/functional/legacy/090_sha256_spec.lua b/test/functional/legacy/090_sha256_spec.lua
index 95e50063a1..e364af9400 100644
--- a/test/functional/legacy/090_sha256_spec.lua
+++ b/test/functional/legacy/090_sha256_spec.lua
@@ -1,6 +1,6 @@
-- Tests for sha256() function.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source = helpers.insert, helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/091_context_variables_spec.lua b/test/functional/legacy/091_context_variables_spec.lua
index 2c46ef643c..edf497d397 100644
--- a/test/functional/legacy/091_context_variables_spec.lua
+++ b/test/functional/legacy/091_context_variables_spec.lua
@@ -1,6 +1,6 @@
-- Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar().
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source = helpers.insert, helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
index f76ba25d7a..f8564384e9 100644
--- a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
+++ b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
@@ -3,7 +3,7 @@
--
-- Same as legacy test 93 but using UTF-8 file encoding.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
index bf3af1a827..719ce25099 100644
--- a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
+++ b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
@@ -3,7 +3,7 @@
--
-- Same as legacy test 92 but using Latin-1 file encoding.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/094_visual_mode_operators_spec.lua b/test/functional/legacy/094_visual_mode_operators_spec.lua
index 4dce39b8d2..a52fa00672 100644
--- a/test/functional/legacy/094_visual_mode_operators_spec.lua
+++ b/test/functional/legacy/094_visual_mode_operators_spec.lua
@@ -4,7 +4,7 @@
-- followed by an operator and those executed via Operator-pending mode. Also
-- part of the test are mappings, counts, and repetition with the . command.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/095_regexp_multibyte_spec.lua b/test/functional/legacy/095_regexp_multibyte_spec.lua
index a80a247612..845ebaaad7 100644
--- a/test/functional/legacy/095_regexp_multibyte_spec.lua
+++ b/test/functional/legacy/095_regexp_multibyte_spec.lua
@@ -3,7 +3,7 @@
-- A pattern that gives the expected result produces OK, so that we know it was
-- actually tried.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source = helpers.insert, helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/096_location_list_spec.lua b/test/functional/legacy/096_location_list_spec.lua
index 6e2f22ea33..eac8d6356d 100644
--- a/test/functional/legacy/096_location_list_spec.lua
+++ b/test/functional/legacy/096_location_list_spec.lua
@@ -6,7 +6,7 @@
-- C. make sure that the location list window is not reused instead of the window
-- it belongs to.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source = helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua
index 5c467fbb20..a6c146891a 100644
--- a/test/functional/legacy/097_glob_path_spec.lua
+++ b/test/functional/legacy/097_glob_path_spec.lua
@@ -2,7 +2,7 @@
-- Test whether glob()/globpath() return correct results with certain escaped
-- characters.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/098_scrollbind_spec.lua b/test/functional/legacy/098_scrollbind_spec.lua
index 6850e373ab..d22aefdcbc 100644
--- a/test/functional/legacy/098_scrollbind_spec.lua
+++ b/test/functional/legacy/098_scrollbind_spec.lua
@@ -1,6 +1,6 @@
-- Test for 'scrollbind' causing an unexpected scroll of one of the windows.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source = helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/101_hlsearch_spec.lua b/test/functional/legacy/101_hlsearch_spec.lua
index 335d275c2a..fa29e5fbe8 100644
--- a/test/functional/legacy/101_hlsearch_spec.lua
+++ b/test/functional/legacy/101_hlsearch_spec.lua
@@ -1,6 +1,6 @@
-- Test for v:hlsearch
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
@@ -61,6 +61,6 @@ describe('v:hlsearch', function()
0:not highlighted
1:highlighted
0:not highlighted
- Vim(let):E706:]])
+ Vim(let):E745:]])
end)
end)
diff --git a/test/functional/legacy/102_fnameescape_spec.lua b/test/functional/legacy/102_fnameescape_spec.lua
index a3b0313d7a..c1a6c57956 100644
--- a/test/functional/legacy/102_fnameescape_spec.lua
+++ b/test/functional/legacy/102_fnameescape_spec.lua
@@ -1,6 +1,6 @@
-- Test if fnameescape is correct for special chars like!
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/103_visual_mode_reset_spec.lua b/test/functional/legacy/103_visual_mode_reset_spec.lua
index c1407ef10a..d05b47fa32 100644
--- a/test/functional/legacy/103_visual_mode_reset_spec.lua
+++ b/test/functional/legacy/103_visual_mode_reset_spec.lua
@@ -1,6 +1,6 @@
-- Test for visual mode not being reset causing E315 error.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, source = helpers.feed, helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/104_let_assignment_spec.lua b/test/functional/legacy/104_let_assignment_spec.lua
index a2431da835..27c3715231 100644
--- a/test/functional/legacy/104_let_assignment_spec.lua
+++ b/test/functional/legacy/104_let_assignment_spec.lua
@@ -1,6 +1,6 @@
-- Tests for :let.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, source = helpers.clear, helpers.source
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/106_errorformat_spec.lua b/test/functional/legacy/106_errorformat_spec.lua
index 5958f1aa7b..2b17d63378 100644
--- a/test/functional/legacy/106_errorformat_spec.lua
+++ b/test/functional/legacy/106_errorformat_spec.lua
@@ -1,6 +1,6 @@
-- Tests for errorformat.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/107_adjust_window_and_contents_spec.lua b/test/functional/legacy/107_adjust_window_and_contents_spec.lua
index 7a6de3d748..ce8d967e00 100644
--- a/test/functional/legacy/107_adjust_window_and_contents_spec.lua
+++ b/test/functional/legacy/107_adjust_window_and_contents_spec.lua
@@ -1,6 +1,6 @@
-- Tests for adjusting window and contents
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local insert = helpers.insert
local clear, execute = helpers.clear, helpers.execute
diff --git a/test/functional/legacy/108_backtrace_debug_commands_spec.lua b/test/functional/legacy/108_backtrace_debug_commands_spec.lua
index 6df645d255..a03092e446 100644
--- a/test/functional/legacy/108_backtrace_debug_commands_spec.lua
+++ b/test/functional/legacy/108_backtrace_debug_commands_spec.lua
@@ -1,6 +1,6 @@
-- Tests for backtrace debug commands.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, clear = helpers.feed, helpers.clear
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua
new file mode 100644
index 0000000000..c128aaf115
--- /dev/null
+++ b/test/functional/legacy/arglist_spec.lua
@@ -0,0 +1,268 @@
+-- Test argument list commands
+
+local helpers = require('test.functional.helpers')(after_each)
+local clear, execute, eq = helpers.clear, helpers.execute, helpers.eq
+local eval, exc_exec, neq = helpers.eval, helpers.exc_exec, helpers.neq
+
+describe('argument list commands', function()
+ before_each(clear)
+
+ local function init_abc()
+ execute('args a b c')
+ execute('next')
+ end
+
+ local function reset_arglist()
+ execute('arga a | %argd')
+ end
+
+ local function assert_fails(cmd, err)
+ neq(exc_exec(cmd):find(err), nil)
+ end
+
+ it('test that argidx() works', function()
+ execute('args a b c')
+ execute('last')
+ eq(2, eval('argidx()'))
+ execute('%argdelete')
+ eq(0, eval('argidx()'))
+
+ execute('args a b c')
+ eq(0, eval('argidx()'))
+ execute('next')
+ eq(1, eval('argidx()'))
+ execute('next')
+ eq(2, eval('argidx()'))
+ execute('1argdelete')
+ eq(1, eval('argidx()'))
+ execute('1argdelete')
+ eq(0, eval('argidx()'))
+ execute('1argdelete')
+ eq(0, eval('argidx()'))
+ end)
+
+ it('test that argadd() works', function()
+ execute('%argdelete')
+ execute('argadd a b c')
+ eq(0, eval('argidx()'))
+
+ execute('%argdelete')
+ execute('argadd a')
+ eq(0, eval('argidx()'))
+ execute('argadd b c d')
+ eq(0, eval('argidx()'))
+
+ init_abc()
+ execute('argadd x')
+ eq({'a', 'b', 'x', 'c'}, eval('argv()'))
+ eq(1, eval('argidx()'))
+
+ init_abc()
+ execute('0argadd x')
+ eq({'x', 'a', 'b', 'c'}, eval('argv()'))
+ eq(2, eval('argidx()'))
+
+ init_abc()
+ execute('1argadd x')
+ eq({'a', 'x', 'b', 'c'}, eval('argv()'))
+ eq(2, eval('argidx()'))
+
+ init_abc()
+ execute('$argadd x')
+ eq({'a', 'b', 'c', 'x'}, eval('argv()'))
+ eq(1, eval('argidx()'))
+
+ init_abc()
+ execute('$argadd x')
+ execute('+2argadd y')
+ eq({'a', 'b', 'c', 'x', 'y'}, eval('argv()'))
+ eq(1, eval('argidx()'))
+
+ execute('%argd')
+ execute('edit d')
+ execute('arga')
+ eq(1, eval('len(argv())'))
+ eq('d', eval('get(argv(), 0, "")'))
+
+ execute('%argd')
+ execute('new')
+ execute('arga')
+ eq(0, eval('len(argv())'))
+ end)
+
+ it('test for [count]argument and [count]argdelete commands', function()
+ reset_arglist()
+ execute('let save_hidden = &hidden')
+ execute('set hidden')
+ execute('let g:buffers = []')
+ execute('augroup TEST')
+ execute([[au BufEnter * call add(buffers, expand('%:t'))]])
+ execute('augroup END')
+
+ execute('argadd a b c d')
+ execute('$argu')
+ execute('$-argu')
+ execute('-argu')
+ execute('1argu')
+ execute('+2argu')
+
+ execute('augroup TEST')
+ execute('au!')
+ execute('augroup END')
+
+ eq({'d', 'c', 'b', 'a', 'c'}, eval('g:buffers'))
+
+ execute('redir => result')
+ execute('ar')
+ execute('redir END')
+ eq(1, eval([[result =~# 'a b \[c] d']]))
+
+ execute('.argd')
+ eq({'a', 'b', 'd'}, eval('argv()'))
+
+ execute('-argd')
+ eq({'a', 'd'}, eval('argv()'))
+
+ execute('$argd')
+ eq({'a'}, eval('argv()'))
+
+ execute('1arga c')
+ execute('1arga b')
+ execute('$argu')
+ execute('$arga x')
+ eq({'a', 'b', 'c', 'x'}, eval('argv()'))
+
+ execute('0arga Y')
+ eq({'Y', 'a', 'b', 'c', 'x'}, eval('argv()'))
+
+ execute('%argd')
+ eq({}, eval('argv()'))
+
+ execute('arga a b c d e f')
+ execute('2,$-argd')
+ eq({'a', 'f'}, eval('argv()'))
+
+ execute('let &hidden = save_hidden')
+
+ -- Setting the argument list should fail when the current buffer has
+ -- unsaved changes
+ execute('%argd')
+ execute('enew!')
+ execute('set modified')
+ assert_fails('args x y z', 'E37:')
+ execute('args! x y z')
+ eq({'x', 'y', 'z'}, eval('argv()'))
+ eq('x', eval('expand("%:t")'))
+
+ execute('%argdelete')
+ assert_fails('argument', 'E163:')
+ end)
+
+ it('test for 0argadd and 0argedit', function()
+ reset_arglist()
+
+ execute('arga a b c d')
+ execute('2argu')
+ execute('0arga added')
+ eq({'added', 'a', 'b', 'c', 'd'}, eval('argv()'))
+
+ execute('%argd')
+ execute('arga a b c d')
+ execute('2argu')
+ execute('0arge edited')
+ eq({'edited', 'a', 'b', 'c', 'd'}, eval('argv()'))
+
+ execute('2argu')
+ execute('arga third')
+ eq({'edited', 'a', 'third', 'b', 'c', 'd'}, eval('argv()'))
+ end)
+
+ it('test for argc()', function()
+ reset_arglist()
+ eq(0, eval('argc()'))
+ execute('argadd a b')
+ eq(2, eval('argc()'))
+ end)
+
+ it('test for arglistid()', function()
+ reset_arglist()
+ execute('arga a b')
+ eq(0, eval('arglistid()'))
+ execute('split')
+ execute('arglocal')
+ eq(1, eval('arglistid()'))
+ execute('tabnew | tabfirst')
+ eq(0, eval('arglistid(2)'))
+ eq(1, eval('arglistid(1, 1)'))
+ eq(0, eval('arglistid(2, 1)'))
+ eq(1, eval('arglistid(1, 2)'))
+ execute('tabonly | only | enew!')
+ execute('argglobal')
+ eq(0, eval('arglistid()'))
+ end)
+
+ it('test for argv()', function()
+ reset_arglist()
+ eq({}, eval('argv()'))
+ eq('', eval('argv(2)'))
+ execute('argadd a b c d')
+ eq('c', eval('argv(2)'))
+ end)
+
+ it('test for :argedit command', function()
+ reset_arglist()
+ execute('argedit a')
+ eq({'a'}, eval('argv()'))
+ eq('a', eval('expand("%:t")'))
+ execute('argedit b')
+ eq({'a', 'b'}, eval('argv()'))
+ eq('b', eval('expand("%:t")'))
+ execute('argedit a')
+ eq({'a', 'b'}, eval('argv()'))
+ eq('a', eval('expand("%:t")'))
+ assert_fails('argedit a b', 'E172:')
+ execute('argedit c')
+ eq({'a', 'c', 'b'}, eval('argv()'))
+ execute('0argedit x')
+ eq({'x', 'a', 'c', 'b'}, eval('argv()'))
+ execute('enew! | set modified')
+ assert_fails('argedit y', 'E37:')
+ execute('argedit! y')
+ eq({'x', 'y', 'a', 'c', 'b'}, eval('argv()'))
+ execute('%argd')
+ end)
+
+ it('test for :argdelete command', function()
+ reset_arglist()
+ execute('args aa a aaa b bb')
+ execute('argdelete a*')
+ eq({'b', 'bb'}, eval('argv()'))
+ eq('aa', eval('expand("%:t")'))
+ execute('last')
+ execute('argdelete %')
+ eq({'b'}, eval('argv()'))
+ assert_fails('argdelete', 'E471:')
+ assert_fails('1,100argdelete', 'E16:')
+ execute('%argd')
+ end)
+
+ it('test for the :next, :prev, :first, :last, :rewind commands', function()
+ reset_arglist()
+ execute('args a b c d')
+ execute('last')
+ eq(3, eval('argidx()'))
+ assert_fails('next', 'E165:')
+ execute('prev')
+ eq(2, eval('argidx()'))
+ execute('Next')
+ eq(1, eval('argidx()'))
+ execute('first')
+ eq(0, eval('argidx()'))
+ assert_fails('prev', 'E164:')
+ execute('3next')
+ eq(3, eval('argidx()'))
+ execute('rewind')
+ eq(0, eval('argidx()'))
+ execute('%argd')
+ end)
+end)
diff --git a/test/functional/legacy/argument_0count_spec.lua b/test/functional/legacy/argument_0count_spec.lua
deleted file mode 100644
index 6e8b60547b..0000000000
--- a/test/functional/legacy/argument_0count_spec.lua
+++ /dev/null
@@ -1,28 +0,0 @@
--- Tests for :0argadd and :0argedit
-
-local helpers = require('test.functional.helpers')
-local eq, eval, clear, execute =
- helpers.eq, helpers.eval, helpers.clear, helpers.execute
-
-describe('argument_0count', function()
- setup(clear)
-
- it('is working', function()
- execute('arga a b c d')
- eq({'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('2argu')
- execute('0arga added')
- eq({'added', 'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('2argu')
- execute('arga third')
- eq({'added', 'a', 'third', 'b', 'c', 'd'}, eval('argv()'))
- execute('%argd')
- execute('arga a b c d')
- execute('2argu')
- execute('0arge edited')
- eq({'edited', 'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('2argu')
- execute('arga third')
- eq({'edited', 'a', 'third', 'b', 'c', 'd'}, eval('argv()'))
- end)
-end)
diff --git a/test/functional/legacy/argument_count_spec.lua b/test/functional/legacy/argument_count_spec.lua
deleted file mode 100644
index 182cce9475..0000000000
--- a/test/functional/legacy/argument_count_spec.lua
+++ /dev/null
@@ -1,47 +0,0 @@
--- Tests for :[count]argument! and :[count]argdelete
-
-local helpers = require('test.functional.helpers')
-local clear, execute, eq, eval =
- helpers.clear, helpers.execute, helpers.eq, helpers.eval
-
-describe('argument_count', function()
- setup(clear)
-
- it('is working', function()
- execute('%argd')
- execute('argadd a b c d')
- eq({'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('set hidden')
- execute('let buffers = []')
- execute('augroup TEST')
- execute([[au BufEnter * call add(buffers, expand('%:t'))]])
- execute('augroup END')
- execute('$argu')
- execute('$-argu')
- execute('-argu')
- execute('1argu')
- execute('+2argu')
- execute('augroup TEST')
- execute('au!')
- execute('augroup END')
- eq({'d', 'c', 'b', 'a', 'c'}, eval('buffers'))
- execute('.argd')
- eq({'a', 'b', 'd'}, eval('argv()'))
- execute('-argd')
- eq({'a', 'd'}, eval('argv()'))
- execute('$argd')
- eq({'a'}, eval('argv()'))
- execute('1arga c')
- execute('1arga b')
- execute('$argu')
- execute('$arga x')
- eq({'a', 'b', 'c', 'x'}, eval('argv()'))
- execute('0arga Y')
- eq({'Y', 'a', 'b', 'c', 'x'}, eval('argv()'))
- execute('%argd')
- eq({}, eval('argv()'))
- execute('arga a b c d e f')
- execute('2,$-argd')
- eq({'a', 'f'}, eval('argv()'))
- end)
-end)
diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua
index 1ce665360d..42dd25023a 100644
--- a/test/functional/legacy/assert_spec.lua
+++ b/test/functional/legacy/assert_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim, call = helpers.meths, helpers.call
local clear, eq = helpers.clear, helpers.eq
local source, execute = helpers.source, helpers.execute
@@ -64,6 +64,20 @@ describe('assert function:', function()
end)
end)
+ -- assert_notequal({expected}, {actual}[, {msg}])
+ describe('assert_notequal', function()
+ it('should not change v:errors when expected differs from actual', function()
+ call('assert_notequal', 'foo', 4)
+ call('assert_notequal', {1, 2, 3}, 'foo')
+ expected_empty()
+ end)
+
+ it('should change v:errors when expected is equal to actual', function()
+ call('assert_notequal', 'foo', 'foo')
+ expected_errors({"Expected 'foo' differs from 'foo'"})
+ end)
+ end)
+
-- assert_false({actual}, [, {msg}])
describe('assert_false', function()
it('should not change v:errors when actual is false', function()
@@ -141,5 +155,98 @@ describe('assert function:', function()
tmpname_two .. " line 1: 'file two'",
})
end)
+
+ it('is reset to a list by assert functions', function()
+ source([[
+ let save_verrors = v:errors
+ let v:['errors'] = {'foo': 3}
+ call assert_equal('yes', 'no')
+ let verrors = v:errors
+ let v:errors = save_verrors
+ call assert_equal(type([]), type(verrors))
+ ]])
+ expected_empty()
+ end)
+ end)
+
+ -- assert_match({pat}, {text}[, {msg}])
+ describe('assert_match', function()
+ it('should not change v:errors when pat matches text', function()
+ call('assert_match', '^f.*b.*r$', 'foobar')
+ expected_empty()
+ end)
+
+ it('should change v:errors when pat does not match text', function()
+ call('assert_match', 'bar.*foo', 'foobar')
+ expected_errors({"Pattern 'bar.*foo' does not match 'foobar'"})
+ end)
+
+ it('should set v:errors to msg when given and match fails', function()
+ call('assert_match', 'bar.*foo', 'foobar', 'wrong')
+ expected_errors({"'wrong'"})
+ end)
+ end)
+
+ -- assert_notmatch({pat}, {text}[, {msg}])
+ describe('assert_notmatch', function()
+ it('should not change v:errors when pat does not match text', function()
+ call('assert_notmatch', 'foo', 'bar')
+ call('assert_notmatch', '^foobar$', 'foobars')
+ expected_empty()
+ end)
+
+ it('should change v:errors when pat matches text', function()
+ call('assert_notmatch', 'foo', 'foobar')
+ expected_errors({"Pattern 'foo' does match 'foobar'"})
+ end)
+ end)
+
+ -- assert_fails({cmd}, [, {error}])
+ describe('assert_fails', function()
+ it('should change v:errors when error does not match v:errmsg', function()
+ execute([[call assert_fails('xxx', {})]])
+ execute([[call assert_match("Expected {} but got 'E731:", v:errors[0])]])
+ expected_errors({"Expected {} but got 'E731: using Dictionary as a String'"})
+ end)
+
+ it('should not change v:errors when cmd errors', function()
+ call('assert_fails', 'NonexistentCmd')
+ expected_empty()
+ end)
+
+ it('should change v:errors when cmd succeeds', function()
+ call('assert_fails', 'call empty("")')
+ expected_errors({'command did not fail: call empty("")'})
+ end)
+ end)
+
+ -- assert_exception({cmd}, [, {error}])
+ describe('assert_exception()', function()
+ it('should assert thrown exceptions properly', function()
+ source([[
+ try
+ nocommand
+ catch
+ call assert_exception('E492')
+ endtry
+ ]])
+ expected_empty()
+ end)
+
+ it('should work properly when nested', function()
+ source([[
+ try
+ nocommand
+ catch
+ try
+ " illegal argument, get NULL for error
+ call assert_exception([])
+ catch
+ call assert_exception('E730')
+ endtry
+ endtry
+ ]])
+ expected_empty()
+ end)
end)
end)
diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua
index 6349371808..28037e17c5 100644
--- a/test/functional/legacy/autocmd_option_spec.lua
+++ b/test/functional/legacy/autocmd_option_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim = helpers.meths
local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq
local curbuf, buf = helpers.curbuf, helpers.bufmeths
diff --git a/test/functional/legacy/autoformat_join_spec.lua b/test/functional/legacy/autoformat_join_spec.lua
index a99cabca24..4110d66f5b 100644
--- a/test/functional/legacy/autoformat_join_spec.lua
+++ b/test/functional/legacy/autoformat_join_spec.lua
@@ -1,7 +1,7 @@
-- vim: set foldmethod=marker foldmarker=[[,]] :
-- Tests for setting the '[,'] marks when joining lines.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/backspace_opt_spec.lua b/test/functional/legacy/backspace_opt_spec.lua
index b40019a410..90bc6f74f0 100644
--- a/test/functional/legacy/backspace_opt_spec.lua
+++ b/test/functional/legacy/backspace_opt_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local call, clear = helpers.call, helpers.clear
local source, eq, nvim = helpers.source, helpers.eq, helpers.meths
diff --git a/test/functional/legacy/breakindent_spec.lua b/test/functional/legacy/breakindent_spec.lua
index a12d4add10..2504fe8e51 100644
--- a/test/functional/legacy/breakindent_spec.lua
+++ b/test/functional/legacy/breakindent_spec.lua
@@ -1,6 +1,6 @@
-- Test for breakindent
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/cdo_spec.lua b/test/functional/legacy/cdo_spec.lua
index 4b313ede3f..5e46431cc1 100644
--- a/test/functional/legacy/cdo_spec.lua
+++ b/test/functional/legacy/cdo_spec.lua
@@ -1,6 +1,6 @@
-- Tests for the :cdo, :cfdo, :ldo and :lfdo commands
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim, clear = helpers.meths, helpers.clear
local call, feed = helpers.call, helpers.feed
local source, eq = helpers.source, helpers.eq
diff --git a/test/functional/legacy/changelist_spec.lua b/test/functional/legacy/changelist_spec.lua
index 7c696369d4..c718da3736 100644
--- a/test/functional/legacy/changelist_spec.lua
+++ b/test/functional/legacy/changelist_spec.lua
@@ -1,7 +1,7 @@
-- Test changelist position after splitting window
-- Set 'undolevels' to make changelist for sourced file
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/charsearch_spec.lua b/test/functional/legacy/charsearch_spec.lua
index 4a83801cfc..ef3369728d 100644
--- a/test/functional/legacy/charsearch_spec.lua
+++ b/test/functional/legacy/charsearch_spec.lua
@@ -1,6 +1,6 @@
-- Test for character searches
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/close_count_spec.lua b/test/functional/legacy/close_count_spec.lua
index ee6b29c618..ad1812f22e 100644
--- a/test/functional/legacy/close_count_spec.lua
+++ b/test/functional/legacy/close_count_spec.lua
@@ -1,6 +1,6 @@
-- Tests for :[count]close! and :[count]hide
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, eval, eq, clear, execute =
helpers.feed, helpers.eval, helpers.eq, helpers.clear, helpers.execute
diff --git a/test/functional/legacy/command_count_spec.lua b/test/functional/legacy/command_count_spec.lua
index d9b4f09263..c463ada968 100644
--- a/test/functional/legacy/command_count_spec.lua
+++ b/test/functional/legacy/command_count_spec.lua
@@ -1,25 +1,20 @@
-- Test for user command counts
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, source, expect = helpers.clear, helpers.source, helpers.expect
-local execute, spawn = helpers.execute, helpers.spawn
-local nvim_prog = helpers.nvim_prog
+local execute = helpers.execute
describe('command_count', function()
- setup(clear)
- teardown(function()
- os.remove('test.out')
- end)
-
it('is working', function()
-- It is relevant for the test to load a file initially. If this is
-- emulated with :arg the buffer count is wrong as nvim creates an empty
-- buffer if it was started without a filename.
- local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed',
- 'test_command_count.in'})
- helpers.set_session(nvim2)
+ clear('test_command_count.in')
source([[
+ let g:tmpname = tempname()
+ call mkdir(g:tmpname)
+ execute "cd ".g:tmpname
lang C
let g:lines = []
com -range=% RangeLines
@@ -239,5 +234,10 @@ describe('command_count', function()
bufdo: 2 3 4 5 6 7 8 9 10 15
bufdo: 4 5 6 7
tabdo: 2 3 4]])
+
+ source([[
+ cd ..
+ call delete(g:tmpname, 'rf')
+ ]])
end)
end)
diff --git a/test/functional/legacy/comparators_spec.lua b/test/functional/legacy/comparators_spec.lua
index e3fa3eea23..27879b0f65 100644
--- a/test/functional/legacy/comparators_spec.lua
+++ b/test/functional/legacy/comparators_spec.lua
@@ -1,6 +1,6 @@
-- " Test for expression comparators.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, eq = helpers.clear, helpers.eq
local eval, execute = helpers.eval, helpers.execute
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
index cd18a8f750..42238b3a9e 100644
--- a/test/functional/legacy/delete_spec.lua
+++ b/test/functional/legacy/delete_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, source = helpers.clear, helpers.source
local eq, eval, execute = helpers.eq, helpers.eval, helpers.execute
diff --git a/test/functional/legacy/erasebackword_spec.lua b/test/functional/legacy/erasebackword_spec.lua
index cb3967b763..33b7704b65 100644
--- a/test/functional/legacy/erasebackword_spec.lua
+++ b/test/functional/legacy/erasebackword_spec.lua
@@ -1,6 +1,6 @@
-- Test for CTRL-W in Insert mode
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, expect = helpers.clear, helpers.feed, helpers.expect
describe('CTRL-W in Insert mode', function()
diff --git a/test/functional/legacy/eval_spec.lua b/test/functional/legacy/eval_spec.lua
index 3ff1092a4b..3684fe714d 100644
--- a/test/functional/legacy/eval_spec.lua
+++ b/test/functional/legacy/eval_spec.lua
@@ -1,15 +1,10 @@
-- Test for various eval features.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
local eq, eval, write_file = helpers.eq, helpers.eval, helpers.write_file
-local function has_clipboard()
- clear()
- return 1 == eval("has('clipboard')")
-end
-
describe('eval', function()
setup(function()
write_file('test_eval_setup.vim', [[
@@ -539,8 +534,13 @@ describe('eval', function()
=: type v; value: abc/]].."\000 (['abc/\000"..[[']), expr: "abc/]]..'\000'..[[" (['"abc/]]..'\000'..[["'])]])
end)
- if has_clipboard() then
- it('system clipboard', function()
+ describe('system clipboard', function()
+ before_each(function()
+ execute('let &runtimepath = "test/functional/fixtures,".&runtimepath')
+ execute('call getreg("*")') -- force load of provider
+ end)
+
+ it('works', function()
insert([[
Some first line (this text was at the top of the old test_eval.in).
@@ -570,9 +570,7 @@ describe('eval', function()
*: type V; value: clipboard contents]]..'\00'..[[ (['clipboard contents']), expr: clipboard contents]]..'\00'..[[ (['clipboard contents'])
*: type V; value: something else]]..'\00'..[[ (['something else']), expr: something else]]..'\00'..[[ (['something else'])]])
end)
- else
- pending('system clipboard not available', function() end)
- end
+ end)
it('errors', function()
source([[
diff --git a/test/functional/legacy/expand_spec.lua b/test/functional/legacy/expand_spec.lua
new file mode 100644
index 0000000000..7bf6fb67dc
--- /dev/null
+++ b/test/functional/legacy/expand_spec.lua
@@ -0,0 +1,77 @@
+-- Test for expanding file names
+
+local helpers = require('test.functional.helpers')(after_each)
+local eq = helpers.eq
+local call = helpers.call
+local nvim = helpers.meths
+local clear = helpers.clear
+local source = helpers.source
+
+local function expected_empty()
+ eq({}, nvim.get_vvar('errors'))
+end
+
+describe('expand file name', function()
+ after_each(function()
+ helpers.rmdir('Xdir1')
+ helpers.rmdir('Xdir2')
+ helpers.rmdir('Xdir3')
+ helpers.rmdir('Xdir4')
+ end)
+
+ before_each(function()
+ clear()
+
+ source([[
+ func Test_with_directories()
+ call mkdir('Xdir1')
+ call mkdir('Xdir2')
+ call mkdir('Xdir3')
+ cd Xdir3
+ call mkdir('Xdir4')
+ cd ..
+
+ split Xdir1/file
+ call setline(1, ['a', 'b'])
+ w
+ w Xdir3/Xdir4/file
+ close
+
+ next Xdir?/*/file
+ call assert_equal('Xdir3/Xdir4/file', expand('%'))
+ if has('unix')
+ next! Xdir?/*/nofile
+ call assert_equal('Xdir?/*/nofile', expand('%'))
+ endif
+ " Edit another file, on MS-Windows the swap file would be in use and can't
+ " be deleted
+ edit foo
+
+ call assert_equal(0, delete('Xdir1', 'rf'))
+ call assert_equal(0, delete('Xdir2', 'rf'))
+ call assert_equal(0, delete('Xdir3', 'rf'))
+ endfunc
+
+ func Test_with_tilde()
+ let dir = getcwd()
+ call mkdir('Xdir ~ dir')
+ call assert_true(isdirectory('Xdir ~ dir'))
+ cd Xdir\ ~\ dir
+ call assert_true(getcwd() =~ 'Xdir \~ dir')
+ exe 'cd ' . fnameescape(dir)
+ call delete('Xdir ~ dir', 'd')
+ call assert_false(isdirectory('Xdir ~ dir'))
+ endfunc
+ ]])
+ end)
+
+ it('works with directories', function()
+ call('Test_with_directories')
+ expected_empty()
+ end)
+
+ it('works with tilde', function()
+ call('Test_with_tilde')
+ expected_empty()
+ end)
+end)
diff --git a/test/functional/legacy/file_perm_spec.lua b/test/functional/legacy/file_perm_spec.lua
index cabeecdc9c..98bdf630dd 100644
--- a/test/functional/legacy/file_perm_spec.lua
+++ b/test/functional/legacy/file_perm_spec.lua
@@ -1,7 +1,7 @@
-- Test getting and setting file permissions.
require('os')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, call, eq = helpers.clear, helpers.call, helpers.eq
local neq, exc_exec = helpers.neq, helpers.exc_exec
diff --git a/test/functional/legacy/fixeol_spec.lua b/test/functional/legacy/fixeol_spec.lua
index 2d1824c8cd..bba1415535 100644
--- a/test/functional/legacy/fixeol_spec.lua
+++ b/test/functional/legacy/fixeol_spec.lua
@@ -1,6 +1,6 @@
-- Tests for 'fixeol'
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed = helpers.feed
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/fnamemodify_spec.lua b/test/functional/legacy/fnamemodify_spec.lua
index 2a32aea127..f614b07b36 100644
--- a/test/functional/legacy/fnamemodify_spec.lua
+++ b/test/functional/legacy/fnamemodify_spec.lua
@@ -1,6 +1,6 @@
-- Test filename modifiers.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, source = helpers.clear, helpers.source
local call, eq, nvim = helpers.call, helpers.eq, helpers.meths
diff --git a/test/functional/legacy/function_sort_spec.lua b/test/functional/legacy/function_sort_spec.lua
index 9083911021..1b65f1ce95 100644
--- a/test/functional/legacy/function_sort_spec.lua
+++ b/test/functional/legacy/function_sort_spec.lua
@@ -1,7 +1,10 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
+local execute = helpers.execute
+local exc_exec = helpers.exc_exec
+local neq = helpers.neq
describe('sort', function()
before_each(clear)
@@ -26,4 +29,25 @@ describe('sort', function()
it('numbers compared as float', function()
eq({0.28, 3, 13.5}, eval("sort([13.5, 0.28, 3], 'f')"))
end)
+
+ it('ability to call sort() from a compare function', function()
+ execute('func Compare1(a, b) abort')
+ execute([[call sort(range(3), 'Compare2')]])
+ execute('return a:a - a:b')
+ execute('endfunc')
+
+ execute('func Compare2(a, b) abort')
+ execute('return a:a - a:b')
+ execute('endfunc')
+ eq({1, 3, 5}, eval("sort([3, 1, 5], 'Compare1')"))
+ end)
+
+ it('default sort', function()
+ -- docs say omitted, empty or zero argument sorts on string representation
+ eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"])'))
+ eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval([[sort([3.3, 1, "2", "A", "a", "AA"], '')]]))
+ eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"], 0)'))
+ eq({'2', 'A', 'a', 'AA', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"], 1)'))
+ neq(exc_exec('call sort([3.3, 1, "2"], 3)'):find('E474:'), nil)
+ end)
end)
diff --git a/test/functional/legacy/getcwd_spec.lua b/test/functional/legacy/getcwd_spec.lua
new file mode 100644
index 0000000000..3bb9930b74
--- /dev/null
+++ b/test/functional/legacy/getcwd_spec.lua
@@ -0,0 +1,86 @@
+-- Tests for getcwd(), haslocaldir(), and :lcd
+
+local helpers = require('test.functional.helpers')(after_each)
+local eq, eval, source = helpers.eq, helpers.eval, helpers.source
+local call, clear, execute = helpers.call, helpers.clear, helpers.execute
+
+describe('getcwd', function()
+ before_each(clear)
+
+ after_each(function()
+ helpers.rmdir('Xtopdir')
+ end)
+
+ it('is working', function()
+ source([[
+ function! GetCwdInfo(win, tab)
+ let tab_changed = 0
+ let mod = ":t"
+ if a:tab > 0 && a:tab != tabpagenr()
+ let tab_changed = 1
+ exec "tabnext " . a:tab
+ endif
+ let bufname = fnamemodify(bufname(winbufnr(a:win)), mod)
+ if tab_changed
+ tabprevious
+ endif
+ if a:win == 0 && a:tab == 0
+ let dirname = fnamemodify(getcwd(), mod)
+ let lflag = haslocaldir()
+ elseif a:tab == 0
+ let dirname = fnamemodify(getcwd(a:win), mod)
+ let lflag = haslocaldir(a:win)
+ else
+ let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
+ let lflag = haslocaldir(a:win, a:tab)
+ endif
+ return bufname . ' ' . dirname . ' ' . lflag
+ endfunction
+ ]])
+ execute('new')
+ execute('let cwd=getcwd()')
+ call('mkdir', 'Xtopdir')
+ execute('silent cd Xtopdir')
+ call('mkdir', 'Xdir1')
+ call('mkdir', 'Xdir2')
+ call('mkdir', 'Xdir3')
+ execute('new a')
+ execute('new b')
+ execute('new c')
+ execute('3wincmd w')
+ execute('silent lcd Xdir1')
+ eq('a Xdir1 1', eval('GetCwdInfo(0, 0)'))
+ execute('wincmd W')
+ eq('b Xtopdir 0', eval('GetCwdInfo(0, 0)'))
+ execute('wincmd W')
+ execute('silent lcd Xdir3')
+ eq('c Xdir3 1', eval('GetCwdInfo(0, 0)'))
+ eq('a Xdir1 1', eval('GetCwdInfo(bufwinnr("a"), 0)'))
+ eq('b Xtopdir 0', eval('GetCwdInfo(bufwinnr("b"), 0)'))
+ eq('c Xdir3 1', eval('GetCwdInfo(bufwinnr("c"), 0)'))
+ execute('wincmd W')
+ eq('a Xdir1 1', eval('GetCwdInfo(bufwinnr("a"), tabpagenr())'))
+ eq('b Xtopdir 0', eval('GetCwdInfo(bufwinnr("b"), tabpagenr())'))
+ eq('c Xdir3 1', eval('GetCwdInfo(bufwinnr("c"), tabpagenr())'))
+
+ execute('tabnew x')
+ execute('new y')
+ execute('new z')
+ execute('3wincmd w')
+ eq('x Xtopdir 0', eval('GetCwdInfo(0, 0)'))
+ execute('wincmd W')
+ execute('silent lcd Xdir2')
+ eq('y Xdir2 1', eval('GetCwdInfo(0, 0)'))
+ execute('wincmd W')
+ execute('silent lcd Xdir3')
+ eq('z Xdir3 1', eval('GetCwdInfo(0, 0)'))
+ eq('x Xtopdir 0', eval('GetCwdInfo(bufwinnr("x"), 0)'))
+ eq('y Xdir2 1', eval('GetCwdInfo(bufwinnr("y"), 0)'))
+ eq('z Xdir3 1', eval('GetCwdInfo(bufwinnr("z"), 0)'))
+ execute('let tp_nr = tabpagenr()')
+ execute('tabrewind')
+ eq('x Xtopdir 0', eval('GetCwdInfo(3, tp_nr)'))
+ eq('y Xdir2 1', eval('GetCwdInfo(2, tp_nr)'))
+ eq('z Xdir3 1', eval('GetCwdInfo(1, tp_nr)'))
+ end)
+end)
diff --git a/test/functional/legacy/glob2regpat_spec.lua b/test/functional/legacy/glob2regpat_spec.lua
index 0492143616..82e7e3010f 100644
--- a/test/functional/legacy/glob2regpat_spec.lua
+++ b/test/functional/legacy/glob2regpat_spec.lua
@@ -1,6 +1,6 @@
-- Tests for signs
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute = helpers.clear, helpers.execute
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
diff --git a/test/functional/legacy/increment_spec.lua b/test/functional/legacy/increment_spec.lua
index 4aa24c0d53..0483edc934 100644
--- a/test/functional/legacy/increment_spec.lua
+++ b/test/functional/legacy/increment_spec.lua
@@ -1,6 +1,6 @@
-- Tests for using Ctrl-A/Ctrl-X on visual selections
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source, execute = helpers.source, helpers.execute
local call, clear = helpers.call, helpers.clear
local eq, nvim = helpers.eq, helpers.meths
diff --git a/test/functional/legacy/insertcount_spec.lua b/test/functional/legacy/insertcount_spec.lua
index 01236e1afe..3142f040b3 100644
--- a/test/functional/legacy/insertcount_spec.lua
+++ b/test/functional/legacy/insertcount_spec.lua
@@ -1,6 +1,6 @@
-- Tests for repeating insert and replace.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
diff --git a/test/functional/legacy/join_spec.lua b/test/functional/legacy/join_spec.lua
index 17ff2e71ad..3c4da8119c 100644
--- a/test/functional/legacy/join_spec.lua
+++ b/test/functional/legacy/join_spec.lua
@@ -1,6 +1,6 @@
-- Test for joining lines
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, eq = helpers.clear, helpers.eq
local eval, execute = helpers.eval, helpers.execute
diff --git a/test/functional/legacy/lispwords_spec.lua b/test/functional/legacy/lispwords_spec.lua
index 48df4de55e..2ec51dca1b 100644
--- a/test/functional/legacy/lispwords_spec.lua
+++ b/test/functional/legacy/lispwords_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
diff --git a/test/functional/legacy/listchars_spec.lua b/test/functional/legacy/listchars_spec.lua
index 89ed90178b..d2838cddb6 100644
--- a/test/functional/legacy/listchars_spec.lua
+++ b/test/functional/legacy/listchars_spec.lua
@@ -1,6 +1,6 @@
-- Tests for 'listchars' display with 'list' and :list.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/listlbr_spec.lua b/test/functional/legacy/listlbr_spec.lua
new file mode 100644
index 0000000000..eb979edc69
--- /dev/null
+++ b/test/functional/legacy/listlbr_spec.lua
@@ -0,0 +1,195 @@
+-- Test for linebreak and list option (non-utf8)
+
+local helpers = require('test.functional.helpers')(after_each)
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('listlbr', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ dummy text]])
+
+ execute('set wildchar=^E')
+ execute('10new')
+ execute('vsp')
+ execute('vert resize 20')
+ execute([[put =\"\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP \"]])
+ execute('norm! zt')
+ execute('set ts=4 sw=4 sts=4 linebreak sbr=+ wrap')
+ source([[
+ fu! ScreenChar(width)
+ let c=''
+ for j in range(1,4)
+ for i in range(1,a:width)
+ let c.=nr2char(screenchar(j, i))
+ endfor
+ let c.="\n"
+ endfor
+ return c
+ endfu
+ fu! DoRecordScreen()
+ wincmd l
+ $put =printf(\"\n%s\", g:test)
+ $put =g:line
+ wincmd p
+ endfu
+ ]])
+ execute('let g:test="Test 1: set linebreak"')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test="Test 2: set linebreak + set list"')
+ execute('set linebreak list listchars=')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test ="Test 3: set linebreak nolist"')
+ execute('set nolist linebreak')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test ="Test 4: set linebreak with tab and 1 line as long as screen: should break!"')
+ execute('set nolist linebreak ts=8')
+ execute([[let line="1\t".repeat('a', winwidth(0)-2)]])
+ execute('$put =line')
+ execute('$')
+ execute('norm! zt')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+ execute([[let line="_S_\t bla"]])
+ execute('$put =line')
+ execute('$')
+ execute('norm! zt')
+
+ execute('let g:test ="Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)"')
+ execute('set cpo&vim list linebreak conceallevel=2 concealcursor=nv listchars=tab:ab')
+ execute('syn match ConcealVar contained /_/ conceal')
+ execute('syn match All /.*/ contains=ConcealVar')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+ execute('set cpo&vim linebreak')
+
+ execute('let g:test ="Test 6: set linebreak with visual block mode"')
+ execute('let line="REMOVE: this not"')
+ execute('$put =g:test')
+ execute('$put =line')
+ execute('let line="REMOVE: aaaaaaaaaaaaa"')
+ execute('$put =line')
+ execute('1/^REMOVE:')
+ feed('0<C-V>jf x')
+ execute('$put')
+ execute('set cpo&vim linebreak')
+
+ execute('let g:test ="Test 7: set linebreak with visual block mode and v_b_A"')
+ execute('$put =g:test')
+ feed('Golong line: <esc>40afoobar <esc>aTARGET at end<esc>')
+ execute([[exe "norm! $3B\<C-v>eAx\<Esc>"]])
+ execute('set cpo&vim linebreak sbr=')
+
+ execute('let g:test ="Test 8: set linebreak with visual char mode and changing block"')
+ execute('$put =g:test')
+ feed('Go1111-1111-1111-11-1111-1111-1111<esc>0f-lv3lc2222<esc>bgj.')
+
+ execute('let g:test ="Test 9: using redo after block visual mode"')
+ execute('$put =g:test')
+ feed('Go<CR>')
+ feed('aaa<CR>')
+ feed('aaa<CR>')
+ feed('a<ESC>2k<C-V>2j~e.<CR>')
+
+ execute('let g:test ="Test 10: using normal commands after block-visual"')
+ execute('$put =g:test')
+ execute('set linebreak')
+ feed('Go<cr>')
+ feed('abcd{ef<cr>')
+ feed('ghijklm<cr>')
+ feed('no}pqrs<esc>2k0f{<C-V><C-V>c%<esc>')
+
+ execute('let g:test ="Test 11: using block replace mode after wrapping"')
+ execute('$put =g:test')
+ execute('set linebreak wrap')
+ feed('Go<esc>150aa<esc>yypk147|<C-V>jr0<cr>')
+
+ execute('let g:test ="Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$"')
+ execute('set list listchars=space:_,trail:-,tab:>-,eol:$')
+ execute('$put =g:test')
+ execute([[let line="a aaaaaaaaaaaaaaaaaaaaaa\ta "]])
+ execute('$put =line')
+ execute('$')
+ execute('norm! zt')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ -- Assert buffer contents.
+ expect([[
+
+ abcdef hijklmn pqrstuvwxyz_1060ABCDEFGHIJKLMNOP
+
+ Test 1: set linebreak
+ abcdef
+ +hijklmn
+ +pqrstuvwxyz_1060ABC
+ +DEFGHIJKLMNOP
+
+ Test 2: set linebreak + set list
+ ^Iabcdef hijklmn^I
+ +pqrstuvwxyz_1060ABC
+ +DEFGHIJKLMNOP
+
+
+ Test 3: set linebreak nolist
+ abcdef
+ +hijklmn
+ +pqrstuvwxyz_1060ABC
+ +DEFGHIJKLMNOP
+ 1 aaaaaaaaaaaaaaaaaa
+
+ Test 4: set linebreak with tab and 1 line as long as screen: should break!
+ 1
+ +aaaaaaaaaaaaaaaaaa
+ ~
+ ~
+ _S_ bla
+
+ Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)
+ Sabbbbbb bla
+ ~
+ ~
+ ~
+ Test 6: set linebreak with visual block mode
+ this not
+ aaaaaaaaaaaaa
+ REMOVE:
+ REMOVE:
+ Test 7: set linebreak with visual block mode and v_b_A
+ long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETx at end
+ Test 8: set linebreak with visual char mode and changing block
+ 1111-2222-1111-11-1111-2222-1111
+ Test 9: using redo after block visual mode
+
+ AaA
+ AaA
+ A
+ Test 10: using normal commands after block-visual
+
+ abcdpqrs
+ Test 11: using block replace mode after wrapping
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa
+ Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$
+ a aaaaaaaaaaaaaaaaaaaaaa a
+
+ Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$
+ a_
+ aaaaaaaaaaaaaaaaaaaa
+ aa>-----a-$
+ ~ ]])
+ end)
+end)
diff --git a/test/functional/legacy/listlbr_utf8_spec.lua b/test/functional/legacy/listlbr_utf8_spec.lua
index df0e817533..f06bca72ba 100644
--- a/test/functional/legacy/listlbr_utf8_spec.lua
+++ b/test/functional/legacy/listlbr_utf8_spec.lua
@@ -1,6 +1,6 @@
-- Test for linebreak and list option in utf-8 mode
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source = helpers.source
local feed = helpers.feed
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/mapping_spec.lua b/test/functional/legacy/mapping_spec.lua
index a0d19926cb..1712219d04 100644
--- a/test/functional/legacy/mapping_spec.lua
+++ b/test/functional/legacy/mapping_spec.lua
@@ -1,6 +1,6 @@
-- Test for mappings and abbreviations
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect, wait = helpers.execute, helpers.expect, helpers.wait
diff --git a/test/functional/legacy/marks_spec.lua b/test/functional/legacy/marks_spec.lua
index 8e9ceb1653..6ecba70f08 100644
--- a/test/functional/legacy/marks_spec.lua
+++ b/test/functional/legacy/marks_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/match_conceal_spec.lua b/test/functional/legacy/match_conceal_spec.lua
index 0ffa3cae7a..d95b07d695 100644
--- a/test/functional/legacy/match_conceal_spec.lua
+++ b/test/functional/legacy/match_conceal_spec.lua
@@ -1,6 +1,6 @@
-- Test for matchadd() and conceal feature
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local expect = helpers.expect
local source = helpers.source
diff --git a/test/functional/legacy/nested_function_spec.lua b/test/functional/legacy/nested_function_spec.lua
index fac3b03191..be9b66ee38 100644
--- a/test/functional/legacy/nested_function_spec.lua
+++ b/test/functional/legacy/nested_function_spec.lua
@@ -1,6 +1,6 @@
-- Tests for nested function.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, insert = helpers.clear, helpers.insert
local execute, expect, source = helpers.execute, helpers.expect, helpers.source
diff --git a/test/functional/legacy/options_spec.lua b/test/functional/legacy/options_spec.lua
index 21e99c4aa1..4f4d4ceaf9 100644
--- a/test/functional/legacy/options_spec.lua
+++ b/test/functional/legacy/options_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local command, clear = helpers.command, helpers.clear
local source, expect = helpers.source, helpers.expect
diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua
new file mode 100644
index 0000000000..b2ed39f288
--- /dev/null
+++ b/test/functional/legacy/packadd_spec.lua
@@ -0,0 +1,350 @@
+-- Tests for 'packpath' and :packadd
+
+local helpers = require('test.functional.helpers')(after_each)
+local clear, source, execute = helpers.clear, helpers.source, helpers.execute
+local call, eq, nvim = helpers.call, helpers.eq, helpers.meths
+local feed = helpers.feed
+
+local function expected_empty()
+ eq({}, nvim.get_vvar('errors'))
+end
+
+describe('packadd', function()
+ before_each(function()
+ clear()
+
+ source([=[
+ func SetUp()
+ let s:topdir = expand('%:p:h') . '/Xdir'
+ exe 'set packpath=' . s:topdir
+ let s:plugdir = s:topdir . '/pack/mine/opt/mytest'
+ endfunc
+
+ func TearDown()
+ call delete(s:topdir, 'rf')
+ endfunc
+
+ func Test_packadd()
+ call mkdir(s:plugdir . '/plugin', 'p')
+ call mkdir(s:plugdir . '/ftdetect', 'p')
+ call mkdir(s:plugdir . '/after', 'p')
+ set rtp&
+ let rtp = &rtp
+ filetype on
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 42')
+ wq
+
+ exe 'split ' . s:plugdir . '/ftdetect/test.vim'
+ call setline(1, 'let g:ftdetect_works = 17')
+ wq
+
+ packadd mytest
+
+ call assert_true(42, g:plugin_works)
+ call assert_true(17, g:ftdetect_works)
+ call assert_true(len(&rtp) > len(rtp))
+ call assert_true(&rtp =~ (s:plugdir . '\($\|,\)'))
+ call assert_true(&rtp =~ (s:plugdir . '/after$'))
+
+ " Check exception
+ call assert_fails("packadd directorynotfound", 'E919:')
+ call assert_fails("packadd", 'E471:')
+ endfunc
+
+ func Test_packadd_noload()
+ call mkdir(s:plugdir . '/plugin', 'p')
+ call mkdir(s:plugdir . '/syntax', 'p')
+ set rtp&
+ let rtp = &rtp
+
+ exe 'split ' . s:plugdir . '/plugin/test.vim'
+ call setline(1, 'let g:plugin_works = 42')
+ wq
+ let g:plugin_works = 0
+
+ packadd! mytest
+
+ call assert_true(len(&rtp) > len(rtp))
+ call assert_true(&rtp =~ (s:plugdir . '\($\|,\)'))
+ call assert_equal(0, g:plugin_works)
+
+ " check the path is not added twice
+ let new_rtp = &rtp
+ packadd! mytest
+ call assert_equal(new_rtp, &rtp)
+ endfunc
+
+ func Test_packloadall()
+ " plugin foo with an autoload directory
+ let fooplugindir = &packpath . '/pack/mine/start/foo/plugin'
+ call mkdir(fooplugindir, 'p')
+ call writefile(['let g:plugin_foo_number = 1234',
+ \ 'let g:plugin_foo_auto = bbb#value',
+ \ 'let g:plugin_extra_auto = extra#value'], fooplugindir . '/bar.vim')
+ let fooautodir = &packpath . '/pack/mine/start/foo/autoload'
+ call mkdir(fooautodir, 'p')
+ call writefile(['let bar#value = 77'], fooautodir . '/bar.vim')
+
+ " plugin aaa with an autoload directory
+ let aaaplugindir = &packpath . '/pack/mine/start/aaa/plugin'
+ call mkdir(aaaplugindir, 'p')
+ call writefile(['let g:plugin_aaa_number = 333',
+ \ 'let g:plugin_aaa_auto = bar#value'], aaaplugindir . '/bbb.vim')
+ let aaaautodir = &packpath . '/pack/mine/start/aaa/autoload'
+ call mkdir(aaaautodir, 'p')
+ call writefile(['let bbb#value = 55'], aaaautodir . '/bbb.vim')
+
+ " plugin extra with only an autoload directory
+ let extraautodir = &packpath . '/pack/mine/start/extra/autoload'
+ call mkdir(extraautodir, 'p')
+ call writefile(['let extra#value = 99'], extraautodir . '/extra.vim')
+
+ packloadall
+ call assert_equal(1234, g:plugin_foo_number)
+ call assert_equal(55, g:plugin_foo_auto)
+ call assert_equal(99, g:plugin_extra_auto)
+ call assert_equal(333, g:plugin_aaa_number)
+ call assert_equal(77, g:plugin_aaa_auto)
+
+ " only works once
+ call writefile(['let g:plugin_bar_number = 4321'],
+ \ fooplugindir . '/bar2.vim')
+ packloadall
+ call assert_false(exists('g:plugin_bar_number'))
+
+ " works when ! used
+ packloadall!
+ call assert_equal(4321, g:plugin_bar_number)
+ endfunc
+
+ func Test_helptags()
+ let docdir1 = &packpath . '/pack/mine/start/foo/doc'
+ let docdir2 = &packpath . '/pack/mine/start/bar/doc'
+ call mkdir(docdir1, 'p')
+ call mkdir(docdir2, 'p')
+ call writefile(['look here: *look-here*'], docdir1 . '/bar.txt')
+ call writefile(['look away: *look-away*'], docdir2 . '/foo.txt')
+ exe 'set rtp=' . &packpath . '/pack/mine/start/foo,' . &packpath . '/pack/mine/start/bar'
+
+ helptags ALL
+
+ let tags1 = readfile(docdir1 . '/tags')
+ call assert_true(tags1[0] =~ 'look-here')
+ let tags2 = readfile(docdir2 . '/tags')
+ call assert_true(tags2[0] =~ 'look-away')
+ endfunc
+
+ func Test_colorscheme()
+ let colordirrun = &packpath . '/runtime/colors'
+ let colordirstart = &packpath . '/pack/mine/start/foo/colors'
+ let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
+ call mkdir(colordirrun, 'p')
+ call mkdir(colordirstart, 'p')
+ call mkdir(colordiropt, 'p')
+ call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
+ call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
+ call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
+ exe 'set rtp=' . &packpath . '/runtime'
+
+ colorscheme one
+ call assert_equal(1, g:found_one)
+ colorscheme two
+ call assert_equal(1, g:found_two)
+ colorscheme three
+ call assert_equal(1, g:found_three)
+ endfunc
+
+ func Test_runtime()
+ let rundir = &packpath . '/runtime/extra'
+ let startdir = &packpath . '/pack/mine/start/foo/extra'
+ let optdir = &packpath . '/pack/mine/opt/bar/extra'
+ call mkdir(rundir, 'p')
+ call mkdir(startdir, 'p')
+ call mkdir(optdir, 'p')
+ call writefile(['let g:sequence .= "run"'], rundir . '/bar.vim')
+ call writefile(['let g:sequence .= "start"'], startdir . '/bar.vim')
+ call writefile(['let g:sequence .= "foostart"'], startdir . '/foo.vim')
+ call writefile(['let g:sequence .= "opt"'], optdir . '/bar.vim')
+ call writefile(['let g:sequence .= "xxxopt"'], optdir . '/xxx.vim')
+ exe 'set rtp=' . &packpath . '/runtime'
+
+ let g:sequence = ''
+ runtime extra/bar.vim
+ call assert_equal('run', g:sequence)
+ let g:sequence = ''
+ runtime START extra/bar.vim
+ call assert_equal('start', g:sequence)
+ let g:sequence = ''
+ runtime OPT extra/bar.vim
+ call assert_equal('opt', g:sequence)
+ let g:sequence = ''
+ runtime PACK extra/bar.vim
+ call assert_equal('start', g:sequence)
+ let g:sequence = ''
+ runtime! PACK extra/bar.vim
+ call assert_equal('startopt', g:sequence)
+ let g:sequence = ''
+ runtime PACK extra/xxx.vim
+ call assert_equal('xxxopt', g:sequence)
+
+ let g:sequence = ''
+ runtime ALL extra/bar.vim
+ call assert_equal('run', g:sequence)
+ let g:sequence = ''
+ runtime ALL extra/foo.vim
+ call assert_equal('foostart', g:sequence)
+ let g:sequence = ''
+ runtime! ALL extra/xxx.vim
+ call assert_equal('xxxopt', g:sequence)
+ let g:sequence = ''
+ runtime! ALL extra/bar.vim
+ call assert_equal('runstartopt', g:sequence)
+ endfunc
+ ]=])
+ call('SetUp')
+ end)
+
+ after_each(function()
+ call('TearDown')
+ end)
+
+ it('is working', function()
+ call('Test_packadd')
+ expected_empty()
+ end)
+
+ it('works with packadd!', function()
+ call('Test_packadd_noload')
+ expected_empty()
+ end)
+
+ it('works with :packloadall', function()
+ call('Test_packloadall')
+ expected_empty()
+ end)
+
+ it('works with helptags', function()
+ call('Test_helptags')
+ expected_empty()
+ end)
+
+ it('works with colorschemes', function()
+ call('Test_colorscheme')
+ expected_empty()
+ end)
+
+ it('works with :runtime [what]', function()
+ call('Test_runtime')
+ expected_empty()
+ end)
+
+ describe('command line completion', function()
+ local Screen = require('test.functional.ui.screen')
+ local screen
+
+ before_each(function()
+ screen = Screen.new(30, 5)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {
+ foreground = Screen.colors.Black,
+ background = Screen.colors.Yellow,
+ },
+ [2] = {bold = true, reverse = true}
+ })
+ local NonText = Screen.colors.Blue
+ screen:set_default_attr_ignore({{}, {bold=true, foreground=NonText}})
+
+ execute([[let optdir1 = &packpath . '/pack/mine/opt']])
+ execute([[let optdir2 = &packpath . '/pack/candidate/opt']])
+ execute([[call mkdir(optdir1 . '/pluginA', 'p')]])
+ execute([[call mkdir(optdir1 . '/pluginC', 'p')]])
+ execute([[call mkdir(optdir2 . '/pluginB', 'p')]])
+ execute([[call mkdir(optdir2 . '/pluginC', 'p')]])
+ end)
+
+ it('works', function()
+ feed(':packadd <Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {1:pluginA}{2: pluginB pluginC }|
+ :packadd pluginA^ |
+ ]=])
+ feed('<Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {2:pluginA }{1:pluginB}{2: pluginC }|
+ :packadd pluginB^ |
+ ]=])
+ feed('<Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {2:pluginA pluginB }{1:pluginC}{2: }|
+ :packadd pluginC^ |
+ ]=])
+ feed('<Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {2:pluginA pluginB pluginC }|
+ :packadd ^ |
+ ]=])
+ end)
+
+ it('works for colorschemes', function()
+ source([[
+ let colordirrun = &packpath . '/runtime/colors'
+ let colordirstart = &packpath . '/pack/mine/start/foo/colors'
+ let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
+ call mkdir(colordirrun, 'p')
+ call mkdir(colordirstart, 'p')
+ call mkdir(colordiropt, 'p')
+ call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
+ call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
+ call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
+ exe 'set rtp=' . &packpath . '/runtime']])
+
+ feed(':colorscheme <Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {1:one}{2: three two }|
+ :colorscheme one^ |
+ ]=])
+ feed('<Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {2:one }{1:three}{2: two }|
+ :colorscheme three^ |
+ ]=])
+ feed('<Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {2:one three }{1:two}{2: }|
+ :colorscheme two^ |
+ ]=])
+ feed('<Tab>')
+ screen:expect([=[
+ |
+ ~ |
+ ~ |
+ {2:one three two }|
+ :colorscheme ^ |
+ ]=])
+ end)
+ end)
+end)
diff --git a/test/functional/legacy/qf_title_spec.lua b/test/functional/legacy/qf_title_spec.lua
index 01c781cc05..9f97eb27b2 100644
--- a/test/functional/legacy/qf_title_spec.lua
+++ b/test/functional/legacy/qf_title_spec.lua
@@ -1,6 +1,6 @@
-- Tests for quickfix window's title
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert, source = helpers.insert, helpers.source
local clear, expect = helpers.clear, helpers.expect
diff --git a/test/functional/legacy/quickfix_spec.lua b/test/functional/legacy/quickfix_spec.lua
index 88f86815b3..df8f2625db 100644
--- a/test/functional/legacy/quickfix_spec.lua
+++ b/test/functional/legacy/quickfix_spec.lua
@@ -1,12 +1,286 @@
-- Test for the quickfix commands.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source, clear = helpers.source, helpers.clear
+local eq, nvim, call = helpers.eq, helpers.meths, helpers.call
+local eval = helpers.eval
+local execute = helpers.execute
+
+local function expected_empty()
+ eq({}, nvim.get_vvar('errors'))
+end
describe('helpgrep', function()
- before_each(clear)
+ before_each(function()
+ clear()
- it('works', function()
+ source([[
+ " Tests for the :clist and :llist commands
+ function XlistTests(cchar)
+ let Xlist = a:cchar . 'list'
+ let Xgetexpr = a:cchar . 'getexpr'
+
+ " With an empty list, command should return error
+ exe Xgetexpr . ' []'
+ exe 'silent! ' . Xlist
+ call assert_true(v:errmsg ==# 'E42: No Errors')
+
+ " Populate the list and then try
+ exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1',
+ \ 'non-error 2', 'Xtestfile2:2:2:Line2',
+ \ 'non-error 3', 'Xtestfile3:3:1:Line3']"
+
+ " List only valid entries
+ redir => result
+ exe 'silent ' . Xlist
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ " List all the entries
+ redir => result
+ exe 'silent ' . Xlist . "!"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ " List a range of errors
+ redir => result
+ exe 'silent '. Xlist . " 3,6"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ redir => result
+ exe 'silent ' . Xlist . "! 3,4"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+
+ redir => result
+ exe 'silent ' . Xlist . " -6,-4"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
+
+ redir => result
+ exe 'silent ' . Xlist . "! -5,-3"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+ endfunction
+
+ " Tests for the :colder, :cnewer, :lolder and :lnewer commands
+ " Note that this test assumes that a quickfix/location list is
+ " already set by the caller
+ function XageTests(cchar)
+ let Xolder = a:cchar . 'older'
+ let Xnewer = a:cchar . 'newer'
+ let Xgetexpr = a:cchar . 'getexpr'
+ if a:cchar == 'c'
+ let Xgetlist = 'getqflist()'
+ else
+ let Xgetlist = 'getloclist(0)'
+ endif
+
+ " Jumping to a non existent list should return error
+ exe 'silent! ' . Xolder . ' 99'
+ call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
+
+ exe 'silent! ' . Xnewer . ' 99'
+ call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
+
+ " Add three quickfix/location lists
+ exe Xgetexpr . " ['Xtestfile1:1:3:Line1']"
+ exe Xgetexpr . " ['Xtestfile2:2:2:Line2']"
+ exe Xgetexpr . " ['Xtestfile3:3:1:Line3']"
+
+ " Go back two lists
+ exe Xolder
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line2', l[0].text)
+
+ " Go forward two lists
+ exe Xnewer
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line3', l[0].text)
+
+ " Test for the optional count argument
+ exe Xolder . ' 2'
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line1', l[0].text)
+
+ exe Xnewer . ' 2'
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line3', l[0].text)
+ endfunction
+
+ " Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
+ " commands
+ function XwindowTests(cchar)
+ let Xwindow = a:cchar . 'window'
+ let Xclose = a:cchar . 'close'
+ let Xopen = a:cchar . 'open'
+ let Xgetexpr = a:cchar . 'getexpr'
+
+ " Create a list with no valid entries
+ exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
+
+ " Quickfix/Location window should not open with no valid errors
+ exe Xwindow
+ call assert_true(winnr('$') == 1)
+
+ " Create a list with valid entries
+ exe Xgetexpr . " ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
+ \ 'Xtestfile3:3:1:Line3']"
+
+ " Open the window
+ exe Xwindow
+ call assert_true(winnr('$') == 2 && winnr() == 2 &&
+ \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
+
+ " Close the window
+ exe Xclose
+ call assert_true(winnr('$') == 1)
+
+ " Create a list with no valid entries
+ exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
+
+ " Open the window
+ exe Xopen . ' 5'
+ call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
+ \ && winheight('.') == 5)
+
+ " Opening the window again, should move the cursor to that window
+ wincmd t
+ exe Xopen . ' 7'
+ call assert_true(winnr('$') == 2 && winnr() == 2 &&
+ \ winheight('.') == 7 &&
+ \ getline('.') ==# '|| non-error 1')
+
+
+ " Calling cwindow should close the quickfix window with no valid errors
+ exe Xwindow
+ call assert_true(winnr('$') == 1)
+ endfunction
+
+ " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
+ " commands.
+ function XfileTests(cchar)
+ let Xfile = a:cchar . 'file'
+ let Xgetfile = a:cchar . 'getfile'
+ let Xaddfile = a:cchar . 'addfile'
+ if a:cchar == 'c'
+ let Xgetlist = 'getqflist()'
+ else
+ let Xgetlist = 'getloclist(0)'
+ endif
+
+ call writefile(['Xtestfile1:700:10:Line 700',
+ \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
+
+ enew!
+ exe Xfile . ' Xqftestfile1'
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
+ \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
+
+ " Run cfile/lfile from a modified buffer
+ enew!
+ silent! put ='Quickfix'
+ exe 'silent! ' . Xfile . ' Xqftestfile1'
+ call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
+
+ call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
+ exe Xaddfile . ' Xqftestfile1'
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 3 &&
+ \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
+
+ call writefile(['Xtestfile1:222:77:Line 222',
+ \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
+
+ enew!
+ exe Xgetfile . ' Xqftestfile1'
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
+ \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
+
+ call delete('Xqftestfile1')
+ endfunction
+
+ " Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
+ " :lgetbuffer commands.
+ function XbufferTests(cchar)
+ let Xbuffer = a:cchar . 'buffer'
+ let Xgetbuffer = a:cchar . 'getbuffer'
+ let Xaddbuffer = a:cchar . 'addbuffer'
+ if a:cchar == 'c'
+ let Xgetlist = 'getqflist()'
+ else
+ let Xgetlist = 'getloclist(0)'
+ endif
+
+ enew!
+ silent! call setline(1, ['Xtestfile7:700:10:Line 700',
+ \ 'Xtestfile8:800:15:Line 800'])
+ exe Xbuffer . "!"
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
+ \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
+
+ enew!
+ silent! call setline(1, ['Xtestfile9:900:55:Line 900',
+ \ 'Xtestfile10:950:66:Line 950'])
+ exe Xgetbuffer
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
+ \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
+
+ enew!
+ silent! call setline(1, ['Xtestfile11:700:20:Line 700',
+ \ 'Xtestfile12:750:25:Line 750'])
+ exe Xaddbuffer
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 4 &&
+ \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
+ \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
+ \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
+
+ endfunction
+
+ function Test_locationlist_curwin_was_closed()
+ augroup testgroup
+ au!
+ autocmd BufReadCmd t call R(expand("<amatch>"))
+ augroup END
+
+ function R(n)
+ quit
+ endfunc
+
+ new
+ let q = []
+ call add(q, {'filename': 't' })
+ call setloclist(0, q)
+ call assert_fails('lrewind', 'E924:')
+
+ augroup! testgroup
+ endfunction
+ ]])
+ end)
+
+ it('copen/cclose work', function()
source([[
helpgrep quickfix
copen
@@ -14,4 +288,55 @@ describe('helpgrep', function()
cclose
]])
end)
+
+ it('clist/llist work', function()
+ call('XlistTests', 'c')
+ expected_empty()
+ call('XlistTests', 'l')
+ expected_empty()
+ end)
+
+ it('colder/cnewer and lolder/lnewer work', function()
+ local list = {{bufnr = 1, lnum = 1}}
+ call('setqflist', list)
+ call('XageTests', 'c')
+ expected_empty()
+
+ call('setloclist', 0, list)
+ call('XageTests', 'l')
+ expected_empty()
+ end)
+
+ it('quickfix/location list window commands work', function()
+ call('XwindowTests', 'c')
+ expected_empty()
+ call('XwindowTests', 'l')
+ expected_empty()
+ end)
+
+ it('quickfix/location list file commands work', function()
+ call('XfileTests', 'c')
+ expected_empty()
+ call('XfileTests', 'l')
+ expected_empty()
+ end)
+
+ it('quickfix/location list buffer commands work', function()
+ call('XbufferTests', 'c')
+ expected_empty()
+ call('XbufferTests', 'l')
+ expected_empty()
+ end)
+
+ it('autocommands triggered by quickfix can get title', function()
+ execute('au FileType qf let g:foo = get(w:, "quickfix_title", "NONE")')
+ execute('call setqflist([])')
+ execute('copen')
+ eq(':setqflist()', eval('g:foo'))
+ end)
+
+ it('errors when an autocommand closes the location list\'s window', function()
+ call('Test_locationlist_curwin_was_closed')
+ expected_empty()
+ end)
end)
diff --git a/test/functional/legacy/search_mbyte_spec.lua b/test/functional/legacy/search_mbyte_spec.lua
index 075b24b897..a5a5822a45 100644
--- a/test/functional/legacy/search_mbyte_spec.lua
+++ b/test/functional/legacy/search_mbyte_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local insert = helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
diff --git a/test/functional/legacy/searchpos_spec.lua b/test/functional/legacy/searchpos_spec.lua
index 1c9b1ccee6..7d4b7a3734 100644
--- a/test/functional/legacy/searchpos_spec.lua
+++ b/test/functional/legacy/searchpos_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local call = helpers.call
local clear = helpers.clear
local execute = helpers.execute
diff --git a/test/functional/legacy/set_spec.lua b/test/functional/legacy/set_spec.lua
index f2c907084e..11f371569d 100644
--- a/test/functional/legacy/set_spec.lua
+++ b/test/functional/legacy/set_spec.lua
@@ -1,6 +1,6 @@
-- Tests for :set
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, eval, eq =
helpers.clear, helpers.execute, helpers.eval, helpers.eq
diff --git a/test/functional/legacy/signs_spec.lua b/test/functional/legacy/signs_spec.lua
index 5a834c39e3..e80a32455a 100644
--- a/test/functional/legacy/signs_spec.lua
+++ b/test/functional/legacy/signs_spec.lua
@@ -1,6 +1,6 @@
-- Tests for signs
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('signs', function()
diff --git a/test/functional/legacy/tagcase_spec.lua b/test/functional/legacy/tagcase_spec.lua
index 9a8c6fbe42..ed2876a375 100644
--- a/test/functional/legacy/tagcase_spec.lua
+++ b/test/functional/legacy/tagcase_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
diff --git a/test/functional/legacy/textobjects_spec.lua b/test/functional/legacy/textobjects_spec.lua
index 1e8e0b0bcb..15a93e3819 100644
--- a/test/functional/legacy/textobjects_spec.lua
+++ b/test/functional/legacy/textobjects_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local call = helpers.call
local clear = helpers.clear
local execute = helpers.execute
diff --git a/test/functional/legacy/undolevels_spec.lua b/test/functional/legacy/undolevels_spec.lua
index 41274b3a04..9902b101f6 100644
--- a/test/functional/legacy/undolevels_spec.lua
+++ b/test/functional/legacy/undolevels_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local source, clear = helpers.source, helpers.clear
local eq, nvim = helpers.eq, helpers.meths
diff --git a/test/functional/legacy/utf8_spec.lua b/test/functional/legacy/utf8_spec.lua
index d33ba6b5fd..4d4f55b9eb 100644
--- a/test/functional/legacy/utf8_spec.lua
+++ b/test/functional/legacy/utf8_spec.lua
@@ -1,6 +1,6 @@
-- Tests for Unicode manipulations
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect = helpers.execute, helpers.expect
local eq, eval = helpers.eq, helpers.eval
diff --git a/test/functional/legacy/wordcount_spec.lua b/test/functional/legacy/wordcount_spec.lua
index ba7be8f21b..300a777772 100644
--- a/test/functional/legacy/wordcount_spec.lua
+++ b/test/functional/legacy/wordcount_spec.lua
@@ -1,6 +1,6 @@
-- Test for wordcount() function
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, insert, source = helpers.feed, helpers.insert, helpers.source
local clear, execute = helpers.clear, helpers.execute
local eq, eval = helpers.eq, helpers.eval
diff --git a/test/functional/legacy/writefile_spec.lua b/test/functional/legacy/writefile_spec.lua
index efdfc1d09f..765d373b82 100644
--- a/test/functional/legacy/writefile_spec.lua
+++ b/test/functional/legacy/writefile_spec.lua
@@ -1,6 +1,6 @@
-- Tests for writefile()
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('writefile', function()
@@ -17,6 +17,7 @@ describe('writefile', function()
execute('bwipeout!')
execute('$put =readfile(f)')
execute('1 delete _')
+ execute('call delete(f)')
-- Assert buffer contents.
expect([[
diff --git a/test/functional/normal/K_spec.lua b/test/functional/normal/K_spec.lua
index df6b429f50..af0f82ef9a 100644
--- a/test/functional/normal/K_spec.lua
+++ b/test/functional/normal/K_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq, clear, eval, feed =
helpers.eq, helpers.clear, helpers.eval, helpers.feed
diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua
new file mode 100644
index 0000000000..0e293761ad
--- /dev/null
+++ b/test/functional/options/autochdir_spec.lua
@@ -0,0 +1,18 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local eq = helpers.eq
+local getcwd = helpers.funcs.getcwd
+
+describe("'autochdir'", function()
+ it('given on the shell gets processed properly', function()
+ local targetdir = 'test/functional/fixtures'
+
+ -- By default 'autochdir' is off, thus getcwd() returns the repo root.
+ clear(targetdir..'/tty-test.c')
+ local rootdir = getcwd()
+
+ -- With 'autochdir' on, we should get the directory of tty-test.c.
+ clear('--cmd', 'set autochdir', targetdir..'/tty-test.c')
+ eq(rootdir..'/'..targetdir, getcwd())
+ end)
+end)
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index d4c3267997..a36939b0bd 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -1,6 +1,6 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
-local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
+local eval, eq = helpers.eval, helpers.eq
local execute = helpers.execute
local function init_session(...)
@@ -15,10 +15,6 @@ local function init_session(...)
end
describe('startup defaults', function()
- before_each(function()
- clear()
- end)
-
describe(':filetype', function()
local function expect_filetype(expected)
local screen = Screen.new(48, 4)
diff --git a/test/functional/options/shortmess_spec.lua b/test/functional/options/shortmess_spec.lua
index 4455ef663f..d531e47e28 100644
--- a/test/functional/options/shortmess_spec.lua
+++ b/test/functional/options/shortmess_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, execute = helpers.clear, helpers.execute
diff --git a/test/functional/plugin/helpers.lua b/test/functional/plugin/helpers.lua
index 5b6ea88c34..7580670149 100644
--- a/test/functional/plugin/helpers.lua
+++ b/test/functional/plugin/helpers.lua
@@ -1,6 +1,6 @@
local paths = require('test.config.paths')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(nil)
local spawn, set_session, nvim_prog, merge_args =
helpers.spawn, helpers.set_session, helpers.nvim_prog, helpers.merge_args
diff --git a/test/functional/plugin/matchparen_spec.lua b/test/functional/plugin/matchparen_spec.lua
index d8c1f2d392..4181f69263 100644
--- a/test/functional/plugin/matchparen_spec.lua
+++ b/test/functional/plugin/matchparen_spec.lua
@@ -1,20 +1,27 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
+local plugin_helpers = require('test.functional.plugin.helpers')
local Screen = require('test.functional.ui.screen')
-local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+
+local execute = helpers.execute
+local meths = helpers.meths
+local feed = helpers.feed
+local eq = helpers.eq
+
+local reset = plugin_helpers.reset
describe('matchparen', function()
local screen
before_each(function()
- clear()
+ reset()
screen = Screen.new(20,5)
screen:attach()
screen:set_default_attr_ignore( {{bold=true, foreground=Screen.colors.Blue}} )
end)
it('uses correct column after i_<Up>. Vim patch 7.4.1296', function()
- execute('set noai nosi nocin')
- execute('runtime plugin/matchparen.vim')
+ execute('set noautoindent nosmartindent nocindent laststatus=0')
+ eq(1, meths.get_var('loaded_matchparen'))
feed('ivoid f_test()<cr>')
feed('{<cr>')
feed('}')
diff --git a/test/functional/plugin/msgpack_spec.lua b/test/functional/plugin/msgpack_spec.lua
index 60ba88e55b..c8da8e8f6c 100644
--- a/test/functional/plugin/msgpack_spec.lua
+++ b/test/functional/plugin/msgpack_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local meths = helpers.meths
local eq, nvim_eval, nvim_command, exc_exec =
helpers.eq, helpers.eval, helpers.command, helpers.exc_exec
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
index aad0e366bf..e18e9ef428 100644
--- a/test/functional/plugin/shada_spec.lua
+++ b/test/functional/plugin/shada_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq, nvim_eval, nvim_command, nvim, exc_exec, funcs, nvim_feed, curbuf =
helpers.eq, helpers.eval, helpers.command, helpers.nvim, helpers.exc_exec,
helpers.funcs, helpers.feed, helpers.curbuf
diff --git a/test/functional/preload.lua b/test/functional/preload.lua
index 1971ef77cc..1107b45d54 100644
--- a/test/functional/preload.lua
+++ b/test/functional/preload.lua
@@ -1,4 +1,4 @@
-- Modules loaded here will not be cleared and reloaded by Busted.
-- Busted started doing this to help provide more isolation. See issue #62
-- for more information about this.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(nil)
diff --git a/test/functional/provider/define_spec.lua b/test/functional/provider/define_spec.lua
index c30ad6d8c2..b0363eb435 100644
--- a/test/functional/provider/define_spec.lua
+++ b/test/functional/provider/define_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim
local eq, run, stop = helpers.eq, helpers.run, helpers.stop
local clear = helpers.clear
diff --git a/test/functional/provider/python3_spec.lua b/test/functional/provider/python3_spec.lua
index a94880d4a2..a4e9a49c8a 100644
--- a/test/functional/provider/python3_spec.lua
+++ b/test/functional/provider/python3_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eval, command, feed = helpers.eval, helpers.command, helpers.feed
local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
local expect, write_file = helpers.expect, helpers.write_file
diff --git a/test/functional/provider/python_spec.lua b/test/functional/provider/python_spec.lua
index da45d6aa00..94dfa90ea8 100644
--- a/test/functional/provider/python_spec.lua
+++ b/test/functional/provider/python_spec.lua
@@ -1,12 +1,22 @@
-local helpers = require('test.functional.helpers')
-local eval, command, feed = helpers.eval, helpers.command, helpers.feed
-local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
-local expect, write_file = helpers.expect, helpers.write_file
+local helpers = require('test.functional.helpers')(after_each)
+
+local eq = helpers.eq
+local neq = helpers.neq
+local feed = helpers.feed
+local clear = helpers.clear
+local funcs = helpers.funcs
+local meths = helpers.meths
+local insert = helpers.insert
+local expect = helpers.expect
+local command = helpers.command
+local exc_exec = helpers.exc_exec
+local write_file = helpers.write_file
+local curbufmeths = helpers.curbufmeths
do
clear()
command('let [g:interp, g:errors] = provider#pythonx#Detect(2)')
- local errors = eval('g:errors')
+ local errors = meths.get_var('errors')
if errors ~= '' then
pending(
'Python 2 (or the Python 2 neovim module) is broken or missing:\n' .. errors,
@@ -15,49 +25,58 @@ do
end
end
-describe('python commands and functions', function()
- before_each(function()
- clear()
- command('python import vim')
- end)
+before_each(function()
+ clear()
+ command('python import vim')
+end)
- it('feature test', function()
- eq(1, eval('has("python")'))
+describe('python feature test', function()
+ it('works', function()
+ eq(1, funcs.has('python'))
end)
+end)
- it('python_execute', function()
+describe(':python command', function()
+ it('works with a line', function()
command('python vim.vars["set_by_python"] = [100, 0]')
- eq({100, 0}, eval('g:set_by_python'))
+ eq({100, 0}, meths.get_var('set_by_python'))
end)
- it('python_execute with nested commands', function()
+ -- TODO(ZyX-I): works with << EOF
+ -- TODO(ZyX-I): works with execute 'python' line1."\n".line2."\n"…
+
+ it('supports nesting', function()
command([[python vim.command('python vim.command("python vim.command(\'let set_by_nested_python = 555\')")')]])
- eq(555, eval('g:set_by_nested_python'))
+ eq(555, meths.get_var('set_by_nested_python'))
end)
- it('python_execute with range', function()
+ it('supports range', function()
insert([[
line1
line2
line3
line4]])
feed('ggjvj:python vim.vars["range"] = vim.current.range[:]<CR>')
- eq({'line2', 'line3'}, eval('g:range'))
+ eq({'line2', 'line3'}, meths.get_var('range'))
end)
+end)
- it('pyfile', function()
+describe(':pyfile command', function()
+ it('works', function()
local fname = 'pyfile.py'
write_file(fname, 'vim.command("let set_by_pyfile = 123")')
command('pyfile pyfile.py')
- eq(123, eval('g:set_by_pyfile'))
+ eq(123, meths.get_var('set_by_pyfile'))
os.remove(fname)
end)
+end)
- it('pydo', function()
+describe(':pydo command', function()
+ it('works', function()
-- :pydo 42 returns None for all lines,
-- the buffer should not be changed
command('normal :pydo 42')
- eq(0, eval('&mod'))
+ eq(false, curbufmeths.get_option('modified'))
-- insert some text
insert('abc\ndef\nghi')
expect([[
@@ -71,8 +90,25 @@ describe('python commands and functions', function()
2
ghi]])
end)
+end)
+
+describe('pyeval()', function()
+ it('works', function()
+ eq({1, 2, {['key'] = 'val'}}, funcs.pyeval('[1, 2, {"key": "val"}]'))
+ end)
+
+ it('errors out when given non-string', function()
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(10)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:_null_dict)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:_null_list)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(0.0)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(function("tr"))'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:true)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:false)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:null)'))
+ end)
- it('pyeval', function()
- eq({1, 2, {['key'] = 'val'}}, eval([[pyeval('[1, 2, {"key": "val"}]')]]))
+ it('accepts NULL string', function()
+ neq(0, exc_exec('call pyeval($XXX_NONEXISTENT_VAR_XXX)'))
end)
end)
diff --git a/test/functional/provider/ruby_spec.lua b/test/functional/provider/ruby_spec.lua
new file mode 100644
index 0000000000..7b0e17688d
--- /dev/null
+++ b/test/functional/provider/ruby_spec.lua
@@ -0,0 +1,96 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local eq = helpers.eq
+local feed = helpers.feed
+local clear = helpers.clear
+local funcs = helpers.funcs
+local meths = helpers.meths
+local insert = helpers.insert
+local expect = helpers.expect
+local command = helpers.command
+local write_file = helpers.write_file
+local curbufmeths = helpers.curbufmeths
+
+do
+ clear()
+ command('let g:prog = provider#ruby#Detect()')
+ local prog = meths.get_var('prog')
+
+ if prog == '' then
+ pending(
+ "Cannot find the neovim RubyGem. Try :CheckHealth",
+ function() end)
+ return
+ end
+end
+
+before_each(function()
+ clear()
+end)
+
+describe('ruby feature test', function()
+ it('works', function()
+ eq(1, funcs.has('ruby'))
+ end)
+end)
+
+describe(':ruby command', function()
+ it('evaluates ruby', function()
+ command('ruby VIM.command("let g:set_by_ruby = [100, 0]")')
+ eq({100, 0}, meths.get_var('set_by_ruby'))
+ end)
+
+ it('supports nesting', function()
+ command([[ruby VIM.command('ruby VIM.command("let set_by_nested_ruby = 555")')]])
+ eq(555, meths.get_var('set_by_nested_ruby'))
+ end)
+end)
+
+describe(':rubyfile command', function()
+ it('evaluates a ruby file', function()
+ local fname = 'rubyfile.rb'
+ write_file(fname, 'VIM.command("let set_by_rubyfile = 123")')
+ command('rubyfile rubyfile.rb')
+ eq(123, meths.get_var('set_by_rubyfile'))
+ os.remove(fname)
+ end)
+end)
+
+describe(':rubydo command', function()
+ it('exposes the $_ variable for modifying lines', function()
+ insert('abc\ndef\nghi\njkl')
+ expect([[
+ abc
+ def
+ ghi
+ jkl]])
+
+ feed('ggjvj:rubydo $_.upcase!<CR>')
+ expect([[
+ abc
+ DEF
+ GHI
+ jkl]])
+ end)
+
+ it('operates on all lines when not given a range', function()
+ insert('abc\ndef\nghi\njkl')
+ expect([[
+ abc
+ def
+ ghi
+ jkl]])
+
+ feed(':rubydo $_.upcase!<CR>')
+ expect([[
+ ABC
+ DEF
+ GHI
+ JKL]])
+ end)
+
+ it('does not modify the buffer if no changes are made', function()
+ command('normal :rubydo 42')
+ eq(false, curbufmeths.get_option('modified'))
+ end)
+end)
diff --git a/test/functional/shada/buffers_spec.lua b/test/functional/shada/buffers_spec.lua
index fd4809e01a..e4d02c268b 100644
--- a/test/functional/shada/buffers_spec.lua
+++ b/test/functional/shada/buffers_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa buffer list saving/reading support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim_command, funcs, eq, curbufmeths =
helpers.command, helpers.funcs, helpers.eq, helpers.curbufmeths
diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua
index 1fa88c58e5..1287ac010c 100644
--- a/test/functional/shada/compatibility_spec.lua
+++ b/test/functional/shada/compatibility_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa compatibility support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim_command, funcs, eq = helpers.command, helpers.funcs, helpers.eq
local exc_exec = helpers.exc_exec
diff --git a/test/functional/shada/errors_spec.lua b/test/functional/shada/errors_spec.lua
index e7951ee74c..98ead6cc3d 100644
--- a/test/functional/shada/errors_spec.lua
+++ b/test/functional/shada/errors_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa errors handling support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim_command, eq, exc_exec, redir_exec =
helpers.command, helpers.eq, helpers.exc_exec, helpers.redir_exec
diff --git a/test/functional/shada/helpers.lua b/test/functional/shada/helpers.lua
index d4eb7f57bd..bb2919d4fb 100644
--- a/test/functional/shada/helpers.lua
+++ b/test/functional/shada/helpers.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(nil)
local spawn, set_session, meths, nvim_prog =
helpers.spawn, helpers.set_session, helpers.meths, helpers.nvim_prog
local write_file, merge_args = helpers.write_file, helpers.merge_args
diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua
index 94513945d0..22e653b1d6 100644
--- a/test/functional/shada/history_spec.lua
+++ b/test/functional/shada/history_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa history saving/reading support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim_command, funcs, meths, nvim_feed, eq =
helpers.command, helpers.funcs, helpers.meths, helpers.feed, helpers.eq
diff --git a/test/functional/shada/marks_spec.lua b/test/functional/shada/marks_spec.lua
index 955a6f382b..ace3c74a62 100644
--- a/test/functional/shada/marks_spec.lua
+++ b/test/functional/shada/marks_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa marks saving/reading support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local meths, curwinmeths, curbufmeths, nvim_command, funcs, eq =
helpers.meths, helpers.curwinmeths, helpers.curbufmeths, helpers.command,
helpers.funcs, helpers.eq
diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua
index 221f989409..25c73b99eb 100644
--- a/test/functional/shada/merging_spec.lua
+++ b/test/functional/shada/merging_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa merging data support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim_command, funcs, curbufmeths, eq =
helpers.command, helpers.funcs,
helpers.curbufmeths, helpers.eq
diff --git a/test/functional/shada/registers_spec.lua b/test/functional/shada/registers_spec.lua
index 4043d94a69..f1c587c640 100644
--- a/test/functional/shada/registers_spec.lua
+++ b/test/functional/shada/registers_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa registers saving/reading support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local nvim_command, funcs, eq = helpers.command, helpers.funcs, helpers.eq
local shada_helpers = require('test.functional.shada.helpers')
diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua
index 683d520627..32e7b16fc5 100644
--- a/test/functional/shada/shada_spec.lua
+++ b/test/functional/shada/shada_spec.lua
@@ -1,5 +1,5 @@
-- Other ShaDa tests
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local meths, nvim_command, funcs, eq =
helpers.meths, helpers.command, helpers.funcs, helpers.eq
local write_file, spawn, set_session, nvim_prog, exc_exec =
diff --git a/test/functional/shada/variables_spec.lua b/test/functional/shada/variables_spec.lua
index 7ceeafdc71..40101baf8f 100644
--- a/test/functional/shada/variables_spec.lua
+++ b/test/functional/shada/variables_spec.lua
@@ -1,5 +1,5 @@
-- ShaDa variables saving/reading support
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local meths, funcs, nvim_command, eq, exc_exec =
helpers.meths, helpers.funcs, helpers.command, helpers.eq, helpers.exc_exec
diff --git a/test/functional/shell/bang_filter_spec.lua b/test/functional/shell/bang_filter_spec.lua
index 964dbd1029..cd5325c4e1 100644
--- a/test/functional/shell/bang_filter_spec.lua
+++ b/test/functional/shell/bang_filter_spec.lua
@@ -1,6 +1,6 @@
-- Specs for bang/filter commands
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local feed, execute, clear = helpers.feed, helpers.execute, helpers.clear
local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdir
diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua
index 00b16e9158..3de022cbd9 100644
--- a/test/functional/shell/viml_system_spec.lua
+++ b/test/functional/shell/viml_system_spec.lua
@@ -2,7 +2,7 @@
-- - `system()`
-- - `systemlist()`
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local eq, clear, eval, feed, nvim =
helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.nvim
@@ -151,8 +151,8 @@ describe('system()', function()
describe('with output containing NULs', function()
local fname = 'Xtest'
- setup(create_file_with_nuls(fname))
- teardown(delete_file(fname))
+ before_each(create_file_with_nuls(fname))
+ after_each(delete_file(fname))
it('replaces NULs by SOH characters', function()
eq('part1\001part2\001part3\n', eval('system("cat '..fname..'")'))
@@ -310,8 +310,8 @@ describe('systemlist()', function()
describe('with output containing NULs', function()
local fname = 'Xtest'
- setup(create_file_with_nuls(fname))
- teardown(delete_file(fname))
+ before_each(create_file_with_nuls(fname))
+ after_each(delete_file(fname))
it('replaces NULs by newline characters', function()
eq({'part1\npart2\npart3'}, eval('systemlist("cat '..fname..'")'))
diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua
index d9d96b25f9..e1760c8ad8 100644
--- a/test/functional/terminal/altscreen_spec.lua
+++ b/test/functional/terminal/altscreen_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
local feed = helpers.feed
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index cefb603a7e..8a535d6864 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local wait = helpers.wait
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index c15da2f760..461ddd0ec7 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua
index dcc4a54610..c98aef70b1 100644
--- a/test/functional/terminal/edit_spec.lua
+++ b/test/functional/terminal/edit_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local screen = require('test.functional.ui.screen')
local curbufmeths = helpers.curbufmeths
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index d89092ff27..458fa02fca 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, wait, nvim = helpers.clear, helpers.wait, helpers.nvim
local nvim_dir, source, eq = helpers.nvim_dir, helpers.source, helpers.eq
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index a32ae650d6..3d1530bd90 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(nil)
local Screen = require('test.functional.ui.screen')
local nvim_dir = helpers.nvim_dir
local execute, nvim, wait = helpers.execute, helpers.nvim, helpers.wait
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 97875c5147..8d7c7451d3 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
@@ -165,24 +165,49 @@ end)
describe('synIDattr()', function()
local screen
-
before_each(function()
clear()
screen = Screen.new(50, 7)
- execute('highlight Normal ctermfg=1 guifg=#ff0000')
+ execute('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black')
+ -- Salmon #fa8072 Maroon #800000
+ execute('highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon')
+ end)
+
+ it('returns cterm-color if RGB-capable UI is _not_ attached', function()
+ eq('252', eval('synIDattr(hlID("Normal"), "fg")'))
+ eq('252', eval('synIDattr(hlID("Normal"), "fg#")'))
+ eq('-1', eval('synIDattr(hlID("Normal"), "bg")'))
+ eq('-1', eval('synIDattr(hlID("Normal"), "bg#")'))
+ eq('79', eval('synIDattr(hlID("Keyword"), "fg")'))
+ eq('79', eval('synIDattr(hlID("Keyword"), "fg#")'))
+ eq('', eval('synIDattr(hlID("Keyword"), "sp")'))
+ eq('', eval('synIDattr(hlID("Keyword"), "sp#")'))
end)
- after_each(function()
- screen:detach()
+ it('returns gui-color if "gui" arg is passed', function()
+ eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")'))
+ eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp", "gui")'))
+ end)
+
+ it('returns gui-color if RGB-capable UI is attached', function()
+ screen:attach(true)
+ eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")'))
+ eq('Black', eval('synIDattr(hlID("Normal"), "bg")'))
+ eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")'))
+ eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")'))
end)
- it('returns RGB number if GUI', function()
+ it('returns #RRGGBB value for fg#/bg#/sp#', function()
screen:attach(true)
- eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")'))
+ eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg#")'))
+ eq('#000000', eval('synIDattr(hlID("Normal"), "bg#")'))
+ eq('#fa8072', eval('synIDattr(hlID("Keyword"), "fg#")'))
+ eq('#800000', eval('synIDattr(hlID("Keyword"), "sp#")'))
end)
it('returns color number if non-GUI', function()
screen:attach(false)
- eq('1', eval('synIDattr(hlID("Normal"), "fg")'))
+ eq('252', eval('synIDattr(hlID("Normal"), "fg")'))
+ eq('79', eval('synIDattr(hlID("Keyword"), "fg")'))
end)
end)
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index c4bd3c2663..a86615184d 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear = helpers.clear
local feed, nvim = helpers.feed, helpers.nvim
@@ -112,7 +112,7 @@ describe('terminal mouse', function()
line28 |line28 |
line29 |line29 |
line30 |line30 |
- rows: 5, cols: 24 |rows: 5, cols: 24 |
+ rows: 5, cols: 25 |rows: 5, cols: 25 |
{2:^ } |{2: } |
========== ========== |
|
@@ -122,7 +122,7 @@ describe('terminal mouse', function()
1 ^ |line28 |
~ |line29 |
~ |line30 |
- ~ |rows: 5, cols: 24 |
+ ~ |rows: 5, cols: 25 |
~ |{2: } |
========== ========== |
:enew | set number |
@@ -132,16 +132,16 @@ describe('terminal mouse', function()
27 line |line28 |
28 line |line29 |
29 line |line30 |
- 30 line |rows: 5, cols: 24 |
+ 30 line |rows: 5, cols: 25 |
31 ^ |{2: } |
========== ========== |
|
]])
feed('<c-w>li')
screen:expect([[
- 27 line |line28 |
- 28 line |line29 |
- 29 line |line30 |
+ 27 line |line29 |
+ 28 line |line30 |
+ 29 line |rows: 5, cols: 25 |
30 line |rows: 5, cols: 24 |
31 |{1: } |
========== ========== |
@@ -151,8 +151,8 @@ describe('terminal mouse', function()
thelpers.enable_mouse()
thelpers.feed_data('mouse enabled\n')
screen:expect([[
- 27 line |line29 |
- 28 line |line30 |
+ 27 line |line30 |
+ 28 line |rows: 5, cols: 25 |
29 line |rows: 5, cols: 24 |
30 line |mouse enabled |
31 |{1: } |
@@ -164,8 +164,8 @@ describe('terminal mouse', function()
it('wont lose focus if another window is scrolled', function()
feed('<MouseDown><0,0><MouseDown><0,0>')
screen:expect([[
- 21 line |line29 |
- 22 line |line30 |
+ 21 line |line30 |
+ 22 line |rows: 5, cols: 25 |
23 line |rows: 5, cols: 24 |
24 line |mouse enabled |
25 line |{1: } |
@@ -174,8 +174,8 @@ describe('terminal mouse', function()
]])
feed('<S-MouseUp><0,0>')
screen:expect([[
- 26 line |line29 |
- 27 line |line30 |
+ 26 line |line30 |
+ 27 line |rows: 5, cols: 25 |
28 line |rows: 5, cols: 24 |
29 line |mouse enabled |
30 line |{1: } |
@@ -187,8 +187,8 @@ describe('terminal mouse', function()
it('will lose focus if another window is clicked', function()
feed('<LeftMouse><5,1>')
screen:expect([[
- 27 line |line29 |
- 28 l^ine |line30 |
+ 27 line |line30 |
+ 28 l^ine |rows: 5, cols: 25 |
29 line |rows: 5, cols: 24 |
30 line |mouse enabled |
31 |{2: } |
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 4b56698520..7914e30a44 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -1,5 +1,5 @@
local Screen = require('test.functional.ui.screen')
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
local feed, nvim_dir, execute = helpers.feed, helpers.nvim_dir, helpers.execute
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 364ca327a4..e6586c7892 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -1,6 +1,6 @@
-- Some sanity checks for the TUI using the builtin terminal emulator
-- as a simple way to send keys and assert screen state.
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local feed = thelpers.feed_data
local execute = helpers.execute
@@ -301,3 +301,72 @@ describe('tui focus event handling', function()
]])
end)
end)
+
+-- These tests require `thelpers` because --headless/--embed
+-- does not initialize the TUI.
+describe("tui 't_Co' (terminal colors)", function()
+ local screen
+ local is_linux = (helpers.eval("system('uname') =~? 'linux'") == 1)
+
+ local function assert_term_colors(term, colorterm, maxcolors)
+ helpers.clear({env={TERM=term}, args={}})
+ -- This is ugly because :term/termopen() forces TERM=xterm-256color.
+ -- TODO: Revisit this after jobstart/termopen accept `env` dict.
+ screen = thelpers.screen_setup(0, string.format(
+ [=[['sh', '-c', 'TERM=%s %s %s -u NONE -i NONE --cmd "silent set noswapfile"']]=],
+ term,
+ (colorterm ~= nil and "COLORTERM="..colorterm or ""),
+ helpers.nvim_prog))
+
+ thelpers.feed_data(":echo &t_Co\n")
+ screen:expect(string.format([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ %-3s |
+ -- TERMINAL -- |
+ ]], tostring(maxcolors and maxcolors or "")))
+ end
+
+ it("unknown TERM sets empty 't_Co'", function()
+ assert_term_colors("yet-another-term", nil, nil)
+ end)
+
+ it("unknown TERM with COLORTERM=screen-256color uses 256 colors", function()
+ assert_term_colors("yet-another-term", "screen-256color", 256)
+ end)
+
+ it("TERM=linux uses 8 colors", function()
+ if is_linux then
+ assert_term_colors("linux", nil, 8)
+ else
+ pending()
+ end
+ end)
+
+ it("TERM=screen uses 8 colors", function()
+ if is_linux then
+ assert_term_colors("screen", nil, 8)
+ else
+ pending()
+ end
+ end)
+
+ it("TERM=screen COLORTERM=screen-256color uses 256 colors", function()
+ assert_term_colors("screen", "screen-256color", 256)
+ end)
+
+ it("TERM=yet-another-term COLORTERM=screen-256color uses 256 colors", function()
+ assert_term_colors("screen", "screen-256color", 256)
+ end)
+
+ it("TERM=xterm uses 256 colors", function()
+ assert_term_colors("xterm", nil, 256)
+ end)
+
+ it("TERM=xterm-256color uses 256 colors", function()
+ assert_term_colors("xterm-256color", nil, 256)
+ end)
+end)
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 6c236ed868..eec8b53f4d 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -1,8 +1,8 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local wait = helpers.wait
-
+local execute = helpers.execute
describe('terminal window', function()
local screen
@@ -12,6 +12,23 @@ describe('terminal window', function()
screen = thelpers.screen_setup()
end)
+ it('resets its size when entering terminal buffer', function()
+ feed('<c-\\><c-n>')
+ execute('set hidden')
+ execute('edit foo')
+ execute('doautoall SessionLoadPost')
+ execute('silent bnext')
+ screen:expect([[
+ tty ready |
+ {2: } |
+ |
+ |
+ |
+ ^ |
+ :silent bnext |
+ ]])
+ end)
+
describe('with colorcolumn set', function()
before_each(function()
feed('<c-\\><c-n>')
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index 727eba2717..644060103a 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -1,7 +1,8 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear = helpers.clear
local feed, nvim = helpers.feed, helpers.nvim
+local execute = helpers.execute
describe('terminal', function()
local screen
@@ -21,6 +22,49 @@ describe('terminal', function()
screen:detach()
end)
+ it('resets its size when entering terminal window', function()
+ feed('<c-\\><c-n>')
+ execute('2split')
+ screen:expect([[
+ tty ready |
+ ^rows: 2, cols: 50 |
+ ========== |
+ tty ready |
+ rows: 2, cols: 50 |
+ {2: } |
+ ~ |
+ ~ |
+ ========== |
+ |
+ ]])
+ execute('wincmd p')
+ screen:expect([[
+ tty ready |
+ rows: 2, cols: 50 |
+ ========== |
+ tty ready |
+ rows: 2, cols: 50 |
+ rows: 5, cols: 50 |
+ {2: } |
+ ^ |
+ ========== |
+ :wincmd p |
+ ]])
+ execute('wincmd p')
+ screen:expect([[
+ rows: 5, cols: 50 |
+ ^rows: 2, cols: 50 |
+ ========== |
+ rows: 5, cols: 50 |
+ rows: 2, cols: 50 |
+ {2: } |
+ ~ |
+ ~ |
+ ========== |
+ :wincmd p |
+ ]])
+ end)
+
describe('when the screen is resized', function()
it('will forward a resize request to the program', function()
screen:try_resize(screen._width + 3, screen._height + 5)
@@ -51,87 +95,4 @@ describe('terminal', function()
]])
end)
end)
-
- describe('split horizontally', function()
- before_each(function()
- nvim('command', 'sp')
- end)
-
- local function reduce_height()
- screen:expect([[
- tty ready |
- rows: 3, cols: 50 |
- {1: } |
- ~ |
- ========== |
- tty ready |
- rows: 3, cols: 50 |
- {2: } |
- ========== |
- -- TERMINAL -- |
- ]])
- end
-
- it('uses the minimum height of all window displaying it', reduce_height)
-
- describe('and then vertically', function()
- before_each(function()
- reduce_height()
- nvim('command', 'vsp')
- end)
-
- local function reduce_width()
- screen:expect([[
- rows: 3, cols: 50 |rows: 3, cols: 50 |
- rows: 3, cols: 24 |rows: 3, cols: 24 |
- {1: } |{2: } |
- ~ |~ |
- ========== ========== |
- rows: 3, cols: 50 |
- rows: 3, cols: 24 |
- {2: } |
- ========== |
- -- TERMINAL -- |
- ]])
- feed('<c-\\><c-n>gg')
- screen:expect([[
- ^tty ready |rows: 3, cols: 50 |
- rows: 3, cols: 50 |rows: 3, cols: 24 |
- rows: 3, cols: 24 |{2: } |
- {2: } |~ |
- ========== ========== |
- rows: 3, cols: 50 |
- rows: 3, cols: 24 |
- {2: } |
- ========== |
- |
- ]])
- end
-
- it('uses the minimum width of all window displaying it', reduce_width)
-
- describe('and then closes one of the vertical splits with q:', function()
- before_each(function()
- reduce_width()
- nvim('command', 'q')
- feed('<c-w>ja')
- end)
-
- it('will restore the width', function()
- screen:expect([[
- rows: 3, cols: 24 |
- rows: 3, cols: 50 |
- {2: } |
- ~ |
- ========== |
- rows: 3, cols: 24 |
- rows: 3, cols: 50 |
- {1: } |
- ========== |
- -- TERMINAL -- |
- ]])
- end)
- end)
- end)
- end)
end)
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua
index 58f5b11de0..f91aa8d402 100644
--- a/test/functional/ui/bufhl_spec.lua
+++ b/test/functional/ui/bufhl_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, request, neq = helpers.execute, helpers.request, helpers.neq
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 85fca4d7ca..6ef40fff62 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local os = require('os')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
@@ -38,7 +38,6 @@ describe('manual syntax highlight', function()
os.remove('Xtest-functional-ui-highlight.tmp.vim')
end)
- -- test with "set hidden" even if the bug did not occur this way
it("works with buffer switch and 'hidden'", function()
execute('e tmp1.vim')
execute('e Xtest-functional-ui-highlight.tmp.vim')
diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua
index 6f5cadaf81..407c576002 100644
--- a/test/functional/ui/input_spec.lua
+++ b/test/functional/ui/input_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear, execute, nvim = helpers.clear, helpers.execute, helpers.nvim
local feed, next_message, eq = helpers.feed, helpers.next_message, helpers.eq
local expect = helpers.expect
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index 993bbd5b0e..7b820347ac 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths
local insert, execute = helpers.insert, helpers.execute
@@ -462,4 +462,321 @@ describe('Mouse input', function()
|
]])
end)
+
+ describe('on concealed text', function()
+ -- Helpful for reading the test expectations:
+ -- :match Error /\^/
+ local concealed = {
+ c = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray }
+ }
+
+ before_each(function()
+ screen:try_resize(25, 7)
+ feed('ggdG')
+
+ execute('set concealcursor=n')
+ execute('set nowrap')
+ execute('syntax match NonText "\\<amet\\>" conceal')
+ execute('syntax match NonText "\\cs\\|g." conceal cchar=X')
+ execute('syntax match NonText "\\%(lo\\|cl\\)." conceal')
+ execute('syntax match NonText "Lo" conceal cchar=Y')
+
+ insert([[
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
+ Stet clita kasd gubergren, no sea takimata sanctus est.
+ ]])
+
+ feed('gg')
+ end)
+
+ it('(level 1) click on non-wrapped lines', function()
+ execute('let &conceallevel=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do{c: } {c:X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><1,0>')
+ screen:expect([[
+ {c:Y}^rem ip{c:X}um do{c: } {c:X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,0>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:^X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: }, con|
+ {c:X}tet {c: }ta ka{c:X}d {c:X}^ber{c:X}en, no|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+ end) -- level 1 - non wrapped
+
+ it('(level 1) click on wrapped lines', function()
+ execute('let &conceallevel=1', 'let &wrap=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><6,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}^etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}etetur {c:X}a^dip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,3>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do{c: } {c:X}it {c: } |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet {c: }ta ka{c:X}d {c:X}^ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+ end) -- level 1 - wrapped
+
+
+ it('(level 2) click on non-wrapped lines', function()
+ execute('let &conceallevel=2', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do {c:X}it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><1,0>')
+ screen:expect([[
+ {c:Y}^rem ip{c:X}um do {c:X}it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,0>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}^it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it , con{c:X}e|
+ {c:X}tet ta ka{c:X}d {c:X}b^er{c:X}en, no |
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+ end) -- level 2 - non wrapped
+
+ it('(level 2) click on wrapped lines', function()
+ execute('let &conceallevel=2', 'let &wrap=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ {c:^Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><6,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}^etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}etetur {c:X}a^dip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}ber{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,3>')
+ screen:expect([[
+ {c:Y}rem ip{c:X}um do {c:X}it |
+ , con{c:X}etetur {c:X}adip{c:X}cin{c:X} |
+ elitr. |
+ {c:X}tet ta ka{c:X}d {c:X}b^er{c:X}en |
+ , no {c:X}ea takimata {c:X}anctu{c:X}|
+ e{c:X}t. |
+ |
+ ]], concealed)
+ end) -- level 2 - wrapped
+
+
+ it('(level 3) click on non-wrapped lines', function()
+ execute('let &conceallevel=3', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ ^rem ipum do it , conetetu|
+ tet ta kad beren, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><1,0>')
+ screen:expect([[
+ r^em ipum do it , conetetu|
+ tet ta kad beren, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,0>')
+ screen:expect([[
+ rem ipum do it ^, conetetu|
+ tet ta kad beren, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ rem ipum do it , conetetu|
+ tet ta kad bere^n, no ea t|
+ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], concealed)
+ end) -- level 3 - non wrapped
+
+ it('(level 3) click on wrapped lines', function()
+ execute('let &conceallevel=3', 'let &wrap=1', 'echo')
+
+ feed('<esc><LeftMouse><0,0>')
+ screen:expect([[
+ ^rem ipum do it |
+ , conetetur adipcin |
+ elitr. |
+ tet ta kad beren |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><6,1>')
+ screen:expect([[
+ rem ipum do it |
+ , cone^tetur adipcin |
+ elitr. |
+ tet ta kad beren |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,1>')
+ screen:expect([[
+ rem ipum do it |
+ , conetetur adi^pcin |
+ elitr. |
+ tet ta kad beren |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+
+ feed('<esc><LeftMouse><15,3>')
+ screen:expect([[
+ rem ipum do it |
+ , conetetur adipcin |
+ elitr. |
+ tet ta kad bere^n |
+ , no ea takimata anctu |
+ et. |
+ |
+ ]], concealed)
+ end) -- level 3 - wrapped
+ end)
end)
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
new file mode 100644
index 0000000000..c7c8986527
--- /dev/null
+++ b/test/functional/ui/output_spec.lua
@@ -0,0 +1,39 @@
+local session = require('test.functional.helpers')(after_each)
+local child_session = require('test.functional.terminal.helpers')
+
+describe("shell command :!", function()
+ local screen
+ before_each(function()
+ session.clear()
+ screen = child_session.screen_setup(0, '["'..session.nvim_prog..
+ '", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile"]')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ |
+ -- TERMINAL -- |
+ ]])
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it("displays output even without LF/EOF. #4646 #4569 #3772", function()
+ -- NOTE: We use a child nvim (within a :term buffer)
+ -- to avoid triggering a UI flush.
+ child_session.feed_data(":!printf foo; sleep 200\n")
+ screen:expect([[
+ ~ |
+ ~ |
+ [No Name] |
+ :!printf foo; sleep 200 |
+ |
+ foo |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 6372cbe081..d7af2a4fce 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -105,7 +105,7 @@
-- To generate a text-only test without highlight checks,
-- use `screen:snapshot_util({},true)`
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(nil)
local request, run = helpers.request, helpers.run
local dedent = helpers.dedent
@@ -290,6 +290,10 @@ If everything else fails, use Screen:redraw_debug to help investigate what is
end
end
+function Screen:sleep(ms)
+ pcall(function() self:wait(function() return "error" end, ms) end)
+end
+
function Screen:_redraw(updates)
for _, update in ipairs(updates) do
-- print('--')
@@ -501,7 +505,7 @@ end
function Screen:snapshot_util(attrs, ignore)
-- util to generate screen test
- pcall(function() self:wait(function() return "error" end, 250) end)
+ self:sleep(250)
self:print_snapshot(attrs, ignore)
end
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index a4545eeff0..9249be4aec 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.clear
local feed, execute = helpers.feed, helpers.execute
diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua
index e4217abcfe..894a75d355 100644
--- a/test/functional/ui/searchhl_spec.lua
+++ b/test/functional/ui/searchhl_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute = helpers.execute
diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua
index c32a7b9381..2b6e294627 100644
--- a/test/functional/ui/sign_spec.lua
+++ b/test/functional/ui/sign_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
diff --git a/test/functional/ui/syntax_conceal_spec.lua b/test/functional/ui/syntax_conceal_spec.lua
index 66ea779011..c2ab0711c0 100644
--- a/test/functional/ui/syntax_conceal_spec.lua
+++ b/test/functional/ui/syntax_conceal_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
local insert = helpers.insert
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index c57d4abcbf..2a55d27567 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
local funcs = helpers.funcs
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 2b3844bf6d..33f481bae2 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed = helpers.clear, helpers.feed
local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
diff --git a/test/functional/viml/errorlist_spec.lua b/test/functional/viml/errorlist_spec.lua
index 30cb86f8d1..56d08771b7 100644
--- a/test/functional/viml/errorlist_spec.lua
+++ b/test/functional/viml/errorlist_spec.lua
@@ -1,4 +1,4 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local command = helpers.command
diff --git a/test/functional/viml/function_spec.lua b/test/functional/viml/function_spec.lua
index 665f5d4467..f0a4406593 100644
--- a/test/functional/viml/function_spec.lua
+++ b/test/functional/viml/function_spec.lua
@@ -1,7 +1,8 @@
-local helpers = require('test.functional.helpers')
+local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
+local eval = helpers.eval
local exc_exec = helpers.exc_exec
describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
@@ -27,3 +28,11 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
eq('Vim(call):E740: Too many arguments for function rpcnotify', ret)
end)
end)
+
+describe('api_info()', function()
+ before_each(clear)
+ it('has the right keys', function()
+ local api_keys = eval("sort(keys(api_info()))")
+ eq({'error_types', 'functions', 'types'}, api_keys)
+ end)
+end)
diff --git a/test/functional/viml/lang_spec.lua b/test/functional/viml/lang_spec.lua
new file mode 100644
index 0000000000..a27e18f695
--- /dev/null
+++ b/test/functional/viml/lang_spec.lua
@@ -0,0 +1,22 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
+local execute, source = helpers.execute, helpers.source
+
+describe('viml', function()
+ before_each(clear)
+
+ it('parses `<SID>` with turkish locale', function()
+ execute('lang ctype tr_TR.UTF-8')
+ if string.find(eval('v:errmsg'), '^E197: ') then
+ pending("Locale tr_TR.UTF-8 not supported")
+ return
+ end
+ source([[
+ func! <sid>_dummy_function()
+ echo 1
+ endfunc
+ au VimEnter * call <sid>_dummy_function()
+ ]])
+ eq(nil, string.find(eval('v:errmsg'), '^E129'))
+ end)
+end)
diff --git a/test/helpers.lua b/test/helpers.lua
new file mode 100644
index 0000000000..4c50c7644f
--- /dev/null
+++ b/test/helpers.lua
@@ -0,0 +1,60 @@
+local assert = require('luassert')
+local lfs = require('lfs')
+
+local check_logs_useless_lines = {
+ ['Warning: noted but unhandled ioctl']=1,
+ ['could cause spurious value errors to appear']=2,
+ ['See README_MISSING_SYSCALL_OR_IOCTL for guidance']=3,
+}
+
+local eq = function(exp, act)
+ return assert.are.same(exp, act)
+end
+local neq = function(exp, act)
+ return assert.are_not.same(exp, act)
+end
+local ok = function(res)
+ return assert.is_true(res)
+end
+
+local function check_logs()
+ local log_dir = os.getenv('LOG_DIR')
+ local runtime_errors = 0
+ if log_dir and lfs.attributes(log_dir, 'mode') == 'directory' then
+ for tail in lfs.dir(log_dir) do
+ if tail:sub(1, 30) == 'valgrind-' or tail:find('san%.') then
+ local file = log_dir .. '/' .. tail
+ local fd = io.open(file)
+ local start_msg = ('='):rep(20) .. ' File ' .. file .. ' ' .. ('='):rep(20)
+ local lines = {}
+ local warning_line = 0
+ for line in fd:lines() do
+ local cur_warning_line = check_logs_useless_lines[line]
+ if cur_warning_line == warning_line + 1 then
+ warning_line = cur_warning_line
+ else
+ lines[#lines + 1] = line
+ end
+ end
+ fd:close()
+ os.remove(file)
+ if #lines > 0 then
+ -- local out = os.getenv('TRAVIS_CI_BUILD') and io.stdout or io.stderr
+ local out = io.stdout
+ out:write(start_msg .. '\n')
+ out:write('= ' .. table.concat(lines, '\n= ') .. '\n')
+ out:write(select(1, start_msg:gsub('.', '=')) .. '\n')
+ runtime_errors = runtime_errors + 1
+ end
+ end
+ end
+ end
+ assert(0 == runtime_errors)
+end
+
+return {
+ eq = eq,
+ neq = neq,
+ ok = ok,
+ check_logs = check_logs,
+}
diff --git a/test/unit/api/helpers.lua b/test/unit/api/helpers.lua
new file mode 100644
index 0000000000..883e1c6c19
--- /dev/null
+++ b/test/unit/api/helpers.lua
@@ -0,0 +1,156 @@
+local helpers = require('test.unit.helpers')
+local eval_helpers = require('test.unit.eval.helpers')
+
+local cimport = helpers.cimport
+local to_cstr = helpers.to_cstr
+local ffi = helpers.ffi
+
+local list_type = eval_helpers.list_type
+local dict_type = eval_helpers.dict_type
+local func_type = eval_helpers.func_type
+local nil_value = eval_helpers.nil_value
+local int_type = eval_helpers.int_type
+local flt_type = eval_helpers.flt_type
+local type_key = eval_helpers.type_key
+
+local api = cimport('./src/nvim/api/private/defs.h',
+ './src/nvim/api/private/helpers.h',
+ './src/nvim/memory.h')
+
+local obj2lua
+
+local obj2lua_tab = {
+ [tonumber(api.kObjectTypeArray)] = function(obj)
+ local ret = {[type_key]=list_type}
+ for i = 1,tonumber(obj.data.array.size) do
+ ret[i] = obj2lua(obj.data.array.items[i - 1])
+ end
+ if ret[1] then
+ ret[type_key] = nil
+ end
+ return ret
+ end,
+ [tonumber(api.kObjectTypeDictionary)] = function(obj)
+ local ret = {}
+ for i = 1,tonumber(obj.data.dictionary.size) do
+ local kv_pair = obj.data.dictionary.items[i - 1]
+ ret[ffi.string(kv_pair.key.data, kv_pair.key.size)] = obj2lua(kv_pair.value)
+ end
+ return ret
+ end,
+ [tonumber(api.kObjectTypeBoolean)] = function(obj)
+ if obj.data.boolean == false then
+ return false
+ else
+ return true
+ end
+ end,
+ [tonumber(api.kObjectTypeNil)] = function(_)
+ return nil_value
+ end,
+ [tonumber(api.kObjectTypeFloat)] = function(obj)
+ return tonumber(obj.data.floating)
+ end,
+ [tonumber(api.kObjectTypeInteger)] = function(obj)
+ return {[type_key]=int_type, value=tonumber(obj.data.integer)}
+ end,
+ [tonumber(api.kObjectTypeString)] = function(obj)
+ return ffi.string(obj.data.string.data, obj.data.string.size)
+ end,
+}
+
+obj2lua = function(obj)
+ return ((obj2lua_tab[tonumber(obj['type'])] or function(obj_inner)
+ assert(false, 'Converting ' .. tostring(tonumber(obj_inner['type'])) .. ' is not implementing yet')
+ end)(obj))
+end
+
+local obj = function(typ, data)
+ return ffi.gc(ffi.new('Object', {['type']=typ, data=data}),
+ api.api_free_object)
+end
+
+local lua2obj
+
+local lua2obj_type_tab = {
+ [int_type] = function(l)
+ return obj(api.kObjectTypeInteger, {integer=l.value})
+ end,
+ [flt_type] = function(l)
+ return obj(api.kObjectTypeFloat, {floating=l})
+ end,
+ [list_type] = function(l)
+ local len = #l
+ local arr = obj(api.kObjectTypeArray, {array={
+ size=len,
+ capacity=len,
+ items=ffi.cast('Object *', api.xmalloc(len * ffi.sizeof('Object'))),
+ }})
+ for i = 1, len do
+ arr.data.array.items[i - 1] = ffi.gc(lua2obj(l[i]), nil)
+ end
+ return arr
+ end,
+ [dict_type] = function(l)
+ local kvs = {}
+ for k, v in pairs(l) do
+ if type(k) == 'string' then
+ kvs[#kvs + 1] = {k, v}
+ end
+ end
+ local len = #kvs
+ local dct = obj(api.kObjectTypeDictionary, {dictionary={
+ size=len,
+ capacity=len,
+ items=ffi.cast('KeyValuePair *',
+ api.xmalloc(len * ffi.sizeof('KeyValuePair'))),
+ }})
+ for i = 1, len do
+ local key, val = table.unpack(kvs[i])
+ dct.data.dictionary.items[i - 1] = ffi.new(
+ 'KeyValuePair', {key=ffi.gc(lua2obj(key), nil).data.string,
+ value=ffi.gc(lua2obj(val), nil)})
+ end
+ return dct
+ end,
+}
+
+lua2obj = function(l)
+ if type(l) == 'table' then
+ if l[type_key] then
+ return lua2obj_type_tab[l[type_key]](l)
+ else
+ if l[1] then
+ return lua2obj_type_tab[list_type](l)
+ else
+ return lua2obj_type_tab[dict_type](l)
+ end
+ end
+ elseif type(l) == 'number' then
+ return lua2obj_type_tab[flt_type](l)
+ elseif type(l) == 'boolean' then
+ return obj(api.kObjectTypeBoolean, {boolean=l})
+ elseif type(l) == 'string' then
+ return obj(api.kObjectTypeString, {string={
+ size=#l,
+ data=api.xmemdupz(to_cstr(l), #l),
+ }})
+ elseif l == nil or l == nil_value then
+ return obj(api.kObjectTypeNil, {integer=0})
+ end
+end
+
+return {
+ list_type=list_type,
+ dict_type=dict_type,
+ func_type=func_type,
+ int_type=int_type,
+ flt_type=flt_type,
+
+ nil_value=nil_value,
+
+ type_key=type_key,
+
+ obj2lua=obj2lua,
+ lua2obj=lua2obj,
+}
diff --git a/test/unit/api/private_helpers_spec.lua b/test/unit/api/private_helpers_spec.lua
new file mode 100644
index 0000000000..1d7c03787b
--- /dev/null
+++ b/test/unit/api/private_helpers_spec.lua
@@ -0,0 +1,88 @@
+local helpers = require('test.unit.helpers')
+local eval_helpers = require('test.unit.eval.helpers')
+local api_helpers = require('test.unit.api.helpers')
+
+local cimport = helpers.cimport
+local NULL = helpers.NULL
+local eq = helpers.eq
+
+local lua2typvalt = eval_helpers.lua2typvalt
+local typvalt = eval_helpers.typvalt
+
+local nil_value = api_helpers.nil_value
+local list_type = api_helpers.list_type
+local int_type = api_helpers.int_type
+local type_key = api_helpers.type_key
+local obj2lua = api_helpers.obj2lua
+
+local api = cimport('./src/nvim/api/private/helpers.h')
+
+describe('vim_to_object', function()
+ local vim_to_object = function(l)
+ return obj2lua(api.vim_to_object(lua2typvalt(l)))
+ end
+
+ local different_output_test = function(name, input, output)
+ it(name, function()
+ eq(output, vim_to_object(input))
+ end)
+ end
+
+ local simple_test = function(name, l)
+ different_output_test(name, l, l)
+ end
+
+ simple_test('converts true', true)
+ simple_test('converts false', false)
+ simple_test('converts nil', nil_value)
+ simple_test('converts 1', 1)
+ simple_test('converts -1.5', -1.5)
+ simple_test('converts empty string', '')
+ simple_test('converts non-empty string', 'foobar')
+ simple_test('converts integer 10', {[type_key]=int_type, value=10})
+ simple_test('converts empty dictionary', {})
+ simple_test('converts dictionary with scalar values', {test=10, test2=true, test3='test'})
+ simple_test('converts dictionary with containers inside', {test={}, test2={1, 2}})
+ simple_test('converts empty list', {[type_key]=list_type})
+ simple_test('converts list with scalar values', {1, 2, 'test', 'foo'})
+ simple_test('converts list with containers inside', {{}, {test={}, test3={test4=true}}})
+
+ local dct = {}
+ dct.dct = dct
+ different_output_test('outputs nil for nested dictionaries (1 level)', dct, {dct=nil_value})
+
+ local lst = {}
+ lst[1] = lst
+ different_output_test('outputs nil for nested lists (1 level)', lst, {nil_value})
+
+ local dct2 = {test=true, dict=nil_value}
+ dct2.dct = {dct2}
+ different_output_test('outputs nil for nested dictionaries (2 level, in list)',
+ dct2, {dct={nil_value}, test=true, dict=nil_value})
+
+ local dct3 = {test=true, dict=nil_value}
+ dct3.dct = {dctin=dct3}
+ different_output_test('outputs nil for nested dictionaries (2 level, in dict)',
+ dct3, {dct={dctin=nil_value}, test=true, dict=nil_value})
+
+ local lst2 = {}
+ lst2[1] = {lst2}
+ different_output_test('outputs nil for nested lists (2 level, in list)', lst2, {{nil_value}})
+
+ local lst3 = {nil, true, false, 'ttest'}
+ lst3[1] = {lst=lst3}
+ different_output_test('outputs nil for nested lists (2 level, in dict)',
+ lst3, {{lst=nil_value}, true, false, 'ttest'})
+
+ it('outputs empty list for NULL list', function()
+ local tt = typvalt('VAR_LIST', {v_list=NULL})
+ eq(nil, tt.vval.v_list)
+ eq({[type_key]=list_type}, obj2lua(api.vim_to_object(tt)))
+ end)
+
+ it('outputs empty dict for NULL dict', function()
+ local tt = typvalt('VAR_DICT', {v_dict=NULL})
+ eq(nil, tt.vval.v_dict)
+ eq({}, obj2lua(api.vim_to_object(tt)))
+ end)
+end)
diff --git a/test/unit/buffer_spec.lua b/test/unit/buffer_spec.lua
index b7f82064d7..317c9be6e7 100644
--- a/test/unit/buffer_spec.lua
+++ b/test/unit/buffer_spec.lua
@@ -1,10 +1,9 @@
-local assert = require("luassert")
local helpers = require("test.unit.helpers")
local to_cstr = helpers.to_cstr
+local get_str = helpers.ffi.string
local eq = helpers.eq
-local neq = helpers.neq
local NULL = helpers.NULL
local globals = helpers.cimport("./src/nvim/globals.h")
@@ -211,93 +210,246 @@ describe('buffer functions', function()
end)
describe('build_stl_str_hl', function()
+ local buffer_byte_size = 100
+ local STL_MAX_ITEM = 80
+ local output_buffer = ''
+
+ -- This function builds the statusline
+ --
+ -- @param arg Optional arguments are:
+ -- .pat The statusline format string
+ -- .fillchar The fill character used in the statusline
+ -- .maximum_cell_count The number of cells available in the statusline
+ local function build_stl_str_hl(arg)
+ output_buffer = to_cstr(string.rep(" ", buffer_byte_size))
+
+ local pat = arg.pat or ''
+ local fillchar = arg.fillchar or (' '):byte()
+ local maximum_cell_count = arg.maximum_cell_count or buffer_byte_size
- local output_buffer = to_cstr(string.rep(" ", 100))
-
- local build_stl_str_hl = function(pat)
return buffer.build_stl_str_hl(globals.curwin,
output_buffer,
- 100,
+ buffer_byte_size,
to_cstr(pat),
false,
- 32,
- 80,
+ fillchar,
+ maximum_cell_count,
NULL,
NULL)
end
- it('should copy plain text', function()
- local width = build_stl_str_hl("this is a test")
-
- eq(14, width)
- eq("this is a test", helpers.ffi.string(output_buffer, width))
-
- end)
-
- it('should print no file name', function()
- local width = build_stl_str_hl("%f")
-
- eq(9, width)
- eq("[No Name]", helpers.ffi.string(output_buffer, width))
-
- end)
-
- it('should print the relative file name', function()
- buffer.setfname(globals.curbuf, to_cstr("Makefile"), NULL, 1)
- local width = build_stl_str_hl("%f")
-
- eq(8, width)
- eq("Makefile", helpers.ffi.string(output_buffer, width))
-
- end)
-
- it('should print the full file name', function()
- buffer.setfname(globals.curbuf, to_cstr("Makefile"), NULL, 1)
-
- local width = build_stl_str_hl("%F")
-
- assert.is_true(8 < width)
- neq(NULL, string.find(helpers.ffi.string(output_buffer, width), "Makefile"))
-
- end)
-
- it('should print the tail file name', function()
- buffer.setfname(globals.curbuf, to_cstr("src/nvim/buffer.c"), NULL, 1)
-
- local width = build_stl_str_hl("%t")
-
- eq(8, width)
- eq("buffer.c", helpers.ffi.string(output_buffer, width))
-
- end)
-
- it('should print the buffer number', function()
- buffer.setfname(globals.curbuf, to_cstr("src/nvim/buffer.c"), NULL, 1)
-
- local width = build_stl_str_hl("%n")
-
- eq(1, width)
- eq("1", helpers.ffi.string(output_buffer, width))
- end)
-
- it('should print the current line number in the buffer', function()
- buffer.setfname(globals.curbuf, to_cstr("test/unit/buffer_spec.lua"), NULL, 1)
-
- local width = build_stl_str_hl("%l")
-
- eq(1, width)
- eq("0", helpers.ffi.string(output_buffer, width))
-
- end)
-
- it('should print the number of lines in the buffer', function()
- buffer.setfname(globals.curbuf, to_cstr("test/unit/buffer_spec.lua"), NULL, 1)
-
- local width = build_stl_str_hl("%L")
+ -- Use this function to simplify testing the comparison between
+ -- the format string and the resulting statusline.
+ --
+ -- @param description The description of what the test should be doing
+ -- @param statusline_cell_count The number of cells available in the statusline
+ -- @param input_stl The format string for the statusline
+ -- @param expected_stl The expected result string for the statusline
+ --
+ -- @param arg Options can be placed in an optional dictionary as the last parameter
+ -- .expected_cell_count The expected number of cells build_stl_str_hl will return
+ -- .expected_byte_length The expected byte length of the string
+ -- .file_name The name of the file to be tested (useful in %f type tests)
+ -- .fillchar The character that will be used to fill any 'extra' space in the stl
+ local function statusline_test (description,
+ statusline_cell_count,
+ input_stl,
+ expected_stl,
+ arg)
+
+ -- arg is the optional parameter
+ -- so we either fill in option with arg or an empty dictionary
+ local option = arg or {}
+
+ local fillchar = option.fillchar or (' '):byte()
+ local expected_cell_count = option.expected_cell_count or statusline_cell_count
+ local expected_byte_length = option.expected_byte_length or expected_cell_count
+
+ it(description, function()
+ if option.file_name then
+ buffer.setfname(globals.curbuf, to_cstr(option.file_name), NULL, 1)
+ else
+ buffer.setfname(globals.curbuf, nil, NULL, 1)
+ end
+
+ local result_cell_count = build_stl_str_hl{pat=input_stl,
+ maximum_cell_count=statusline_cell_count,
+ fillchar=fillchar}
+
+ eq(expected_stl, get_str(output_buffer, expected_byte_length))
+ eq(expected_cell_count, result_cell_count)
+ end)
+ end
- eq(1, width)
- eq("1", helpers.ffi.string(output_buffer, width))
+ -- file name testing
+ statusline_test('should print no file name', 10,
+ '%f', '[No Name]',
+ {expected_cell_count=9})
+ statusline_test('should print the relative file name', 30,
+ '%f', 'test/unit/buffer_spec.lua',
+ {file_name='test/unit/buffer_spec.lua', expected_cell_count=25})
+ statusline_test('should print the full file name', 40,
+ '%F', '/test/unit/buffer_spec.lua',
+ {file_name='/test/unit/buffer_spec.lua', expected_cell_count=26})
+
+ -- fillchar testing
+ statusline_test('should handle `!` as a fillchar', 10,
+ 'abcde%=', 'abcde!!!!!',
+ {fillchar=('!'):byte()})
+ statusline_test('should handle `~` as a fillchar', 10,
+ '%=abcde', '~~~~~abcde',
+ {fillchar=('~'):byte()})
+ statusline_test('should put fillchar `!` in between text', 10,
+ 'abc%=def', 'abc!!!!def',
+ {fillchar=('!'):byte()})
+ statusline_test('should put fillchar `~` in between text', 10,
+ 'abc%=def', 'abc~~~~def',
+ {fillchar=('~'):byte()})
+ statusline_test('should print the tail file name', 80,
+ '%t', 'buffer_spec.lua',
+ {file_name='test/unit/buffer_spec.lua', expected_cell_count=15})
+
+ -- standard text testing
+ statusline_test('should copy plain text', 80,
+ 'this is a test', 'this is a test',
+ {expected_cell_count=14})
+
+ -- line number testing
+ statusline_test('should print the buffer number', 80,
+ '%n', '1',
+ {expected_cell_count=1})
+ statusline_test('should print the current line number in the buffer', 80,
+ '%l', '0',
+ {expected_cell_count=1})
+ statusline_test('should print the number of lines in the buffer', 80,
+ '%L', '1',
+ {expected_cell_count=1})
+
+ -- truncation testing
+ statusline_test('should truncate when standard text pattern is too long', 10,
+ '0123456789abcde', '<6789abcde')
+ statusline_test('should truncate when using =', 10,
+ 'abcdef%=ghijkl', 'abcdef<jkl')
+ statusline_test('should truncate centered text when using ==', 10,
+ 'abcde%=gone%=fghij', 'abcde<ghij')
+ statusline_test('should respect the `<` marker', 10,
+ 'abc%<defghijkl', 'abc<ghijkl')
+ statusline_test('should truncate at `<` with one `=`, test 1', 10,
+ 'abc%<def%=ghijklmno', 'abc<jklmno')
+ statusline_test('should truncate at `<` with one `=`, test 2', 10,
+ 'abcdef%=ghijkl%<mno', 'abcdefghi>')
+ statusline_test('should truncate at `<` with one `=`, test 3', 10,
+ 'abc%<def%=ghijklmno', 'abc<jklmno')
+ statusline_test('should truncate at `<` with one `=`, test 4', 10,
+ 'abc%<def%=ghij', 'abcdefghij')
+ statusline_test('should truncate at `<` with one `=`, test 4', 10,
+ 'abc%<def%=ghijk', 'abc<fghijk')
+
+ statusline_test('should truncate at `<` with many `=`, test 4', 10,
+ 'ab%<cdef%=g%=h%=ijk', 'ab<efghijk')
+
+ statusline_test('should truncate at the first `<`', 10,
+ 'abc%<def%<ghijklm', 'abc<hijklm')
+
+ -- alignment testing
+ statusline_test('should right align when using =', 20,
+ 'neo%=vim', 'neo vim')
+ statusline_test('should, when possible, center text when using %=text%=', 20,
+ 'abc%=neovim%=def', 'abc neovim def')
+ statusline_test('should handle uneven spacing in the buffer when using %=text%=', 20,
+ 'abc%=neo_vim%=def', 'abc neo_vim def')
+ statusline_test('should have equal spaces even with non-equal sides when using =', 20,
+ 'foobar%=test%=baz', 'foobar test baz')
+ statusline_test('should have equal spaces even with longer right side when using =', 20,
+ 'a%=test%=longtext', 'a test longtext')
+ statusline_test('should handle an empty left side when using ==', 20,
+ '%=test%=baz', ' test baz')
+ statusline_test('should handle an empty right side when using ==', 20,
+ 'foobar%=test%=', 'foobar test ')
+ statusline_test('should handle consecutive empty ==', 20,
+ '%=%=test%=', ' test ')
+ statusline_test('should handle an = alone', 20,
+ '%=', ' ')
+ statusline_test('should right align text when it is alone with =', 20,
+ '%=foo', ' foo')
+ statusline_test('should left align text when it is alone with =', 20,
+ 'foo%=', 'foo ')
+
+ statusline_test('should approximately center text when using %=text%=', 21,
+ 'abc%=neovim%=def', 'abc neovim def')
+ statusline_test('should completely fill the buffer when using %=text%=', 21,
+ 'abc%=neo_vim%=def', 'abc neo_vim def')
+ statusline_test('should have equal spaces even with non-equal sides when using =', 21,
+ 'foobar%=test%=baz', 'foobar test baz')
+ statusline_test('should have equal spaces even with longer right side when using =', 21,
+ 'a%=test%=longtext', 'a test longtext')
+ statusline_test('should handle an empty left side when using ==', 21,
+ '%=test%=baz', ' test baz')
+ statusline_test('should handle an empty right side when using ==', 21,
+ 'foobar%=test%=', 'foobar test ')
+
+ statusline_test('should quadrant the text when using 3 %=', 40,
+ 'abcd%=n%=eovim%=ef', 'abcd n eovim ef')
+ statusline_test('should work well with %t', 40,
+ '%t%=right_aligned', 'buffer_spec.lua right_aligned',
+ {file_name='test/unit/buffer_spec.lua'})
+ statusline_test('should work well with %t and regular text', 40,
+ 'l%=m_l %t m_r%=r', 'l m_l buffer_spec.lua m_r r',
+ {file_name='test/unit/buffer_spec.lua'})
+ statusline_test('should work well with %=, %t, %L, and %l', 40,
+ '%t %= %L %= %l', 'buffer_spec.lua 1 0',
+ {file_name='test/unit/buffer_spec.lua'})
+
+ statusline_test('should quadrant the text when using 3 %=', 41,
+ 'abcd%=n%=eovim%=ef', 'abcd n eovim ef')
+ statusline_test('should work well with %t', 41,
+ '%t%=right_aligned', 'buffer_spec.lua right_aligned',
+ {file_name='test/unit/buffer_spec.lua'})
+ statusline_test('should work well with %t and regular text', 41,
+ 'l%=m_l %t m_r%=r', 'l m_l buffer_spec.lua m_r r',
+ {file_name='test/unit/buffer_spec.lua'})
+ statusline_test('should work well with %=, %t, %L, and %l', 41,
+ '%t %= %L %= %l', 'buffer_spec.lua 1 0',
+ {file_name='test/unit/buffer_spec.lua'})
+
+ statusline_test('should work with 10 %=', 50,
+ 'aaaa%=b%=c%=d%=e%=fg%=hi%=jk%=lmnop%=qrstuv%=wxyz',
+ 'aaaa b c d e fg hi jk lmnop qrstuv wxyz')
+
+ -- maximum stl item testing
+ statusline_test('should handle a much larger amount of = than buffer locations', 20,
+ ('%='):rep(STL_MAX_ITEM - 1),
+ ' ') -- Should be fine, because within limit
+ statusline_test('should handle a much larger amount of = than stl max item', 20,
+ ('%='):rep(STL_MAX_ITEM + 1),
+ ' E541') -- Should show the VIM error
+ statusline_test('should handle many extra characters', 20,
+ 'a' .. ('a'):rep(STL_MAX_ITEM * 4),
+ '<aaaaaaaaaaaaaaaaaaa') -- Does not show the error because there are no items
+ statusline_test('should handle almost maximum of characters and flags', 20,
+ 'a' .. ('%=a'):rep(STL_MAX_ITEM - 1),
+ 'a<aaaaaaaaaaaaaaaaaa') -- Should not show the VIM error
+ statusline_test('should handle many extra characters and flags', 20,
+ 'a' .. ('%=a'):rep(STL_MAX_ITEM),
+ 'a<aaaaaaaaaaaaa E541') -- Should show the VIM error
+ statusline_test('should handle many extra characters and flags', 20,
+ 'a' .. ('%=a'):rep(STL_MAX_ITEM * 2),
+ 'a<aaaaaaaaaaaaa E541') -- Should show the VIM error
+ statusline_test('should handle many extra characters and flags with truncation', 20,
+ 'aaa%<' .. ('%=a'):rep(STL_MAX_ITEM),
+ 'aaa<aaaaaaaaaaa E541') -- Should show the VIM error
+ statusline_test('should handle many characters and flags before and after truncation', 20,
+ 'a%=a%=a%<' .. ('%=a'):rep(STL_MAX_ITEM),
+ 'aaa<aaaaaaaaaaa E541') -- Should show the VIM error
+
+
+ -- multi-byte testing
+ statusline_test('should handle multibyte characters', 10,
+ 'Ĉ%=x', 'Ĉ x',
+ {expected_byte_length=11})
+ statusline_test('should handle multibyte characters and different fillchars', 10,
+ 'Ą%=mid%=end', 'Ą@mid@@end',
+ {fillchar=('@'):byte(), expected_byte_length=11})
- end)
end)
end)
diff --git a/test/unit/eval/encode_spec.lua b/test/unit/eval/encode_spec.lua
index f151a191fb..98fc8305e0 100644
--- a/test/unit/eval/encode_spec.lua
+++ b/test/unit/eval/encode_spec.lua
@@ -27,74 +27,74 @@ describe('encode_list_write()', function()
it('writes ASCII string literal with printable characters', function()
local l = list()
eq(0, encode_list_write(l, 'abc'))
- eq({[type_key]=list_type, 'abc'}, lst2tbl(l))
+ eq({'abc'}, lst2tbl(l))
end)
it('writes string starting with NL', function()
local l = list()
eq(0, encode_list_write(l, '\nabc'))
- eq({[type_key]=list_type, null_string, 'abc'}, lst2tbl(l))
+ eq({null_string, 'abc'}, lst2tbl(l))
end)
it('writes string starting with NL twice', function()
local l = list()
eq(0, encode_list_write(l, '\nabc'))
- eq({[type_key]=list_type, null_string, 'abc'}, lst2tbl(l))
+ eq({null_string, 'abc'}, lst2tbl(l))
eq(0, encode_list_write(l, '\nabc'))
- eq({[type_key]=list_type, null_string, 'abc', 'abc'}, lst2tbl(l))
+ eq({null_string, 'abc', 'abc'}, lst2tbl(l))
end)
it('writes string ending with NL', function()
local l = list()
eq(0, encode_list_write(l, 'abc\n'))
- eq({[type_key]=list_type, 'abc', null_string}, lst2tbl(l))
+ eq({'abc', null_string}, lst2tbl(l))
end)
it('writes string ending with NL twice', function()
local l = list()
eq(0, encode_list_write(l, 'abc\n'))
- eq({[type_key]=list_type, 'abc', null_string}, lst2tbl(l))
+ eq({'abc', null_string}, lst2tbl(l))
eq(0, encode_list_write(l, 'abc\n'))
- eq({[type_key]=list_type, 'abc', 'abc', null_string}, lst2tbl(l))
+ eq({'abc', 'abc', null_string}, lst2tbl(l))
end)
it('writes string starting, ending and containing NL twice', function()
local l = list()
eq(0, encode_list_write(l, '\na\nb\n'))
- eq({[type_key]=list_type, null_string, 'a', 'b', null_string}, lst2tbl(l))
+ eq({null_string, 'a', 'b', null_string}, lst2tbl(l))
eq(0, encode_list_write(l, '\na\nb\n'))
- eq({[type_key]=list_type, null_string, 'a', 'b', null_string, 'a', 'b', null_string}, lst2tbl(l))
+ eq({null_string, 'a', 'b', null_string, 'a', 'b', null_string}, lst2tbl(l))
end)
it('writes string starting, ending and containing NUL with NL between twice', function()
local l = list()
eq(0, encode_list_write(l, '\0\n\0\n\0'))
- eq({[type_key]=list_type, '\n', '\n', '\n'}, lst2tbl(l))
+ eq({'\n', '\n', '\n'}, lst2tbl(l))
eq(0, encode_list_write(l, '\0\n\0\n\0'))
- eq({[type_key]=list_type, '\n', '\n', '\n\n', '\n', '\n'}, lst2tbl(l))
+ eq({'\n', '\n', '\n\n', '\n', '\n'}, lst2tbl(l))
end)
it('writes string starting, ending and containing NL with NUL between twice', function()
local l = list()
eq(0, encode_list_write(l, '\n\0\n\0\n'))
- eq({[type_key]=list_type, null_string, '\n', '\n', null_string}, lst2tbl(l))
+ eq({null_string, '\n', '\n', null_string}, lst2tbl(l))
eq(0, encode_list_write(l, '\n\0\n\0\n'))
- eq({[type_key]=list_type, null_string, '\n', '\n', null_string, '\n', '\n', null_string}, lst2tbl(l))
+ eq({null_string, '\n', '\n', null_string, '\n', '\n', null_string}, lst2tbl(l))
end)
it('writes string containing a single NL twice', function()
local l = list()
eq(0, encode_list_write(l, '\n'))
- eq({[type_key]=list_type, null_string, null_string}, lst2tbl(l))
+ eq({null_string, null_string}, lst2tbl(l))
eq(0, encode_list_write(l, '\n'))
- eq({[type_key]=list_type, null_string, null_string, null_string}, lst2tbl(l))
+ eq({null_string, null_string, null_string}, lst2tbl(l))
end)
it('writes string containing a few NLs twice', function()
local l = list()
eq(0, encode_list_write(l, '\n\n\n'))
- eq({[type_key]=list_type, null_string, null_string, null_string, null_string}, lst2tbl(l))
+ eq({null_string, null_string, null_string, null_string}, lst2tbl(l))
eq(0, encode_list_write(l, '\n\n\n'))
- eq({[type_key]=list_type, null_string, null_string, null_string, null_string, null_string, null_string, null_string}, lst2tbl(l))
+ eq({null_string, null_string, null_string, null_string, null_string, null_string, null_string}, lst2tbl(l))
end)
end)
diff --git a/test/unit/eval/helpers.lua b/test/unit/eval/helpers.lua
index 2367f03e0d..45fbf8da5c 100644
--- a/test/unit/eval/helpers.lua
+++ b/test/unit/eval/helpers.lua
@@ -11,6 +11,12 @@ local null_string = {[true]='NULL string'}
local null_list = {[true]='NULL list'}
local type_key = {[true]='type key'}
local list_type = {[true]='list type'}
+local dict_type = {[true]='dict type'}
+local func_type = {[true]='func type'}
+local int_type = {[true]='int type'}
+local flt_type = {[true]='flt type'}
+
+local nil_value = {[true]='nil'}
local function list(...)
local ret = ffi.gc(eval.list_alloc(), eval.list_unref)
@@ -37,7 +43,53 @@ local function list(...)
return ret
end
-local lst2tbl = function(l)
+local special_tab = {
+ [eval.kSpecialVarFalse] = false,
+ [eval.kSpecialVarNull] = nil_value,
+ [eval.kSpecialVarTrue] = true,
+}
+
+local lst2tbl
+local dct2tbl
+
+local typvalt2lua_tab
+
+typvalt2lua_tab = {
+ [tonumber(eval.VAR_SPECIAL)] = function(t)
+ return special_tab[t.vval.v_special]
+ end,
+ [tonumber(eval.VAR_NUMBER)] = function(t)
+ return {[type_key]=int_type, value=tonumber(t.vval.v_number)}
+ end,
+ [tonumber(eval.VAR_FLOAT)] = function(t)
+ return tonumber(t.vval.v_float)
+ end,
+ [tonumber(eval.VAR_STRING)] = function(t)
+ local str = t.vval.v_string
+ if str == nil then
+ return null_string
+ else
+ return ffi.string(str)
+ end
+ end,
+ [tonumber(eval.VAR_LIST)] = function(t)
+ return lst2tbl(t.vval.v_list)
+ end,
+ [tonumber(eval.VAR_DICT)] = function(t)
+ return dct2tbl(t.vval.v_dict)
+ end,
+ [tonumber(eval.VAR_FUNC)] = function(t)
+ return {[type_key]=func_type, value=typvalt2lua_tab[eval.VAR_STRING](t)}
+ end,
+}
+
+local typvalt2lua = function(t)
+ return ((typvalt2lua_tab[tonumber(t.v_type)] or function(t_inner)
+ assert(false, 'Converting ' .. tonumber(t_inner.v_type) .. ' was not implemented yet')
+ end)(t))
+end
+
+lst2tbl = function(l)
local ret = {[type_key]=list_type}
if l == nil then
return ret
@@ -45,28 +97,119 @@ local lst2tbl = function(l)
local li = l.lv_first
-- (listitem_T *) NULL is equal to nil, but yet it is not false.
while li ~= nil do
- local typ = li.li_tv.v_type
- if typ == eval.VAR_STRING then
- local str = li.li_tv.vval.v_string
- if str == nil then
- ret[#ret + 1] = null_string
- else
- ret[#ret + 1] = ffi.string(str)
+ ret[#ret + 1] = typvalt2lua(li.li_tv)
+ li = li.li_next
+ end
+ if ret[1] then
+ ret[type_key] = nil
+ end
+ return ret
+end
+
+dct2tbl = function(d)
+ local ret = {d=d}
+ assert(false, 'Converting dictionaries is not implemented yet')
+ return ret
+end
+
+local lua2typvalt
+
+local typvalt = function(typ, vval)
+ if type(typ) == 'string' then
+ typ = eval[typ]
+ end
+ return ffi.gc(ffi.new('typval_T', {v_type=typ, vval=vval}), eval.clear_tv)
+end
+
+local lua2typvalt_type_tab = {
+ [int_type] = function(l, _)
+ return typvalt(eval.VAR_NUMBER, {v_number=l.value})
+ end,
+ [flt_type] = function(l, processed)
+ return lua2typvalt(l.value, processed)
+ end,
+ [list_type] = function(l, processed)
+ if processed[l] then
+ processed[l].lv_refcount = processed[l].lv_refcount + 1
+ return typvalt(eval.VAR_LIST, {v_list=processed[l]})
+ end
+ local lst = eval.list_alloc()
+ lst.lv_refcount = 1
+ processed[l] = lst
+ local ret = typvalt(eval.VAR_LIST, {v_list=lst})
+ for i = 1, #l do
+ local item_tv = ffi.gc(lua2typvalt(l[i], processed), nil)
+ eval.list_append_tv(lst, item_tv)
+ eval.clear_tv(item_tv)
+ end
+ return ret
+ end,
+ [dict_type] = function(l, processed)
+ if processed[l] then
+ processed[l].dv_refcount = processed[l].dv_refcount + 1
+ return typvalt(eval.VAR_DICT, {v_dict=processed[l]})
+ end
+ local dct = eval.dict_alloc()
+ dct.dv_refcount = 1
+ processed[l] = dct
+ local ret = typvalt(eval.VAR_DICT, {v_dict=dct})
+ for k, v in pairs(l) do
+ if type(k) == 'string' then
+ local di = eval.dictitem_alloc(to_cstr(k))
+ local val_tv = ffi.gc(lua2typvalt(v, processed), nil)
+ eval.copy_tv(val_tv, di.di_tv)
+ eval.clear_tv(val_tv)
+ eval.dict_add(dct, di)
end
+ end
+ return ret
+ end,
+}
+
+lua2typvalt = function(l, processed)
+ processed = processed or {}
+ if l == nil or l == nil_value then
+ return typvalt(eval.VAR_SPECIAL, {v_special=eval.kSpecialVarNull})
+ elseif type(l) == 'table' then
+ if l[type_key] then
+ return lua2typvalt_type_tab[l[type_key]](l, processed)
else
- assert(false, 'Not implemented yet')
+ if l[1] then
+ return lua2typvalt_type_tab[list_type](l, processed)
+ else
+ return lua2typvalt_type_tab[dict_type](l, processed)
+ end
end
- li = li.li_next
+ elseif type(l) == 'number' then
+ return typvalt(eval.VAR_FLOAT, {v_float=l})
+ elseif type(l) == 'boolean' then
+ return typvalt(eval.VAR_SPECIAL, {
+ v_special=(l and eval.kSpecialVarTrue or eval.kSpecialVarFalse)
+ })
+ elseif type(l) == 'string' then
+ return typvalt(eval.VAR_STRING, {v_string=eval.xmemdupz(to_cstr(l), #l)})
end
- return ret
end
return {
null_string=null_string,
null_list=null_list,
list_type=list_type,
+ dict_type=dict_type,
+ func_type=func_type,
+ int_type=int_type,
+ flt_type=flt_type,
+
+ nil_value=nil_value,
+
type_key=type_key,
list=list,
lst2tbl=lst2tbl,
+ dct2tbl=dct2tbl,
+
+ lua2typvalt=lua2typvalt,
+ typvalt2lua=typvalt2lua,
+
+ typvalt=typvalt,
}
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 426ae2d9e0..91da459393 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -1,9 +1,13 @@
-local assert = require('luassert')
local ffi = require('ffi')
local formatc = require('test.unit.formatc')
local Set = require('test.unit.set')
local Preprocess = require('test.unit.preprocess')
local Paths = require('test.config.paths')
+local global_helpers = require('test.helpers')
+
+local neq = global_helpers.neq
+local eq = global_helpers.eq
+local ok = global_helpers.ok
-- add some standard header locations
for _, p in ipairs(Paths.include_paths) do
@@ -31,7 +35,8 @@ local function filter_complex_blocks(body)
if not (string.find(line, "(^)", 1, true) ~= nil
or string.find(line, "_ISwupper", 1, true)
or string.find(line, "msgpack_zone_push_finalizer")
- or string.find(line, "msgpack_unpacker_reserve_buffer")) then
+ or string.find(line, "msgpack_unpacker_reserve_buffer")
+ or string.find(line, "inline _Bool")) then
result[#result + 1] = line
end
end
@@ -153,12 +158,9 @@ return {
cimport = cimport,
cppimport = cppimport,
internalize = internalize,
- eq = function(expected, actual)
- return assert.are.same(expected, actual)
- end,
- neq = function(expected, actual)
- return assert.are_not.same(expected, actual)
- end,
+ ok = ok,
+ eq = eq,
+ neq = neq,
ffi = ffi,
lib = libnvim,
cstr = cstr,
diff --git a/test/unit/os/fileio_spec.lua b/test/unit/os/fileio_spec.lua
new file mode 100644
index 0000000000..5358022422
--- /dev/null
+++ b/test/unit/os/fileio_spec.lua
@@ -0,0 +1,365 @@
+local lfs = require('lfs')
+
+local helpers = require('test.unit.helpers')
+
+local eq = helpers.eq
+local ffi = helpers.ffi
+local cimport = helpers.cimport
+
+local m = cimport('./src/nvim/os/fileio.h')
+
+local fcontents = ''
+for i = 0, 255 do
+ fcontents = fcontents .. (i == 0 and '\0' or ('%c'):format(i))
+end
+fcontents = fcontents:rep(16)
+
+local dir = 'Xtest-unit-file_spec.d'
+local file1 = dir .. '/file1.dat'
+local file2 = dir .. '/file2.dat'
+local linkf = dir .. '/file.lnk'
+local linkb = dir .. '/broken.lnk'
+local filec = dir .. '/created-file.dat'
+
+before_each(function()
+ lfs.mkdir(dir);
+
+ local f1 = io.open(file1, 'w')
+ f1:write(fcontents)
+ f1:close()
+
+ local f2 = io.open(file2, 'w')
+ f2:write(fcontents)
+ f2:close()
+
+ lfs.link('file1.dat', linkf, true)
+ lfs.link('broken.dat', linkb, true)
+end)
+
+after_each(function()
+ os.remove(file1)
+ os.remove(file2)
+ os.remove(linkf)
+ os.remove(linkb)
+ os.remove(filec)
+ lfs.rmdir(dir)
+end)
+
+local function file_open(fname, flags, mode)
+ local ret2 = ffi.new('FileDescriptor')
+ local ret1 = m.file_open(ret2, fname, flags, mode)
+ return ret1, ret2
+end
+
+local function file_open_new(fname, flags, mode)
+ local ret1 = ffi.new('int[?]', 1, {0})
+ local ret2 = ffi.gc(m.file_open_new(ret1, fname, flags, mode), nil)
+ return ret1[0], ret2
+end
+
+local function file_write(fp, buf)
+ return m.file_write(fp, buf, #buf)
+end
+
+local function file_read(fp, size)
+ local buf = nil
+ if size == nil then
+ size = 0
+ else
+ -- For some reason if length of NUL-bytes-string is the same as `char[?]`
+ -- size luajit garbage collector crashes. But it does not do so in
+ -- os_read[v] tests in os/fs_spec.lua.
+ buf = ffi.new('char[?]', size + 1, ('\0'):rep(size))
+ end
+ local ret1 = m.file_read(fp, buf, size)
+ local ret2 = ''
+ if buf ~= nil then
+ ret2 = ffi.string(buf, size)
+ end
+ return ret1, ret2
+end
+
+local function file_fsync(fp)
+ return m.file_fsync(fp)
+end
+
+local function file_skip(fp, size)
+ return m.file_skip(fp, size)
+end
+
+describe('file_open', function()
+ it('can create a rwx------ file with kFileCreate', function()
+ local err, fp = file_open(filec, m.kFileCreate, 448)
+ eq(0, err)
+ local attrs = lfs.attributes(filec)
+ eq('rwx------', attrs.permissions)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can create a rw------- file with kFileCreate', function()
+ local err, fp = file_open(filec, m.kFileCreate, 384)
+ eq(0, err)
+ local attrs = lfs.attributes(filec)
+ eq('rw-------', attrs.permissions)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can create a rwx------ file with kFileCreateOnly', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 448)
+ eq(0, err)
+ local attrs = lfs.attributes(filec)
+ eq('rwx------', attrs.permissions)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can create a rw------- file with kFileCreateOnly', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ local attrs = lfs.attributes(filec)
+ eq('rw-------', attrs.permissions)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('fails to open an existing file with kFileCreateOnly', function()
+ local err, _ = file_open(file1, m.kFileCreateOnly, 384)
+ eq(m.UV_EEXIST, err)
+ end)
+
+ it('fails to open an symlink with kFileNoSymlink', function()
+ local err, _ = file_open(linkf, m.kFileNoSymlink, 384)
+ -- err is UV_EMLINK in FreeBSD, but if I use `ok(err == m.UV_ELOOP or err ==
+ -- m.UV_EMLINK)`, then I loose the ability to see actual `err` value.
+ if err ~= m.UV_ELOOP then eq(m.UV_EMLINK, err) end
+ end)
+
+ it('can open an existing file write-only with kFileCreate', function()
+ local err, fp = file_open(file1, m.kFileCreate, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can open an existing file read-only with zero', function()
+ local err, fp = file_open(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can open an existing file read-only with kFileReadOnly', function()
+ local err, fp = file_open(file1, m.kFileReadOnly, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can open an existing file read-only with kFileNoSymlink', function()
+ local err, fp = file_open(file1, m.kFileNoSymlink, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can truncate an existing file with kFileTruncate', function()
+ local err, fp = file_open(file1, m.kFileTruncate, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ eq(0, m.file_close(fp))
+ local attrs = lfs.attributes(file1)
+ eq(0, attrs.size)
+ end)
+
+ it('can open an existing file write-only with kFileWriteOnly', function()
+ local err, fp = file_open(file1, m.kFileWriteOnly, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ eq(0, m.file_close(fp))
+ local attrs = lfs.attributes(file1)
+ eq(4096, attrs.size)
+ end)
+
+ it('fails to create a file with just kFileWriteOnly', function()
+ local err, _ = file_open(filec, m.kFileWriteOnly, 384)
+ eq(m.UV_ENOENT, err)
+ local attrs = lfs.attributes(filec)
+ eq(nil, attrs)
+ end)
+
+ it('can truncate an existing file with kFileTruncate when opening a symlink',
+ function()
+ local err, fp = file_open(linkf, m.kFileTruncate, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ eq(0, m.file_close(fp))
+ local attrs = lfs.attributes(file1)
+ eq(0, attrs.size)
+ end)
+
+ it('fails to open a directory write-only', function()
+ local err, _ = file_open(dir, m.kFileWriteOnly, 384)
+ eq(m.UV_EISDIR, err)
+ end)
+
+ it('fails to open a broken symbolic link write-only', function()
+ local err, _ = file_open(linkb, m.kFileWriteOnly, 384)
+ eq(m.UV_ENOENT, err)
+ end)
+
+ it('fails to open a broken symbolic link read-only', function()
+ local err, _ = file_open(linkb, m.kFileReadOnly, 384)
+ eq(m.UV_ENOENT, err)
+ end)
+end)
+
+describe('file_open_new', function()
+ it('can open a file read-only', function()
+ local err, fp = file_open_new(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq(0, m.file_free(fp))
+ end)
+
+ it('fails to open an existing file with kFileCreateOnly', function()
+ local err, fp = file_open_new(file1, m.kFileCreateOnly, 384)
+ eq(m.UV_EEXIST, err)
+ eq(nil, fp)
+ end)
+end)
+
+-- file_close is called above, so it is not tested directly
+
+describe('file_fsync', function()
+ it('can flush writes to disk', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, file_fsync(fp))
+ eq(0, err)
+ eq(0, lfs.attributes(filec).size)
+ local wsize = file_write(fp, 'test')
+ eq(4, wsize)
+ eq(0, lfs.attributes(filec).size)
+ eq(0, file_fsync(fp))
+ eq(wsize, lfs.attributes(filec).size)
+ eq(0, m.file_close(fp))
+ end)
+end)
+
+describe('file_read', function()
+ it('can read small chunks of input until eof', function()
+ local err, fp = file_open(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ local shift = 0
+ while shift < #fcontents do
+ local size = 3
+ local exp_err = size
+ local exp_s = fcontents:sub(shift + 1, shift + size)
+ if shift + size >= #fcontents then
+ exp_err = #fcontents - shift
+ exp_s = (fcontents:sub(shift + 1, shift + size)
+ .. (('\0'):rep(size - exp_err)))
+ end
+ eq({exp_err, exp_s}, {file_read(fp, size)})
+ shift = shift + size
+ end
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can read the whole file at once', function()
+ local err, fp = file_open(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq({#fcontents, fcontents}, {file_read(fp, #fcontents)})
+ eq({0, ('\0'):rep(#fcontents)}, {file_read(fp, #fcontents)})
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can read more then 1024 bytes after reading a small chunk', function()
+ local err, fp = file_open(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq({5, fcontents:sub(1, 5)}, {file_read(fp, 5)})
+ eq({#fcontents - 5, fcontents:sub(6) .. (('\0'):rep(5))},
+ {file_read(fp, #fcontents)})
+ eq(0, m.file_close(fp))
+ end)
+
+ it('can read file by 768-byte-chunks', function()
+ local err, fp = file_open(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ local shift = 0
+ while shift < #fcontents do
+ local size = 768
+ local exp_err = size
+ local exp_s = fcontents:sub(shift + 1, shift + size)
+ if shift + size >= #fcontents then
+ exp_err = #fcontents - shift
+ exp_s = (fcontents:sub(shift + 1, shift + size)
+ .. (('\0'):rep(size - exp_err)))
+ end
+ eq({exp_err, exp_s}, {file_read(fp, size)})
+ shift = shift + size
+ end
+ eq(0, m.file_close(fp))
+ end)
+end)
+
+describe('file_write', function()
+ it('can write the whole file at once', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ local wr = file_write(fp, fcontents)
+ eq(#fcontents, wr)
+ eq(0, m.file_close(fp))
+ eq(wr, lfs.attributes(filec).size)
+ eq(fcontents, io.open(filec):read('*a'))
+ end)
+
+ it('can write the whole file by small chunks', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ local shift = 0
+ while shift < #fcontents do
+ local size = 3
+ local s = fcontents:sub(shift + 1, shift + size)
+ local wr = file_write(fp, s)
+ eq(wr, #s)
+ shift = shift + size
+ end
+ eq(0, m.file_close(fp))
+ eq(#fcontents, lfs.attributes(filec).size)
+ eq(fcontents, io.open(filec):read('*a'))
+ end)
+
+ it('can write the whole file by 768-byte-chunks', function()
+ local err, fp = file_open(filec, m.kFileCreateOnly, 384)
+ eq(0, err)
+ eq(true, fp.wr)
+ local shift = 0
+ while shift < #fcontents do
+ local size = 768
+ local s = fcontents:sub(shift + 1, shift + size)
+ local wr = file_write(fp, s)
+ eq(wr, #s)
+ shift = shift + size
+ end
+ eq(0, m.file_close(fp))
+ eq(#fcontents, lfs.attributes(filec).size)
+ eq(fcontents, io.open(filec):read('*a'))
+ end)
+end)
+
+describe('file_skip', function()
+ it('can skip 3 bytes', function()
+ local err, fp = file_open(file1, 0, 384)
+ eq(0, err)
+ eq(false, fp.wr)
+ eq(3, file_skip(fp, 3))
+ local rd, s = file_read(fp, 3)
+ eq(3, rd)
+ eq(fcontents:sub(4, 6), s)
+ eq(0, m.file_close(fp))
+ end)
+end)
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index 857a5001f1..7e7eddb6fc 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -6,6 +6,7 @@ local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
local cppimport = helpers.cppimport
local internalize = helpers.internalize
+local ok = helpers.ok
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
@@ -27,6 +28,12 @@ cppimport('sys/stat.h')
cppimport('fcntl.h')
cppimport('uv-errno.h')
+local s = ''
+for i = 0, 255 do
+ s = s .. (i == 0 and '\0' or ('%c'):format(i))
+end
+local fcontents = s:rep(16)
+
local buffer = ""
local directory = nil
local absolute_executable = nil
@@ -68,6 +75,8 @@ describe('fs function', function()
io.open('unit-test-directory/test_2.file', 'w').close()
lfs.link('test.file', 'unit-test-directory/test_link.file', true)
+
+ lfs.link('non_existing_file.file', 'unit-test-directory/test_broken_link.file', true)
-- Since the tests are executed, they are called by an executable. We use
-- that executable for several asserts.
absolute_executable = arg[0]
@@ -81,6 +90,7 @@ describe('fs function', function()
os.remove('unit-test-directory/test_2.file')
os.remove('unit-test-directory/test_link.file')
os.remove('unit-test-directory/test_hlink.file')
+ os.remove('unit-test-directory/test_broken_link.file')
lfs.rmdir('unit-test-directory')
end)
@@ -150,11 +160,11 @@ describe('fs function', function()
local function os_can_exe(name)
local buf = ffi.new('char *[1]')
buf[0] = NULL
- local ok = fs.os_can_exe(to_cstr(name), buf, true)
+ local ce_ret = fs.os_can_exe(to_cstr(name), buf, true)
-- When os_can_exe returns true, it must set the path.
-- When it returns false, the path must be NULL.
- if ok then
+ if ce_ret then
neq(NULL, buf[0])
return internalize(buf[0])
else
@@ -356,8 +366,8 @@ describe('fs function', function()
end)
describe('file operations', function()
- local function os_file_exists(filename)
- return fs.os_file_exists((to_cstr(filename)))
+ local function os_path_exists(filename)
+ return fs.os_path_exists((to_cstr(filename)))
end
local function os_rename(path, new_path)
return fs.os_rename((to_cstr(path)), (to_cstr(new_path)))
@@ -368,14 +378,67 @@ describe('fs function', function()
local function os_open(path, flags, mode)
return fs.os_open((to_cstr(path)), flags, mode)
end
+ local function os_close(fd)
+ return fs.os_close(fd)
+ end
+ -- For some reason if length of NUL-bytes-string is the same as `char[?]`
+ -- size luajit crashes. Though it does not do so in this test suite, better
+ -- be cautios and allocate more elements then needed. I only did this to
+ -- strings.
+ local function os_read(fd, size)
+ local buf = nil
+ if size == nil then
+ size = 0
+ else
+ buf = ffi.new('char[?]', size + 1, ('\0'):rep(size))
+ end
+ local eof = ffi.new('bool[?]', 1, {true})
+ local ret2 = fs.os_read(fd, eof, buf, size)
+ local ret1 = eof[0]
+ local ret3 = ''
+ if buf ~= nil then
+ ret3 = ffi.string(buf, size)
+ end
+ return ret1, ret2, ret3
+ end
+ local function os_readv(fd, sizes)
+ local bufs = {}
+ for i, size in ipairs(sizes) do
+ bufs[i] = {
+ iov_base=ffi.new('char[?]', size + 1, ('\0'):rep(size)),
+ iov_len=size,
+ }
+ end
+ local iov = ffi.new('struct iovec[?]', #sizes, bufs)
+ local eof = ffi.new('bool[?]', 1, {true})
+ local ret2 = fs.os_readv(fd, eof, iov, #sizes)
+ local ret1 = eof[0]
+ local ret3 = {}
+ for i = 1,#sizes do
+ -- Warning: iov may not be used.
+ ret3[i] = ffi.string(bufs[i].iov_base, bufs[i].iov_len)
+ end
+ return ret1, ret2, ret3
+ end
+ local function os_write(fd, data)
+ return fs.os_write(fd, data, data and #data or 0)
+ end
- describe('os_file_exists', function()
+ describe('os_path_exists', function()
it('returns false when given a non-existing file', function()
- eq(false, (os_file_exists('non-existing-file')))
+ eq(false, (os_path_exists('non-existing-file')))
end)
it('returns true when given an existing file', function()
- eq(true, (os_file_exists('unit-test-directory/test.file')))
+ eq(true, (os_path_exists('unit-test-directory/test.file')))
+ end)
+
+ it('returns false when given a broken symlink', function()
+ eq(false, (os_path_exists('unit-test-directory/test_broken_link.file')))
+ end)
+
+ it('returns true when given a directory', function()
+ eq(true, (os_path_exists('unit-test-directory')))
end)
end)
@@ -385,8 +448,8 @@ describe('fs function', function()
it('can rename file if destination file does not exist', function()
eq(OK, (os_rename(test, not_exist)))
- eq(false, (os_file_exists(test)))
- eq(true, (os_file_exists(not_exist)))
+ eq(false, (os_path_exists(test)))
+ eq(true, (os_path_exists(not_exist)))
eq(OK, (os_rename(not_exist, test))) -- restore test file
end)
@@ -402,8 +465,8 @@ describe('fs function', function()
file:close()
eq(OK, (os_rename(other, test)))
- eq(false, (os_file_exists(other)))
- eq(true, (os_file_exists(test)))
+ eq(false, (os_path_exists(other)))
+ eq(true, (os_path_exists(test)))
file = io.open(test, 'r')
eq('other', (file:read('*all')))
file:close()
@@ -432,30 +495,34 @@ describe('fs function', function()
end)
describe('os_open', function()
+ local new_file = 'test_new_file'
+ local existing_file = 'unit-test-directory/test_existing.file'
+
before_each(function()
- io.open('unit-test-directory/test_existing.file', 'w').close()
+ (io.open(existing_file, 'w')):close()
end)
after_each(function()
- os.remove('unit-test-directory/test_existing.file')
- os.remove('test_new_file')
+ os.remove(existing_file)
+ os.remove(new_file)
end)
- local new_file = 'test_new_file'
- local existing_file = 'unit-test-directory/test_existing.file'
-
it('returns UV_ENOENT for O_RDWR on a non-existing file', function()
eq(ffi.C.UV_ENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0)))
end)
- it('returns non-negative for O_CREAT on a non-existing file', function()
+ it('returns non-negative for O_CREAT on a non-existing file which then can be closed', function()
assert_file_does_not_exist(new_file)
- assert.is_true(0 <= (os_open(new_file, ffi.C.kO_CREAT, 0)))
+ local fd = os_open(new_file, ffi.C.kO_CREAT, 0)
+ assert.is_true(0 <= fd)
+ eq(0, os_close(fd))
end)
- it('returns non-negative for O_CREAT on a existing file', function()
+ it('returns non-negative for O_CREAT on a existing file which then can be closed', function()
assert_file_exists(existing_file)
- assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_CREAT, 0)))
+ local fd = os_open(existing_file, ffi.C.kO_CREAT, 0)
+ assert.is_true(0 <= fd)
+ eq(0, os_close(fd))
end)
it('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function()
@@ -463,24 +530,181 @@ describe('fs function', function()
eq(ffi.C.kUV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
end)
- it('sets `rwx` permissions for O_CREAT 700', function()
+ it('sets `rwx` permissions for O_CREAT 700 which then can be closed', function()
assert_file_does_not_exist(new_file)
--create the file
- os_open(new_file, ffi.C.kO_CREAT, tonumber("700", 8))
+ local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("700", 8))
--verify permissions
eq('rwx------', lfs.attributes(new_file)['permissions'])
+ eq(0, os_close(fd))
end)
- it('sets `rw` permissions for O_CREAT 600', function()
+ it('sets `rw` permissions for O_CREAT 600 which then can be closed', function()
assert_file_does_not_exist(new_file)
--create the file
- os_open(new_file, ffi.C.kO_CREAT, tonumber("600", 8))
+ local fd = os_open(new_file, ffi.C.kO_CREAT, tonumber("600", 8))
--verify permissions
eq('rw-------', lfs.attributes(new_file)['permissions'])
+ eq(0, os_close(fd))
+ end)
+
+ it('returns a non-negative file descriptor for an existing file which then can be closed', function()
+ local fd = os_open(existing_file, ffi.C.kO_RDWR, 0)
+ assert.is_true(0 <= fd)
+ eq(0, os_close(fd))
+ end)
+ end)
+
+ describe('os_close', function()
+ it('returns EBADF for negative file descriptors', function()
+ eq(ffi.C.UV_EBADF, os_close(-1))
+ eq(ffi.C.UV_EBADF, os_close(-1000))
+ end)
+ end)
+
+ describe('os_read', function()
+ local file = 'test-unit-os-fs_spec-os_read.dat'
+
+ before_each(function()
+ local f = io.open(file, 'w')
+ f:write(fcontents)
+ f:close()
+ end)
+
+ after_each(function()
+ os.remove(file)
+ end)
+
+ it('can read zero bytes from a file', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, 0, ''}, {os_read(fd, nil)})
+ eq({false, 0, ''}, {os_read(fd, 0)})
+ eq(0, os_close(fd))
+ end)
+
+ it('can read from a file multiple times', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, 2, '\000\001'}, {os_read(fd, 2)})
+ eq({false, 2, '\002\003'}, {os_read(fd, 2)})
+ eq(0, os_close(fd))
+ end)
+
+ it('can read the whole file at once and then report eof', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, #fcontents, fcontents}, {os_read(fd, #fcontents)})
+ eq({true, 0, ('\0'):rep(#fcontents)}, {os_read(fd, #fcontents)})
+ eq(0, os_close(fd))
+ end)
+
+ it('can read the whole file in two calls, one partially', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, #fcontents * 3/4, fcontents:sub(1, #fcontents * 3/4)},
+ {os_read(fd, #fcontents * 3/4)})
+ eq({true,
+ (#fcontents * 1/4),
+ fcontents:sub(#fcontents * 3/4 + 1) .. ('\0'):rep(#fcontents * 2/4)},
+ {os_read(fd, #fcontents * 3/4)})
+ eq(0, os_close(fd))
+ end)
+ end)
+
+ describe('os_readv', function()
+ -- Function may be absent
+ if not pcall(function() return fs.os_readv end) then
+ return
+ end
+ local file = 'test-unit-os-fs_spec-os_readv.dat'
+
+ before_each(function()
+ local f = io.open(file, 'w')
+ f:write(fcontents)
+ f:close()
+ end)
+
+ after_each(function()
+ os.remove(file)
+ end)
+
+ it('can read zero bytes from a file', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, 0, {}}, {os_readv(fd, {})})
+ eq({false, 0, {'', '', ''}}, {os_readv(fd, {0, 0, 0})})
+ eq(0, os_close(fd))
+ end)
+
+ it('can read from a file multiple times to a differently-sized buffers', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, 2, {'\000\001'}}, {os_readv(fd, {2})})
+ eq({false, 5, {'\002\003', '\004\005\006'}}, {os_readv(fd, {2, 3})})
+ eq(0, os_close(fd))
+ end)
+
+ it('can read the whole file at once and then report eof', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false,
+ #fcontents,
+ {fcontents:sub(1, #fcontents * 1/4),
+ fcontents:sub(#fcontents * 1/4 + 1, #fcontents * 3/4),
+ fcontents:sub(#fcontents * 3/4 + 1, #fcontents * 15/16),
+ fcontents:sub(#fcontents * 15/16 + 1, #fcontents)}},
+ {os_readv(fd, {#fcontents * 1/4,
+ #fcontents * 2/4,
+ #fcontents * 3/16,
+ #fcontents * 1/16})})
+ eq({true, 0, {'\0'}}, {os_readv(fd, {1})})
+ eq(0, os_close(fd))
+ end)
+
+ it('can read the whole file in two calls, one partially', function()
+ local fd = os_open(file, ffi.C.kO_RDONLY, 0)
+ ok(fd >= 0)
+ eq({false, #fcontents * 3/4, {fcontents:sub(1, #fcontents * 3/4)}},
+ {os_readv(fd, {#fcontents * 3/4})})
+ eq({true,
+ (#fcontents * 1/4),
+ {fcontents:sub(#fcontents * 3/4 + 1) .. ('\0'):rep(#fcontents * 2/4)}},
+ {os_readv(fd, {#fcontents * 3/4})})
+ eq(0, os_close(fd))
+ end)
+ end)
+
+ describe('os_write', function()
+ -- Function may be absent
+ local file = 'test-unit-os-fs_spec-os_write.dat'
+
+ before_each(function()
+ local f = io.open(file, 'w')
+ f:write(fcontents)
+ f:close()
+ end)
+
+ after_each(function()
+ os.remove(file)
+ end)
+
+ it('can write zero bytes to a file', function()
+ local fd = os_open(file, ffi.C.kO_WRONLY, 0)
+ ok(fd >= 0)
+ eq(0, os_write(fd, ''))
+ eq(0, os_write(fd, nil))
+ eq(fcontents, io.open(file, 'r'):read('*a'))
+ eq(0, os_close(fd))
end)
- it('returns a non-negative file descriptor for an existing file', function()
- assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_RDWR, 0)))
+ it('can write some data to a file', function()
+ local fd = os_open(file, ffi.C.kO_WRONLY, 0)
+ ok(fd >= 0)
+ eq(3, os_write(fd, 'abc'))
+ eq(4, os_write(fd, ' def'))
+ eq('abc def' .. fcontents:sub(8), io.open(file, 'r'):read('*a'))
+ eq(0, os_close(fd))
end)
end)
diff --git a/test/unit/os/shell_spec.lua b/test/unit/os/shell_spec.lua
index 93103e4e8c..906f950308 100644
--- a/test/unit/os/shell_spec.lua
+++ b/test/unit/os/shell_spec.lua
@@ -30,10 +30,6 @@ describe('shell functions', function()
cimported.p_shcf = to_cstr('-c')
end)
- teardown(function()
- cimported.event_teardown()
- end)
-
local function shell_build_argv(cmd, extra_args)
local res = cimported.shell_build_argv(
cmd and to_cstr(cmd),
diff --git a/test/unit/strings_spec.lua b/test/unit/strings_spec.lua
index e935d2af6a..0034670ee8 100644
--- a/test/unit/strings_spec.lua
+++ b/test/unit/strings_spec.lua
@@ -8,6 +8,38 @@ local to_cstr = helpers.to_cstr
local strings = cimport('stdlib.h', './src/nvim/strings.h',
'./src/nvim/memory.h')
+describe('vim_strsave_escaped()', function()
+ local vim_strsave_escaped = function(s, chars)
+ local res = strings.vim_strsave_escaped(to_cstr(s), to_cstr(chars))
+ local ret = ffi.string(res)
+
+ -- Explicitly free memory so we are sure it is allocated: if it was not it
+ -- will crash.
+ strings.xfree(res)
+ return ret
+ end
+
+ it('precedes by a backslash all chars from second argument', function()
+ eq([[\a\b\c\d]], vim_strsave_escaped('abcd','abcd'))
+ end)
+
+ it('precedes by a backslash chars only from second argument', function()
+ eq([[\a\bcd]], vim_strsave_escaped('abcd','ab'))
+ end)
+
+ it('returns a copy of passed string if second argument is empty', function()
+ eq('text \n text', vim_strsave_escaped('text \n text',''))
+ end)
+
+ it('returns an empty string if first argument is empty string', function()
+ eq('', vim_strsave_escaped('','\r'))
+ end)
+
+ it('returns a copy of passed string if it does not contain chars from 2nd argument', function()
+ eq('some text', vim_strsave_escaped('some text', 'a'))
+ end)
+end)
+
describe('vim_strnsave_unquoted()', function()
local vim_strnsave_unquoted = function(s, len)
local res = strings.vim_strnsave_unquoted(to_cstr(s), len or #s)
diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua
index 7975d11aed..cf0d78b7a7 100644
--- a/test/unit/tempfile_spec.lua
+++ b/test/unit/tempfile_spec.lua
@@ -43,7 +43,7 @@ describe('tempfile related functions', function()
it('generate name of non-existing file', function()
local file = vim_tempname()
assert.truthy(file)
- assert.False(os.os_file_exists(file))
+ assert.False(os.os_path_exists(file))
end)
it('generate different names on each call', function()