Merge remote-tracking branch 'origin/master' into vim-7.4.1975

This commit is contained in:
James McCoy 2017-06-06 07:33:50 -04:00
commit 9281653233
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB
21 changed files with 580 additions and 118 deletions

View File

@ -8,7 +8,8 @@ low-risk/isolated tasks:
- Merge a [Vim patch].
- Try a [complexity:low] issue.
- Fix bugs found by [clang-scan], [coverity](#coverity), and [PVS](#pvs-studio).
- Fix bugs found by [clang scan-build](#clang-scan-build),
[coverity](#coverity), and [PVS](#pvs-studio).
Developer guidelines
--------------------
@ -112,6 +113,15 @@ QuickBuild uses this invocation:
VERBOSE=1 nvim unittest-prereqs functionaltest-prereqs
### Clang scan-build
The auto-generated [clang-scan] report presents walk-throughs of bugs found by
Clang's [scan-build](https://clang-analyzer.llvm.org/scan-build.html) static
analyzer. To verify a fix locally, run `scan-build` like this:
rm -rf build/
scan-build --use-analyzer=/usr/bin/clang make
### Coverity
[Coverity](https://scan.coverity.com/projects/neovim-neovim) runs against the

View File

@ -1943,16 +1943,23 @@ argidx() Number current index in the argument list
arglistid([{winnr} [, {tabnr}]]) Number argument list id
argv({nr}) String {nr} entry of the argument list
argv() List the argument list
assert_equal({exp}, {act} [, {msg}]) none assert {exp} is equal to {act}
assert_exception( {error} [, {msg}]) none assert {error} is in v:exception
assert_fails( {cmd} [, {error}]) none assert {cmd} fails
assert_false({actual} [, {msg}]) none assert {actual} is false
assert_equal({exp}, {act} [, {msg}])
none assert {exp} is equal to {act}
assert_exception({error} [, {msg}])
none assert {error} is in v:exception
assert_fails({cmd} [, {error}]) none assert {cmd} fails
assert_false({actual} [, {msg}])
none assert {actual} is false
assert_inrange({lower}, {upper}, {actual} [, {msg}])
none assert {actual} is inside the range
assert_match( {pat}, {text} [, {msg}]) none assert {pat} matches {text}
assert_notequal( {exp}, {act} [, {msg}]) none assert {exp} is not equal {act}
assert_notmatch( {pat}, {text} [, {msg}]) none assert {pat} not matches {text}
assert_true({actual} [, {msg}]) none assert {actual} is true
assert_match({pat}, {text} [, {msg}])
none assert {pat} matches {text}
assert_notequal({exp}, {act} [, {msg}])
none assert {exp} is not equal {act}
assert_notmatch({pat}, {text} [, {msg}])
none assert {pat} not matches {text}
assert_report({msg}) none report a test failure
assert_true({actual} [, {msg}]) none assert {actual} is true
asin({expr}) Float arc sine of {expr}
atan({expr}) Float arc tangent of {expr}
atan2({expr}, {expr}) Float arc tangent of {expr1} / {expr2}
@ -2508,6 +2515,9 @@ assert_notmatch({pattern}, {actual} [, {msg}])
The opposite of `assert_match()`: add an error message to
|v:errors| when {pattern} matches {actual}.
assert_report({msg}) *assert_report()*
Report a test failure directly, using {msg}.
assert_true({actual} [, {msg}]) *assert_true()*
When {actual} is not true an error message is added to
|v:errors|, like with |assert_equal()|.
@ -3641,11 +3651,14 @@ foldtext() Returns a String, to be displayed for a closed fold. This is
|v:foldstart|, |v:foldend| and |v:folddashes| variables.
The returned string looks like this: >
+-- 45 lines: abcdef
< The number of dashes depends on the foldlevel. The "45" is
the number of lines in the fold. "abcdef" is the text in the
first non-blank line of the fold. Leading white space, "//"
or "/*" and the text from the 'foldmarker' and 'commentstring'
options is removed.
< The number of leading dashes depends on the foldlevel. The
"45" is the number of lines in the fold. "abcdef" is the text
in the first non-blank line of the fold. Leading white space,
"//" or "/*" and the text from the 'foldmarker' and
'commentstring' options is removed.
When used to draw the actual foldtext, the rest of the line
will be filled with the fold char from the 'fillchars'
setting.
{not available when compiled without the |+folding| feature}
foldtextresult({lnum}) *foldtextresult()*

View File

@ -679,7 +679,7 @@ vim.Function object *python-Function*
8. pyeval() and py3eval() Vim functions *python-pyeval*
To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()|
functions to evaluate Python expressions and pass their values to VimL.
functions to evaluate Python expressions and pass their values to Vim script.
==============================================================================
9. Python 3 *python3*

View File

@ -3285,8 +3285,8 @@ Some folding is now supported with syntax/vim.vim: >
g:vimsyn_folding =~ 'P' : fold python script
<
*g:vimsyn_noerror*
Not all error highlighting that syntax/vim.vim does may be correct; VimL is a
difficult language to highlight correctly. A way to suppress error
Not all error highlighting that syntax/vim.vim does may be correct; Vim script
is a difficult language to highlight correctly. A way to suppress error
highlighting is to put the following line in your |vimrc|: >
let g:vimsyn_noerror = 1

View File

@ -578,7 +578,7 @@ Summary: *help-summary* >
register: >
:help quote:
13) Vim Script (VimL) is available at >
13) Vim Script is available at >
:help eval.txt
< Certain aspects of the language are available at :h expr-X where "X" is a
single letter. E.g. >
@ -588,10 +588,10 @@ Summary: *help-summary* >
Also important is >
:help function-list
< to find a short description of all functions available. Help topics for
VimL functions always include the "()", so: >
Vim script functions always include the "()", so: >
:help append()
< talks about the append VimL function rather than how to append text in the
current buffer.
< talks about the append Vim script function rather than how to append text
in the current buffer.
14) Mappings are talked about in the help page :h |map.txt|. Use >
:help mapmode-i

View File

@ -1189,7 +1189,7 @@ int get_spellword(list_T *list, const char **pp)
}
// Call some vimL function and return the result in "*rettv".
// Call some vim script function and return the result in "*rettv".
// Uses argv[argc] for the function arguments. Only Number and String
// arguments are currently supported.
//
@ -1256,18 +1256,16 @@ int call_vim_function(
return ret;
}
/*
* Call vimL function "func" and return the result as a number.
* Returns -1 when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
varnumber_T
call_func_retnr(
char_u *func,
int argc,
const char_u *const *const argv,
int safe // use the sandbox
)
/// Call Vim script function and return the result as a number
///
/// @param[in] func Function name.
/// @param[in] argc Number of arguments.
/// @param[in] argv Array with string arguments.
/// @param[in] safe Use with sandbox.
///
/// @return -1 when calling function fails, result of function otherwise.
varnumber_T call_func_retnr(char_u *func, int argc,
const char_u *const *const argv, int safe)
{
typval_T rettv;
varnumber_T retval;
@ -1281,14 +1279,14 @@ call_func_retnr(
return retval;
}
/// Call VimL function and return the result as a string
/// Call Vim script function and return the result as a string
///
/// @param[in] func Function name.
/// @param[in] argc Number of arguments.
/// @param[in] argv Array with string arguments.
/// @param[in] safe Use the sandbox.
///
/// @return [allocated] NULL when calling function failes, allocated string
/// @return [allocated] NULL when calling function fails, allocated string
/// otherwise.
char *call_func_retstr(const char *const func, const int argc,
const char_u *const *const argv,
@ -1307,18 +1305,17 @@ char *call_func_retstr(const char *const func, const int argc,
return retval;
}
/*
* Call vimL function "func" and return the result as a List.
* Uses argv[argc] for the function arguments.
* Returns NULL when there is something wrong.
*/
void *
call_func_retlist (
char_u *func,
int argc,
const char_u *const *const argv,
int safe // use the sandbox
)
/// Call Vim script function and return the result as a List
///
/// @param[in] func Function name.
/// @param[in] argc Number of arguments.
/// @param[in] argv Array with string arguments.
/// @param[in] safe Use the sandbox.
///
/// @return [allocated] NULL when calling function fails or return tv is not a
/// List, allocated List otherwise.
void *call_func_retlist(char_u *func, int argc, const char_u *const *const argv,
int safe)
{
typval_T rettv;
@ -5900,6 +5897,19 @@ size_t string2float(const char *const text, float_T *const ret_value)
{
char *s = NULL;
// MS-Windows does not deal with "inf" and "nan" properly
if (STRNICMP(text, "inf", 3) == 0) {
*ret_value = INFINITY;
return 3;
}
if (STRNICMP(text, "-inf", 3) == 0) {
*ret_value = -INFINITY;
return 4;
}
if (STRNICMP(text, "nan", 3) == 0) {
*ret_value = NAN;
return 3;
}
*ret_value = strtod(text, &s);
return (size_t) (s - text);
}
@ -6796,6 +6806,17 @@ static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
assert_equal_common(argvars, ASSERT_NOTEQUAL);
}
/// "assert_report(msg)
static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
prepare_assert_error(&ga);
ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
assert_error(&ga);
ga_clear(&ga);
}
/// "assert_exception(string[, msg])" function
static void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@ -15688,11 +15709,15 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
bool isneg = (*p == '-');
if (*p == '+') {
if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
}
(void)string2float((char *)p, &rettv->vval.v_float);
if (isneg) {
rettv->vval.v_float *= -1;
}
rettv->v_type = VAR_FLOAT;
}
@ -15712,7 +15737,8 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
if (*p == '+') {
bool isneg = (*p == '-');
if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
}
switch (base) {
@ -15733,7 +15759,11 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
rettv->vval.v_number = n;
if (isneg) {
rettv->vval.v_number = -n;
} else {
rettv->vval.v_number = n;
}
}
/*
@ -19842,9 +19872,15 @@ void ex_function(exarg_T *eap)
}
}
/* Check for ":append" or ":insert". */
// Check for ":append", ":change", ":insert".
p = skip_range(p, NULL);
if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
|| (p[0] == 'c'
&& (!ASCII_ISALPHA(p[1])
|| (p[1] == 'h' && (!ASCII_ISALPHA(p[2])
|| (p[2] == 'a'
&& (STRNCMP(&p[3], "nge", 3) != 0
|| !ASCII_ISALPHA(p[6])))))))
|| (p[0] == 'i'
&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
&& (!ASCII_ISALPHA(p[2])

View File

@ -33,6 +33,7 @@ return {
assert_match={args={2, 3}},
assert_notequal={args={2, 3}},
assert_notmatch={args={2, 3}},
assert_report={args=1},
assert_true={args={1, 2}},
atan={args=1, func="float_op_wrapper", data="&atan"},
atan2={args=2},

View File

@ -4174,10 +4174,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
}
}
/*
* Call "user_expand_func()" to invoke a user defined VimL function and return
* the result (either a string or a List).
*/
/// Call "user_expand_func()" to invoke a user defined Vim script function and
/// return the result (either a string or a List).
static void * call_user_expand_func(user_expand_func_T user_expand_func,
expand_T *xp, int *num_file, char_u ***file)
{

View File

@ -68,7 +68,7 @@ NEW_TESTS ?= \
test_timers.res \
test_undo.res \
test_usercommands.res \
test_viml.res \
test_vimscript.res \
test_visual.res \
test_window_id.res \
test_writefile.res \

View File

@ -76,7 +76,7 @@ set listchars=eol:$
" Prevent Nvim log from writing to stderr.
let $NVIM_LOG_FILE='Xnvim.log'
function RunTheTest(test)
func RunTheTest(test)
echo 'Executing ' . a:test
if exists("*SetUp")
call SetUp()
@ -113,6 +113,60 @@ function RunTheTest(test)
set nomodified
endfunc
func AfterTheTest()
if len(v:errors) > 0
let s:fail += 1
call add(s:errors, 'Found errors in ' . s:test . ':')
call extend(s:errors, v:errors)
let v:errors = []
endif
endfunc
" This function can be called by a test if it wants to abort testing.
func FinishTesting()
call AfterTheTest()
" Don't write viminfo on exit.
set viminfo=
if s:fail == 0
" Success, create the .res file so that make knows it's done.
exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
write
endif
if len(s:errors) > 0
" Append errors to test.log
split test.log
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:errors)
write
endif
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
echo message
call add(s:messages, message)
if s:fail > 0
let message = s:fail . ' FAILED:'
echo message
call add(s:messages, message)
call extend(s:messages, s:errors)
endif
" Add SKIPPED messages
call extend(s:messages, s:skipped)
" Append messages to the file "messages"
split messages
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:messages)
write
qall!
endfunc
" Source the test script. First grab the file name, in case the script
" navigates away. g:testname can be used by the tests.
let g:testname = expand('%')
@ -121,7 +175,7 @@ let s:fail = 0
let s:errors = []
let s:messages = []
let s:skipped = []
if expand('%') =~ 'test_viml.vim'
if expand('%') =~ 'test_vimscript.vim'
" this test has intentional s:errors, don't use try/catch.
source %
else
@ -157,56 +211,14 @@ for s:test in sort(s:tests)
call RunTheTest(s:test)
if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
call add(s:messages, 'Flaky test failed, running it again')
let v:errors = []
call RunTheTest(s:test)
endif
if len(v:errors) > 0
let s:fail += 1
call add(s:errors, 'Found errors in ' . s:test . ':')
call extend(s:errors, v:errors)
call add(s:messages, 'Flaky test failed, running it again')
let v:errors = []
call RunTheTest(s:test)
endif
call AfterTheTest()
endfor
" Don't write viminfo on exit.
set viminfo=
call FinishTesting()
if s:fail == 0
" Success, create the .res file so that make knows it's done.
exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
write
endif
if len(s:errors) > 0
" Append errors to test.log
split test.log
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:errors)
write
endif
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests': ' test')
echo message
call add(s:messages, message)
if s:fail > 0
let message = s:fail . ' FAILED'
echo message
call add(s:messages, message)
call extend(s:messages, s:errors)
endif
" Add SKIPPED messages
call extend(s:messages, s:skipped)
" Append messages to the file "messages"
split messages
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:messages)
write
qall!
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -608,7 +608,7 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
" Tests 1 to 15 were moved to test_viml.vim
" Tests 1 to 15 were moved to test_vimscript.vim
let Xtest = 16
"-------------------------------------------------------------------------------

