Skip to content

Commit 5f924a0

Browse files
authored
ref(test)!: revamp test infra (#73)
* feat(linter): add zsh syntax checker * fix(ci): add luarocks bin to PATH * fix: revert ci change * feat(linter): add cpplint C++ linter * feat(linter): add cpplint C++ linter * ci: rewrite workflow with parallel jobs and modern actions replaces monolithic test job with parallel jobs grouped by package manager. each job installs only what it needs and runs its specific tests. - uses nvim-neorocks/nvim-busted-action for neovim + vusted setup - updates all actions to latest versions (checkout@v4, setup-python@v5, etc) - adds coverage job to warn when tools are missing tests - removes setup.sh and env.sh (no longer needed) * test: update expectations for guard.nvim diagnostic format changes - Strip _extmark_id in linter helper (internal nvim field) - Update tests to use separate code field instead of message suffix - Update end_col values to match guard.nvim behavior - Update rustfmt expected output for new import formatting style - Update buf formatter expected output (compact style) - Add missing W292 diagnostic to flake8 test - Remove buf linter test (requires buf.yaml config) * refactor(test): reorganize tests by package manager Move tests from test/{formatter,linter}/ to test/{pip,npm,go,rust,lua,binary,clang,haskell}/ to allow CI to use glob patterns (busted test/pip/*_spec.lua) instead of listing each test file explicitly. This means adding new tools no longer requires workflow changes. * fix(test): update checkmake expected output for new phonydeclared rule * fix(ci): run clang tests separately to avoid state pollution Run each clang test file in its own busted process to prevent test state from leaking between clang-format and clang-tidy tests. * fix(test): revert checkmake linter, fix test order Revert checkmake linter to original fn-based approach. Update test to match actual diagnostic output order. * fix(test): restore swiftformat test with proper naming Original test was named swiftformat.lua (missing _spec suffix) so busted never ran it. Restored with correct naming and added swiftformat installation to CI. * fix(ci): rename swiftformat binary after extraction * fix(test): restore buf linter test and fix formatter expectation * fix(buf): use fn approach for linter, fname for formatter * Revert "fix(buf): use fn approach for linter, fname for formatter" This reverts commit 51d94b1. * fix(buf): simpler test input, formatter uses fname not stdin * Revert "fix(buf): simpler test input, formatter uses fname not stdin" This reverts commit 3b5c3af. * fix(ci): remove buf tests (fix in separate PR) * fix: move cpplint to pip, zsh to binary * refactor(test)!: replace async test infra with synchronous execution Old test helpers used guard.nvim's async pipeline with a hardcoded vim.wait(3000), causing flaky CI failures. New approach runs tools directly via vim.system():wait() — zero timing issues, tests real tool output, no dependency on guard.nvim's format/filetype modules. This commit strips all existing tests and CI jobs down to a single MVP (black formatter + flake8 linter) to validate the approach. Remaining tools will be re-added in a follow-up PR. BREAKING CHANGE: test helpers renamed from fmt_helper/lint_helper to a unified test/helper.lua with run_fmt(), run_lint(), get_linter()
1 parent e9667a3 commit 5f924a0

41 files changed

Lines changed: 173 additions & 1096 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: JohnnyMorganz/stylua-action@v4
15+
with:
16+
token: ${{ secrets.GITHUB_TOKEN }}
17+
version: 2.0.2
18+
args: --check .
19+
20+
test-pip:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
- uses: rhysd/action-setup-vim@v1
25+
with:
26+
neovim: true
27+
version: nightly
28+
- uses: actions/setup-python@v5
29+
with:
30+
python-version: '3.12'
31+
- uses: leso-kn/gh-actions-lua@master
32+
with:
33+
luaVersion: "5.1"
34+
- uses: hishamhm/gh-actions-luarocks@master
35+
- name: Install tools
36+
run: |
37+
pip install -q black flake8
38+
luarocks install busted --local
39+
luarocks install nlua --local
40+
- name: Clone guard.nvim
41+
run: git clone --depth 1 https://github.com/nvimdev/guard.nvim && mv guard.nvim/lua/guard lua/
42+
- name: Run tests
43+
run: |
44+
export LUA_PATH="lua/?.lua;lua/?/init.lua;$LUA_PATH"
45+
busted --lua nlua test/pip/*_spec.lua

.github/workflows/test.yml

Lines changed: 0 additions & 75 deletions
This file was deleted.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CLAUDE.md

CONTRIBUTING.md

Lines changed: 35 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,71 @@
11
# Contributing to guard-collection
22

33
- Add your config to `formatter.lua` or `linter/<tool-name>.lua`, if it's a linter don't forget to export it in `linter/init.lua`
4-
- Write a test. If it's a formatter, show that the config works by giving an example input and verify that the file did got formatted as intended. For example:
4+
- Write a test in the appropriate `test/<category>/` directory. Tests run tools synchronously via `vim.system():wait()`, bypassing guard.nvim's async pipeline.
5+
6+
Formatter example:
57

68
```lua
79
describe('black', function()
810
it('can format', function()
9-
-- pre-test setup
10-
local ft = require('guard.filetype')
11-
ft('python'):fmt('black')
12-
-- Giving example input to the helper
13-
-- the helper creates a new buffer with it, formats, and returns the formatted output
14-
local formatted = require('test.formatter.helper').test_with('python', {
15-
-- The input code should somewhat reflect the filetype
11+
local formatted = require('test.helper').run_fmt('black', 'python', {
1612
[[def foo(n):]],
1713
[[ if n in (1,2,3):]],
1814
[[ return n+1]],
19-
[[a, b = 1, 2]],
20-
[[b, a = a, b]],
21-
[[print( f"The factorial of {a} is: {foo(a)}")]],
2215
})
23-
-- Show that the input is indeed formatted as intended
2416
assert.are.same({
2517
[[def foo(n):]],
2618
[[ if n in (1, 2, 3):]],
2719
[[ return n + 1]],
28-
[[]],
29-
[[]],
30-
[[a, b = 1, 2]],
31-
[[b, a = a, b]],
32-
[[print(f"The factorial of {a} is: {foo(a)}")]],
3320
}, formatted)
3421
end)
3522
end)
3623
```
3724

38-
- Or if it's a linter, show that the linter's output is converted correctly into neovim diagnostics
25+
Linter example:
3926

4027
```lua
41-
describe('selene', function()
28+
describe('flake8', function()
4229
it('can lint', function()
43-
-- pre-test setup
44-
local helper = require('test.linter.helper')
45-
local ns = helper.namespace
46-
local ft = require('guard.filetype')
47-
ft('lua'):lint('selene')
48-
require('guard').setup()
49-
-- Giving example input to the helper
50-
-- the helper creates a new buffer with it, requires lint, and returns the diagnostics
51-
local buf, diagnostics = require('test.linter.helper').test_with('lua', {
52-
-- Make sure the input actually has some problems that the linter detects
53-
[[local M = {}]],
54-
[[function M.foo()]],
55-
[[ print("foo")]],
56-
[[end]],
57-
[[U.bar()]],
58-
[[return M]],
30+
local helper = require('test.helper')
31+
local buf, diagnostics = helper.run_lint('flake8', 'python', {
32+
[[import os]],
5933
})
60-
-- Show that the diagnostics is indeed valid
61-
assert.are.same({
62-
{
63-
bufnr = buf,
64-
col = 0,
65-
end_col = 0,
66-
end_lnum = 4,
67-
lnum = 4,
68-
message = '`U` is not defined [undefined_variable]',
69-
-- sometimes the namespace is not fixed
70-
namespace = ns,
71-
severity = 1,
72-
source = 'selene',
73-
},
74-
}, diagnostics)
34+
assert.is_true(#diagnostics > 0)
35+
for _, d in ipairs(diagnostics) do
36+
assert.equal(buf, d.bufnr)
37+
assert.equal('flake8', d.source)
38+
assert.is_number(d.lnum)
39+
assert.is_string(d.message)
40+
end
7541
end)
7642
end)
77-
7843
```
7944

80-
- To run the test you just created, install [vusted](https://github.com/notomo/vusted)
81-
```shell
82-
luarocks --lua-version=5.1 install vusted
83-
```
84-
- Create a symlink so that vusted recognizes guard.nvim namespaces
45+
For linters with a custom `fn` (cpplint, checkmake, zsh), run the command directly and test `parse()`:
8546

86-
```shell
87-
ln -s ~/.local/share/nvim/lazy/guard.nvim/lua/guard lua
47+
```lua
48+
describe('cpplint', function()
49+
it('can lint', function()
50+
local linter = require('test.helper').get_linter('cpplint')
51+
local tmpfile = '/tmp/guard-test.cpp'
52+
vim.fn.writefile({ [[int main(){int x=1;}]] }, tmpfile)
53+
local bufnr = vim.api.nvim_create_buf(false, true)
54+
local result = vim.system({ 'cpplint', '--filter=-legal/copyright', tmpfile }, {}):wait()
55+
local diagnostics = linter.parse(result.stderr or '', bufnr)
56+
assert.is_true(#diagnostics > 0)
57+
end)
58+
end)
8859
```
8960

90-
- Run the test and make sure it passes
91-
61+
- Add your tool to CI in `.github/workflows/ci.yaml` under the appropriate job
62+
- Run the test locally:
9263
```shell
93-
94-
vusted ./test/formatter/<tool-name>_spec.lua
95-
# or
96-
vusted ./test/linter/<tool-name>\_spec.lua
97-
98-
ok 1 - <tool-name> can format
99-
ok 1 - <tool-name> can lint
64+
# requires: neovim, lua 5.1, luarocks, busted, nlua
65+
# also requires guard.nvim cloned: git clone --depth 1 https://github.com/nvimdev/guard.nvim && mv guard.nvim/lua/guard lua/
66+
make test-pip # or whichever category
10067
```
101-
102-
- Modify `test/setup.sh` so that CI installs your tool
103-
104-
- Optionally, format the code with stylua
68+
- Format with stylua before submitting:
10569
```shell
10670
stylua .
10771
```

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
LUA_PATH := lua/?.lua;lua/?/init.lua;$(LUA_PATH)
2+
export LUA_PATH
3+
4+
.PHONY: lint test test-pip
5+
6+
lint:
7+
stylua --check .
8+
9+
test: test-pip
10+
11+
test-pip:
12+
busted --lua nlua test/pip/*_spec.lua

test/env.sh

Lines changed: 0 additions & 4 deletions
This file was deleted.

test/formatter/alejandra_spec.lua

Lines changed: 0 additions & 17 deletions
This file was deleted.

test/formatter/autopep8_spec.lua

Lines changed: 0 additions & 25 deletions
This file was deleted.

test/formatter/biome_spec.lua

Lines changed: 0 additions & 30 deletions
This file was deleted.

test/formatter/buf_spec.lua

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)