local pack = require("pack") local t = require("test") ---Build a fake plugin tree under a temp dir. `files` maps module names ---(e.g. "foo", "foo.bar") to a string body — the file path is derived by ---swapping `.` for `/` and adding `.lua`. Cleanup is queued so the dir ---is removed after the current test. ---@param files table ---@return string plugin_path local function fake_plugin(files) local dir = vim.fn.tempname() vim.fn.mkdir(dir, "p") for module, body in pairs(files) do local rel = module:gsub("%.", "/") .. ".lua" t.write(dir, "lua/" .. rel, body) end t.defer(function() vim.fn.delete(dir, "rf") end) return dir end ---Pre-populate `package.loaded` and queue cleanup so the entry doesn't ---leak across tests. local function preload(name) package.loaded[name] = { _marker = name } t.defer(function() package.loaded[name] = nil end) end t.test("unload clears top-level module", function() local dir = fake_plugin({ foo = "return {}" }) preload("foo") pack.unload(dir) t.eq(package.loaded.foo, nil, "foo should be uncached") end) t.test("unload clears submodules via dotted names", function() local dir = fake_plugin({ foo = "return {}", ["foo.bar"] = "return {}", ["foo.baz.qux"] = "return {}", }) preload("foo") preload("foo.bar") preload("foo.baz.qux") pack.unload(dir) t.eq(package.loaded.foo, nil, "foo cleared") t.eq(package.loaded["foo.bar"], nil, "foo.bar cleared") t.eq(package.loaded["foo.baz.qux"], nil, "foo.baz.qux cleared") end) t.test("unload leaves unrelated modules untouched", function() local dir = fake_plugin({ foo = "return {}" }) preload("foo") preload("unrelated") preload("foo_neighbor") pack.unload(dir) t.eq(package.loaded.foo, nil, "foo cleared") t.truthy(package.loaded.unrelated, "unrelated kept") t.truthy(package.loaded.foo_neighbor, "foo_neighbor kept") end) t.test("unload handles init.lua submodules", function() local dir = fake_plugin({ ["pkg.init"] = "return {}" }) preload("pkg") pack.unload(dir) t.eq(package.loaded.pkg, nil, "pkg cleared via init.lua") end) t.test("unload on non-existent path is a no-op", function() preload("foo") pack.unload("/nonexistent/path/to/nowhere") t.truthy(package.loaded.foo, "foo kept") end)