mirror of
https://github.com/kristoferssolo/telescope-frecency.nvim.git
synced 2025-10-21 20:10:38 +00:00
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
326 lines
13 KiB
Lua
326 lines
13 KiB
Lua
-- HACK: This is needed because plenary.test_harness resets &rtp.
|
|
-- https://github.com/nvim-lua/plenary.nvim/blob/663246936325062427597964d81d30eaa42ab1e4/lua/plenary/test_harness.lua#L86-L86
|
|
vim.opt.runtimepath:append(vim.env.TELESCOPE_PATH)
|
|
|
|
local util = require "frecency.tests.util"
|
|
local log = require "plenary.log"
|
|
|
|
local filepath = util.filepath
|
|
local make_epoch = util.make_epoch
|
|
local make_register = util.make_register
|
|
local with_fake_register = util.with_fake_register
|
|
local with_files = util.with_files
|
|
|
|
describe("frecency", function()
|
|
describe("register", function()
|
|
describe("when opening files", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt" }, function(frecency, finder, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch1 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch2 = make_epoch "2023-07-29T01:00:00+09:00"
|
|
-- HACK: This suspicious 'swapfile' setting is for avoiding E303.
|
|
vim.o.swapfile = false
|
|
register("hoge1.txt", epoch1)
|
|
vim.o.swapfile = true
|
|
register("hoge2.txt", epoch2)
|
|
|
|
it("has valid records in DB", function()
|
|
local results = finder:get_results(nil, make_epoch "2023-07-29T02:00:00+09:00")
|
|
assert.are.same({
|
|
{ count = 1, path = filepath(dir, "hoge2.txt"), score = 10, timestamps = { epoch2 } },
|
|
{ count = 1, path = filepath(dir, "hoge1.txt"), score = 10, timestamps = { epoch1 } },
|
|
}, results)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("when opening again", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt" }, function(frecency, finder, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch11 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch2 = make_epoch "2023-07-29T01:00:00+09:00"
|
|
local epoch12 = make_epoch "2023-07-29T02:00:00+09:00"
|
|
register("hoge1.txt", epoch11)
|
|
register("hoge2.txt", epoch2)
|
|
register("hoge1.txt", epoch12, true)
|
|
|
|
it("increases the score", function()
|
|
local results = finder:get_results(nil, make_epoch "2023-07-29T03:00:00+09:00")
|
|
assert.are.same({
|
|
{ count = 2, path = filepath(dir, "hoge1.txt"), score = 40, timestamps = { epoch11, epoch12 } },
|
|
{ count = 1, path = filepath(dir, "hoge2.txt"), score = 10, timestamps = { epoch2 } },
|
|
}, results)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("when opening again but the same instance", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt" }, function(frecency, finder, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch11 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch2 = make_epoch "2023-07-29T01:00:00+09:00"
|
|
local epoch12 = make_epoch "2023-07-29T02:00:00+09:00"
|
|
register("hoge1.txt", epoch11)
|
|
register("hoge2.txt", epoch2)
|
|
register("hoge1.txt", epoch12)
|
|
|
|
it("does not increase the score", function()
|
|
local results = finder:get_results(nil, make_epoch "2023-07-29T03:00:00+09:00")
|
|
assert.are.same({
|
|
{ count = 1, path = filepath(dir, "hoge2.txt"), score = 10, timestamps = { epoch2 } },
|
|
{ count = 1, path = filepath(dir, "hoge1.txt"), score = 10, timestamps = { epoch11 } },
|
|
}, results)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("when opening more than 10 times", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt" }, function(frecency, finder, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch11 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch12 = make_epoch "2023-07-29T00:01:00+09:00"
|
|
register("hoge1.txt", epoch11)
|
|
register("hoge1.txt", epoch12, true)
|
|
|
|
local epoch201 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch202 = make_epoch "2023-07-29T00:01:00+09:00"
|
|
local epoch203 = make_epoch "2023-07-29T00:02:00+09:00"
|
|
local epoch204 = make_epoch "2023-07-29T00:03:00+09:00"
|
|
local epoch205 = make_epoch "2023-07-29T00:04:00+09:00"
|
|
local epoch206 = make_epoch "2023-07-29T00:05:00+09:00"
|
|
local epoch207 = make_epoch "2023-07-29T00:06:00+09:00"
|
|
local epoch208 = make_epoch "2023-07-29T00:07:00+09:00"
|
|
local epoch209 = make_epoch "2023-07-29T00:08:00+09:00"
|
|
local epoch210 = make_epoch "2023-07-29T00:09:00+09:00"
|
|
local epoch211 = make_epoch "2023-07-29T00:10:00+09:00"
|
|
local epoch212 = make_epoch "2023-07-29T00:11:00+09:00"
|
|
register("hoge2.txt", epoch201)
|
|
register("hoge2.txt", epoch202, true)
|
|
register("hoge2.txt", epoch203, true)
|
|
register("hoge2.txt", epoch204, true)
|
|
register("hoge2.txt", epoch205, true)
|
|
register("hoge2.txt", epoch206, true)
|
|
register("hoge2.txt", epoch207, true)
|
|
register("hoge2.txt", epoch208, true)
|
|
register("hoge2.txt", epoch209, true)
|
|
register("hoge2.txt", epoch210, true)
|
|
register("hoge2.txt", epoch211, true)
|
|
register("hoge2.txt", epoch212, true)
|
|
|
|
it("calculates score from the recent 10 times", function()
|
|
local results = finder:get_results(nil, make_epoch "2023-07-29T00:12:00+09:00")
|
|
assert.are.same({
|
|
{
|
|
count = 12,
|
|
path = filepath(dir, "hoge2.txt"),
|
|
score = 12 * (10 * 100) / 10,
|
|
timestamps = {
|
|
epoch203,
|
|
epoch204,
|
|
epoch205,
|
|
epoch206,
|
|
epoch207,
|
|
epoch208,
|
|
epoch209,
|
|
epoch210,
|
|
epoch211,
|
|
epoch212,
|
|
},
|
|
},
|
|
{
|
|
count = 2,
|
|
path = filepath(dir, "hoge1.txt"),
|
|
score = 2 * (2 * 100) / 10,
|
|
timestamps = { epoch11, epoch12 },
|
|
},
|
|
}, results)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("when ignore_register is set", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt" }, {
|
|
ignore_register = function(bufnr)
|
|
local _, bufname = pcall(vim.api.nvim_buf_get_name, bufnr)
|
|
local should_ignore = not not (bufname and bufname:find "hoge2%.txt$")
|
|
log.debug { bufnr = bufnr, bufname = bufname, should_ignore = should_ignore }
|
|
return should_ignore
|
|
end,
|
|
}, function(frecency, finder, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch1 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
register("hoge1.txt", epoch1)
|
|
local epoch2 = make_epoch "2023-07-29T01:00:00+09:00"
|
|
register("hoge2.txt", epoch2)
|
|
it("ignores the file the func returns true", function()
|
|
local results = finder:get_results(nil, make_epoch "2023-07-29T02:00:00+09:00")
|
|
assert.are.same({
|
|
{ count = 1, path = filepath(dir, "hoge1.txt"), score = 10, timestamps = { epoch1 } },
|
|
}, results)
|
|
end)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("benchmark", function()
|
|
describe("after registered over >5000 files", function()
|
|
with_files({}, function(frecency, finder, dir)
|
|
with_fake_register(frecency, dir, function(register)
|
|
-- TODO: 6000 records is too many to use with native?
|
|
-- local file_count = 6000
|
|
local file_count = 600
|
|
if not os.getenv "CI" then
|
|
log.info "It works not on CI. Files is decreased into 10 count."
|
|
file_count = 10
|
|
end
|
|
local expected = {}
|
|
log.info(("making %d files and register them"):format(file_count))
|
|
for i = 1, file_count do
|
|
local file = ("hoge%08d.txt"):format(i)
|
|
table.insert(expected, { count = 1, path = filepath(dir, file), score = 10 })
|
|
-- HACK: disable log because it fails with too many logging
|
|
log.new({ level = "info" }, true)
|
|
register(file, make_epoch "2023-07-29T00:00:00+09:00")
|
|
log.new({}, true)
|
|
end
|
|
local start = os.clock()
|
|
local results = vim.tbl_map(function(result)
|
|
result.timestamps = nil
|
|
return result
|
|
end, finder:get_results(nil, make_epoch "2023-07-29T00:01:00+09:00"))
|
|
table.sort(results, function(a, b)
|
|
return a.path < b.path
|
|
end)
|
|
local elapsed = os.clock() - start
|
|
log.info(("it takes %f seconds in fetching all results"):format(elapsed))
|
|
|
|
it("returns appropriate latency (<1.0 second)", function()
|
|
assert.are.is_true(elapsed < 1.0)
|
|
end)
|
|
|
|
it("returns valid response", function()
|
|
assert.are.same(expected, results)
|
|
end)
|
|
end)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("delete", function()
|
|
describe("when file exists", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt" }, function(frecency, finder, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch1 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch2 = make_epoch "2023-07-29T00:01:00+09:00"
|
|
register("hoge1.txt", epoch1)
|
|
register("hoge2.txt", epoch2)
|
|
|
|
it("deletes the file successfully", function()
|
|
local path = filepath(dir, "hoge2.txt")
|
|
local result
|
|
---@diagnostic disable-next-line: duplicate-set-field, invisible
|
|
frecency.notify = function(self, fmt, ...)
|
|
---@diagnostic disable-next-line: invisible
|
|
vim.notify(self:message(fmt, ...))
|
|
result = true
|
|
end
|
|
frecency:delete(path)
|
|
assert.are.same(result, true)
|
|
end)
|
|
|
|
it("returns valid results", function()
|
|
local results = finder:get_results(nil, make_epoch "2023-07-29T02:00:00+09:00")
|
|
assert.are.same({
|
|
{ count = 1, path = filepath(dir, "hoge1.txt"), score = 10, timestamps = { epoch1 } },
|
|
}, results)
|
|
end)
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe("query", function()
|
|
with_files({ "hoge1.txt", "hoge2.txt", "hoge3.txt", "hoge4.txt" }, function(frecency, _, dir)
|
|
local register = make_register(frecency, dir)
|
|
local epoch11 = make_epoch "2023-07-29T00:00:00+09:00"
|
|
local epoch2 = make_epoch "2023-07-29T00:01:00+09:00"
|
|
local epoch12 = make_epoch "2023-07-29T00:02:00+09:00"
|
|
local epoch31 = make_epoch "2023-07-29T00:03:00+09:00"
|
|
local epoch13 = make_epoch "2023-07-29T00:04:00+09:00"
|
|
local epoch32 = make_epoch "2023-07-29T00:05:00+09:00"
|
|
local epoch4 = make_epoch "2023-07-29T00:06:00+09:00"
|
|
register("hoge1.txt", epoch11)
|
|
register("hoge2.txt", epoch2)
|
|
register("hoge1.txt", epoch12, true)
|
|
register("hoge3.txt", epoch31)
|
|
register("hoge1.txt", epoch13, true)
|
|
register("hoge3.txt", epoch32, true)
|
|
register("hoge4.txt", epoch4)
|
|
|
|
for _, c in ipairs {
|
|
{
|
|
desc = "with no opts",
|
|
opts = nil,
|
|
results = {
|
|
filepath(dir, "hoge1.txt"),
|
|
filepath(dir, "hoge3.txt"),
|
|
filepath(dir, "hoge2.txt"),
|
|
filepath(dir, "hoge4.txt"),
|
|
},
|
|
},
|
|
{
|
|
desc = "with an empty opts",
|
|
opts = {},
|
|
results = {
|
|
filepath(dir, "hoge1.txt"),
|
|
filepath(dir, "hoge3.txt"),
|
|
filepath(dir, "hoge2.txt"),
|
|
filepath(dir, "hoge4.txt"),
|
|
},
|
|
},
|
|
{
|
|
desc = "with limit",
|
|
opts = { limit = 3 },
|
|
results = {
|
|
filepath(dir, "hoge1.txt"),
|
|
filepath(dir, "hoge3.txt"),
|
|
filepath(dir, "hoge2.txt"),
|
|
},
|
|
},
|
|
{
|
|
desc = "with limit, direction",
|
|
opts = { direction = "asc", limit = 3 },
|
|
results = {
|
|
filepath(dir, "hoge2.txt"),
|
|
filepath(dir, "hoge4.txt"),
|
|
filepath(dir, "hoge3.txt"),
|
|
},
|
|
},
|
|
{
|
|
desc = "with limit, direction, order",
|
|
opts = { direction = "asc", limit = 3, order = "path" },
|
|
results = {
|
|
filepath(dir, "hoge1.txt"),
|
|
filepath(dir, "hoge2.txt"),
|
|
filepath(dir, "hoge3.txt"),
|
|
},
|
|
},
|
|
{
|
|
desc = "with limit, direction, order, record",
|
|
opts = { direction = "asc", limit = 3, order = "path", record = true },
|
|
results = {
|
|
{ count = 3, path = filepath(dir, "hoge1.txt"), score = 90, timestamps = { epoch11, epoch12, epoch13 } },
|
|
{ count = 1, path = filepath(dir, "hoge2.txt"), score = 10, timestamps = { epoch2 } },
|
|
{ count = 2, path = filepath(dir, "hoge3.txt"), score = 40, timestamps = { epoch31, epoch32 } },
|
|
},
|
|
},
|
|
} do
|
|
describe(c.desc, function()
|
|
it("returns valid results", function()
|
|
assert.are.same(c.results, frecency:query(c.opts, make_epoch "2023-07-29T04:00:00+09:00"))
|
|
end)
|
|
end)
|
|
end
|
|
end)
|
|
end)
|
|
end)
|