telescope-frecency.nvim/lua/frecency/tests/file_lock_spec.lua
JINNOUCHI Yasushi 58c0089414
fix!: register realpath for consistency (#240)
Now it uses realpath for registering and validating DB. This means, if you have entries that has filenames differing only for case, it can deal with them as they exist.

Before this, it has miscalculated scores for such cases. For example, in case you have `/path/to/foo.lua` and `/path/to/Foo.lua`, it registers entries for each file. Now it detects accurate filename for the specified one, and removes it in validation.

* test: separate logic for utils

* fix!: register realpath for consistency

* refactor: convert fs module from class

* refactor: move db initialization phase to start()

* fix: run database:start() truly asynchronously

* fix: call each functions with async wrapping

* refactor: add types for args in command

* fix: run register() synchronously

Because vim.api.nvim_* cannot be used in asynchronous functions.

* docs: add note for calling setup() twice

* fix: run non-fast logic on next tick
2024-08-15 17:40:03 +09:00

170 lines
4.9 KiB
Lua

---@diagnostic disable: undefined-field
local config = require "frecency.config"
local FileLock = require "frecency.file_lock"
local util = require "frecency.tests.util"
local async = require "plenary.async" --[[@as FrecencyPlenaryAsync]]
require("plenary.async").tests.add_to_env()
config.setup { debug = true }
local function with_dir(f)
local dir, close = util.make_tree {}
local filename = (dir / "file_lock_test").filename
f(filename)
close()
end
local function with_unlink_fails(f)
return function()
local original = async.uv.fs_unlink
---@diagnostic disable-next-line: duplicate-set-field
async.uv.fs_unlink = function()
return "overwritten"
end
f()
async.uv.fs_unlink = original
end
end
a.describe("file_lock", function()
a.describe("get()", function()
a.describe("when no lock file", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("gets successfully", function()
assert.is.Nil(fl:get())
end)
end)
end)
a.describe("when with a lock file", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("gets successfully", function()
local err, fd = async.uv.fs_open(fl.lock, "wx", tonumber("600", 8))
assert.is.Nil(err)
assert.is.Nil(async.uv.fs_close(fd))
assert.is.Nil(fl:get())
end)
end)
end)
a.describe("when getting twice", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("gets successfully", function()
assert.is.Nil(fl:get())
assert.is.Nil(fl:get())
end)
end)
end)
a.describe("when getting twice but unlink fails", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it(
"fails to get",
with_unlink_fails(function()
assert.is.Nil(fl:get())
assert.are.same("failed to get lock", fl:get())
end)
)
end)
end)
end)
a.describe("release()", function()
a.describe("when no lock file", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("fails to release", function()
assert.are.same("lock not found", fl:release())
end)
end)
end)
a.describe("when with a lock file", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("releases successfully", function()
assert.is.Nil(fl:get())
assert.is.Nil(fl:release())
end)
end)
end)
a.describe("when releasing twice", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("fails to release", function()
assert.is.Nil(fl:get())
assert.is.Nil(fl:release())
assert.are.same("lock not found", fl:release())
end)
end)
end)
end)
a.describe("with()", function()
a.describe("when get() fails", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it(
"fails with a valid err",
with_unlink_fails(function()
assert.is.Nil(fl:get())
assert.are.same(
"failed to get lock",
fl:with(function()
return nil
end)
)
end)
)
end)
end)
a.describe("when release() fails", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("fails with a valid err", function()
assert.are.same(
"lock not found",
fl:with(function()
assert.is.Nil(async.uv.fs_unlink(fl.lock))
return nil
end)
)
end)
end)
end)
a.describe("when f() fails", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("fails with a valid err", function()
assert.has.match(
": error in hoge function$",
fl:with(function()
error "error in hoge function"
end)
)
end)
end)
end)
a.describe("when no errors", function()
with_dir(function(filename)
local fl = FileLock.new(filename, { retry = 1, interval = 10 })
a.it("run successfully and returns valid results", function()
local err, result = fl:with(function()
return "hogehogeo"
end)
assert.is.Nil(err)
assert.are.same("hogehogeo", result)
end)
end)
end)
end)
end)