patch 8.2.0174: various commands not completely tested

Problem:    Various commands not completely tested.
Solution:   Add more test cases. (Yegappan Lakshmanan, closes #5551)
diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim
index 992fc3d..37cc24c 100644
--- a/src/testdir/test_excmd.vim
+++ b/src/testdir/test_excmd.vim
@@ -44,3 +44,129 @@
   bwipeout bufb
   bwipeout bufc
 endfunc
+
+" Test for the :copy command
+func Test_copy()
+  new
+
+  call setline(1, ['L1', 'L2', 'L3', 'L4'])
+  " copy lines in a range to inside the range
+  1,3copy 2
+  call assert_equal(['L1', 'L2', 'L1', 'L2', 'L3', 'L3', 'L4'], getline(1, 7))
+
+  close!
+endfunc
+
+" Test for the :file command
+func Test_file_cmd()
+  call assert_fails('3file', 'E474:')
+  call assert_fails('0,0file', 'E474:')
+  call assert_fails('0file abc', 'E474:')
+endfunc
+
+" Test for the :drop command
+func Test_drop_cmd()
+  call writefile(['L1', 'L2'], 'Xfile')
+  enew | only
+  drop Xfile
+  call assert_equal('L2', getline(2))
+  " Test for switching to an existing window
+  below new
+  drop Xfile
+  call assert_equal(1, winnr())
+  " Test for splitting the current window
+  enew | only
+  set modified
+  drop Xfile
+  call assert_equal(2, winnr('$'))
+  " Check for setting the argument list
+  call assert_equal(['Xfile'], argv())
+  enew | only!
+  call delete('Xfile')
+endfunc
+
+" Test for the :append command
+func Test_append_cmd()
+  new
+  call setline(1, ['  L1'])
+  call feedkeys(":append\<CR>  L2\<CR>  L3\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L1', '  L2', '  L3'], getline(1, '$'))
+  %delete _
+  " append after a specific line
+  call setline(1, ['  L1', '  L2', '  L3'])
+  call feedkeys(":2append\<CR>  L4\<CR>  L5\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L1', '  L2', '  L4', '  L5', '  L3'], getline(1, '$'))
+  %delete _
+  " append with toggling 'autoindent'
+  call setline(1, ['  L1'])
+  call feedkeys(":append!\<CR>  L2\<CR>  L3\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L1', '    L2', '      L3'], getline(1, '$'))
+  call assert_false(&autoindent)
+  %delete _
+  " append with 'autoindent' set and toggling 'autoindent'
+  set autoindent
+  call setline(1, ['  L1'])
+  call feedkeys(":append!\<CR>  L2\<CR>  L3\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L1', '  L2', '  L3'], getline(1, '$'))
+  call assert_true(&autoindent)
+  set autoindent&
+  close!
+endfunc
+
+" Test for the :insert command
+func Test_insert_cmd()
+  new
+  call setline(1, ['  L1'])
+  call feedkeys(":insert\<CR>  L2\<CR>  L3\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L2', '  L3', '  L1'], getline(1, '$'))
+  %delete _
+  " insert before a specific line
+  call setline(1, ['  L1', '  L2', '  L3'])
+  call feedkeys(":2insert\<CR>  L4\<CR>  L5\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L1', '  L4', '  L5', '  L2', '  L3'], getline(1, '$'))
+  %delete _
+  " insert with toggling 'autoindent'
+  call setline(1, ['  L1'])
+  call feedkeys(":insert!\<CR>  L2\<CR>  L3\<CR>.\<CR>", 'xt')
+  call assert_equal(['    L2', '      L3', '  L1'], getline(1, '$'))
+  call assert_false(&autoindent)
+  %delete _
+  " insert with 'autoindent' set and toggling 'autoindent'
+  set autoindent
+  call setline(1, ['  L1'])
+  call feedkeys(":insert!\<CR>  L2\<CR>  L3\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L2', '  L3', '  L1'], getline(1, '$'))
+  call assert_true(&autoindent)
+  set autoindent&
+  close!
+endfunc
+
+" Test for the :change command
+func Test_change_cmd()
+  new
+  call setline(1, ['  L1', 'L2', 'L3'])
+  call feedkeys(":change\<CR>  L4\<CR>  L5\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L4', '  L5', 'L2', 'L3'], getline(1, '$'))
+  %delete _
+  " change a specific line
+  call setline(1, ['  L1', '  L2', '  L3'])
+  call feedkeys(":2change\<CR>  L4\<CR>  L5\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L1', '  L4', '  L5', '  L3'], getline(1, '$'))
+  %delete _
+  " change with toggling 'autoindent'
+  call setline(1, ['  L1', 'L2', 'L3'])
+  call feedkeys(":change!\<CR>  L4\<CR>  L5\<CR>.\<CR>", 'xt')
+  call assert_equal(['    L4', '      L5', 'L2', 'L3'], getline(1, '$'))
+  call assert_false(&autoindent)
+  %delete _
+  " change with 'autoindent' set and toggling 'autoindent'
+  set autoindent
+  call setline(1, ['  L1', 'L2', 'L3'])
+  call feedkeys(":change!\<CR>  L4\<CR>  L5\<CR>.\<CR>", 'xt')
+  call assert_equal(['  L4', '  L5', 'L2', 'L3'], getline(1, '$'))
+  call assert_true(&autoindent)
+  set autoindent&
+  close!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_fnameescape.vim b/src/testdir/test_fnameescape.vim
index b0fdb3a..cdb96ba 100644
--- a/src/testdir/test_fnameescape.vim
+++ b/src/testdir/test_fnameescape.vim
@@ -18,4 +18,10 @@
   endtry
   call assert_true(status, "ExclamationMark")
   call delete(fname)
+
+  call assert_equal('\-', fnameescape('-'))
+  call assert_equal('\+', fnameescape('+'))
+  call assert_equal('\>', fnameescape('>'))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_ga.vim b/src/testdir/test_ga.vim
index ea3d211..22f030c 100644
--- a/src/testdir/test_ga.vim
+++ b/src/testdir/test_ga.vim
@@ -18,6 +18,7 @@
   call assert_equal("\nNUL",                             Do_ga(''))
   call assert_equal("\n<^A>  1,  Hex 01,  Oct 001, Digr SH",    Do_ga("\x01"))
   call assert_equal("\n<^I>  9,  Hex 09,  Oct 011, Digr HT",    Do_ga("\t"))
+  call assert_equal("\n<^@>  0,  Hex 00,  Octal 000",    Do_ga("\n"))
 
   call assert_equal("\n<e>  101,  Hex 65,  Octal 145",   Do_ga('e'))
 
@@ -29,5 +30,13 @@
   call assert_equal("\n<e>  101,  Hex 65,  Octal 145 < ́> 769, Hex 0301, Octal 1401", Do_ga("e\u0301"))
   call assert_equal("\n<e>  101,  Hex 65,  Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461", Do_ga("e\u0301\u0331"))
   call assert_equal("\n<e>  101,  Hex 65,  Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461 < ̸> 824, Hex 0338, Octal 1470", Do_ga("e\u0301\u0331\u0338"))
+
+  " When using Mac fileformat, CR instead of NL is used for line termination
+  enew!
+  set fileformat=mac
+  call assert_equal("\n<^J>  10,  Hex 0a,  Oct 012, Digr NU",    Do_ga("\r"))
+
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_global.vim b/src/testdir/test_global.vim
index bdeaf8e..044839f 100644
--- a/src/testdir/test_global.vim
+++ b/src/testdir/test_global.vim
@@ -18,3 +18,11 @@
   call assert_equal(['nothing', '++found', 'found bad', 'bad'], getline(1, 4))
   bwipe!
 endfunc
+
+func Test_global_error()
+  call assert_fails('g\\a', 'E10:')
+  call assert_fails('g', 'E148:')
+  call assert_fails('g/\(/y', 'E476:')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_move.vim b/src/testdir/test_move.vim
index d774c93..f666a90 100644
--- a/src/testdir/test_move.vim
+++ b/src/testdir/test_move.vim
@@ -35,6 +35,11 @@
 
   call assert_fails('1,2move 1', 'E134')
   call assert_fails('2,3move 2', 'E134')
+  call assert_fails("move -100", 'E16:')
+  call assert_fails("move +100", 'E16:')
+  call assert_fails('move', 'E16:')
 
   %bwipeout!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 7a74af6..e3f2c10 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -640,3 +640,24 @@
   set novisualbell
   set belloff=all
 endfunc
+
+" Test for the 'write' option
+func Test_write()
+  new
+  call setline(1, ['L1'])
+  set nowrite
+  call assert_fails('write Xfile', 'E142:')
+  set write
+  close!
+endfunc
+
+" Test for 'buftype' option
+func Test_buftype()
+  new
+  call setline(1, ['L1'])
+  set buftype=nowrite
+  call assert_fails('write', 'E382:')
+  close!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_packadd.vim b/src/testdir/test_packadd.vim
index 6d0565b..fcb8b80 100644
--- a/src/testdir/test_packadd.vim
+++ b/src/testdir/test_packadd.vim
@@ -264,6 +264,8 @@
   call assert_match('look-here', tags1[0])
   let tags2 = readfile(docdir2 . '/tags') 
   call assert_match('look-away', tags2[0])
+
+  call assert_fails('helptags abcxyz', 'E150:')
 endfunc
 
 func Test_colorscheme()
@@ -355,3 +357,5 @@
   runtime! ALL extra/bar.vim
   call assert_equal('runstartopt', g:sequence)
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_sort.vim b/src/testdir/test_sort.vim
index 7da82b0..4abe31d 100644
--- a/src/testdir/test_sort.vim
+++ b/src/testdir/test_sort.vim
@@ -1150,7 +1150,7 @@
 	\    'input' : [
 	\	'1.234',
 	\	'0.88',
-	\	'123.456',
+	\	'  +  123.456',
 	\	'1.15e-6',
 	\	'-1.1e3',
 	\	'-1.01e3',
@@ -1165,7 +1165,7 @@
 	\	'1.15e-6',
 	\	'0.88',
 	\	'1.234',
-	\	'123.456'
+	\	'  +  123.456'
 	\    ]
 	\ },
 	\ {
@@ -1197,6 +1197,30 @@
 	\	'cc',
 	\    ]
 	\ },
+	\ {
+	\    'name' : 'sort one line buffer',
+	\    'cmd' : 'sort',
+	\    'input' : [
+	\	'single line'
+	\    ],
+	\    'expected' : [
+	\	'single line'
+	\    ]
+	\ },
+	\ {
+	\    'name' : 'sort ignoring case',
+	\    'cmd' : '%sort i',
+	\    'input' : [
+	\	'BB',
+	\	'Cc',
+	\	'aa'
+	\    ],
+	\    'expected' : [
+	\	'aa',
+	\	'BB',
+	\	'Cc'
+	\    ]
+	\ },
 	\ ]
 
   for t in tests
@@ -1217,7 +1241,11 @@
     endif
   endfor
 
-  call assert_fails('sort no', 'E474')
+  " Needs atleast two lines for this test
+  call setline(1, ['line1', 'line2'])
+  call assert_fails('sort no', 'E474:')
+  call assert_fails('sort c', 'E475:')
+  call assert_fails('sort #pat%', 'E682:')
 
   enew!
 endfunc
@@ -1321,4 +1349,46 @@
     " the output comes from the :g command, not from the :sort
     call assert_match("6 fewer lines", res)
     enew!
-  endfunc
+endfunc
+
+" Test for a :sort command followed by another command
+func Test_sort_followed_by_cmd()
+  new
+  let var = ''
+  call setline(1, ['cc', 'aa', 'bb'])
+  %sort | let var = "sortcmdtest"
+  call assert_equal(var, "sortcmdtest")
+  call assert_equal(['aa', 'bb', 'cc'], getline(1, '$'))
+  " Test for :sort followed by a comment
+  call setline(1, ['3b', '1c', '2a'])
+  %sort /\d\+/ " sort alphabetically
+  call assert_equal(['2a', '3b', '1c'], getline(1, '$'))
+  close!
+endfunc
+
+" Test for :sort using last search pattern
+func Test_sort_last_search_pat()
+  new
+  let @/ = '\d\+'
+  call setline(1, ['3b', '1c', '2a'])
+  sort //
+  call assert_equal(['2a', '3b', '1c'], getline(1, '$'))
+  close!
+endfunc
+
+" Test for retaining marks across a :sort
+func Test_sort_with_marks()
+  new
+  call setline(1, ['cc', 'aa', 'bb'])
+  call setpos("'c", [0, 1, 0, 0])
+  call setpos("'a", [0, 2, 0, 0])
+  call setpos("'b", [0, 3, 0, 0])
+  %sort
+  call assert_equal(['aa', 'bb', 'cc'], getline(1, '$'))
+  call assert_equal(2, line("'a"))
+  call assert_equal(3, line("'b"))
+  call assert_equal(1, line("'c"))
+  close!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
index c7532fb..abdbf68 100644
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -218,6 +218,8 @@
   call assert_fails('s/FOO/bar/', 'E486:')
   call assert_fails('s/foo/bar/@', 'E488:')
   call assert_fails('s/\(/bar/', 'E476:')
+  call assert_fails('s afooabara', 'E146:')
+  call assert_fails('s\\a', 'E10:')
 
   setl nomodifiable
   call assert_fails('s/foo/bar/', 'E21:')
@@ -745,3 +747,5 @@
   call assert_equal('#', getline(1))
   bwipe!
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_textformat.vim b/src/testdir/test_textformat.vim
index 2223be9..a49ef5c 100644
--- a/src/testdir/test_textformat.vim
+++ b/src/testdir/test_textformat.vim
@@ -424,6 +424,14 @@
 	      \ ], getline(1, '$'))
   enew!
 
+  " align text with 'wrapmargin'
+  call setline(1, ['Vim'])
+  set textwidth=0
+  set wrapmargin=60
+  right
+  call assert_equal("\t\t Vim", getline(1))
+  set wrapmargin&
+
   set tw&
 endfunc
 
diff --git a/src/testdir/test_writefile.vim b/src/testdir/test_writefile.vim
index 8eb2e78..db17e6f 100644
--- a/src/testdir/test_writefile.vim
+++ b/src/testdir/test_writefile.vim
@@ -179,3 +179,68 @@
   bwipe!
   set noautowrite
 endfunc
+
+" Test for ':w !<cmd>' to pipe lines from the current buffer to an external
+" command.
+func Test_write_pipe_to_cmd()
+  if !has('unix')
+    return
+  endif
+  new
+  call setline(1, ['L1', 'L2', 'L3', 'L4'])
+  2,3w !cat > Xfile
+  call assert_equal(['L2', 'L3'], readfile('Xfile'))
+  close!
+  call delete('Xfile')
+endfunc
+
+" Test for :saveas
+func Test_saveas()
+  call assert_fails('saveas', 'E471:')
+  call writefile(['L1'], 'Xfile')
+  new Xfile
+  new
+  call setline(1, ['L1'])
+  call assert_fails('saveas Xfile', 'E139:')
+  close!
+  enew | only
+  call delete('Xfile')
+endfunc
+
+func Test_write_errors()
+  " Test for writing partial buffer
+  call writefile(['L1', 'L2', 'L3'], 'Xfile')
+  new Xfile
+  call assert_fails('1,2write', 'E140:')
+  close!
+
+  " Try to overwrite a directory
+  if has('unix')
+    call mkdir('Xdir1')
+    call assert_fails('write Xdir1', 'E17:')
+    call delete('Xdir1', 'd')
+  endif
+
+  " Test for :wall for a buffer with no name
+  enew | only
+  call setline(1, ['L1'])
+  call assert_fails('wall', 'E141:')
+  enew!
+
+  " Test for writing a 'readonly' file
+  new Xfile
+  set readonly
+  call assert_fails('write', 'E45:')
+  close
+
+  " Test for writing to a read-only file
+  new Xfile
+  call setfperm('Xfile', 'r--r--r--')
+  call assert_fails('write', 'E505:')
+  call setfperm('Xfile', 'rw-rw-rw-')
+  close
+
+  call delete('Xfile')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab