blob: 8ef7e057fe2130dc9762c408604daf87daf4b46b [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
8
Bram Moolenaardb913952012-06-29 12:54:53 +02009STARTTEST
10:so small.vim
11:if !has('python') | e! test.ok | wq! test.out | endif
12: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'
337:try
338: throw "Abc"
339:catch
340: put =pyeval('vim.vvars[''exception'']')
341:endtry
342:put =pyeval('vim.vars[''foo'']')
343:put =pyeval('vim.current.window.vars[''abc'']')
344:put =pyeval('vim.current.buffer.vars[''baz'']')
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200345:"
346:" Options
347:" paste: boolean, global
348:" previewheight number, global
349:" operatorfunc: string, global
350:" number: boolean, window-local
351:" numberwidth: number, window-local
352:" colorcolumn: string, window-local
353:" statusline: string, window-local/global
354:" autoindent: boolean, buffer-local
355:" iminsert: number, buffer-local
356:" omnifunc: string, buffer-local
357:" preserveindent: boolean, buffer-local/global
358:" path: string, buffer-local/global
359:let g:bufs=[bufnr('%')]
360:new
361:let g:bufs+=[bufnr('%')]
362:vnew
363:let g:bufs+=[bufnr('%')]
364:wincmd j
365:vnew
366:let g:bufs+=[bufnr('%')]
367:wincmd l
368:fun RecVars(opt)
369: let gval =string(eval('&g:'.a:opt))
370: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))'))
371: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))'))
372: put =' G: '.gval
373: put =' W: '.wvals
374: put =' B: '.wvals
375:endfun
376py << EOF
377def e(s, g=globals(), l=locals()):
378 try:
379 exec(s, g, l)
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200380 except:
381 vim.command('throw ' + repr(sys.exc_type.__name__))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200382
383def ev(s, g=globals(), l=locals()):
384 try:
385 return eval(s, g, l)
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200386 except:
387 vim.command('throw ' + repr(sys.exc_type.__name__))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200388 return 0
389EOF
390:function E(s)
391: python e(vim.eval('a:s'))
392:endfunction
393:function Ev(s)
394: return pyeval('ev(vim.eval("a:s"))')
395:endfunction
396:py gopts1=vim.options
397:py wopts1=vim.windows[2].options
398:py wopts2=vim.windows[0].options
399:py wopts3=vim.windows[1].options
400:py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
401:py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
402:py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
403:let lst=[]
404:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
405:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]]
406:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
407:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
408:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
409:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc', 0, 0, 1 ]]
410:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
411:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
412:let lst+=[['iminsert', 0, 2, 1, 3, 0, 0, 2 ]]
413:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]]
414:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]]
415:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]]
416:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
417: py oname=vim.eval('oname')
418: py oval1=vim.bindeval('oval1')
419: py oval2=vim.bindeval('oval2')
420: py oval3=vim.bindeval('oval3')
421: if invval is 0 || invval is 1
422: py invval=bool(vim.bindeval('invval'))
423: else
424: py invval=vim.bindeval('invval')
425: endif
426: if bool
427: py oval1=bool(oval1)
428: py oval2=bool(oval2)
429: py oval3=bool(oval3)
430: endif
431: put ='>>> '.oname
432: for v in ['gopts1', 'wopts1', 'bopts1']
433: try
434: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
435: catch
436: put =' p/'.v.'! '.v:exception
437: endtry
438: try
439: call E(v.'["'.oname.'"]=invval')
440: catch
441: put =' inv: '.string(invval).'! '.v:exception
442: endtry
443: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
444: let val=substitute(vv, '^.opts', 'oval', '')
445: try
446: call E(vv.'["'.oname.'"]='.val)
447: catch
448: put =' '.vv.'! '.v:exception
449: endtry
450: endfor
451: endfor
452: call RecVars(oname)
453: for v in ['wopts3', 'bopts3']
454: try
455: call E('del '.v.'["'.oname.'"]')
456: catch
457: put =' del '.v.'! '.v:exception
458: endtry
459: endfor
460: call RecVars(oname)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +0200461:endfor
462:only
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200463:for buf in g:bufs[1:]
464: execute 'bwipeout!' buf
465:endfor
Bram Moolenaarbd80f352013-05-12 21:16:23 +0200466:"
467:" Test buffer object
468:vnew
469:put ='First line'
470:put ='Second line'
471:put ='Third line'
472:1 delete _
473:py b=vim.current.buffer
474:wincmd w
475:mark a
476py << EOF
477cb = vim.current.buffer
478# Tests BufferAppend and BufferItem
479cb.append(b[0])
480# Tests BufferSlice and BufferAssSlice
481cb.append('abc') # Will be overwritten
482cb[-1:] = b[:-2]
483# Test BufferLength and BufferAssSlice
484cb.append('def') # Will not be overwritten
485cb[len(cb):] = b[:]
486# Test BufferAssItem and BufferMark
487cb.append('ghi') # Will be overwritten
488cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
489# Test BufferRepr
490cb.append(repr(cb) + repr(b))
491# Modify foreign buffer
492b.append('foo')
493b[0]='bar'
494b[0:0]=['baz']
495vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
496# Test CheckBuffer
497vim.command('bwipeout! ' + str(b.number))
498for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")'):
499 try:
500 exec(expr)
501 except vim.error:
502 pass
503 else:
504 # Usually a SEGV here
505 # Should not happen in any case
506 cb.append('No exception for ' + expr)
507EOF
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200508:"
509:" Test vim.buffers object
510:set hidden
511:edit a
512:buffer #
513:edit b
514:buffer #
515:edit c
516:buffer #
517py << EOF
518# Check GCing iterator that was not fully exhausted
519i = iter(vim.buffers)
520cb.append('i:' + str(next(i)))
521# and also check creating more then one iterator at a time
522i2 = iter(vim.buffers)
523cb.append('i2:' + str(next(i2)))
524cb.append('i:' + str(next(i)))
525# The following should trigger GC and not cause any problems
526del i
527del i2
528i3 = iter(vim.buffers)
529cb.append('i3:' + str(next(i3)))
530del i3
531
532prevnum = 0
533for b in vim.buffers:
534 # Check buffer order
535 if prevnum >= b.number:
536 cb.append('!!! Buffer numbers not in strictly ascending order')
537 # Check indexing: vim.buffers[number].number == number
538 cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
539 prevnum = b.number
540
541cb.append(str(len(vim.buffers)))
542
543bnums = list(map(lambda b: b.number, vim.buffers))[1:]
544
545# Test wiping out buffer with existing iterator
546i4 = iter(vim.buffers)
547cb.append('i4:' + str(next(i4)))
548vim.command('bwipeout! ' + str(bnums.pop(0)))
549try:
550 next(i4)
551except vim.error:
552 pass
553else:
554 cb.append('!!!! No vim.error')
555i4 = iter(vim.buffers)
556vim.command('bwipeout! ' + str(bnums.pop(-1)))
557vim.command('bwipeout! ' + str(bnums.pop(-1)))
558cb.append('i4:' + str(next(i4)))
559try:
560 next(i4)
561except StopIteration:
562 cb.append('StopIteration')
563EOF
Bram Moolenaardb913952012-06-29 12:54:53 +0200564:endfun
565:"
566:call Test()
567:"
568:delfunc Test
569:call garbagecollect(1)
570:"
571:/^start:/,$wq! test.out
Bram Moolenaar66b79852012-09-21 14:00:35 +0200572:call getchar()
Bram Moolenaardb913952012-06-29 12:54:53 +0200573ENDTEST
574
575start: