diff options
Diffstat (limited to 'mnv/src/testdir/test_cd.mnv')
| -rw-r--r-- | mnv/src/testdir/test_cd.mnv | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/mnv/src/testdir/test_cd.mnv b/mnv/src/testdir/test_cd.mnv new file mode 100644 index 0000000000..384290b90d --- /dev/null +++ b/mnv/src/testdir/test_cd.mnv @@ -0,0 +1,423 @@ +" Test for :cd and chdir() + +func Test_cd_large_path() + " This used to crash with a heap write overflow. + call assert_fails('cd ' . repeat('x', 5000), 'E344:') +endfunc + +func Test_cd_up_and_down() + let path = getcwd() + cd .. + call assert_notequal(path, getcwd()) + exe 'cd ' .. fnameescape(path) + call assert_equal(path, getcwd()) +endfunc + +func Test_cd_no_arg() + if has('unix') + " Test that cd without argument goes to $HOME directory on Unix systems. + let path = getcwd() + cd + call assert_equal($HOME, getcwd()) + call assert_notequal(path, getcwd()) + exe 'cd ' .. fnameescape(path) + call assert_equal(path, getcwd()) + else + " Test that cd without argument echoes cwd on non-Unix systems. + call assert_match(getcwd(), execute('cd')) + endif +endfunc + +func Test_cd_minus() + " Test the :cd - goes back to the previous directory. + let path = getcwd() + cd .. + let path_dotdot = getcwd() + call assert_notequal(path, path_dotdot) + cd - + call assert_equal(path, getcwd()) + cd - + call assert_equal(path_dotdot, getcwd()) + cd - + call assert_equal(path, getcwd()) + + " Test for :cd - after a failed :cd + call assert_fails('cd /nonexistent', 'E344:') + call assert_equal(path, getcwd()) + cd - + call assert_equal(path_dotdot, getcwd()) + cd - + + " Test for :cd - without a previous directory + let lines =<< trim [SCRIPT] + call assert_fails('cd -', 'E186:') + call assert_fails('call chdir("-")', 'E186:') + call writefile(v:errors, 'Xresult') + qall! + [SCRIPT] + call writefile(lines, 'Xscript', 'D') + if RunMNV([], [], '--clean -S Xscript') + call assert_equal([], readfile('Xresult')) + endif + call delete('Xresult') +endfunc + +" Test for chdir() +func Test_chdir_func() + let topdir = getcwd() + call mkdir('Xchdir/y/z', 'pR') + + " Create a few tabpages and windows with different directories + new + cd Xchdir + tabnew + tcd y + below new + below new + lcd z + + tabfirst + call assert_match('^\[global\] .*/Xchdir$', trim(execute('verbose pwd'))) + call chdir('..') + call assert_equal('y', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('z', fnamemodify(3->getcwd(2), ':t')) + tabnext | wincmd t + call assert_match('^\[tabpage\] .*/y$', trim(execute('verbose pwd'))) + eval '..'->chdir() + call assert_equal('Xchdir', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('Xchdir', fnamemodify(getcwd(2, 2), ':t')) + call assert_equal('z', fnamemodify(getcwd(3, 2), ':t')) + call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t')) + 3wincmd w + call assert_match('^\[window\] .*/z$', trim(execute('verbose pwd'))) + call chdir('..') + call assert_equal('Xchdir', fnamemodify(getcwd(1, 2), ':t')) + call assert_equal('Xchdir', fnamemodify(getcwd(2, 2), ':t')) + call assert_equal('y', fnamemodify(getcwd(3, 2), ':t')) + call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t')) + + " Forcing scope + call chdir('.', 'global') + call assert_match('^\[global\]', trim(execute('verbose pwd'))) + call chdir('.', 'tabpage') + call assert_match('^\[tabpage\]', trim(execute('verbose pwd'))) + call chdir('.', 'window') + call assert_match('^\[window\]', trim(execute('verbose pwd'))) + + " Error case + call assert_fails("call chdir('dir-abcd')", 'E344:') + silent! let d = chdir("dir_abcd") + call assert_equal("", d) + call assert_fails("call chdir('.', test_null_string())", 'E475:') + call assert_fails("call chdir('.', [])", 'E730:') + " Should not crash + call chdir(d) + call assert_equal('', chdir([])) + + only | tabonly + call chdir(topdir) +endfunc + +" Test for changing to the previous directory '-' +func Test_prev_dir() + let topdir = getcwd() + call mkdir('Xprevdir/a/b/c', 'pR') + + " Create a few tabpages and windows with different directories + new | only + tabnew | new + tabnew + tabfirst + cd Xprevdir + tabnext | wincmd t + tcd a + wincmd w + lcd b + tabnext + tcd a/b/c + + " Change to the previous directory twice in all the windows. + tabfirst + cd - | cd - + tabnext | wincmd t + tcd - | tcd - + wincmd w + lcd - | lcd - + tabnext + tcd - | tcd - + + " Check the directory of all the windows + tabfirst + call assert_equal('Xprevdir', fnamemodify(getcwd(), ':t')) + tabnext | wincmd t + call assert_equal('a', fnamemodify(getcwd(), ':t')) + wincmd w + call assert_equal('b', fnamemodify(getcwd(), ':t')) + tabnext + call assert_equal('c', fnamemodify(getcwd(), ':t')) + + " Change to the previous directory using chdir() + tabfirst + call chdir("-") | call chdir("-") + tabnext | wincmd t + call chdir("-") | call chdir("-") + wincmd w + call chdir("-") | call chdir("-") + tabnext + call chdir("-") | call chdir("-") + + " Check the directory of all the windows + tabfirst + call assert_equal('Xprevdir', fnamemodify(getcwd(), ':t')) + tabnext | wincmd t + call assert_equal('a', fnamemodify(getcwd(), ':t')) + wincmd w + call assert_equal('b', fnamemodify(getcwd(), ':t')) + tabnext + call assert_equal('c', fnamemodify(getcwd(), ':t')) + + only | tabonly + call chdir(topdir) +endfunc + +func Test_lcd_split() + let curdir = getcwd() + lcd .. + split + lcd - + call assert_equal(curdir, getcwd()) + quit! +endfunc + +" Test that a temporary override of 'autochdir' via :lcd isn't clobbered by win_execute() in a split window. +func Test_lcd_win_execute() + CheckOption autochdir + + let startdir = getcwd() + call mkdir('Xsubdir', 'R') + call test_autochdir() + set autochdir + edit Xsubdir/file + call assert_match('testdir.Xsubdir.file$', expand('%:p')) + split + lcd .. + call assert_match('testdir.Xsubdir.file$', expand('%:p')) + call win_execute(win_getid(2), "") + call assert_match('testdir.Xsubdir.file$', expand('%:p')) + + set noautochdir + bwipe! + call chdir(startdir) +endfunc + +func Test_cd_from_non_existing_dir() + CheckNotMSWindows + + let saveddir = getcwd() + call mkdir('Xdeleted_dir') + cd Xdeleted_dir + call delete(saveddir .. '/Xdeleted_dir', 'd') + + " Expect E187 as the current directory was deleted. + call assert_fails('pwd', 'E187:') + call assert_equal('', getcwd()) + cd - + call assert_equal(saveddir, getcwd()) +endfunc + +func Test_cd_completion() + call mkdir('XComplDir1', 'D') + call mkdir('XComplDir2', 'D') + call mkdir('sub/XComplDir3', 'pD') + call writefile([], 'XComplFile', 'D') + + for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] + call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/', @:) + endfor + + set cdpath+=sub + for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] + call feedkeys(':' .. cmd .. " XCompl\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"' .. cmd .. ' XComplDir1/ XComplDir2/ XComplDir3/', @:) + endfor + set cdpath& + + if has('win32') + " Test Windows absolute path completion + let saved_cwd = getcwd() + + " Retrieve a suitable dir in the current drive + for d in readdir('/', 'isdirectory("/" .. v:val) && len(v:val) > 2') + " Paths containing '$' such as "$RECYCLE.BIN" are skipped because + " they are considered environment variables and completion does not + " work. + if d =~ '\V$' + continue + endif + " Skip directories that we don't have permission to "cd" into by + " actually "cd"ing into them and making sure they don't fail. + " Directory "System Volume Information" is an example of this. + try + call chdir('/' .. d) + let dir = d + " Yay! We found a suitable dir! + break + catch /:E472:/ + " Just skip directories where "cd" fails + continue + finally + call chdir(saved_cwd) + endtry + endfor + if !exists('dir') + throw 'Skipped: no testable directories found in the current drive root' + endif + + " Get partial path + let partial = dir[0:-2] + " Get the current drive letter and full path of the target dir + call chdir('/' .. dir) + let full = getcwd() + let drive = full[0] + call chdir(saved_cwd) + + " Spaces are escaped in command line completion. Next, in assert_match(), + " the backslash added by the first escape also needs to be escaped + " separately, so the escape is doubled. + let want_full = escape(escape(full, ' '), '\') + let want_dir = escape(escape(dir, ' '), '\') + + for cmd in ['cd', 'chdir', 'lcd', 'lchdir', 'tcd', 'tchdir'] + for sep in [ '/', '\'] + + " Explicit drive letter + call feedkeys(':' .. cmd .. ' ' .. drive .. ':' .. sep .. + \ partial .. "\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match(want_full, @:) + + " Implicit drive letter + call feedkeys(':' .. cmd .. ' ' .. sep .. partial .. "\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match('/' .. want_dir .. '/', @:) + + " UNC path + call feedkeys(':' .. cmd .. ' ' .. sep .. sep .. $COMPUTERNAME .. sep .. + \ drive .. '$' .. sep .. partial .."\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match('//' .. $COMPUTERNAME .. '/' .. drive .. '$/' .. want_dir .. '/' , @:) + + endfor + endfor + endif +endfunc + +func Test_cd_unknown_dir() + call mkdir('Xa', 'R') + cd Xa + call writefile(['text'], 'Xb.txt') + edit Xa/Xb.txt + let first_buf = bufnr() + cd .. + edit + call assert_equal(first_buf, bufnr()) + edit Xa/Xb.txt + call assert_notequal(first_buf, bufnr()) + + bwipe! + exe "bwipe! " .. first_buf +endfunc + +func Test_getcwd_actual_dir() + CheckOption autochdir + + let startdir = getcwd() + call mkdir('Xactual', 'R') + call test_autochdir() + set autochdir + edit Xactual/file.txt + call assert_match('testdir.Xactual$', getcwd()) + lcd .. + call assert_match('testdir$', getcwd()) + edit + call assert_match('testdir.Xactual$', getcwd()) + call assert_match('testdir$', getcwd(win_getid())) + + set noautochdir + bwipe! + call chdir(startdir) +endfunc + +func Test_cd_preserve_symlinks() + " Test new behavior: preserve symlinks when cpo-=~ + set cpoptions+=~ + + let savedir = getcwd() + call mkdir('Xsource', 'R') + call writefile(['abc'], 'Xsource/foo.txt', 'D') + + if has("win32") + silent !mklink /D Xdest Xsource + else + silent !ln -s Xsource Xdest + endif + if v:shell_error + call delete('Xsource', 'rf') + throw 'Skipped: cannot create symlinks' + endif + + edit Xdest/foo.txt + let path_before = expand('%') + call assert_match('Xdest[/\\]foo\.txt$', path_before) + + cd . + let path_after = expand('%') + call assert_equal(path_before, path_after) + call assert_match('Xdest[/\\]foo\.txt$', path_after) + + bwipe! + set cpoptions& + call delete('Xdest', 'rf') + call delete('Xsource', 'rf') + call chdir(savedir) +endfunc + +func Test_cd_symlinks() + CheckNotMSWindows + + let savedir = getcwd() + call mkdir('Xsource', 'R') + call writefile(['abc'], 'Xsource/foo.txt', 'D') + + silent !ln -s Xsource Xdest + if v:shell_error + call delete('Xsource', 'rf') + throw 'Skipped: cannot create symlinks' + endif + + edit Xdest/foo.txt + let path_before = expand('%') + call assert_match('Xdest[/\\]foo\.txt$', path_before) + + cd . + let path_after = expand('%') + call assert_match('Xsource[/\\]foo\.txt$', path_after) + call assert_notequal(path_before, path_after) + + bwipe! + set cpoptions& + call delete('Xdest', 'rf') + call delete('Xsource', 'rf') + call chdir(savedir) +endfunc + +func Test_cd_shorten_bufname_with_duplicate_slashes() + let savedir = getcwd() + call mkdir('Xexistingdir', 'R') + new Xexistingdir//foo/bar + cd Xexistingdir + call assert_equal('foo/bar', bufname('%')) + + call chdir(savedir) + bwipe! +endfunc + +" mnv: shiftwidth=2 sts=2 expandtab |