View File

@ -10,6 +10,8 @@ source test_expr_utf8.vim
source test_feedkeys.vim
source test_filter_cmd.vim
source test_filter_map.vim
source test_float_func.vim
source test_functions.vim
source test_goto.vim
source test_jumps.vim
source test_lambda.vim

View File

@ -28,7 +28,7 @@ func Test_cscopeWithCscopeConnections()
cscope add Xcscope.out
set cscopeverbose
catch
call assert_true(0)
call assert_report('exception thrown')
endtry
call assert_fails('cscope add', 'E560')
call assert_fails('cscope add Xcscope.out', 'E568')

View File

@ -1,13 +1,7 @@
" Tests for cursor().
func Test_wrong_arguments()
try
call cursor(1. 3)
" not reached
call assert_false(1)
catch
call assert_exception('E474:')
endtry
call assert_fails('call cursor(1. 3)', 'E474:')
endfunc
func Test_move_cursor()

View File

@ -78,7 +78,7 @@ endfunc
func Test_loop_over_null_list()
let null_list = submatch(1, 1)
for i in null_list
call assert_true(0, 'should not get here')
call assert_report('should not get here')
endfor
endfunc

View File

@ -0,0 +1,285 @@
" test float functions
if !has('float')
finish
end
func Test_abs()
call assert_equal('1.23', string(abs(1.23)))
call assert_equal('1.23', string(abs(-1.23)))
call assert_equal('0.0', string(abs(0.0)))
call assert_equal('0.0', string(abs(1.0/(1.0/0.0))))
call assert_equal('0.0', string(abs(-1.0/(1.0/0.0))))
call assert_equal("str2float('inf')", string(abs(1.0/0.0)))
call assert_equal("str2float('inf')", string(abs(-1.0/0.0)))
call assert_equal("str2float('nan')", string(abs(0.0/0.0)))
call assert_equal('12', string(abs('-12abc')))
call assert_fails("call abs([])", 'E745:')
call assert_fails("call abs({})", 'E728:')
call assert_fails("call abs(function('string'))", 'E703:')
endfunc
func Test_sqrt()
call assert_equal('0.0', string(sqrt(0.0)))
call assert_equal('1.414214', string(sqrt(2.0)))
call assert_equal("str2float('inf')", string(sqrt(1.0/0.0)))
call assert_equal("str2float('nan')", string(sqrt(-1.0)))
call assert_equal("str2float('nan')", string(sqrt(0.0/0.0)))
call assert_fails('call sqrt("")', 'E808:')
endfunc
func Test_log()
call assert_equal('0.0', string(log(1.0)))
call assert_equal('-0.693147', string(log(0.5)))
call assert_equal("-str2float('inf')", string(log(0.0)))
call assert_equal("str2float('nan')", string(log(-1.0)))
call assert_equal("str2float('inf')", string(log(1.0/0.0)))
call assert_equal("str2float('nan')", string(log(0.0/0.0)))
call assert_fails('call log("")', 'E808:')
endfunc
func Test_log10()
call assert_equal('0.0', string(log10(1.0)))
call assert_equal('2.0', string(log10(100.0)))
call assert_equal('2.079181', string(log10(120.0)))
call assert_equal("-str2float('inf')", string(log10(0.0)))
call assert_equal("str2float('nan')", string(log10(-1.0)))
call assert_equal("str2float('inf')", string(log10(1.0/0.0)))
call assert_equal("str2float('nan')", string(log10(0.0/0.0)))
call assert_fails('call log10("")', 'E808:')
endfunc
func Test_exp()
call assert_equal('1.0', string(exp(0.0)))
call assert_equal('7.389056', string(exp(2.0)))
call assert_equal('0.367879', string(exp(-1.0)))
call assert_equal("str2float('inf')", string(exp(1.0/0.0)))
call assert_equal('0.0', string(exp(-1.0/0.0)))
call assert_equal("str2float('nan')", string(exp(0.0/0.0)))
call assert_fails('call exp("")', 'E808:')
endfunc
func Test_sin()
call assert_equal('0.0', string(sin(0.0)))
call assert_equal('0.841471', string(sin(1.0)))
call assert_equal('-0.479426', string(sin(-0.5)))
call assert_equal("str2float('nan')", string(sin(0.0/0.0)))
call assert_equal("str2float('nan')", string(sin(1.0/0.0)))
call assert_equal('0.0', string(sin(1.0/(1.0/0.0))))
call assert_equal('-0.0', string(sin(-1.0/(1.0/0.0))))
call assert_fails('call sin("")', 'E808:')
endfunc
func Test_asin()
call assert_equal('0.0', string(asin(0.0)))
call assert_equal('1.570796', string(asin(1.0)))
call assert_equal('-0.523599', string(asin(-0.5)))
call assert_equal("str2float('nan')", string(asin(1.1)))
call assert_equal("str2float('nan')", string(asin(1.0/0.0)))
call assert_equal("str2float('nan')", string(asin(0.0/0.0)))
call assert_fails('call asin("")', 'E808:')
endfunc
func Test_sinh()
call assert_equal('0.0', string(sinh(0.0)))
call assert_equal('0.521095', string(sinh(0.5)))
call assert_equal('-1.026517', string(sinh(-0.9)))
call assert_equal("str2float('inf')", string(sinh(1.0/0.0)))
call assert_equal("-str2float('inf')", string(sinh(-1.0/0.0)))
call assert_equal("str2float('nan')", string(sinh(0.0/0.0)))
call assert_fails('call sinh("")', 'E808:')
endfunc
func Test_cos()
call assert_equal('1.0', string(cos(0.0)))
call assert_equal('0.540302', string(cos(1.0)))
call assert_equal('0.877583', string(cos(-0.5)))
call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
call assert_equal("str2float('nan')", string(cos(1.0/0.0)))
call assert_fails('call cos("")', 'E808:')
endfunc
func Test_acos()
call assert_equal('1.570796', string(acos(0.0)))
call assert_equal('0.0', string(acos(1.0)))
call assert_equal('3.141593', string(acos(-1.0)))
call assert_equal('2.094395', string(acos(-0.5)))
call assert_equal("str2float('nan')", string(acos(1.1)))
call assert_equal("str2float('nan')", string(acos(1.0/0.0)))
call assert_equal("str2float('nan')", string(acos(0.0/0.0)))
call assert_fails('call acos("")', 'E808:')
endfunc
func Test_cosh()
call assert_equal('1.0', string(cosh(0.0)))
call assert_equal('1.127626', string(cosh(0.5)))
call assert_equal("str2float('inf')", string(cosh(1.0/0.0)))
call assert_equal("str2float('inf')", string(cosh(-1.0/0.0)))
call assert_equal("str2float('nan')", string(cosh(0.0/0.0)))
call assert_fails('call cosh("")', 'E808:')
endfunc
func Test_tan()
call assert_equal('0.0', string(tan(0.0)))
call assert_equal('0.546302', string(tan(0.5)))
call assert_equal('-0.546302', string(tan(-0.5)))
call assert_equal("str2float('nan')", string(tan(1.0/0.0)))
call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
call assert_equal('0.0', string(tan(1.0/(1.0/0.0))))
call assert_equal('-0.0', string(tan(-1.0/(1.0/0.0))))
call assert_fails('call tan("")', 'E808:')
endfunc
func Test_atan()
call assert_equal('0.0', string(atan(0.0)))
call assert_equal('0.463648', string(atan(0.5)))
call assert_equal('-0.785398', string(atan(-1.0)))
call assert_equal('1.570796', string(atan(1.0/0.0)))
call assert_equal('-1.570796', string(atan(-1.0/0.0)))
call assert_equal("str2float('nan')", string(atan(0.0/0.0)))
call assert_fails('call atan("")', 'E808:')
endfunc
func Test_atan2()
call assert_equal('-2.356194', string(atan2(-1, -1)))
call assert_equal('2.356194', string(atan2(1, -1)))
call assert_equal('0.0', string(atan2(1.0, 1.0/0.0)))
call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0)))
call assert_equal("str2float('nan')", string(atan2(0.0/0.0, 1.0)))
call assert_fails('call atan2("", -1)', 'E808:')
call assert_fails('call atan2(-1, "")', 'E808:')
endfunc
func Test_tanh()
call assert_equal('0.0', string(tanh(0.0)))
call assert_equal('0.462117', string(tanh(0.5)))
call assert_equal('-0.761594', string(tanh(-1.0)))
call assert_equal('1.0', string(tanh(1.0/0.0)))
call assert_equal('-1.0', string(tanh(-1.0/0.0)))
call assert_equal("str2float('nan')", string(tanh(0.0/0.0)))
call assert_fails('call tanh("")', 'E808:')
endfunc
func Test_fmod()
call assert_equal('0.13', string(fmod(12.33, 1.22)))
call assert_equal('-0.13', string(fmod(-12.33, 1.22)))
call assert_equal("str2float('nan')", string(fmod(1.0/0.0, 1.0)))
" On Windows we get "nan" instead of 1.0, accept both.
let res = string(fmod(1.0, 1.0/0.0))
if res != "str2float('nan')"
call assert_equal('1.0', res)
endif
call assert_equal("str2float('nan')", string(fmod(1.0, 0.0)))
call assert_fails("call fmod('', 1.22)", 'E808:')
call assert_fails("call fmod(12.33, '')", 'E808:')
endfunc
func Test_pow()
call assert_equal('1.0', string(pow(0.0, 0.0)))
call assert_equal('8.0', string(pow(2.0, 3.0)))
call assert_equal("str2float('nan')", string(pow(2.0, 0.0/0.0)))
call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
call assert_equal("str2float('inf')", string(pow(2.0, 1.0/0.0)))
call assert_equal("str2float('inf')", string(pow(1.0/0.0, 3.0)))
call assert_fails("call pow('', 2.0)", 'E808:')
call assert_fails("call pow(2.0, '')", 'E808:')
endfunc
func Test_str2float()
call assert_equal('1.0', string(str2float('1')))
call assert_equal('1.0', string(str2float(' 1 ')))
call assert_equal('1.0', string(str2float(' 1.0 ')))
call assert_equal('1.23', string(str2float('1.23')))
call assert_equal('1.23', string(str2float('1.23abc')))
call assert_equal('1.0e40', string(str2float('1e40')))
call assert_equal('-1.23', string(str2float('-1.23')))
call assert_equal('1.23', string(str2float(' + 1.23 ')))
call assert_equal('1.0', string(str2float('+1')))
call assert_equal('1.0', string(str2float('+1')))
call assert_equal('1.0', string(str2float(' +1 ')))
call assert_equal('1.0', string(str2float(' + 1 ')))
call assert_equal('-1.0', string(str2float('-1')))
call assert_equal('-1.0', string(str2float('-1')))
call assert_equal('-1.0', string(str2float(' -1 ')))
call assert_equal('-1.0', string(str2float(' - 1 ')))
call assert_equal('0.0', string(str2float('+0.0')))
call assert_equal('-0.0', string(str2float('-0.0')))
call assert_equal("str2float('inf')", string(str2float('1e1000')))
call assert_equal("str2float('inf')", string(str2float('inf')))
call assert_equal("-str2float('inf')", string(str2float('-inf')))
call assert_equal("str2float('inf')", string(str2float('+inf')))
call assert_equal("str2float('inf')", string(str2float('Inf')))
call assert_equal("str2float('inf')", string(str2float(' +inf ')))
call assert_equal("str2float('nan')", string(str2float('nan')))
call assert_equal("str2float('nan')", string(str2float('NaN')))
call assert_equal("str2float('nan')", string(str2float(' nan ')))
call assert_fails("call str2float(1.2)", 'E806:')
call assert_fails("call str2float([])", 'E730:')
call assert_fails("call str2float({})", 'E731:')
call assert_fails("call str2float(function('string'))", 'E729:')
endfunc
func Test_floor()
call assert_equal('2.0', string(floor(2.0)))
call assert_equal('2.0', string(floor(2.11)))
call assert_equal('2.0', string(floor(2.99)))
call assert_equal('-3.0', string(floor(-2.11)))
call assert_equal('-3.0', string(floor(-2.99)))
call assert_equal("str2float('nan')", string(floor(0.0/0.0)))
call assert_equal("str2float('inf')", string(floor(1.0/0.0)))
call assert_equal("-str2float('inf')", string(floor(-1.0/0.0)))
call assert_fails("call floor('')", 'E808:')
endfunc
func Test_ceil()
call assert_equal('2.0', string(ceil(2.0)))
call assert_equal('3.0', string(ceil(2.11)))
call assert_equal('3.0', string(ceil(2.99)))
call assert_equal('-2.0', string(ceil(-2.11)))
call assert_equal('-2.0', string(ceil(-2.99)))
call assert_equal("str2float('nan')", string(ceil(0.0/0.0)))
call assert_equal("str2float('inf')", string(ceil(1.0/0.0)))
call assert_equal("-str2float('inf')", string(ceil(-1.0/0.0)))
call assert_fails("call ceil('')", 'E808:')
endfunc
func Test_round()
call assert_equal('2.0', string(round(2.1)))
call assert_equal('3.0', string(round(2.5)))
call assert_equal('3.0', string(round(2.9)))
call assert_equal('-2.0', string(round(-2.1)))
call assert_equal('-3.0', string(round(-2.5)))
call assert_equal('-3.0', string(round(-2.9)))
call assert_equal("str2float('nan')", string(round(0.0/0.0)))
call assert_equal("str2float('inf')", string(round(1.0/0.0)))
call assert_equal("-str2float('inf')", string(round(-1.0/0.0)))
call assert_fails("call round('')", 'E808:')
endfunc
func Test_trunc()
call assert_equal('2.0', string(trunc(2.1)))
call assert_equal('2.0', string(trunc(2.5)))
call assert_equal('2.0', string(trunc(2.9)))
call assert_equal('-2.0', string(trunc(-2.1)))
call assert_equal('-2.0', string(trunc(-2.5)))
call assert_equal('-2.0', string(trunc(-2.9)))
call assert_equal("str2float('nan')", string(trunc(0.0/0.0)))
call assert_equal("str2float('inf')", string(trunc(1.0/0.0)))
call assert_equal("-str2float('inf')", string(trunc(-1.0/0.0)))
call assert_fails("call trunc('')", 'E808:')
endfunc
func Test_isnan()
throw 'skipped: Nvim does not support isnan()'
call assert_equal(0, isnan(1.0))
call assert_equal(1, isnan(0.0/0.0))
call assert_equal(0, isnan(1.0/0.0))
call assert_equal(0, isnan('a'))
call assert_equal(0, isnan([]))
call assert_equal(0, isnan({}))
endfunc

