python3_spec.lua (5789B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local assert_alive = n.assert_alive 5 local eval, command, feed = n.eval, n.command, n.feed 6 local eq, clear, insert = t.eq, n.clear, n.insert 7 local expect, write_file = n.expect, t.write_file 8 local feed_command = n.feed_command 9 local source = n.source 10 local missing_provider = n.missing_provider 11 local matches = t.matches 12 local pcall_err = t.pcall_err 13 local fn = n.fn 14 local dedent = t.dedent 15 16 do 17 clear() 18 local reason = missing_provider('python') 19 if reason then 20 it(':python3 reports E319 if provider is missing', function() 21 local expected = [[Vim%(py3.*%):E319: No "python3" provider found.*]] 22 matches(expected, pcall_err(command, 'py3 print("foo")')) 23 matches(expected, pcall_err(command, 'py3file foo')) 24 end) 25 it('feature test when Python 3 provider is missing', function() 26 eq(0, eval('has("python3")')) 27 eq(0, eval('has("python3_compiled")')) 28 eq(0, eval('has("python3_dynamic")')) 29 eq(0, eval('has("pythonx")')) 30 end) 31 pending( 32 string.format('Python 3 (or the pynvim module) is broken/missing (%s)', reason), 33 function() end 34 ) 35 return 36 end 37 end 38 39 describe('python3 provider', function() 40 before_each(function() 41 clear() 42 command('python3 import vim') 43 end) 44 45 it('feature test', function() 46 eq(1, eval('has("python3")')) 47 eq(1, eval('has("python3_compiled")')) 48 eq(1, eval('has("python3_dynamic")')) 49 eq(1, eval('has("pythonx")')) 50 eq(0, eval('has("python3_dynamic_")')) 51 eq(0, eval('has("python3_")')) 52 end) 53 54 it('python3_execute', function() 55 command('python3 vim.vars["set_by_python3"] = [100, 0]') 56 eq({ 100, 0 }, eval('g:set_by_python3')) 57 end) 58 59 it('does not truncate error message <1 MB', function() 60 -- XXX: Python limits the error name to 200 chars, so this test is 61 -- mostly bogus. 62 local very_long_symbol = string.rep('a', 1200) 63 feed_command(':silent! py3 print(' .. very_long_symbol .. ' b)') 64 -- Error message will contain this (last) line. 65 matches( 66 string.format( 67 dedent([[ 68 ^Invoking 'python_execute' on channel 3 %%(python3%%-script%%-host%%): 69 File "<string>", line 1 70 print%%(%s b%%) 71 %%C* 72 SyntaxError: invalid syntax%%C*$]]), 73 very_long_symbol 74 ), 75 eval('v:errmsg') 76 ) 77 end) 78 79 it('python3_execute with nested commands', function() 80 command( 81 [[python3 vim.command('python3 vim.command("python3 vim.command(\'let set_by_nested_python3 = 555\')")')]] 82 ) 83 eq(555, eval('g:set_by_nested_python3')) 84 end) 85 86 it('python3_execute with range', function() 87 insert([[ 88 line1 89 line2 90 line3 91 line4]]) 92 feed('ggjvj:python3 vim.vars["range"] = vim.current.range[:]<CR>') 93 eq({ 'line2', 'line3' }, eval('g:range')) 94 end) 95 96 it('py3file', function() 97 local fname = 'py3file.py' 98 write_file(fname, 'vim.command("let set_by_py3file = 123")') 99 command('py3file py3file.py') 100 eq(123, eval('g:set_by_py3file')) 101 os.remove(fname) 102 end) 103 104 it('py3do', function() 105 -- :pydo3 42 returns None for all lines, 106 -- the buffer should not be changed 107 command('normal :py3do 42') 108 eq(0, eval('&mod')) 109 -- insert some text 110 insert('abc\ndef\nghi') 111 expect([[ 112 abc 113 def 114 ghi]]) 115 -- go to top and select and replace the first two lines 116 feed('ggvj:py3do return str(linenr)<CR>') 117 expect([[ 118 1 119 2 120 ghi]]) 121 end) 122 123 describe('py3eval()', function() 124 it('works', function() 125 eq({ 1, 2, { ['key'] = 'val' } }, fn.py3eval('[1, 2, {"key": "val"}]')) 126 end) 127 128 it('errors out when given non-string', function() 129 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(10)')) 130 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(v:_null_dict)')) 131 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(v:_null_list)')) 132 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(0.0)')) 133 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(function("tr"))')) 134 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(v:true)')) 135 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(v:false)')) 136 eq('Vim:E474: Invalid argument', pcall_err(eval, 'py3eval(v:null)')) 137 end) 138 139 it('accepts NULL string', function() 140 matches('.*SyntaxError.*', pcall_err(eval, 'py3eval($XXX_NONEXISTENT_VAR_XXX)')) 141 end) 142 end) 143 144 it('pyxeval #10758', function() 145 eq(3, eval([[&pyxversion]])) 146 eq(3, eval([[pyxeval('sys.version_info[:3][0]')]])) 147 eq(3, eval([[&pyxversion]])) 148 end) 149 150 it("setting 'pyxversion'", function() 151 command 'set pyxversion=3' -- no error 152 eq('Vim(set):E474: Invalid argument: pyxversion=2', pcall_err(command, 'set pyxversion=2')) 153 command 'set pyxversion=0' -- allowed, but equivalent to pyxversion=3 154 eq(3, eval '&pyxversion') 155 end) 156 157 it('RPC call to expand("<afile>") during BufDelete #5245 #5617', function() 158 n.add_builddir_to_rtp() 159 source([=[ 160 python3 << EOF 161 import vim 162 def foo(): 163 vim.eval('expand("<afile>:p")') 164 vim.eval('bufnr(expand("<afile>:p"))') 165 EOF 166 autocmd BufDelete * python3 foo() 167 autocmd BufUnload * python3 foo()]=]) 168 feed_command("exe 'split' tempname()") 169 feed_command('bwipeout!') 170 feed_command('help help') 171 assert_alive() 172 end) 173 end) 174 175 describe('python2 feature test', function() 176 -- python2 is not supported, so correct behaviour is to return 0 177 it('works', function() 178 eq(0, fn.has('python2')) 179 eq(0, fn.has('python')) 180 eq(0, fn.has('python_compiled')) 181 eq(0, fn.has('python_dynamic')) 182 eq(0, fn.has('python_dynamic_')) 183 eq(0, fn.has('python_')) 184 end) 185 end)