diff --git a/lua/orgmode/utils/init.lua b/lua/orgmode/utils/init.lua index 321444cc4..443f59340 100644 --- a/lua/orgmode/utils/init.lua +++ b/lua/orgmode/utils/init.lua @@ -55,10 +55,12 @@ end ---@param file string ---@param data string|string[] +---@param opts? {excl?: boolean} ---@return OrgPromise bytes -function utils.writefile(file, data) +function utils.writefile(file, data, opts) return Promise.new(function(resolve, reject) - uv.fs_open(file, 'w', 438, function(err1, fd) + local flags = opts and opts.excl and 'wx' or 'w' + uv.fs_open(file, flags, 438, function(err1, fd) if err1 then return reject(err1) end diff --git a/tests/plenary/org/fold_spec.lua b/tests/plenary/org/fold_spec.lua new file mode 100644 index 000000000..6f28f9e6c --- /dev/null +++ b/tests/plenary/org/fold_spec.lua @@ -0,0 +1,17 @@ +local helpers = require('tests.plenary.helpers') + +describe('folding', function() + it('works', function() + helpers.create_file({ + '* First', + '** Second', + '*** Third', + '**** Fourth', + '***** Fifth', + 'text', + }) + vim.cmd.normal({ 'GzM', bang = true }) + local foldlevel = vim.fn.foldlevel(6) + assert.are.same(5, foldlevel) + end) +end) diff --git a/tests/plenary/utils_spec.lua b/tests/plenary/utils_spec.lua index b969eb23b..0e5afce3f 100644 --- a/tests/plenary/utils_spec.lua +++ b/tests/plenary/utils_spec.lua @@ -38,4 +38,101 @@ describe('Util', function() end) end) end) + + describe('readfile', function() + ---@type OrgFile + local file + before_each(function() + if not file then + file = helpers.create_file({ + 'First line', + '', + '* Headline', + 'Contents', + }) + end + end) + + it('returns lines', function() + local contents = utils.readfile(file.filename):wait() + assert.are.same(contents, { + 'First line', + '', + '* Headline', + 'Contents', + }) + end) + + it('returns raw contents', function() + local contents = utils.readfile(file.filename, { raw = true }):wait() + assert.are.equal(contents, 'First line\n\n* Headline\nContents\n') + end) + + it('schedules its results for later', function() + utils + .readfile(file.filename, { schedule = true }) + :next(function(contents) + -- Without `schedule = true`, this line would run inside `fast-api` + -- and thus fail. + vim.fn.setreg('', contents) + end) + :wait() + local contents = vim.fn.getreg('') + assert.are.equal(contents, 'First line\n\n* Headline\nContents\n') + end) + end) + + describe('writefile', function() + ---@type string + local filename + before_each(function() + if not filename then + filename = vim.fn.tempname() + end + end) + + local contents = { + 'First line', + '', + '* Headline', + 'Contents', + } + + it('writes bare strings', function() + local bytes = utils.writefile(filename, table.concat(contents, '\n')):wait() + assert.are.equal(bytes, 31) + local reread = vim.fn.readfile(filename) + assert.are.same(reread, contents) + end) + + it('writes lists of strings by concatenation', function() + local bytes = utils.writefile(filename, contents):wait() + assert.are.equal(bytes, 28) + local reread = vim.fn.readfile(filename) + assert.are.same(reread, { 'First line* HeadlineContents' }) + end) + + it('does not schedule its results', function() + local promise = utils.writefile(filename, contents):next(function(bytes) + return vim.fn.setreg('', bytes) + end) + ---@type boolean, string? + local ok, err = pcall(promise.wait, promise) + assert.is.False(ok) + assert(err) + local expected = 'E5560: Vimscript function must not be called in a lua loop callback' + local msg = err:sub(#err - #expected) + assert.are.equal(expected, msg) + end) + + it('allows no-clobber writes', function() + local promise = utils.writefile(filename, contents, { excl = true }) + ---@type boolean, string? + local ok, err = pcall(promise.wait, promise) + assert.is.False(ok) + assert(err) + local expected = 'EEXIST: file already exists: ' .. filename + assert.are.equal(expected, err) + end) + end) end)