Skip to content

Nvim test - #398

Merged
shunkakinoki merged 6 commits into
mainfrom
nvim-test
Dec 6, 2025
Merged

Nvim test#398
shunkakinoki merged 6 commits into
mainfrom
nvim-test

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Dec 6, 2025

Copy link
Copy Markdown
Owner

Summary by cubic

Adds a Neovim test runner and a comprehensive test suite to verify core APIs, editor settings, and keymaps. This improves reliability and makes running tests simple via make.

  • New Features

    • Added Makefile test target: make test → neovim-test.
    • Moved run_tests.sh and fixed path; NVIM_DIR now resolves from the script directory.
    • minimal_init.lua now supports PLENARY_DIR to locate plenary.nvim.
    • Added tests for buffers, windows, keymaps, settings, LSP/diagnostics, Treesitter, Telescope, UI, terminal, autocmds, plugins, workspace, AI keymap patterns, and completion.
  • Migration

    • Run with make test or make neovim-test.
    • If plenary.nvim isn’t in a standard path, set PLENARY_DIR to its location.

Written for commit 0652089. Summary will update automatically on new commits.

Copilot AI review requested due to automatic review settings December 6, 2025 18:42
@coderabbitai

coderabbitai Bot commented Dec 6, 2025

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Summary by CodeRabbit

  • Tests

    • Added comprehensive test suites validating Neovim API functionality including buffers, windows, autocmds, LSP, keymaps, completion, plugins, settings, telescope, terminal, and treesitter.
    • Added test coverage for AI integration and workspace configuration.
  • Chores

    • Introduced test make target for running test suites.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds a public Makefile test target, moves the Neovim test runner path and adjusts NVIM_DIR resolution, adds PLENARY_DIR support, and introduces ~15 new Neovim Lua test suites covering APIs, keymaps, autocmds, plugins, LSP, treesitter, completion, UI, terminal, telescope, and workspace behaviors.

Changes

