* Add testing setup + CI
* Add tests for components and utils funtions

Co-authored-by: shadmansaleh <shadmansaleh3@gmail.com>
This commit is contained in:
Hubert Pelczarski 2021-05-05 20:04:16 +02:00 committed by GitHub
parent 141417de61
commit 8572db014a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 517 additions and 0 deletions

39
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Tests
on:
push:
branches-ignore: [master]
pull_request:
types: [opened, reopened]
jobs:
appimage-ubuntu:
name: ubuntu
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: date +%F > todays-date
- name: Restore cache for today's nightly.
uses: actions/cache@v2
with:
path: |
build
key: ${{ runner.os }}-appimage-${{ hashFiles('todays-date') }}
- name: Prepare
run: |
sudo apt install fd-find
test -d build || {
mkdir -p build
wget https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage
chmod +x nvim.appimage
mv nvim.appimage ./build/nvim
}
mkdir -p ~/.local/share/nvim/site/pack/vendor/start
git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim
git clone --depth 1 https://github.com/kyazdani42/nvim-web-devicons ~/.local/share/nvim/site/pack/vendor/start/nvim-web-devicons
ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start
- name: Run tests
run: |
export PATH="${PWD}/build/:${PATH}"
make test

22
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Linting
on:
push:
branches-ignore: [master]
pull_request:
types: [opened, reopened]
jobs:
build:
name: Luacheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install linter
run: |
sudo apt-get update
sudo apt-get install luarocks
sudo luarocks install luacheck
- name: Lint
run: make lint

13
Makefile Normal file
View File

@ -0,0 +1,13 @@
.DEFAULT_GOAL = check
lint:
@luacheck lua/lualine
@luacheck tests
format:
@for file in `find -name '*.lua'`;do lua-format $$file -i; done;
test:
@nvim --headless -u tests/minimal_init.lua -c "PlenaryBustedDirectory tests/ { minimal_init = './tests/minimal_init.lua' }"
check: lint test

35
tests/helpers.lua Normal file
View File

@ -0,0 +1,35 @@
local luassert = require 'luassert'
local M = {}
M.eq = luassert.are.same
M.neq = luassert.are_not.same
M.meths = setmetatable({}, {
__index = function(_, key) return vim.api['nvim_' .. key] end
})
-- Checks ouput of a component
M.assert_component = function(component, opts, result)
-- for testing global options
if component == nil then component = 'special.function_component' end
local comp = require('lualine.components.' .. component):new(opts)
M.eq(result, comp:draw(opts.hl))
end
-- sets defaults for component options
M.build_component_opts = function(opts)
if not opts then opts = {} end
if opts[1] == nil then opts[1] = function() return 'test' end end
if not opts.self then opts.self = {section = 'lualine_c'} end
if not opts.theme then opts.theme = 'gruvbox' end
if not opts.hl then opts.hl = '' end
if opts.icons_enabled == nil then opts.icons_enabled = true end
if not opts.component_separators then
opts.component_separators = {'', ''}
end
if not opts.section_separators then opts.section_separators = {'', ''} end
return opts
end
M.P = function(t) print(vim.inspect(t)) end
return M

5
tests/minimal_init.lua Normal file
View File

@ -0,0 +1,5 @@
-- load lualine and plenary
vim.api.nvim_exec([[
set rtp+=.
set rtp+=../plenary.nvim
]], false)

View File

