Bram Moolenaar | 53f0c96 | 2017-10-22 14:23:59 +0200 | [diff] [blame] | 1 | " Test for user functions. |
| 2 | " Also test an <expr> mapping calling a function. |
| 3 | " Also test that a builtin function cannot be replaced. |
| 4 | " Also test for regression when calling arbitrary expression. |
| 5 | |
| 6 | func Table(title, ...) |
| 7 | let ret = a:title |
| 8 | let idx = 1 |
| 9 | while idx <= a:0 |
| 10 | exe "let ret = ret . a:" . idx |
| 11 | let idx = idx + 1 |
| 12 | endwhile |
| 13 | return ret |
| 14 | endfunc |
| 15 | |
| 16 | func Compute(n1, n2, divname) |
| 17 | if a:n2 == 0 |
| 18 | return "fail" |
| 19 | endif |
| 20 | exe "let g:" . a:divname . " = ". a:n1 / a:n2 |
| 21 | return "ok" |
| 22 | endfunc |
| 23 | |
| 24 | func Expr1() |
| 25 | silent! normal! v |
| 26 | return "111" |
| 27 | endfunc |
| 28 | |
| 29 | func Expr2() |
| 30 | call search('XX', 'b') |
| 31 | return "222" |
| 32 | endfunc |
| 33 | |
| 34 | func ListItem() |
| 35 | let g:counter += 1 |
| 36 | return g:counter . '. ' |
| 37 | endfunc |
| 38 | |
| 39 | func ListReset() |
| 40 | let g:counter = 0 |
| 41 | return '' |
| 42 | endfunc |
| 43 | |
| 44 | func FuncWithRef(a) |
| 45 | unlet g:FuncRef |
| 46 | return a:a |
| 47 | endfunc |
| 48 | |
| 49 | func Test_user_func() |
Bram Moolenaar | fcfe1a9 | 2019-08-04 23:04:39 +0200 | [diff] [blame] | 50 | let g:FuncRef = function("FuncWithRef") |
Bram Moolenaar | 53f0c96 | 2017-10-22 14:23:59 +0200 | [diff] [blame] | 51 | let g:counter = 0 |
| 52 | inoremap <expr> ( ListItem() |
| 53 | inoremap <expr> [ ListReset() |
| 54 | imap <expr> + Expr1() |
| 55 | imap <expr> * Expr2() |
| 56 | let g:retval = "nop" |
| 57 | |
| 58 | call assert_equal('xxx4asdf', Table("xxx", 4, "asdf")) |
| 59 | call assert_equal('fail', Compute(45, 0, "retval")) |
| 60 | call assert_equal('nop', g:retval) |
| 61 | call assert_equal('ok', Compute(45, 5, "retval")) |
| 62 | call assert_equal(9, g:retval) |
| 63 | call assert_equal(333, g:FuncRef(333)) |
| 64 | |
Bram Moolenaar | fcfe1a9 | 2019-08-04 23:04:39 +0200 | [diff] [blame] | 65 | let g:retval = "nop" |
| 66 | call assert_equal('xxx4asdf', "xxx"->Table(4, "asdf")) |
| 67 | call assert_equal('fail', 45->Compute(0, "retval")) |
| 68 | call assert_equal('nop', g:retval) |
| 69 | call assert_equal('ok', 45->Compute(5, "retval")) |
| 70 | call assert_equal(9, g:retval) |
| 71 | " call assert_equal(333, 333->g:FuncRef()) |
| 72 | |
Bram Moolenaar | 53f0c96 | 2017-10-22 14:23:59 +0200 | [diff] [blame] | 73 | enew |
| 74 | |
| 75 | normal oXX+-XX |
| 76 | call assert_equal('XX111-XX', getline('.')) |
| 77 | normal o---*--- |
| 78 | call assert_equal('---222---', getline('.')) |
| 79 | normal o(one |
| 80 | call assert_equal('1. one', getline('.')) |
| 81 | normal o(two |
| 82 | call assert_equal('2. two', getline('.')) |
| 83 | normal o[(one again |
| 84 | call assert_equal('1. one again', getline('.')) |
| 85 | |
| 86 | call assert_equal(3, max([1, 2, 3])) |
| 87 | call assert_fails("call extend(g:, {'max': function('min')})", 'E704') |
| 88 | call assert_equal(3, max([1, 2, 3])) |
| 89 | |
| 90 | " Regression: the first line below used to throw ?E110: Missing ')'? |
| 91 | " Second is here just to prove that this line is correct when not skipping |
| 92 | " rhs of &&. |
| 93 | call assert_equal(0, (0 && (function('tr'))(1, 2, 3))) |
| 94 | call assert_equal(1, (1 && (function('tr'))(1, 2, 3))) |
| 95 | |
| 96 | delfunc Table |
| 97 | delfunc Compute |
| 98 | delfunc Expr1 |
| 99 | delfunc Expr2 |
| 100 | delfunc ListItem |
| 101 | delfunc ListReset |
| 102 | unlet g:retval g:counter |
| 103 | enew! |
| 104 | endfunc |
Bram Moolenaar | 42ae78c | 2019-05-09 21:08:58 +0200 | [diff] [blame] | 105 | |
| 106 | func Log(val, base = 10) |
| 107 | return log(a:val) / log(a:base) |
| 108 | endfunc |
| 109 | |
| 110 | func Args(mandatory, optional = v:null, ...) |
| 111 | return deepcopy(a:) |
| 112 | endfunc |
| 113 | |
| 114 | func Args2(a = 1, b = 2, c = 3) |
| 115 | return deepcopy(a:) |
| 116 | endfunc |
| 117 | |
| 118 | func MakeBadFunc() |
| 119 | func s:fcn(a, b=1, c) |
| 120 | endfunc |
| 121 | endfunc |
| 122 | |
| 123 | func Test_default_arg() |
Bram Moolenaar | 5feabe0 | 2020-01-30 18:24:53 +0100 | [diff] [blame^] | 124 | if has('float') |
| 125 | call assert_equal(1.0, Log(10)) |
| 126 | call assert_equal(log(10), Log(10, exp(1))) |
| 127 | call assert_fails("call Log(1,2,3)", 'E118') |
| 128 | endif |
Bram Moolenaar | 42ae78c | 2019-05-09 21:08:58 +0200 | [diff] [blame] | 129 | |
| 130 | let res = Args(1) |
| 131 | call assert_equal(res.mandatory, 1) |
| 132 | call assert_equal(res.optional, v:null) |
| 133 | call assert_equal(res['0'], 0) |
| 134 | |
| 135 | let res = Args(1,2) |
| 136 | call assert_equal(res.mandatory, 1) |
| 137 | call assert_equal(res.optional, 2) |
| 138 | call assert_equal(res['0'], 0) |
| 139 | |
| 140 | let res = Args(1,2,3) |
| 141 | call assert_equal(res.mandatory, 1) |
| 142 | call assert_equal(res.optional, 2) |
| 143 | call assert_equal(res['0'], 1) |
| 144 | |
| 145 | call assert_fails("call MakeBadFunc()", 'E989') |
| 146 | call assert_fails("fu F(a=1 ,) | endf", 'E475') |
| 147 | |
| 148 | let d = Args2(7, v:none, 9) |
| 149 | call assert_equal([7, 2, 9], [d.a, d.b, d.c]) |
| 150 | |
| 151 | call assert_equal("\n" |
| 152 | \ .. " function Args2(a = 1, b = 2, c = 3)\n" |
| 153 | \ .. "1 return deepcopy(a:)\n" |
| 154 | \ .. " endfunction", |
| 155 | \ execute('func Args2')) |
| 156 | endfunc |
Bram Moolenaar | fcfe1a9 | 2019-08-04 23:04:39 +0200 | [diff] [blame] | 157 | |
| 158 | func s:addFoo(lead) |
| 159 | return a:lead .. 'foo' |
| 160 | endfunc |
| 161 | |
| 162 | func Test_user_method() |
| 163 | eval 'bar'->s:addFoo()->assert_equal('barfoo') |
| 164 | endfunc |