diff options
author | Josh Rahm <rahm@google.com> | 2022-07-18 19:37:18 +0000 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-07-18 19:37:18 +0000 |
commit | 308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (patch) | |
tree | 35fe43e01755e0f312650667004487a44d6b7941 /test/functional/treesitter | |
parent | 96a00c7c588b2f38a2424aeeb4ea3581d370bf2d (diff) | |
parent | e8c94697bcbe23a5c7b07c292b90a6b70aadfa87 (diff) | |
download | rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.gz rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.bz2 rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.zip |
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'test/functional/treesitter')
-rw-r--r-- | test/functional/treesitter/highlight_spec.lua | 129 | ||||
-rw-r--r-- | test/functional/treesitter/language_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/treesitter/parser_spec.lua | 55 |
3 files changed, 195 insertions, 1 deletions
diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua index 175525b3f2..5ec0a8a060 100644 --- a/test/functional/treesitter/highlight_spec.lua +++ b/test/functional/treesitter/highlight_spec.lua @@ -23,7 +23,7 @@ local hl_query = [[ "enum" @type "extern" @type - (string_literal) @string + (string_literal) @string.nonexistent-specializer-for-string.should-fallback-to-string (number_literal) @number (char_literal) @string @@ -613,4 +613,131 @@ describe('treesitter highlighting', function() [12] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Grey100}; }} 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?"; + ]]) + + screen:expect{grid=[[ + char* x = "Will somebody ever read this?"; | + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + 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"}}) + ]] + + screen:expect{grid=[[ + {3: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. + exec_lua [=[ + vim.opt.cole = 2 + local parser = vim.treesitter.get_parser(0, "c") + test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = [[ + ("static" @keyword + (set! conceal "R")) + + ((identifier) @Identifier + (set! conceal "") + (eq? @Identifier "lstate")) + ]]}}) + ]=] + + screen:expect{grid=[[ + /// Schedule Lua callback on main loop's event queue | + {4:R} int nlua_schedule(lua_State *const ) | + { | + if (lua_type(, 1) != LUA_TFUNCTION | + || != ) { | + lua_pushliteral(, "vim.schedule: expected function"); | + return lua_error(); | + } | + | + LuaRef cb = nlua_ref(, 1); | + | + multiqueue_put(main_loop.events, nlua_schedule_event, | + 1, (void *)(ptrdiff_t)cb); | + return 0; | + ^} | + {1:~ }| + {1:~ }| + | + ]]} + 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") + ]] + + end) end) diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua index afb17dd2cf..30585be328 100644 --- a/test/functional/treesitter/language_spec.lua +++ b/test/functional/treesitter/language_spec.lua @@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq +local command = helpers.command local exec_lua = helpers.exec_lua local pcall_err = helpers.pcall_err local matches = helpers.matches @@ -67,5 +68,16 @@ describe('treesitter API', function() end eq({true,true}, {has_named,has_anonymous}) 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", + pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0)")) + end) end) diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index 911fa017ab..7f3b0e770a 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -167,6 +167,27 @@ void ui_refresh(void) eq('variable', ret) end) + it("supports caching queries", function() + local long_query = query:rep(100) + local function q(n) + return exec_lua ([[ + local query, n = ... + local before = vim.loop.hrtime() + for i=1,n,1 do + cquery = vim.treesitter.parse_query("c", ...) + end + local after = vim.loop.hrtime() + return after - before + ]], long_query, n) + end + + local firstrun = q(1) + local manyruns = q(100) + + -- First run should be at least 4x slower. + assert(400 * manyruns < firstrun, ('firstrun: %d ms, manyruns: %d ms'):format(firstrun / 1000, manyruns / 1000)) + end) + it('support query and iter by capture', function() insert(test_text) @@ -264,6 +285,25 @@ end]] eq(true, result) end) + it('support getting empty text if node range is zero width', function() + local text = [[ +```lua +{} +```]] + insert(text) + local result = exec_lua([[ + local fake_node = {} + function fake_node:start() + return 1, 0, 7 + end + function fake_node:end_() + return 1, 0, 7 + end + return vim.treesitter.get_node_text(fake_node, 0) == '' + ]]) + eq(true, result) + end) + it('can match special regex characters like \\ * + ( with `vim-match?`', function() insert('char* astring = "\\n"; (1 + 1) * 2 != 2;') @@ -645,6 +685,21 @@ int x = INT_MAX; -- READ_STRING_OK(x, y) (char_u *)read_string((x), (size_t)(y)) }, get_ranges()) end) + + it("should not inject bad languages", function() + if helpers.pending_win32(pending) then return end + exec_lua([=[ + vim.treesitter.add_directive("inject-bad!", function(match, _, _, pred, metadata) + metadata.language = "{" + metadata.combined = true + metadata.content = pred[2] + end) + + parser = vim.treesitter.get_parser(0, "c", { + injections = { + c = "(preproc_function_def value: ((preproc_arg) @_a (#inject-bad! @_a)))"}}) + ]=]) + end) end) describe("when using the offset directive", function() |