diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8be511e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: Tests + +on: [push] + +jobs: + unit_tests: + name: unit tests + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04] + rev: [stable] + include: + - os: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + + - uses: rhysd/action-setup-vim@v1 + with: + neovim: true + version: ${{ matrix.rev }} + + - name: Prepare + run: | + make prepare + + - name: Run tests + run: | + nvim --version + make test + diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e79bebf..2f4a4df 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,4 +27,4 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} version: latest - args: --color always --check lua/ + args: --color always --check lua/ test/ diff --git a/Makefile b/Makefile index a1d9c63..4d5f28a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,10 @@ -.PHONY: lint +.PHONY: prepare test lint + +prepare: + git clone --depth 1 https://github.com/nvim-lua/plenary.nvim .ci/vendor/pack/vendor/start/plenary.nvim + +test: + nvim --headless --clean -u scripts/minimal_init.lua -c "PlenaryBustedDirectory test/ { minimal_init = 'scripts/minimal_init.lua', sequential = true }" lint: luacheck lua/toggle diff --git a/lua/toggle/mapping.lua b/lua/toggle/mapping.lua index 075a3ed..5a4f842 100644 --- a/lua/toggle/mapping.lua +++ b/lua/toggle/mapping.lua @@ -11,7 +11,7 @@ M.__get_mapping = function(word) end M.__register = function(list) - for i, value in ipairs(list) do + for i, value in ipairs(list or {}) do if i == #list then mapping[value] = list[1] else diff --git a/scripts/minimal_init.lua b/scripts/minimal_init.lua new file mode 100644 index 0000000..44425da --- /dev/null +++ b/scripts/minimal_init.lua @@ -0,0 +1,9 @@ +vim.opt.runtimepath:append('.') + +local cwd = vim.fn.getcwd() +vim.cmd(string.format([[set packpath=%s/.ci/vendor]], cwd)) +vim.cmd([[packloadall]]) + +vim.o.swapfile = false +vim.bo.swapfile = false + diff --git a/test/defaults_spec.lua b/test/defaults_spec.lua new file mode 100644 index 0000000..330b892 --- /dev/null +++ b/test/defaults_spec.lua @@ -0,0 +1,16 @@ +local defaults = require('toggle.defaults') + +describe('defaults', function() + it('no duplicates in mappings', function() + local seen = {} + for _, mapping in ipairs(defaults) do + for _, word in ipairs(mapping) do + if seen[word] then + assert(false) + else + seen[word] = true + end + end + end + end) +end) diff --git a/test/mapping_spec.lua b/test/mapping_spec.lua new file mode 100644 index 0000000..7f40fdf --- /dev/null +++ b/test/mapping_spec.lua @@ -0,0 +1,57 @@ +local mapping = require('toggle.mapping') + +describe('mapping', function() + it('__reset clears mapping', function() + mapping.__register({ 'foo', 'bar' }) + mapping.__reset() + assert(mapping.__has_mapping('foo') == false) + assert(mapping.__has_mapping('bar') == false) + end) + + it('__get_mapping - existing mapping', function() + mapping.__reset() + mapping.__register({ 'foo', 'bar' }) + assert(mapping.__get_mapping('foo') == 'bar') + assert(mapping.__get_mapping('bar') == 'foo') + end) + + it('__get_mapping - chain of mappings', function() + mapping.__reset() + mapping.__register({ 'foo', 'bar', 'zoo' }) + assert(mapping.__get_mapping('foo') == 'bar') + assert(mapping.__get_mapping('bar') == 'zoo') + assert(mapping.__get_mapping('zoo') == 'foo') + end) + + it('__get_mapping - non-existing mapping', function() + mapping.__reset() + assert(mapping.__get_mapping('non-existing') == nil) + end) + + it('__register - empty', function() + mapping.__register({}) + end) + + it('__register - null', function() + mapping.__register(nil) + end) + + it('__register - happy path', function() + mapping.__reset() + mapping.__register({ 'foo', 'bar', 'zoo' }) + assert(mapping.__has_mapping('foo')) + assert(mapping.__has_mapping('bar')) + assert(mapping.__has_mapping('zoo')) + end) + + it('__has_mapping - existing map', function() + mapping.__reset() + mapping.__register({ 'foo', 'bar' }) + assert(mapping.__has_mapping('foo')) + assert(mapping.__has_mapping('bar')) + end) + + it('__has_mapping - nil', function() + assert(mapping.__has_mapping(nil) == false) + end) +end) diff --git a/test/test_files/test_1.txt b/test/test_files/test_1.txt new file mode 100644 index 0000000..ba0004c --- /dev/null +++ b/test/test_files/test_1.txt @@ -0,0 +1,3 @@ +false +false, +< diff --git a/test/toggle_spec.lua b/test/toggle_spec.lua new file mode 100644 index 0000000..94c4041 --- /dev/null +++ b/test/toggle_spec.lua @@ -0,0 +1,38 @@ +local toggle = require('toggle') + +local function open_file_at(file_to_open, row, column, callback) + local full_path = vim.fs.joinpath(vim.fn.getcwd(), file_to_open) + vim.api.nvim_command('edit ' .. full_path) + vim.api.nvim_win_set_cursor(0, { row, column }) + callback() + vim.cmd(':bd!') +end + +local function get_character_under_cursor() + local coords = vim.api.nvim_win_get_cursor(0) + local line = vim.api.nvim_get_current_line() + return line:sub(coords[2] + 1, coords[2] + 1) +end + +describe('toggle', function() + it('toggle cword', function() + open_file_at('test/test_files/test_1.txt', 1, 1, function() + toggle.toggle() + assert(vim.fn.expand('') == 'true') + end) + end) + + it('toggle cWORD', function() + open_file_at('test/test_files/test_1.txt', 2, 1, function() + toggle.toggle() + assert(vim.fn.expand('') == 'true') + end) + end) + + it('toggle char', function() + open_file_at('test/test_files/test_1.txt', 3, 1, function() + toggle.toggle() + assert(get_character_under_cursor() == '>') + end) + end) +end)