aboutsummaryrefslogtreecommitdiff
path: root/test/functional/treesitter
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/treesitter')
-rw-r--r--test/functional/treesitter/highlight_spec.lua126
-rw-r--r--test/functional/treesitter/language_spec.lua46
-rw-r--r--test/functional/treesitter/node_spec.lua54
-rw-r--r--test/functional/treesitter/parser_spec.lua9
-rw-r--r--test/functional/treesitter/utils_spec.lua31
5 files changed, 189 insertions, 77 deletions
diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua
index 5ec0a8a060..2a2311c0fa 100644
--- a/test/functional/treesitter/highlight_spec.lua
+++ b/test/functional/treesitter/highlight_spec.lua
@@ -5,12 +5,14 @@ local clear = helpers.clear
local insert = helpers.insert
local exec_lua = helpers.exec_lua
local feed = helpers.feed
-local pending_c_parser = helpers.pending_c_parser
+local command = helpers.command
+local meths = helpers.meths
+local eq = helpers.eq
before_each(clear)
local hl_query = [[
- (ERROR) @ErrorMsg
+ (ERROR) @error
"if" @keyword
"else" @keyword
@@ -23,23 +25,24 @@ local hl_query = [[
"enum" @type
"extern" @type
- (string_literal) @string.nonexistent-specializer-for-string.should-fallback-to-string
+ ; nonexistent specializer for string should fallback to string
+ (string_literal) @string.nonexistent_specializer
(number_literal) @number
(char_literal) @string
(type_identifier) @type
- ((type_identifier) @Special (#eq? @Special "LuaRef"))
+ ((type_identifier) @constant.builtin (#eq? @constant.builtin "LuaRef"))
(primitive_type) @type
(sized_type_specifier) @type
; Use lua regexes
- ((identifier) @Identifier (#contains? @Identifier "lua_"))
+ ((identifier) @function (#contains? @function "lua_"))
((identifier) @Constant (#lua-match? @Constant "^[A-Z_]+$"))
- ((identifier) @Normal (#vim-match? @Constant "^lstate$"))
+ ((identifier) @Normal (#vim-match? @Normal "^lstate$"))
- ((binary_expression left: (identifier) @WarningMsg.left right: (identifier) @WarningMsg.right) (#eq? @WarningMsg.left @WarningMsg.right))
+ ((binary_expression left: (identifier) @warning.left right: (identifier) @warning.right) (#eq? @warning.left @warning.right))
(comment) @comment
]]
@@ -103,11 +106,11 @@ describe('treesitter highlighting', function()
}
exec_lua([[ hl_query = ... ]], hl_query)
+ command [[ hi link @error ErrorMsg ]]
+ command [[ hi link @warning WarningMsg ]]
end)
it('is updated with edits', function()
- if pending_c_parser(pending) then return end
-
insert(hl_text)
screen:expect{grid=[[
/// Schedule Lua callback on main loop's event queue |
@@ -271,8 +274,6 @@ describe('treesitter highlighting', function()
end)
it('is updated with :sort', function()
- if pending_c_parser(pending) then return end
-
insert(test_text)
exec_lua [[
local parser = vim.treesitter.get_parser(0, "c")
@@ -346,8 +347,6 @@ describe('treesitter highlighting', function()
end)
it("supports with custom parser", function()
- if pending_c_parser(pending) then return end
-
screen:set_default_attr_ids {
[1] = {bold = true, foreground = Screen.colors.SeaGreen4};
}
@@ -412,8 +411,6 @@ describe('treesitter highlighting', function()
end)
it("supports injected languages", function()
- if pending_c_parser(pending) then return end
-
insert([[
int x = INT_MAX;
#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
@@ -474,8 +471,6 @@ describe('treesitter highlighting', function()
end)
it("supports overriding queries, like ", function()
- if pending_c_parser(pending) then return end
-
insert([[
int x = INT_MAX;
#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
@@ -515,8 +510,6 @@ describe('treesitter highlighting', function()
end)
it("supports highlighting with custom highlight groups", function()
- if pending_c_parser(pending) then return end
-
insert(hl_text)
exec_lua [[
@@ -547,7 +540,7 @@ describe('treesitter highlighting', function()
-- This will change ONLY the literal strings to look like comments
-- The only literal string is the "vim.schedule: expected function" in this test.
- exec_lua [[vim.cmd("highlight link cString comment")]]
+ exec_lua [[vim.cmd("highlight link @string.nonexistent_specializer comment")]]
screen:expect{grid=[[
{2:/// Schedule Lua callback on main loop's event queue} |
{3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) |
@@ -572,8 +565,6 @@ describe('treesitter highlighting', function()
end)
it("supports highlighting with priority", function()
- if pending_c_parser(pending) then return end
-
insert([[
int x = INT_MAX;
#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
@@ -589,9 +580,9 @@ describe('treesitter highlighting', function()
-- expect everything to have Error highlight
screen:expect{grid=[[
{12:int}{8: x = INT_MAX;} |
- {8:#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))}|
- {8:#define foo void main() { \} |
- {8: return 42; \} |
+ {8:#define READ_STRING(x, y) (}{12:char_u}{8: *)read_string((x), (}{12:size_t}{8:)(y))}|
+ {8:#define foo }{12:void}{8: main() { \} |
+ {8: }{12:return}{8: 42; \} |
{8: }} |
^ |
{1:~ }|
@@ -612,11 +603,14 @@ describe('treesitter highlighting', function()
-- bold will not be overwritten at the moment
[12] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Grey100};
}}
+
+ eq({
+ {capture='Error', metadata = { priority='101' }, lang='c' };
+ {capture='type', metadata = { }, lang='c' };
+ }, exec_lua [[ return vim.treesitter.get_captures_at_pos(0, 0, 2) ]])
end)
it("allows to use captures with dots (don't use fallback when specialization of foo exists)", function()
- if pending_c_parser(pending) then return end
-
insert([[
char* x = "Will somebody ever read this?";
]])
@@ -642,11 +636,13 @@ describe('treesitter highlighting', function()
|
]]}
+ command [[
+ hi link @foo.bar Type
+ hi link @foo String
+ ]]
exec_lua [[
local parser = vim.treesitter.get_parser(0, "c", {})
local highlighter = vim.treesitter.highlighter
- highlighter.hl_map['foo.bar'] = 'Type'
- highlighter.hl_map['foo'] = 'String'
test_hl = highlighter.new(parser, {queries = {c = "(primitive_type) @foo.bar (string_literal) @foo"}})
]]
@@ -670,10 +666,32 @@ describe('treesitter highlighting', function()
{1:~ }|
|
]]}
+
+ -- clearing specialization reactivates fallback
+ command [[ hi clear @foo.bar ]]
+ screen:expect{grid=[[
+ {5:char}* x = {5:"Will somebody ever read this?"}; |
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
end)
it("supports conceal attribute", function()
- if pending_c_parser(pending) then return end
insert(hl_text)
-- conceal can be empty or a single cchar.
@@ -712,32 +730,26 @@ describe('treesitter highlighting', function()
]]}
end)
- it("hl_map has the correct fallback behavior", function()
- exec_lua [[
- local hl_map = vim.treesitter.highlighter.hl_map
- hl_map["foo"] = 1
- hl_map["foo.bar"] = 2
- hl_map["foo.bar.baz"] = 3
-
- assert(hl_map["foo"] == 1)
- assert(hl_map["foo.a.b.c.d"] == 1)
- assert(hl_map["foo.bar"] == 2)
- assert(hl_map["foo.bar.a.b.c.d"] == 2)
- assert(hl_map["foo.bar.baz"] == 3)
- assert(hl_map["foo.bar.baz.d"] == 3)
-
- hl_map["FOO"] = 1
- hl_map["FOO.BAR"] = 2
- assert(hl_map["FOO.BAR.BAZ"] == 2)
-
- hl_map["foo.missing.exists"] = 3
- assert(hl_map["foo.missing"] == 1)
- assert(hl_map["foo.missing.exists"] == 3)
- assert(hl_map["foo.missing.exists.bar"] == 3)
- assert(hl_map["total.nonsense.but.a.lot.of.dots"] == nil)
- -- It will not perform a second look up of this variable but return a sentinel value
- assert(hl_map["total.nonsense.but.a.lot.of.dots"] == "__notfound")
- ]]
-
+ it("@foo.bar groups has the correct fallback behavior", function()
+ local get_hl = function(name) return meths.get_hl_by_name(name,1).foreground end
+ meths.set_hl(0, "@foo", {fg = 1})
+ meths.set_hl(0, "@foo.bar", {fg = 2})
+ meths.set_hl(0, "@foo.bar.baz", {fg = 3})
+
+ eq(1, get_hl"@foo")
+ eq(1, get_hl"@foo.a.b.c.d")
+ eq(2, get_hl"@foo.bar")
+ eq(2, get_hl"@foo.bar.a.b.c.d")
+ eq(3, get_hl"@foo.bar.baz")
+ eq(3, get_hl"@foo.bar.baz.d")
+
+ -- lookup is case insensitive
+ eq(2, get_hl"@FOO.BAR.SPAM")
+
+ meths.set_hl(0, "@foo.missing.exists", {fg = 3})
+ eq(1, get_hl"@foo.missing")
+ eq(3, get_hl"@foo.missing.exists")
+ eq(3, get_hl"@foo.missing.exists.bar")
+ eq(nil, get_hl"@total.nonsense.but.a.lot.of.dots")
end)
end)
diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua
index 30585be328..f95b05a1cc 100644
--- a/test/functional/treesitter/language_spec.lua
+++ b/test/functional/treesitter/language_spec.lua
@@ -6,31 +6,32 @@ local command = helpers.command
local exec_lua = helpers.exec_lua
local pcall_err = helpers.pcall_err
local matches = helpers.matches
-local pending_c_parser = helpers.pending_c_parser
+local insert = helpers.insert
before_each(clear)
-describe('treesitter API', function()
+describe('treesitter language API', function()
-- error tests not requiring a parser library
it('handles missing language', function()
- eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
+ eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')"))
-- actual message depends on platform
- matches("Error executing lua: Failed to load parser: uv_dlopen: .+",
+ matches("Failed to load parser for language 'borklang': uv_dlopen: .+",
pcall_err(exec_lua, "parser = vim.treesitter.require_language('borklang', 'borkbork.so')"))
-- Should not throw an error when silent
eq(false, exec_lua("return vim.treesitter.require_language('borklang', nil, true)"))
eq(false, exec_lua("return vim.treesitter.require_language('borklang', 'borkbork.so', true)"))
- eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
+ eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "parser = vim.treesitter.inspect_language('borklang')"))
+
+ matches("Failed to load parser: uv_dlsym: .+",
+ pcall_err(exec_lua, 'vim.treesitter.require_language("c", nil, false, "borklang")'))
end)
it('inspects language', function()
- if pending_c_parser(pending) then return end
-
local keys, fields, symbols = unpack(exec_lua([[
local lang = vim.treesitter.inspect_language('c')
local keys, symbols = {}, {}
@@ -70,14 +71,41 @@ describe('treesitter API', function()
end)
it('checks if vim.treesitter.get_parser tries to create a new parser on filetype change', function ()
- if pending_c_parser(pending) then return end
command("set filetype=c")
-- Should not throw an error when filetype is c
eq('c', exec_lua("return vim.treesitter.get_parser(0):lang()"))
command("set filetype=borklang")
-- Should throw an error when filetype changes to borklang
- eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
+ eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0)"))
end)
+
+ it('retrieve the tree given a range', function ()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ langtree = vim.treesitter.get_parser(0, "c")
+ tree = langtree:tree_for_range({1, 3, 1, 3})
+ ]])
+
+ eq('<node translation_unit>', exec_lua('return tostring(tree:root())'))
+ end)
+
+ it('retrieve the node given a range', function ()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ langtree = vim.treesitter.get_parser(0, "c")
+ node = langtree:named_node_for_range({1, 3, 1, 3})
+ ]])
+
+ eq('<node primitive_type>', exec_lua('return tostring(node)'))
+ end)
end)
diff --git a/test/functional/treesitter/node_spec.lua b/test/functional/treesitter/node_spec.lua
index 21c287644e..a82dce47b7 100644
--- a/test/functional/treesitter/node_spec.lua
+++ b/test/functional/treesitter/node_spec.lua
@@ -4,7 +4,6 @@ local clear = helpers.clear
local eq = helpers.eq
local exec_lua = helpers.exec_lua
local insert = helpers.insert
-local pending_c_parser = helpers.pending_c_parser
before_each(clear)
@@ -15,10 +14,6 @@ end
describe('treesitter node API', function()
clear()
- if pending_c_parser(pending) then
- return
- end
-
it('can move between siblings', function()
insert([[
int main(int x, int y, int z) {
@@ -59,4 +54,53 @@ describe('treesitter node API', function()
exec_lua 'node = node:prev_named_sibling()'
eq('int x', lua_eval('node_text(node)'))
end)
+
+ it('can retrieve the children of a node', function()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ local len = exec_lua([[
+ tree = vim.treesitter.get_parser(0, "c"):parse()[1]
+ node = tree:root():child(0)
+ children = node:named_children()
+
+ return #children
+ ]])
+
+ eq(3, len)
+ eq('<node compound_statement>', lua_eval('tostring(children[3])'))
+ end)
+
+ it('can retrieve the tree root given a node', function()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ tree = vim.treesitter.get_parser(0, "c"):parse()[1]
+ root = tree:root()
+ node = root:child(0):child(2)
+ ]])
+
+ eq(lua_eval('tostring(root)'), lua_eval('tostring(node:root())'))
+ end)
+
+ it('can compute the byte length of a node', function()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ tree = vim.treesitter.get_parser(0, "c"):parse()[1]
+ root = tree:root()
+ child = root:child(0):child(0)
+ ]])
+
+ eq(28, lua_eval('root:byte_length()'))
+ eq(3, lua_eval('child:byte_length()'))
+ end)
end)
diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua
index 7f3b0e770a..f006ad4539 100644
--- a/test/functional/treesitter/parser_spec.lua
+++ b/test/functional/treesitter/parser_spec.lua
@@ -5,17 +5,15 @@ local eq = helpers.eq
local insert = helpers.insert
local exec_lua = helpers.exec_lua
local feed = helpers.feed
-local pending_c_parser = helpers.pending_c_parser
+local is_os = helpers.is_os
+local skip = helpers.skip
before_each(clear)
describe('treesitter parser API', function()
clear()
- if pending_c_parser(pending) then return end
it('parses buffer', function()
- if helpers.pending_win32(pending) then return end
-
insert([[
int main() {
int x = 3;
@@ -249,7 +247,6 @@ void ui_refresh(void)
end)
it('supports getting text of multiline node', function()
- if pending_c_parser(pending) then return end
insert(test_text)
local res = exec_lua([[
local parser = vim.treesitter.get_parser(0, "c")
@@ -687,7 +684,7 @@ int x = INT_MAX;
end)
it("should not inject bad languages", function()
- if helpers.pending_win32(pending) then return end
+ skip(is_os('win'))
exec_lua([=[
vim.treesitter.add_directive("inject-bad!", function(match, _, _, pred, metadata)
metadata.language = "{"
diff --git a/test/functional/treesitter/utils_spec.lua b/test/functional/treesitter/utils_spec.lua
new file mode 100644
index 0000000000..7f5a864c3d
--- /dev/null
+++ b/test/functional/treesitter/utils_spec.lua
@@ -0,0 +1,31 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local insert = helpers.insert
+local eq = helpers.eq
+local exec_lua = helpers.exec_lua
+
+before_each(clear)
+
+describe('treesitter utils', function()
+ before_each(clear)
+
+ it('can find an ancestor', function()
+
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ parser = vim.treesitter.get_parser(0, "c")
+ tree = parser:parse()[1]
+ root = tree:root()
+ ancestor = root:child(0)
+ child = ancestor:child(0)
+ ]])
+
+ eq(true, exec_lua('return vim.treesitter.is_ancestor(ancestor, child)'))
+ eq(false, exec_lua('return vim.treesitter.is_ancestor(child, ancestor)'))
+ end)
+end)