Skip to content

refactor: migrate test suite to Neovim/Lua#171

Merged
dkarter merged 20 commits into
masterfrom
chore/migrate-tests-to-neovim
Jun 3, 2026
Merged

refactor: migrate test suite to Neovim/Lua#171
dkarter merged 20 commits into
masterfrom
chore/migrate-tests-to-neovim

Conversation

@dkarter
Copy link
Copy Markdown
Member

@dkarter dkarter commented Jun 1, 2026

Summary

  • Replaces the broken Ruby + RSpec + Vimrunner test setup (which relied on MacVim's --servername client-server protocol, broken on macOS 16 with MacVim 9.2) with a headless Neovim + Lua + Plenary stack
  • Migrates all 61 existing Ruby tests to Lua with full parity — 63 tests total pass (61 ported + 2 infrastructure smoke tests)
  • Removes Ruby/Bundler as a test dependency; mise run test is the single command to run the suite
  • Updates CI to use jdx/mise-action@v4.0.1 and pins Ruby to major version 4

Changes

  • mise.toml: adds mise run test task; pins Ruby to 4; drops .tool-versions
  • Gemfile / Gemfile.lock: removes pry/pry-byebug (incompatible with Ruby 4 native ext)
  • .github/workflows/test.yml: replaces ruby/setup-ruby + xvfb-run rspec with jdx/mise-action + nvim --headless
  • test/minimal_init.lua: bootstraps Plenary from /tmp, loads plugin, sets test-safe defaults (noexpandtab, formatoptions=)
  • test/helpers.lua: feedkeys, new_buffer, get_lines, test_bullet_inserted, reset_config
  • test/*_spec.lua: full Lua test suite (9 spec files)
  • README.md: adds local development setup section

Key learnings from the migration

  • feedkeys('tx') exits insert mode after draining typeahead — for non-bullet-line CR tests, use two calls with i prefix on the second
  • The plugin defers <CR> via feedkeys("\<CR>", 'n') on non-bullet lines; the x flag drains this within the same outer call
  • vim.wait() exits insert mode — never use it between feedkeys calls
  • noexpandtab and formatoptions= must be set globally or tests contaminate each other
  • The nested dot-bullet test that was pending in Ruby now passes in Neovim (was a Vimrunner-specific issue)

Test plan

  • mise run test — 63/63 passing locally
  • CI green on push

Speed

⚡ blazing fast!
CleanShot 2026-06-03 at 00 18 44@2x

dkarter added 20 commits May 31, 2026 12:39
Replace .tool-versions with mise.toml, pinning to Ruby major version 4
to avoid unexpected breaking changes from future major version bumps.
byebug's native extension fails to compile against Ruby 4's updated C
API. Neither gem is referenced in the test suite, so they are safe to
remove. Also regenerates Gemfile.lock with current compatible versions.
Document the mise + bundle install workflow so contributors know how to
get a working local environment.
Use mise to install Ruby in CI, keeping the toolchain consistent with
local development. Removes the hardcoded ruby-version matrix — the
version is now sourced from mise.toml. Also bumps actions/checkout to
v6.0.2.
Introduces a Lua-based test suite driven by Neovim headless mode and
Plenary.nvim, replacing the broken Vimrunner/MacVim client-server setup.

- test/minimal_init.lua: bootstraps Plenary from /tmp and loads the plugin
- test/helpers.lua: feedkeys, new_buffer, test_bullet_inserted utilities
- test/poc_spec.lua: infrastructure smoke tests
- test/bullets_spec.lua: first ported spec (basic bullet insertion)
- mise.toml: adds `mise run test` task; no Makefile needed
…idoc)

Key learnings captured in test infrastructure:
- feedkeys 'tx' exits insert mode; for non-bullet CR tests use two feedkeys
  calls where the second prefixes 'i' to re-enter insert mode
- Non-bullet-line CR is deferred via feedkeys('n') by the plugin; the 'x'
  flag drains it within the first call, leaving normal mode on the new line
- vim.wait() exits insert mode — do not use it between feedkeys calls
- startinsert! is not synchronous from Lua — cannot bridge feedkeys calls
- set formatoptions= + comments= in minimal_init and per-test to prevent
  Neovim's '#' comment-continuation from corrupting test buffers
- nested dot bullet test (asciidoc) passes in Neovim — pending mark removed
…ckboxes)

Additional learnings added to minimal_init.lua:
- set noexpandtab globally to prevent user config leaking \t → spaces
- new_buffer() positions cursor at last line, so tests navigating from
  line 1 must prefix 'gg' before their first motion
- expandtab contamination affects <C-t> indent tests; fixed globally
Completes full test suite migration — all 63 tests passing.

Additional learnings:
- set expandtab=false + shiftwidth/tabstop=4 in before_each for indent tests
- visual mode selection is re-entered by plugin after </> ops; subsequent
  operations stay in visual — no <Esc> needed between chained motions
- A<CR><CR> in one feedkeys call handles the empty-bullet deletion case
  (both CRs fire while in insert mode, second deletes the empty bullet)
- .strip in Ruby tests hides trailing "- " (with space); Lua tests assert
  the actual content including the trailing space
- mid-test config changes (e.g. g:bullets_enable_roman_list) work by setting
  the global between separate feedkeys calls
@dkarter dkarter marked this pull request as ready for review June 3, 2026 06:06
@dkarter dkarter changed the title Migrate test suite from Ruby/RSpec/Vimrunner to Neovim/Lua/Plenary refactor: migrate test suite from Ruby/RSpec/Vimrunner to Neovim/Lua Jun 3, 2026
@dkarter dkarter changed the title refactor: migrate test suite from Ruby/RSpec/Vimrunner to Neovim/Lua refactor: migrate test suite to Neovim/Lua Jun 3, 2026
@dkarter dkarter merged commit 3f667ee into master Jun 3, 2026
2 checks passed
@dkarter dkarter deleted the chore/migrate-tests-to-neovim branch June 3, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant