FEATURES:3cc7ebf810#7234 built-in VimL expression parser6a7c904648#4419 implement <Cmd> key to invoke command in any modeb8363283fa#7679 'startup: treat stdin as text instead of commands'58b210e114:digraphs : highlight with hl-SpecialKey #26907a13611ba2#8276 'startup: Let `-s -` read from stdin'1e71978cf0events: VimSuspend, VimResume #82801e7d5e8cdf#6272 'stdpath()'f96d99ad11#8247 server: introduce --listene8c39f72fd#8226 insert-mode: interpret unmapped META as ESC98e7112390msg: do not scroll entire screen (#8088)f72630b784#8055 let negative 'writedelay' show all redraws5d2dd2ebe2win: has("wsl") on Windows Subsystem for Linux #7330a4f6cec7a3cmdline: CmdlineEnter and CmdlineLeave autocommands (#7422)207b7ca4bc#6844 channels: support buffered output and bytes sockets/stdio API:f85cbea725#7917 API: buffer updates418abfc9d0#6743 API: list information about all channels/jobs.36b2e3f743#8375 API: nvim_get_commands273d2cd5d5#8329 API: Make nvim_set_option() update `:verbose set …`8d40b3617c#8371 API: more reliable/descriptive VimL errorsebb1acb3c0#8353 API: nvim_call_dict_function9f994bb699#8004 API: nvim_list_uis34057045be#7520 API/UI: forward option updates to UIs911b1e49ab#7821 API: improve nvim_command_output WINDOWS OS:9cefd83cc7#8084, #8516 build/win: support MSVCee4e1fd8ecwin: Fix reading content from stdin (#8267) TUI:ffb8904913#8309 TUI: add support for mouse release events in urxvt8d5a46e77b#8081 TUI: implement "standout" attribute60716371e9TUI: support TERM=konsole-256color67848c0b91#7653 TUI: report TUI info with -V3 ('verbose' >= 3)3d0ee17c91TUI/rxvt: enable focus-reportingd109f5645b#7640 TUI: 'term' option: reflect effective terminal behavior FIXES:ed6a113804#8273 'job-control: avoid kill-timer race'4e02f1ab87#8107 'jobs: separate process-group'451c48a092terminal: flush vterm output buffer on pty output #84865d6732ff09:checkhealth fixes #833553f11dcfc7#8218 'Fix errors reported by PVS'd05712fbe7inccommand: pause :terminal redraws (#8307)51af911a27inccommand: do not execute trailing commands #825684359a467fterminal: resize to the max dimensions (#8249)d49c1dda8b#8228 Make vim_fgets() return the same values as in Vim60e96a45b4screen: winhl=Normal:Background should not override syntax (#8093)0c59ac1a2c#5908 'shada: Also save numbered marks'ba87a2cde7cscope: ignore EINTR while reading the prompt (#8079)b1412dc412#7971 ':terminal Enter/Leave should not increment jumplist'3a5721e91bTUI: libtermkey: force CSI driver for mouse input #79486ff13d78b7#7720 TUI: faster startup1c6e956079#7862 TUI: fix resize-related segfaultsa58c9094db#7676 TUI: always hide cursor when flushing, never flush buffers during unibilium output303e1df13f#7624 TUI: disable BCE almost always249bdb07dd#7761 mark: Make sure that jumplist item will not have zero lnum6f41ce0260#7704 macOS: Set $LANG based on the system localea043899ba2#7633 'Retry fgets on EINTR' CHANGES:ad60927d09#8304 default to 'nofsync'f3f1970597#8035 defaults: 'fillchars'a6052c7307#7984 defaults: sidescroll=1b69fa866db#7888 defaults: enable cscopeverbose7c4bb23ff3defaults: do :filetype stuff unless explicitly "off"2aa308c685#5658 'Apply :lmap in macros'8ce6393048terminal: Leave 'relativenumber' alone (#8360)e46534b423#4486 refactor: Remove maxmem, maxmemtot options131aad953cwin: defaults: 'shellcmdflag', 'shellxquote' #7343c57d315963#8031 jobwait(): return -2 on interrupt also with timeout6452831cf9clipboard: macOS: fallback to tmux if pbcopy is broken #7940300d3651e2#7919 Make 'langnoremap' apply directly after a mapada1956206#7880 'lua/executor: Remove lightuserdata' INTERNAL:de0a9548f7#7806 internal statistics for list impldee78a4095#7708 rewrite internal list impl
Tests
Tests are run by /cmake/RunTests.cmake file, using busted.
For some failures, .nvimlog (or $NVIM_LOG_FILE) may provide insight.
Running tests
Executing Tests
To run all non-legacy (unit + functional) tests:
make test
To run only unit tests:
make unittest
To run only functional tests:
make functionaltest
Filter Tests
Filter by name
Another filter method is by setting a pattern of test name to TEST_FILTER.
it('foo api',function()
...
end)
it('bar api',function()
...
end)
To run only test with filter name:
TEST_TAG='foo.*api' make functionaltest
Filter by file
To run a specific unit test:
TEST_FILE=test/unit/foo.lua make unittest
To run a specific functional test:
TEST_FILE=test/functional/foo.lua make functionaltest
To repeat a test many times:
.deps/usr/bin/busted --filter 'foo' --repeat 1000 test/functional/ui/foo_spec.lua
Filter by tag
Tests can be "tagged" by adding # before a token in the test description.
it('#foo bar baz', function()
...
end)
it('#foo another test', function()
...
end)
To run only the tagged tests:
TEST_TAG=foo make functionaltest
NOTES:
- Tags are mainly used for testing issues (ex:
#1234), so use the following method. TEST_FILEis not a pattern string likeTEST_TAGorTEST_FILTER. The given value toTEST_FILEmust be a path to an existing file.- Both
TEST_TAGandTEST_FILTERfilter tests by the strings from eitherit()ordescribe()functions.
Legacy
To run all legacy (Vim) integration tests:
make oldtest
To run a single legacy test, run make with TEST_FILE=test_name.res. E.g.
to run test_syntax.vim:
TEST_FILE=test_syntax.res make oldtest
- The
.resextension (instead of.vim) is required. - Specify only the test file name, not the full path.
Functional tests
$GDB can be set to run tests under
gdbserver. If $VALGRIND is also
set, it will add the --vgdb=yes option to valgrind instead of
starting gdbserver directly.
Unit tests
Tests are broadly divided into unit tests (test/unit directory) and functional tests (test/functional directory). Use any of the existing tests as a template to start writing new tests.
- Unit testing is achieved by compiling the tests as a shared library which is loaded and called by LuaJit FFI.
- Functional tests are driven by RPC, so they do not require LuaJit (as opposed to Lua).
You can learn the key concepts of Lua in 15 minutes.
Guidelines for writing tests
- Consider BDD guidelines for organization and readability of tests. Describe what you're testing (and the environment if applicable) and create specs that assert its behavior.
- For testing static functions or functions that have side effects visible only
in module-global variables, create accessors for the modified variables. For
example, say you are testing a function in misc1.c that modifies a static
variable, create a file
test/c-helpers/misc1.cand add a function that retrieves the value after the function call. Files undertest/c-helperswill only be compiled when building the test shared library. - Luajit needs to know about type and constant declarations used in function
prototypes. The
helpers.lua
file automatically parses
types.h, so types used in the tested functions must be moved to it to avoid having to rewrite the declarations in the test files (even though this is how it's currently done currently in the misc1/fs modules, but contributors are encouraged to refactor the declarations).- Macro constants must be rewritten as enums so they can be "visible" to the tests automatically.
- Busted supports various "output providers". The
gtest output provider
shows verbose details that can be useful to diagnose hung tests. Either modify
the Makefile or compile with
make CMAKE_EXTRA_FLAGS=-DBUSTED_OUTPUT_TYPE=gtestto enable it. - Use busted's
pending()feature to skip tests (example). Do not silently skip the test withif-else. If a functional test depends on some external factor (e.g. the existence ofmd5sumon$PATH), and you can't mock or fake the dependency, then skip the test viapending()if the external factor is missing. This ensures that the total test-count (success + fail + error + pending) is the same in all environments.- Note:
pending()is ignored if it is missing an argument unless it is contained in anit()block. Provide empty function argument if thepending()call is outside ofit()(example).
- Note:
- Use
make testlintfor using the shipped luacheck program (supported by syntastic) to lint all tests.
Where tests go
- Unit tests
(test/unit) should
match 1-to-1 with the structure of
src/nvim/, because they are testing functions directly. E.g. unit-tests forsrc/nvim/undo.cshould live intest/unit/undo_spec.lua. - Functional tests
(test/functional)
are higher-level (plugins and user input) than unit tests; they are organized
by concept.
- Try to find an existing
test/functional/*/*_spec.luagroup that makes sense, before creating a new one.
- Try to find an existing
Checklist for migrating legacy tests
Note: Only "old style" (src/testdir/*.in) legacy tests should be
converted. Please do not convert "new style" Vim tests (src/testdir/*.vim).
The "new style" Vim tests are faster than the old ones, and converting them
takes time and effort better spent elsewhere.
- Remove the test from the Makefile (
src/nvim/testdir/Makefile). - Remove the associated
test.in,test.out, andtest.okfiles fromsrc/nvim/testdir/. - Make sure the lua test ends in
_spec.lua. - Make sure the test count increases accordingly in the build log.
- Make sure the new test contains the same control characters (
^], ...) as the old test.- Instead of the actual control characters, use an equivalent textual
representation (e.g.
<esc>instead of^]). Thescripts/legacy2luatest.plscript does some of these conversions automatically.
- Instead of the actual control characters, use an equivalent textual
representation (e.g.
Tips
- Really long
source([=[...]=])blocks may break syntax highlighting. Try:syntax sync fromstartto fix it.
Lint
make lint (and make testlint) runs luacheck
on the test code.
If a luacheck warning must be ignored, specify the warning code. Example:
-- luacheck: ignore 621
http://luacheck.readthedocs.io/en/stable/warnings.html
Ignore the smallest applicable scope (e.g. inside a function, not at the top of the file).
Layout
/test/benchmark: benchmarks/test/functional: functional tests/test/unit: unit tests/test/config: contains*.infiles which are transformed into*.luafiles usingconfigure_fileCMake command: this is for acessing CMake variables in lua tests./test/includes: include-files for use by luajitffi.cdefC definitions parser: normally used to make macros not accessible via this mechanism accessible the other way./test/*/preload.lua: modules preloaded by busted--helperoption/test/**/helpers.lua: common utility functions for test code/test/*/**/*_spec.lua: actual tests. Files that do not end with_spec.luaare libraries like/test/**/helpers.lua, except that they have some common topic.
Tests in /test/unit and /test/functional are normally divided into groups
by the semantic component they are testing.
Environment variables
Test behaviour is affected by environment variables. Currently supported (Functional, Unit, Benchmarks) (when Defined; when set to 1; when defined, treated as Integer; when defined, treated as String; when defined, treated as Number; !must be defined to function properly):
GDB (F) (D): makes nvim instances to be run under gdbserver. It will be
accessible on localhost:7777: use gdb build/bin/nvim, type target remote :7777 inside.
GDBSERVER_PORT (F) (I): overrides port used for GDB.
VALGRIND (F) (D): makes nvim instances to be run under valgrind. Log files
are named valgrind-%p.log in this case. Note that non-empty valgrind log may
fail tests. Valgrind arguments may be seen in /test/functional/helpers.lua.
May be used in conjunction with GDB.
VALGRIND_LOG (F) (S): overrides valgrind log file name used for VALGRIND.
TEST_SKIP_FRAGILE (F) (D): makes test suite skip some fragile tests.
NVIM_PROG, NVIM_PRG (F) (S): override path to Neovim executable (default to
build/bin/nvim).
CC (U) (S): specifies which C compiler to use to preprocess files. Currently
only compilers with gcc-compatible arguments are supported.
NVIM_TEST_MAIN_CDEFS (U) (1): makes ffi.cdef run in main process. This
raises a possibility of bugs due to conflicts in header definitions, despite the
counters, but greatly speeds up unit tests by not requiring ffi.cdef to do
parsing of big strings with C definitions.
NVIM_TEST_PRINT_I (U) (1): makes cimport print preprocessed, but not yet
filtered through formatc headers. Used to debug formatc. Printing is done
with the line numbers.
NVIM_TEST_PRINT_CDEF (U) (1): makes cimport print final lines which will be
then passed to ffi.cdef. Used to debug errors ffi.cdef happens to throw
sometimes.
NVIM_TEST_PRINT_SYSCALLS (U) (1): makes it print to stderr when syscall
wrappers are called and what they returned. Used to debug code which makes unit
tests be executed in separate processes.
NVIM_TEST_RUN_FAILING_TESTS (U) (1): makes itp run tests which are known to
fail (marked by setting third argument to true).
LOG_DIR (FU) (S!): specifies where to seek for valgrind and ASAN log files.
NVIM_TEST_CORE_* (FU) (S): a set of environment variables which specify where
to search for core files. Are supposed to be defined all at once.
NVIM_TEST_CORE_GLOB_DIRECTORY (FU) (S): directory where core files are
located. May be .. This directory is then recursively searched for core files.
Note: this variable must be defined for any of the following to have any effect.
NVIM_TEST_CORE_GLOB_RE (FU) (S): regular expression which must be matched by
core files. E.g. /core[^/]*$. May be absent, in which case any file is
considered to be matched.
NVIM_TEST_CORE_EXC_RE (FU) (S): regular expression which excludes certain
directories from searching for core files inside. E.g. use ^/%.deps$ to not
search inside /.deps. If absent, nothing is excluded.
NVIM_TEST_CORE_DB_CMD (FU) (S): command to get backtrace out of the debugger.
E.g. gdb -n -batch -ex "thread apply all bt full" "$_NVIM_TEST_APP" -c "$_NVIM_TEST_CORE". Defaults to the example command. This debug command may use
environment variables _NVIM_TEST_APP (path to application which is being
debugged: normally either nvim or luajit) and _NVIM_TEST_CORE (core file to
get backtrace from).
NVIM_TEST_CORE_RANDOM_SKIP (FU) (D): makes check_cores not check cores after
approximately 90% of the tests. Should be used when finding cores is too hard
for some reason. Normally (on OS X or when NVIM_TEST_CORE_GLOB_DIRECTORY is
defined and this variable is not) cores are checked for after each test.
NVIM_TEST_RUN_TESTTEST (U) (1): allows running test/unit/testtest_spec.lua
used to check how testing infrastructure works.
NVIM_TEST_TRACE_LEVEL (U) (N): specifies unit tests tracing level: 0
disables tracing (the fastest, but you get no data if tests crash and there was
no core dump generated), 1 or empty/undefined leaves only C function cals and
returns in the trace (faster then recording everything), 2 records all
function calls, returns and lua source lines exuecuted.
NVIM_TEST_TRACE_ON_ERROR (U) (1): makes unit tests yield trace on error in
addition to regular error message.
NVIM_TEST_MAXTRACE (U) (N): specifies maximum number of trace lines to keep.
Default is 1024.