View File

@ -1,3 +1,22 @@
" Tests for various functions.
func Test_str2nr()
call assert_equal(0, str2nr(''))
call assert_equal(1, str2nr('1'))
call assert_equal(1, str2nr(' 1 '))
call assert_equal(1, str2nr('+1'))
call assert_equal(1, str2nr('+ 1'))
call assert_equal(1, str2nr(' + 1 '))
call assert_equal(-1, str2nr('-1'))
call assert_equal(-1, str2nr('- 1'))
call assert_equal(-1, str2nr(' - 1 '))
call assert_equal(123456789, str2nr('123456789'))
call assert_equal(-123456789, str2nr('-123456789'))
endfunc
func Test_setbufvar_options()
" This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the
" window layout.

View File

@ -4,6 +4,6 @@ func Test_load_menu()
try
source $VIMRUNTIME/menu.vim
catch
call assert_false(1, 'error while loading menus: ' . v:exception)
call assert_report('error while loading menus: ' . v:exception)
endtry
endfunc

View File

@ -533,7 +533,7 @@ func Test_completion_comment_formatting()
%d
try
call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
call assert_false(1, 'completefunc not set, should have failed')
call assert_report('completefunc not set, should have failed')
catch
call assert_exception('E764:')
endtry

View File

@ -1090,6 +1090,88 @@ func Test_num64()
call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
endfunc
"-------------------------------------------------------------------------------
" Test 95: lines of :append, :change, :insert {{{1
"-------------------------------------------------------------------------------
function! DefineFunction(name, body)
let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
exec func
endfunction
func Test_script_lines()
" :append
try
call DefineFunction('T_Append', [
\ 'append',
\ 'py <<EOS',
\ '.',
\ ])
catch
call assert_report("Can't define function")
endtry
try
call DefineFunction('T_Append', [
\ 'append',
\ 'abc',
\ ])
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
" :change
try
call DefineFunction('T_Change', [
\ 'change',
\ 'py <<EOS',
\ '.',
\ ])
catch
call assert_report("Can't define function")
endtry
try
call DefineFunction('T_Change', [
\ 'change',
\ 'abc',
\ ])
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
" :insert
try
call DefineFunction('T_Insert', [
\ 'insert',
\ 'py <<EOS',
\ '.',
\ ])
catch
call assert_report("Can't define function")
endtry
try
call DefineFunction('T_Insert', [
\ 'insert',
\ 'abc',
\ ])
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
endfunc
"-------------------------------------------------------------------------------
" Test 96: line continuation {{{1
"
" Undefined behavior was detected by ubsan with line continuation
" after an empty line.
"-------------------------------------------------------------------------------
func Test_script_emty_line_continuation()
\
endfunc
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker

View File

@ -255,6 +255,16 @@ describe('assert function:', function()
end)
end)
-- assert_report({msg})
describe('assert_report()', function()
it('should add a message to v:errors', function()
command("call assert_report('something is wrong')")
command("call assert_match('something is wrong', v:errors[0])")
command('call remove(v:errors, 0)')
expected_empty()
end)
end)
-- assert_exception({cmd}, [, {error}])
describe('assert_exception()', function()
it('should assert thrown exceptions properly', function()