@ -0,0 +1,288 @@
local helpers = require 'tests.helpers'
local eq = helpers.eq
local neq = helpers.neq
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('lua.lualine.components.special.function_component'):new(opts)
-- correct for lualine_c
eq('', comp.options.separator)
local opts2 = build_component_opts({self = {section = 'lualine_y'}})
local comp2 =
require('lua.lualine.components.special.function_component'):new(opts2)
-- correct for lualine_u
eq('', comp2.options.separator)
end)
it('can provide unique identifier', function()
local opts1 = build_component_opts()
local comp1 =
require('lua.lualine.components.special.function_component'):new(opts1)
local opts2 = build_component_opts()
local comp2 =
require('lua.lualine.components.special.function_component'):new(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('lua.lualine.components.special.function_component'):new(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)
hl.create_component_highlight_group:revert()
local opts2 = build_component_opts({color = 'MyHl'})
local comp2 =
require('lua.lualine.components.special.function_component'):new(opts2)
eq('MyHl', comp2.options.color_highlight_link)
end)
it('can draw', function()
local opts = build_component_opts({
component_separators = {'', ''},
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, 'test%#My_highlight#')
end)
describe('Global options:', function()
it('upper', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
upper = true
})
assert_component(nil, opts, 'TEST')
end)
it('lower', function()
local opts = build_component_opts({
function() return 'TeSt' end,
component_separators = {'', ''},
padding = 0,
lower = true
})
assert_component(nil, opts, 'test')
end)
it('left_padding', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
left_padding = 5
})
assert_component(nil, opts, ' test')
end)
it('right_padding', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
right_padding = 5
})
assert_component(nil, opts, 'test ')
end)
it('padding', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 5
})
assert_component(nil, opts, ' test ')
end)
it('icon', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
icon = '0'
})
assert_component(nil, opts, '0 test')
end)
it('icons_enabled', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
icons_enabled = true,
icon = '0'
})
assert_component(nil, opts, '0 test')
local opts2 = build_component_opts(
{
component_separators = {'', ''},
padding = 0,
icons_enabled = false,
icon = '0'
})
assert_component(nil, opts2, 'test')
end)
it('separator', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
separator = '|'
})
assert_component(nil, opts, 'test|')
end)
it('format', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
format = function(data)
return data:sub(1, 1):upper() .. data:sub(2, #data)
end
})
assert_component(nil, opts, 'Test')
end)
it('condition', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
condition = function() return true end
})
assert_component(nil, opts, 'test')
local opts2 = build_component_opts(
{
component_separators = {'', ''},
padding = 0,
condition = function() return false end
})
assert_component(nil, opts2, '')
end)
it('color', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0,
color = 'MyHl'
})
assert_component(nil, opts, '%#MyHl#test')
local opts2 = build_component_opts(
{
component_separators = {'', ''},
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('lua.lualine.components.special.function_component'):new(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 = {'', ''},
padding = 0
})
assert_component('encoding', opts, '%{strlen(&fenc)?&fenc:&enc}')
end)
end)
describe('Fileformat component', function()
it('works with icons', function()
local opts = build_component_opts({
component_separators = {'', ''},
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 = {'', ''},
padding = 0,
icons_enabled = false
})
assert_component('fileformat', opts, vim.bo.fileformat)
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 = {'', ''},
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 = {'', ''},
padding = 0
})
assert_component('location', opts, '%3l:%-2c')
end)
end)
describe('Progress component', function()
it('works', function()
local opts = build_component_opts({
component_separators = {'', ''},
padding = 0
})
assert_component('progress', opts, '%3P')
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 = {'', ''},
padding = 0
})
assert_component('mode', opts, 'NORMAL')
vim.api.nvim_get_mode:revert()
end)
end)

115
tests/spec/utils_spec.lua Normal file
View File