Cohort / File(s) Summary
Makefile configuration
Makefile
Added .PHONY: test and test: neovim-test to expose a public make test target; updated invocation path to the moved Neovim test runner.
Test runner setup
home-manager/programs/neovim/run_tests.sh
Rebound NVIM_DIR to the script's own directory (changes test path resolution/context).
Test infrastructure
home-manager/programs/neovim/tests/minimal_init.lua
Reads PLENARY_DIR from environment and prepends it to plenary search paths so an env-provided plenary.nvim takes precedence.
API test suites
home-manager/programs/neovim/tests/api/*
home-manager/programs/neovim/tests/api/{buffer_spec.lua,init_spec.lua,window_spec.lua}
New/updated suites validating buffer, init, and window APIs: creation/deletion, content, options, listing, dimensions, cursor behavior, and cleanup.
Keymaps & completion
home-manager/programs/neovim/tests/{keymaps_spec.lua,completion_spec.lua,ai_spec.lua}
Tests for leader/key mappings, insert-mode mappings, completion APIs, snippet presence, and a minimal AI/sidekick keymap check.
Autocmds & settings
home-manager/programs/neovim/tests/{autocmds_spec.lua,settings_spec.lua}
Autogroup/autocmd existence and behavior tests, plus extensive assertions on editor settings/options.
LSP, treesitter, UI & terminal
home-manager/programs/neovim/tests/{lsp_spec.lua,treesitter_spec.lua,ui_spec.lua,terminal_spec.lua}
Surface-level tests for LSP APIs/diagnostics, treesitter modules, UI (notify/colorscheme/ui functions), and terminal buffers/windows/autocmds.
Plugins, telescope & workspace
home-manager/programs/neovim/tests/{plugins_spec.lua,telescope_spec.lua,workspace_spec.lua}
Tests for plugin setup patterns, telescope config/find-command/themes/extensions, and workspace commands/autocmd-driven indentation behaviors.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • Many new, similar test files lower per-file complexity but require sampling.
  • Focus review on:
    • run_tests.sh NVIM_DIR rebinding and path assumptions
    • minimal_init.lua PLENARY_DIR precedence and runtimepath assembly
    • Representative tests for correct setup/teardown (buffers, windows, keymaps, autocmds)

Possibly related PRs

Poem

🐰
I hopped through code beneath the moon,
Planted tests that hum a tune,
Maps and buffers, trees that sing,
LSP and plugins take to wing,
A tiny hop — the suites are strewn.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Nvim test' is vague and generic, lacking specific detail about what was added or changed. Consider a more descriptive title such as 'Add comprehensive Neovim test suite and make test target' to better convey the main changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the PR objectives, detailing the test suite additions, Makefile changes, path fixes, and environment variable support.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nvim-test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @shunkakinoki, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the testing infrastructure for the Neovim configuration. It introduces a dedicated test command for easier test execution, refactors the test runner script's location for better organization, and vastly expands the test coverage across various Neovim APIs and configuration modules. The changes aim to ensure the stability and correctness of the Neovim setup by providing a robust and comprehensive testing framework.

Highlights

  • Test Infrastructure Enhancement: A new test target has been added to the Makefile to streamline the execution of Neovim tests, simplifying the testing workflow.
  • Test Runner Relocation: The run_tests.sh script, responsible for executing Neovim tests, has been moved to a more central location within the Neovim configuration directory, and the Makefile has been updated to reflect this change.
  • Expanded Test Suite: Numerous new test files have been introduced, significantly expanding the coverage of Neovim's core APIs, configuration settings, autocommands, keymaps, LSP, completion, UI, and various plugin-related patterns.
  • API Test Categorization: Existing and new API-related tests have been organized into a dedicated api subdirectory, improving the structure and maintainability of the test suite.
  • Plenary Path Prioritization: The minimal_init.lua script now prioritizes the PLENARY_DIR environment variable when resolving the path for the plenary.nvim plugin, offering more flexibility in test environments.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mesa-dot-dev

mesa-dot-dev Bot commented Dec 6, 2025

Copy link
Copy Markdown

Mesa Description

TL;DR

Adds a comprehensive Neovim test runner and a new test suite to verify core APIs, editor settings, keymaps, and plugin configurations, making tests easily runnable via make test.

What changed?

  • Makefile: Added a new test target that invokes neovim-test, updating the command to reflect the run_tests.sh script's new location.
  • home-manager/programs/neovim/run_tests.sh: Simplified the NVIM_DIR path calculation using SCRIPT_DIR.
  • home-manager/programs/neovim/tests/minimal_init.lua: Updated to support custom Plenary installations by checking and prioritizing the PLENARY_DIR environment variable.
  • New Test Files Added:
    • home-manager/programs/neovim/tests/ai_spec.lua: Tests AI 'sidekick' module structure and leader-based keymaps.
    • home-manager/programs/neovim/tests/api/buffer_spec.lua: Comprehensive tests for Neovim buffer API (creation, deletion, content, options).
    • home-manager/programs/neovim/tests/api/init_spec.lua: Renamed from config_spec.lua, now tests Neovim's init/core API and basic configuration.
    • home-manager/programs/neovim/tests/api/window_spec.lua: Comprehensive tests for Neovim window API (creation, deletion, management, options).
    • home-manager/programs/neovim/tests/autocmds_spec.lua: Comprehensive tests for Neovim autocommands (creation, groups, functionality, filetype settings).
    • home-manager/programs/neovim/tests/completion_spec.lua: Unit tests for Neovim's completion system (vim.fn.complete, vim.snippet, key mappings).
    • home-manager/programs/neovim/tests/keymaps_spec.lua: Comprehensive tests for Neovim keymap functionality (vim.keymap API, buffer-local, modes).
    • home-manager/programs/neovim/tests/lsp_spec.lua: Unit tests for Neovim's LSP and diagnostic functionalities (vim.lsp.buf, vim.diagnostic).
    • home-manager/programs/neovim/tests/plugins_spec.lua: Unit tests for Neovim plugin management (vim.pack.add, setup({}), specific configurations).
    • home-manager/programs/neovim/tests/settings_spec.lua: Validates various Neovim core settings (options, split, indentation, search, UI).
    • home-manager/programs/neovim/tests/telescope_spec.lua: Tests Neovim Telescope plugin configuration (keymaps, vimgrep, themes, extensions).
    • home-manager/programs/neovim/tests/terminal_spec.lua: Tests Neovim's terminal and window API (vim.fn.termopen, TermOpen autocommand, floating windows).
    • home-manager/programs/neovim/tests/treesitter_spec.lua: Comprehensive tests for Neovim's treesitter configuration (core APIs, keymaps, query functions).
    • home-manager/programs/neovim/tests/ui_spec.lua: UI configuration tests for Neovim (nvim-notify, colorscheme, vim.ui.select, laststatus).
    • home-manager/programs/neovim/tests/workspace_spec.lua: Unit tests for the workspace.lua plugin (WorkspaceRoot command, indentation, getcwd()).

Description generated by Mesa. Update settings

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive test suite for the Neovim configuration, which is a great step towards ensuring its stability and maintainability. The changes are well-structured, with tests organized by feature. My review focuses on improving the test code itself by reducing duplication and leveraging testing framework features to make the tests more concise and easier to maintain. I've noticed two common patterns that could be improved:

  1. Many test suites have repetitive setup and teardown code (like creating and deleting buffers) within each it block. This can be extracted into before_each and after_each hooks to reduce boilerplate.
  2. Some test suites contain multiple it blocks that perform very similar checks. These can often be consolidated into a single, data-driven test using a loop, making the test suite more compact.
    I've left specific suggestions on several of the new test files to illustrate these points. Applying these patterns across the new test files will significantly improve the test suite's quality.

Comment on lines +28 to +61
describe("content manipulation", function()
it("should set and get buffer lines", function()
local buf = vim.api.nvim_create_buf(false, true)
local lines = { "line 1", "line 2", "line 3" }
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)

local result = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
assert.are.same(lines, result)

vim.api.nvim_buf_delete(buf, { force = true })
end)

it("should append lines to buffer", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "first" })
vim.api.nvim_buf_set_lines(buf, -1, -1, false, { "second" })

local result = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
assert.are.same({ "first", "second" }, result)

vim.api.nvim_buf_delete(buf, { force = true })
end)

it("should replace specific lines", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "a", "b", "c" })
vim.api.nvim_buf_set_lines(buf, 1, 2, false, { "replaced" })

local result = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
assert.are.same({ "a", "replaced", "c" }, result)

vim.api.nvim_buf_delete(buf, { force = true })
end)
end)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a lot of repeated buffer creation and deletion in these tests. You can make the test suite cleaner and more maintainable by using before_each and after_each hooks to handle this setup and teardown logic. This avoids duplicating the same lines in every it block.

describe("content manipulation", function()
		local buf
		before_each(function()
			buf = vim.api.nvim_create_buf(false, true)
		end)

		after_each(function()
			if buf and vim.api.nvim_buf_is_valid(buf) then
				vim.api.nvim_buf_delete(buf, { force = true })
			end
		end)

		it("should set and get buffer lines", function()
			local lines = { "line 1", "line 2", "line 3" }
			vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)

			local result = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
			assert.are.same(lines, result)
		end)

		it("should append lines to buffer", function()
			vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "first" })
			vim.api.nvim_buf_set_lines(buf, -1, -1, false, { "second" })

			local result = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
			assert.are.same({ "first", "second" }, result)
		end)

		it("should replace specific lines", function()
			vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "a", "b", "c" })
			vim.api.nvim_buf_set_lines(buf, 1, 2, false, { "replaced" })

			local result = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
			assert.are.same({ "a", "replaced", "c" }, result)
		end)
	end)

Comment on lines +10 to +59
describe("augroup creation", function()
local function augroup_exists(name)
local ok, id = pcall(vim.api.nvim_get_autocmds, { group = name })
return ok and id ~= nil
end

it("should create HighlightYank augroup", function()
assert.is_true(augroup_exists("HighlightYank"))
end)

it("should create ResizeSplits augroup", function()
assert.is_true(augroup_exists("ResizeSplits"))
end)

it("should create CheckTime augroup", function()
assert.is_true(augroup_exists("CheckTime"))
end)

it("should create GitCommit augroup", function()
assert.is_true(augroup_exists("GitCommit"))
end)

it("should create NewFile augroup", function()
assert.is_true(augroup_exists("NewFile"))
end)

it("should create Help augroup", function()
assert.is_true(augroup_exists("Help"))
end)

it("should create Git augroup", function()
assert.is_true(augroup_exists("Git"))
end)

it("should create Fugitive augroup", function()
assert.is_true(augroup_exists("Fugitive"))
end)

it("should create QuickfixHelp augroup", function()
assert.is_true(augroup_exists("QuickfixHelp"))
end)

it("should create Markdown augroup", function()
assert.is_true(augroup_exists("Markdown"))
end)

it("should create Terminal augroup", function()
assert.is_true(augroup_exists("Terminal"))
end)
end)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of tests is quite repetitive. You can make it more concise and easier to extend by consolidating these checks into a single data-driven test that iterates over a list of augroup names.

describe("augroup creation", function()
		local function augroup_exists(name)
			local ok, id = pcall(vim.api.nvim_get_autocmds, { group = name })
			return ok and id ~= nil
		end)

		it("should create all expected augroups", function()
			local expected_augroups = {
				"HighlightYank",
				"ResizeSplits",
				"CheckTime",
				"GitCommit",
				"NewFile",
				"Help",
				"Git",
				"Fugitive",
				"QuickfixHelp",
				"Markdown",
				"Terminal",
			}
			for _, name in ipairs(expected_augroups) do
				assert.is_true(augroup_exists(name), "Expected augroup '" .. name .. "' to exist")
			end
		end)
	end)

Comment on lines +5 to +45
describe("vim.lsp API", function()
it("should have vim.lsp.buf available", function()
assert.is_table(vim.lsp.buf)
end)

it("should have hover function", function()
assert.is_function(vim.lsp.buf.hover)
end)

it("should have definition function", function()
assert.is_function(vim.lsp.buf.definition)
end)

it("should have declaration function", function()
assert.is_function(vim.lsp.buf.declaration)
end)

it("should have implementation function", function()
assert.is_function(vim.lsp.buf.implementation)
end)

it("should have references function", function()
assert.is_function(vim.lsp.buf.references)
end)

it("should have type_definition function", function()
assert.is_function(vim.lsp.buf.type_definition)
end)

it("should have code_action function", function()
assert.is_function(vim.lsp.buf.code_action)
end)

it("should have rename function", function()
assert.is_function(vim.lsp.buf.rename)
end)

it("should have signature_help function", function()
assert.is_function(vim.lsp.buf.signature_help)
end)
end)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These tests for the vim.lsp.buf API are very repetitive. To make the test suite more concise and maintainable, you can consolidate them into a single data-driven test that iterates through a list of function names to check for their existence.

describe("vim.lsp API", function()
		it("should have vim.lsp.buf available", function()
			assert.is_table(vim.lsp.buf)
		end)

		it("should have standard LSP buffer functions", function()
			local functions = {
				"hover",
				"definition",
				"declaration",
				"implementation",
				"references",
				"type_definition",
				"code_action",
				"rename",
				"signature_help",
			}
			for _, func_name in ipairs(functions) do
				assert.is_function(vim.lsp.buf[func_name], "vim.lsp.buf." .. func_name .. " should be a function")
			end
		end)
	end)

Comment on lines +39 to +59
describe("indentation", function()
it("should use spaces instead of tabs", function()
assert.is_true(vim.opt.expandtab:get())
end)

it("should enable smart indentation", function()
assert.is_true(vim.opt.smartindent:get())
end)

it("should set shiftwidth to 2", function()
assert.equals(2, vim.opt.shiftwidth:get())
end)

it("should set softtabstop to 2", function()
assert.equals(2, vim.opt.softtabstop:get())
end)

it("should set tabstop to 2", function()
assert.equals(2, vim.opt.tabstop:get())
end)
end)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The tests for indentation settings can be grouped into a single, more descriptive test case. This makes the intent clearer (testing the overall indentation setup) and reduces the number of individual tests, making the suite more concise.

describe("indentation", function()
		it("should be configured for 2-space soft tabs", function()
			assert.is_true(vim.opt.expandtab:get(), "should use spaces instead of tabs")
			assert.is_true(vim.opt.smartindent:get(), "should enable smart indentation")
			assert.equals(2, vim.opt.shiftwidth:get(), "shiftwidth should be 2")
			assert.equals(2, vim.opt.softtabstop:get(), "softtabstop should be 2")
			assert.equals(2, vim.opt.tabstop:get(), "tabstop should be 2")
		end)
	end)

Comment on lines +23 to +47
describe("indentation autocmd", function()
it("should set shiftwidth to 2 for new buffers", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_current_buf(buf)
vim.bo[buf].filetype = "lua"

vim.api.nvim_exec_autocmds("FileType", { pattern = "lua" })

assert.equals(2, vim.opt_local.shiftwidth:get())

vim.api.nvim_buf_delete(buf, { force = true })
end)

it("should set tabstop to 2 for new buffers", function()
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_current_buf(buf)
vim.bo[buf].filetype = "javascript"

vim.api.nvim_exec_autocmds("FileType", { pattern = "javascript" })

assert.equals(2, vim.opt_local.tabstop:get())

vim.api.nvim_buf_delete(buf, { force = true })
end)
end)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test block contains duplicated buffer creation and deletion logic. By using before_each and after_each hooks, you can centralize this setup and teardown, making the tests cleaner and less repetitive.

describe("indentation autocmd", function()
		local buf

		before_each(function()
			buf = vim.api.nvim_create_buf(false, true)
			vim.api.nvim_set_current_buf(buf)
		end)

		after_each(function()
			if buf and vim.api.nvim_buf_is_valid(buf) then
				vim.api.nvim_buf_delete(buf, { force = true })
			end
		end)

		it("should set shiftwidth to 2 for new buffers", function()
			vim.bo[buf].filetype = "lua"

			vim.api.nvim_exec_autocmds("FileType", { pattern = "lua" })

			assert.equals(2, vim.opt_local.shiftwidth:get())
		end)

		it("should set tabstop to 2 for new buffers", function()
			vim.bo[buf].filetype = "javascript"

			vim.api.nvim_exec_autocmds("FileType", { pattern = "javascript" })

			assert.equals(2, vim.opt_local.tabstop:get())
		end)
	end)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +26 to +29
describe("colorscheme", function()
it("should have dracula colorscheme available", function()
local colors = vim.fn.getcompletion("dracula", "color")
assert.is_true(#colors > 0 or vim.g.colors_name == "dracula")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Colorscheme test fails without dracula plugin

The new UI spec asserts that the dracula colorscheme is available (vim.fn.getcompletion("dracula", "color") must be non-empty or vim.g.colors_name already set), but the bundled test runner only bootstraps plenary and launches Neovim with the minimal init (run_tests.sh lines 25‑41). In a clean checkout running make neovim-test, no colorscheme plugins are installed or loaded, so the assertion at lines 27‑29 fails every time. Either load lua/ui.lua/install the colorscheme in the test harness or relax the expectation so the suite can pass on a fresh environment.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive test coverage for Neovim configuration using plenary.nvim as the testing framework. The tests cover various aspects of the Neovim setup including LSP, treesitter, completion, keymaps, autocmds, UI settings, and core API functionality.

Key changes:

  • Moves run_tests.sh from tests/ to the neovim config root directory and updates related paths
  • Adds 15 new test specification files covering different aspects of Neovim configuration
  • Updates minimal_init.lua to support environment variable for plenary directory
  • Adds a test target to the Makefile for easier test execution

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
Makefile Adds test target and updates neovim-test path to reflect script relocation
home-manager/programs/neovim/run_tests.sh Updates NVIM_DIR path logic for new script location
home-manager/programs/neovim/tests/minimal_init.lua Adds PLENARY_DIR environment variable support for flexible plenary.nvim location
home-manager/programs/neovim/tests/workspace_spec.lua Adds tests for workspace-specific settings and commands
home-manager/programs/neovim/tests/ui_spec.lua Adds tests for UI configurations including notify, colorscheme, and statusline
home-manager/programs/neovim/tests/treesitter_spec.lua Adds tests for treesitter API and configuration
home-manager/programs/neovim/tests/terminal_spec.lua Adds tests for terminal functionality and API basics
home-manager/programs/neovim/tests/telescope_spec.lua Adds tests for telescope-related APIs and configuration patterns
home-manager/programs/neovim/tests/settings_spec.lua Adds comprehensive tests for vim settings and options
home-manager/programs/neovim/tests/plugins_spec.lua Adds tests for plugin management patterns and setup
home-manager/programs/neovim/tests/lsp_spec.lua Adds tests for LSP configuration and diagnostics API
home-manager/programs/neovim/tests/keymaps_spec.lua Adds tests for keymap functionality and vim.keymap API
home-manager/programs/neovim/tests/completion_spec.lua Adds tests for completion-related APIs
home-manager/programs/neovim/tests/autocmds_spec.lua Adds tests for autocommands configuration
home-manager/programs/neovim/tests/api/window_spec.lua Adds tests for Neovim window API manipulation
home-manager/programs/neovim/tests/api/init_spec.lua Updates test suite name and removes verbose comments
home-manager/programs/neovim/tests/api/buffer_spec.lua Adds tests for Neovim buffer API operations
home-manager/programs/neovim/tests/ai_spec.lua Adds placeholder tests for AI/sidekick integration
Comments suppressed due to low confidence (2)

home-manager/programs/neovim/tests/api/init_spec.lua:2

  • The description has been updated to "Tests for Neovim init/core API" which is more accurate than the old "Tests for Neovim configuration loading" since the test suite has been renamed from "config" to "init".
    home-manager/programs/neovim/tests/api/init_spec.lua:54
  • The removal of inline comments (like "-- Create a new buffer", "-- Set lines", "-- Clean up") makes the code less readable, especially for complex test scenarios. Consider keeping helpful comments that explain non-obvious test steps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


it("should have get or get_query function", function()
-- API changed in newer Neovim versions
local has_get = vim.treesitter.query.get ~= nil or vim.treesitter.query.get_query ~= nil

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test checks for the existence of either get or get_query but doesn't verify that at least one of them is actually a function. Consider: assert.is_true((vim.treesitter.query.get and type(vim.treesitter.query.get) == "function") or (vim.treesitter.query.get_query and type(vim.treesitter.query.get_query) == "function"))

Suggested change
local has_get = vim.treesitter.query.get ~= nil or vim.treesitter.query.get_query ~= nil
local has_get = (vim.treesitter.query.get and type(vim.treesitter.query.get) == "function") or (vim.treesitter.query.get_query and type(vim.treesitter.query.get_query) == "function")

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +54
describe("getcwd", function()
it("should return current working directory", function()
local cwd = vim.fn.getcwd()
assert.is_string(cwd)
assert.is_true(#cwd > 0)
end)

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test "should return current working directory" only verifies that vim.fn.getcwd() returns a non-empty string, but it doesn't actually test any workspace.lua functionality. Consider either removing this test or modifying it to test actual workspace-related behavior if the workspace module provides any getcwd wrapper or related functionality.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +31
it("should support leader keymaps for pickers", function()
local leader_maps = {
"<leader>of",
"<leader>lg",
"<leader>fb",
"<leader>fh",
"<leader>fc",
"<leader>fr",
"<leader>fq",
"<leader>/",
}
for _, lhs in ipairs(leader_maps) do
vim.keymap.set("n", lhs, function() end, { noremap = true })
local keymap = vim.fn.maparg(lhs, "n")
assert.is_true(keymap ~= "", "Failed for " .. lhs)
vim.keymap.del("n", lhs)
end
end)

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The test name "should support leader keymaps for pickers" is somewhat generic. Consider being more specific about what's being tested, e.g., "should allow setting and verifying leader-based picker keymaps".

Copilot uses AI. Check for mistakes.

it("should set undo directory", function()
local undodir = vim.opt.undodir:get()
assert.is_true(type(undodir) == "string" or type(undodir) == "table")

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type check allows both string and table types for undodir, but doesn't verify that a table contains valid values or that a string is non-empty. Consider adding more specific assertions to ensure the undodir is properly configured.

Suggested change
assert.is_true(type(undodir) == "string" or type(undodir) == "table")
if type(undodir) == "string" then
assert.is_true(undodir ~= "")
elseif type(undodir) == "table" then
local has_nonempty = false
for _, v in ipairs(undodir) do
if type(v) == "string" and v ~= "" then
has_nonempty = true
break
end
end
assert.is_true(has_nonempty)
else
assert.is_true(false, "undodir must be string or table")
end

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +8
it("should set leader key to space", function()
assert.equals(" ", vim.g.mapleader)
end)

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The test assumes the leader key is already set to space. Consider setting it explicitly in the test or in a before_each hook to ensure test isolation and avoid dependency on external configuration state.

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +41
it("should support menu option", function()
vim.opt.completeopt:append("menu")
local completeopt = vim.opt.completeopt:get()
assert.is_true(vim.tbl_contains(completeopt, "menu"))
end)

it("should support menuone option", function()
vim.opt.completeopt:append("menuone")
local completeopt = vim.opt.completeopt:get()
assert.is_true(vim.tbl_contains(completeopt, "menuone"))
end)

it("should support noselect option", function()
vim.opt.completeopt:append("noselect")
local completeopt = vim.opt.completeopt:get()
assert.is_true(vim.tbl_contains(completeopt, "noselect"))
end)

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test modifies the global completeopt setting by appending "menu", which could affect subsequent tests. Consider using a before_each/after_each pattern to save and restore the original value, or create a fresh test buffer with local options.

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +10
it("should have sidekick module structure expected", function()
-- In full config, sidekick would be loaded
-- Here we just verify the expected API pattern
assert.is_true(true)
end)

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The test "should have sidekick module structure expected" has a placeholder comment but only asserts true without testing anything meaningful. Consider either implementing a real test for the sidekick API structure, or removing this placeholder test.

Copilot uses AI. Check for mistakes.

it("should enable mouse support for all modes", function()
local mouse = vim.opt.mouse:get()
assert.is_true(mouse.a == true or mouse == "a")

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition mouse.a == true or mouse == "a" is checking if either the table has an 'a' key set to true or if mouse equals the string "a". However, in Neovim, vim.opt.mouse:get() typically returns a string (e.g., "a"), not a table with boolean values. The first condition mouse.a == true would error if mouse is a string. Consider simplifying to just check: assert.equals("a", mouse) or handle the type check more carefully.

Suggested change
assert.is_true(mouse.a == true or mouse == "a")
assert.equals("a", mouse)

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +62
describe("plugin setup pattern", function()
it("should support setup with empty table", function()
-- Common pattern: require("plugin").setup({})
-- We test the pattern works
local mock_setup_called = false
local mock_plugin = {
setup = function(opts)
mock_setup_called = true
assert.is_table(opts)
end,
}
mock_plugin.setup({})
assert.is_true(mock_setup_called)
end)

it("should support setup with options", function()
local received_opts = nil
local mock_plugin = {
setup = function(opts)
received_opts = opts
end,
}
mock_plugin.setup({ enabled = true, timeout = 500 })
assert.equals(true, received_opts.enabled)
assert.equals(500, received_opts.timeout)
end)
end)

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The test "plugin setup pattern" doesn't actually test any real plugin functionality from the plugins.lua file. It only tests mock objects. Consider either testing actual plugin setup behavior or renaming to indicate it's testing the pattern/API, not the plugins.lua module.

Copilot uses AI. Check for mistakes.
describe("augroup creation", function()
local function augroup_exists(name)
local ok, id = pcall(vim.api.nvim_get_autocmds, { group = name })
return ok and id ~= nil

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The augroup_exists function uses pcall to catch errors, but it checks id ~= nil which is always true when pcall returns ok=true. The function should check if the returned autocmds table has elements or use a different approach to verify the group exists. Consider: return ok and #id > 0 or check vim.api.nvim_create_augroup to get the group ID.

Suggested change
return ok and id ~= nil
return ok and #id > 0

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
home-manager/programs/neovim/tests/minimal_init.lua (1)

21-32: Nil PLENARY_DIR breaks fallback plenary path discovery

With local plenary_paths = { plenary_dir, ... }, if PLENARY_DIR is unset (nil) then plenary_paths[1] is nil and ipairs(plenary_paths) stops immediately. This prevents any of the fallback paths from being checked, so plenary may never be added to runtimepath unless the env var is set.

Guard the env var and insert it only when non‑empty, keeping the original fallbacks intact:

-local plenary_dir = os.getenv("PLENARY_DIR")
-local plenary_paths = {
-	plenary_dir, -- Environment variable takes precedence
-	vim.fn.stdpath("data") .. "/site/pack/plugins/start/plenary.nvim",
-	vim.fn.stdpath("data") .. "/site/pack/plugins/opt/plenary.nvim",
-	vim.fn.expand("~/.local/share/nvim/site/pack/plugins/start/plenary.nvim"),
-	vim.fn.expand("~/.local/share/nvim/site/pack/plugins/opt/plenary.nvim"),
-	-- CI/test environment paths
-	"/tmp/plenary.nvim",
-	tests_dir .. "/plenary.nvim",
-}
+local plenary_dir = os.getenv("PLENARY_DIR")
+local plenary_paths = {
+	vim.fn.stdpath("data") .. "/site/pack/plugins/start/plenary.nvim",
+	vim.fn.stdpath("data") .. "/site/pack/plugins/opt/plenary.nvim",
+	vim.fn.expand("~/.local/share/nvim/site/pack/plugins/start/plenary.nvim"),
+	vim.fn.expand("~/.local/share/nvim/site/pack/plugins/opt/plenary.nvim"),
+	-- CI/test environment paths
+	"/tmp/plenary.nvim",
+	tests_dir .. "/plenary.nvim",
+}
+
+if plenary_dir ~= nil and plenary_dir ~= "" then
+	table.insert(plenary_paths, 1, plenary_dir) -- Environment variable takes precedence
+end
🧹 Nitpick comments (6)
home-manager/programs/neovim/tests/completion_spec.lua (1)

19-42: Consider resetting completeopt between tests.

The tests append values to completeopt without resetting it, which could cause state pollution if tests run in different orders or if new tests are added. Consider storing the original value and restoring it after each test.

Apply this pattern in a setup/teardown:

 describe("completeopt", function()
+   local original_completeopt
+   
+   before_each(function()
+     original_completeopt = vim.opt.completeopt:get()
+   end)
+   
+   after_each(function()
+     vim.opt.completeopt = original_completeopt
+   end)
+
   it("should be configurable", function()
     local completeopt = vim.opt.completeopt:get()
     assert.is_table(completeopt)
   end)
home-manager/programs/neovim/tests/treesitter_spec.lua (1)

1-62: Treesitter API presence tests are fine; keymap assertion is intentionally loose

The Treesitter API/query checks look good and version‑tolerant. For the incremental selection keymap you currently only assert maparg() returns a string, which is always true; if you ever want to enforce that <C-space> is actually mapped, you could tighten that to keymap ~= "" or mark the test pending when not present.

home-manager/programs/neovim/tests/ai_spec.lua (1)

1-22: AI/sidekick tests: keymap spec is useful; sidekick spec is just a stub

The keymap pattern test is a good minimal check and cleans up after itself. The “sidekick API” example is currently a no‑op stub; if that’s intentional scaffolding, you may want to either mark it pending or flesh it out once the sidekick module is loadable in the minimal env.

home-manager/programs/neovim/tests/ui_spec.lua (1)

1-60: UI tests are good; consider how hard you want to depend on Dracula

The vim.notify, vim.ui, and statusline checks are straightforward. The Dracula test (getcompletion("dracula", "color") or colors_name == "dracula") will fail if that colorscheme isn’t installed or loaded in the minimal test env; if you ever run these tests without Dracula present, you may want to soften this to “any colorscheme works” or gate/mark it pending when not available.

home-manager/programs/neovim/tests/settings_spec.lua (1)

112-120: Consider strengthening directory path assertions.

The current tests only verify that backupdir is non-empty and undodir is the correct type, but don't validate the actual directory paths. If the expected paths are predictable and consistent across test environments, consider asserting the specific values.

Example:

 it("should set backup directory", function()
   local backupdir = vim.opt.backupdir:get()
-  assert.is_true(#backupdir > 0)
+  -- More specific assertion if path is known:
+  assert.is_true(vim.tbl_contains(backupdir, vim.fn.expand("~/.local/state/nvim/backup//")))
 end)
home-manager/programs/neovim/tests/telescope_spec.lua (1)

1-3: Consider tracking integration tests as future work.

While the current pattern validation tests are useful, they don't exercise the actual telescope module or verify that your telescope configuration loads correctly. When feasible, consider adding integration tests that load telescope in a fuller test environment to catch real configuration issues.

Would you like me to open an issue to track adding telescope integration tests in the future?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9406219 and 9799ede.

📒 Files selected for processing (18)
  • Makefile (2 hunks)
  • home-manager/programs/neovim/run_tests.sh (1 hunks)
  • home-manager/programs/neovim/tests/ai_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/api/buffer_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/api/init_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/api/window_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/autocmds_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/completion_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/keymaps_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/lsp_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/minimal_init.lua (1 hunks)
  • home-manager/programs/neovim/tests/plugins_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/settings_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/telescope_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/terminal_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/treesitter_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/ui_spec.lua (1 hunks)
  • home-manager/programs/neovim/tests/workspace_spec.lua (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{sh,bash}

📄 CodeRabbit inference engine (CLAUDE.md)

Use shfmt with 2-space indentation for shell scripts

**/*.{sh,bash}: Use 2 spaces for indentation in shell scripts
Add proper shebang lines to shell scripts
Follow shellcheck recommendations in shell scripts
Document complex commands in shell scripts
Use consistent variable naming in shell scripts

