blob: 94c1ab5357836d2b093b6547b306e83b501f51d5 [file] [log] [blame]
Bram Moolenaardb913952012-06-29 12:54:53 +02001Tests for various python features. vim: set ft=vim :
2
3STARTTEST
4:so small.vim
5:if !has('python3') | e! test.ok | wq! test.out | endif
Bram Moolenaarc24c1ac2013-05-16 20:47:56 +02006:lang C
Bram Moolenaardb913952012-06-29 12:54:53 +02007:py3 import vim
8:fun Test()
9:let l = []
10:py3 l=vim.bindeval('l')
11:py3 f=vim.bindeval('function("strlen")')
12:" Extending List directly with different types
13:py3 l+=[1, "as'd", [1, 2, f, {'a': 1}]]
14:$put =string(l)
15:$put =string(l[-1])
16:try
17: $put =string(l[-4])
18:catch
19: $put =v:exception[:13]
20:endtry
21:" List assignment
22:py3 l[0]=0
23:$put =string(l)
24:py3 l[-2]=f
25:$put =string(l)
26:"
27:" Extending Dictionary directly with different types
28:let d = {}
29:py3 d=vim.bindeval('d')
30:py3 d['1']='asd'
31:py3 d['b']=[1, 2, f]
32:py3 d['-1']={'a': 1}
33:let dkeys = []
34:py3 dk=vim.bindeval('dkeys')
35:py3 dkeys=d.keys()
36:py3 dkeys.sort()
37:py3 dk+=dkeys
38:$put =string(dkeys)
39:for [key, val] in sort(items(d))
40: $put =string(key) . ' : ' . string(val)
41: unlet key val
42:endfor
43:"
44:" removing items with del
45:py3 del l[2]
46:$put =string(l)
47:let l = range(8)
48:py3 l=vim.bindeval('l')
49:try
50: py3 del l[:3]
51: py3 del l[1:]
52:catch
53: $put =v:exception
54:endtry
55:$put =string(l)
56:"
57:py3 del d['-1']
58:$put =string(d)
59:"
60:" removing items out of range: silently skip items that don't exist
61:let l = [0, 1, 2, 3]
62:py3 l=vim.bindeval('l')
63:" The following two ranges delete nothing as they match empty list:
64:py3 del l[2:1]
65:$put =string(l)
66:py3 del l[2:2]
67:$put =string(l)
68:py3 del l[2:3]
69:$put =string(l)
70:let l = [0, 1, 2, 3]
71:py3 l=vim.bindeval('l')
72:py3 del l[2:4]
73:$put =string(l)
74:let l = [0, 1, 2, 3]
75:py3 l=vim.bindeval('l')
76:py3 del l[2:5]
77:$put =string(l)
78:let l = [0, 1, 2, 3]
79:py3 l=vim.bindeval('l')
80:py3 del l[2:6]
81:$put =string(l)
82:let l = [0, 1, 2, 3]
83:py3 l=vim.bindeval('l')
84:" The following two ranges delete nothing as they match empty list:
85:py3 del l[-1:2]
86:$put =string(l)
87:py3 del l[-2:2]
88:$put =string(l)
89:py3 del l[-3:2]
90:$put =string(l)
91:let l = [0, 1, 2, 3]
92:py3 l=vim.bindeval('l')
93:py3 del l[-4:2]
94:$put =string(l)
95:let l = [0, 1, 2, 3]
96:py3 l=vim.bindeval('l')
97:py3 del l[-5:2]
98:$put =string(l)
99:let l = [0, 1, 2, 3]
100:py3 l=vim.bindeval('l')
101:py3 del l[-6:2]
102:$put =string(l)
103:"
104:" Slice assignment to a list
105:let l = [0, 1, 2, 3]
106:py3 l=vim.bindeval('l')
107:py3 l[0:0]=['a']
108:$put =string(l)
109:let l = [0, 1, 2, 3]
110:py3 l=vim.bindeval('l')
111:py3 l[1:2]=['b']
112:$put =string(l)
113:let l = [0, 1, 2, 3]
114:py3 l=vim.bindeval('l')
115:py3 l[2:4]=['c']
116:$put =string(l)
117:let l = [0, 1, 2, 3]
118:py3 l=vim.bindeval('l')
119:py3 l[4:4]=['d']
120:$put =string(l)
121:let l = [0, 1, 2, 3]
122:py3 l=vim.bindeval('l')
123:py3 l[-1:2]=['e']
124:$put =string(l)
125:let l = [0, 1, 2, 3]
126:py3 l=vim.bindeval('l')
127:py3 l[-10:2]=['f']
128:$put =string(l)
129:let l = [0, 1, 2, 3]
130:py3 l=vim.bindeval('l')
131:py3 l[2:-10]=['g']
132:$put =string(l)
133:let l = []
134:py3 l=vim.bindeval('l')
135:py3 l[0:0]=['h']
136:$put =string(l)
137:"
138:" Locked variables
139:let l = [0, 1, 2, 3]
140:py3 l=vim.bindeval('l')
141:lockvar! l
142:py3 l[2]='i'
143:$put =string(l)
144:unlockvar! l
145:"
146:" Function calls
147:function New(...)
148:return ['NewStart']+a:000+['NewEnd']
149:endfunction
150:function DictNew(...) dict
151:return ['DictNewStart']+a:000+['DictNewEnd', self]
152:endfunction
153:let l=[function('New'), function('DictNew')]
154:py3 l=vim.bindeval('l')
155:py3 l.extend(list(l[0](1, 2, 3)))
156:$put =string(l)
157:py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
158:$put =string(l)
159:py3 l+=[l[0].name]
160:$put =string(l)
161:try
162: py3 l[1](1, 2, 3)
163:catch
164: $put =v:exception[:13]
165:endtry
166:delfunction New
167:try
168: py3 l[0](1, 2, 3)
169:catch
170: $put =v:exception[:13]
171:endtry
172:if has('float')
173: let l=[0.0]
174: py3 l=vim.bindeval('l')
175: py3 l.extend([0.0])
176: $put =string(l)
177:else
178: $put ='[0.0, 0.0]'
179:endif
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200180:let messages=[]
181:py3 <<EOF
182d=vim.bindeval('{}')
183m=vim.bindeval('messages')
184try:
185 d['abc']
186except Exception as e:
187 m.extend([e.__class__.__name__])
188
189try:
190 d['abc']="\0"
191except Exception as e:
192 m.extend([e.__class__.__name__])
193
194try:
195 d['abc']=vim
196except Exception as e:
197 m.extend([e.__class__.__name__])
198
199try:
200 d['']=1
201except Exception as e:
202 m.extend([e.__class__.__name__])
203
204try:
205 d['a\0b']=1
206except Exception as e:
207 m.extend([e.__class__.__name__])
208
209try:
210 d[b'a\0b']=1
211except Exception as e:
212 m.extend([e.__class__.__name__])
213EOF
214:$put =messages
Bram Moolenaar66b79852012-09-21 14:00:35 +0200215:unlet messages
216:" locked and scope attributes
217:let d={} | let dl={} | lockvar dl
218:for s in split("d dl v: g:")
219: let name=tr(s, ':', 's')
220: execute 'py3 '.name.'=vim.bindeval("'.s.'")'
221: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".py3eval(name.".".v:val)'), ';')
222: $put =toput
223:endfor
224:silent! let d.abc=1
225:silent! let dl.abc=1
226:py3 d.locked=True
227:py3 dl.locked=False
228:silent! let d.def=1
229:silent! let dl.def=1
230:put ='d:'.string(d)
231:put ='dl:'.string(dl)
232:unlet d dl
233:
234:let l=[] | let ll=[] | lockvar ll
235:for s in split("l ll")
236: let name=tr(s, ':', 's')
237: execute 'py3 '.name.'=vim.bindeval("'.s.'")'
238: let toput=s.' : locked:'.py3eval(name.'.locked')
239: $put =toput
240:endfor
241:silent! call extend(l, [0])
242:silent! call extend(ll, [0])
243:py3 l.locked=True
244:py3 ll.locked=False
245:silent! call extend(l, [1])
246:silent! call extend(ll, [1])
247:put ='l:'.string(l)
248:put ='ll:'.string(ll)
249:unlet l ll
Bram Moolenaardb913952012-06-29 12:54:53 +0200250:"
251:" py3eval()
252:let l=py3eval('[0, 1, 2]')
253:$put =string(l)
254:let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}')
255:$put =sort(items(d))
Bram Moolenaardb913952012-06-29 12:54:53 +0200256:if has('float')
257: let f=py3eval('0.0')
258: $put =string(f)
259:else
260: $put ='0.0'
261:endif
Bram Moolenaarc11073c2012-09-05 19:17:42 +0200262:" Invalid values:
263:for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim']
264: try
265: let v=py3eval(e)
266: catch
267: let toput=e.":\t".v:exception[:13]
268: $put =toput
269: endtry
270:endfor
Bram Moolenaar76d711c2013-02-13 14:17:08 +0100271:"
272:" threading
273:let l = [0]
274:py3 l=vim.bindeval('l')
275:py3 <<EOF
276import threading
277import time
278
279class T(threading.Thread):
280 def __init__(self):
281 threading.Thread.__init__(self)
282 self.t = 0
283 self.running = True
284
285 def run(self):
286 while self.running:
287 self.t += 1
288 time.sleep(0.1)
289
290t = T()
291t.start()
292EOF
293:sleep 1
294:py3 t.running = False
295:py3 t.join()
296:py3 l[0] = t.t > 8 # check if the background thread is working
297:$put =string(l)
298:"
299:" settrace
300:let l = []
301:py3 l=vim.bindeval('l')
302:py3 <<EOF
303import sys
304
305def traceit(frame, event, arg):
306 global l
307 if event == "line":
308 l += [frame.f_lineno]
309 return traceit
310
311def trace_main():
312 for i in range(5):
313 pass
314EOF
315:py3 sys.settrace(traceit)
316:py3 trace_main()
317:py3 sys.settrace(None)
318:$put =string(l)
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200319:"
320:" Vars
321:let g:foo = 'bac'
322:let w:abc = 'def'
323:let b:baz = 'bar'
Bram Moolenaara4720012013-05-15 16:27:37 +0200324:let t:bar = 'jkl'
Bram Moolenaar230bb3f2013-04-24 14:07:45 +0200325:try
326: throw "Abc"
327:catch
328: put =py3eval('vim.vvars[''exception'']')
329:endtry
330:put =py3eval('vim.vars[''foo'']')
331:put =py3eval('vim.current.window.vars[''abc'']')
332:put =py3eval('vim.current.buffer.vars[''baz'']')
Bram Moolenaara4720012013-05-15 16:27:37 +0200333:put =py3eval('vim.current.tabpage.vars[''bar'']')
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200334:"
335:" Options
336:" paste: boolean, global
337:" previewheight number, global
338:" operatorfunc: string, global
339:" number: boolean, window-local
340:" numberwidth: number, window-local
341:" colorcolumn: string, window-local
342:" statusline: string, window-local/global
343:" autoindent: boolean, buffer-local
Bram Moolenaar55b8ad32013-05-17 13:38:04 +0200344:" shiftwidth: number, buffer-local
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200345:" omnifunc: string, buffer-local
346:" preserveindent: boolean, buffer-local/global
347:" path: string, buffer-local/global
348:let g:bufs=[bufnr('%')]
349:new
350:let g:bufs+=[bufnr('%')]
351:vnew
352:let g:bufs+=[bufnr('%')]
353:wincmd j
354:vnew
355:let g:bufs+=[bufnr('%')]
356:wincmd l
357:fun RecVars(opt)
358: let gval =string(eval('&g:'.a:opt))
359: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))'))
360: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))'))
361: put =' G: '.gval
362: put =' W: '.wvals
363: put =' B: '.wvals
364:endfun
365py3 << EOF
366def e(s, g=globals(), l=locals()):
367 try:
368 exec(s, g, l)
369 except Exception as e:
370 vim.command('throw ' + repr(e.__class__.__name__))
371
372def ev(s, g=globals(), l=locals()):
373 try:
374 return eval(s, g, l)
375 except Exception as e:
376 vim.command('throw ' + repr(e.__class__.__name__))
377 return 0
378EOF
379:function E(s)
380: python3 e(vim.eval('a:s'))
381:endfunction
382:function Ev(s)
383: return py3eval('ev(vim.eval("a:s"))')
384:endfunction
385:py3 gopts1=vim.options
386:py3 wopts1=vim.windows[2].options
387:py3 wopts2=vim.windows[0].options
388:py3 wopts3=vim.windows[1].options
389:py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
390:py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
391:py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
392:let lst=[]
393:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
394:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]]
395:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
396:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
397:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
398:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc', 0, 0, 1 ]]
399:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
400:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
Bram Moolenaar55b8ad32013-05-17 13:38:04 +0200401:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]]
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200402:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]]
403:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]]
404:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]]
405:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
406: py3 oname=vim.eval('oname')
407: py3 oval1=vim.bindeval('oval1')
408: py3 oval2=vim.bindeval('oval2')
409: py3 oval3=vim.bindeval('oval3')
410: if invval is 0 || invval is 1
411: py3 invval=bool(vim.bindeval('invval'))
412: else
413: py3 invval=vim.bindeval('invval')
414: endif
415: if bool
416: py3 oval1=bool(oval1)
417: py3 oval2=bool(oval2)
418: py3 oval3=bool(oval3)
419: endif
420: put ='>>> '.oname
421: for v in ['gopts1', 'wopts1', 'bopts1']
422: try
423: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
424: catch
425: put =' p/'.v.'! '.v:exception
426: endtry
427: try
428: call E(v.'["'.oname.'"]=invval')
429: catch
430: put =' inv: '.string(invval).'! '.v:exception
431: endtry
432: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
433: let val=substitute(vv, '^.opts', 'oval', '')
434: try
435: call E(vv.'["'.oname.'"]='.val)
436: catch
437: put =' '.vv.'! '.v:exception
438: endtry
439: endfor
440: endfor
441: call RecVars(oname)
442: for v in ['wopts3', 'bopts3']
443: try
444: call E('del '.v.'["'.oname.'"]')
445: catch
446: put =' del '.v.'! '.v:exception
447: endtry
448: endfor
449: call RecVars(oname)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200450:endfor
451:only
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200452:for buf in g:bufs[1:]
453: execute 'bwipeout!' buf
454:endfor
Bram Moolenaarbd80f352013-05-12 21:16:23 +0200455:"
456:" Test buffer object
457:vnew
458:put ='First line'
459:put ='Second line'
460:put ='Third line'
461:1 delete _
462:py3 b=vim.current.buffer
463:wincmd w
464:mark a
465py3 << EOF
466cb = vim.current.buffer
467# Tests BufferAppend and BufferItem
468cb.append(b[0])
469# Tests BufferSlice and BufferAssSlice
470cb.append('abc') # Will be overwritten
471cb[-1:] = b[:-2]
472# Test BufferLength and BufferAssSlice
473cb.append('def') # Will not be overwritten
474cb[len(cb):] = b[:]
475# Test BufferAssItem and BufferMark
476cb.append('ghi') # Will be overwritten
477cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
478# Test BufferRepr
479cb.append(repr(cb) + repr(b))
480# Modify foreign buffer
481b.append('foo')
482b[0]='bar'
483b[0:0]=['baz']
484vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
485# Test CheckBuffer
486vim.command('bwipeout! ' + str(b.number))
487for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")'):
488 try:
489 exec(expr)
490 except vim.error:
491 pass
492 else:
493 # Usually a SEGV here
494 # Should not happen in any case
495 cb.append('No exception for ' + expr)
496EOF
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200497:"
498:" Test vim.buffers object
499:set hidden
500:edit a
501:buffer #
502:edit b
503:buffer #
504:edit c
505:buffer #
506py3 << EOF
507# Check GCing iterator that was not fully exhausted
508i = iter(vim.buffers)
509cb.append('i:' + str(next(i)))
510# and also check creating more then one iterator at a time
511i2 = iter(vim.buffers)
512cb.append('i2:' + str(next(i2)))
513cb.append('i:' + str(next(i)))
514# The following should trigger GC and not cause any problems
515del i
516del i2
517i3 = iter(vim.buffers)
518cb.append('i3:' + str(next(i3)))
519del i3
520
521prevnum = 0
522for b in vim.buffers:
523 # Check buffer order
524 if prevnum >= b.number:
525 cb.append('!!! Buffer numbers not in strictly ascending order')
526 # Check indexing: vim.buffers[number].number == number
527 cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
528 prevnum = b.number
529
530cb.append(str(len(vim.buffers)))
531
532bnums = list(map(lambda b: b.number, vim.buffers))[1:]
533
534# Test wiping out buffer with existing iterator
535i4 = iter(vim.buffers)
536cb.append('i4:' + str(next(i4)))
537vim.command('bwipeout! ' + str(bnums.pop(0)))
538try:
539 next(i4)
540except vim.error:
541 pass
542else:
543 cb.append('!!!! No vim.error')
544i4 = iter(vim.buffers)
545vim.command('bwipeout! ' + str(bnums.pop(-1)))
546vim.command('bwipeout! ' + str(bnums.pop(-1)))
547cb.append('i4:' + str(next(i4)))
548try:
549 next(i4)
550except StopIteration:
551 cb.append('StopIteration')
552EOF
Bram Moolenaara4720012013-05-15 16:27:37 +0200553:"
554:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
555:tabnew 0
556:tabnew 1
557:vnew a.1
558:tabnew 2
559:vnew a.2
560:vnew b.2
561:vnew c.2
562py3 << EOF
563def W(w):
564 if '(unknown)' in repr(w):
565 return '<window object (unknown)>'
566 else:
567 return repr(w)
568cb.append('Number of tabs: ' + str(len(vim.tabpages)))
569cb.append('Current tab pages:')
570for t in vim.tabpages:
571 cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window))
572 cb.append(' Windows:')
573 for w in t.windows:
574 cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + repr(w.cursor))
575 # Other values depend on the size of the terminal, so they are checked partly:
576 for attr in ('height', 'row', 'width', 'col'):
577 try:
578 aval = getattr(w, attr)
579 if type(aval) is not int:
580 raise TypeError
581 if aval < 0:
582 raise ValueError
583 except Exception as e:
584 cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__)
585 w.cursor = (len(w.buffer), 0)
586cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
587if list(vim.windows) != list(vim.current.tabpage.windows):
588 cb.append('!!!!!! Windows differ')
589EOF
590:"
591:" Test vim.current
592py3 << EOF
593def H(o):
594 return repr(o)
595cb.append('Current tab page: ' + repr(vim.current.tabpage))
596cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
597cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
598# Assigning: fails
599try:
600 vim.current.window = vim.tabpages[0].window
601except ValueError:
602 cb.append('ValueError at assigning foreign tab window')
603
604for attr in ('window', 'tabpage', 'buffer'):
605 try:
606 setattr(vim.current, attr, None)
607 except TypeError:
608 cb.append('Type error at assigning None to vim.current.' + attr)
609
610# Assigning: success
611vim.current.tabpage = vim.tabpages[-2]
612vim.current.buffer = cb
613vim.current.window = vim.windows[0]
614vim.current.window.cursor = (len(vim.current.buffer), 0)
615cb.append('Current tab page: ' + repr(vim.current.tabpage))
616cb.append('Current window: ' + repr(vim.current.window))
617cb.append('Current buffer: ' + repr(vim.current.buffer))
618cb.append('Current line: ' + repr(vim.current.line))
619for b in vim.buffers:
620 if b is not cb:
621 vim.command('bwipeout! ' + str(b.number))
622EOF
623:tabonly!
624:only!
Bram Moolenaarcac867a2013-05-21 19:50:34 +0200625:"
626:" Test types
627py3 << EOF
628for expr, attr in (
629 ('vim.vars', 'Dictionary'),
630 ('vim.options', 'Options'),
631 ('vim.bindeval("{}")', 'Dictionary'),
632 ('vim.bindeval("[]")', 'List'),
633 ('vim.bindeval("function(\'tr\')")', 'Function'),
634 ('vim.current.buffer', 'Buffer'),
635 ('vim.current.range', 'Range'),
636 ('vim.current.window', 'Window'),
637 ('vim.current.tabpage', 'TabPage'),
638):
639 cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
640EOF
Bram Moolenaardb913952012-06-29 12:54:53 +0200641:endfun
642:"
643:call Test()
644:"
645:delfunc Test
646:call garbagecollect(1)
647:"
648:/^start:/,$wq! test.out
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200649:call getchar()
Bram Moolenaardb913952012-06-29 12:54:53 +0200650ENDTEST
651
652start: