diff --git a/tests/mutator_spec.lua b/tests/mutator_spec.lua index 55b9c0c..13349e2 100644 --- a/tests/mutator_spec.lua +++ b/tests/mutator_spec.lua @@ -2,259 +2,18 @@ require("plenary.async").tests.add_to_env() local cache = require("oil.cache") local constants = require("oil.constants") local mutator = require("oil.mutator") -local parser = require("oil.mutator.parser") local test_adapter = require("oil.adapters.test") local test_util = require("tests.test_util") -local util = require("oil.util") -local view = require("oil.view") local FIELD_ID = constants.FIELD_ID local FIELD_NAME = constants.FIELD_NAME local FIELD_TYPE = constants.FIELD_TYPE -local FIELD_META = constants.FIELD_META - -local function set_lines(bufnr, lines) - vim.bo[bufnr].modifiable = true - vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines) -end a.describe("mutator", function() after_each(function() - for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do - vim.api.nvim_buf_delete(bufnr, { force = true }) - end - test_adapter.test_clear() - cache.clear_everything() test_util.reset_editor() end) - describe("parser", function() - it("detects new files", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "a.txt", - }) - local diffs = parser.parse(bufnr) - assert.are.same({ { entry_type = "file", name = "a.txt", type = "new" } }, diffs) - end) - - it("detects new directories", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "foo/", - }) - local diffs = parser.parse(bufnr) - assert.are.same({ { entry_type = "directory", name = "foo", type = "new" } }, diffs) - end) - - it("detects new links", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "a.txt -> b.txt", - }) - local diffs = parser.parse(bufnr) - assert.are.same( - { { entry_type = "link", name = "a.txt", type = "new", link = "b.txt" } }, - diffs - ) - end) - - it("detects deleted files", function() - local file = test_adapter.test_set("/foo/a.txt", "file") - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, {}) - local diffs = parser.parse(bufnr) - assert.are.same({ - { name = "a.txt", type = "delete", id = file[FIELD_ID] }, - }, diffs) - end) - - it("detects deleted directories", function() - local dir = test_adapter.test_set("/foo/bar", "directory") - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, {}) - local diffs = parser.parse(bufnr) - assert.are.same({ - { name = "bar", type = "delete", id = dir[FIELD_ID] }, - }, diffs) - end) - - it("detects deleted links", function() - local file = test_adapter.test_set("/foo/a.txt", "link") - file[FIELD_META] = { link = "b.txt" } - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, {}) - local diffs = parser.parse(bufnr) - assert.are.same({ - { name = "a.txt", type = "delete", id = file[FIELD_ID] }, - }, diffs) - end) - - it("ignores empty lines", function() - local file = test_adapter.test_set("/foo/a.txt", "file") - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - local cols = view.format_entry_cols(file, {}, {}, test_adapter) - local lines = util.render_table({ cols }, {}) - table.insert(lines, "") - table.insert(lines, " ") - set_lines(bufnr, lines) - local diffs = parser.parse(bufnr) - assert.are.same({}, diffs) - end) - - it("errors on missing filename", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "/008", - }) - local _, errors = parser.parse(bufnr) - assert.are_same({ - { - message = "Malformed ID at start of line", - lnum = 0, - col = 0, - }, - }, errors) - end) - - it("errors on empty dirname", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "/008 /", - }) - local _, errors = parser.parse(bufnr) - assert.are.same({ - { - message = "No filename found", - lnum = 0, - col = 0, - }, - }, errors) - end) - - it("errors on duplicate names", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "foo", - "foo/", - }) - local _, errors = parser.parse(bufnr) - assert.are.same({ - { - message = "Duplicate filename", - lnum = 1, - col = 0, - }, - }, errors) - end) - - it("errors on duplicate names for existing files", function() - local file = test_adapter.test_set("/foo/a.txt", "file") - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "a.txt", - string.format("/%d a.txt", file[FIELD_ID]), - }) - local _, errors = parser.parse(bufnr) - assert.are.same({ - { - message = "Duplicate filename", - lnum = 1, - col = 0, - }, - }, errors) - end) - - it("ignores new dirs with empty name", function() - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - "/", - }) - local diffs = parser.parse(bufnr) - assert.are.same({}, diffs) - end) - - it("parses a rename as a delete + new", function() - local file = test_adapter.test_set("/foo/a.txt", "file") - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - string.format("/%d b.txt", file[FIELD_ID]), - }) - local diffs = parser.parse(bufnr) - assert.are.same({ - { type = "new", id = file[FIELD_ID], name = "b.txt", entry_type = "file" }, - { type = "delete", id = file[FIELD_ID], name = "a.txt" }, - }, diffs) - end) - - it("detects a new trailing slash as a delete + create", function() - local file = test_adapter.test_set("/foo", "file") - vim.cmd.edit({ args = { "oil-test:///" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - string.format("/%d foo/", file[FIELD_ID]), - }) - local diffs = parser.parse(bufnr) - assert.are.same({ - { type = "new", name = "foo", entry_type = "directory" }, - { type = "delete", id = file[FIELD_ID], name = "foo" }, - }, diffs) - end) - - it("detects renamed files that conflict", function() - local afile = test_adapter.test_set("/foo/a.txt", "file") - local bfile = test_adapter.test_set("/foo/b.txt", "file") - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - string.format("/%d a.txt", bfile[FIELD_ID]), - string.format("/%d b.txt", afile[FIELD_ID]), - }) - local diffs = parser.parse(bufnr) - local first_two = { diffs[1], diffs[2] } - local last_two = { diffs[3], diffs[4] } - table.sort(first_two, function(a, b) - return a.id < b.id - end) - table.sort(last_two, function(a, b) - return a.id < b.id - end) - assert.are.same({ - { name = "b.txt", type = "new", id = afile[FIELD_ID], entry_type = "file" }, - { name = "a.txt", type = "new", id = bfile[FIELD_ID], entry_type = "file" }, - }, first_two) - assert.are.same({ - { name = "a.txt", type = "delete", id = afile[FIELD_ID] }, - { name = "b.txt", type = "delete", id = bfile[FIELD_ID] }, - }, last_two) - end) - - it("views link targets with trailing slashes as the same", function() - local file = test_adapter.test_set("/foo/mydir", "link") - file[FIELD_META] = { link = "dir/" } - vim.cmd.edit({ args = { "oil-test:///foo/" } }) - local bufnr = vim.api.nvim_get_current_buf() - set_lines(bufnr, { - string.format("/%d mydir/ -> dir/", file[FIELD_ID]), - }) - local diffs = parser.parse(bufnr) - assert.are.same({}, diffs) - end) - end) - describe("build actions", function() it("empty diffs produce no actions", function() vim.cmd.edit({ args = { "oil-test:///foo/" } }) diff --git a/tests/parser_spec.lua b/tests/parser_spec.lua new file mode 100644 index 0000000..f3a4262 --- /dev/null +++ b/tests/parser_spec.lua @@ -0,0 +1,245 @@ +require("plenary.async").tests.add_to_env() +local constants = require("oil.constants") +local parser = require("oil.mutator.parser") +local test_adapter = require("oil.adapters.test") +local test_util = require("tests.test_util") +local util = require("oil.util") +local view = require("oil.view") + +local FIELD_ID = constants.FIELD_ID +local FIELD_META = constants.FIELD_META + +local function set_lines(bufnr, lines) + vim.bo[bufnr].modifiable = true + vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, lines) +end + +describe("parser", function() + after_each(function() + test_util.reset_editor() + end) + it("detects new files", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "a.txt", + }) + local diffs = parser.parse(bufnr) + assert.are.same({ { entry_type = "file", name = "a.txt", type = "new" } }, diffs) + end) + + it("detects new directories", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "foo/", + }) + local diffs = parser.parse(bufnr) + assert.are.same({ { entry_type = "directory", name = "foo", type = "new" } }, diffs) + end) + + it("detects new links", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "a.txt -> b.txt", + }) + local diffs = parser.parse(bufnr) + assert.are.same( + { { entry_type = "link", name = "a.txt", type = "new", link = "b.txt" } }, + diffs + ) + end) + + it("detects deleted files", function() + local file = test_adapter.test_set("/foo/a.txt", "file") + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, {}) + local diffs = parser.parse(bufnr) + assert.are.same({ + { name = "a.txt", type = "delete", id = file[FIELD_ID] }, + }, diffs) + end) + + it("detects deleted directories", function() + local dir = test_adapter.test_set("/foo/bar", "directory") + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, {}) + local diffs = parser.parse(bufnr) + assert.are.same({ + { name = "bar", type = "delete", id = dir[FIELD_ID] }, + }, diffs) + end) + + it("detects deleted links", function() + local file = test_adapter.test_set("/foo/a.txt", "link") + file[FIELD_META] = { link = "b.txt" } + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, {}) + local diffs = parser.parse(bufnr) + assert.are.same({ + { name = "a.txt", type = "delete", id = file[FIELD_ID] }, + }, diffs) + end) + + it("ignores empty lines", function() + local file = test_adapter.test_set("/foo/a.txt", "file") + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + local cols = view.format_entry_cols(file, {}, {}, test_adapter) + local lines = util.render_table({ cols }, {}) + table.insert(lines, "") + table.insert(lines, " ") + set_lines(bufnr, lines) + local diffs = parser.parse(bufnr) + assert.are.same({}, diffs) + end) + + it("errors on missing filename", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "/008", + }) + local _, errors = parser.parse(bufnr) + assert.are_same({ + { + message = "Malformed ID at start of line", + lnum = 0, + col = 0, + }, + }, errors) + end) + + it("errors on empty dirname", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "/008 /", + }) + local _, errors = parser.parse(bufnr) + assert.are.same({ + { + message = "No filename found", + lnum = 0, + col = 0, + }, + }, errors) + end) + + it("errors on duplicate names", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "foo", + "foo/", + }) + local _, errors = parser.parse(bufnr) + assert.are.same({ + { + message = "Duplicate filename", + lnum = 1, + col = 0, + }, + }, errors) + end) + + it("errors on duplicate names for existing files", function() + local file = test_adapter.test_set("/foo/a.txt", "file") + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "a.txt", + string.format("/%d a.txt", file[FIELD_ID]), + }) + local _, errors = parser.parse(bufnr) + assert.are.same({ + { + message = "Duplicate filename", + lnum = 1, + col = 0, + }, + }, errors) + end) + + it("ignores new dirs with empty name", function() + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + "/", + }) + local diffs = parser.parse(bufnr) + assert.are.same({}, diffs) + end) + + it("parses a rename as a delete + new", function() + local file = test_adapter.test_set("/foo/a.txt", "file") + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + string.format("/%d b.txt", file[FIELD_ID]), + }) + local diffs = parser.parse(bufnr) + assert.are.same({ + { type = "new", id = file[FIELD_ID], name = "b.txt", entry_type = "file" }, + { type = "delete", id = file[FIELD_ID], name = "a.txt" }, + }, diffs) + end) + + it("detects a new trailing slash as a delete + create", function() + local file = test_adapter.test_set("/foo", "file") + vim.cmd.edit({ args = { "oil-test:///" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + string.format("/%d foo/", file[FIELD_ID]), + }) + local diffs = parser.parse(bufnr) + assert.are.same({ + { type = "new", name = "foo", entry_type = "directory" }, + { type = "delete", id = file[FIELD_ID], name = "foo" }, + }, diffs) + end) + + it("detects renamed files that conflict", function() + local afile = test_adapter.test_set("/foo/a.txt", "file") + local bfile = test_adapter.test_set("/foo/b.txt", "file") + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + string.format("/%d a.txt", bfile[FIELD_ID]), + string.format("/%d b.txt", afile[FIELD_ID]), + }) + local diffs = parser.parse(bufnr) + local first_two = { diffs[1], diffs[2] } + local last_two = { diffs[3], diffs[4] } + table.sort(first_two, function(a, b) + return a.id < b.id + end) + table.sort(last_two, function(a, b) + return a.id < b.id + end) + assert.are.same({ + { name = "b.txt", type = "new", id = afile[FIELD_ID], entry_type = "file" }, + { name = "a.txt", type = "new", id = bfile[FIELD_ID], entry_type = "file" }, + }, first_two) + assert.are.same({ + { name = "a.txt", type = "delete", id = afile[FIELD_ID] }, + { name = "b.txt", type = "delete", id = bfile[FIELD_ID] }, + }, last_two) + end) + + it("views link targets with trailing slashes as the same", function() + local file = test_adapter.test_set("/foo/mydir", "link") + file[FIELD_META] = { link = "dir/" } + vim.cmd.edit({ args = { "oil-test:///foo/" } }) + local bufnr = vim.api.nvim_get_current_buf() + set_lines(bufnr, { + string.format("/%d mydir/ -> dir/", file[FIELD_ID]), + }) + local diffs = parser.parse(bufnr) + assert.are.same({}, diffs) + end) +end) diff --git a/tests/test_util.lua b/tests/test_util.lua index 63c55ca..e2ab2aa 100644 --- a/tests/test_util.lua +++ b/tests/test_util.lua @@ -1,5 +1,6 @@ require("plenary.async").tests.add_to_env() local cache = require("oil.cache") +local test_adapter = require("oil.adapters.test") local M = {} M.reset_editor = function() @@ -21,6 +22,7 @@ M.reset_editor = function() vim.api.nvim_buf_delete(bufnr, { force = true }) end cache.clear_everything() + test_adapter.test_clear() end M.wait_for_autocmd = a.wrap(function(autocmd, cb)