From 56046a64ddbf8f09fb8b6a075666972e9e00b544 Mon Sep 17 00:00:00 2001 From: AnnatarHe Date: Sun, 28 Dec 2025 20:46:39 +0800 Subject: [PATCH 1/3] feat(ci): add GitHub Actions workflow with code coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add CI workflow testing on Neovim v0.11.0 and nightly - Configure luacov for code coverage tracking - Add coverage upload to Codecov - Create test-coverage.sh script for coverage collection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 51 ++++++++++++++++++++++++++++++++++++++++ .luacov | 9 +++++++ scripts/test-coverage.sh | 29 +++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .luacov create mode 100755 scripts/test-coverage.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e76a334 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + neovim: ['v0.11.0', 'nightly'] + steps: + - uses: actions/checkout@v4 + + - name: Setup Neovim + uses: rhysd/action-setup-vim@v1 + with: + neovim: true + version: ${{ matrix.neovim }} + + - name: Install LuaRocks + run: sudo apt-get install -y luarocks + + - name: Install luacov + run: | + sudo luarocks install luacov + sudo luarocks install luacov-reporter-lcov + + - name: Clone plenary.nvim + run: | + mkdir -p ~/.local/share/nvim/site/pack/vendor/start + git clone --depth 1 https://github.com/nvim-lua/plenary.nvim \ + ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim + + - name: Run tests + run: ./scripts/test.sh + + - name: Run tests with coverage + if: matrix.neovim == 'v0.11.0' + run: ./scripts/test-coverage.sh + + - name: Upload coverage to Codecov + if: matrix.neovim == 'v0.11.0' + uses: codecov/codecov-action@v5 + with: + files: ./lcov.info + fail_ci_if_error: false diff --git a/.luacov b/.luacov new file mode 100644 index 0000000..d0cbe15 --- /dev/null +++ b/.luacov @@ -0,0 +1,9 @@ +return { + include = { + "lua/shelltime/.+%.lua$", + }, + exclude = { + "tests/", + "plugin/", + }, +} diff --git a/scripts/test-coverage.sh b/scripts/test-coverage.sh new file mode 100755 index 0000000..911a6ec --- /dev/null +++ b/scripts/test-coverage.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Run tests with code coverage using luacov +# Requires: luacov, luacov-reporter-lcov installed via luarocks + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +cd "$PROJECT_DIR" + +# Clean previous coverage data +rm -f luacov.stats.out luacov.report.out lcov.info + +# Run tests with luacov +nvim --headless \ + -u "$PROJECT_DIR/tests/minimal_init.lua" \ + -c "lua require('luacov')" \ + -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal_init.lua'}" \ + 2>&1 + +# Generate lcov report for Codecov +if [ -f luacov.stats.out ]; then + luacov -r lcov -o lcov.info + echo "Coverage report generated: lcov.info" +else + echo "Warning: No coverage stats generated" + exit 1 +fi From a456d32b47bca827a1171fd7279ab77664593284 Mon Sep 17 00:00:00 2001 From: AnnatarHe Date: Sun, 28 Dec 2025 21:00:30 +0800 Subject: [PATCH 2/3] fix(ci): add project root to package path for test helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests require 'tests.helpers' but the package path only included the tests/ directory, causing resolution to fail in CI environment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- tests/minimal_init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/minimal_init.lua b/tests/minimal_init.lua index 2cdb591..0e26b4d 100644 --- a/tests/minimal_init.lua +++ b/tests/minimal_init.lua @@ -5,7 +5,11 @@ local plugin_dir = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':h:h') vim.opt.rtp:prepend(plugin_dir) --- Add tests directory to package path for helpers +-- Add project root to package path for 'tests.helpers' requires +package.path = plugin_dir .. '/?.lua;' .. package.path +package.path = plugin_dir .. '/?/init.lua;' .. package.path + +-- Add tests directory to package path for 'helpers' requires package.path = plugin_dir .. '/tests/?.lua;' .. package.path package.path = plugin_dir .. '/tests/?/init.lua;' .. package.path From 83db2fd04b932ba43a7c79ae521fddddee81696e Mon Sep 17 00:00:00 2001 From: AnnatarHe Date: Sun, 28 Dec 2025 21:06:08 +0800 Subject: [PATCH 3/3] fix(ci): properly initialize luacov for coverage collection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create coverage_init.lua to load luacov before test code - Save coverage stats on VimLeavePre autocmd - Set LUA_PATH/LUA_CPATH env vars for luarocks modules - Don't fail CI if coverage stats unavailable 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 3 +++ scripts/test-coverage.sh | 14 +++++++------- tests/coverage_init.lua | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 tests/coverage_init.lua diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e76a334..f5b6057 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,9 @@ jobs: - name: Run tests with coverage if: matrix.neovim == 'v0.11.0' + env: + LUA_PATH: '/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;;' + LUA_CPATH: '/usr/local/lib/lua/5.1/?.so;;' run: ./scripts/test-coverage.sh - name: Upload coverage to Codecov diff --git a/scripts/test-coverage.sh b/scripts/test-coverage.sh index 911a6ec..6e409e0 100755 --- a/scripts/test-coverage.sh +++ b/scripts/test-coverage.sh @@ -12,18 +12,18 @@ cd "$PROJECT_DIR" # Clean previous coverage data rm -f luacov.stats.out luacov.report.out lcov.info -# Run tests with luacov +# Run tests with coverage init (loads luacov before test code) nvim --headless \ - -u "$PROJECT_DIR/tests/minimal_init.lua" \ - -c "lua require('luacov')" \ - -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal_init.lua'}" \ - 2>&1 + -u "$PROJECT_DIR/tests/coverage_init.lua" \ + -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/coverage_init.lua'}" \ + 2>&1 || true # Generate lcov report for Codecov if [ -f luacov.stats.out ]; then luacov -r lcov -o lcov.info echo "Coverage report generated: lcov.info" else - echo "Warning: No coverage stats generated" - exit 1 + echo "Warning: No coverage stats generated (luacov may not be installed)" + # Don't fail CI if coverage isn't available + exit 0 fi diff --git a/tests/coverage_init.lua b/tests/coverage_init.lua new file mode 100644 index 0000000..e37c1e6 --- /dev/null +++ b/tests/coverage_init.lua @@ -0,0 +1,23 @@ +-- Coverage init for running tests with luacov +-- This file wraps minimal_init.lua and adds luacov support + +-- Initialize luacov BEFORE loading any other modules +local ok, luacov = pcall(require, 'luacov') +if not ok then + print('Warning: luacov not found, running tests without coverage') +end + +-- Load the regular minimal init +local script_path = debug.getinfo(1, 'S').source:sub(2) +local tests_dir = vim.fn.fnamemodify(script_path, ':h') +dofile(tests_dir .. '/minimal_init.lua') + +-- Save coverage stats on exit +vim.api.nvim_create_autocmd('VimLeavePre', { + callback = function() + if ok and luacov then + local runner = require('luacov.runner') + runner.save_stats() + end + end, +})