diff options
| -rw-r--r-- | src/nvim/os/fs.c | 4 | ||||
| -rw-r--r-- | test/unit/os/fs_spec.lua | 52 | ||||
| -rw-r--r-- | test/unit/path_spec.lua | 81 | 
3 files changed, 73 insertions, 64 deletions
| diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index c39ff5d358..aaa750db50 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -61,9 +61,9 @@ void fs_init(void)  } -/// Change to the given directory. +/// Changes the current directory to `path`.  /// -/// @return `0` on success, a libuv error code on failure. +/// @return 0 on success, or negative error code.  int os_chdir(const char *path)    FUNC_ATTR_NONNULL_ALL  { diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua index 860ebfdbcb..23eb05b4b8 100644 --- a/test/unit/os/fs_spec.lua +++ b/test/unit/os/fs_spec.lua @@ -35,7 +35,6 @@ for i = 0, 255 do  end  local fcontents = s:rep(16) -local buffer = ""  local directory = nil  local absolute_executable = nil  local executable_name = nil @@ -65,7 +64,11 @@ local function os_getperm(filename)    return tonumber(perm)  end -describe('fs function', function() +describe('fs.c', function() +  local function os_isdir(name) +    return fs.os_isdir(to_cstr(name)) +  end +    before_each(function()      lfs.mkdir('unit-test-directory'); @@ -91,32 +94,37 @@ describe('fs function', function()    end)    describe('os_dirname', function() -    local length - -    local function os_dirname(buf, len) -      return fs.os_dirname(buf, len) -    end - -    before_each(function() -      length = (string.len(lfs.currentdir())) + 1 -      buffer = cstr(length, '') +    itp('returns OK and writes current directory to the buffer', function() +      local length = string.len(lfs.currentdir()) + 1 +      local buf = cstr(length, '') +      eq(OK, fs.os_dirname(buf, length)) +      eq(lfs.currentdir(), ffi.string(buf))      end) -    itp('returns OK and writes current directory into the buffer if it is large\n    enough', function() -      eq(OK, (os_dirname(buffer, length))) -      eq(lfs.currentdir(), (ffi.string(buffer))) -    end) - -    -- What kind of other failing cases are possible?      itp('returns FAIL if the buffer is too small', function() -      local buf = cstr((length - 1), '') -      eq(FAIL, (os_dirname(buf, (length - 1)))) +      local length = string.len(lfs.currentdir()) + 1 +      local buf = cstr(length - 1, '') +      eq(FAIL, fs.os_dirname(buf, length - 1))      end)    end) -  local function os_isdir(name) -    return fs.os_isdir((to_cstr(name))) -  end +  describe('os_chdir', function() +    itp('fails with path="~"', function() +      eq(false, os_isdir('~')) -- sanity check: no literal "~" directory. +      local length = 4096 +      local expected_cwd = cstr(length, '') +      local cwd = cstr(length, '') +      eq(OK, fs.os_dirname(expected_cwd, length)) + +      -- os_chdir returns 0 for success, not OK (1). +      neq(0, fs.os_chdir('~'))    -- fail +      neq(0, fs.os_chdir('~/'))   -- fail + +      eq(OK, fs.os_dirname(cwd, length)) +      -- CWD did not change. +      eq(ffi.string(expected_cwd), ffi.string(cwd)) +    end) +  end)    describe('os_isdir', function()      itp('returns false if an empty string is given', function() diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index 470f971e68..6b9e2c8695 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -13,7 +13,7 @@ local OK = helpers.OK  local FAIL = helpers.FAIL  cimport('string.h') -local path = cimport('./src/nvim/path.h') +local cimp = cimport('./src/nvim/os/os.h', './src/nvim/path.h')  local length = 0  local buffer = nil @@ -30,7 +30,7 @@ describe('path function', function()      local function path_full_dir_name(directory, buf, len)        directory = to_cstr(directory) -      return path.path_full_dir_name(directory, buf, len) +      return cimp.path_full_dir_name(directory, buf, len)      end      before_each(function() @@ -69,7 +69,7 @@ describe('path function', function()      local function path_full_compare(s1, s2, cn)        s1 = to_cstr(s1)        s2 = to_cstr(s2) -      return path.path_full_compare(s1, s2, cn or 0) +      return cimp.path_full_compare(s1, s2, cn or 0)      end      local f1 = 'f1.o' @@ -86,31 +86,31 @@ describe('path function', function()      end)      itp('returns kEqualFiles when passed the same file', function() -      eq(path.kEqualFiles, (path_full_compare(f1, f1))) +      eq(cimp.kEqualFiles, (path_full_compare(f1, f1)))      end)      itp('returns kEqualFileNames when files that dont exist and have same name', function() -      eq(path.kEqualFileNames, (path_full_compare('null.txt', 'null.txt', true))) +      eq(cimp.kEqualFileNames, (path_full_compare('null.txt', 'null.txt', true)))      end)      itp('returns kBothFilesMissing when files that dont exist', function() -      eq(path.kBothFilesMissing, (path_full_compare('null.txt', 'null.txt'))) +      eq(cimp.kBothFilesMissing, (path_full_compare('null.txt', 'null.txt')))      end)      itp('returns kDifferentFiles when passed different files', function() -      eq(path.kDifferentFiles, (path_full_compare(f1, f2))) -      eq(path.kDifferentFiles, (path_full_compare(f2, f1))) +      eq(cimp.kDifferentFiles, (path_full_compare(f1, f2))) +      eq(cimp.kDifferentFiles, (path_full_compare(f2, f1)))      end)      itp('returns kOneFileMissing if only one does not exist', function() -      eq(path.kOneFileMissing, (path_full_compare(f1, 'null.txt'))) -      eq(path.kOneFileMissing, (path_full_compare('null.txt', f1))) +      eq(cimp.kOneFileMissing, (path_full_compare(f1, 'null.txt'))) +      eq(cimp.kOneFileMissing, (path_full_compare('null.txt', f1)))      end)    end)    describe('path_tail', function()      local function path_tail(file) -      local res = path.path_tail((to_cstr(file))) +      local res = cimp.path_tail((to_cstr(file)))        neq(NULL, res)        return ffi.string(res)      end @@ -126,7 +126,7 @@ describe('path function', function()    describe('path_tail_with_sep', function()      local function path_tail_with_sep(file) -      local res = path.path_tail_with_sep((to_cstr(file))) +      local res = cimp.path_tail_with_sep((to_cstr(file)))        neq(NULL, res)        return ffi.string(res)      end @@ -159,11 +159,11 @@ describe('path function', function()      -- strcmp.      local function invocation_path_tail(invk)        local plen = ffi.new('size_t[?]', 1) -      local ptail = path.invocation_path_tail((to_cstr(invk)), plen) +      local ptail = cimp.invocation_path_tail((to_cstr(invk)), plen)        neq(NULL, ptail)        -- it does not change the output if len==NULL -      local tail2 = path.invocation_path_tail((to_cstr(invk)), NULL) +      local tail2 = cimp.invocation_path_tail((to_cstr(invk)), NULL)        neq(NULL, tail2)        eq((ffi.string(ptail)), (ffi.string(tail2)))        return ptail, plen[0] @@ -204,7 +204,7 @@ describe('path function', function()      end)      itp('is equivalent to path_tail when args do not contain a path separator', function() -      local ptail = path.path_tail(to_cstr("a/b/c x y z")) +      local ptail = cimp.path_tail(to_cstr("a/b/c x y z"))        neq(NULL, ptail)        local tail = ffi.string(ptail)        local invk, _ = invocation_path_tail("a/b/c x y z") @@ -212,7 +212,7 @@ describe('path function', function()      end)      itp('is not equivalent to path_tail when args contain a path separator', function() -      local ptail = path.path_tail(to_cstr("a/b/c x y/z")) +      local ptail = cimp.path_tail(to_cstr("a/b/c x y/z"))        neq(NULL, ptail)        local invk, _ = invocation_path_tail("a/b/c x y/z")        neq((ffi.string(ptail)), (ffi.string(invk))) @@ -221,7 +221,7 @@ describe('path function', function()    describe('path_next_component', function()      local function path_next_component(file) -      local res = path.path_next_component((to_cstr(file))) +      local res = cimp.path_next_component((to_cstr(file)))        neq(NULL, res)        return ffi.string(res)      end @@ -238,25 +238,25 @@ describe('path function', function()    describe('path_shorten_fname', function()      itp('returns NULL if `full_path` is NULL', function()        local dir = to_cstr('some/directory/file.txt') -      eq(NULL, (path.path_shorten_fname(NULL, dir))) +      eq(NULL, (cimp.path_shorten_fname(NULL, dir)))      end)      itp('returns NULL if the path and dir does not match', function()        local dir = to_cstr('not/the/same')        local full = to_cstr('as/this.txt') -      eq(NULL, (path.path_shorten_fname(full, dir))) +      eq(NULL, (cimp.path_shorten_fname(full, dir)))      end)      itp('returns NULL if the path is not separated properly', function()        local dir = to_cstr('some/very/long/')        local full = to_cstr('some/very/long/directory/file.txt') -      eq(NULL, (path.path_shorten_fname(full, dir))) +      eq(NULL, (cimp.path_shorten_fname(full, dir)))      end)      itp('shortens the filename if `dir_name` is the start of `full_path`', function()        local full = to_cstr('some/very/long/directory/file.txt')        local dir = to_cstr('some/very/long') -      eq('directory/file.txt', (ffi.string(path.path_shorten_fname(full, dir)))) +      eq('directory/file.txt', (ffi.string(cimp.path_shorten_fname(full, dir))))      end)    end)  end) @@ -277,23 +277,23 @@ describe('path_shorten_fname_if_possible', function()      itp('returns shortened path if possible', function()        lfs.chdir('ut_directory')        local full = to_cstr(lfs.currentdir() .. '/subdir/file.txt') -      eq('subdir/file.txt', (ffi.string(path.path_shorten_fname_if_possible(full)))) +      eq('subdir/file.txt', (ffi.string(cimp.path_shorten_fname_if_possible(full))))      end)      itp('returns `full_path` if a shorter version is not possible', function()        local old = lfs.currentdir()        lfs.chdir('ut_directory')        local full = old .. '/subdir/file.txt' -      eq(full, (ffi.string(path.path_shorten_fname_if_possible(to_cstr(full))))) +      eq(full, (ffi.string(cimp.path_shorten_fname_if_possible(to_cstr(full)))))      end)      itp('returns NULL if `full_path` is NULL', function() -      eq(NULL, (path.path_shorten_fname_if_possible(NULL))) +      eq(NULL, (cimp.path_shorten_fname_if_possible(NULL)))      end)    end)  end) -describe('more path function', function() +describe('path.c', function()    setup(function()      lfs.mkdir('unit-test-directory');      io.open('unit-test-directory/test.file', 'w').close() @@ -315,7 +315,7 @@ describe('more path function', function()    describe('vim_FullName', function()      local function vim_FullName(filename, buf, len, force)        filename = to_cstr(filename) -      return path.vim_FullName(filename, buf, len, force) +      return cimp.vim_FullName(filename, buf, len, force)      end      before_each(function() @@ -326,7 +326,7 @@ describe('more path function', function()      itp('fails if given filename is NULL', function()        local force_expansion = 1 -      local result = path.vim_FullName(NULL, buffer, length, force_expansion) +      local result = cimp.vim_FullName(NULL, buffer, length, force_expansion)        eq(FAIL, result)      end) @@ -335,7 +335,7 @@ describe('more path function', function()        local filename = 'foo/bar/bazzzzzzz/buz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/a'        local too_short_len = 8        local buf = cstr(too_short_len, '') -      local result = path.vim_FullName(filename, buf, too_short_len, force_expansion) +      local result = cimp.vim_FullName(filename, buf, too_short_len, force_expansion)        local expected = string.sub(filename, 1, (too_short_len - 1))        eq(expected, (ffi.string(buf)))        eq(FAIL, result) @@ -357,7 +357,7 @@ describe('more path function', function()        eq(FAIL, result)      end) -    itp('concatenates given filename if it does not contain a slash', function() +    itp('concatenates filename if it does not contain a slash', function()        local force_expansion = 1        local result = vim_FullName('test.file', buffer, length, force_expansion)        local expected = lfs.currentdir() .. '/test.file' @@ -365,7 +365,7 @@ describe('more path function', function()        eq(OK, result)      end) -    itp('concatenates given filename if it is a directory but does not contain a\n    slash', function() +    itp('concatenates directory name if it does not contain a slash', function()        local force_expansion = 1        local result = vim_FullName('..', buffer, length, force_expansion)        local expected = lfs.currentdir() .. '/..' @@ -395,6 +395,7 @@ describe('more path function', function()      end)      itp('fails and uses filename when the path is relative to HOME', function() +      eq(false, cimp.os_isdir('~')) -- sanity check: no literal "~" directory.        local force_expansion = 1        local absolute_path = '~/home.file'        local result = vim_FullName(absolute_path, buffer, length, force_expansion) @@ -414,7 +415,7 @@ describe('more path function', function()        local filename = to_cstr('unit-test-directory/test.file')        -- Don't use the wrapper here but pass a cstring directly to the c        -- function. -      local result = path.vim_FullName(filename, buffer, length, force_expansion) +      local result = cimp.vim_FullName(filename, buffer, length, force_expansion)        eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))        eq('unit-test-directory/test.file', (ffi.string(filename)))        eq(OK, result) @@ -423,7 +424,7 @@ describe('more path function', function()      itp('works with directories that have one path component', function()        local force_expansion = 1        local filename = to_cstr('/tmp') -      local result = path.vim_FullName(filename, buffer, length, force_expansion) +      local result = cimp.vim_FullName(filename, buffer, length, force_expansion)        eq('/tmp', ffi.string(buffer))        eq(OK, result)      end) @@ -432,7 +433,7 @@ describe('more path function', function()    describe('path_fix_case', function()      local function fix_case(file)        local c_file = to_cstr(file) -      path.path_fix_case(c_file) +      cimp.path_fix_case(c_file)        return ffi.string(c_file)      end @@ -456,41 +457,41 @@ describe('more path function', function()      itp('joins given paths with a slash', function()        local path1 = cstr(100, 'path1')        local to_append = to_cstr('path2') -      eq(OK, (path.append_path(path1, to_append, 100))) +      eq(OK, (cimp.append_path(path1, to_append, 100)))        eq("path1/path2", (ffi.string(path1)))      end)      itp('joins given paths without adding an unnecessary slash', function()        local path1 = cstr(100, 'path1/')        local to_append = to_cstr('path2') -      eq(OK, path.append_path(path1, to_append, 100)) +      eq(OK, cimp.append_path(path1, to_append, 100))        eq("path1/path2", (ffi.string(path1)))      end)      itp('fails and uses filename if there is not enough space left for to_append', function()        local path1 = cstr(11, 'path1/')        local to_append = to_cstr('path2') -      eq(FAIL, (path.append_path(path1, to_append, 11))) +      eq(FAIL, (cimp.append_path(path1, to_append, 11)))      end)      itp('does not append a slash if to_append is empty', function()        local path1 = cstr(6, 'path1')        local to_append = to_cstr('') -      eq(OK, (path.append_path(path1, to_append, 6))) +      eq(OK, (cimp.append_path(path1, to_append, 6)))        eq('path1', (ffi.string(path1)))      end)      itp('does not append unnecessary dots', function()        local path1 = cstr(6, 'path1')        local to_append = to_cstr('.') -      eq(OK, (path.append_path(path1, to_append, 6))) +      eq(OK, (cimp.append_path(path1, to_append, 6)))        eq('path1', (ffi.string(path1)))      end)      itp('copies to_append to path, if path is empty', function()        local path1 = cstr(7, '')        local to_append = to_cstr('/path2') -      eq(OK, (path.append_path(path1, to_append, 7))) +      eq(OK, (cimp.append_path(path1, to_append, 7)))        eq('/path2', (ffi.string(path1)))      end)    end) @@ -498,7 +499,7 @@ describe('more path function', function()    describe('path_is_absolute_path', function()      local function path_is_absolute_path(filename)        filename = to_cstr(filename) -      return path.path_is_absolute_path(filename) +      return cimp.path_is_absolute_path(filename)      end      itp('returns true if filename starts with a slash', function() | 
