blob: cededb2e4bc06189992e0dc9b8d6855e0a6dcb37 [file] [log] [blame]
Bram Moolenaare9b892e2016-01-17 21:15:58 +01001" Tests for Perl interface
2
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003CheckFeature perl
Bram Moolenaare9b892e2016-01-17 21:15:58 +01004
Bram Moolenaar41c363a2018-08-02 21:46:51 +02005" FIXME: RunTest don't see any error when Perl abort...
6perl $SIG{__WARN__} = sub { die "Unexpected warnings from perl: @_" };
7
Bram Moolenaar021b5932016-01-17 22:05:48 +01008func Test_change_buffer()
9 call setline(line('$'), ['1 line 1'])
10 perl VIM::DoCommand("normal /^1\n")
11 perl $curline = VIM::Eval("line('.')")
12 perl $curbuf->Set($curline, "1 changed line 1")
13 call assert_equal('1 changed line 1', getline('$'))
14endfunc
15
16func Test_evaluate_list()
17 call setline(line('$'), ['2 line 2'])
18 perl VIM::DoCommand("normal /^2\n")
19 perl $curline = VIM::Eval("line('.')")
20 let l = ["abc", "def"]
21 perl << EOF
22 $l = VIM::Eval("l");
23 $curbuf->Append($curline, $l);
24EOF
25 normal j
26 .perldo s|\n|/|g
27 call assert_equal('abc/def/', getline('$'))
28endfunc
Bram Moolenaare9b892e2016-01-17 21:15:58 +010029
Bram Moolenaar2472ae82019-02-23 15:04:17 +010030funct Test_VIM_Blob()
31 call assert_equal('0z', perleval('VIM::Blob("")'))
Bram Moolenaar3f4f3d82019-09-04 20:05:59 +020032 call assert_equal('0z31326162', 'VIM::Blob("12ab")'->perleval())
Bram Moolenaar2472ae82019-02-23 15:04:17 +010033 call assert_equal('0z00010203', perleval('VIM::Blob("\x00\x01\x02\x03")'))
34 call assert_equal('0z8081FEFF', perleval('VIM::Blob("\x80\x81\xfe\xff")'))
35endfunc
36
Bram Moolenaarae177b72017-02-23 13:45:57 +010037func Test_buffer_Delete()
38 new
39 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
40 perl $curbuf->Delete(7)
41 perl $curbuf->Delete(2, 5)
42 perl $curbuf->Delete(10)
43 call assert_equal(['a', 'f', 'h'], getline(1, '$'))
44 bwipe!
45endfunc
46
47func Test_buffer_Append()
48 new
49 perl $curbuf->Append(1, '1')
50 perl $curbuf->Append(2, '2', '3', '4')
51 perl @l = ('5' ..'7')
52 perl $curbuf->Append(0, @l)
53 call assert_equal(['5', '6', '7', '', '1', '2', '3', '4'], getline(1, '$'))
Dominique Pelle588cf752021-05-10 23:49:39 +020054
55 perl $curbuf->Append(0)
56 call assert_match('^Usage: VIBUF::Append(vimbuf, lnum, @lines) at .* line 1\.$',
57 \ GetMessages()[-1])
58
Bram Moolenaarae177b72017-02-23 13:45:57 +010059 bwipe!
60endfunc
61
62func Test_buffer_Set()
63 new
64 call setline(1, ['1', '2', '3', '4', '5'])
65 perl $curbuf->Set(2, 'a', 'b', 'c')
66 perl $curbuf->Set(4, 'A', 'B', 'C')
67 call assert_equal(['1', 'a', 'b', 'A', 'B'], getline(1, '$'))
Dominique Pelle588cf752021-05-10 23:49:39 +020068
69 perl $curbuf->Set(0)
70 call assert_match('^Usage: VIBUF::Set(vimbuf, lnum, @lines) at .* line 1\.$',
71 \ GetMessages()[-1])
72
Bram Moolenaarae177b72017-02-23 13:45:57 +010073 bwipe!
74endfunc
75
76func Test_buffer_Get()
77 new
78 call setline(1, ['1', '2', '3', '4'])
79 call assert_equal('2:3', perleval('join(":", $curbuf->Get(2, 3))'))
80 bwipe!
81endfunc
82
83func Test_buffer_Count()
84 new
85 call setline(1, ['a', 'b', 'c'])
86 call assert_equal(3, perleval('$curbuf->Count()'))
87 bwipe!
88endfunc
89
90func Test_buffer_Name()
91 new
92 call assert_equal('', perleval('$curbuf->Name()'))
93 bwipe!
94 new Xfoo
95 call assert_equal('Xfoo', perleval('$curbuf->Name()'))
96 bwipe!
97endfunc
98
99func Test_buffer_Number()
100 call assert_equal(bufnr('%'), perleval('$curbuf->Number()'))
101endfunc
102
103func Test_window_Cursor()
104 new
105 call setline(1, ['line1', 'line2'])
106 perl $curwin->Cursor(2, 3)
107 call assert_equal('2:3', perleval('join(":", $curwin->Cursor())'))
108 " Col is numbered from 0 in Perl, and from 1 in Vim script.
109 call assert_equal([0, 2, 4, 0], getpos('.'))
110 bwipe!
111endfunc
112
113func Test_window_SetHeight()
114 new
115 perl $curwin->SetHeight(2)
116 call assert_equal(2, winheight(0))
117 bwipe!
118endfunc
119
120func Test_VIM_Windows()
121 new
122 " VIM::Windows() without argument in scalar and list context.
123 perl $winnr = VIM::Windows()
124 perl @winlist = VIM::Windows()
125 perl $curbuf->Append(0, $winnr, scalar(@winlist))
126 call assert_equal(['2', '2', ''], getline(1, '$'))
127
128 " VIM::Windows() with window number argument.
129 perl VIM::Windows(VIM::Eval('winnr()'))->Buffer()->Set(1, 'bar')
130 call assert_equal('bar', getline(1))
131 bwipe!
132endfunc
133
134func Test_VIM_Buffers()
135 new Xbar
136 " VIM::Buffers() without argument in scalar and list context.
137 perl $nbuf = VIM::Buffers()
138 perl @buflist = VIM::Buffers()
139
140 " VIM::Buffers() with argument.
141 perl $mybuf = (VIM::Buffers('Xbar'))[0]
142 perl $mybuf->Append(0, $nbuf, scalar(@buflist))
143 call assert_equal(['2', '2', ''], getline(1, '$'))
144 bwipe!
145endfunc
146
147func <SID>catch_peval(expr)
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100148 try
149 call perleval(a:expr)
150 catch
151 return v:exception
152 endtry
Bram Moolenaar37175402017-03-18 20:18:45 +0100153 call assert_report('no exception for `perleval("'.a:expr.'")`')
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100154 return ''
Bram Moolenaar95509e12016-04-15 21:16:11 +0200155endfunc
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100156
Bram Moolenaarae177b72017-02-23 13:45:57 +0100157func Test_perleval()
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100158 call assert_false(perleval('undef'))
159
160 " scalar
161 call assert_equal(0, perleval('0'))
162 call assert_equal(2, perleval('2'))
163 call assert_equal(-2, perleval('-2'))
Bram Moolenaar73e28dc2022-09-17 21:08:33 +0100164 call assert_equal(2.5, perleval('2.5'))
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100165
166 sandbox call assert_equal(2, perleval('2'))
167
168 call assert_equal('abc', perleval('"abc"'))
169 call assert_equal("abc\ndef", perleval('"abc\0def"'))
170
171 " ref
172 call assert_equal([], perleval('[]'))
173 call assert_equal(['word', 42, [42],{}], perleval('["word", 42, [42], {}]'))
174
175 call assert_equal({}, perleval('{}'))
176 call assert_equal({'foo': 'bar'}, perleval('{foo => "bar"}'))
177
178 perl our %h; our @a;
179 let a = perleval('[\(%h, %h, @a, @a)]')
180 call assert_true((a[0] is a[1]))
181 call assert_true((a[2] is a[3]))
182 perl undef %h; undef @a;
183
184 call assert_true(<SID>catch_peval('{"" , 0}') =~ 'Malformed key Dictionary')
185 call assert_true(<SID>catch_peval('{"\0" , 0}') =~ 'Malformed key Dictionary')
186 call assert_true(<SID>catch_peval('{"foo\0bar" , 0}') =~ 'Malformed key Dictionary')
187
188 call assert_equal('*VIM', perleval('"*VIM"'))
189 call assert_true(perleval('\\0') =~ 'SCALAR(0x\x\+)')
Bram Moolenaar730677a2020-12-09 16:05:45 +0100190
191 " typeglob
192 call assert_equal('*main::STDOUT', perleval('*STDOUT'))
193'
194 call perleval("++-$foo")
195 let messages = split(execute('message'), "\n")
196 call assert_match("Can't modify negation", messages[-1])
Bram Moolenaar95509e12016-04-15 21:16:11 +0200197endfunc
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100198
Bram Moolenaarae177b72017-02-23 13:45:57 +0100199func Test_perldo()
Bram Moolenaar730677a2020-12-09 16:05:45 +0100200 new
201 " :perldo in empty buffer does nothing.
202 perldo ++$counter
203 call assert_equal(0, perleval("$counter"))
204
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100205 sp __TEST__
206 exe 'read ' g:testname
207 perldo s/perl/vieux_chameau/g
208 1
209 call assert_false(search('\Cperl'))
210 bw!
Bram Moolenaar85b57432017-01-29 22:59:12 +0100211
Bram Moolenaar85b57432017-01-29 22:59:12 +0100212 new
zeertzjqe99f0682024-01-29 19:32:39 +0100213
214 " Check deleting lines does not trigger ml_get error.
Bram Moolenaar85b57432017-01-29 22:59:12 +0100215 call setline(1, ['one', 'two', 'three'])
216 perldo VIM::DoCommand("%d_")
zeertzjqe99f0682024-01-29 19:32:39 +0100217 call assert_equal([''], getline(1, '$'))
218
219 call setline(1, ['one', 'two', 'three'])
220 perldo VIM::DoCommand("1,2d_")
221 call assert_equal(['three'], getline(1, '$'))
222
223 call setline(1, ['one', 'two', 'three'])
224 perldo VIM::DoCommand("2,3d_"); $_ = "REPLACED"
225 call assert_equal(['REPLACED'], getline(1, '$'))
226
227 call setline(1, ['one', 'two', 'three'])
228 2,3perldo VIM::DoCommand("1,2d_"); $_ = "REPLACED"
229 call assert_equal(['three'], getline(1, '$'))
230
Bram Moolenaar85b57432017-01-29 22:59:12 +0100231 bwipe!
232
Dominique Pelle588cf752021-05-10 23:49:39 +0200233 " Check a Perl expression which gives an error.
234 new
235 call setline(1, 'one')
236 perldo 1/0
237 call assert_match('^Illegal division by zero at .* line 1\.$', GetMessages()[-1])
238 bwipe!
239
Bram Moolenaar85b57432017-01-29 22:59:12 +0100240 " Check switching to another buffer does not trigger ml_get error.
241 new
242 let wincount = winnr('$')
243 call setline(1, ['one', 'two', 'three'])
244 perldo VIM::DoCommand("new")
245 call assert_equal(wincount + 1, winnr('$'))
Bram Moolenaar730677a2020-12-09 16:05:45 +0100246 %bwipe!
Bram Moolenaar95509e12016-04-15 21:16:11 +0200247endfunc
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100248
Bram Moolenaarae177b72017-02-23 13:45:57 +0100249func Test_VIM_package()
Bram Moolenaare9b892e2016-01-17 21:15:58 +0100250 perl VIM::DoCommand('let l:var = "foo"')
251 call assert_equal(l:var, 'foo')
252
253 set noet
254 perl VIM::SetOption('et')
255 call assert_true(&et)
Bram Moolenaar95509e12016-04-15 21:16:11 +0200256endfunc
Bram Moolenaar6244a0f2016-04-14 14:09:25 +0200257
Bram Moolenaarae177b72017-02-23 13:45:57 +0100258func Test_stdio()
Bram Moolenaar6244a0f2016-04-14 14:09:25 +0200259 redir =>l:out
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200260 perl << trim EOF
Dominique Pelle588cf752021-05-10 23:49:39 +0200261 VIM::Msg("VIM::Msg");
262 VIM::Msg("VIM::Msg Error", "Error");
Bram Moolenaar6244a0f2016-04-14 14:09:25 +0200263 print "STDOUT";
264 print STDERR "STDERR";
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200265 EOF
Bram Moolenaar6244a0f2016-04-14 14:09:25 +0200266 redir END
Dominique Pelle588cf752021-05-10 23:49:39 +0200267 call assert_equal(['VIM::Msg', 'VIM::Msg Error', 'STDOUT', 'STDERR'], split(l:out, "\n"))
Bram Moolenaar95509e12016-04-15 21:16:11 +0200268endfunc
269
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200270" Run first to get a clean namespace
271func Test_000_SvREFCNT()
Bram Moolenaar3166afd2018-07-16 18:09:14 +0200272 for i in range(8)
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200273 exec 'new X'.i
274 endfor
Bram Moolenaar95509e12016-04-15 21:16:11 +0200275 new t
276 perl <<--perl
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200277#line 5 "Test_000_SvREFCNT()"
Bram Moolenaar95509e12016-04-15 21:16:11 +0200278 my ($b, $w);
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200279
Bram Moolenaar41c363a2018-08-02 21:46:51 +0200280 my $num = 0;
281 for ( 0 .. 100 ) {
282 if ( ++$num >= 8 ) { $num = 0 }
283 VIM::DoCommand("buffer X$num");
284 $b = $curbuf;
285 }
286
287 VIM::DoCommand("buffer t");
288
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200289 $b = $curbuf for 0 .. 100;
290 $w = $curwin for 0 .. 100;
291 () = VIM::Buffers for 0 .. 100;
292 () = VIM::Windows for 0 .. 100;
293
Bram Moolenaar95509e12016-04-15 21:16:11 +0200294 VIM::DoCommand('bw! t');
295 if (exists &Internals::SvREFCNT) {
296 my $cb = Internals::SvREFCNT($$b);
297 my $cw = Internals::SvREFCNT($$w);
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200298 VIM::Eval("assert_equal(2, $cb, 'T1')");
299 VIM::Eval("assert_equal(2, $cw, 'T2')");
Bram Moolenaar41c363a2018-08-02 21:46:51 +0200300 my $strongref;
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200301 foreach ( VIM::Buffers, VIM::Windows ) {
Bram Moolenaar41c363a2018-08-02 21:46:51 +0200302 VIM::DoCommand("%bw!");
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200303 my $c = Internals::SvREFCNT($_);
304 VIM::Eval("assert_equal(2, $c, 'T3')");
305 $c = Internals::SvREFCNT($$_);
Bram Moolenaar41c363a2018-08-02 21:46:51 +0200306 next if $c == 2 && !$strongref++;
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200307 VIM::Eval("assert_equal(1, $c, 'T4')");
308 }
309 $cb = Internals::SvREFCNT($$curbuf);
310 $cw = Internals::SvREFCNT($$curwin);
311 VIM::Eval("assert_equal(3, $cb, 'T5')");
312 VIM::Eval("assert_equal(3, $cw, 'T6')");
Bram Moolenaar95509e12016-04-15 21:16:11 +0200313 }
314 VIM::Eval("assert_false($$b)");
315 VIM::Eval("assert_false($$w)");
316--perl
Bram Moolenaar18c4f1b2018-07-16 17:45:38 +0200317 %bw!
Bram Moolenaar95509e12016-04-15 21:16:11 +0200318endfunc
Bram Moolenaar53901442018-07-25 22:02:36 +0200319
Bram Moolenaaread24152022-05-10 21:11:12 +0100320" This caused a memory error before issue #10386 was fixed
321func Test_stack_usage_fix()
322 let script =<< CODE
323 " This will grow Perl's stack in first invocation
324 eval [0, 0]->map({ -> perleval("push@_,0..4096;0") })
325 q!
326CODE
327 call RunVim([], script, '')
328endfunc
329
Bram Moolenaar53901442018-07-25 22:02:36 +0200330func Test_set_cursor()
331 " Check that setting the cursor position works.
332 new
333 call setline(1, ['first line', 'second line'])
334 normal gg
335 perldo $curwin->Cursor(1, 5)
336 call assert_equal([1, 6], [line('.'), col('.')])
337
338 " Check that movement after setting cursor position keeps current column.
339 normal j
340 call assert_equal([2, 6], [line('.'), col('.')])
341endfunc
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200342
343" Test for various heredoc syntax
344func Test_perl_heredoc()
345 perl << END
346VIM::DoCommand('let s = "A"')
347END
348 perl <<
349VIM::DoCommand('let s ..= "B"')
350.
351 perl << trim END
352 VIM::DoCommand('let s ..= "C"')
353 END
354 perl << trim
355 VIM::DoCommand('let s ..= "D"')
356 .
Bram Moolenaar6ab09532020-05-01 14:10:13 +0200357 perl << trim eof
358 VIM::DoCommand('let s ..= "E"')
359 eof
zeertzjq449c2e52025-02-03 18:56:16 +0100360 perl << trimm
361VIM::DoCommand('let s ..= "F"')
362trimm
363 call assert_equal('ABCDEF', s)
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200364endfunc
365
Bram Moolenaar730677a2020-12-09 16:05:45 +0100366func Test_perl_in_sandbox()
367 sandbox perl print 'test'
368 let messages = split(execute('message'), "\n")
369 call assert_match("'print' trapped by operation mask", messages[-1])
370endfunc
371
Bram Moolenaar6c2b7b82020-04-14 20:15:49 +0200372" vim: shiftwidth=2 sts=2 expandtab