Files
neovim/test
Björn Linse a5ac2f45ff NVIM v0.5.0
This release represents ~4000 commits since v0.4.4, the previous
non-maintenance release. Highlights include builtin support for LSP, new APIs
for extended marks (with byte resolution tracking of changes) and buffer
decorations, as well as vast improvements to lua as a plugin and configuration
language. Experimental support for tree-sitter as a syntax engine is also
included, building on the new core APIs for byte tracking and decorations.

FEATURES:

New API functions:
  nvim_exec: execute multiline vim script blocks
  nvim_get_hl_id_by_name: Gets a highight definition by name
  nvim_exec_lua: new name for nvim_execute_lua
  nvim_notify: Notify the user with a message
  nvim_get_runtime_file: Find files in runtime directories
  nvim_get_all_options_info: Get option information for all options
  nvim_get_option_info: Get option information for one option
  nvim_echo: Echo a message with highlights
  nvim_open_term: Open a virtual terminal in a buffer
  nvim_chan_send: send data to a channel. (like chansend() but supports lua strings)
  nvim_set_decoration_provider: callback driven decoration API for a namespace

  nvim_buf_set_text: Set/replace a character range in a buffer
  nvim_buf_delete: Delete the buffer. |:bwipeout|
  nvim_buf_get_extmark_by_id: Returns position for a given extmark id.
  nvim_buf_get_extmarks: get extmarks in traversal order.
  nvim_buf_set_extmark: Creates or updates an extmark.

  nvim_buf_del_extmark: Removes an extmark.
  nvim_buf_call: call a function with buffer as temporary current buffer

  nvim_win_hide: Closes the window and hide the buffer it contains |:hide|
  nvim_win_call: Calls a function with window as temporary current window.

New UI events:
  redraw.screenshot
  redraw.win_viewport

Lua:
  767cd8b17 #12235 startup: add init.lua as an alternative user config
  687eb0b39 #14686 feat(startup): Source runtime/plugin/**/*.lua at startup
  #14686 runtime: allow lua in various runtime search paths such as
         syntax/ ftdetect/ indent/ ftplugin/ compiler/ colors/
  43956dea5 #13479 lua: Add vim.opt and fix scopes of vim.o
  1407899c3 #12268 lua: Add buffer, window and tab accessors
  be662fe5c lua: vim.wait implementation
  2b663c061 #14213 viml: embed Lua syntax highlighting
  901dd79f6 feat: add completion to ':lua'
  82688973 lua: complete methods in metatables
  342148525 runtime: propagate lua parsing errors while using "require"
  aaca2c1c4 #13276 feat(lua): improve error message to make it actionable
  c60c7375f startup: handle autoload and lua packages during startup
  3ccdbc570 #12536 lua: add vim.register_keystroke_callback
  971a191c4 lua: Add ability to pass lua functions directly to vimL
  91e41c857 #12401 lua: add vim.highlight.range
  f2894bffb #12279 lua: Add highlight.on_yank
  ae5bd0454 #11969 lua: add tbl_deep_extend
  ea4127e9a lua: metatable for empty dict value
  dab40f43b Add v:lua.func() vimL syntax for calling lua
  678a51b1d Lua: vim.validate()
  474d0bcbf lua: vim.rpcrequest, vim.rpcnotify, vim.NIL
  8ee7c94a9 lua: add vim.fn.{func} for direct access to vimL function
  d0d38fc36 #11442 Lua: vim.env, vim.{g,v,w,bo,wo}

Tree-sitter:
  Note: tree-sitter is considered experimental for 0.5. There's remaining
  bugs for buffer parsing, as well as known performance issues for
  large files and injected (nested) languages.

  e93342629 #10124 Tree-sitter API for lua
  440695c29 tree-sitter: implement query functionality and highlighting prototype
  8bea39f37 feat(treesitter): allow injections to be configured through directives
  929f19414 feat(treesitter): add offset predicate for language injection
  cd75d3289 #14200 feat: treesitter checkhealth
  1a631026a feat(treesitter): add language tree
  d3f544002 treesitter: runtime queries
  3c5141d2c #13008 treesitter: add string parser
  9437327d5 treesitter: use new on_bytes interface
  e4b5efa51 treesitter: use decoration provider API
  d6209a7b8 fix: Add a test and it is so pretty
  836c31032 feat(ts): bump tree-sitter to v0.20.0

