aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/eval.c4
-rw-r--r--src/nvim/testdir/test_cmdline.vim29
-rw-r--r--src/nvim/testdir/test_expr.vim110
3 files changed, 114 insertions, 29 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index d9d276e8ea..245ad8d9d8 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -330,6 +330,10 @@ varnumber_T num_divide(varnumber_T n1, varnumber_T n2)
} else {
result = VARNUMBER_MAX;
}
+ } else if (n1 == VARNUMBER_MIN && n2 == -1) {
+ // specific case: trying to do VARNUMBAR_MIN / -1 results in a positive
+ // number that doesn't fit in varnumber_T and causes an FPE
+ result = VARNUMBER_MAX;
} else {
result = n1 / n2;
}
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 3f8e141afa..f37e8be59a 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -349,35 +349,6 @@ func Test_highlight_completion()
call assert_equal([], getcompletion('A', 'highlight'))
endfunc
-func Test_expr_completion()
- if !has('cmdline_compl')
- return
- endif
- for cmd in [
- \ 'let a = ',
- \ 'const a = ',
- \ 'if',
- \ 'elseif',
- \ 'while',
- \ 'for',
- \ 'echo',
- \ 'echon',
- \ 'execute',
- \ 'echomsg',
- \ 'echoerr',
- \ 'call',
- \ 'return',
- \ 'cexpr',
- \ 'caddexpr',
- \ 'cgetexpr',
- \ 'lexpr',
- \ 'laddexpr',
- \ 'lgetexpr']
- call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
- call assert_equal('"' . cmd . ' getline(', getreg(':'))
- endfor
-endfunc
-
func Test_getcompletion()
if !has('cmdline_compl')
return
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 15622cd6fe..c63a969e50 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -1,5 +1,7 @@
" Tests for expressions.
+source check.vim
+
func Test_equal()
let base = {}
func base.method()
@@ -76,6 +78,17 @@ func Test_strcharpart()
call assert_equal('', strcharpart('axb', -2, 2))
call assert_equal('a', strcharpart('axb', -1, 2))
+
+ call assert_equal('edit', "editor"[-10:3])
+endfunc
+
+func Test_getreg_empty_list()
+ call assert_equal('', getreg('x'))
+ call assert_equal([], getreg('x', 1, 1))
+ let x = getreg('x', 1, 1)
+ let y = x
+ call add(x, 'foo')
+ call assert_equal(['foo'], y)
endfunc
func Test_loop_over_null_list()
@@ -529,6 +542,7 @@ func Test_function_with_funcref()
call assert_fails("call function('foo()')", 'E475:')
call assert_fails("call function('foo()')", 'foo()')
+ call assert_fails("function('')", 'E129:')
endfunc
func Test_funcref()
@@ -587,3 +601,99 @@ func Test_eval_after_if()
if 0 | eval SetVal('a') | endif | call SetVal('b')
call assert_equal('b', s:val)
endfunc
+
+func Test_divide_by_zero()
+ " only tests that this doesn't crash, the result is not important
+ echo 0 / 0
+ echo 0 / 0 / -1
+endfunc
+
+" Test for command-line completion of expressions
+func Test_expr_completion()
+ CheckFeature cmdline_compl
+ for cmd in [
+ \ 'let a = ',
+ \ 'const a = ',
+ \ 'if',
+ \ 'elseif',
+ \ 'while',
+ \ 'for',
+ \ 'echo',
+ \ 'echon',
+ \ 'execute',
+ \ 'echomsg',
+ \ 'echoerr',
+ \ 'call',
+ \ 'return',
+ \ 'cexpr',
+ \ 'caddexpr',
+ \ 'cgetexpr',
+ \ 'lexpr',
+ \ 'laddexpr',
+ \ 'lgetexpr']
+ call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"' . cmd . ' getline(', getreg(':'))
+ endfor
+
+ " completion for the expression register
+ call feedkeys(":\"\<C-R>=float2\t\"\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"float2nr("', @=)
+
+ " completion for window local variables
+ let w:wvar1 = 10
+ let w:wvar2 = 10
+ call feedkeys(":echo w:wvar\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"echo w:wvar1 w:wvar2', @:)
+ unlet w:wvar1 w:wvar2
+
+ " completion for tab local variables
+ let t:tvar1 = 10
+ let t:tvar2 = 10
+ call feedkeys(":echo t:tvar\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"echo t:tvar1 t:tvar2', @:)
+ unlet t:tvar1 t:tvar2
+
+ " completion for variables
+ let g:tvar1 = 1
+ let g:tvar2 = 2
+ call feedkeys(":let g:tv\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"let g:tvar1 g:tvar2', @:)
+ " completion for variables after a ||
+ call feedkeys(":echo 1 || g:tv\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"echo 1 || g:tvar1 g:tvar2', @:)
+
+ " completion for options
+ call feedkeys(":echo &compat\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"echo &compatible', @:)
+ call feedkeys(":echo 1 && &compat\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"echo 1 && &compatible', @:)
+ call feedkeys(":echo &g:equala\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"echo &g:equalalways', @:)
+
+ " completion for string
+ call feedkeys(":echo \"Hello\\ World\"\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal("\"echo \"Hello\\ World\"\<C-A>", @:)
+ call feedkeys(":echo 'Hello World'\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal("\"echo 'Hello World'\<C-A>", @:)
+
+ " completion for command after a |
+ call feedkeys(":echo 'Hello' | cwin\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal("\"echo 'Hello' | cwindow", @:)
+
+ " completion for environment variable
+ let $X_VIM_TEST_COMPLETE_ENV = 'foo'
+ call feedkeys(":let $X_VIM_TEST_COMPLETE_E\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('"let $X_VIM_TEST_COMPLETE_ENV', @:)
+ unlet $X_VIM_TEST_COMPLETE_ENV
+endfunc
+
+" Test for errors in expression evaluation
+func Test_expr_eval_error()
+ call assert_fails("let i = 'abc' . []", 'E730:')
+ call assert_fails("let l = [] + 10", 'E745:')
+ call assert_fails("let v = 10 + []", 'E745:')
+ call assert_fails("let v = 10 / []", 'E745:')
+ call assert_fails("let v = -{}", 'E728:')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab