test: add automated test framework and CI foundation - #25
Merged
Merged
Conversation
Adds a dependency-free unit test harness that runs inside headless Neovim, plus regression coverage for the behavior that exists on main. The harness provides describe/it, deep-equality and error assertions, and a runner (`nvim -l tests/run.lua`, wrapped as `make test`) that exits non-zero on failure so CI can gate on it. A stub module replaces the handful of system-facing calls the plugin makes (vim.fn.system, vim.fn.executable, vim.system, vim.notify) and restores them per case, so no test contacts a real SSH server or mount table. Baseline suites cover mount table parsing for Linux fuse.sshfs, macFUSE and findmnt output, mount directory creation, SSH command construction including tilde expansion and quote escaping, ad-hoc host string parsing, configuration merging with its deprecation shims, and remote path mapping. CI runs the suite and stylua --check on every pull request. Refs #24
A call under test can return more than one value, and keeping only the first silently turned assertions on the later ones into assertions on nil.
This was referenced Aug 31, 2026
A case that failed before its own restore_all left vim.fn stubs active for every later case in the process, so one real failure cascaded into unrelated false failures. The runner-level cleanup ran far too late to prevent it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements #24: a lightweight, dependency-free test harness plus CI, so the open feature PRs have somewhere to put their regression coverage.
describe/it, deep-equality and error assertions, and a result reportervim.fn.system,vim.fn.executable,vim.system,vim.notify), restored per casenvim -l tests/run.lua, wrapped asmake testmake test PATTERN=<substring>to run a subsetstylua --checkon every pull requesttests/README.mdDesign
The harness runs inside headless Neovim via
nvim -l, so the realvimAPI is available and only the handful of calls that reach the operating system need stubbing. That keeps the mocking surface small: a spec stubs the mount table or an SSH subprocess and calls the module directly.No external dependency is introduced. Neovim is the only thing CI installs.
Two conventions keep cases isolated:
stub.restore_all()undoes stubs at the end of a case, andstub.reload()clears cachedsshfs.*modules so memoized state (configuration, SSHFS version detection) does not leak between cases.Baseline coverage
41 cases against behavior already on
main:fuse.sshfs, macFUSE, andfindmntoutput, including non-sshfs lines, mounts outside the base directory, and a failingmountcommanduser@host:path -p 2222and its variants)Follow-up
Feature-specific coverage stays with each feature PR, as those PRs describe. Once this lands, #20, #21, #22, and #23 pick it up and add their own regression suites.
Closes #24