LSP client:
  00dc12c5d #11336 lua LSP client: initial implementation
  d5aaad14e #11430 Followup improvements to LSP
  ee7ac469c #11578 LSP: Use async completion for omnifunc.
  070bd3ea2 #11604 LSP: shrink API, improve docs
  25afa10f9 #11669 Merge 'LSP: differentiate diagnostic underline by severity'
  e956ea767 #11777 LSP: show diagnostic in qf/loclist
  dd8b29cfe #11838 LSP: set InitializeParams.rootPath value
  0c5d2ffeb #11837 Merge 'LSP: fixes, improve test visibility'
  ca8699378 #11638 LSP: implement documentHighlight
  220a2b05c LSP/references: Add context to locations returned by server
  ccb038dc6 LSP/completion: add textEdit support
  da6f38ab3 #12313 LSP: Add workspace.applyEdit client capabilities
  f559e5249 #11607 LSP: Add textDocument/codeAction support
  0d83a1c43 #12638 LSP: Feature/add workspace folders
  fd507e278 #13641 LSP: window/showMessageRequest
  e467d2939 LSP: Move workspace/configuration handler from nvim-lspconfig to core
  2bdd553c9 feat(lsp): Add codelens support

UI:
  f8134f2fd screen.c: remove fold_line special case
  c146eddc8 experimental support for per-window color schemes
  a1508c9f6 nvim__screenshot (dump TUI state to file)
  08fe10010 terminal: enable pass through indexed colors to TUI in rgb mode
  5a8569942 tests/ui: make screen.lua use "linegrid" representation internally
  8fe19d9d8 screen: make ui_compositor aware of the intended size of a float
  54ce1010e extmark: add new flexible "decorations" abstraction
  4781333a7 decorations: allow virt_text overlay at any column
  bdebe8516 decorations: use extmark column adjustments for buffer highlights
  7b488314d decorations: Allow highlights beyond end of line hl_eol
  425bc438a decorations: add additional styling of virt_text overlays
  edb5864a2 floats: z-index
  243820ebd floats: add borders (MS-DOS MODE)
  5b6edc852 feat(float): add rounded borders preset
  4a36ec6da #14310 float: add "solid" border style

vim patches:
  around ~1000 vim patches and runtime updates got merged. Hooray!
  Changes include improvements to quickfix, prompt buffers, incsearch,
  display of search counts, and much much more.

various features and changes:
  858c05613 #12809 Support for :perl, :perlfile, :perldo and perleval()
  bc86f76c0 api/buffer: add "on_bytes" callback to nvim_buf_attach
  19b623708 jobstart now supports env/clear_env
  ef7c6b972 Support specifying "env" option for termopen()
  7c4f34966 #13287 switch from travis to github actions
  24db59ca8 feat: implement BufModified autocmd
  b83d8223f implement Scroll autocommand
  8caf84130 Lower "closed by the client" message level to INFO
  7de276b87 bump libvterm to 0.1.4
  097ec71bd #14096 aarch64/linux: fix build by updating LuaJIT
  bd5f0e969 #12531 support autoread using tui focus tracking
  8a1276005 #12382 Add v:event.visual during `TextYankPost`
  802f8429d api(nvim_open_win): add "noautocmd" option

FIXES:
  21444552c BugFix(clipboard): Fix block paste not working properly
  01493e799 #14413 api: fix nvim_exec() silencing behaviour
  9699f3be1 fix(doc): Add '/site' to stdpath('data') example in `:help 'rtp'`
  581b2bcde screen: fix problem with p_ch
  eae4b1e5c luaref: fix leaks for global luarefs
  409b2711f fix: segfault when pasting in term with empty buffer
  cf6c23fb0 #14273 fix plenty of errors discovered by clang
  21035cff9 #14500 fix plenty of errors discovered by coverity
  bca19138b #13987 tui: fix possibility of evaluating uninitialized variables
  9f2335937 fix_cursor: do not change line number when edit will not impact cursor row
  33f92fe02 fix(pty): Always use $TERM from the job's env dict
  6249059d4 checkhealth: fix terminfo problems on Windows
  397be5d38 #12811 UI: fix cursor not displayed after hiding and un-hiding
  87afc9031 screen.c: fix an issue with wrap and folds
  b419e39a2 screen.c: fix last character on foldtext
  2ea312769 #13688 screen.c: fix display of signcolumn=auto in diffs
  c2d288e29 Fix screen terminal family issues
  314b222c2 #14127 Fix click on foldcolumn with vsplit
  e65d0e53b vim.fn: throw error when trying to use API function
