language_spec.lua (5067B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local clear = n.clear 5 local eq = t.eq 6 local command = n.command 7 local exec_lua = n.exec_lua 8 local pcall_err = t.pcall_err 9 local matches = t.matches 10 local insert = n.insert 11 local NIL = vim.NIL 12 13 before_each(clear) 14 15 describe('treesitter language API', function() 16 -- error tests not requiring a parser library 17 it('handles missing language', function() 18 eq( 19 '.../treesitter.lua:0: Parser could not be created for buffer 1 and language "borklang"', 20 pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')") 21 ) 22 23 eq(NIL, exec_lua("return vim.treesitter.get_parser(0, 'borklang', { error = false })")) 24 25 -- actual message depends on platform 26 matches( 27 "Failed to load parser for language 'borklang': uv_dlopen: .+", 28 pcall_err( 29 exec_lua, 30 "parser = vim.treesitter.language.add('borklang', { path = 'borkbork.so' })" 31 ) 32 ) 33 34 eq(NIL, exec_lua("return vim.treesitter.language.add('borklang')")) 35 36 eq( 37 false, 38 exec_lua("return pcall(vim.treesitter.language.add, 'borklang', { path = 'borkbork.so' })") 39 ) 40 41 matches( 42 'Failed to load parser: uv_dlsym: .+', 43 pcall_err(exec_lua, 'vim.treesitter.language.add("c", { symbol_name = "borklang" })') 44 ) 45 end) 46 47 it('does not load parser for invalid language name', function() 48 eq(NIL, exec_lua('vim.treesitter.language.add("/foo/")')) 49 end) 50 51 it('inspects language', function() 52 local keys, fields, symbols = unpack(exec_lua(function() 53 local lang = vim.treesitter.language.inspect('c') 54 local keys = {} 55 for k, v in pairs(lang) do 56 if type(v) == 'boolean' then 57 keys[k] = v 58 else 59 keys[k] = true 60 end 61 end 62 63 return { keys, lang.fields, lang.symbols } 64 end)) 65 66 eq({ 67 abi_version = true, 68 fields = true, 69 metadata = true, 70 symbols = true, 71 state_count = true, 72 supertypes = true, 73 _wasm = false, 74 }, keys) 75 76 local fset = {} 77 for _, f in pairs(fields) do 78 eq('string', type(f)) 79 fset[f] = true 80 end 81 eq(true, fset['directive']) 82 eq(true, fset['initializer']) 83 84 local has_named, has_anonymous, has_supertype 85 for symbol, named in pairs(symbols) do 86 eq('string', type(symbol)) 87 eq('boolean', type(named)) 88 if symbol == 'for_statement' and named == true then 89 has_named = true 90 elseif symbol == '"|="' and named == false then 91 has_anonymous = true 92 elseif symbol == 'statement' and named == true then 93 has_supertype = true 94 end 95 end 96 eq( 97 { has_named = true, has_anonymous = true, has_supertype = true }, 98 { has_named = has_named, has_anonymous = has_anonymous, has_supertype = has_supertype } 99 ) 100 end) 101 102 it( 103 'checks if vim.treesitter.get_parser tries to create a new parser on filetype change', 104 function() 105 command('set filetype=c') 106 -- Should not throw an error when filetype is c 107 eq('c', exec_lua('return vim.treesitter.get_parser(0):lang()')) 108 command('set filetype=borklang') 109 -- Should throw an error when filetype changes to borklang 110 eq( 111 '.../treesitter.lua:0: Parser could not be created for buffer 1 and language "borklang"', 112 pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')") 113 ) 114 eq(NIL, exec_lua("return vim.treesitter.get_parser(0, 'borklang', { error = false })")) 115 end 116 ) 117 118 it('retrieve the tree given a range', function() 119 insert([[ 120 int main() { 121 int x = 3; 122 }]]) 123 124 eq( 125 '<node translation_unit>', 126 exec_lua(function() 127 local langtree = vim.treesitter.get_parser(0, 'c') 128 langtree:parse() 129 local tree = langtree:tree_for_range({ 1, 3, 1, 3 }) 130 return tostring(tree:root()) 131 end) 132 ) 133 end) 134 135 it('retrieve the tree given a range when range is out of bounds relative to buffer', function() 136 insert([[ 137 int main() { 138 int x = 3; 139 }]]) 140 141 eq( 142 '<node translation_unit>', 143 exec_lua(function() 144 local langtree = vim.treesitter.get_parser(0, 'c') 145 langtree:parse() 146 local tree = langtree:tree_for_range({ 10, 10, 10, 10 }) 147 return tostring(tree:root()) 148 end) 149 ) 150 end) 151 152 it('retrieve the node given a range', function() 153 insert([[ 154 int main() { 155 int x = 3; 156 }]]) 157 158 eq( 159 '<node primitive_type>', 160 exec_lua(function() 161 local langtree = vim.treesitter.get_parser(0, 'c') 162 langtree:parse() 163 local node = langtree:named_node_for_range({ 1, 3, 1, 3 }) 164 return tostring(node) 165 end) 166 ) 167 end) 168 169 it('retrieve an anonymous node given a range', function() 170 insert([[vim.fn.input()]]) 171 172 exec_lua(function() 173 _G.langtree = vim.treesitter.get_parser(0, 'lua') 174 _G.langtree:parse() 175 _G.node = _G.langtree:node_for_range({ 0, 3, 0, 3 }) 176 end) 177 178 eq('.', exec_lua('return node:type()')) 179 end) 180 end)