diff options
Diffstat (limited to 'test/unit/viml/expressions')
-rw-r--r-- | test/unit/viml/expressions/lexer_spec.lua | 603 | ||||
-rw-r--r-- | test/unit/viml/expressions/parser_spec.lua | 384 | ||||
-rw-r--r-- | test/unit/viml/expressions/parser_tests.lua | 239 |
3 files changed, 754 insertions, 472 deletions
diff --git a/test/unit/viml/expressions/lexer_spec.lua b/test/unit/viml/expressions/lexer_spec.lua index 358e858d61..96052a5ce1 100644 --- a/test/unit/viml/expressions/lexer_spec.lua +++ b/test/unit/viml/expressions/lexer_spec.lua @@ -83,24 +83,23 @@ local function eltkn2lua(pstate, tkn) type = conv_eltkn_type(tkn.type), } pstate_set_str(pstate, tkn.start, tkn.len, ret) - if not ret.error and (#(ret.str) ~= ret.len) then + if not ret.error and (#ret.str ~= ret.len) then ret.error = '#str /= len' end if ret.type == 'Comparison' then ret.data = { type = conv_cmp_type(tkn.data.cmp.type), ccs = conv_ccs(tkn.data.cmp.ccs), - inv = (not not tkn.data.cmp.inv), + inv = not not tkn.data.cmp.inv, } elseif ret.type == 'Multiplication' then ret.data = { type = conv_enum(eltkn_mul_type_tab, tkn.data.mul.type) } elseif bracket_types[ret.type] then - ret.data = { closing = (not not tkn.data.brc.closing) } + ret.data = { closing = not not tkn.data.brc.closing } elseif ret.type == 'Register' then ret.data = { name = intchar2lua(tkn.data.reg.name) } - elseif (ret.type == 'SingleQuotedString' - or ret.type == 'DoubleQuotedString') then - ret.data = { closed = (not not tkn.data.str.closed) } + elseif ret.type == 'SingleQuotedString' or ret.type == 'DoubleQuotedString' then + ret.data = { closed = not not tkn.data.str.closed } elseif ret.type == 'Option' then ret.data = { scope = conv_enum(eltkn_opt_scope_tab, tkn.data.opt.scope), @@ -109,16 +108,15 @@ local function eltkn2lua(pstate, tkn) elseif ret.type == 'PlainIdentifier' then ret.data = { scope = intchar2lua(tkn.data.var.scope), - autoload = (not not tkn.data.var.autoload), + autoload = not not tkn.data.var.autoload, } elseif ret.type == 'Number' then ret.data = { - is_float = (not not tkn.data.num.is_float), + is_float = not not tkn.data.num.is_float, base = tonumber(tkn.data.num.base), } - ret.data.val = tonumber(tkn.data.num.is_float - and tkn.data.num.val.floating - or tkn.data.num.val.integer) + ret.data.val = + tonumber(tkn.data.num.is_float and tkn.data.num.val.floating or tkn.data.num.val.integer) elseif ret.type == 'Assignment' then ret.data = { type = conv_expr_asgn_type(tkn.data.ass.type) } elseif ret.type == 'Invalid' then @@ -150,156 +148,263 @@ describe('Expressions lexer', function() end end local function singl_eltkn_test(typ, str, data) - local pstate = new_pstate({str}) - eq({data=data, len=#str, start={col=0, line=0}, str=str, type=typ}, - next_eltkn(pstate, flags)) + local pstate = new_pstate({ str }) + eq( + { data = data, len = #str, start = { col = 0, line = 0 }, str = str, type = typ }, + next_eltkn(pstate, flags) + ) check_advance(pstate, #str, 0) - if not ( + if + not ( typ == 'Spacing' or (typ == 'Register' and str == '@') - or ((typ == 'SingleQuotedString' or typ == 'DoubleQuotedString') - and not data.closed) - ) then - pstate = new_pstate({str .. ' '}) - eq({data=data, len=#str, start={col=0, line=0}, str=str, type=typ}, - next_eltkn(pstate, flags)) + or ((typ == 'SingleQuotedString' or typ == 'DoubleQuotedString') and not data.closed) + ) + then + pstate = new_pstate({ str .. ' ' }) + eq( + { data = data, len = #str, start = { col = 0, line = 0 }, str = str, type = typ }, + next_eltkn(pstate, flags) + ) check_advance(pstate, #str, 0) end - pstate = new_pstate({'x' .. str}) + pstate = new_pstate({ 'x' .. str }) pstate.pos.col = 1 - eq({data=data, len=#str, start={col=1, line=0}, str=str, type=typ}, - next_eltkn(pstate, flags)) + eq( + { data = data, len = #str, start = { col = 1, line = 0 }, str = str, type = typ }, + next_eltkn(pstate, flags) + ) check_advance(pstate, #str, 1) end local function scope_test(scope) - singl_eltkn_test('PlainIdentifier', scope .. ':test#var', {autoload=true, scope=scope}) - singl_eltkn_test('PlainIdentifier', scope .. ':', {autoload=false, scope=scope}) + singl_eltkn_test('PlainIdentifier', scope .. ':test#var', { autoload = true, scope = scope }) + singl_eltkn_test('PlainIdentifier', scope .. ':', { autoload = false, scope = scope }) end local function comparison_test(op, inv_op, cmp_type) - singl_eltkn_test('Comparison', op, {type=cmp_type, inv=false, ccs='UseOption'}) - singl_eltkn_test('Comparison', inv_op, {type=cmp_type, inv=true, ccs='UseOption'}) - singl_eltkn_test('Comparison', op .. '#', {type=cmp_type, inv=false, ccs='MatchCase'}) - singl_eltkn_test('Comparison', inv_op .. '#', {type=cmp_type, inv=true, ccs='MatchCase'}) - singl_eltkn_test('Comparison', op .. '?', {type=cmp_type, inv=false, ccs='IgnoreCase'}) - singl_eltkn_test('Comparison', inv_op .. '?', {type=cmp_type, inv=true, ccs='IgnoreCase'}) + singl_eltkn_test('Comparison', op, { type = cmp_type, inv = false, ccs = 'UseOption' }) + singl_eltkn_test('Comparison', inv_op, { type = cmp_type, inv = true, ccs = 'UseOption' }) + singl_eltkn_test('Comparison', op .. '#', { type = cmp_type, inv = false, ccs = 'MatchCase' }) + singl_eltkn_test( + 'Comparison', + inv_op .. '#', + { type = cmp_type, inv = true, ccs = 'MatchCase' } + ) + singl_eltkn_test('Comparison', op .. '?', { type = cmp_type, inv = false, ccs = 'IgnoreCase' }) + singl_eltkn_test( + 'Comparison', + inv_op .. '?', + { type = cmp_type, inv = true, ccs = 'IgnoreCase' } + ) end local function simple_test(pstate_arg, exp_type, exp_len, exp) local pstate = new_pstate(pstate_arg) exp = shallowcopy(exp) exp.type = exp_type - exp.len = exp_len or #(pstate_arg[0]) + exp.len = exp_len or #pstate_arg[0] exp.start = { col = 0, line = 0 } eq(exp, next_eltkn(pstate, flags)) end local function stable_tests() - singl_eltkn_test('Parenthesis', '(', {closing=false}) - singl_eltkn_test('Parenthesis', ')', {closing=true}) - singl_eltkn_test('Bracket', '[', {closing=false}) - singl_eltkn_test('Bracket', ']', {closing=true}) - singl_eltkn_test('FigureBrace', '{', {closing=false}) - singl_eltkn_test('FigureBrace', '}', {closing=true}) + singl_eltkn_test('Parenthesis', '(', { closing = false }) + singl_eltkn_test('Parenthesis', ')', { closing = true }) + singl_eltkn_test('Bracket', '[', { closing = false }) + singl_eltkn_test('Bracket', ']', { closing = true }) + singl_eltkn_test('FigureBrace', '{', { closing = false }) + singl_eltkn_test('FigureBrace', '}', { closing = true }) singl_eltkn_test('Question', '?') singl_eltkn_test('Colon', ':') singl_eltkn_test('Dot', '.') - singl_eltkn_test('Assignment', '.=', {type='Concat'}) + singl_eltkn_test('Assignment', '.=', { type = 'Concat' }) singl_eltkn_test('Plus', '+') - singl_eltkn_test('Assignment', '+=', {type='Add'}) + singl_eltkn_test('Assignment', '+=', { type = 'Add' }) singl_eltkn_test('Comma', ',') - singl_eltkn_test('Multiplication', '*', {type='Mul'}) - singl_eltkn_test('Multiplication', '/', {type='Div'}) - singl_eltkn_test('Multiplication', '%', {type='Mod'}) + singl_eltkn_test('Multiplication', '*', { type = 'Mul' }) + singl_eltkn_test('Multiplication', '/', { type = 'Div' }) + singl_eltkn_test('Multiplication', '%', { type = 'Mod' }) singl_eltkn_test('Spacing', ' \t\t \t\t') singl_eltkn_test('Spacing', ' ') singl_eltkn_test('Spacing', '\t') - singl_eltkn_test('Invalid', '\x01\x02\x03', {error='E15: Invalid control character present in input: %.*s'}) - singl_eltkn_test('Number', '0123', {is_float=false, base=8, val=83}) - singl_eltkn_test('Number', '01234567', {is_float=false, base=8, val=342391}) - singl_eltkn_test('Number', '012345678', {is_float=false, base=10, val=12345678}) - singl_eltkn_test('Number', '0x123', {is_float=false, base=16, val=291}) - singl_eltkn_test('Number', '0x56FF', {is_float=false, base=16, val=22271}) - singl_eltkn_test('Number', '0xabcdef', {is_float=false, base=16, val=11259375}) - singl_eltkn_test('Number', '0xABCDEF', {is_float=false, base=16, val=11259375}) - singl_eltkn_test('Number', '0x0', {is_float=false, base=16, val=0}) - singl_eltkn_test('Number', '00', {is_float=false, base=8, val=0}) - singl_eltkn_test('Number', '0b0', {is_float=false, base=2, val=0}) - singl_eltkn_test('Number', '0b010111', {is_float=false, base=2, val=23}) - singl_eltkn_test('Number', '0b100111', {is_float=false, base=2, val=39}) - singl_eltkn_test('Number', '0', {is_float=false, base=10, val=0}) - singl_eltkn_test('Number', '9', {is_float=false, base=10, val=9}) + singl_eltkn_test( + 'Invalid', + '\x01\x02\x03', + { error = 'E15: Invalid control character present in input: %.*s' } + ) + singl_eltkn_test('Number', '0123', { is_float = false, base = 8, val = 83 }) + singl_eltkn_test('Number', '01234567', { is_float = false, base = 8, val = 342391 }) + singl_eltkn_test('Number', '012345678', { is_float = false, base = 10, val = 12345678 }) + singl_eltkn_test('Number', '0x123', { is_float = false, base = 16, val = 291 }) + singl_eltkn_test('Number', '0x56FF', { is_float = false, base = 16, val = 22271 }) + singl_eltkn_test('Number', '0xabcdef', { is_float = false, base = 16, val = 11259375 }) + singl_eltkn_test('Number', '0xABCDEF', { is_float = false, base = 16, val = 11259375 }) + singl_eltkn_test('Number', '0x0', { is_float = false, base = 16, val = 0 }) + singl_eltkn_test('Number', '00', { is_float = false, base = 8, val = 0 }) + singl_eltkn_test('Number', '0b0', { is_float = false, base = 2, val = 0 }) + singl_eltkn_test('Number', '0b010111', { is_float = false, base = 2, val = 23 }) + singl_eltkn_test('Number', '0b100111', { is_float = false, base = 2, val = 39 }) + singl_eltkn_test('Number', '0', { is_float = false, base = 10, val = 0 }) + singl_eltkn_test('Number', '9', { is_float = false, base = 10, val = 9 }) singl_eltkn_test('Env', '$abc') singl_eltkn_test('Env', '$') - singl_eltkn_test('PlainIdentifier', 'test', {autoload=false, scope=0}) - singl_eltkn_test('PlainIdentifier', '_test', {autoload=false, scope=0}) - singl_eltkn_test('PlainIdentifier', '_test_foo', {autoload=false, scope=0}) - singl_eltkn_test('PlainIdentifier', 't', {autoload=false, scope=0}) - singl_eltkn_test('PlainIdentifier', 'test5', {autoload=false, scope=0}) - singl_eltkn_test('PlainIdentifier', 't0', {autoload=false, scope=0}) - singl_eltkn_test('PlainIdentifier', 'test#var', {autoload=true, scope=0}) - singl_eltkn_test('PlainIdentifier', 'test#var#val###', {autoload=true, scope=0}) - singl_eltkn_test('PlainIdentifier', 't#####', {autoload=true, scope=0}) + singl_eltkn_test('PlainIdentifier', 'test', { autoload = false, scope = 0 }) + singl_eltkn_test('PlainIdentifier', '_test', { autoload = false, scope = 0 }) + singl_eltkn_test('PlainIdentifier', '_test_foo', { autoload = false, scope = 0 }) + singl_eltkn_test('PlainIdentifier', 't', { autoload = false, scope = 0 }) + singl_eltkn_test('PlainIdentifier', 'test5', { autoload = false, scope = 0 }) + singl_eltkn_test('PlainIdentifier', 't0', { autoload = false, scope = 0 }) + singl_eltkn_test('PlainIdentifier', 'test#var', { autoload = true, scope = 0 }) + singl_eltkn_test('PlainIdentifier', 'test#var#val###', { autoload = true, scope = 0 }) + singl_eltkn_test('PlainIdentifier', 't#####', { autoload = true, scope = 0 }) singl_eltkn_test('And', '&&') singl_eltkn_test('Or', '||') - singl_eltkn_test('Invalid', '&', {error='E112: Option name missing: %.*s'}) - singl_eltkn_test('Option', '&opt', {scope='Unspecified', name='opt'}) - singl_eltkn_test('Option', '&t_xx', {scope='Unspecified', name='t_xx'}) - singl_eltkn_test('Option', '&t_\r\r', {scope='Unspecified', name='t_\r\r'}) - singl_eltkn_test('Option', '&t_\t\t', {scope='Unspecified', name='t_\t\t'}) - singl_eltkn_test('Option', '&t_ ', {scope='Unspecified', name='t_ '}) - singl_eltkn_test('Option', '&g:opt', {scope='Global', name='opt'}) - singl_eltkn_test('Option', '&l:opt', {scope='Local', name='opt'}) - singl_eltkn_test('Invalid', '&l:', {error='E112: Option name missing: %.*s'}) - singl_eltkn_test('Invalid', '&g:', {error='E112: Option name missing: %.*s'}) - singl_eltkn_test('Register', '@', {name=-1}) - singl_eltkn_test('Register', '@a', {name='a'}) - singl_eltkn_test('Register', '@\r', {name=13}) - singl_eltkn_test('Register', '@ ', {name=' '}) - singl_eltkn_test('Register', '@\t', {name=9}) - singl_eltkn_test('SingleQuotedString', '\'test', {closed=false}) - singl_eltkn_test('SingleQuotedString', '\'test\'', {closed=true}) - singl_eltkn_test('SingleQuotedString', '\'\'\'\'', {closed=true}) - singl_eltkn_test('SingleQuotedString', '\'x\'\'\'', {closed=true}) - singl_eltkn_test('SingleQuotedString', '\'\'\'x\'', {closed=true}) - singl_eltkn_test('SingleQuotedString', '\'\'\'', {closed=false}) - singl_eltkn_test('SingleQuotedString', '\'x\'\'', {closed=false}) - singl_eltkn_test('SingleQuotedString', '\'\'\'x', {closed=false}) - singl_eltkn_test('DoubleQuotedString', '"test', {closed=false}) - singl_eltkn_test('DoubleQuotedString', '"test"', {closed=true}) - singl_eltkn_test('DoubleQuotedString', '"\\""', {closed=true}) - singl_eltkn_test('DoubleQuotedString', '"x\\""', {closed=true}) - singl_eltkn_test('DoubleQuotedString', '"\\"x"', {closed=true}) - singl_eltkn_test('DoubleQuotedString', '"\\"', {closed=false}) - singl_eltkn_test('DoubleQuotedString', '"x\\"', {closed=false}) - singl_eltkn_test('DoubleQuotedString', '"\\"x', {closed=false}) + singl_eltkn_test('Invalid', '&', { error = 'E112: Option name missing: %.*s' }) + singl_eltkn_test('Option', '&opt', { scope = 'Unspecified', name = 'opt' }) + singl_eltkn_test('Option', '&t_xx', { scope = 'Unspecified', name = 't_xx' }) + singl_eltkn_test('Option', '&t_\r\r', { scope = 'Unspecified', name = 't_\r\r' }) + singl_eltkn_test('Option', '&t_\t\t', { scope = 'Unspecified', name = 't_\t\t' }) + singl_eltkn_test('Option', '&t_ ', { scope = 'Unspecified', name = 't_ ' }) + singl_eltkn_test('Option', '&g:opt', { scope = 'Global', name = 'opt' }) + singl_eltkn_test('Option', '&l:opt', { scope = 'Local', name = 'opt' }) + singl_eltkn_test('Invalid', '&l:', { error = 'E112: Option name missing: %.*s' }) + singl_eltkn_test('Invalid', '&g:', { error = 'E112: Option name missing: %.*s' }) + singl_eltkn_test('Register', '@', { name = -1 }) + singl_eltkn_test('Register', '@a', { name = 'a' }) + singl_eltkn_test('Register', '@\r', { name = 13 }) + singl_eltkn_test('Register', '@ ', { name = ' ' }) + singl_eltkn_test('Register', '@\t', { name = 9 }) + singl_eltkn_test('SingleQuotedString', "'test", { closed = false }) + singl_eltkn_test('SingleQuotedString', "'test'", { closed = true }) + singl_eltkn_test('SingleQuotedString', "''''", { closed = true }) + singl_eltkn_test('SingleQuotedString', "'x'''", { closed = true }) + singl_eltkn_test('SingleQuotedString', "'''x'", { closed = true }) + singl_eltkn_test('SingleQuotedString', "'''", { closed = false }) + singl_eltkn_test('SingleQuotedString', "'x''", { closed = false }) + singl_eltkn_test('SingleQuotedString', "'''x", { closed = false }) + singl_eltkn_test('DoubleQuotedString', '"test', { closed = false }) + singl_eltkn_test('DoubleQuotedString', '"test"', { closed = true }) + singl_eltkn_test('DoubleQuotedString', '"\\""', { closed = true }) + singl_eltkn_test('DoubleQuotedString', '"x\\""', { closed = true }) + singl_eltkn_test('DoubleQuotedString', '"\\"x"', { closed = true }) + singl_eltkn_test('DoubleQuotedString', '"\\"', { closed = false }) + singl_eltkn_test('DoubleQuotedString', '"x\\"', { closed = false }) + singl_eltkn_test('DoubleQuotedString', '"\\"x', { closed = false }) singl_eltkn_test('Not', '!') - singl_eltkn_test('Assignment', '=', {type='Plain'}) + singl_eltkn_test('Assignment', '=', { type = 'Plain' }) comparison_test('==', '!=', 'Equal') comparison_test('=~', '!~', 'Matches') comparison_test('>', '<=', 'Greater') comparison_test('>=', '<', 'GreaterOrEqual') singl_eltkn_test('Minus', '-') - singl_eltkn_test('Assignment', '-=', {type='Subtract'}) + singl_eltkn_test('Assignment', '-=', { type = 'Subtract' }) singl_eltkn_test('Arrow', '->') - singl_eltkn_test('Invalid', '~', {error='E15: Unidentified character: %.*s'}) - simple_test({{data=nil, size=0}}, 'EOC', 0, {error='start.col >= #pstr'}) - simple_test({''}, 'EOC', 0, {error='start.col >= #pstr'}) - simple_test({'2.'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2e5'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.x'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.2.'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0x'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e+'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e-'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e+x'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e-x'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e+1a'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e-1a'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'0b102'}, 'Number', 4, {data={is_float=false, base=2, val=2}, str='0b10'}) - simple_test({'10F'}, 'Number', 2, {data={is_float=false, base=10, val=10}, str='10'}) - simple_test({'0x0123456789ABCDEFG'}, 'Number', 18, {data={is_float=false, base=16, val=81985529216486895}, str='0x0123456789ABCDEF'}) - simple_test({{data='00', size=2}}, 'Number', 2, {data={is_float=false, base=8, val=0}, str='00'}) - simple_test({{data='009', size=2}}, 'Number', 2, {data={is_float=false, base=8, val=0}, str='00'}) - simple_test({{data='01', size=1}}, 'Number', 1, {data={is_float=false, base=10, val=0}, str='0'}) + singl_eltkn_test('Invalid', '~', { error = 'E15: Unidentified character: %.*s' }) + simple_test({ { data = nil, size = 0 } }, 'EOC', 0, { error = 'start.col >= #pstr' }) + simple_test({ '' }, 'EOC', 0, { error = 'start.col >= #pstr' }) + simple_test( + { '2.' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2e5' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.x' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.2.' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0x' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e+' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e-' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e+x' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e-x' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e+1a' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e-1a' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '0b102' }, + 'Number', + 4, + { data = { is_float = false, base = 2, val = 2 }, str = '0b10' } + ) + simple_test( + { '10F' }, + 'Number', + 2, + { data = { is_float = false, base = 10, val = 10 }, str = '10' } + ) + simple_test({ '0x0123456789ABCDEFG' }, 'Number', 18, { + data = { is_float = false, base = 16, val = 81985529216486895 }, + str = '0x0123456789ABCDEF', + }) + simple_test( + { { data = '00', size = 2 } }, + 'Number', + 2, + { data = { is_float = false, base = 8, val = 0 }, str = '00' } + ) + simple_test( + { { data = '009', size = 2 } }, + 'Number', + 2, + { data = { is_float = false, base = 8, val = 0 }, str = '00' } + ) + simple_test( + { { data = '01', size = 1 } }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 0 }, str = '0' } + ) end local function regular_scope_tests() @@ -312,29 +417,104 @@ describe('Expressions lexer', function() scope_test('l') scope_test('a') - simple_test({'g:'}, 'PlainIdentifier', 2, {data={scope='g', autoload=false}, str='g:'}) - simple_test({'g:is#foo'}, 'PlainIdentifier', 8, {data={scope='g', autoload=true}, str='g:is#foo'}) - simple_test({'g:isnot#foo'}, 'PlainIdentifier', 11, {data={scope='g', autoload=true}, str='g:isnot#foo'}) + simple_test( + { 'g:' }, + 'PlainIdentifier', + 2, + { data = { scope = 'g', autoload = false }, str = 'g:' } + ) + simple_test( + { 'g:is#foo' }, + 'PlainIdentifier', + 8, + { data = { scope = 'g', autoload = true }, str = 'g:is#foo' } + ) + simple_test( + { 'g:isnot#foo' }, + 'PlainIdentifier', + 11, + { data = { scope = 'g', autoload = true }, str = 'g:isnot#foo' } + ) end local function regular_is_tests() comparison_test('is', 'isnot', 'Identical') - simple_test({'is'}, 'Comparison', 2, {data={type='Identical', inv=false, ccs='UseOption'}, str='is'}) - simple_test({'isnot'}, 'Comparison', 5, {data={type='Identical', inv=true, ccs='UseOption'}, str='isnot'}) - simple_test({'is?'}, 'Comparison', 3, {data={type='Identical', inv=false, ccs='IgnoreCase'}, str='is?'}) - simple_test({'isnot?'}, 'Comparison', 6, {data={type='Identical', inv=true, ccs='IgnoreCase'}, str='isnot?'}) - simple_test({'is#'}, 'Comparison', 3, {data={type='Identical', inv=false, ccs='MatchCase'}, str='is#'}) - simple_test({'isnot#'}, 'Comparison', 6, {data={type='Identical', inv=true, ccs='MatchCase'}, str='isnot#'}) - simple_test({'is#foo'}, 'Comparison', 3, {data={type='Identical', inv=false, ccs='MatchCase'}, str='is#'}) - simple_test({'isnot#foo'}, 'Comparison', 6, {data={type='Identical', inv=true, ccs='MatchCase'}, str='isnot#'}) + simple_test( + { 'is' }, + 'Comparison', + 2, + { data = { type = 'Identical', inv = false, ccs = 'UseOption' }, str = 'is' } + ) + simple_test( + { 'isnot' }, + 'Comparison', + 5, + { data = { type = 'Identical', inv = true, ccs = 'UseOption' }, str = 'isnot' } + ) + simple_test( + { 'is?' }, + 'Comparison', + 3, + { data = { type = 'Identical', inv = false, ccs = 'IgnoreCase' }, str = 'is?' } + ) + simple_test( + { 'isnot?' }, + 'Comparison', + 6, + { data = { type = 'Identical', inv = true, ccs = 'IgnoreCase' }, str = 'isnot?' } + ) + simple_test( + { 'is#' }, + 'Comparison', + 3, + { data = { type = 'Identical', inv = false, ccs = 'MatchCase' }, str = 'is#' } + ) + simple_test( + { 'isnot#' }, + 'Comparison', + 6, + { data = { type = 'Identical', inv = true, ccs = 'MatchCase' }, str = 'isnot#' } + ) + simple_test( + { 'is#foo' }, + 'Comparison', + 3, + { data = { type = 'Identical', inv = false, ccs = 'MatchCase' }, str = 'is#' } + ) + simple_test( + { 'isnot#foo' }, + 'Comparison', + 6, + { data = { type = 'Identical', inv = true, ccs = 'MatchCase' }, str = 'isnot#' } + ) end local function regular_number_tests() - simple_test({'2.0'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e5'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e+5'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({'2.0e-5'}, 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) + simple_test( + { '2.0' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e5' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e+5' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { '2.0e-5' }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) end local function regular_eoc_tests() @@ -369,7 +549,12 @@ describe('Expressions lexer', function() regular_is_tests() regular_number_tests() - simple_test({'g:'}, 'PlainIdentifier', 1, {data={scope=0, autoload=false}, str='g'}) + simple_test( + { 'g:' }, + 'PlainIdentifier', + 1, + { data = { scope = 0, autoload = false }, str = 'g' } + ) end) itp('allows floats', function() flags = tonumber(lib.kELFlagAllowFloat) @@ -379,20 +564,72 @@ describe('Expressions lexer', function() regular_scope_tests() regular_is_tests() - simple_test({'2.2'}, 'Number', 3, {data={is_float=true, base=10, val=2.2}, str='2.2'}) - simple_test({'2.0e5'}, 'Number', 5, {data={is_float=true, base=10, val=2e5}, str='2.0e5'}) - simple_test({'2.0e+5'}, 'Number', 6, {data={is_float=true, base=10, val=2e5}, str='2.0e+5'}) - simple_test({'2.0e-5'}, 'Number', 6, {data={is_float=true, base=10, val=2e-5}, str='2.0e-5'}) - simple_test({'2.500000e-5'}, 'Number', 11, {data={is_float=true, base=10, val=2.5e-5}, str='2.500000e-5'}) - simple_test({'2.5555e2'}, 'Number', 8, {data={is_float=true, base=10, val=2.5555e2}, str='2.5555e2'}) - simple_test({'2.5555e+2'}, 'Number', 9, {data={is_float=true, base=10, val=2.5555e2}, str='2.5555e+2'}) - simple_test({'2.5555e-2'}, 'Number', 9, {data={is_float=true, base=10, val=2.5555e-2}, str='2.5555e-2'}) - simple_test({{data='2.5e-5', size=3}}, - 'Number', 3, {data={is_float=true, base=10, val=2.5}, str='2.5'}) - simple_test({{data='2.5e5', size=4}}, - 'Number', 1, {data={is_float=false, base=10, val=2}, str='2'}) - simple_test({{data='2.5e-50', size=6}}, - 'Number', 6, {data={is_float=true, base=10, val=2.5e-5}, str='2.5e-5'}) + simple_test( + { '2.2' }, + 'Number', + 3, + { data = { is_float = true, base = 10, val = 2.2 }, str = '2.2' } + ) + simple_test( + { '2.0e5' }, + 'Number', + 5, + { data = { is_float = true, base = 10, val = 2e5 }, str = '2.0e5' } + ) + simple_test( + { '2.0e+5' }, + 'Number', + 6, + { data = { is_float = true, base = 10, val = 2e5 }, str = '2.0e+5' } + ) + simple_test( + { '2.0e-5' }, + 'Number', + 6, + { data = { is_float = true, base = 10, val = 2e-5 }, str = '2.0e-5' } + ) + simple_test( + { '2.500000e-5' }, + 'Number', + 11, + { data = { is_float = true, base = 10, val = 2.5e-5 }, str = '2.500000e-5' } + ) + simple_test( + { '2.5555e2' }, + 'Number', + 8, + { data = { is_float = true, base = 10, val = 2.5555e2 }, str = '2.5555e2' } + ) + simple_test( + { '2.5555e+2' }, + 'Number', + 9, + { data = { is_float = true, base = 10, val = 2.5555e2 }, str = '2.5555e+2' } + ) + simple_test( + { '2.5555e-2' }, + 'Number', + 9, + { data = { is_float = true, base = 10, val = 2.5555e-2 }, str = '2.5555e-2' } + ) + simple_test( + { { data = '2.5e-5', size = 3 } }, + 'Number', + 3, + { data = { is_float = true, base = 10, val = 2.5 }, str = '2.5' } + ) + simple_test( + { { data = '2.5e5', size = 4 } }, + 'Number', + 1, + { data = { is_float = false, base = 10, val = 2 }, str = '2' } + ) + simple_test( + { { data = '2.5e-50', size = 6 } }, + 'Number', + 6, + { data = { is_float = true, base = 10, val = 2.5e-5 }, str = '2.5e-5' } + ) end) itp('treats `is` as an identifier', function() flags = tonumber(lib.kELFlagIsNotCmp) @@ -402,14 +639,54 @@ describe('Expressions lexer', function() regular_scope_tests() regular_number_tests() - simple_test({'is'}, 'PlainIdentifier', 2, {data={scope=0, autoload=false}, str='is'}) - simple_test({'isnot'}, 'PlainIdentifier', 5, {data={scope=0, autoload=false}, str='isnot'}) - simple_test({'is?'}, 'PlainIdentifier', 2, {data={scope=0, autoload=false}, str='is'}) - simple_test({'isnot?'}, 'PlainIdentifier', 5, {data={scope=0, autoload=false}, str='isnot'}) - simple_test({'is#'}, 'PlainIdentifier', 3, {data={scope=0, autoload=true}, str='is#'}) - simple_test({'isnot#'}, 'PlainIdentifier', 6, {data={scope=0, autoload=true}, str='isnot#'}) - simple_test({'is#foo'}, 'PlainIdentifier', 6, {data={scope=0, autoload=true}, str='is#foo'}) - simple_test({'isnot#foo'}, 'PlainIdentifier', 9, {data={scope=0, autoload=true}, str='isnot#foo'}) + simple_test( + { 'is' }, + 'PlainIdentifier', + 2, + { data = { scope = 0, autoload = false }, str = 'is' } + ) + simple_test( + { 'isnot' }, + 'PlainIdentifier', + 5, + { data = { scope = 0, autoload = false }, str = 'isnot' } + ) + simple_test( + { 'is?' }, + 'PlainIdentifier', + 2, + { data = { scope = 0, autoload = false }, str = 'is' } + ) + simple_test( + { 'isnot?' }, + 'PlainIdentifier', + 5, + { data = { scope = 0, autoload = false }, str = 'isnot' } + ) + simple_test( + { 'is#' }, + 'PlainIdentifier', + 3, + { data = { scope = 0, autoload = true }, str = 'is#' } + ) + simple_test( + { 'isnot#' }, + 'PlainIdentifier', + 6, + { data = { scope = 0, autoload = true }, str = 'isnot#' } + ) + simple_test( + { 'is#foo' }, + 'PlainIdentifier', + 6, + { data = { scope = 0, autoload = true }, str = 'is#foo' } + ) + simple_test( + { 'isnot#foo' }, + 'PlainIdentifier', + 9, + { data = { scope = 0, autoload = true }, str = 'isnot#foo' } + ) end) itp('forbids EOC', function() flags = tonumber(lib.kELFlagForbidEOC) @@ -419,8 +696,8 @@ describe('Expressions lexer', function() regular_is_tests() regular_number_tests() - singl_eltkn_test('Invalid', '|', {error='E15: Unexpected EOC character: %.*s'}) - singl_eltkn_test('Invalid', '\0', {error='E15: Unexpected EOC character: %.*s'}) - singl_eltkn_test('Invalid', '\n', {error='E15: Unexpected EOC character: %.*s'}) + singl_eltkn_test('Invalid', '|', { error = 'E15: Unexpected EOC character: %.*s' }) + singl_eltkn_test('Invalid', '\0', { error = 'E15: Unexpected EOC character: %.*s' }) + singl_eltkn_test('Invalid', '\n', { error = 'E15: Unexpected EOC character: %.*s' }) end) end) diff --git a/test/unit/viml/expressions/parser_spec.lua b/test/unit/viml/expressions/parser_spec.lua index 51a703b593..c7d3f8532f 100644 --- a/test/unit/viml/expressions/parser_spec.lua +++ b/test/unit/viml/expressions/parser_spec.lua @@ -14,8 +14,8 @@ local ffi = helpers.ffi local neq = helpers.neq local eq = helpers.eq local mergedicts_copy = helpers.mergedicts_copy -local format_string = helpers.format_string -local format_luav = helpers.format_luav +local format_string = require('test.format_string').format_string +local format_luav = require('test.format_string').format_luav local intchar2lua = helpers.intchar2lua local dictdiff = helpers.dictdiff @@ -25,100 +25,99 @@ local conv_cmp_type = viml_helpers.conv_cmp_type local pstate_set_str = viml_helpers.pstate_set_str local conv_expr_asgn_type = viml_helpers.conv_expr_asgn_type -local lib = cimport('./src/nvim/viml/parser/expressions.h', - './src/nvim/syntax.h') +local lib = cimport('./src/nvim/viml/parser/expressions.h', './src/nvim/syntax.h') local alloc_log = alloc_log_new() local predefined_hl_defs = { -- From highlight_init_both - Conceal=true, - Cursor=true, - lCursor=true, - DiffText=true, - ErrorMsg=true, - IncSearch=true, - ModeMsg=true, - NonText=true, - PmenuSbar=true, - StatusLine=true, - StatusLineNC=true, - TabLineFill=true, - TabLineSel=true, - TermCursor=true, - VertSplit=true, - WildMenu=true, - WinSeparator=true, - EndOfBuffer=true, - QuickFixLine=true, - Substitute=true, - Whitespace=true, - Error=true, - Todo=true, - String=true, - Character=true, - Number=true, - Boolean=true, - Float=true, - Function=true, - Conditional=true, - Repeat=true, - Label=true, - Operator=true, - Keyword=true, - Exception=true, - Include=true, - Define=true, - Macro=true, - PreCondit=true, - StorageClass=true, - Structure=true, - Typedef=true, - Tag=true, - SpecialChar=true, - Delimiter=true, - SpecialComment=true, - Debug=true, + Conceal = true, + Cursor = true, + lCursor = true, + DiffText = true, + ErrorMsg = true, + IncSearch = true, + ModeMsg = true, + NonText = true, + PmenuSbar = true, + StatusLine = true, + StatusLineNC = true, + TabLineFill = true, + TabLineSel = true, + TermCursor = true, + VertSplit = true, + WildMenu = true, + WinSeparator = true, + EndOfBuffer = true, + QuickFixLine = true, + Substitute = true, + Whitespace = true, + Error = true, + Todo = true, + String = true, + Character = true, + Number = true, + Boolean = true, + Float = true, + Function = true, + Conditional = true, + Repeat = true, + Label = true, + Operator = true, + Keyword = true, + Exception = true, + Include = true, + Define = true, + Macro = true, + PreCondit = true, + StorageClass = true, + Structure = true, + Typedef = true, + Tag = true, + SpecialChar = true, + Delimiter = true, + SpecialComment = true, + Debug = true, -- From highlight_init_(dark|light) - ColorColumn=true, - CursorColumn=true, - CursorLine=true, - CursorLineNr=true, - DiffAdd=true, - DiffChange=true, - DiffDelete=true, - Directory=true, - FoldColumn=true, - Folded=true, - LineNr=true, - MatchParen=true, - MoreMsg=true, - Pmenu=true, - PmenuSel=true, - PmenuThumb=true, - Question=true, - Search=true, - SignColumn=true, - SpecialKey=true, - SpellBad=true, - SpellCap=true, - SpellLocal=true, - SpellRare=true, - TabLine=true, - Title=true, - Visual=true, - WarningMsg=true, - Normal=true, - Comment=true, - Constant=true, - Special=true, - Identifier=true, - Statement=true, - PreProc=true, - Type=true, - Underlined=true, - Ignore=true, + ColorColumn = true, + CursorColumn = true, + CursorLine = true, + CursorLineNr = true, + DiffAdd = true, + DiffChange = true, + DiffDelete = true, + Directory = true, + FoldColumn = true, + Folded = true, + LineNr = true, + MatchParen = true, + MoreMsg = true, + Pmenu = true, + PmenuSel = true, + PmenuThumb = true, + Question = true, + Search = true, + SignColumn = true, + SpecialKey = true, + SpellBad = true, + SpellCap = true, + SpellLocal = true, + SpellRare = true, + TabLine = true, + Title = true, + Visual = true, + WarningMsg = true, + Normal = true, + Comment = true, + Constant = true, + Special = true, + Identifier = true, + Statement = true, + PreProc = true, + Type = true, + Underlined = true, + Ignore = true, } local nvim_hl_defs = {} @@ -136,22 +135,18 @@ child_call_once(function() -- linking, otherwise it will be created as cleared. So existence -- of the group is checked here and not in the next pass over -- nvim_hl_defs. - eq(true, not not (nvim_hl_defs[grp_link] - or predefined_hl_defs[grp_link])) - eq(false, not not (nvim_hl_defs[new_grp] - or predefined_hl_defs[new_grp])) - nvim_hl_defs[new_grp] = {'link', grp_link} + eq(true, not not (nvim_hl_defs[grp_link] or predefined_hl_defs[grp_link])) + eq(false, not not (nvim_hl_defs[new_grp] or predefined_hl_defs[new_grp])) + nvim_hl_defs[new_grp] = { 'link', grp_link } else local new_grp, grp_args = s:match('^(%w+) (.*)') neq(nil, new_grp) - eq(false, not not (nvim_hl_defs[new_grp] - or predefined_hl_defs[new_grp])) - nvim_hl_defs[new_grp] = {'definition', grp_args} + eq(false, not not (nvim_hl_defs[new_grp] or predefined_hl_defs[new_grp])) + nvim_hl_defs[new_grp] = { 'definition', grp_args } end end) if not err then - msg = format_string( - 'Error while processing string %s at position %u:\n%s', s, i, msg) + msg = format_string('Error while processing string %s at position %u:\n%s', s, i, msg) error(msg) end i = i + 1 @@ -185,12 +180,12 @@ local function hls_to_hl_fs(hls) local col_shift = col - next_col assert(col_shift >= 0) next_col = col + #str - ret[i] = format_string('hl(%r, %r%s)', - group, - str, - (col_shift == 0 - and '' - or (', %u'):format(col_shift))) + ret[i] = format_string( + 'hl(%r, %r%s)', + group, + str, + (col_shift == 0 and '' or (', %u'):format(col_shift)) + ) end return ret end @@ -205,9 +200,9 @@ local function format_check(expr, format_check_data, opts) dig_len = #opts.funcname + 2 else print(format_string('\n_check_parsing(%r, %r, {', opts, expr)) - dig_len = #('_check_parsing(, \'') + #(format_string('%r', opts)) + dig_len = #"_check_parsing(, '" + #(format_string('%r', opts)) end - local digits = ' --' .. (' '):rep(dig_len - #(' --')) + local digits = ' --' .. (' '):rep(dig_len - #' --') local digits2 = digits:sub(1, -10) for i = 0, #expr - 1 do if i % 10 == 0 then @@ -240,10 +235,9 @@ local function format_check(expr, format_check_data, opts) diffs[flags] = dictdiff(zdata, v) if diffs[flags] then if flags == 3 + zflags then - if (dictdiff(format_check_data[1 + zflags], - format_check_data[3 + zflags]) == nil - or dictdiff(format_check_data[2 + zflags], - format_check_data[3 + zflags]) == nil) + if + dictdiff(format_check_data[1 + zflags], format_check_data[3 + zflags]) == nil + or dictdiff(format_check_data[2 + zflags], format_check_data[3 + zflags]) == nil then diffs[flags] = nil else @@ -268,7 +262,7 @@ local function format_check(expr, format_check_data, opts) end if diff.hl_fs then print(' hl_fs = ' .. format_luav(diff.hl_fs, ' ', { - literal_strings=true + literal_strings = true, }) .. ',') end print(' },') @@ -280,47 +274,54 @@ local function format_check(expr, format_check_data, opts) end local east_node_type_tab -make_enum_conv_tab(lib, { - 'kExprNodeMissing', - 'kExprNodeOpMissing', - 'kExprNodeTernary', - 'kExprNodeTernaryValue', - 'kExprNodeRegister', - 'kExprNodeSubscript', - 'kExprNodeListLiteral', - 'kExprNodeUnaryPlus', - 'kExprNodeBinaryPlus', - 'kExprNodeNested', - 'kExprNodeCall', - 'kExprNodePlainIdentifier', - 'kExprNodePlainKey', - 'kExprNodeComplexIdentifier', - 'kExprNodeUnknownFigure', - 'kExprNodeLambda', - 'kExprNodeDictLiteral', - 'kExprNodeCurlyBracesIdentifier', - 'kExprNodeComma', - 'kExprNodeColon', - 'kExprNodeArrow', - 'kExprNodeComparison', - 'kExprNodeConcat', - 'kExprNodeConcatOrSubscript', - 'kExprNodeInteger', - 'kExprNodeFloat', - 'kExprNodeSingleQuotedString', - 'kExprNodeDoubleQuotedString', - 'kExprNodeOr', - 'kExprNodeAnd', - 'kExprNodeUnaryMinus', - 'kExprNodeBinaryMinus', - 'kExprNodeNot', - 'kExprNodeMultiplication', - 'kExprNodeDivision', - 'kExprNodeMod', - 'kExprNodeOption', - 'kExprNodeEnvironment', - 'kExprNodeAssignment', -}, 'kExprNode', function(ret) east_node_type_tab = ret end) +make_enum_conv_tab( + lib, + { + 'kExprNodeMissing', + 'kExprNodeOpMissing', + 'kExprNodeTernary', + 'kExprNodeTernaryValue', + 'kExprNodeRegister', + 'kExprNodeSubscript', + 'kExprNodeListLiteral', + 'kExprNodeUnaryPlus', + 'kExprNodeBinaryPlus', + 'kExprNodeNested', + 'kExprNodeCall', + 'kExprNodePlainIdentifier', + 'kExprNodePlainKey', + 'kExprNodeComplexIdentifier', + 'kExprNodeUnknownFigure', + 'kExprNodeLambda', + 'kExprNodeDictLiteral', + 'kExprNodeCurlyBracesIdentifier', + 'kExprNodeComma', + 'kExprNodeColon', + 'kExprNodeArrow', + 'kExprNodeComparison', + 'kExprNodeConcat', + 'kExprNodeConcatOrSubscript', + 'kExprNodeInteger', + 'kExprNodeFloat', + 'kExprNodeSingleQuotedString', + 'kExprNodeDoubleQuotedString', + 'kExprNodeOr', + 'kExprNodeAnd', + 'kExprNodeUnaryMinus', + 'kExprNodeBinaryMinus', + 'kExprNodeNot', + 'kExprNodeMultiplication', + 'kExprNodeDivision', + 'kExprNodeMod', + 'kExprNodeOption', + 'kExprNodeEnvironment', + 'kExprNodeAssignment', + }, + 'kExprNode', + function(ret) + east_node_type_tab = ret + end +) local function conv_east_node_type(typ) return conv_enum(east_node_type_tab, typ) @@ -346,25 +347,35 @@ local function eastnode2lua(pstate, eastnode, checked_nodes) ret_str = ('%u:%u:%s'):format(str.start.line, str.start.col, str.str) end if typ == 'Register' then - typ = typ .. ('(name=%s)'):format( - tostring(intchar2lua(eastnode.data.reg.name))) + typ = typ .. ('(name=%s)'):format(tostring(intchar2lua(eastnode.data.reg.name))) elseif typ == 'PlainIdentifier' then - typ = typ .. ('(scope=%s,ident=%s)'):format( - tostring(intchar2lua(eastnode.data.var.scope)), - ffi.string(eastnode.data.var.ident, eastnode.data.var.ident_len)) + typ = typ + .. ('(scope=%s,ident=%s)'):format( + tostring(intchar2lua(eastnode.data.var.scope)), + ffi.string(eastnode.data.var.ident, eastnode.data.var.ident_len) + ) elseif typ == 'PlainKey' then - typ = typ .. ('(key=%s)'):format( - ffi.string(eastnode.data.var.ident, eastnode.data.var.ident_len)) - elseif (typ == 'UnknownFigure' or typ == 'DictLiteral' - or typ == 'CurlyBracesIdentifier' or typ == 'Lambda') then - typ = typ .. ('(%s)'):format( - (eastnode.data.fig.type_guesses.allow_lambda and '\\' or '-') - .. (eastnode.data.fig.type_guesses.allow_dict and 'd' or '-') - .. (eastnode.data.fig.type_guesses.allow_ident and 'i' or '-')) + typ = typ + .. ('(key=%s)'):format(ffi.string(eastnode.data.var.ident, eastnode.data.var.ident_len)) + elseif + typ == 'UnknownFigure' + or typ == 'DictLiteral' + or typ == 'CurlyBracesIdentifier' + or typ == 'Lambda' + then + typ = typ + .. ('(%s)'):format( + (eastnode.data.fig.type_guesses.allow_lambda and '\\' or '-') + .. (eastnode.data.fig.type_guesses.allow_dict and 'd' or '-') + .. (eastnode.data.fig.type_guesses.allow_ident and 'i' or '-') + ) elseif typ == 'Comparison' then - typ = typ .. ('(type=%s,inv=%u,ccs=%s)'):format( - conv_cmp_type(eastnode.data.cmp.type), eastnode.data.cmp.inv and 1 or 0, - conv_ccs(eastnode.data.cmp.ccs)) + typ = typ + .. ('(type=%s,inv=%u,ccs=%s)'):format( + conv_cmp_type(eastnode.data.cmp.type), + eastnode.data.cmp.inv and 1 or 0, + conv_ccs(eastnode.data.cmp.ccs) + ) elseif typ == 'Integer' then typ = typ .. ('(val=%u)'):format(tonumber(eastnode.data.num.value)) elseif typ == 'Float' then @@ -380,11 +391,13 @@ local function eastnode2lua(pstate, eastnode, checked_nodes) typ = ('%s(scope=%s,ident=%s)'):format( typ, tostring(intchar2lua(eastnode.data.opt.scope)), - ffi.string(eastnode.data.opt.ident, eastnode.data.opt.ident_len)) + ffi.string(eastnode.data.opt.ident, eastnode.data.opt.ident_len) + ) elseif typ == 'Environment' then typ = ('%s(ident=%s)'):format( typ, - ffi.string(eastnode.data.env.ident, eastnode.data.env.ident_len)) + ffi.string(eastnode.data.env.ident, eastnode.data.env.ident_len) + ) elseif typ == 'Assignment' then typ = ('%s(%s)'):format(typ, conv_expr_asgn_type(eastnode.data.ass.type)) end @@ -433,22 +446,21 @@ local function phl2lua(pstate) local ret = {} for i = 0, (tonumber(pstate.colors.size) - 1) do local chunk = pstate.colors.items[i] - local chunk_tbl = pstate_set_str( - pstate, chunk.start, chunk.end_col - chunk.start.col, { - group = ffi.string(chunk.group), - }) + local chunk_tbl = pstate_set_str(pstate, chunk.start, chunk.end_col - chunk.start.col, { + group = ffi.string(chunk.group), + }) ret[i + 1] = ('%s:%u:%u:%s'):format( chunk_tbl.group, chunk_tbl.start.line, chunk_tbl.start.col, - chunk_tbl.str) + chunk_tbl.str + ) end return ret end describe('Expressions parser', function() - local function _check_parsing(opts, str, exp_ast, exp_highlighting_fs, - nz_flags_exps) + local function _check_parsing(opts, str, exp_ast, exp_highlighting_fs, nz_flags_exps) local zflags = opts.flags[1] nz_flags_exps = nz_flags_exps or {} local format_check_data = {} @@ -460,12 +472,12 @@ describe('Expressions parser', function() end alloc_log:check({}) - local pstate = new_pstate({str}) + local pstate = new_pstate({ str }) local east = lib.viml_pexpr_parse(pstate, flags) local ast = east2lua(str, pstate, east) local hls = phl2lua(pstate) if exp_ast == nil then - format_check_data[flags] = {ast=ast, hl_fs=hls_to_hl_fs(hls)} + format_check_data[flags] = { ast = ast, hl_fs = hls_to_hl_fs(hls) } else local exps = { ast = exp_ast, @@ -499,8 +511,7 @@ describe('Expressions parser', function() alloc_log:check({}) end) if not err then - msg = format_string('Error while processing test (%r, %u):\n%s', - str, flags, msg) + msg = format_string('Error while processing test (%r, %u):\n%s', str, flags, msg) error(msg) end end @@ -514,16 +525,11 @@ describe('Expressions parser', function() error(('Unknown group: Nvim%s'):format(group)) end local col = next_col + (shift or 0) - return (('%s:%u:%u:%s'):format( - 'Nvim' .. group, - 0, - col, - str)), (col + #str) + return (('%s:%u:%u:%s'):format('Nvim' .. group, 0, col, str)), (col + #str) end end local function fmtn(typ, args, rest) return ('%s(%s)%s'):format(typ, args, rest) end - require('test.unit.viml.expressions.parser_tests')( - itp, _check_parsing, hl, fmtn) + require('test.unit.viml.expressions.parser_tests')(itp, _check_parsing, hl, fmtn) end) diff --git a/test/unit/viml/expressions/parser_tests.lua b/test/unit/viml/expressions/parser_tests.lua index da61672bb1..aa2bf740de 100644 --- a/test/unit/viml/expressions/parser_tests.lua +++ b/test/unit/viml/expressions/parser_tests.lua @@ -1,15 +1,13 @@ -local global_helpers = require('test.helpers') - -local REMOVE_THIS = global_helpers.REMOVE_THIS +local REMOVE_THIS = vim.NIL return function(itp, _check_parsing, hl, fmtn) local function check_parsing(...) - return _check_parsing({flags={0, 1, 2, 3}, funcname='check_parsing'}, ...) + return _check_parsing({ flags = { 0, 1, 2, 3 }, funcname = 'check_parsing' }, ...) end local function check_asgn_parsing(...) return _check_parsing({ - flags={4, 5, 6, 7}, - funcname='check_asgn_parsing', + flags = { 4, 5, 6, 7 }, + funcname = 'check_asgn_parsing', }, ...) end itp('works with + and @a', function() @@ -142,7 +140,7 @@ return function(itp, _check_parsing, hl, fmtn) len = 2, err = REMOVE_THIS, ast = { - 'Register(name=a):0:0:@a' + 'Register(name=a):0:0:@a', }, }, hl_fs = { @@ -174,7 +172,7 @@ return function(itp, _check_parsing, hl, fmtn) len = 6, err = REMOVE_THIS, ast = { - 'Register(name=a):0:0: @a' + 'Register(name=a):0:0: @a', }, }, hl_fs = { @@ -541,7 +539,7 @@ return function(itp, _check_parsing, hl, fmtn) children = { { 'Nested:0:4:(', - children = { 'Register(name=b):0:5:@b' } + children = { 'Register(name=b):0:5:@b' }, }, }, }, @@ -579,7 +577,7 @@ return function(itp, _check_parsing, hl, fmtn) children = { { 'Nested:0:4:(', - children = { 'Register(name=b):0:5:@b' } + children = { 'Register(name=b):0:5:@b' }, }, }, }, @@ -600,13 +598,13 @@ return function(itp, _check_parsing, hl, fmtn) hl('BinaryPlus', '+'), hl('Register', '@c'), }) - check_parsing( - '@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', {--[[ + check_parsing('@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', {--[[ | | | | | | | | || | | || | | ||| || || || || 000000000011111111112222222222333333333344444444445555555 012345678901234567890123456789012345678901234567890123456 ]] - ast = {{ + ast = { + { 'BinaryPlus:0:31: +', children = { { @@ -696,45 +694,46 @@ return function(itp, _check_parsing, hl, fmtn) }, }, }, - }}, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Register', '@b'), - hl('BinaryPlus', '+', 1), - hl('Register', '@c', 1), - hl('NestingParenthesis', ')'), - hl('BinaryPlus', '+', 1), - hl('Register', '@d', 1), - hl('CallingParenthesis', '('), - hl('Register', '@e'), - hl('CallingParenthesis', ')'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('UnaryPlus', '+'), - hl('Register', '@f'), - hl('NestingParenthesis', ')'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('NestingParenthesis', '('), - hl('UnaryPlus', '+'), - hl('Register', '@g'), - hl('CallingParenthesis', '('), - hl('Register', '@h'), - hl('CallingParenthesis', ')'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@j'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@k'), - hl('CallingParenthesis', ')'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@l'), - hl('CallingParenthesis', ')'), - }) + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Register', '@b'), + hl('BinaryPlus', '+', 1), + hl('Register', '@c', 1), + hl('NestingParenthesis', ')'), + hl('BinaryPlus', '+', 1), + hl('Register', '@d', 1), + hl('CallingParenthesis', '('), + hl('Register', '@e'), + hl('CallingParenthesis', ')'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('UnaryPlus', '+'), + hl('Register', '@f'), + hl('NestingParenthesis', ')'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('NestingParenthesis', '('), + hl('UnaryPlus', '+'), + hl('Register', '@g'), + hl('CallingParenthesis', '('), + hl('Register', '@h'), + hl('CallingParenthesis', ')'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@j'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@k'), + hl('CallingParenthesis', ')'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@l'), + hl('CallingParenthesis', ')'), + }) check_parsing('@a)', { -- 012 ast = { @@ -1078,25 +1077,25 @@ return function(itp, _check_parsing, hl, fmtn) end) itp('works with variable names, including curly braces ones', function() check_parsing('var', { - ast = { - 'PlainIdentifier(scope=0,ident=var):0:0:var', - }, + ast = { + 'PlainIdentifier(scope=0,ident=var):0:0:var', + }, }, { hl('IdentifierName', 'var'), }) check_parsing('g:var', { - ast = { - 'PlainIdentifier(scope=g,ident=var):0:0:g:var', - }, + ast = { + 'PlainIdentifier(scope=g,ident=var):0:0:g:var', + }, }, { hl('IdentifierScope', 'g'), hl('IdentifierScopeDelimiter', ':'), hl('IdentifierName', 'var'), }) check_parsing('g:', { - ast = { - 'PlainIdentifier(scope=g,ident=):0:0:g:', - }, + ast = { + 'PlainIdentifier(scope=g,ident=):0:0:g:', + }, }, { hl('IdentifierScope', 'g'), hl('IdentifierScopeDelimiter', ':'), @@ -1141,7 +1140,7 @@ return function(itp, _check_parsing, hl, fmtn) children = { { 'OpMissing:0:3:', - children={ + children = { 'PlainIdentifier(scope=a,ident=):0:1:a:', 'Register(name=b):0:3:@b', }, @@ -1783,7 +1782,7 @@ return function(itp, _check_parsing, hl, fmtn) { 'Comma:0:3:,', children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', + 'PlainIdentifier(scope=0,ident=b):0:2:b', { 'Comma:0:5:,', children = { @@ -1819,7 +1818,7 @@ return function(itp, _check_parsing, hl, fmtn) { 'Comma:0:3:,', children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', + 'PlainIdentifier(scope=0,ident=b):0:2:b', { 'Comma:0:5:,', children = { @@ -2851,7 +2850,7 @@ return function(itp, _check_parsing, hl, fmtn) }, err = { arg = '{a : b', - msg = 'E723: Missing end of Dictionary \'}\': %.*s', + msg = "E723: Missing end of Dictionary '}': %.*s", }, }, { hl('Dict', '{'), @@ -3182,7 +3181,7 @@ return function(itp, _check_parsing, hl, fmtn) }, err = { arg = '?b', - msg = 'E109: Missing \':\' after \'?\': %.*s', + msg = "E109: Missing ':' after '?': %.*s", }, }, { hl('IdentifierName', 'a'), @@ -3207,7 +3206,7 @@ return function(itp, _check_parsing, hl, fmtn) }, err = { arg = '?b:', - msg = 'E109: Missing \':\' after \'?\': %.*s', + msg = "E109: Missing ':' after '?': %.*s", }, }, { hl('IdentifierName', 'a'), @@ -4840,7 +4839,7 @@ return function(itp, _check_parsing, hl, fmtn) }, err = { arg = '[1', - msg = 'E697: Missing end of List \']\': %.*s', + msg = "E697: Missing end of List ']': %.*s", }, }, { hl('List', '['), @@ -4848,15 +4847,15 @@ return function(itp, _check_parsing, hl, fmtn) }) end) itp('works with strings', function() - check_parsing('\'abc\'', { + check_parsing("'abc'", { -- 01234 ast = { - fmtn('SingleQuotedString', 'val="abc"', ':0:0:\'abc\''), + fmtn('SingleQuotedString', 'val="abc"', ":0:0:'abc'"), }, }, { - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), hl('SingleQuotedBody', 'abc'), - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), }) check_parsing('"abc"', { -- 01234 @@ -4868,14 +4867,14 @@ return function(itp, _check_parsing, hl, fmtn) hl('DoubleQuotedBody', 'abc'), hl('DoubleQuote', '"'), }) - check_parsing('\'\'', { + check_parsing("''", { -- 01 ast = { - fmtn('SingleQuotedString', 'val=NULL', ':0:0:\'\''), + fmtn('SingleQuotedString', 'val=NULL', ":0:0:''"), }, }, { - hl('SingleQuote', '\''), - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), + hl('SingleQuote', "'"), }) check_parsing('""', { -- 01 @@ -4898,17 +4897,17 @@ return function(itp, _check_parsing, hl, fmtn) }, { hl('InvalidDoubleQuote', '"'), }) - check_parsing('\'', { + check_parsing("'", { -- 0 ast = { - fmtn('SingleQuotedString', 'val=NULL', ':0:0:\''), + fmtn('SingleQuotedString', 'val=NULL', ":0:0:'"), }, err = { - arg = '\'', + arg = "'", msg = 'E115: Missing single quote: %.*s', }, }, { - hl('InvalidSingleQuote', '\''), + hl('InvalidSingleQuote', "'"), }) check_parsing('"a', { -- 01 @@ -4923,71 +4922,71 @@ return function(itp, _check_parsing, hl, fmtn) hl('InvalidDoubleQuote', '"'), hl('InvalidDoubleQuotedBody', 'a'), }) - check_parsing('\'a', { + check_parsing("'a", { -- 01 ast = { - fmtn('SingleQuotedString', 'val="a"', ':0:0:\'a'), + fmtn('SingleQuotedString', 'val="a"', ":0:0:'a"), }, err = { - arg = '\'a', + arg = "'a", msg = 'E115: Missing single quote: %.*s', }, }, { - hl('InvalidSingleQuote', '\''), + hl('InvalidSingleQuote', "'"), hl('InvalidSingleQuotedBody', 'a'), }) - check_parsing('\'abc\'\'def\'', { + check_parsing("'abc''def'", { -- 0123456789 ast = { - fmtn('SingleQuotedString', 'val="abc\'def"', ':0:0:\'abc\'\'def\''), + fmtn('SingleQuotedString', 'val="abc\'def"', ":0:0:'abc''def'"), }, }, { - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), hl('SingleQuotedBody', 'abc'), - hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedQuote', "''"), hl('SingleQuotedBody', 'def'), - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), }) - check_parsing('\'abc\'\'', { + check_parsing("'abc''", { -- 012345 ast = { - fmtn('SingleQuotedString', 'val="abc\'"', ':0:0:\'abc\'\''), + fmtn('SingleQuotedString', 'val="abc\'"', ":0:0:'abc''"), }, err = { - arg = '\'abc\'\'', + arg = "'abc''", msg = 'E115: Missing single quote: %.*s', }, }, { - hl('InvalidSingleQuote', '\''), + hl('InvalidSingleQuote', "'"), hl('InvalidSingleQuotedBody', 'abc'), - hl('InvalidSingleQuotedQuote', '\'\''), + hl('InvalidSingleQuotedQuote', "''"), }) - check_parsing('\'\'\'\'\'\'\'\'', { + check_parsing("''''''''", { -- 01234567 ast = { - fmtn('SingleQuotedString', 'val="\'\'\'"', ':0:0:\'\'\'\'\'\'\'\''), + fmtn('SingleQuotedString', "val=\"'''\"", ":0:0:''''''''"), }, }, { - hl('SingleQuote', '\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), + hl('SingleQuotedQuote', "''"), + hl('SingleQuotedQuote', "''"), + hl('SingleQuotedQuote', "''"), + hl('SingleQuote', "'"), }) - check_parsing('\'\'\'a\'\'\'\'bc\'', { + check_parsing("'''a''''bc'", { -- 01234567890 -- 0 1 ast = { - fmtn('SingleQuotedString', 'val="\'a\'\'bc"', ':0:0:\'\'\'a\'\'\'\'bc\''), + fmtn('SingleQuotedString', "val=\"'a''bc\"", ":0:0:'''a''''bc'"), }, }, { - hl('SingleQuote', '\''), - hl('SingleQuotedQuote', '\'\''), + hl('SingleQuote', "'"), + hl('SingleQuotedQuote', "''"), hl('SingleQuotedBody', 'a'), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedQuote', "''"), + hl('SingleQuotedQuote', "''"), hl('SingleQuotedBody', 'bc'), - hl('SingleQuote', '\''), + hl('SingleQuote', "'"), }) check_parsing('"\\"\\"\\"\\""', { -- 0123456789 @@ -5006,7 +5005,11 @@ return function(itp, _check_parsing, hl, fmtn) -- 0123456789012345678901234 -- 0 1 2 ast = { - fmtn('DoubleQuotedString', 'val="abc\\"def\\"ghi\\"jkl\\"mno"', ':0:0:"abc\\"def\\"ghi\\"jkl\\"mno"'), + fmtn( + 'DoubleQuotedString', + 'val="abc\\"def\\"ghi\\"jkl\\"mno"', + ':0:0:"abc\\"def\\"ghi\\"jkl\\"mno"' + ), }, }, { hl('DoubleQuote', '"'), @@ -6977,8 +6980,7 @@ return function(itp, _check_parsing, hl, fmtn) arg = '\0002&A:\000', msg = 'E15: Expected value, got EOC: %.*s', }, - }, { - }, { + }, {}, { [2] = { ast = { len = REMOVE_THIS, @@ -7025,7 +7027,7 @@ return function(itp, _check_parsing, hl, fmtn) }, }, }) - check_parsing({data='01', size=1}, { + check_parsing({ data = '01', size = 1 }, { len = 1, ast = { 'Integer(val=0):0:0:0', @@ -7033,7 +7035,7 @@ return function(itp, _check_parsing, hl, fmtn) }, { hl('Number', '0'), }) - check_parsing({data='001', size=2}, { + check_parsing({ data = '001', size = 2 }, { len = 2, ast = { 'Integer(val=0):0:0:00', @@ -7076,8 +7078,7 @@ return function(itp, _check_parsing, hl, fmtn) arg = '|"\\U\\', msg = 'E15: Expected value, got EOC: %.*s', }, - }, { - }, { + }, {}, { [2] = { ast = { len = REMOVE_THIS, @@ -7109,8 +7110,7 @@ return function(itp, _check_parsing, hl, fmtn) arg = '|"\\e"', msg = 'E15: Expected value, got EOC: %.*s', }, - }, { - }, { + }, {}, { [2] = { ast = { len = REMOVE_THIS, @@ -7142,8 +7142,7 @@ return function(itp, _check_parsing, hl, fmtn) arg = '|\029', msg = 'E15: Expected value, got EOC: %.*s', }, - }, { - }, { + }, {}, { [2] = { ast = { len = REMOVE_THIS, @@ -7373,7 +7372,7 @@ return function(itp, _check_parsing, hl, fmtn) hl_fs = { [2] = REMOVE_THIS, [3] = REMOVE_THIS, - } + }, }, }) |