Asynchronous function testing without any callback #2126
-
Contributing guidelines
Module(s)mini.test QuestionHi there! I already check the other discussion but wasn't fully understand. I am kind of new to neovim plugin testing. Currently I have a basic testing setup for my plugin because most of the time i was testing synchronous functions. Now i move to asynchronous equivalent of what i have before, so the previous strategy will no longer be applicable for new functions. Here is one of the many asynchronous functions that i have: ---@param path string
---@param callback function
function commands.touch(path, callback)
assert(path, "path is not provided")
local _path = Path.new(path)
vim.uv.fs_open(_path:normalize(), "a", 420, function(err_open, fd)
if err_open or not fd then
return callback(err_open or "Failed to open file")
end
vim.uv.fs_close(fd, function(err_close)
callback(err_close)
end)
end)
endCan you provide me an example to test this callback based function. One more query which is how to write tests for non-callback based asynchronous functions which means completion cannot be defined. If you need more context then here is the repository link |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
|
The answer is indeed the same as in this comment: I usually go with "call the function in child process; wait small amount of time, validate that it succeeded". I emphasized "in child process" because this test doesn't look like it does it. It is not necessary for this question, but it is strongly suggested to do for a robust testing. So here it might be something like: T["touch"] = function()
local exists_before = child.lua([[
-- Note, that these are not local, to persist across `child.lua` calls
-- I'd do this in `pre_case` hook
Path = require "fyler.lib.path"
fs = require "fyler.lib.fs"
-- Make sure that `FYLER_TESTING_DIR_DATA` is assigned *in child process*
_G.path = Path.new(FYLER_TESTING_DIR_DATA):join "foobar.txt"
local exists_before = path:exists()
fs.touch(path:normalize())
return exists_before
]])
test.expect.equality(exists_before, false)
-- Wait small time for async function to finish
vim.uv.sleep(5)
test.expect.equality(child.lua_get('_G.path:exists()'), true)
end |
Beta Was this translation helpful? Give feedback.
-
|
@echasnovski thanks |
Beta Was this translation helpful? Give feedback.
-
|
@echasnovski One more help, If this work then I can handle the rest by myself. Here is the util.lua local MiniTest = require "mini.test"
local M = {}
function M.new_child_neovim()
local child = MiniTest.new_child_neovim()
child.setup = function()
child.restart { "-u", "tests/minit.lua" }
child.bo.readonly = true
end
child.load = function(name, config)
child.lua(([[require('%s').setup(...)]]):format(name), { config })
end
return child
end
return Mand here is the test_finder.lua local MiniTest = require "mini.test"
local util = require "tests.util"
local T = MiniTest.new_set {}
local child = util.new_child_neovim()
local temp = vim.env.FYLER_TEMP_DIR or vim.fs.joinpath(vim.uv.cwd(), ".temp")
local data = vim.fs.joinpath(temp, "data")
T["open"] = MiniTest.new_set {
hooks = {
pre_case = function()
child.setup()
child.load "fyler"
end,
post_case = function()
vim.fn.mkdir(data)
vim.uv.fs_close(assert(vim.uv.fs_open(vim.fs.joinpath(data, "foobar.txt"), "a", 420)))
end,
post_once = function()
child.stop()
vim.fn.delete(data, "rf")
end,
},
}
T["open"]["without args"] = function()
child.lua [[ require('fyler').open() ]]
vim.uv.sleep(5)
vim.print(child.lua_get "vim.api.nvim_buf_get_lines(0, 0, -1, false)")
end
return TAm i doing something wrong because Here |
Beta Was this translation helpful? Give feedback.
The answer is indeed the same as in this comment: I usually go with "call the function in child process; wait small amount of time, validate that it succeeded". I emphasized "in child process" because this test doesn't look like it does it. It is not necessary for this question, but it is strongly suggested to do for a robust testing.
So here it might be something like: