node_spec.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local clear = n.clear
  4. local eq = t.eq
  5. local exec_lua = n.exec_lua
  6. local insert = n.insert
  7. local assert_alive = n.assert_alive
  8. before_each(clear)
  9. local function lua_eval(lua_expr)
  10. return exec_lua('return ' .. lua_expr)
  11. end
  12. describe('treesitter node API', function()
  13. clear()
  14. it('double free tree', function()
  15. insert('F')
  16. exec_lua(function()
  17. vim.treesitter.start(0, 'lua')
  18. vim.treesitter.get_parser(0):parse()
  19. vim.treesitter.get_node():tree()
  20. vim.treesitter.get_node():tree()
  21. collectgarbage()
  22. end)
  23. assert_alive()
  24. end)
  25. it('double free tree 2', function()
  26. exec_lua(function()
  27. local parser = vim.treesitter.get_parser(0, 'c')
  28. local x = parser:parse()[1]:root():tree()
  29. vim.api.nvim_buf_set_text(0, 0, 0, 0, 0, { 'y' })
  30. parser:parse()
  31. vim.api.nvim_buf_set_text(0, 0, 0, 0, 1, { 'z' })
  32. parser:parse()
  33. collectgarbage()
  34. x:root()
  35. end)
  36. assert_alive()
  37. end)
  38. it('get_node() with lang given', function()
  39. -- this buffer doesn't have filetype set!
  40. insert('local foo = function() end')
  41. exec_lua(function()
  42. vim.treesitter.get_parser(0, 'lua'):parse()
  43. _G.node = vim.treesitter.get_node({
  44. bufnr = 0,
  45. pos = { 0, 6 }, -- on "foo"
  46. lang = 'lua',
  47. })
  48. end)
  49. eq('foo', lua_eval('vim.treesitter.get_node_text(node, 0)'))
  50. eq('identifier', lua_eval('node:type()'))
  51. end)
  52. it('get_node() with anonymous nodes included', function()
  53. insert([[print('test')]])
  54. exec_lua(function()
  55. _G.parser = vim.treesitter.get_parser(0, 'lua')
  56. _G.tree = _G.parser:parse()[1]
  57. _G.node = vim.treesitter.get_node({
  58. bufnr = 0,
  59. pos = { 0, 6 }, -- on the first apostrophe
  60. include_anonymous = true,
  61. })
  62. end)
  63. eq("'", lua_eval('node:type()'))
  64. eq(false, lua_eval('node:named()'))
  65. end)
  66. it('can move between siblings', function()
  67. insert([[
  68. int main(int x, int y, int z) {
  69. return x + y * z
  70. }
  71. ]])
  72. exec_lua(function()
  73. local parser = vim.treesitter.get_parser(0, 'c')
  74. local tree = parser:parse()[1]
  75. _G.root = tree:root()
  76. vim.treesitter.language.inspect('c')
  77. function _G.node_text(node)
  78. return vim.treesitter.get_node_text(node, 0)
  79. end
  80. end)
  81. exec_lua 'node = root:descendant_for_range(0, 11, 0, 16)'
  82. eq('int x', lua_eval('node_text(node)'))
  83. exec_lua 'node = node:next_sibling()'
  84. eq(',', lua_eval('node_text(node)'))
  85. exec_lua 'node = node:next_sibling()'
  86. eq('int y', lua_eval('node_text(node)'))
  87. exec_lua 'node = node:prev_sibling()'
  88. eq(',', lua_eval('node_text(node)'))
  89. exec_lua 'node = node:prev_sibling()'
  90. eq('int x', lua_eval('node_text(node)'))
  91. exec_lua 'node = node:next_named_sibling()'
  92. eq('int y', lua_eval('node_text(node)'))
  93. exec_lua 'node = node:prev_named_sibling()'
  94. eq('int x', lua_eval('node_text(node)'))
  95. end)
  96. it('can retrieve the children of a node', function()
  97. insert([[
  98. int main() {
  99. int x = 3;
  100. }]])
  101. local len = exec_lua(function()
  102. local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
  103. local node = assert(tree:root():child(0))
  104. _G.children = node:named_children()
  105. return #_G.children
  106. end)
  107. eq(3, len)
  108. eq('<node compound_statement>', lua_eval('tostring(children[3])'))
  109. end)
  110. it('can retrieve the tree root given a node', function()
  111. insert([[
  112. int main() {
  113. int x = 3;
  114. }]])
  115. exec_lua(function()
  116. local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
  117. _G.root = tree:root()
  118. _G.node = _G.root:child(0):child(2)
  119. end)
  120. eq(lua_eval('tostring(root)'), lua_eval('tostring(node:root())'))
  121. end)
  122. it('can compute the byte length of a node', function()
  123. insert([[
  124. int main() {
  125. int x = 3;
  126. }]])
  127. exec_lua(function()
  128. local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
  129. _G.root = tree:root()
  130. _G.child = _G.root:child(0):child(0)
  131. end)
  132. eq(28, lua_eval('root:byte_length()'))
  133. eq(3, lua_eval('child:byte_length()'))
  134. end)
  135. it('child_with_descendant() works', function()
  136. insert([[
  137. int main() {
  138. int x = 3;
  139. }]])
  140. exec_lua(function()
  141. local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
  142. _G.root = assert(tree:root())
  143. _G.main = assert(_G.root:child(0))
  144. _G.body = assert(_G.main:child(2))
  145. _G.statement = assert(_G.body:child(1))
  146. _G.declarator = assert(_G.statement:child(1))
  147. _G.value = assert(_G.declarator:child(1))
  148. end)
  149. eq(lua_eval('main:type()'), lua_eval('root:child_with_descendant(value):type()'))
  150. eq(lua_eval('body:type()'), lua_eval('main:child_with_descendant(value):type()'))
  151. eq(lua_eval('statement:type()'), lua_eval('body:child_with_descendant(value):type()'))
  152. eq(lua_eval('declarator:type()'), lua_eval('statement:child_with_descendant(value):type()'))
  153. eq(lua_eval('value:type()'), lua_eval('declarator:child_with_descendant(value):type()'))
  154. eq(vim.NIL, lua_eval('value:child_with_descendant(value)'))
  155. end)
  156. it('gets all children with a given field name', function()
  157. insert([[
  158. function foo(a,b,c)
  159. end
  160. ]])
  161. exec_lua(function()
  162. local tree = vim.treesitter.get_parser(0, 'lua'):parse()[1]
  163. _G.parameters_node = assert(tree:root():named_descendant_for_range(0, 18, 0, 18))
  164. _G.children_by_field = _G.parameters_node:field('name')
  165. end)
  166. eq('parameters', lua_eval('parameters_node:type()'))
  167. eq(3, lua_eval('#children_by_field'))
  168. eq('a', lua_eval('vim.treesitter.get_node_text(children_by_field[1], 0)'))
  169. eq('b', lua_eval('vim.treesitter.get_node_text(children_by_field[2], 0)'))
  170. eq('c', lua_eval('vim.treesitter.get_node_text(children_by_field[3], 0)'))
  171. end)
  172. end)