aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/core/job_spec.lua20
-rw-r--r--test/functional/normal/macro_spec.lua30
-rw-r--r--test/functional/options/defaults_spec.lua45
-rw-r--r--test/functional/options/keymap_spec.lua233
-rw-r--r--test/functional/provider/nodejs_spec.lua12
-rw-r--r--test/functional/ui/inccommand_spec.lua15
-rw-r--r--test/functional/viml/completion_spec.lua145
7 files changed, 393 insertions, 107 deletions
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index e90339b0cd..4a21444ee0 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -433,9 +433,25 @@ describe('jobs', function()
let cmd = ['sh', '-c', 'for i in $(seq 1 5); do echo $i; sleep 0.1; done']
endif
call jobwait([jobstart(cmd, d)])
- call rpcnotify(g:channel, 'data', d.data)
]])
- eq({'notification', 'data', {{{'1', ''}, {'2', ''}, {'3', ''}, {'4', ''}, {'5', ''}, {''}}}}, next_msg())
+
+ local expected = {'1', '2', '3', '4', '5', ''}
+ local chunks = eval('d.data')
+ local received = {''}
+ for i, chunk in ipairs(chunks) do
+ if i < #chunks then
+ -- if chunks got joined, a spurious [''] callback was not sent
+ neq({''}, chunk)
+ else
+ -- but EOF callback is still sent
+ eq({''}, chunk)
+ end
+ received[#received] = received[#received]..chunk[1]
+ for j = 2, #chunk do
+ received[#received+1] = chunk[j]
+ end
+ end
+ eq(expected, received)
end)
it('jobstart() works with partial functions', function()
diff --git a/test/functional/normal/macro_spec.lua b/test/functional/normal/macro_spec.lua
new file mode 100644
index 0000000000..102d8fc723
--- /dev/null
+++ b/test/functional/normal/macro_spec.lua
@@ -0,0 +1,30 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local eq = helpers.eq
+local eval = helpers.eval
+local feed = helpers.feed
+local clear = helpers.clear
+local expect = helpers.expect
+local command = helpers.command
+
+describe('macros', function()
+ before_each(clear)
+ it('can be recorded and replayed', function()
+ feed('qiahello<esc>q')
+ expect('hello')
+ eq(eval('@i'), 'ahello')
+ feed('@i')
+ expect('hellohello')
+ eq(eval('@i'), 'ahello')
+ end)
+ it('applies maps', function()
+ command('imap x l')
+ command('nmap l a')
+ feed('qilxxx<esc>q')
+ expect('lll')
+ eq(eval('@i'), 'lxxx')
+ feed('@i')
+ expect('llllll')
+ eq(eval('@i'), 'lxxx')
+ end)
+end)
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index f452cafd22..787ec366b8 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -10,6 +10,7 @@ local eval = helpers.eval
local eq = helpers.eq
local funcs = helpers.funcs
local insert = helpers.insert
+local iswin = helpers.iswin
local neq = helpers.neq
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
@@ -170,8 +171,7 @@ describe('startup defaults', function()
end)
describe('$NVIM_LOG_FILE', function()
- -- TODO(jkeyes): use stdpath('data') instead.
- local datasubdir = helpers.iswin() and 'nvim-data' or 'nvim'
+ local datasubdir = iswin() and 'nvim-data' or 'nvim'
local xdgdir = 'Xtest-startup-xdg-logpath'
local xdgdatadir = xdgdir..'/'..datasubdir
after_each(function()
@@ -428,7 +428,24 @@ end)
describe('stdpath()', function()
+ -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions
+ -- due to XDG_CONFIG_HOME and XDG_DATA_HOME being the same.
+ local datadir = iswin() and 'nvim-data' or 'nvim'
+
+ it('acceptance', function()
+ clear() -- Do not explicitly set any env vars.
+
+ eq('nvim', funcs.fnamemodify(funcs.stdpath('cache'), ':t'))
+ eq('nvim', funcs.fnamemodify(funcs.stdpath('config'), ':t'))
+ eq(datadir, funcs.fnamemodify(funcs.stdpath('data'), ':t'))
+ eq('table', type(funcs.stdpath('config_dirs')))
+ eq('table', type(funcs.stdpath('data_dirs')))
+ -- Check for crash. #8393
+ eq(2, eval('1+1'))
+ end)
+
context('returns a String', function()
+
describe('with "config"' , function ()
it('knows XDG_CONFIG_HOME', function()
clear({env={
@@ -463,32 +480,20 @@ describe('stdpath()', function()
end)
describe('with "data"' , function ()
- local appended_dir
- setup(function()
- -- Windows appends 'nvim-data' instead of just 'nvim' to
- -- prevent collisions due to XDG_CONFIG_HOME and XDG_DATA_HOME
- -- being the same.
- if helpers.iswin() then
- appended_dir = '/nvim-data'
- else
- appended_dir = '/nvim'
- end
- end)
-
it('knows XDG_DATA_HOME', function()
clear({env={
XDG_DATA_HOME=alter_slashes('/home/docwhat/.local'),
}})
- eq(alter_slashes('/home/docwhat/.local' .. appended_dir), funcs.stdpath('data'))
+ eq(alter_slashes('/home/docwhat/.local/'..datadir), funcs.stdpath('data'))
end)
it('handles changes during runtime', function()
clear({env={
XDG_DATA_HOME=alter_slashes('/home/original'),
}})
- eq(alter_slashes('/home/original' .. appended_dir), funcs.stdpath('data'))
+ eq(alter_slashes('/home/original/'..datadir), funcs.stdpath('data'))
command("let $XDG_DATA_HOME='"..alter_slashes('/home/new').."'")
- eq(alter_slashes('/home/new' .. appended_dir), funcs.stdpath('data'))
+ eq(alter_slashes('/home/new/'..datadir), funcs.stdpath('data'))
end)
it("doesn't expand $VARIABLES", function()
@@ -496,14 +501,14 @@ describe('stdpath()', function()
XDG_DATA_HOME='$VARIABLES',
VARIABLES='this-should-not-happen',
}})
- eq(alter_slashes('$VARIABLES' .. appended_dir), funcs.stdpath('data'))
+ eq(alter_slashes('$VARIABLES/'..datadir), funcs.stdpath('data'))
end)
it("doesn't expand ~/", function()
clear({env={
XDG_DATA_HOME=alter_slashes('~/frobnitz'),
}})
- eq(alter_slashes('~/frobnitz' .. appended_dir), funcs.stdpath('data'))
+ eq(alter_slashes('~/frobnitz/'..datadir), funcs.stdpath('data'))
end)
end)
@@ -544,7 +549,7 @@ describe('stdpath()', function()
context('returns a List', function()
-- Some OS specific variables the system would have set.
local function base_env()
- if helpers.iswin() then
+ if iswin() then
return {
HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH
HOMEDRIVE='C:',
diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua
new file mode 100644
index 0000000000..7f6d623dc7
--- /dev/null
+++ b/test/functional/options/keymap_spec.lua
@@ -0,0 +1,233 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq
+local expect, command, eval = helpers.expect, helpers.command, helpers.eval
+local insert, call = helpers.insert, helpers.call
+local funcs, dedent = helpers.funcs, helpers.dedent
+
+-- First test it's implemented using the :lmap and :lnoremap commands, then
+-- check those mappings behave as expected.
+describe("'keymap' / :lmap", function()
+ clear()
+ before_each(function()
+ clear()
+ insert("lllaaa")
+ command('set iminsert=1')
+ command('set imsearch=1')
+ command('lmap l a')
+ feed('gg0')
+ end)
+
+ describe("'keymap' as :lmap", function()
+ -- Shows that 'keymap' sets language mappings that allows remapping.
+ -- This equivalence allows us to only test :lmap commands and assert they
+ -- behave the same as 'keymap' settings.
+ -- It does rely on the absence of special code that implements 'keymap'
+ -- and :lmap differently but shows mappings from the 'keymap' after
+ -- typing :lmap.
+ -- At the moment this is the case.
+ it("'keymap' mappings are shown with :lmap", function()
+ command('lmapclear')
+ command('lmapclear <buffer>')
+ command('set keymap=dvorak')
+ command('set nomore')
+ local bindings = funcs.nvim_command_output('lmap')
+ eq(dedent([[
+
+ l " @_
+ l ' @-
+ l + @}
+ l , @w
+ l - @[
+ l . @v
+ l / @z
+ l : @S
+ l ; @s
+ l < @W
+ l = @]
+ l > @V
+ l ? @Z
+ l A @A
+ l B @X
+ l C @J
+ l D @E
+ l E @>
+ l F @U
+ l G @I
+ l H @D
+ l I @C
+ l J @H
+ l K @T
+ l L @N
+ l M @M
+ l N @B
+ l O @R
+ l P @L
+ l Q @"
+ l R @P
+ l S @O
+ l T @Y
+ l U @G
+ l V @K
+ l W @<
+ l X @Q
+ l Y @F
+ l Z @:
+ l [ @/
+ l \ @\
+ l ] @=
+ l _ @{
+ l a @a
+ l b @x
+ l c @j
+ l d @e
+ l e @.
+ l f @u
+ l g @i
+ l h @d
+ l i @c
+ l j @h
+ l k @t
+ l l @n
+ l m @m
+ l n @b
+ l o @r
+ l p @l
+ l q @'
+ l r @p
+ l s @o
+ l t @y
+ l u @g
+ l v @k
+ l w @,
+ l x @q
+ l y @f
+ l z @;
+ l { @?
+ l | @|
+ l } @+]]), bindings)
+ end)
+ end)
+ describe("'iminsert' option", function()
+ it("Uses :lmap in insert mode when ON", function()
+ feed('il<esc>')
+ expect('alllaaa')
+ end)
+ it("Ignores :lmap in insert mode when OFF", function()
+ command('set iminsert=0')
+ feed('il<esc>')
+ expect('llllaaa')
+ end)
+ it("Can be toggled with <C-^> in insert mode", function()
+ feed('i<C-^>l<C-^>l<esc>')
+ expect('lalllaaa')
+ eq(eval('&iminsert'), 1)
+ feed('i<C-^><esc>')
+ eq(eval('&iminsert'), 0)
+ end)
+ end)
+ describe("'imsearch' option", function()
+ it("Uses :lmap at search prompt when ON", function()
+ feed('/lll<cr>3x')
+ expect('lll')
+ end)
+ it("Ignores :lmap at search prompt when OFF", function()
+ command('set imsearch=0')
+ feed('gg/lll<cr>3x')
+ expect('aaa')
+ end)
+ it("Can be toggled with C-^", function()
+ eq(eval('&imsearch'), 1)
+ feed('/<C-^>lll<cr>3x')
+ expect('aaa')
+ eq(eval('&imsearch'), 0)
+ feed('u0/<C-^>lll<cr>3x')
+ expect('lll')
+ eq(eval('&imsearch'), 1)
+ end)
+ it("can follow 'iminsert'", function()
+ command('set imsearch=-1')
+ feed('/lll<cr>3x')
+ expect('lll')
+ eq(eval('&imsearch'), -1)
+ eq(eval('&iminsert'), 1)
+ feed('u/<C-^>lll<cr>3x')
+ expect('aaa')
+ eq(eval('&imsearch'), -1)
+ eq(eval('&iminsert'), 0)
+ end)
+ end)
+ it(":lmap not applied to macros", function()
+ command("call setreg('a', 'il')")
+ feed('@a')
+ expect('llllaaa')
+ eq(call('getreg', 'a'), 'il')
+ end)
+ it(":lmap applied to macro recording", function()
+ feed('qail<esc>q@a')
+ expect('aalllaaa')
+ eq(call('getreg', 'a'), 'ia')
+ end)
+ it(":lmap not applied to mappings", function()
+ command('imap t l')
+ feed('it<esc>')
+ expect('llllaaa')
+ end)
+ it("mappings applied to keys created with :lmap", function()
+ command('imap a x')
+ feed('il<esc>')
+ expect('xlllaaa')
+ end)
+ it("mappings not applied to keys gotten with :lnoremap", function()
+ command('lmapclear')
+ command('lnoremap l a')
+ command('imap a x')
+ feed('il<esc>')
+ expect('alllaaa')
+ end)
+ -- This is a problem introduced when introducting :lmap and macro
+ -- compatibility. There are no plans to fix this as the complexity involved
+ -- seems too great.
+ pending('mappings not applied to macro replay of :lnoremap', function()
+ command('lmapclear')
+ command('lnoremap l a')
+ command('imap a x')
+ feed('qail<esc>q')
+ expect('alllaaa')
+ feed('@a')
+ expect('aalllaaa')
+ end)
+ it("is applied when using f/F t/T", function()
+ feed('flx')
+ expect('lllaa')
+ feed('0ia<esc>4lFlx')
+ expect('lllaa')
+ feed('tllx')
+ expect('llla')
+ feed('0ia<esc>4lTlhx')
+ expect('llla')
+ end)
+ it('takes priority over :imap mappings', function()
+ command('imap l x')
+ feed('il<esc>')
+ expect('alllaaa')
+ command('lmapclear')
+ command('lmap l a')
+ feed('il')
+ expect('aalllaaa')
+ end)
+ it('does not cause recursive mappings', function()
+ command('lmap a l')
+ feed('qaila<esc>q')
+ expect('allllaaa')
+ feed('u@a')
+ expect('allllaaa')
+ end)
+ it('can handle multicharacter mappings', function()
+ command("lmap 'a x")
+ command("lmap '' '")
+ feed("qai'a''a<esc>q")
+ expect("x'alllaaa")
+ feed('u@a')
+ expect("x'alllaaa")
+ end)
+end)
diff --git a/test/functional/provider/nodejs_spec.lua b/test/functional/provider/nodejs_spec.lua
index d9af020bfe..f69c3e7c78 100644
--- a/test/functional/provider/nodejs_spec.lua
+++ b/test/functional/provider/nodejs_spec.lua
@@ -45,15 +45,13 @@ describe('nodejs host', function()
const nvim = neovim.attach({socket: socket});
class TestPlugin {
- hello() {
- this.nvim.command('let g:job_out = "hello-plugin"')
- }
+ hello() {
+ this.nvim.command('let g:job_out = "hello-plugin"');
+ }
}
-
const PluginClass = neovim.Plugin(TestPlugin);
- const plugin = new PluginClass(nvim);
- plugin.hello();
- nvim.command('call jobstop(g:job_id)');
+ const plugin = new neovim.NvimPlugin(null, PluginClass, nvim);
+ plugin.instance.hello();
]])
command('let g:job_id = jobstart(["node", "'..fname..'"])')
retry(nil, 2000, function() eq('hello-plugin', eval('g:job_out')) end)
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index ee1a3240a2..9cc697a4b6 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -1846,8 +1846,7 @@ describe("'inccommand' with 'gdefault'", function()
end)
describe(":substitute", function()
- local screen = Screen.new(30,15)
-
+ local screen = Screen.new(30,15)
before_each(function()
clear()
end)
@@ -2471,8 +2470,13 @@ describe(":substitute", function()
:%s/some\(thing\)\@!/every/^ |
]])
end)
+end)
+
+it(':substitute with inccommand during :terminal activity', function()
+ retry(2, nil, function()
+ local screen = Screen.new(30,15)
+ clear()
- it('with inccommand during :terminal activity', function()
command("set cmdwinheight=3")
if iswin() then
feed([[:terminal for /L \%I in (1,1,5000) do @(echo xxx & echo xxx & echo xxx)<cr>]])
@@ -2484,7 +2488,7 @@ describe(":substitute", function()
common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz')
command('wincmd =')
- -- Allow some terminal output.
+ -- Wait for terminal output.
screen:expect([[
bar baz fox |
bar foo ba^z |
@@ -2505,7 +2509,7 @@ describe(":substitute", function()
feed('gg')
feed(':%s/foo/ZZZ')
- sleep(50) -- Allow some terminal activity.
+ sleep(20) -- Allow some terminal activity.
screen:expect([[
{12:ZZZ} bar baz |
bar baz fox |
@@ -2523,5 +2527,6 @@ describe(":substitute", function()
{10:[Preview] }|
:%s/foo/ZZZ^ |
]])
+
end)
end)
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 93d3909568..c14f7fc1a6 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -975,90 +975,89 @@ describe('ui/ext_popupmenu', function()
end)
end)
- describe('TextChangeP autocommand', function()
- it('can trigger TextChangedP autocommand as expected',
- function()
- curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar'})
- command('set complete=. completeopt=menuone')
- command('let g:foo = []')
- command('autocmd! TextChanged * :call add(g:foo, "N")')
- command('autocmd! TextChangedI * :call add(g:foo, "I")')
- command('autocmd! TextChangedP * :call add(g:foo, "P")')
- command('call cursor(3, 1)')
+ it('TextChangedP autocommand', function()
+ curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar'})
+ source([[
+ set complete=. completeopt=menuone
+ let g:foo = []
+ autocmd! TextChanged * :call add(g:foo, "N")
+ autocmd! TextChangedI * :call add(g:foo, "I")
+ autocmd! TextChangedP * :call add(g:foo, "P")
+ call cursor(3, 1)
+ ]])
- command('let g:foo = []')
- feed('o')
- wait()
- feed('<esc>')
- assert.same({'I'}, eval('g:foo'))
+ command('let g:foo = []')
+ feed('o')
+ wait()
+ feed('<esc>')
+ eq({'I'}, eval('g:foo'))
- command('let g:foo = []')
- feed('S')
- wait()
- feed('f')
- wait()
- assert.same({'I', 'I'}, eval('g:foo'))
- feed('<esc>')
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ eq({'I', 'I'}, eval('g:foo'))
+ feed('<esc>')
- command('let g:foo = []')
- feed('S')
- wait()
- feed('f')
- wait()
- feed('<C-n>')
- wait()
- assert.same({'I', 'I', 'P'}, eval('g:foo'))
- feed('<esc>')
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ eq({'I', 'I', 'P'}, eval('g:foo'))
+ feed('<esc>')
- command('let g:foo = []')
- feed('S')
- wait()
- feed('f')
- wait()
- feed('<C-n>')
- wait()
- feed('<C-n>')
- wait()
- assert.same({'I', 'I', 'P', 'P'}, eval('g:foo'))
- feed('<esc>')
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ eq({'I', 'I', 'P', 'P'}, eval('g:foo'))
+ feed('<esc>')
- command('let g:foo = []')
- feed('S')
- wait()
- feed('f')
- wait()
- feed('<C-n>')
- wait()
- feed('<C-n>')
- wait()
- feed('<C-n>')
- wait()
- assert.same({'I', 'I', 'P', 'P', 'P'}, eval('g:foo'))
- feed('<esc>')
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ eq({'I', 'I', 'P', 'P', 'P'}, eval('g:foo'))
+ feed('<esc>')
- command('let g:foo = []')
- feed('S')
- wait()
- feed('f')
- wait()
- feed('<C-n>')
- wait()
- feed('<C-n>')
- wait()
- feed('<C-n>')
- wait()
- feed('<C-n>')
- assert.same({'I', 'I', 'P', 'P', 'P', 'P'}, eval('g:foo'))
- feed('<esc>')
+ command('let g:foo = []')
+ feed('S')
+ wait()
+ feed('f')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ wait()
+ feed('<C-N>')
+ eq({'I', 'I', 'P', 'P', 'P', 'P'}, eval('g:foo'))
+ feed('<esc>')
- assert.same({'foo', 'bar', 'foobar', 'foo'}, eval('getline(1, "$")'))
+ eq({'foo', 'bar', 'foobar', 'foo'}, eval('getline(1, "$")'))
- source([[
+ source([[
au! TextChanged
au! TextChangedI
au! TextChangedP
set complete&vim completeopt&vim
- ]])
- end)
+ ]])
end)
end)