summaryrefslogtreecommitdiff
path: root/mnv/src/testdir/test_plugin_netrw.mnv
diff options
context:
space:
mode:
Diffstat (limited to 'mnv/src/testdir/test_plugin_netrw.mnv')
-rw-r--r--mnv/src/testdir/test_plugin_netrw.mnv606
1 files changed, 606 insertions, 0 deletions
diff --git a/mnv/src/testdir/test_plugin_netrw.mnv b/mnv/src/testdir/test_plugin_netrw.mnv
new file mode 100644
index 0000000000..2850fa841e
--- /dev/null
+++ b/mnv/src/testdir/test_plugin_netrw.mnv
@@ -0,0 +1,606 @@
+const s:testdir = expand("<script>:h")
+const s:runtimedir = simplify(s:testdir . '/../../runtime')
+const s:netrw_path = s:runtimedir . '/pack/dist/opt/netrw/autoload/netrw.mnv'
+const s:netrw_test_path = s:testdir . '/samples/netrw.mnv'
+const s:testScript =<< trim END
+
+" Testing functions: {{{1
+function! TestNetrwCaptureRemotePath(dirname)
+ call s:RemotePathAnalysis(a:dirname)
+ return {"method": s:method, "user": s:user, "machine": s:machine, "port": s:port, "path": s:path, "fname": s:fname}
+endfunction
+
+" Test directory creation via s:NetrwMakeDir()
+" Precondition: inputsave() and inputrestore() must be disabled in s:NetrwMakeDir
+
+function s:test_inputsave()
+ if exists("s:inputguards_disabled") && s:inputguards_disabled
+ return
+ endif
+ call inputsave()
+endfunction
+
+function s:test_inputrestore()
+ if exists("s:inputguards_disabled") && s:inputguards_disabled
+ return
+ endif
+ call inputrestore()
+endfunction
+
+function s:test_input(prompt, text = v:none, completion = v:none)
+
+ if exists("s:inputdefaults_disabled") && s:inputdefaults_disabled || a:text == v:none
+ return input(a:prompt)
+ elseif a:completion == v:none
+ return input(a:prompt, a:text)
+ endif
+
+ return input(a:prompt, a:text, a:completion)
+endfunction
+
+function Test_NetrwMakeDir(parentdir = $HOME, dirname = "NetrwMakeDir", symlink = 0) abort
+ if a:symlink
+ " Plainly delegate, this device is necessary because feedkeys() can't
+ " access script functions directly.
+ call s:NetrwMakeDir('')
+ " wipe out the test buffer
+ bw
+ " reenable the guards
+ let s:inputguards_disabled = 0
+ else
+ " Use feedkeys() to simulate user input (directory name)
+ new
+ let b:netrw_curdir = a:parentdir
+ let s:inputguards_disabled = 1
+ call feedkeys($"\<Cmd>call Test_NetrwMakeDir('{a:parentdir}', '{a:dirname}', 1)\<CR>{a:dirname}\<CR>", "x")
+ endif
+endfunction
+
+" Test file copy operations via s:NetrwMarkFileCopy()
+function Test_NetrwMarkFileCopy(source_dir, target_dir, marked_files) abort
+ " set up
+ new
+ let b:netrw_curdir= a:source_dir
+ let s:netrwmftgt = a:target_dir
+ let s:netrwmarkfilelist_{bufnr("%")} = a:marked_files
+ let s:netrwmftgt_islocal = 1
+ " delegate
+ call s:NetrwMarkFileCopy(1)
+ " wipe out the test buffer
+ bw
+endfunction
+
+" Corner case: copy into the same dir triggers a user prompt
+function Test_NetrwMarkFileCopy_SameDir(dir = $HOME, symlink = 0) abort
+ const filename = "filename.txt"
+ const file = netrw#fs#PathJoin(a:dir, filename)
+
+ const newfilename = "newfilename.txt"
+ const newfile = netrw#fs#PathJoin(a:dir, newfilename)
+
+ if a:symlink
+ " Plainly delegate, this device is necessary because feedkeys() can't
+ " access script functions directly.
+ " set up
+ new
+ let b:netrw_curdir = a:dir
+ let s:netrwmftgt = a:dir
+ let s:netrwmarkfilelist_{bufnr("%")} = [filename]
+ let s:netrwmftgt_islocal = 1
+
+ " delegate
+ call s:NetrwMarkFileCopy(1)
+
+ " validate
+ call assert_equalfile(file, newfile, "File copy in same dir failed")
+
+ " tear down
+ call delete(file)
+ call delete(newfile)
+ " wipe out the test buffer
+ bw
+ " reenable the guards
+ let s:inputguards_disabled = 0
+ let s:inputdefaults_disabled = 0
+ else
+ " Use feedkeys() to simulate user input (directory name)
+ let s:inputguards_disabled = 1
+ let s:inputdefaults_disabled = 1
+
+ call writefile([$"NetrwMarkFileCopy test file"], file)
+
+ call feedkeys($"\<Cmd>call Test_NetrwMarkFileCopy_SameDir('{a:dir}', 1)\<CR>{newfilename}\<CR>", "x")
+ endif
+endfunction
+
+" Test file copy operations via s:NetrwMarkFileMove()
+function Test_NetrwMarkFileMove(source_dir, target_dir, marked_files) abort
+ " set up
+ new
+ let b:netrw_curdir= a:source_dir
+ let s:netrwmftgt = a:target_dir
+ let s:netrwmarkfilelist_{bufnr("%")} = a:marked_files
+ let s:netrwmftgt_islocal = 1
+ " delegate
+ call s:NetrwMarkFileMove(1)
+ " wipe out the test buffer
+ bw
+endfunction
+
+" Test how netrw fixes paths according with settings
+" (g:netrw_keepdir, g:netrw_cygwin, tree style ...)
+function Test_NetrwFile(fname) abort
+ return s:NetrwFile(a:fname)
+endfunction
+
+" Test hostname validation
+function Test_NetrwValidateHostname(hostname) abort
+ return s:NetrwValidateHostname(a:hostname)
+endfunction
+
+" }}}
+END
+
+"make copy of netrw script and add function to print local variables"
+func s:appendDebugToNetrw(netrw_path, netrw_test_path)
+
+ " load the netrw script
+ execute "split" a:netrw_test_path
+ execute "read" a:netrw_path
+
+ " replace input guards for convenient testing versions
+ %substitute@call inputsave()@call s:test_inputsave()@g
+ %substitute@call inputrestore()@call s:test_inputrestore()@g
+ %substitute@\<input(@s:test_input(@g
+
+ call cursor(1,1)
+ let pos = search("Settings Restoration:")-1
+ " insert the test functions before the end guard
+ call assert_false(append(pos, s:testScript))
+
+ " save the modified script content
+ write
+ bwipe!
+
+endfunction
+
+func SetUp()
+
+ " prepare modified netrw script
+ call s:appendDebugToNetrw(s:netrw_path, s:netrw_test_path)
+
+ " source the modified script
+ exe "source" s:netrw_test_path
+
+ " Rig the package. The modified script guard prevents loading it again.
+ let &runtimepath=s:runtimedir
+ let &packpath=s:runtimedir
+ packadd netrw
+
+ " use proper path
+ if has('win32')
+ let $HOME = substitute($HOME, '/', '\\', 'g')
+ endif
+
+endfunction
+
+func TearDown()
+ " cleanup
+ call delete(s:netrw_test_path)
+endfunction
+
+func SetShell(shell)
+ " select different shells
+ if a:shell == "default"
+ set shell& shellcmdflag& shellxquote& shellpipe& shellredir&
+ elseif a:shell == "powershell" " help dos-powershell
+ " powershell desktop is windows only
+ if !has("win32")
+ throw 'Skipped: powershell desktop is missing'
+ endif
+ set shell=powershell shellcmdflag=-NoProfile\ -Command shellxquote=\"
+ set shellpipe=2>&1\ \|\ Out-File\ -Encoding\ default shellredir=2>&1\ \|\ Out-File\ -Encoding\ default
+ elseif a:shell == "pwsh" " help dos-powershell
+ " powershell core works crossplatform
+ if !executable("pwsh")
+ throw 'Skipped: powershell core is missing'
+ endif
+ set shell=pwsh shellcmdflag=-NoProfile\ -c shellpipe=>%s\ 2>&1 shellredir=>%s\ 2>&1
+ if has("win32")
+ set shellxquote=\"
+ else
+ set shellxquote=
+ endif
+ else
+ call assert_report("Trying to select an unknown shell")
+ endif
+endfunc
+
+func s:combine
+ \( usernames
+ \, methods
+ \, hosts
+ \, ports
+ \, dirs
+ \, files)
+ for username in a:usernames
+ for method in a:methods
+ for host in a:hosts
+ for port in a:ports
+ for dir in a:dirs
+ for file in a:files
+ " --- Build a full remote path ---
+
+ let port_str = empty(port) ? "" : ':' . port
+ let remote = printf('%s://%s@%s%s/%s%s', method, username, host, port_str, dir, file)
+
+ let result = TestNetrwCaptureRemotePath(remote)
+
+ call assert_equal(result.method, method)
+ call assert_equal(result.user, username)
+ call assert_equal(result.machine, host)
+ call assert_equal(result.port, port)
+ call assert_equal(result.path, dir . file)
+ endfor
+ endfor
+ endfor
+ endfor
+ endfor
+ endfor
+endfunction
+
+
+func Test_netrw_parse_remote_simple()
+ let result = TestNetrwCaptureRemotePath('scp://user@localhost:2222/test.txt')
+ call assert_equal(result.method, 'scp')
+ call assert_equal(result.user, 'user')
+ call assert_equal(result.machine, 'localhost')
+ call assert_equal(result.port, '2222')
+ call assert_equal(result.path, 'test.txt')
+endfunction
+
+"testing different combinations"
+func Test_netrw_parse_regular_usernames()
+
+ " --- sample data for combinations ---"
+ let usernames = ["root", "toor", "user01", "skillIssue"]
+ let methods = ["scp", "ssh", "ftp", "sftp"]
+ let hosts = ["localhost", "server.com", "fit-workspaces.ksi.fit.cvut.cz", "192.168.1.42"]
+ let ports = ["", "22","420", "443", "2222", "1234"]
+ let dirs = ["", "somefolder/", "path/to/the/bottom/of/the/world/please/send/help/"]
+ let files = ["test.txt", "tttt.mnv", "Makefile"]
+
+ call s:combine(usernames, methods, hosts, ports, dirs, files)
+
+endfunc
+
+"Host myserver
+" HostName 192.168.1.42
+" User alice
+func Test_netrw_parse_ssh_config_entries()
+ let result = TestNetrwCaptureRemotePath('scp://myserver//etc/nginx/nginx.conf')
+ call assert_equal(result.method, 'scp')
+ call assert_equal(result.user, '')
+ call assert_equal(result.machine, 'myserver')
+ call assert_equal(result.port, '')
+ call assert_equal(result.path, '/etc/nginx/nginx.conf')
+endfunction
+
+"username containing special-chars"
+func Test_netrw_parse_special_char_user()
+ let result = TestNetrwCaptureRemotePath('scp://user-01@localhost:2222/test.txt')
+ call assert_equal(result.method, 'scp')
+ call assert_equal(result.user, 'user-01')
+ call assert_equal(result.machine, 'localhost')
+ call assert_equal(result.port, '2222')
+ call assert_equal(result.path, 'test.txt')
+endfunction
+
+func Test_netrw_empty_buffer_fastpath_wipe()
+ " SetUp() may have opened some buffers
+ let previous = bufnr('$')
+ let g:netrw_fastbrowse=0
+ call setline(1, 'foobar')
+ let bufnr = bufnr('%')
+ tabnew
+ Explore
+ call search('README.txt', 'W')
+ exe ":norm \<cr>"
+ call assert_equal(previous + 2, bufnr('$'))
+ call assert_true(bufexists(bufnr))
+ bw
+
+ unlet! netrw_fastbrowse
+endfunction
+
+" Test UNC paths on windows
+func Test_netrw_check_UNC_paths()
+ CheckMSWindows
+
+ let test_paths = [
+ \ '\\Server2\Share\Test\Foo.txt',
+ \ '//Server2/Share/Test/Foo.txt',
+ \ '\\Server2\Share\Test\',
+ \ '//Server2/Share/Test/',
+ \ '\\wsl.localhost\Ubuntu\home\user\_mnvrc',
+ \ '//wsl.localhost/Ubuntu/home/user/_mnvrc',
+ \ '\\wsl.localhost\Ubuntu\home\user',
+ \ '//wsl.localhost/Ubuntu/home/user']
+
+ " The paths must be interpreted as absolute ones
+ for path in test_paths
+ call assert_equal(
+ \ path,
+ \ Test_NetrwFile(path),
+ \ $"UNC path: {path} misinterpreted")
+ endfor
+
+endfunction
+
+" ---------------------------------
+" Testing file management functions
+" ---------------------------------
+
+" Browser directory creation
+func s:netrw_mkdir()
+
+ " create a testdir in the fake $HOME
+ call Test_NetrwMakeDir($HOME, "NetrwMakeDir")
+
+ " Check the test directory was created
+ let test_dir = netrw#fs#PathJoin($HOME, "NetrwMakeDir")
+ call WaitForAssert({-> assert_true(
+ \ isdirectory(test_dir),
+ \ "Unable to create a dir via s:NetrwMakeDir()")
+ \ })
+
+ " remove the test directory
+ call delete(test_dir, 'd')
+endfunc
+
+func Test_netrw_mkdir_default()
+ call SetShell('default')
+ call s:netrw_mkdir()
+endfunc
+
+func Test_netrw_mkdir_powershell()
+ call SetShell('powershell')
+ call s:netrw_mkdir()
+endfunc
+
+func Test_netrw_mkdir_pwsh()
+ call SetShell('pwsh')
+ call s:netrw_mkdir()
+endfunc
+
+func s:netrw_filecopy(count = 1)
+ " setup
+ let marked_files = []
+ let source_dir = netrw#fs#PathJoin($HOME, "src")
+ let target_dir = netrw#fs#PathJoin($HOME, "target")
+
+ call mkdir(source_dir, "R")
+ call mkdir(target_dir, "R")
+
+ for i in range(a:count)
+ call add(marked_files, $"testfile{i}.txt")
+ call writefile(
+ \ [$"NetrwMarkFileCopy test file {i}"],
+ \ netrw#fs#PathJoin(source_dir, marked_files[-1]))
+ endfor
+
+ " delegate
+ call Test_NetrwMarkFileCopy(source_dir, target_dir, marked_files)
+
+ " verify
+ for file in marked_files
+ call assert_equalfile(
+ \ netrw#fs#PathJoin(source_dir, file),
+ \ netrw#fs#PathJoin(target_dir, file),
+ \ "File copy failed for " . file)
+ endfor
+endfunc
+
+" Browser file copy
+func s:test_netrw_filecopy()
+
+ " if shellslash is available, check both settings
+ if exists('+shellslash')
+ set shellslash&
+ call s:netrw_filecopy(1)
+ call s:netrw_filecopy(10)
+ set shellslash!
+ endif
+
+ call s:netrw_filecopy(1)
+ call s:netrw_filecopy(10)
+
+endfunc
+
+func Test_netrw_filecopy_default()
+ call SetShell('default')
+ call s:test_netrw_filecopy()
+endfunc
+
+func Test_netrw_filecopy_powershell()
+ call SetShell('powershell')
+ call s:test_netrw_filecopy()
+endfunc
+
+func Test_netrw_filecopy_pwsh()
+ call SetShell('pwsh')
+ call s:test_netrw_filecopy()
+endfunc
+
+" Browser recursive directory copy
+func s:netrw_dircopy(count = 1)
+
+ " setup
+ let marked_dirname = "test_dir"
+ let marked_dir = netrw#fs#PathJoin($HOME, marked_dirname)
+ let target_dir = netrw#fs#PathJoin($HOME, "target")
+
+ call mkdir(marked_dir, "R")
+ call mkdir(target_dir, "R")
+
+ let dir_content = []
+ for i in range(a:count)
+ call add(dir_content, $"testfile{i}.txt")
+ call writefile(
+ \ [$"NetrwMarkFileCopy test dir content {i}"],
+ \ netrw#fs#PathJoin(marked_dir, dir_content[-1]))
+ endfor
+
+ " delegate
+ call Test_NetrwMarkFileCopy($HOME, target_dir, [marked_dirname])
+
+ " verify
+ for file in dir_content
+ call assert_equalfile(
+ \ netrw#fs#PathJoin(marked_dir, file),
+ \ netrw#fs#PathJoin(target_dir, marked_dirname, file),
+ \ "File copy failed for " . file)
+ endfor
+
+endfunc
+
+func s:test_netrw_dircopy()
+
+ " if shellslash is available, check both settings
+ if exists('+shellslash')
+ set shellslash&
+ call s:netrw_dircopy(10)
+ set shellslash!
+ endif
+
+ call s:netrw_dircopy(10)
+
+endfunc
+
+func Test_netrw_dircopy_default()
+ call SetShell('default')
+ call s:test_netrw_dircopy()
+endfunc
+
+func Test_netrw_dircopy_powershell()
+ call SetShell('powershell')
+ call s:test_netrw_dircopy()
+endfunc
+
+func Test_netrw_dircopy_pwsh()
+ call SetShell('pwsh')
+ call s:test_netrw_dircopy()
+endfunc
+
+" Copy file into the same directory with a different name
+func Test_netrw_dircopy_rename_default()
+ call SetShell('default')
+ call Test_NetrwMarkFileCopy_SameDir()
+endfunc
+
+func Test_netrw_dircopy_rename_powershell()
+ call SetShell('powershell')
+ call Test_NetrwMarkFileCopy_SameDir()
+endfunc
+
+func Test_netrw_dircopy_rename_pwsh()
+ call SetShell('pwsh')
+ call Test_NetrwMarkFileCopy_SameDir()
+endfunc
+
+" Browser file move
+func s:netrw_filemove(count = 1)
+ " setup
+ let marked_files = []
+ let source_dir = netrw#fs#PathJoin($HOME, "src")
+ let target_dir = netrw#fs#PathJoin($HOME, "target")
+
+ call mkdir(source_dir, "R")
+ call mkdir(target_dir, "R")
+
+ for i in range(a:count)
+ call add(marked_files, $"testfile{i}.txt")
+ call writefile(
+ \ [$"NetrwMarkFileMove test file {i}"],
+ \ netrw#fs#PathJoin(source_dir, marked_files[-1]))
+ endfor
+
+ " delegate
+ call Test_NetrwMarkFileMove(source_dir, target_dir, marked_files)
+
+ " verify
+ for i in range(a:count)
+ call assert_equal(
+ \ [$"NetrwMarkFileMove test file {i}"],
+ \ readfile(netrw#fs#PathJoin(target_dir, $"testfile{i}.txt")),
+ \ $"File move failed for testfile{i}.txt")
+ endfor
+endfunc
+
+func s:test_netrw_filemove()
+
+ " if shellslash is available, check both settings
+ if exists('+shellslash')
+ set shellslash&
+ call s:netrw_filemove(10)
+ set shellslash!
+ endif
+
+ call s:netrw_filemove(10)
+
+endfunc
+
+func Test_netrw_filemove_default()
+ call SetShell('default')
+ call s:test_netrw_filemove()
+endfunc
+
+func Test_netrw_filemove_powershell()
+ call SetShell('powershell')
+ call s:test_netrw_filemove()
+endfunc
+
+func Test_netrw_filemove_pwsh()
+ call SetShell('pwsh')
+ call s:test_netrw_filemove()
+endfunc
+
+func Test_netrw_reject_evil_hostname()
+ let msg = execute(':e scp://x;touch RCE;x/dir/')
+ let msg = split(msg, "\n")[-1]
+ call assert_match('Rejecting invalid hostname', msg)
+endfunc
+
+func Test_netrw_hostname()
+ let valid_hostnames = [
+ \ 'localhost',
+ \ '127.0.0.1',
+ \ '::1',
+ \ '0:0:0:0:0:0:0:1',
+ \ 'user@localhost',
+ \ 'usuario@127.0.0.1',
+ \ 'utilisateur@::1',
+ \ 'benutzer@0:0:0:0:0:0:0:1',
+ \ 'localhost:22',
+ \ '127.0.0.1:80',
+ \ '[::1]:443',
+ \ '[0:0:0:0:0:0:0:1]:5432',
+ \ 'user@localhost:22',
+ \ 'usuario@127.0.0.1:80',
+ \ 'utilisateur@[::1]:443',
+ \ 'benutzer@[0:0:0:0:0:0:0:1]:5432']
+
+ for hostname in valid_hostnames
+ call assert_true(Test_NetrwValidateHostname(hostname), $"Valid hostname {hostname} was rejected")
+ endfor
+endfunc
+
+func Test_netrw_FileUrlEdit_pipe_injection()
+ CheckExecutable id
+ let fname = 'Xtestfile'
+ let url = 'file:///tmp/file.md%7C!id>'..fname
+ sil call netrw#FileUrlEdit(url)
+ call assert_false(filereadable(fname), 'Command injection via pipe in file URL')
+endfunc
+
+" mnv:ts=8 sts=2 sw=2 et