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