aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/api/vim_spec.lua199
-rw-r--r--test/functional/ex_cmds/map_spec.lua21
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua109
-rw-r--r--test/functional/ui/cmdline_spec.lua16
4 files changed, 330 insertions, 15 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index b849304d45..841b7a584a 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,5 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
+local global_helpers = require('test.helpers')
+
local NIL = helpers.NIL
local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
@@ -10,6 +12,10 @@ local request = helpers.request
local meth_pcall = helpers.meth_pcall
local command = helpers.command
+local intchar2lua = global_helpers.intchar2lua
+local format_string = global_helpers.format_string
+local mergedicts_copy = global_helpers.mergedicts_copy
+
describe('api', function()
before_each(clear)
@@ -710,4 +716,197 @@ describe('api', function()
ok(err:match(': Wrong type for argument 1, expecting String') ~= nil)
end)
+ describe('nvim_parse_expression', function()
+ before_each(function()
+ meths.set_option('isident', '')
+ end)
+ local function simplify_east_api_node(line, east_api_node)
+ if east_api_node == NIL then
+ return nil
+ end
+ if east_api_node.children then
+ for k, v in pairs(east_api_node.children) do
+ east_api_node.children[k] = simplify_east_api_node(line, v)
+ end
+ end
+ local typ = east_api_node.type
+ if typ == 'Register' then
+ typ = typ .. ('(name=%s)'):format(
+ tostring(intchar2lua(east_api_node.name)))
+ east_api_node.name = nil
+ elseif typ == 'PlainIdentifier' then
+ typ = typ .. ('(scope=%s,ident=%s)'):format(
+ tostring(intchar2lua(east_api_node.scope)), east_api_node.ident)
+ east_api_node.scope = nil
+ east_api_node.ident = nil
+ elseif typ == 'PlainKey' then
+ typ = typ .. ('(key=%s)'):format(east_api_node.ident)
+ east_api_node.ident = nil
+ elseif typ == 'Comparison' then
+ typ = typ .. ('(type=%s,inv=%u,ccs=%s)'):format(
+ east_api_node.cmp_type, east_api_node.invert and 1 or 0,
+ east_api_node.ccs_strategy)
+ east_api_node.ccs_strategy = nil
+ east_api_node.cmp_type = nil
+ east_api_node.invert = nil
+ elseif typ == 'Integer' then
+ typ = typ .. ('(val=%u)'):format(east_api_node.ivalue)
+ east_api_node.ivalue = nil
+ elseif typ == 'Float' then
+ typ = typ .. format_string('(val=%e)', east_api_node.fvalue)
+ east_api_node.fvalue = nil
+ elseif typ == 'SingleQuotedString' or typ == 'DoubleQuotedString' then
+ typ = format_string('%s(val=%q)', typ, east_api_node.svalue)
+ east_api_node.svalue = nil
+ elseif typ == 'Option' then
+ typ = ('%s(scope=%s,ident=%s)'):format(
+ typ,
+ tostring(intchar2lua(east_api_node.scope)),
+ east_api_node.ident)
+ east_api_node.ident = nil
+ east_api_node.scope = nil
+ elseif typ == 'Environment' then
+ typ = ('%s(ident=%s)'):format(typ, east_api_node.ident)
+ east_api_node.ident = nil
+ elseif typ == 'Assignment' then
+ local aug = east_api_node.augmentation
+ if aug == '' then aug = 'Plain' end
+ typ = ('%s(%s)'):format(typ, aug)
+ east_api_node.augmentation = nil
+ end
+ typ = ('%s:%u:%u:%s'):format(
+ typ, east_api_node.start[1], east_api_node.start[2],
+ line:sub(east_api_node.start[2] + 1,
+ east_api_node.start[2] + 1 + east_api_node.len - 1))
+ assert(east_api_node.start[2] + east_api_node.len - 1 <= #line)
+ for k, _ in pairs(east_api_node.start) do
+ assert(({true, true})[k])
+ end
+ east_api_node.start = nil
+ east_api_node.type = nil
+ east_api_node.len = nil
+ local can_simplify = true
+ for _, _ in pairs(east_api_node) do
+ if can_simplify then can_simplify = false end
+ end
+ if can_simplify then
+ return typ
+ else
+ east_api_node[1] = typ
+ return east_api_node
+ end
+ end
+ local function simplify_east_api(line, east_api)
+ if east_api.error then
+ east_api.err = east_api.error
+ east_api.error = nil
+ east_api.err.msg = east_api.err.message
+ east_api.err.message = nil
+ end
+ if east_api.ast then
+ east_api.ast = {simplify_east_api_node(line, east_api.ast)}
+ if #east_api.ast == 0 then
+ east_api.ast = nil
+ end
+ end
+ if east_api.len == #line then
+ east_api.len = nil
+ end
+ return east_api
+ end
+ local function simplify_east_hl(line, east_hl)
+ for i, v in ipairs(east_hl) do
+ east_hl[i] = ('%s:%u:%u:%s'):format(
+ v[4],
+ v[1],
+ v[2],
+ line:sub(v[2] + 1, v[3]))
+ end
+ return east_hl
+ end
+ local FLAGS_TO_STR = {
+ [0] = "",
+ [1] = "m",
+ [2] = "E",
+ [3] = "mE",
+ [4] = "l",
+ [5] = "lm",
+ [6] = "lE",
+ [7] = "lmE",
+ }
+ local function _check_parsing(opts, str, exp_ast, exp_highlighting_fs,
+ nz_flags_exps)
+ if type(str) ~= 'string' then
+ return
+ end
+ local zflags = opts.flags[1]
+ nz_flags_exps = nz_flags_exps or {}
+ for _, flags in ipairs(opts.flags) do
+ local err, msg = pcall(function()
+ local east_api = meths.parse_expression(str, FLAGS_TO_STR[flags], true)
+ local east_hl = east_api.highlight
+ east_api.highlight = nil
+ local ast = simplify_east_api(str, east_api)
+ local hls = simplify_east_hl(str, east_hl)
+ local exps = {
+ ast = exp_ast,
+ hl_fs = exp_highlighting_fs,
+ }
+ local add_exps = nz_flags_exps[flags]
+ if not add_exps and flags == 3 + zflags then
+ add_exps = nz_flags_exps[1 + zflags] or nz_flags_exps[2 + zflags]
+ end
+ if add_exps then
+ if add_exps.ast then
+ exps.ast = mergedicts_copy(exps.ast, add_exps.ast)
+ end
+ if add_exps.hl_fs then
+ exps.hl_fs = mergedicts_copy(exps.hl_fs, add_exps.hl_fs)
+ end
+ end
+ eq(exps.ast, ast)
+ if exp_highlighting_fs then
+ local exp_highlighting = {}
+ local next_col = 0
+ for i, h in ipairs(exps.hl_fs) do
+ exp_highlighting[i], next_col = h(next_col)
+ end
+ eq(exp_highlighting, hls)
+ end
+ end)
+ if not err then
+ msg = format_string('Error while processing test (%r, %s):\n%s',
+ str, FLAGS_TO_STR[flags], msg)
+ error(msg)
+ end
+ end
+ end
+ local function hl(group, str, shift)
+ return function(next_col)
+ local col = next_col + (shift or 0)
+ return (('%s:%u:%u:%s'):format(
+ 'NVim' .. group,
+ 0,
+ col,
+ str)), (col + #str)
+ end
+ end
+ local function fmtn(typ, args, rest)
+ if (typ == 'UnknownFigure'
+ or typ == 'DictLiteral'
+ or typ == 'CurlyBracesIdentifier'
+ or typ == 'Lambda') then
+ return ('%s%s'):format(typ, rest)
+ elseif typ == 'DoubleQuotedString' or typ == 'SingleQuotedString' then
+ if args:sub(-4) == 'NULL' then
+ args = args:sub(1, -5) .. '""'
+ end
+ return ('%s(%s)%s'):format(typ, args, rest)
+ end
+ end
+ assert:set_parameter('TableFormatLevel', 1000000)
+ require('test.unit.viml.expressions.parser_tests')(
+ it, _check_parsing, hl, fmtn)
+ end)
+
end)
diff --git a/test/functional/ex_cmds/map_spec.lua b/test/functional/ex_cmds/map_spec.lua
new file mode 100644
index 0000000000..b46f83405e
--- /dev/null
+++ b/test/functional/ex_cmds/map_spec.lua
@@ -0,0 +1,21 @@
+local helpers = require("test.functional.helpers")(after_each)
+
+local eq = helpers.eq
+local feed = helpers.feed
+local meths = helpers.meths
+local clear = helpers.clear
+local command = helpers.command
+
+describe(':*map', function()
+ before_each(clear)
+
+ it('are not affected by &isident', function()
+ meths.set_var('counter', 0)
+ command('nnoremap <C-x> :let counter+=1<CR>')
+ meths.set_option('isident', ('%u'):format(('>'):byte()))
+ command('nnoremap <C-y> :let counter+=1<CR>')
+ -- &isident used to disable keycode parsing here as well
+ feed('\24\25<C-x><C-y>')
+ eq(4, meths.get_var('counter'))
+ end)
+end)
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index d87ce72599..54d27723f0 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -144,7 +144,13 @@ before_each(function()
EOB={bold = true, foreground = Screen.colors.Blue1},
ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red},
SK={foreground = Screen.colors.Blue},
- PE={bold = true, foreground = Screen.colors.SeaGreen4}
+ PE={bold = true, foreground = Screen.colors.SeaGreen4},
+ NUM={foreground = Screen.colors.Blue2},
+ NPAR={foreground = Screen.colors.Yellow},
+ SQ={foreground = Screen.colors.Blue3},
+ SB={foreground = Screen.colors.Blue4},
+ E={foreground = Screen.colors.Red, background = Screen.colors.Blue},
+ M={bold = true},
})
end)
@@ -863,7 +869,10 @@ describe('Ex commands coloring support', function()
end)
describe('Expressions coloring support', function()
it('works', function()
- meths.set_var('Nvim_color_expr', 'RainBowParens')
+ meths.command('hi clear NVimNumber')
+ meths.command('hi clear NVimNestingParenthesis')
+ meths.command('hi NVimNumber guifg=Blue2')
+ meths.command('hi NVimNestingParenthesis guifg=Yellow')
feed(':echo <C-r>=(((1)))')
screen:expect([[
|
@@ -873,21 +882,103 @@ describe('Expressions coloring support', function()
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
- ={RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ |
+ ={NPAR:(((}{NUM:1}{NPAR:)))}^ |
]])
end)
- it('errors out when failing to get callback', function()
+ it('does not use Nvim_color_expr', function()
meths.set_var('Nvim_color_expr', 42)
+ -- Used to error out due to failing to get callback.
+ meths.command('hi clear NVimNumber')
+ meths.command('hi NVimNumber guifg=Blue2')
feed(':<C-r>=1')
screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ ={NUM:1}^ |
+ ]])
+ end)
+ it('works correctly with non-ASCII and control characters', function()
+ meths.command('hi clear NVimStringBody')
+ meths.command('hi clear NVimStringQuote')
+ meths.command('hi clear NVimInvalid')
+ meths.command('hi NVimStringQuote guifg=Blue3')
+ meths.command('hi NVimStringBody guifg=Blue4')
+ meths.command('hi NVimInvalid guifg=Red guibg=Blue')
+ feed('i<C-r>="«»"«»')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ ={SQ:"}{SB:«»}{SQ:"}{E:«»}^ |
+ ]])
+ feed('<C-c>')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {M:-- INSERT --} |
+ ]])
+ feed('<Esc>')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ feed(':<C-\\>e"<C-v><C-x>"<C-v><C-x>')
+ -- TODO(ZyX-I): Parser highlighting should not override special character
+ -- highlighting.
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ ={SQ:"}{SB:^X}{SQ:"}{ERR:^X}^ |
+ ]])
+ feed('<C-c>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :^ |
+ ]])
+ funcs.setreg('a', {'\192'})
+ feed('<C-r>="<C-r><C-r>a"<C-r><C-r>a"foo"')
+ -- TODO(ZyX-I): Parser highlighting should not override special character
+ -- highlighting.
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
- = |
- {ERR:E5409: Unable to get g:Nvim_color_expr c}|
- {ERR:allback: Vim:E6000: Argument is not a fu}|
- {ERR:nction or function name} |
- =1^ |
+ ={SQ:"}{SB:<c0>}{SQ:"}{E:<c0>"}{SB:foo}{E:"}^ |
]])
end)
end)
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 0f8302b036..136ab09d4f 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -226,7 +226,11 @@ describe('external cmdline', function()
prompt = "",
special = {'"', true},
},{
- content = { { {}, "1+2" } },
+ content = {
+ { {}, "1" },
+ { {}, "+" },
+ { {}, "2" },
+ },
firstc = "=",
indent = 0,
pos = 3,
@@ -303,7 +307,7 @@ describe('external cmdline', function()
pos = 0,
prompt = "",
}}, cmdline)
- eq({{{{}, 'function Foo()'}}}, block)
+ eq({ { { {}, 'function Foo()'} } }, block)
end)
feed('line1<cr>')
@@ -314,8 +318,8 @@ describe('external cmdline', function()
~ |
|
]], nil, nil, function()
- eq({{{{}, 'function Foo()'}},
- {{{}, ' line1'}}}, block)
+ eq({ { { {}, 'function Foo()'} },
+ { { {}, ' line1'} } }, block)
end)
block = {}
@@ -327,8 +331,8 @@ describe('external cmdline', function()
~ |
^ |
]], nil, nil, function()
- eq({{{{}, 'function Foo()'}},
- {{{}, ' line1'}}}, block)
+ eq({ { { {}, 'function Foo()'} },
+ { { {}, ' line1'} } }, block)
end)