This document provides detailed information about the testing infrastructure for ansillary.nvim.
The testing suite is designed to ensure the plugin works reliably across different ANSI escape sequence formats and edge cases. Tests run without requiring a full Neovim instance by using a comprehensive vim API mock.
regex_spec.lua- Tests ANSI pattern matching and extractionconfig_spec.lua- Tests configuration loading and validationhighlights_spec.lua- Tests highlight group creation and color mappinginit_spec.lua- Tests main plugin logic, integration, and user commands
full_integration_spec.lua- End-to-end testing with real-world ANSI samples
ansi_samples.lua- Comprehensive collection of ANSI escape sequence samples for testing
test_helper.lua- Vim API mocking and test utility functions
Ensure you have Lua installed (version 5.1 or higher, 5.4 recommended):
lua -v # Check if Lua is installed# Using Make (recommended)
make test
# Or directly with Lua
lua run_tests.lua# Test individual modules
make test-regex # ANSI pattern matching tests
make test-config # Configuration tests
make test-highlights # Highlight creation tests
make test-init # Main plugin logic testsSuccessful test run:
Basic functionality test
✓ should load regex module
✓ should load config module
✓ should load highlights module
✓ should load main module
ANSI parsing
✓ should parse literal ESC sequences
Test Results: 5 passed, 0 failed
All tests passed!
Failed test run:
📊 Final Results: 107 passed, 1 failed
❌ Failed tests:
1. config > configuration structure > should have correct default values
→ Expected boolean, got: string
-
Choose the appropriate test file based on what you're testing:
- Regex pattern matching →
tests/unit/regex_spec.lua - Configuration →
tests/unit/config_spec.lua - Highlight creation →
tests/unit/highlights_spec.lua - Main plugin logic →
tests/unit/init_spec.lua - End-to-end workflows →
tests/integration/full_integration_spec.lua
- Regex pattern matching →
-
Follow the test structure:
describe("feature being tested", function() before_each(function() -- Setup code (reset state, etc.) end) it("should do something specific", function() -- Test implementation assert.are.equal(expected, actual) end) end)
-
Use the test helper functions:
local helper = require("tests.test_helper") helper.setup_vim_mock() -- Set up vim API mocks helper.create_test_buffer({"line1", "line2"}) -- Create test buffer content
The test framework provides these assertion functions:
assert.are.equal(expected, actual, message)assert.are.same(expected_table, actual_table, message)assert.is_true(value, message)assert.is_false(value, message)assert.is_nil(value, message)assert.is_not_nil(value, message)assert.is_table(value, message)assert.is_string(value, message)assert.is_boolean(value, message)assert.has_no.errors(function, message)
Add new ANSI samples to tests/fixtures/ansi_samples.lua:
-- Add to appropriate category
M.new_category = {
{
text = "\\033[38;5;196mBright red\\033[0m",
expected_attrs = {fg_extended = true},
description = "256-color foreground",
},
}The test helper provides comprehensive vim API mocking:
-- Mock vim functions are automatically set up
vim.api.nvim_set_hl(0, "TestGroup", {fg = "#ff0000"})
vim.notify("Test message", vim.log.levels.WARN)
vim.tbl_deep_extend("force", {}, {key = "value"})You can extend mocking as needed:
-- Custom mock function
vim.api.custom_function = function(arg)
return "mocked_result"
endEach test should be independent and not rely on state from other tests:
before_each(function()
helper.reset_vim_mock() -- Reset all mocks to clean state
package.loaded["ansillary.init"] = nil -- Clear module cache
end)Use clear, descriptive test names:
-- Good
it("should parse multiple ANSI attributes in single sequence", function()
-- Bad
it("should work", function()Always test boundary conditions and error cases:
it("should handle empty ANSI codes gracefully", function()
local line = "\\033[m" -- Empty code
-- Test that it doesn't crash
end)
it("should handle malformed sequences", function()
local line = "\\033[incomplete"
-- Test graceful degradation
end)For complex test data, use the fixtures system:
local fixtures = require("tests.fixtures.ansi_samples")
for _, sample in ipairs(fixtures.basic_colors) do
it("should handle " .. sample.description, function()
-- Test with sample.text
end)
end- Module not found errors: Check that
package.pathincludes the correct directories - Vim API errors: Ensure
helper.setup_vim_mock()is called before requiring modules - State pollution: Use
before_eachto reset state between tests
Add debug prints to understand test behavior:
it("should debug something", function()
local result = some_function()
print("Debug result:", vim.inspect(result)) -- Use vim.inspect for tables
assert.are.equal(expected, result)
end)To run a specific test, modify the test file temporarily:
-- Add 'only' to focus on specific test
it.only("should run only this test", function()
-- Test code
end)When setting up CI, ensure the test environment has:
- Lua 5.1+ installed
- Make utility (for Makefile commands)
- Access to the project directory
Example CI command:
make testThe tests are designed to run in any Unix-like environment and return appropriate exit codes for CI systems.