blob: 433a65bd342c298495cc1ee918ba4d177402b083 [file] [log] [blame]
Bram Moolenaar53f0c962017-10-22 14:23:59 +02001" 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
6func 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
14endfunc
15
16func 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"
22endfunc
23
24func Expr1()
25 silent! normal! v
26 return "111"
27endfunc
28
29func Expr2()
30 call search('XX', 'b')
31 return "222"
32endfunc
33
34func ListItem()
35 let g:counter += 1
36 return g:counter . '. '
37endfunc
38
39func ListReset()
40 let g:counter = 0
41 return ''
42endfunc
43
44func FuncWithRef(a)
45 unlet g:FuncRef
46 return a:a
47endfunc
48
49func Test_user_func()
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +020050 let g:FuncRef = function("FuncWithRef")
Bram Moolenaar53f0c962017-10-22 14:23:59 +020051 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 Moolenaarfcfe1a92019-08-04 23:04:39 +020065 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 Moolenaar53f0c962017-10-22 14:23:59 +020073 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
Bram Moolenaar8dfcce32020-03-18 19:32:26 +010090 " Try to overwrite an user defined function with a function reference
91 call assert_fails("let Expr1 = function('min')", 'E705:')
92
Bram Moolenaar53f0c962017-10-22 14:23:59 +020093 " Regression: the first line below used to throw ?E110: Missing ')'?
94 " Second is here just to prove that this line is correct when not skipping
95 " rhs of &&.
96 call assert_equal(0, (0 && (function('tr'))(1, 2, 3)))
97 call assert_equal(1, (1 && (function('tr'))(1, 2, 3)))
98
99 delfunc Table
100 delfunc Compute
101 delfunc Expr1
102 delfunc Expr2
103 delfunc ListItem
104 delfunc ListReset
105 unlet g:retval g:counter
106 enew!
107endfunc
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200108
109func Log(val, base = 10)
110 return log(a:val) / log(a:base)
111endfunc
112
113func Args(mandatory, optional = v:null, ...)
114 return deepcopy(a:)
115endfunc
116
117func Args2(a = 1, b = 2, c = 3)
118 return deepcopy(a:)
119endfunc
120
121func MakeBadFunc()
122 func s:fcn(a, b=1, c)
123 endfunc
124endfunc
125
126func Test_default_arg()
Bram Moolenaar5feabe02020-01-30 18:24:53 +0100127 if has('float')
128 call assert_equal(1.0, Log(10))
129 call assert_equal(log(10), Log(10, exp(1)))
130 call assert_fails("call Log(1,2,3)", 'E118')
131 endif
Bram Moolenaar42ae78c2019-05-09 21:08:58 +0200132
133 let res = Args(1)
134 call assert_equal(res.mandatory, 1)
135 call assert_equal(res.optional, v:null)
136 call assert_equal(res['0'], 0)
137
138 let res = Args(1,2)
139 call assert_equal(res.mandatory, 1)
140 call assert_equal(res.optional, 2)
141 call assert_equal(res['0'], 0)
142
143 let res = Args(1,2,3)
144 call assert_equal(res.mandatory, 1)
145 call assert_equal(res.optional, 2)
146 call assert_equal(res['0'], 1)
147
148 call assert_fails("call MakeBadFunc()", 'E989')
149 call assert_fails("fu F(a=1 ,) | endf", 'E475')
150
151 let d = Args2(7, v:none, 9)
152 call assert_equal([7, 2, 9], [d.a, d.b, d.c])
153
154 call assert_equal("\n"
155 \ .. " function Args2(a = 1, b = 2, c = 3)\n"
156 \ .. "1 return deepcopy(a:)\n"
157 \ .. " endfunction",
158 \ execute('func Args2'))
159endfunc
Bram Moolenaarfcfe1a92019-08-04 23:04:39 +0200160
161func s:addFoo(lead)
162 return a:lead .. 'foo'
163endfunc
164
165func Test_user_method()
166 eval 'bar'->s:addFoo()->assert_equal('barfoo')
167endfunc
Bram Moolenaare51bb172020-02-16 19:42:23 +0100168
169func Test_failed_call_in_try()
170 try | call UnknownFunc() | catch | endtry
171endfunc