Files:

  • home-manager/programs/neovim/run_tests.sh
🧠 Learnings (1)
📚 Learning: 2025-11-25T09:34:40.062Z
Learnt from: CR
Repo: shunkakinoki/dotfiles PR: 0
File: .cursor/rules/general.mdc:0-0
Timestamp: 2025-11-25T09:34:40.062Z
Learning: Test Nix and home-manager configurations locally before pushing using `make test`

Applied to files:

  • Makefile
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Agent
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Mesa Review
  • GitHub Check: docker-build-push (linux/amd64, amd64, ubuntu-latest)
  • GitHub Check: docker-build-push (linux/arm64, arm64, ubuntu-24.04-arm)
  • GitHub Check: nix-linux
  • GitHub Check: nix-darwin
  • GitHub Check: lua-neovim
  • GitHub Check: e2e-run (Ubuntu, ubuntu-latest)
  • GitHub Check: nix-nixos
  • GitHub Check: e2e-run (MacOS, macos-latest)
  • GitHub Check: e2e-run (NixOS, ubuntu-latest)
  • GitHub Check: lua-hammerspoon
  • GitHub Check: lua-neovim-test
🔇 Additional comments (17)
home-manager/programs/neovim/tests/terminal_spec.lua (1)

1-46: LGTM! Well-structured terminal API tests.