2021-07-02 17:54:29 +02:00
..
2021-07-02 17:54:29 +02:00

Tests

Tests are broadly divided into unit tests (test/unit), functional tests (test/functional), and old tests (src/nvim/testdir/).

  • 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. Use any existing test as a template to start writing new tests.

Tests are run by /cmake/RunTests.cmake file, using busted (a Lua test-runner). For some failures, .nvimlog (or $NVIM_LOG_FILE) may provide insight.

Depending on the presence of binaries (e.g., xclip) some tests will be ignored. You must compile with libintl to prevent E319: The command is not available in this version errors.



Layout

  • /test/benchmark : benchmarks
  • /test/functional : functional tests
  • /test/unit : unit tests
  • /test/config : contains *.in files which are transformed into *.lua files using configure_file CMake command: this is for acessing CMake variables in lua tests.
  • /test/includes : include-files for use by luajit ffi.cdef C definitions parser: normally used to make macros not accessible via this mechanism accessible the other way.
  • /test/*/preload.lua : modules preloaded by busted --helper option
  • /test/**/helpers.lua : common utility functions for test code
  • /test/*/**/*_spec.lua : actual tests. Files that do not end with _spec.lua are libraries like /test/**/helpers.lua, except that they have some common topic.
  • /src/nvim/testdir : old tests (from Vim)

Running tests

Executing Tests

To run all tests (except "old" tests):

make test

To run only unit tests:

make unittest

To run only functional tests:

make functionaltest

Legacy tests

To run all legacy Vim tests:

make oldtest

To run a single legacy test file you can use either:

make oldtest TEST_FILE=test_syntax.vim

or:

make src/nvim/testdir/test_syntax.vim
  • Specify only the test file name, not the full path.

Debugging tests

  • You can set $GDB to run tests under gdbserver. And if $VALGRIND is set it will pass --vgdb=yes to valgrind instead of starting gdbserver directly.

  • Hanging tests often happen due to unexpected :h press-enter prompts. The default screen width is 50 columns. Commands that try to print lines longer than 50 columns in the command-line, e.g. :edit very...long...path, will trigger the prompt. In this case, a shorter path or :silent edit should be used.

  • If you can't figure out what is going on, try to visualize the screen. Put this at the beginning of your test:

    local Screen = require('test.functional.ui.screen')
    local screen = Screen.new()
    screen:attach()
    

    Afterwards, put screen:snapshot_util() at any position in your test. See the comment at the top of test/functional/ui/screen.lua for more.

Filtering 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_FILTER='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:

BUSTED_ARGS="--repeat=100 --no-keep-going" TEST_FILE=test/functional/foo_spec.lua make functionaltest

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

NOTE:

  • TEST_FILE is not a pattern string like TEST_TAG or TEST_FILTER. The given value to TEST_FILE must be a path to an existing file.
  • Both TEST_TAG and TEST_FILTER filter tests by the string descriptions found in it() and describe().

Writing tests

Guidelines

  • 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 could be moved to it to avoid having to rewrite the declarations in the test files.
    • #define constants must be rewritten const or enum so they can be "visible" to the tests.
  • Use pending() to skip tests (example). Do not silently skip the test with if-else. If a functional test depends on some external factor (e.g. the existence of md5sum on $PATH), and you can't mock or fake the dependency, then skip the test via pending() 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 an it() block. Provide empty function argument if the pending() call is outside of it() (example).
  • Really long source([=[...]=]) blocks may break Vim's Lua syntax highlighting. Try :syntax sync fromstart to fix it.

Where tests go

Tests in /test/unit and /test/functional are divided into groups by the semantic component they are testing.

  • 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 for src/nvim/undo.c should live in test/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.lua group that makes sense, before creating a new one.

Lint

make lint (and make lualint) 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).

Configuration

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):

  • BUSTED_ARGS (F) (U): arguments forwarded to busted.

  • 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 no core dump was generated),
    • 1 leaves only C function calls and returns in the trace (faster than recording everything),
    • 2 records all function calls, returns and executed Lua source lines.
  • 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.