Files
neovim/test/unit/path.moon
John Schmidt 2a0c6ff3ef Fix broken build due to unit test include order
Commit 4348d1e6f7
 introduced a bug that breaks the unit tests unless
 they run in a certain order. Both path.moon
 and os/fs.moon tries to include the same Enum, which
 fails since ffi.cdef can only include definitions once.

 This solves the bug by using Lua variables instead of
 ffi.cdef Enums.
2014-04-09 17:17:26 -03:00

264 lines
9.2 KiB
Plaintext

{:cimport, :internalize, :eq, :neq, :ffi, :lib, :cstr, :to_cstr} = require 'test.unit.helpers'
require 'lfs'
path = lib
ffi.cdef [[
typedef enum file_comparison {
kEqualFiles = 1, kDifferentFiles = 2, kBothFilesMissing = 4, kOneFileMissing = 6, kEqualFileNames = 7
} FileComparison;
FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname);
char_u *path_tail(char_u *fname);
char_u *path_tail_with_sep(char_u *fname);
char_u *path_next_component(char_u *fname);
]]
-- import constants parsed by ffi
{:kEqualFiles, :kDifferentFiles, :kBothFilesMissing, :kOneFileMissing, :kEqualFileNames} = path
NULL = ffi.cast 'void*', 0
OK = 1
FAIL = 0
describe 'path function', ->
describe 'path_full_compare', ->
path_full_compare = (s1, s2, cn) ->
s1 = to_cstr s1
s2 = to_cstr s2
path.path_full_compare s1, s2, cn or 0
f1 = 'f1.o'
f2 = 'f2.o'
before_each ->
-- create the three files that will be used in this spec
(io.open f1, 'w').close!
(io.open f2, 'w').close!
after_each ->
os.remove f1
os.remove f2
it 'returns kEqualFiles when passed the same file', ->
eq kEqualFiles, (path_full_compare f1, f1)
it 'returns kEqualFileNames when files that dont exist and have same name', ->
eq kEqualFileNames, (path_full_compare 'null.txt', 'null.txt', true)
it 'returns kBothFilesMissing when files that dont exist', ->
eq kBothFilesMissing, (path_full_compare 'null.txt', 'null.txt')
it 'returns kDifferentFiles when passed different files', ->
eq kDifferentFiles, (path_full_compare f1, f2)
eq kDifferentFiles, (path_full_compare f2, f1)
it 'returns kOneFileMissing if only one does not exist', ->
eq kOneFileMissing, (path_full_compare f1, 'null.txt')
eq kOneFileMissing, (path_full_compare 'null.txt', f1)
describe 'path_tail', ->
path_tail = (file) ->
res = path.path_tail (to_cstr file)
neq NULL, res
ffi.string res
it 'returns the tail of a given file path', ->
eq 'file.txt', path_tail 'directory/file.txt'
it 'returns an empty string if file ends in a slash', ->
eq '', path_tail 'directory/'
describe 'path_tail_with_sep', ->
path_tail_with_sep = (file) ->
res = path.path_tail_with_sep (to_cstr file)
neq NULL, res
ffi.string res
it 'returns the tail of a file together with its seperator', ->
eq '///file.txt', path_tail_with_sep 'directory///file.txt'
it 'returns an empty string when given an empty file name', ->
eq '', path_tail_with_sep ''
it 'returns only the seperator if there is a traling seperator', ->
eq '/', path_tail_with_sep 'some/directory/'
it 'cuts a leading seperator', ->
eq 'file.txt', path_tail_with_sep '/file.txt'
eq '', path_tail_with_sep '/'
it 'returns the whole file name if there is no seperator', ->
eq 'file.txt', path_tail_with_sep 'file.txt'
describe 'path_next_component', ->
path_next_component = (file) ->
res = path.path_next_component (to_cstr file)
neq NULL, res
ffi.string res
it 'returns', ->
eq 'directory/file.txt', path_next_component 'some/directory/file.txt'
it 'returns empty string if given file contains no seperator', ->
eq '', path_next_component 'file.txt'
describe 'more path function', ->
setup ->
lfs.mkdir 'unit-test-directory'
(io.open 'unit-test-directory/test.file', 'w').close!
-- Since the tests are executed, they are called by an executable. We use
-- that executable for several asserts.
export absolute_executable = arg[0]
-- Split absolute_executable into a directory and the actual file name for
-- later usage.
export directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$')
teardown ->
os.remove 'unit-test-directory/test.file'
lfs.rmdir 'unit-test-directory'
describe 'vim_FullName', ->
ffi.cdef 'int vim_FullName(char *fname, char *buf, int len, int force);'
vim_FullName = (filename, buffer, length, force) ->
filename = to_cstr filename
path.vim_FullName filename, buffer, length, force
before_each ->
-- Create empty string buffer which will contain the resulting path.
export len = (string.len lfs.currentdir!) + 33
export buffer = cstr len, ''
it 'fails if given filename is NULL', ->
force_expansion = 1
result = path.vim_FullName NULL, buffer, len, force_expansion
eq FAIL, result
it 'uses the filename if the filename is a URL', ->
force_expansion = 1
filename = 'http://www.neovim.org'
result = vim_FullName filename, buffer, len, force_expansion
eq filename, (ffi.string buffer)
eq OK, result
it 'fails and uses filename if given filename contains non-existing directory', ->
force_expansion = 1
filename = 'non_existing_dir/test.file'
result = vim_FullName filename, buffer, len, force_expansion
eq filename, (ffi.string buffer)
eq FAIL, result
it 'concatenates given filename if it does not contain a slash', ->
force_expansion = 1
result = vim_FullName 'test.file', buffer, len, force_expansion
expected = lfs.currentdir! .. '/test.file'
eq expected, (ffi.string buffer)
eq OK, result
it 'concatenates given filename if it is a directory but does not contain a
slash', ->
force_expansion = 1
result = vim_FullName '..', buffer, len, force_expansion
expected = lfs.currentdir! .. '/..'
eq expected, (ffi.string buffer)
eq OK, result
-- Is it possible for every developer to enter '..' directory while running
-- the unit tests? Which other directory would be better?
it 'enters given directory (instead of just concatenating the strings) if
possible and if path contains a slash', ->
force_expansion = 1
result = vim_FullName '../test.file', buffer, len, force_expansion
old_dir = lfs.currentdir!
lfs.chdir '..'
expected = lfs.currentdir! .. '/test.file'
lfs.chdir old_dir
eq expected, (ffi.string buffer)
eq OK, result
it 'just copies the path if it is already absolute and force=0', ->
force_expansion = 0
absolute_path = '/absolute/path'
result = vim_FullName absolute_path, buffer, len, force_expansion
eq absolute_path, (ffi.string buffer)
eq OK, result
it 'fails and uses filename when the path is relative to HOME', ->
force_expansion = 1
absolute_path = '~/home.file'
result = vim_FullName absolute_path, buffer, len, force_expansion
eq absolute_path, (ffi.string buffer)
eq FAIL, result
it 'works with some "normal" relative path with directories', ->
force_expansion = 1
result = vim_FullName 'unit-test-directory/test.file', buffer, len, force_expansion
eq OK, result
eq lfs.currentdir! .. '/unit-test-directory/test.file', (ffi.string buffer)
it 'does not modify the given filename', ->
force_expansion = 1
filename = to_cstr 'unit-test-directory/test.file'
-- Don't use the wrapper here but pass a cstring directly to the c
-- function.
result = path.vim_FullName filename, buffer, len, 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
describe 'append_path', ->
ffi.cdef 'int append_path(char *path, char *to_append, int max_len);'
it 'joins given paths with a slash', ->
path1 = cstr 100, 'path1'
to_append = to_cstr 'path2'
eq OK, (path.append_path path1, to_append, 100)
eq "path1/path2", (ffi.string path1)
it 'joins given paths without adding an unnecessary slash', ->
path1 = cstr 100, 'path1/'
to_append = to_cstr 'path2'
eq OK, path.append_path path1, to_append, 100
eq "path1/path2", (ffi.string path1)
it 'fails and uses filename if there is not enough space left for to_append', ->
path1 = cstr 11, 'path1/'
to_append = to_cstr 'path2'
eq FAIL, (path.append_path path1, to_append, 11)
it 'does not append a slash if to_append is empty', ->
path1 = cstr 6, 'path1'
to_append = to_cstr ''
eq OK, (path.append_path path1, to_append, 6)
eq 'path1', (ffi.string path1)
it 'does not append unnecessary dots', ->
path1 = cstr 6, 'path1'
to_append = to_cstr '.'
eq OK, (path.append_path path1, to_append, 6)
eq 'path1', (ffi.string path1)
it 'copies to_append to path, if path is empty', ->
path1 = cstr 7, ''
to_append = to_cstr '/path2'
eq OK, (path.append_path path1, to_append, 7)
eq '/path2', (ffi.string path1)
describe 'path_is_absolute_path', ->
ffi.cdef 'int path_is_absolute_path(char *fname);'
path_is_absolute_path = (filename) ->
filename = to_cstr filename
path.path_is_absolute_path filename
it 'returns true if filename starts with a slash', ->
eq OK, path_is_absolute_path '/some/directory/'
it 'returns true if filename starts with a tilde', ->
eq OK, path_is_absolute_path '~/in/my/home~/directory'
it 'returns false if filename starts not with slash nor tilde', ->
eq FAIL, path_is_absolute_path 'not/in/my/home~/directory'