Tests #558
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Tests | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| merge_group: | |
| permissions: | |
| contents: read | |
| # Cancel in-progress runs for pull requests when developers push | |
| # additional changes | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| jobs: | |
| # Unit/component tests run under LuaJIT with a mocked vim global (busted), so | |
| # they do not need a real Neovim binary β hence no neovim-version matrix here. | |
| # Real-Neovim coverage lives in the integration-tests job below. | |
| unit-tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| # Build deps: PUC Lua builds from source, and the test rocks compile C modules. | |
| - name: Install build dependencies | |
| run: | | |
| sudo apt-get -o Acquire::Retries=3 update | |
| sudo apt-get -o Acquire::Retries=3 install -y build-essential libreadline-dev unzip | |
| - name: Set up mise | |
| uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 | |
| - name: Install release tooling dependencies | |
| env: | |
| NPM_CONFIG_IGNORE_SCRIPTS: "true" | |
| run: npm ci --prefix scripts | |
| - name: Run release tooling tests | |
| run: npm --prefix scripts run test:release-please-runner | |
| # Cache the rock tree (rebuilt from luarocks.org otherwise); a miss just rebuilds. | |
| - name: Cache Lua test rocks | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: .luarocks | |
| key: luarocks-${{ runner.os }}-${{ hashFiles('mise.toml') }} | |
| - name: Install Lua test rocks | |
| run: mise run setup | |
| - name: Run luacheck | |
| run: mise run check | |
| - name: Run tests | |
| run: mise run test | |
| - name: Check formatting | |
| run: mise run format-check | |
| - name: Generate coverage report | |
| run: | | |
| if [ -f "luacov.stats.out" ]; then | |
| ./.luarocks/bin/luacov | |
| echo "Creating lcov.info from luacov.report.out" | |
| { | |
| echo "TN:" | |
| grep -E "^Summary$" -A1000 luacov.report.out | grep -E "^[^ ].*:" | while read -r line; do | |
| file=$(echo "$line" | cut -d':' -f1) | |
| echo "SF:$file" | |
| percent=$(echo "$line" | grep -oE "[0-9\.]+%" | tr -d '%') | |
| if [ -n "$percent" ]; then | |
| echo "DA:1,1" | |
| echo "LF:1" | |
| echo "LH:$percent" | |
| fi | |
| echo "end_of_record" | |
| done | |
| } > lcov.info | |
| { | |
| echo "## π Test Coverage Report" | |
| echo "" | |
| if [ -f "luacov.report.out" ]; then | |
| overall_coverage=$(grep -E "Total.*%" luacov.report.out | grep -oE "[0-9]+\.[0-9]+%" | head -1) | |
| if [ -n "$overall_coverage" ]; then | |
| echo "**Overall Coverage: $overall_coverage**" | |
| echo "" | |
| fi | |
| echo "| File | Coverage |" | |
| echo "|------|----------|" | |
| grep -E "^[^ ].*:" luacov.report.out | while read -r line; do | |
| file=$(echo "$line" | cut -d':' -f1) | |
| percent=$(echo "$line" | grep -oE "[0-9]+\.[0-9]+%" | head -1) | |
| if [ -n "$percent" ]; then | |
| # Add emoji based on coverage level | |
| percent_num="${percent%.*}" | |
| if [ "$percent_num" -ge 90 ]; then | |
| emoji="π’" | |
| elif [ "$percent_num" -ge 70 ]; then | |
| emoji="π‘" | |
| else | |
| emoji="π΄" | |
| fi | |
| echo "| \`$file\` | $emoji $percent |" | |
| fi | |
| done | |
| else | |
| echo "β No coverage report generated" | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| else | |
| { | |
| echo "## π Test Coverage Report" | |
| echo "" | |
| echo "β No coverage data found - tests may not have run with coverage enabled" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| integration-tests: | |
| runs-on: ubuntu-latest | |
| needs: unit-tests | |
| strategy: | |
| matrix: | |
| neovim-version: ["stable"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| # Neovim here comes from action-setup-vim (matrix-driven), independent of | |
| # the mise.toml neovim pin used for local dev. | |
| - name: Setup Neovim | |
| uses: rhysd/action-setup-vim@8e931b9954b19d4203d5caa5ff5521f3bc21dcc7 # v1.4.2 | |
| with: | |
| neovim: true | |
| version: ${{ matrix.neovim-version }} | |
| - name: Install test dependencies | |
| run: | | |
| git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim | |
| ln -s "$(pwd)" ~/.local/share/nvim/site/pack/vendor/start/claudecode.nvim | |
| - name: Run integration tests | |
| run: ./scripts/run_integration_tests_individually.sh | |
| # Real-Neovim regression gate for issue #238 (reject-with-:q). The unit spec | |
| # only exercises the WinClosed handler logic against a mock; this drives a | |
| # genuine `:q` and self-reports via cquit (exit 0 = fixed, 1 = regressed). | |
| - name: Reject-on-quit regression gate (#238) | |
| run: nvim --headless -u NONE -l scripts/repro_issue_238.lua | |
| required: | |
| name: Required | |
| runs-on: ubuntu-latest | |
| needs: | |
| - unit-tests | |
| - integration-tests | |
| if: ${{ always() }} | |
| steps: | |
| - name: Check required jobs | |
| env: | |
| UNIT_TESTS_RESULT: ${{ needs.unit-tests.result }} | |
| INTEGRATION_TESTS_RESULT: ${{ needs.integration-tests.result }} | |
| run: | | |
| echo "unit-tests: $UNIT_TESTS_RESULT" | |
| echo "integration-tests: $INTEGRATION_TESTS_RESULT" | |
| if [ "$UNIT_TESTS_RESULT" != "success" ] || [ "$INTEGRATION_TESTS_RESULT" != "success" ]; then | |
| echo "One or more required jobs failed." | |
| exit 1 | |
| fi |