lualine.nvim/tests/spec/component_spec.lua

810 lines
25 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Copyright (c) 2020-2021 shadmansaleh
-- MIT license, see LICENSE for more details.
local helpers = require('tests.helpers')
local eq = assert.are.same
local neq = assert.are_not.same
local assert_component = helpers.assert_component
local build_component_opts = helpers.build_component_opts
local stub = require('luassert.stub')
describe('Component:', function()
it('can select separators', function()
local opts = build_component_opts()
local comp = require('lualine.components.special.function_component')(opts)
-- correct for lualine_c
eq('', comp.options.separator)
local opts2 = build_component_opts { self = { section = 'y' } }
local comp2 = require('lualine.components.special.function_component')(opts2)
-- correct for lualine_u
eq('', comp2.options.separator)
end)
it('can provide unique identifier', function()
local opts1 = build_component_opts()
local comp1 = require('lualine.components.special.function_component')(opts1)
local opts2 = build_component_opts()
local comp2 = require('lualine.components.special.function_component')(opts2)
neq(comp1.component_no, comp2.component_no)
end)
it('create option highlights', function()
local color = { fg = '#224532', bg = '#892345' }
local opts1 = build_component_opts { color = color }
local hl = require('lualine.highlight')
stub(hl, 'create_component_highlight_group')
hl.create_component_highlight_group.returns('MyCompHl')
local comp1 = require('lualine.components.special.function_component')(opts1)
eq('MyCompHl', comp1.options.color_highlight)
-- color highlight wan't in options when create_comp_hl was
-- called so remove it before assert
comp1.options.color_highlight = nil
assert.stub(hl.create_component_highlight_group).was_called_with(
color,
comp1.options.component_name,
comp1.options,
false
)
hl.create_component_highlight_group:revert()
color = 'MyHl'
local opts2 = build_component_opts { color = color }
stub(hl, 'create_component_highlight_group')
hl.create_component_highlight_group.returns('MyCompLinkedHl')
local comp2 = require('lualine.components.special.function_component')(opts2)
eq('MyCompLinkedHl', comp2.options.color_highlight)
-- color highlight wan't in options when create_comp_hl was
-- called so remove it before assert
comp2.options.color_highlight = nil
assert.stub(hl.create_component_highlight_group).was_called_with(
color,
comp2.options.component_name,
comp2.options,
false
)
hl.create_component_highlight_group:revert()
end)
it('can draw', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
assert_component(nil, opts, 'test')
end)
it('can apply separators', function()
local opts = build_component_opts { padding = 0 }
assert_component(nil, opts, 'test')
end)
it('can apply default highlight', function()
local opts = build_component_opts { padding = 0, hl = '%#My_highlight#' }
assert_component(nil, opts, '%#My_highlight#test')
opts = build_component_opts {
function()
return '%#Custom_hl#test'
end,
padding = 0,
hl = '%#My_highlight#',
}
assert_component(nil, opts, '%#Custom_hl#test%#My_highlight#')
opts = build_component_opts {
function()
return 'in middle%#Custom_hl#test'
end,
padding = 0,
hl = '%#My_highlight#',
}
assert_component(nil, opts, '%#My_highlight#in middle%#Custom_hl#test%#My_highlight#')
end)
describe('Global options:', function()
it('left_padding', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = { left = 5 },
}
assert_component(nil, opts, ' test')
end)
it('right_padding', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = { right = 5 },
}
assert_component(nil, opts, 'test ')
end)
it('padding', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 5,
}
assert_component(nil, opts, ' test ')
end)
it('icon', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
icon = '0',
}
assert_component(nil, opts, '0 test')
end)
it('icons_enabled', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
icons_enabled = true,
icon = '0',
}
assert_component(nil, opts, '0 test')
local opts2 = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
icons_enabled = false,
icon = '0',
}
assert_component(nil, opts2, 'test')
end)
it('separator', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
separator = '|',
}
assert_component(nil, opts, 'test|')
end)
it('fmt', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
fmt = function(data)
return data:sub(1, 1):upper() .. data:sub(2, #data)
end,
}
assert_component(nil, opts, 'Test')
end)
it('cond', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
cond = function()
return true
end,
}
assert_component(nil, opts, 'test')
local opts2 = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
cond = function()
return false
end,
}
assert_component(nil, opts2, '')
end)
it('color', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
color = 'MyHl',
}
local comp = require('lualine.components.special.function_component')(opts)
local custom_link_hl_name = 'lualine_c_' .. comp.options.component_name
eq('%#' .. custom_link_hl_name .. '#test', comp:draw(opts.hl))
local opts2 = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
color = { bg = '#230055', fg = '#223344' },
}
local hl = require('lualine.highlight')
stub(hl, 'component_format_highlight')
hl.component_format_highlight.returns('%#MyCompHl#')
local comp2 = require('lualine.components.special.function_component')(opts2)
assert_component(nil, opts2, '%#MyCompHl#test')
assert.stub(hl.component_format_highlight).was_called_with(comp2.options.color_highlight)
hl.component_format_highlight:revert()
end)
end)
end)
describe('Encoding component', function()
it('works', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
local tmp_path = 'tmp.txt'
local tmp_fp = io.open(tmp_path, 'w')
tmp_fp:write('test file')
tmp_fp:close()
vim.cmd('e ' .. tmp_path)
assert_component('encoding', opts, 'utf-8')
vim.cmd('bd!')
os.remove(tmp_path)
end)
end)
describe('Fileformat component', function()
it('works with icons', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
local fmt = vim.bo.fileformat
vim.bo.fileformat = 'unix'
assert_component('fileformat', opts, '')
vim.bo.fileformat = 'dos'
assert_component('fileformat', opts, '')
vim.bo.fileformat = 'mac'
assert_component('fileformat', opts, '')
vim.bo.fileformat = fmt
end)
it('works without icons', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
icons_enabled = false,
}
assert_component('fileformat', opts, vim.bo.fileformat)
end)
end)
describe('Filetype component', function()
local filetype
before_each(function()
filetype = vim.bo.filetype
vim.bo.filetype = 'lua'
end)
after_each(function()
vim.bo.filetype = filetype
end)
it('does not add icon when library unavailable', function()
local old_require = _G.require
function _G.require(...)
if select(1, ...) == 'nvim-web-devicons' then
error('Test case not suppose to have web-dev-icon 👀')
end
return old_require(...)
end
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
assert_component('filetype', opts, 'lua')
_G.require = old_require
end)
it('colors nvim-web-devicons icons', function()
vim.g.actual_curwin = tostring(vim.api.nvim_get_current_win())
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:t').returns('test.lua')
local hl = require('lualine.highlight')
stub(hl, 'create_component_highlight_group')
hl.create_component_highlight_group.returns { name = 'MyCompHl', no_mode = false, section = 'a' }
stub(hl, 'format_highlight')
hl.format_highlight.returns('%#lualine_c_normal#')
local utils = require('lualine.utils.utils')
stub(utils, 'extract_highlight_colors')
utils.extract_highlight_colors.returns('#000')
local devicons = require('nvim-web-devicons')
stub(devicons, 'get_icon')
devicons.get_icon.on_call_with('test.lua').returns('*', 'test_highlight_group')
local opts = build_component_opts {
component_separators = { left = '', right = '' },
hl = '%#lualine_c_normal#',
padding = 0,
colored = true,
icon_only = false,
}
assert_component('filetype', opts, '%#MyCompHl_normal#*%#lualine_c_normal# lua%#lualine_c_normal#')
assert.stub(devicons.get_icon).was_called_with('test.lua')
assert.stub(utils.extract_highlight_colors).was_called_with('test_highlight_group', 'fg')
assert.stub(hl.create_component_highlight_group).was_called_with(
{ fg = '#000' },
'filetype_test_highlight_group',
opts,
false
)
assert.stub(vim.fn.expand).was_called_with('%:t')
devicons.get_icon:revert()
utils.extract_highlight_colors:revert()
hl.create_component_highlight_group:revert()
hl.format_highlight:revert()
vim.fn.expand:revert()
vim.g.actual_curwin = nil
end)
it("doesn't color when colored is false", function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:t').returns('test.lua')
local hl = require('lualine.highlight')
stub(hl, 'create_component_highlight_group')
local utils = require('lualine.utils.utils')
stub(utils, 'extract_highlight_colors')
local devicons = require('nvim-web-devicons')
stub(devicons, 'get_icon')
devicons.get_icon.on_call_with('test.lua').returns('*', 'test_highlight_group')
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
colored = false,
}
assert_component('filetype', opts, '* lua')
assert.stub(devicons.get_icon).was_called_with('test.lua')
assert.stub(utils.extract_highlight_colors).was_not_called()
assert.stub(hl.create_component_highlight_group).was_not_called()
assert.stub(vim.fn.expand).was_called_with('%:t')
devicons.get_icon:revert()
utils.extract_highlight_colors:revert()
hl.create_component_highlight_group:revert()
vim.fn.expand:revert()
end)
it('displays only icon when icon_only is true', function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:t').returns('test.lua')
local hl = require('lualine.highlight')
stub(hl, 'create_component_highlight_group')
local utils = require('lualine.utils.utils')
stub(utils, 'extract_highlight_colors')
local devicons = require('nvim-web-devicons')
stub(devicons, 'get_icon')
devicons.get_icon.on_call_with('test.lua').returns('*', 'test_highlight_group')
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
colored = false,
icon_only = true,
}
assert_component('filetype', opts, '*')
assert.stub(devicons.get_icon).was_called_with('test.lua')
assert.stub(utils.extract_highlight_colors).was_not_called()
assert.stub(hl.create_component_highlight_group).was_not_called()
assert.stub(vim.fn.expand).was_called_with('%:t')
devicons.get_icon:revert()
utils.extract_highlight_colors:revert()
hl.create_component_highlight_group:revert()
vim.fn.expand:revert()
end)
it('displays right aligned icon when icon.align is "right"', function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:t').returns('test.lua')
local hl = require('lualine.highlight')
stub(hl, 'create_component_highlight_group')
local utils = require('lualine.utils.utils')
stub(utils, 'extract_highlight_colors')
local devicons = require('nvim-web-devicons')
stub(devicons, 'get_icon')
devicons.get_icon.on_call_with('test.lua').returns('*', 'test_highlight_group')
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
colored = false,
icon_only = false,
icon = { align = 'right' }
}
assert_component('filetype', opts, 'lua *')
assert.stub(devicons.get_icon).was_called_with('test.lua')
assert.stub(utils.extract_highlight_colors).was_not_called()
assert.stub(hl.create_component_highlight_group).was_not_called()
assert.stub(vim.fn.expand).was_called_with('%:t')
devicons.get_icon:revert()
utils.extract_highlight_colors:revert()
hl.create_component_highlight_group:revert()
vim.fn.expand:revert()
end)
it('uses filetype lookup when file has no extension', function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:t').returns('test')
local hl = require('lualine.highlight')
stub(hl, 'create_component_highlight_group')
local utils = require('lualine.utils.utils')
stub(utils, 'extract_highlight_colors')
local devicons = require('nvim-web-devicons')
stub(devicons, 'get_icon')
devicons.get_icon.on_call_with('test').returns(nil)
stub(devicons, 'get_icon_by_filetype')
devicons.get_icon_by_filetype.on_call_with('lua').returns('*', 'test_highlight_group')
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
colored = false,
icon_only = false,
}
assert_component('filetype', opts, '* lua')
assert.stub(devicons.get_icon).was_called_with('test')
assert.stub(devicons.get_icon_by_filetype).was_called_with('lua')
assert.stub(utils.extract_highlight_colors).was_not_called()
assert.stub(hl.create_component_highlight_group).was_not_called()
assert.stub(vim.fn.expand).was_called_with('%:t')
devicons.get_icon_by_filetype:revert()
devicons.get_icon:revert()
utils.extract_highlight_colors:revert()
hl.create_component_highlight_group:revert()
vim.fn.expand:revert()
end)
end)
describe('Hostname component', function()
it('works', function()
stub(vim.loop, 'os_gethostname')
vim.loop.os_gethostname.returns('localhost')
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
assert_component('hostname', opts, 'localhost')
vim.loop.os_gethostname:revert()
end)
end)
describe('Location component', function()
it('works', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
assert_component('location', opts, ' 1:1 ')
vim.cmd('normal! 9o')
assert_component('location', opts, ' 10:1 ')
vim.api.nvim_win_set_cursor(0, {5, 0})
assert_component('location', opts, ' 5:1 ')
-- test column number
vim.cmd('normal! oTest')
assert_component('location', opts, ' 6:4 ')
-- test column number in line containing cyrillic symbols
vim.cmd('normal! oТест')
assert_component('location', opts, ' 7:4 ')
vim.cmd('bdelete!')
end)
end)
describe('Progress component', function()
it('works', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
assert_component('progress', opts, 'Top')
vim.cmd('normal! 9o')
assert_component('progress', opts, 'Bot')
vim.api.nvim_win_set_cursor(0, {5, 0})
assert_component('progress', opts, '50%%')
vim.cmd('bdelete!')
end)
end)
describe('Mode component', function()
it('works', function()
stub(vim.api, 'nvim_get_mode')
vim.api.nvim_get_mode.returns { mode = 'n', blocking = false }
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
assert_component('mode', opts, 'NORMAL')
vim.api.nvim_get_mode:revert()
end)
end)
describe('FileSize component', function()
it('works', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
local fname = 'test-file.txt'
local f = io.open(fname, 'w')
f:write(string.rep('........................................\n', 200))
f:close()
vim.cmd(':edit ' .. fname)
assert_component('filesize', opts, '8.0k')
vim.cmd(':bdelete!')
os.remove(fname)
end)
end)
describe('Filename component', function()
it('works', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = false,
path = 0,
}
vim.cmd(':e test-file.txt')
assert_component('filename', opts, 'test-file.txt')
vim.cmd(':bdelete!')
end)
it('can show file_status', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = true,
path = 0,
}
vim.cmd(':e test-file.txt')
vim.bo.modified = false
assert_component('filename', opts, 'test-file.txt')
vim.bo.modified = true
assert_component('filename', opts, 'test-file.txt [+]')
vim.bo.ro = true
assert_component('filename', opts, 'test-file.txt [+][-]')
vim.bo.modified = false
assert_component('filename', opts, 'test-file.txt [-]')
vim.cmd(':bdelete!')
end)
it('can show new_file_status', function ()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
newfile_status = true,
path = 0,
}
vim.cmd(':e new-file.txt')
assert_component('filename', opts, 'new-file.txt [New]')
vim.bo.modified = true
assert_component('filename', opts, 'new-file.txt [+][New]')
vim.cmd(':bdelete!')
end)
it('can show relative path', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = false,
path = 1,
}
vim.cmd(':e test-file.txt')
assert_component('filename', opts, vim.fn.expand('%:~:.'))
vim.cmd(':bdelete!')
end)
it('can show full path', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = false,
path = 2,
shorting_target = 0,
}
vim.cmd(':e test-file.txt')
assert_component('filename', opts, vim.fn.expand('%:p'))
vim.cmd(':bdelete!')
end)
it('shortens path', function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:p').returns('/home/foobar/test/test.lua')
stub(vim.fn, 'winwidth')
vim.fn.winwidth.on_call_with(0).returns(100)
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = false,
path = 2,
shorting_target = 90,
}
vim.cmd(':e test-file.txt')
assert_component('filename', opts, '/h/f/t/test.lua')
vim.cmd(':bdelete!')
vim.fn.winwidth:revert()
vim.fn.expand:revert()
end)
it('shortens path with tilde', function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:p:~').returns('~/test/test.lua')
stub(vim.fn, 'winwidth')
vim.fn.winwidth.on_call_with(0).returns(100)
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = false,
path = 3,
shorting_target = 90,
}
vim.cmd(':e test-file.txt')
assert_component('filename', opts, '~/t/test.lua')
vim.cmd(':bdelete!')
vim.fn.winwidth:revert()
vim.fn.expand:revert()
end)
it('shortens path with hidden directory', function()
stub(vim.fn, 'expand')
vim.fn.expand.on_call_with('%:p').returns('/home/foobar/.test/test.lua')
stub(vim.fn, 'winwidth')
vim.fn.winwidth.on_call_with(0).returns(100)
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
file_status = false,
path = 2,
shorting_target = 90,
}
vim.cmd(':e test-file.txt')
assert_component('filename', opts, '/h/f/.t/test.lua')
vim.cmd(':bdelete!')
vim.fn.winwidth:revert()
vim.fn.expand:revert()
end)
end)
describe('vim option & variable component', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
local function assert_vim_var_component(name, options, result)
options[1] = name
assert_component('special.vim_var_component', options, result)
opts[1] = nil
end
it('works with variable', function()
assert_vim_var_component('g:gvar', opts, '')
vim.g.gvar = 'var1'
assert_vim_var_component('g:gvar', opts, 'var1')
vim.g.gvar = 'var2'
assert_vim_var_component('g:gvar', opts, 'var2')
vim.b.gvar = 'bvar1'
assert_vim_var_component('b:gvar', opts, 'bvar1')
vim.w.gvar = 'wvar1'
assert_vim_var_component('w:gvar', opts, 'wvar1')
end)
it('can index dictionaries', function()
vim.g.gvar = { a = { b = 'var-value' } }
assert_vim_var_component('g:gvar.a.b', opts, 'var-value')
end)
it('works with options', function()
local old_number = vim.wo.number
vim.wo.number = false
assert_vim_var_component('wo:number', opts, 'false')
vim.wo.number = old_number
local old_tw = vim.go.tw
vim.go.tw = 80
assert_vim_var_component('go:tw', opts, '80')
vim.go.tw = old_tw
end)
end)
describe('Vim option & variable component', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
local function assert_vim_var_component(name, options, result)
options[1] = name
assert_component('special.eval_func_component', options, result)
opts[1] = nil
end
it('works with vim function', function()
vim.cmd([[
func! TestFunction() abort
return "TestVimFunction"
endf
]])
assert_vim_var_component('TestFunction', opts, 'TestVimFunction')
vim.cmd('delfunction TestFunction')
end)
it('works with lua expression', function()
_G.TestFunction = function()
return 'TestLuaFunction'
end
assert_vim_var_component('TestFunction()', opts, 'TestLuaFunction')
_G.TestFunction = nil
end)
end)
describe('Branch component', function()
-- these tests are broken in wsl will look at them later
if vim.fn.has('wsl') == 1 then
return
end
local tmpdir
local file
local git = function(...)
return vim.fn.system(
"git -c user.name='asdf' -c user.email='asdf@jlk.org' -C " .. tmpdir .. ' ' .. string.format(...)
)
end
local assert_comp_ins = helpers.assert_component_instance
before_each(function()
tmpdir = os.tmpname()
os.remove(tmpdir)
file = tmpdir .. '/test.txt'
vim.fn.mkdir(tmpdir, 'p')
git('init -b test_branch')
vim.cmd([[aug lualine
au!
aug END
]])
end)
after_each(function()
os.remove(tmpdir)
end)
it('works with regular branches', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
padding = 0,
}
local branch_comp = helpers.init_component('branch', opts)
vim.cmd('e ' .. file)
assert_comp_ins(branch_comp, ' test_branch')
git('checkout -b test_branch2')
vim.cmd('e k')
vim.cmd('bd')
vim.cmd('e ' .. file)
opts.icons_enabled = false
assert_comp_ins(branch_comp, 'test_branch2')
end)
it('works in detached head mode', function()
local opts = build_component_opts {
component_separators = { left = '', right = '' },
icons_enabled = false,
padding = 0,
}
git('checkout -b test_branch2')
git('commit --allow-empty -m "test commit1"')
git('commit --allow-empty -m "test commit2"')
git('commit --allow-empty -m "test commit3"')
git('checkout HEAD~1')
vim.cmd('e ' .. file)
local rev = git('rev-parse --short=6 HEAD'):sub(1, 6)
assert_component('branch', opts, rev)
end)
end)