Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
name: Test on Neovim ${{ matrix.neovim }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
neovim: ['v0.9.5', 'v0.10.0', 'stable', 'nightly']

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Neovim
uses: rhysd/action-setup-vim@v1
with:
neovim: true
version: ${{ matrix.neovim }}

- name: Run tests
run: |
nvim --version
nvim --headless -u tests/minimal_init.lua -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal_init.lua'}"

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check formatting with stylua
uses: JohnnyMorganz/stylua-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
args: --check lua/ tests/
6 changes: 6 additions & 0 deletions stylua.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
column_width = 120
line_endings = "Unix"
indent_type = "Tabs"
indent_width = 4
quote_style = "AutoPreferDouble"
call_parentheses = "Always"
98 changes: 43 additions & 55 deletions tests/auto_activate_venv_spec.lua
Original file line number Diff line number Diff line change
@@ -1,63 +1,51 @@
-- Tests for granular auto_activate_venv setting
-- Run with: nvim --headless -u tests/minimal_init.lua -c "luafile tests/auto_activate_venv_spec.lua" -c "qa!"

local uv = require("uv")

local function assert_eq(expected, actual, message)
if expected ~= actual then
error(string.format("%s: expected %s, got %s", message or "Assertion failed", vim.inspect(expected), vim.inspect(actual)))
end
print(string.format("PASS: %s", message or "assertion"))
end

local function reset_state()
vim.g.uv_auto_activate_venv = nil
vim.b.uv_auto_activate_venv = nil
uv.config.auto_activate_venv = true
end

print("\n=== Testing auto_activate_venv setting ===\n")

-- Test 1: is_auto_activate_enabled() respects global vim variable
print("Test 1: Global vim variable")
reset_state()
uv.setup({ auto_activate_venv = true })
assert_eq(true, uv.is_auto_activate_enabled(), "Default from config")

vim.g.uv_auto_activate_venv = false
assert_eq(false, uv.is_auto_activate_enabled(), "Global set to false")
reset_state()

-- Test 2: Buffer-local takes precedence over global
print("\nTest 2: Buffer-local precedence")
reset_state()
vim.g.uv_auto_activate_venv = true
vim.b.uv_auto_activate_venv = false
assert_eq(false, uv.is_auto_activate_enabled(), "Buffer false overrides global true")
reset_state()

-- Test 3: toggle_auto_activate_venv() works
print("\nTest 3: Toggle function")
reset_state()
uv.setup({ auto_activate_venv = true })
assert_eq(true, uv.is_auto_activate_enabled(), "Initial true")

uv.toggle_auto_activate_venv()
assert_eq(false, uv.is_auto_activate_enabled(), "After toggle: false")

uv.toggle_auto_activate_venv()
assert_eq(true, uv.is_auto_activate_enabled(), "After second toggle: true")
reset_state()

-- Test 4: Buffer-local toggle
print("\nTest 4: Buffer-local toggle")
reset_state()
vim.g.uv_auto_activate_venv = true

uv.toggle_auto_activate_venv(true)
assert_eq(false, uv.is_auto_activate_enabled(), "Buffer toggle to false")
assert_eq(false, vim.b.uv_auto_activate_venv, "Buffer var is false")
assert_eq(true, vim.g.uv_auto_activate_venv, "Global unchanged")
reset_state()

print("\n=== All tests passed! ===\n")
describe("auto_activate_venv setting", function()
after_each(function()
reset_state()
end)

it("respects global vim variable", function()
reset_state()
uv.setup({ auto_activate_venv = true })
assert.is_true(uv.is_auto_activate_enabled())

vim.g.uv_auto_activate_venv = false
assert.is_false(uv.is_auto_activate_enabled())
end)

it("buffer-local takes precedence over global", function()
reset_state()
vim.g.uv_auto_activate_venv = true
vim.b.uv_auto_activate_venv = false
assert.is_false(uv.is_auto_activate_enabled())
end)

it("toggle_auto_activate_venv works", function()
reset_state()
uv.setup({ auto_activate_venv = true })
assert.is_true(uv.is_auto_activate_enabled())

uv.toggle_auto_activate_venv()
assert.is_false(uv.is_auto_activate_enabled())

uv.toggle_auto_activate_venv()
assert.is_true(uv.is_auto_activate_enabled())
end)

it("buffer-local toggle works", function()
reset_state()
vim.g.uv_auto_activate_venv = true

uv.toggle_auto_activate_venv(true)
assert.is_false(uv.is_auto_activate_enabled())
assert.is_false(vim.b.uv_auto_activate_venv)
assert.is_true(vim.g.uv_auto_activate_venv)
end)
end)
15 changes: 10 additions & 5 deletions tests/minimal_init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
-- Minimal init for running tests
-- Add the plugin to the runtime path
vim.opt.rtp:prepend(".")
-- Minimal init.lua for running plenary tests
vim.opt.runtimepath:prepend(vim.fn.getcwd())

-- Load the plugin
require("uv")
local plenary_path = vim.fn.stdpath("data") .. "/site/pack/test/start/plenary.nvim"
if vim.fn.isdirectory(plenary_path) == 0 then
vim.fn.system({ "git", "clone", "https://github.com/nvim-lua/plenary.nvim", plenary_path })
end
vim.opt.runtimepath:append(plenary_path)

vim.g.mapleader = " "
vim.opt.swapfile = false
69 changes: 4 additions & 65 deletions tests/remove_package_spec.lua
Original file line number Diff line number Diff line change
@@ -1,79 +1,18 @@
-- Tests for remove_package function (PR #21)
-- Run with: nvim --headless -u NONE -c "lua dofile('tests/remove_package_spec.lua')" -c "qa!"

-- Tests the public contract only - no mocking internals

assert(vim and vim.fn, "This test must be run in Neovim")

-- Minimal test framework
local tests_passed = 0
local tests_failed = 0

local function describe(name, fn)
print("\n=== " .. name .. " ===")
fn()
end

local function it(name, fn)
local ok, err = pcall(fn)
if ok then
tests_passed = tests_passed + 1
print(" ✓ " .. name)
else
tests_failed = tests_failed + 1
print(" ✗ " .. name)
print(" Error: " .. tostring(err))
end
end

local function assert_equal(expected, actual, msg)
if expected ~= actual then
error((msg or "Assertion failed") .. ": expected " .. tostring(expected) .. ", got " .. tostring(actual))
end
end

local function assert_true(value, msg)
if not value then
error((msg or "Assertion failed") .. ": expected true, got " .. tostring(value))
end
end

-- Load the module
package.path = package.path .. ";./lua/?.lua;./lua/?/init.lua"
local uv = require("uv")

describe("remove_package()", function()
it("should be exported as a function", function()
assert_equal("function", type(uv.remove_package), "remove_package should be a function")
end)
end)

describe("keymap setup", function()
it("should set up 'd' keymap for remove package when keymaps enabled", function()
describe("remove_package", function()
it("sets up keymap when enabled", function()
uv.setup({ keymaps = { prefix = "<leader>u", remove_package = true } })

local keymaps = vim.api.nvim_get_keymap("n")
local found = false
for _, km in ipairs(keymaps) do
-- Check for keymap ending in 'd' with UV Remove Package description
if km.desc == "UV Remove Package" then
found = true
assert_true(
km.rhs:match("remove_package") or km.callback ~= nil,
"keymap should invoke remove_package"
)
assert.is_truthy(km.rhs:match("remove_package") or km.callback)
break
end
end
assert_true(found, "should have remove_package keymap defined")
assert.is_true(found, "should have remove_package keymap defined")
end)
end)

-- Print summary
print("\n" .. string.rep("=", 40))
print(string.format("Tests: %d passed, %d failed", tests_passed, tests_failed))
print(string.rep("=", 40))

if tests_failed > 0 then
os.exit(1)
end
Loading