The test suite properly covers terminal functionality basics and window options. All tests include appropriate resource cleanup, preventing state pollution between test runs.

home-manager/programs/neovim/tests/api/buffer_spec.lua (1)

1-129: LGTM! Comprehensive buffer API test coverage.

The test suite thoroughly covers buffer operations including creation, deletion, content manipulation, options, listing, and naming. All tests properly clean up resources.

home-manager/programs/neovim/tests/plugins_spec.lua (1)

1-75: LGTM! Appropriate plugin pattern testing.

The test suite validates plugin management patterns and APIs using mocks, which is suitable for a minimal test environment where actual plugins aren't loaded.

home-manager/programs/neovim/tests/autocmds_spec.lua (2)

10-163: LGTM! Thorough autocmd testing.

The test suite comprehensively covers augroup creation, event registration, API usage, and filetype-specific settings. All tests properly manage buffer lifecycle and clean up test augroups.


5-8: No action needed. The autocmds module exists at home-manager/programs/neovim/lua/autocmds.lua and properly initializes all expected augroups (HighlightYank, ResizeSplits, CheckTime, GitCommit, NewFile, Help, Git, Fugitive, QuickfixHelp, Markdown, and Terminal). The test's before_each hook correctly reloads the module for each test.

home-manager/programs/neovim/tests/completion_spec.lua (1)