@ -0,0 +1,115 @@
local helpers = require 'tests.helpers'
local eq = helpers.eq
local meths = helpers.meths
local build_component_opts = helpers.build_component_opts
describe('Utils', function()
local utils = require('lualine.utils.utils')
it('can save and restore highlights', function()
local hl1 = {'hl1', '#122233', '#445566', 'italic', true}
utils.save_highlight(hl1[1], hl1)
-- highlight loaded in loaded_highlights table
eq(utils.loaded_highlights[hl1[1]], hl1)
-- highlight exists works properly
eq(utils.highlight_exists('hl1'), true)
eq(utils.highlight_exists('hl2'), false)
-- highlights can be restored
-- hl doesn't exist
assert.has_error(function() meths.get_hl_by_name('hl1', true) end,
'Invalid highlight name: hl1')
utils.reload_highlights()
-- Now hl1 is created
eq(meths.get_hl_by_name('hl1', true), {
foreground = tonumber(hl1[2]:sub(2, #hl1[2]), 16), -- convert rgb -> int
background = tonumber(hl1[3]:sub(2, #hl1[3]), 16), -- convert rgb -> int
italic = true
})
-- highlights can be cleared
utils.clear_highlights()
eq(utils.highlight_exists('hl1'), false)
-- highlight group has been cleared
eq(meths.get_hl_by_name('hl1', true), {[true] = 6})
end)
it('can retrive highlight groups', function()
local hl2 = {fg = '#aabbcc', bg = '#889977', reverse = true}
-- handles non existing hl groups
eq(utils.extract_highlight_colors('hl2'), nil)
-- create highlight
vim.cmd(
string.format('hi hl2 guifg=%s guibg=%s gui=reverse', hl2.fg, hl2.bg))
-- Can retrive entire highlight table
eq(utils.extract_highlight_colors('hl2'), hl2)
-- Can retrive specific parts of highlight
eq(utils.extract_highlight_colors('hl2', 'fg'), hl2.fg)
-- clear hl2
vim.cmd 'hi clear hl2'
end)
it('can shrink list with holes', function()
local list_with_holes = {
'2', '4', '6', nil, '43', nil, '2', '', 'a', '', 'b', ' '
}
local list_without_holes = {'2', '4', '6', '43', '2', 'a', 'b', ' '}
eq(utils.list_shrink(list_with_holes), list_without_holes)
end)
end)
describe('Cterm genarator', function()
local cterm = require 'lualine.utils.cterm_colors'
it('can convert rgb to cterm', function()
local colors = {['#112233'] = 235, ['#7928ae'] = 97, ['#017bdc'] = 68}
for rgb, ct in pairs(colors) do
eq(cterm.get_cterm_color(rgb), tostring(ct))
end
end)
end)
describe('Section genarator', function()
local sec = require 'lualine.utils.section'
it('can draw', function()
local opts = build_component_opts()
local section = {
require('lua.lualine.components.special.function_component'):new(opts),
require('lua.lualine.components.special.function_component'):new(opts)
}
eq('%#MyHl# test %#MyHl# test ', sec.draw_section(section, '%#MyHl#'))
end)
it('can remove separators from component with custom colors', function()
local opts = build_component_opts()
local opts_colored = build_component_opts({color = 'MyColor'})
local opts_colored2 = build_component_opts({color = {bg = '#223344'}})
local opts_colored3 = build_component_opts({color = {fg = '#223344'}})
require'lualine.highlight'.create_highlight_groups(
require 'lualine.themes.gruvbox')
local section = {
require('lua.lualine.components.special.function_component'):new(opts),
require('lua.lualine.components.special.function_component'):new(
opts_colored),
require('lua.lualine.components.special.function_component'):new(opts)
}
-- Removes separator on string color
eq('%#MyHl# test %#MyHl#%#MyColor# test %#MyHl# test ',
sec.draw_section(section, '%#MyHl#'))
section[2] =
require('lua.lualine.components.special.function_component'):new(
opts_colored2)
local highlight_name =
'%#lualine_c_' .. section[2].options.component_name .. '_normal#'
-- Removes separator on color with bg
eq('%#MyHl# test %#MyHl#' .. highlight_name .. ' test %#MyHl# test ',
sec.draw_section(section, '%#MyHl#'))
section[2] =
require('lua.lualine.components.special.function_component'):new(
opts_colored3)
local highlight_name2 =
'%#lualine_c_' .. section[2].options.component_name .. '_normal#'
-- Doesn't remove separator on color without bg
eq('%#MyHl# test %#MyHl#' .. highlight_name2 .. ' test %#MyHl# test ',
sec.draw_section(section, '%#MyHl#'))
end)
end)