44-82: LGTM! Good cleanup practices for keymaps.

The snippet expansion and insert mode mapping tests properly clean up created keymaps, preventing test pollution.

home-manager/programs/neovim/tests/api/window_spec.lua (1)

1-142: LGTM! Comprehensive window API test coverage.

The test suite thoroughly validates window operations with proper resource cleanup throughout. Tests cover all major window API features including creation, deletion, buffer management, options, dimensions, and cursor positioning.

home-manager/programs/neovim/run_tests.sh (2)

9-51: LGTM! Well-structured test runner script.

The script follows shell best practices with proper error handling, availability checks, clear output, and correct exit code propagation. Indentation uses 2 spaces as per coding guidelines.


7-8: The test structure is correctly aligned with the NVIM_DIR path. The tests/ directory exists at home-manager/programs/neovim/tests/ with minimal_init.lua and all 16 test spec files (utils_spec.lua, ai_spec.lua, api/*.lua, autocmds_spec.lua, etc.) in place. Since NVIM_DIR points to the script's own directory and the script changes to that directory on line 35, the relative paths to tests/minimal_init.lua and tests/ on lines 40-41 will resolve correctly. No action required.

Likely an incorrect or invalid review comment.

Makefile (2)

140-141: LGTM! Public test target improves discoverability.

The new test target provides a clear entry point for running tests, aligning with the learning to "test Nix and home-manager configurations locally before pushing using make test."


498-501: LGTM! Test runner path correctly updated.

The path update to home-manager/programs/neovim/run_tests.sh aligns with the test infrastructure reorganization and matches the run_tests.sh location in this PR.

home-manager/programs/neovim/tests/api/init_spec.lua (1)

1-56: Init/core API tests look solid and self‑contained

The specs exercise core APIs (settings load, leader key, buffer/window validity, buffer ops, feedkeys) without leaving state behind; no issues from a correctness or flakiness standpoint.

home-manager/programs/neovim/tests/lsp_spec.lua (1)

1-104: LSP and diagnostic API surface tests look appropriate

This suite cleanly validates the expected vim.lsp and vim.diagnostic functions and severity constants without side effects (no server startup). Nothing concerning here.

home-manager/programs/neovim/tests/workspace_spec.lua (1)

1-56: Workspace command and autocmd tests are well‑structured

Reloading workspace per test, explicitly creating buffers, triggering FileType autocmds, and cleaning up buffers makes these specs clear and low‑risk.

home-manager/programs/neovim/tests/keymaps_spec.lua (1)

1-139: Comprehensive keymap API coverage with proper cleanup

This spec gives nice coverage of keymap behaviors (options, buffer-local, callbacks, multi-mode, and execution) and consistently deletes mappings/buffers afterward. No changes needed.

home-manager/programs/neovim/tests/settings_spec.lua (1)

1-170: LGTM! Comprehensive settings test coverage.

The test suite is well-structured with logical groupings, proper module reloading for isolation, and thorough coverage of Neovim settings. The assertions correctly validate expected option values using the vim.opt API.

home-manager/programs/neovim/tests/telescope_spec.lua (1)

1-99: LGTM! Pattern validation tests for telescope configuration.

The test suite appropriately validates telescope configuration patterns and keymap capabilities without loading the actual telescope plugin. The "pattern" naming in describe blocks clearly signals this scope, and the comment on line 2 explains the constraint. These smoke tests ensure configuration structures are syntactically valid.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 18 files

Prompt for AI agents (all 5 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="home-manager/programs/neovim/tests/ai_spec.lua">

<violation number="1" location="home-manager/programs/neovim/tests/ai_spec.lua:9">
P2: Trivial assertion `assert.is_true(true)` always passes and provides no test coverage. Consider either implementing a meaningful test (e.g., checking module structure exists) or marking it as pending/skipped with a clear TODO.</violation>
</file>

<file name="home-manager/programs/neovim/tests/treesitter_spec.lua">

<violation number="1" location="home-manager/programs/neovim/tests/treesitter_spec.lua:56">
P2: Test assertion doesn&#39;t verify what the test name claims. `vim.fn.maparg()` returns an empty string when no mapping exists, so `assert.is_string(keymap)` will always pass. Consider either:
1. Rename the test to reflect what it actually tests (e.g., &#39;should not error when checking C-space keymap&#39;)
2. Or add a meaningful assertion like `assert.is_truthy(keymap ~= &quot;&quot;)` if the mapping should exist</violation>
</file>

<file name="home-manager/programs/neovim/tests/completion_spec.lua">

<violation number="1" location="home-manager/programs/neovim/tests/completion_spec.lua:19">
P2: Tests modify `vim.opt.completeopt` but don&#39;t restore the original value, causing test pollution. Consider saving and restoring the original value, or add a `before_each`/`after_each` hook to reset state between tests.</violation>
</file>

<file name="home-manager/programs/neovim/tests/workspace_spec.lua">

<violation number="1" location="home-manager/programs/neovim/tests/workspace_spec.lua:49">
P2: This test doesn&#39;t actually test the workspace module - it only verifies Vim&#39;s built-in `vim.fn.getcwd()`. Consider testing workspace-specific getcwd behavior, or remove this test if the workspace module doesn&#39;t have related functionality.</violation>
</file>

<file name="home-manager/programs/neovim/tests/minimal_init.lua">

<violation number="1" location="home-manager/programs/neovim/tests/minimal_init.lua:24">
P1: Adding potentially `nil` value as first element breaks `ipairs` iteration. When `PLENARY_DIR` is not set, `os.getenv()` returns `nil`, causing `ipairs()` to stop immediately and skip all fallback paths. Consider filtering out nil or conditionally adding the path.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

it("should have sidekick module structure expected", function()
-- In full config, sidekick would be loaded
-- Here we just verify the expected API pattern
assert.is_true(true)

@cubic-dev-ai cubic-dev-ai Bot Dec 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Trivial assertion assert.is_true(true) always passes and provides no test coverage. Consider either implementing a meaningful test (e.g., checking module structure exists) or marking it as pending/skipped with a clear TODO.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/tests/ai_spec.lua, line 9:

<comment>Trivial assertion `assert.is_true(true)` always passes and provides no test coverage. Consider either implementing a meaningful test (e.g., checking module structure exists) or marking it as pending/skipped with a clear TODO.</comment>

<file context>
@@ -0,0 +1,22 @@
+		it(&quot;should have sidekick module structure expected&quot;, function()
+			-- In full config, sidekick would be loaded
+			-- Here we just verify the expected API pattern
+			assert.is_true(true)
+		end)
+	end)
</file context>
Fix with Cubic

end)

describe("incremental selection keymaps", function()
it("should have C-space mapped for init_selection", function()

@cubic-dev-ai cubic-dev-ai Bot Dec 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Test assertion doesn't verify what the test name claims. vim.fn.maparg() returns an empty string when no mapping exists, so assert.is_string(keymap) will always pass. Consider either:

  1. Rename the test to reflect what it actually tests (e.g., 'should not error when checking C-space keymap')
  2. Or add a meaningful assertion like assert.is_truthy(keymap ~= "") if the mapping should exist
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/tests/treesitter_spec.lua, line 56:

<comment>Test assertion doesn&#39;t verify what the test name claims. `vim.fn.maparg()` returns an empty string when no mapping exists, so `assert.is_string(keymap)` will always pass. Consider either:
1. Rename the test to reflect what it actually tests (e.g., &#39;should not error when checking C-space keymap&#39;)
2. Or add a meaningful assertion like `assert.is_truthy(keymap ~= &quot;&quot;)` if the mapping should exist</comment>

<file context>
@@ -0,0 +1,62 @@
+	end)
+
+	describe(&quot;incremental selection keymaps&quot;, function()
+		it(&quot;should have C-space mapped for init_selection&quot;, function()
+			local keymap = vim.fn.maparg(&quot;&lt;C-space&gt;&quot;, &quot;n&quot;)
+			-- Just verify it doesn&#39;t error, may not be set in test env
</file context>
Suggested change
it("should have C-space mapped for init_selection", function()
it("should be able to check C-space keymap without error", function()
Fix with Cubic

end)
end)

describe("completeopt", function()

@cubic-dev-ai cubic-dev-ai Bot Dec 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Tests modify vim.opt.completeopt but don't restore the original value, causing test pollution. Consider saving and restoring the original value, or add a before_each/after_each hook to reset state between tests.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/tests/completion_spec.lua, line 19:

<comment>Tests modify `vim.opt.completeopt` but don&#39;t restore the original value, causing test pollution. Consider saving and restoring the original value, or add a `before_each`/`after_each` hook to reset state between tests.</comment>

<file context>
@@ -0,0 +1,82 @@
+		end)
+	end)
+
+	describe(&quot;completeopt&quot;, function()
+		it(&quot;should be configurable&quot;, function()
+			local completeopt = vim.opt.completeopt:get()
</file context>
Fix with Cubic

end)
end)

describe("getcwd", function()

@cubic-dev-ai cubic-dev-ai Bot Dec 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This test doesn't actually test the workspace module - it only verifies Vim's built-in vim.fn.getcwd(). Consider testing workspace-specific getcwd behavior, or remove this test if the workspace module doesn't have related functionality.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/tests/workspace_spec.lua, line 49:

<comment>This test doesn&#39;t actually test the workspace module - it only verifies Vim&#39;s built-in `vim.fn.getcwd()`. Consider testing workspace-specific getcwd behavior, or remove this test if the workspace module doesn&#39;t have related functionality.</comment>

<file context>
@@ -0,0 +1,56 @@
+		end)
+	end)
+
+	describe(&quot;getcwd&quot;, function()
+		it(&quot;should return current working directory&quot;, function()
+			local cwd = vim.fn.getcwd()
</file context>
Fix with Cubic

-- Add plenary to runtimepath if installed via vim.pack or available
local plenary_dir = os.getenv("PLENARY_DIR")
local plenary_paths = {
plenary_dir, -- Environment variable takes precedence

@cubic-dev-ai cubic-dev-ai Bot Dec 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Adding potentially nil value as first element breaks ipairs iteration. When PLENARY_DIR is not set, os.getenv() returns nil, causing ipairs() to stop immediately and skip all fallback paths. Consider filtering out nil or conditionally adding the path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/programs/neovim/tests/minimal_init.lua, line 24:

<comment>Adding potentially `nil` value as first element breaks `ipairs` iteration. When `PLENARY_DIR` is not set, `os.getenv()` returns `nil`, causing `ipairs()` to stop immediately and skip all fallback paths. Consider filtering out nil or conditionally adding the path.</comment>

<file context>
@@ -19,7 +19,9 @@ vim.opt.runtimepath:append(&quot;.&quot;)
 -- Add plenary to runtimepath if installed via vim.pack or available
+local plenary_dir = os.getenv(&quot;PLENARY_DIR&quot;)
 local plenary_paths = {
+	plenary_dir, -- Environment variable takes precedence
 	vim.fn.stdpath(&quot;data&quot;) .. &quot;/site/pack/plugins/start/plenary.nvim&quot;,
 	vim.fn.stdpath(&quot;data&quot;) .. &quot;/site/pack/plugins/opt/plenary.nvim&quot;,
</file context>
Fix with Cubic

@mesa-dot-dev mesa-dot-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performed full review of 9406219...9799ede

Analysis

  1. Test-Source Structure Mismatch - The file tests/api/init_spec.lua was renamed from tests/config_spec.lua but doesn't correspond to any source file at lua/api/init.lua. This breaks the mirror pattern established between test files and source files, reducing discoverability and creating confusion.

  2. Missing Test Helper Abstraction - Common patterns are repeated across test files without abstraction (buffer creation/cleanup, keymap verification, autocmd checking). This leads to code duplication and harder maintenance. A shared test utilities file would improve consistency and reduce boilerplate.

  3. Inconsistent Test Cleanup - Some tests properly clean up resources (keymaps, buffers) while others don't. Files like keymaps_spec.lua use vim.keymap.del() but similar tests in other files (ai_spec, completion_spec) lack cleanup, potentially causing test pollution.

  4. Ambiguous Testing Approach for Plugin Dependencies - Tests acknowledge plugin dependencies won't be loaded in the minimal test environment, but are inconsistent about what they're actually validating. This creates ambiguity about whether tests validate correct behavior or just API availability.

Tip

Help

Slash Commands:

  • /review - Request a full code review
  • /review latest - Review only changes since the last review
  • /describe - Generate PR description. This will update the PR body or issue comment depending on your configuration
  • /help - Get help with Mesa commands and configuration options

18 files reviewed | 1 comments | Edit Agent SettingsRead Docs

-- Tests basic configuration loading and core Neovim functionality

describe("config", function()
describe("init", function()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

This file was renamed from config_spec.lua to api/init_spec.lua, but there's no corresponding source file at lua/api/init.lua. This breaks the test-to-source mirror pattern used throughout the test suite (e.g., tests/autocmds_spec.lualua/autocmds.lua). Consider either:

  1. Moving this back to tests/config_spec.lua with describe("config", ...), OR
  2. Adding a clear comment explaining why this deviates from the naming convention and what it's actually testing

The test content (settings loading, basic API operations) suggests this might be better as tests/init_spec.lua at the root level rather than under api/.

Agent: 🏛 Architecture • Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#398
File: home-manager/programs/neovim/tests/api/init_spec.lua#L4
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
This file was renamed from `config_spec.lua` to `api/init_spec.lua`, but there's no corresponding source file at `lua/api/init.lua`. This breaks the test-to-source mirror pattern used throughout the test suite (e.g., `tests/autocmds_spec.lua` → `lua/autocmds.lua`). Consider either:

1. Moving this back to `tests/config_spec.lua` with `describe("config", ...)`, OR
2. Adding a clear comment explaining why this deviates from the naming convention and what it's actually testing

The test content (settings loading, basic API operations) suggests this might be better as `tests/init_spec.lua` at the root level rather than under `api/`.

Copilot AI review requested due to automatic review settings December 6, 2025 19:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
home-manager/programs/neovim/tests/ui_spec.lua (1)

57-59: laststatus assertion always passes.

The check laststatus >= 0 will always be true since valid values are 0, 1, 2, or 3. If you want to verify a specific UI configuration (e.g., always showing the statusline), consider checking for an exact value like assert.equals(laststatus, 2) or assert.is_true(laststatus >= 2).

Apply this diff if you want to verify the statusline is always shown:

-		it("should have laststatus set", function()
+		it("should always show statusline", function()
 			local laststatus = vim.opt.laststatus:get()
-			assert.is_true(laststatus >= 0)
+			assert.is_true(laststatus >= 2)
 		end)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8f994e5 and 0652089.

📒 Files selected for processing (1)
  • home-manager/programs/neovim/tests/ui_spec.lua (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: docker-build-push (linux/amd64, amd64, ubuntu-latest)
  • GitHub Check: docker-build-push (linux/arm64, arm64, ubuntu-24.04-arm)
  • GitHub Check: Agent
  • GitHub Check: e2e-run (Ubuntu, ubuntu-latest)
  • GitHub Check: e2e-run (MacOS, macos-latest)
  • GitHub Check: e2e-run (NixOS, ubuntu-latest)
  • GitHub Check: lua-hammerspoon
  • GitHub Check: lua-neovim
  • GitHub Check: lua-neovim-test
  • GitHub Check: nix-nixos
  • GitHub Check: nix-linux
  • GitHub Check: nix-darwin
🔇 Additional comments (2)
home-manager/programs/neovim/tests/ui_spec.lua (2)

27-32: Colorscheme test is intentionally minimal.

The test has been simplified to work in minimal environments (addressing past review feedback), but it only verifies that the colorscheme API exists, not any actual configuration. This is acceptable given the constraints, though the test name "should support colorscheme API" accurately reflects what it tests.


46-54: vim.ui tests verify API availability.

The tests confirm vim.ui.select and vim.ui.input exist, which is appropriate for a minimal environment. They don't verify if these have been enhanced by plugins (e.g., dressing.nvim), but this aligns with the test suite's minimal environment approach.

Comment on lines +6 to +8
it("should be overridden with nvim-notify", function()
assert.is_function(vim.notify)
end)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test doesn't verify nvim-notify override.

The assertion only checks that vim.notify is a function, which is always true since vim.notify is a built-in Neovim API. This doesn't confirm that nvim-notify has overridden it. If verifying the override is important, consider checking for nvim-notify-specific behavior or metadata (e.g., checking if require("notify") exists). Alternatively, if the minimal test environment doesn't load nvim-notify, update the test description to reflect that it's only verifying the API exists.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shunkakinoki
shunkakinoki merged commit 5812f55 into main Dec 6, 2025
27 of 28 checks passed
@shunkakinoki
shunkakinoki deleted the nvim-test branch December 6, 2025 19:40
@coderabbitai coderabbitai Bot mentioned this pull request Dec 13, 2025
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.

2 participants