diff --git a/CHANGELOG.md b/CHANGELOG.md index fb7ad98..5d755cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.6.0](https://github.com/nvim-java/nvim-java/compare/v1.5.1...v1.6.0) (2024-06-25) + + +### Features + +* handle multiple running app ([#182](https://github.com/nvim-java/nvim-java/issues/182)) ([#191](https://github.com/nvim-java/nvim-java/issues/191)) ([ca5cfdb](https://github.com/nvim-java/nvim-java/commit/ca5cfdba0d0629a829d16fa838808be0d5db8baa)) + ## [1.5.1](https://github.com/nvim-java/nvim-java/compare/v1.5.0...v1.5.1) (2024-05-29) diff --git a/README.md b/README.md index c45f26c..c94b909 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ Just install and start writing `public static void main(String[] args)`. +> [!WARNING] +> You cannot use `nvim-java` alongside `nvim-jdtls`. So remove `nvim-jdtls` before installing this + ## :loudspeaker: Demo https://github.com/nvim-java/nvim-java/assets/18459807/047c8c46-9a0a-4869-b342-d5c2e15647bc @@ -18,6 +21,7 @@ https://github.com/nvim-java/nvim-java/assets/18459807/047c8c46-9a0a-4869-b342-d - :white_check_mark: Automatic [DAP](https://github.com/mfussenegger/nvim-dap) debug configuration - :white_check_mark: Running tests +- :white_check_mark: Run & Debug profiles ## :bulb: Why @@ -36,6 +40,10 @@ https://github.com/nvim-java/nvim-java/assets/18459807/047c8c46-9a0a-4869-b342-d :small_orange_diamond:details +### Q & A + +If you face any issues, check our [Q & A](https://github.com/nvim-java/nvim-java/wiki/Q-&-A) wiki to see if that helps + ### Distributions - [Lazyvim](https://github.com/nvim-java/nvim-java/wiki/Lazyvim) diff --git a/lua/java.lua b/lua/java.lua index eb29279..e378f87 100644 --- a/lua/java.lua +++ b/lua/java.lua @@ -64,12 +64,11 @@ M.refactor.extract_variable = refactor.extract_variable -- Runner APIs -- ---------------------------------------------------------------------- M.runner = {} -M.runner.run_app = runner.run_app - M.runner.built_in = {} M.runner.built_in.run_app = runner.built_in.run_app M.runner.built_in.toggle_logs = runner.built_in.toggle_logs M.runner.built_in.stop_app = runner.built_in.stop_app +M.runner.built_in.switch_app = runner.built_in.switch_app ---------------------------------------------------------------------- -- Profile UI -- diff --git a/lua/java/api/runner.lua b/lua/java/api/runner.lua index 7c1909f..b060062 100644 --- a/lua/java/api/runner.lua +++ b/lua/java/api/runner.lua @@ -1,222 +1,45 @@ -local log = require('java.utils.log') local async = require('java-core.utils.async').sync local get_error_handler = require('java.handlers.error') -local jdtls = require('java.utils.jdtls') -local DapSetup = require('java-dap.api.setup') -local ui = require('java.utils.ui') -local profile_config = require('java.api.profile_config') -local class = require('java-core.utils.class') - ---- @class BuiltInMainRunner ---- @field win number ---- @field bufnr number ---- @field job_id number ---- @field is_open boolean -local BuiltInMainRunner = class() - -function BuiltInMainRunner:_set_up_buffer_autocmd() - local group = vim.api.nvim_create_augroup('logger', { clear = true }) - vim.api.nvim_create_autocmd({ 'BufHidden' }, { - group = group, - buffer = self.bufnr, - callback = function(_) - self.is_open = true - end, - }) -end - -function BuiltInMainRunner:_init() - self.is_open = false -end - -function BuiltInMainRunner:stop() - if self.job_id ~= nil then - vim.fn.jobstop(self.job_id) - vim.fn.jobwait({ self.job_id }, 1000) - self.job_id = nil - end -end - ---- @param cmd string[] -function BuiltInMainRunner:run_app(cmd) - self:stop() - if not self.bufnr then - self.bufnr = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_call(self.bufnr, function() - self:_set_up_buffer() - end) - end - - self.chan = vim.api.nvim_open_term(self.bufnr, { - on_input = function(_, _, _, data) - if self.job_id then - vim.fn.chansend(self.job_id, data) - end - end, - }) - - local command = table.concat(cmd, ' ') - vim.fn.chansend(self.chan, command) - self.job_id = vim.fn.jobstart(command, { - pty = true, - on_stdout = function(_, data) - self:_on_stdout(data) - end, - on_exit = function(_, exit_code) - self:_on_exit(exit_code) - end, - }) -end - -function BuiltInMainRunner:hide_logs() - if self.bufnr then - self.is_open = true - vim.api.nvim_buf_call(self.bufnr, function() - vim.cmd('hide') - end) - end -end - -function BuiltInMainRunner:toggle_logs() - if self.is_open then - vim.api.nvim_buf_call(self.bufnr, function() - self:_set_up_buffer() - self:_scroll_down() - end) - else - self:hide_logs() - end -end - -function BuiltInMainRunner:_set_up_buffer() - vim.cmd('sp | winc J | res 15 | buffer ' .. self.bufnr) - self.win = vim.api.nvim_get_current_win() - - vim.wo[self.win].number = false - vim.wo[self.win].relativenumber = false - vim.wo[self.win].signcolumn = 'no' - - self:_set_up_buffer_autocmd() - self.is_open = false -end - ---- @param data string[] -function BuiltInMainRunner:_on_stdout(data) - vim.fn.chansend(self.chan, data) - vim.api.nvim_buf_call(self.bufnr, function() - local current_buf = vim.api.nvim_get_current_buf() - local mode = vim.api.nvim_get_mode().mode - if current_buf ~= self.bufnr or mode ~= 'i' then - self:_scroll_down() - end - end) -end - ---- @param exit_code number -function BuiltInMainRunner:_on_exit(exit_code) - vim.fn.chansend( - self.chan, - '\nProcess finished with exit code ' .. exit_code .. '\n' - ) - self.job_id = nil - local current_buf = vim.api.nvim_get_current_buf() - if current_buf == self.bufnr then - vim.cmd('stopinsert') - end -end - -function BuiltInMainRunner:_scroll_down() - local last_line = vim.api.nvim_buf_line_count(self.bufnr) - vim.api.nvim_win_set_cursor(self.win, { last_line, 0 }) -end - ---- @class RunnerApi ---- @field client LspClient ---- @field private dap java.DapSetup -local RunnerApi = class() - -function RunnerApi:_init(args) - self.client = args.client - self.dap = DapSetup(args.client) -end - -function RunnerApi:get_config() - local configs = self.dap:get_dap_config() - return ui.select_from_dap_configs(configs) -end - ---- @param callback fun(cmd) ---- @param args string -function RunnerApi:run_app(callback, args) - local config = self:get_config() - if not config then - return - end - - config.request = 'launch' - local enrich_config = self.dap:enrich_config(config) - local class_paths = table.concat(enrich_config.classPaths, ':') - local main_class = enrich_config.mainClass - local java_exec = enrich_config.javaExec - - local active_profile = profile_config.get_active_profile(enrich_config.name) - - local vm_args = '' - local prog_args = '' - if active_profile then - prog_args = (active_profile.prog_args or '') .. ' ' .. (args or '') - vm_args = active_profile.vm_args or '' - end - - local cmd = { - java_exec, - vm_args, - '-cp', - class_paths, - main_class, - prog_args, - } - - log.debug('run app cmd: ', cmd) - callback(cmd) -end +local Runner = require('java.runner.runner') local M = { built_in = {}, + + ---@type java.Runner + runner = Runner(), } ---- @param callback fun(cmd) ---- @param args string -function M.run_app(callback, args) - return async(function() - return RunnerApi(jdtls()):run_app(callback, args) +--- @param opts {} +function M.built_in.run_app(opts) + async(function() + M.runner:start_run(opts.args) end) - .catch(get_error_handler('failed to run app')) + .catch(get_error_handler('Failed to run app')) .run() end ---- @param opts {} -function M.built_in.run_app(opts) - if not M.BuildInRunner then - M.BuildInRunner = BuiltInMainRunner() - end - M.run_app(function(cmd) - M.BuildInRunner:run_app(cmd) - end, opts.args) +function M.built_in.toggle_logs() + async(function() + M.runner:toggle_open_log() + end) + .catch(get_error_handler('Failed to run app')) + .run() end -function M.built_in.toggle_logs() - if M.BuildInRunner then - M.BuildInRunner:toggle_logs() - end +function M.built_in.switch_app() + async(function() + M.runner:switch_log() + end) + .catch(get_error_handler('Failed to switch run')) + .run() end function M.built_in.stop_app() - if M.BuildInRunner then - M.BuildInRunner:stop(false) - end + async(function() + M.runner:stop_run() + end) + .catch(get_error_handler('Failed to switch run')) + .run() end -M.RunnerApi = RunnerApi -M.BuiltInMainRunner = BuiltInMainRunner return M diff --git a/lua/java/runner/run-logger.lua b/lua/java/runner/run-logger.lua new file mode 100644 index 0000000..96ed4cc --- /dev/null +++ b/lua/java/runner/run-logger.lua @@ -0,0 +1,57 @@ +local class = require('java-core.utils.class') + +---@class java.RunLogger +---@field window number +local RunLogger = class() + +function RunLogger:_init() + self.window = -1 +end + +---Opens the log window with the given run buffer +---@param buffer number +function RunLogger:create(buffer) + vim.cmd('sp | winc J | res 15 | buffer ' .. buffer) + self.window = vim.api.nvim_get_current_win() + + vim.wo[self.window].number = false + vim.wo[self.window].relativenumber = false + vim.wo[self.window].signcolumn = 'no' + + self:scroll_to_bottom() +end + +function RunLogger:set_buffer(buffer) + if self:is_opened() then + vim.api.nvim_win_set_buf(self.window, buffer) + else + self:create(buffer) + end + + self:scroll_to_bottom() +end + +function RunLogger:scroll_to_bottom() + local buffer = vim.api.nvim_win_get_buf(self.window) + local line_count = vim.api.nvim_buf_line_count(buffer) + vim.api.nvim_win_set_cursor(self.window, { line_count, 0 }) +end + +---Returns true if the log window is opened +---@return boolean +function RunLogger:is_opened() + if not self.window then + return false + end + + return vim.api.nvim_win_is_valid(self.window) +end + +---Closes the log window if opened +function RunLogger:close() + if self.window and vim.api.nvim_win_is_valid(self.window) then + vim.api.nvim_win_hide(self.window) + end +end + +return RunLogger diff --git a/lua/java/runner/run.lua b/lua/java/runner/run.lua new file mode 100644 index 0000000..4e677f6 --- /dev/null +++ b/lua/java/runner/run.lua @@ -0,0 +1,88 @@ +local class = require('java-core.utils.class') +local notify = require('java-core.utils.notify') + +---@class java.Run +---@field name string +---@field main_class string +---@field buffer number +---@field private cmd string +---@field private term_chan_id number +---@field private job_chan_id number | nil +---@field private is_running boolean +---@field private is_failure boolean +local Run = class() + +---@param dap_config java-dap.DapLauncherConfig +---@param cmd string[] +function Run:_init(dap_config, cmd) + self.name = dap_config.name + self.main_class = dap_config.mainClass + self.cmd = table.concat(cmd, ' ') + self.buffer = vim.api.nvim_create_buf(false, true) + self.term_chan_id = vim.api.nvim_open_term(self.buffer, { + on_input = function(_, _, _, data) + self:send_job(data) + end, + }) +end + +function Run:start() + self.is_running = true + self:send_term(self.cmd) + + self.job_chan_id = vim.fn.jobstart(self.cmd, { + pty = true, + on_stdout = function(_, data) + self:send_term(data) + end, + on_exit = function(_, exit_code) + self:on_job_exit(exit_code) + end, + }) +end + +function Run:stop() + if not self.job_chan_id then + return + end + + vim.fn.jobstop(self.job_chan_id) + vim.fn.jobwait({ self.job_chan_id }, 1000) + self.job_chan_id = nil +end + +---Send data to execution job channel +---@private +---@param data string +function Run:send_job(data) + if self.job_chan_id then + vim.fn.chansend(self.job_chan_id, data) + end +end + +---Send message to terminal channel +---@private +---@param data string +function Run:send_term(data) + vim.fn.chansend(self.term_chan_id, data) +end + +---Runs when the current job exists +---@private +---@param exit_code number +function Run:on_job_exit(exit_code) + local message = + string.format('Process finished with exit code::%s', exit_code) + self:send_term(message) + + self.is_running = false + + if exit_code == 0 then + self.is_failure = false + else + self.is_failure = true + notify.error(string.format('%s %s', self.name, message)) + end +end + +return Run diff --git a/lua/java/runner/runner.lua b/lua/java/runner/runner.lua new file mode 100644 index 0000000..3f7c2f3 --- /dev/null +++ b/lua/java/runner/runner.lua @@ -0,0 +1,138 @@ +local ui = require('java.utils.ui') +local class = require('java-core.utils.class') +local jdtls = require('java.utils.jdtls2') +local profile_config = require('java.api.profile_config') +local Run = require('java.runner.run') +local RunLogger = require('java.runner.run-logger') +local DapSetup = require('java-dap.api.setup') + +---@class java.Runner +---@field runs table +---@field logger java.RunLogger +local Runner = class() + +function Runner:_init() + self.runs = {} + self.curr_run = nil + self.logger = RunLogger() +end + +---Starts a new run +---@param args string +function Runner:start_run(args) + local cmd, dap_config = Runner.select_dap_config(args) + + if not cmd or not dap_config then + return + end + + local run ---@as java.Run + + -- get the default run if exist or create new run + if self.runs[dap_config.mainClass] then + run = self.runs[dap_config.mainClass] + else + run = Run(dap_config, cmd) + self.runs[dap_config.mainClass] = run + end + + self.curr_run = run + self.logger:set_buffer(run.buffer) + + run:start() +end + +---Stops the user selected run +function Runner:stop_run() + local run = self:select_run() + + if not run then + return + end + + run:stop() +end + +function Runner:toggle_open_log() + if self.logger:is_opened() then + self.logger:close() + else + if self.curr_run then + self.logger:create(self.curr_run.buffer) + end + end +end + +---Switches the log to selected run +function Runner:switch_log() + local selected_run = self:select_run() + + if not selected_run then + return + end + + self.curr_run = selected_run + self.logger:set_buffer(selected_run.buffer) +end + +---Prompt the user to select an active run and returns the selected run +---@private +---@return java.Run | nil +function Runner:select_run() + local active_main_classes = {} ---@type string[] + + for _, run in pairs(self.runs) do + table.insert(active_main_classes, run.main_class) + end + + local selected_main = ui.select('Select main class', active_main_classes) + + if not selected_main then + return + end + + return self.runs[selected_main] +end + +---Returns the dap config for user selected main +---@param args string additional program arguments to pass +---@return string[] | nil +---@return java-dap.DapLauncherConfig | nil +function Runner.select_dap_config(args) + local dap = DapSetup(jdtls()) + local dap_config_list = dap:get_dap_config() + local selected_dap_config = ui.select_from_dap_configs(dap_config_list) + + if not selected_dap_config then + return nil, nil + end + + local enriched_config = dap:enrich_config(selected_dap_config) + + local class_paths = table.concat(enriched_config.classPaths, ':') + local main_class = enriched_config.mainClass + local java_exec = enriched_config.javaExec + + local active_profile = profile_config.get_active_profile(enriched_config.name) + + local vm_args = '' + local prog_args = args + + if active_profile then + prog_args = (active_profile.prog_args or '') .. ' ' .. (args or '') + vm_args = active_profile.vm_args or '' + end + + local cmd = { + java_exec, + vm_args, + '-cp', + class_paths, + main_class, + prog_args, + } + + return cmd, selected_dap_config +end + +return Runner diff --git a/lua/java/utils/ui.lua b/lua/java/utils/ui.lua index 7c06439..214112d 100644 --- a/lua/java/utils/ui.lua +++ b/lua/java/utils/ui.lua @@ -26,8 +26,12 @@ function M.select_from_dap_configs(configs) local config_lookup = {} for _, config in ipairs(configs) do if config.projectName then - table.insert(config_names, config.name) - config_lookup[config.name] = config + local key = config.name + if config.extra_args then + key = key .. ' | ' .. config.extra_args + end + table.insert(config_names, key) + config_lookup[key] = config end end diff --git a/plugin/java.lua b/plugin/java.lua index 3e43e25..9c28519 100644 --- a/plugin/java.lua +++ b/plugin/java.lua @@ -18,6 +18,7 @@ local cmd_map = { JavaRunnerRunMain = { java.runner.built_in.run_app, { nargs = '?' } }, JavaRunnerStopMain = { java.runner.built_in.stop_app }, JavaRunnerToggleLogs = { java.runner.built_in.toggle_logs }, + JavaRunnerSwitchLogs = { java.runner.built_in.switch_app }, JavaProfile = { java.profile.ui }, diff --git a/tests/java/api/runner_spec.lua b/tests/java/api/runner_spec.lua deleted file mode 100644 index c78086d..0000000 --- a/tests/java/api/runner_spec.lua +++ /dev/null @@ -1,501 +0,0 @@ --- local spy = require('luassert.spy') --- local mock = require('luassert.mock') --- local notify = require('java-core.utils.notify') --- local DapSetup = require('java-dap.api.setup') --- local mock_client = { jdtls_args = {} } --- local runner = require('java.api.runner') --- local async = require('java-core.utils.async').sync --- local profile_config = require('java.api.profile_config') --- --- local RunnerApi = runner.RunnerApi({ client = mock_client }) --- --- describe('java-core.api.runner', function() --- it('RunnerApi()', function() --- local mock_dap = DapSetup(mock_client) --- assert.same(RunnerApi.client, mock_client) --- assert.same(RunnerApi.dap, mock_dap) --- end) --- --- it('RunnerApi:get_config when no config found', function() --- local dap_mock = mock(DapSetup, true) --- dap_mock.get_dap_config.returns({}) --- --- local notify_spy = spy.on(notify, 'warn') --- local config = RunnerApi:get_config() --- --- assert.equals(config, nil) --- assert.spy(notify_spy).was_called_with('Config not found') --- mock.revert() --- end) --- --- it('RunnerApi:get_config when only one config found', function() --- local dap_mock = mock(DapSetup, true) --- dap_mock.get_dap_config.returns({ --- { name = 'config1', projectName = 'projectName' }, --- }) --- --- local config = RunnerApi:get_config() --- assert.same(config, { name = 'config1', projectName = 'projectName' }) --- mock.revert() --- end) --- --- it('RunnerApi:get_config when multiple config found', function() --- RunnerApi.dap.get_dap_config = function() --- return { --- { name = 'config1' }, --- { name = 'config2', projectName = 'project2' }, --- { name = 'config3', projectName = 'project3' }, --- } --- end --- --- local ui = mock(vim.ui, true) --- local mock_select = function(main_class_choices, opts, callback) --- assert.same(main_class_choices, { 'config2', 'config3' }) --- assert.same(opts, { --- prompt = 'Select the main class (modul -> mainClass)', --- }) --- callback('config2', 2) --- end --- --- ui.select = mock_select --- --- return async(function() --- local config = RunnerApi:get_config() --- --- assert.same({ name = 'config2', projectName = 'project2' }, config) --- mock.revert(ui) --- end).run() --- end) --- --- it('RunnerApi:run_app when no config found', function() --- RunnerApi.get_config = function() --- return nil --- end --- --- local callback_mock = function(_) end --- local callback_spy = spy.new(callback_mock) --- --- RunnerApi:run_app(callback_spy) --- assert.spy(callback_spy).was_not_called() --- end) --- --- it('RunnerApi:run_app without active profile', function() --- RunnerApi.get_config = function() --- return { name = 'config1' } --- end --- --- RunnerApi.dap.enrich_config = function() --- return { --- classPaths = { 'path1', 'path2' }, --- mainClass = 'mainClass', --- javaExec = 'javaExec', --- } --- end --- --- RunnerApi.profile_config = profile_config --- RunnerApi.profile_config.get_active_profile = function(main_class) --- assert.equals(main_class, 'mainClass') --- return nil --- end --- --- local callback_mock = function(_, _) end --- local callback_spy = spy.new(callback_mock) --- --- RunnerApi:run_app(callback_spy) --- assert.spy(callback_spy).was_called_with({ --- 'javaExec', --- '', -- vm_args --- '-cp', --- 'path1:path2', --- 'mainClass', --- '', -- prog_args --- }) --- end) --- --- it('RunnerApi:run_app with active profile', function() --- RunnerApi.get_config = function() --- return { name = 'config1' } --- end --- --- RunnerApi.dap.enrich_config = function() --- return { --- classPaths = { 'path1', 'path2' }, --- mainClass = 'mainClass', --- javaExec = 'javaExec', --- } --- end --- --- RunnerApi.profile_config = profile_config --- RunnerApi.profile_config.get_active_profile = function(main_class) --- assert.equals(main_class, 'mainClass') --- return { --- prog_args = 'profile_prog_args', --- vm_args = 'vm_args', --- } --- end --- --- local callback_mock = function(_, _) end --- local callback_spy = spy.new(callback_mock) --- --- RunnerApi:run_app(callback_spy, 'input_prog_args') --- assert.spy(callback_spy).was_called_with({ --- 'javaExec', --- 'vm_args', --- '-cp', --- 'path1:path2', --- 'mainClass', --- 'profile_prog_args input_prog_args', --- }) --- end) --- --- it('BuildInRunner:new', function() --- local built_in_main_runner = runner.BuiltInMainRunner() --- assert.equals(built_in_main_runner.is_open, false) --- end) --- --- it('BuildInRunner:_set_up_buffer', function() --- local vim = mock(vim, true) --- vim.wo = {} --- vim.wo[1] = {} --- local spy_cmd = spy.on(vim, 'cmd') --- --- local api = mock(vim.api, true) --- api.nvim_get_current_win.returns(1) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = 1 --- built_in_main_runner.is_open = true --- spy.on(built_in_main_runner, '_set_up_buffer_autocmd') --- built_in_main_runner:_set_up_buffer() --- --- assert.equals(built_in_main_runner.is_open, false) --- assert.spy(spy_cmd).was_called_with('sp | winc J | res 15 | buffer 1') --- assert.spy(built_in_main_runner._set_up_buffer_autocmd).was_called() --- --- mock.revert(vim) --- mock.revert(api) --- end) --- --- it('BuildInRunner:_set_up_buffer_autocmd', function() --- local api = mock(vim.api, true) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = 1 --- built_in_main_runner.is_open = false --- built_in_main_runner:_set_up_buffer_autocmd() --- --- local call_info = api.nvim_create_autocmd.calls[1] --- assert.same(call_info.vals[1], { 'BufHidden' }) --- assert.equals(call_info.vals[2].buffer, 1) --- --- call_info.vals[2].callback() --- assert.is_true(built_in_main_runner.is_open) --- --- mock.revert(api) --- end) --- --- it( --- 'BuiltInMainRunner:_on_stdout when bufnr is equal to current bufnr and mode is "i" (skip scroll)', --- function() --- local mock_current_bufnr = 1 --- local vim = mock(vim, true) --- local api = mock(vim.api, true) --- local spy_chensend = spy.on(vim.fn, 'chansend') --- --- api.nvim_get_current_buf.returns(mock_current_bufnr) --- api.nvim_get_mode.returns({ mode = 'i' }) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.chan = 2 --- built_in_main_runner.bufnr = mock_current_bufnr --- spy.on(built_in_main_runner, '_scroll_down') --- --- built_in_main_runner:_on_stdout({ 'data1', 'data2' }) --- --- assert.spy(spy_chensend).was_called_with(2, { 'data1', 'data2' }) --- -- call nvim_create_buf --- local call_info = api.nvim_buf_call.calls[1] --- call_info.vals[2]() --- assert.spy(built_in_main_runner._scroll_down).was_not_called() --- -- --- mock.revert(vim) --- mock.revert(api) --- end --- ) --- --- it( --- 'BuiltInMainRunner:_on_stdout when bufnr is not equal to current bufnr and mode is "i" (scroll)', --- function() --- local api = mock(vim.api, true) --- local spy_chensend = spy.on(vim.fn, 'chansend') --- --- api.nvim_get_current_buf.returns(2) --- api.nvim_get_mode.returns({ mode = 'i' }) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = 1 --- built_in_main_runner.chan = 2 --- spy.on(built_in_main_runner, '_scroll_down') --- built_in_main_runner:_on_stdout({ 'data1', 'data2', 'data3' }) --- --- assert.spy(spy_chensend).was_called_with(2, { 'data1', 'data2', 'data3' }) --- local call_info = api.nvim_buf_call.calls[1] --- assert.equals(call_info.vals[1], 1) --- --- call_info.vals[2]() --- assert.spy(built_in_main_runner._scroll_down).was_called() --- --- mock.revert(api) --- end --- ) --- --- it( --- 'BuiltInMainRunner:_on_stdout when bufnr is equal to current bufnr and mode is not "i" (scroll)', --- function() --- local mock_current_bufnr = 1 --- local api = mock(vim.api, true) --- local spy_chensend = spy.on(vim.fn, 'chansend') --- --- api.nvim_get_current_buf.returns(mock_current_bufnr) --- api.nvim_get_mode.returns({ mode = 'n' }) --- api.nvim_buf_line_count.returns(3) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = mock_current_bufnr --- built_in_main_runner.chan = 2 --- spy.on(built_in_main_runner, '_scroll_down') --- built_in_main_runner:_on_stdout({ 'data1', 'data2' }) --- --- assert.spy(spy_chensend).was_called_with(2, { 'data1', 'data2' }) --- local call_info = api.nvim_buf_call.calls[1] --- assert.equals(call_info.vals[1], 1) --- --- call_info.vals[2]() --- assert.spy(built_in_main_runner._scroll_down).was_called() --- --- mock.revert(api) --- end --- ) --- --- it( --- 'BuiltInMainRunner:_on_exit when bufnr is equal to current bufnr (scroll)', --- function() --- local mock_current_bufnr = 1 --- local api = mock(vim.api, true) --- local spy_chensend = spy.on(vim.fn, 'chansend') --- local spy_cmd = spy.on(vim, 'cmd') --- --- api.nvim_get_current_buf.returns(mock_current_bufnr) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = mock_current_bufnr --- built_in_main_runner.chan = 2 --- built_in_main_runner:_on_exit(0) --- --- assert --- .spy(spy_chensend) --- .was_called_with(2, '\nProcess finished with exit code 0\n') --- assert.spy(spy_cmd).was_called_with('stopinsert') --- assert.equals(built_in_main_runner.job_id, nil) --- --- mock.revert(api) --- end --- ) --- --- it( --- 'BuiltInMainRunner:_on_exit when bufnr is not equal to current bufnr (skip scroll)', --- function() --- local mock_current_bufnr = 1 --- local api = mock(vim.api, true) --- local spy_chensend = spy.on(vim.fn, 'chansend') --- local spy_cmd = spy.on(vim, 'cmd') --- --- api.nvim_get_current_buf.returns(mock_current_bufnr) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = mock_current_bufnr + 1 --- built_in_main_runner.chan = 2 --- built_in_main_runner:_on_exit(0) --- --- assert --- .spy(spy_chensend) --- .was_called_with(2, '\nProcess finished with exit code 0\n') --- assert.spy(spy_cmd).was_not_called() --- assert.equals(built_in_main_runner.job_id, nil) --- --- mock.revert(api) --- end --- ) --- --- it('BuiltInMainRunner:run_app when there is no running job', function() --- local fn = mock(vim.fn, true) --- local spy_jobstart = spy.on(fn, 'jobstart') --- local spy_chansend = spy.on(fn, 'chansend') --- local spy_stop = spy.on(fn, 'jobstop') --- local api = mock(vim.api, true) --- --- api.nvim_create_buf.returns(1) --- api.nvim_open_term.returns(2) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner:run_app({ 'java', '-cp', 'path1:path2', 'mainClass' }) --- --- assert --- .spy(spy_chansend) --- .was_called_with(2, 'java -cp path1:path2 mainClass') --- assert.stub(api.nvim_buf_call).was_called() --- assert.spy(spy_jobstart).was_called() --- assert.not_nil(built_in_main_runner.job_id) --- --- local call_info = fn.jobstart.calls[1] --- assert.equals(call_info.vals[1], 'java -cp path1:path2 mainClass') --- assert.not_nil(call_info.vals[2].on_exit) --- assert.not_nil(call_info.vals[2].on_stdout) --- assert.spy(spy_stop).was_not_called() --- --- mock.revert(api) --- mock.revert(fn) --- end) --- --- it('BuiltInMainRunner:run_app when there is a running job', function() --- local fn = mock(vim.fn, true) --- local spy_chensend = spy.on(fn, 'chansend') --- local spy_jobstart = spy.on(fn, 'jobstart') --- local spy_jobwait = spy.on(fn, 'jobwait') --- local spy_stop = spy.on(fn, 'jobstop') --- local api = mock(vim.api, true) --- --- api.nvim_create_buf.returns(1) --- api.nvim_open_term.returns(2) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = 11 --- built_in_main_runner.job_id = 1 --- built_in_main_runner:run_app({ 'java', '-cp', 'path1:path2', 'mainClass' }) --- --- assert --- .spy(spy_chensend) --- .was_called_with(2, 'java -cp path1:path2 mainClass') --- assert.spy(spy_stop).was_called_with(1) --- assert.spy(spy_jobstart).was_called() --- assert.spy(spy_jobwait).was_called_with({ 1 }, 1000) --- --- mock.revert(api) --- mock.revert(fn) --- end) --- --- it('BuiltInMainRunner:toggle_logs when is_open=true', function() --- local api = mock(vim.api, true) --- --- api.nvim_buf_line_count.returns(3) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- -- mock private functions --- built_in_main_runner._set_up_buffer = function() end --- built_in_main_runner.hide_logs = function() end --- --- built_in_main_runner.is_open = true --- built_in_main_runner.bufnr = 11 --- spy.on(built_in_main_runner, '_set_up_buffer') --- spy.on(built_in_main_runner, 'hide_logs') --- --- built_in_main_runner:toggle_logs() --- --- local call_info = api.nvim_buf_call.calls[1] --- assert.equals(call_info.vals[1], 11) --- --- -- verify that private functions were called --- call_info.vals[2]() --- assert.spy(built_in_main_runner._set_up_buffer).was_called() --- assert.spy(built_in_main_runner.hide_logs).was_not_called() --- --- mock.revert(api) --- end) --- --- it('BuiltInMainRunner:toggle_logs when is_open=false', function() --- local api = mock(vim.api, true) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.is_open = false --- spy.on(built_in_main_runner, 'hide_logs') --- --- built_in_main_runner:toggle_logs() --- --- assert.stub(api.nvim_buf_call).was_not_called() --- assert.spy(built_in_main_runner.hide_logs).was_called() --- --- mock.revert(api) --- end) --- --- it('BuiltInMainRunner:stop when job_id is nil', function() --- local fn = mock(vim.fn, true) --- local spy_jobstop = spy.on(fn, 'jobstop') --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner:stop() --- --- assert.spy(spy_jobstop).was_not_called() --- --- mock.revert(fn) --- end) --- --- it('BuiltInMainRunner:hide_logs', function() --- local vim = mock(vim, true) --- local spy_cmd = spy.on(vim, 'cmd') --- local api = mock(vim.api, true) --- --- local built_in_main_runner = runner.BuiltInMainRunner() --- built_in_main_runner.bufnr = 1 --- built_in_main_runner:hide_logs() --- --- local call_info = api.nvim_buf_call.calls[1] --- assert.equals(call_info.vals[1], 1) --- assert.is_function(call_info.vals[2]) --- --- call_info.vals[2]() --- assert.spy(spy_cmd).was_called_with('hide') --- --- mock.revert(vim) --- mock.revert(api) --- end) --- --- it('built_in.run_app', function() --- local built_in_main_runner_mock = mock(runner.BuiltInMainRunner, true) --- built_in_main_runner_mock._init.returns(built_in_main_runner_mock) --- spy.on(built_in_main_runner_mock, 'run_app') --- spy.on(built_in_main_runner_mock, '_init') --- --- runner.run_app = function(callback, args) --- assert.equals(args, 'args') --- callback() --- end --- --- runner.built_in.run_app({ args = 'args' }) --- --- assert.not_nil(runner.BuiltInMainRunner) --- assert.spy(built_in_main_runner_mock._init).was_called() --- assert.spy(built_in_main_runner_mock.run_app).was_called() --- end) --- --- it('built_in.toggle_logs', function() --- local built_in_main_runner_mock = mock(runner.BuiltInMainRunner, true) --- spy.on(built_in_main_runner_mock, 'toggle_logs') --- runner.BuildInRunner = built_in_main_runner_mock --- --- runner.built_in.toggle_logs() --- assert.spy(built_in_main_runner_mock.toggle_logs).was_called() --- --- runner.BuildInRunner = nil --- end) --- --- it('built_in.stop_app', function() --- local built_in_main_runner_mock = mock(runner.BuiltInMainRunner, true) --- spy.on(built_in_main_runner_mock, 'stop') --- --- runner.BuildInRunner = built_in_main_runner_mock --- --- runner.built_in.stop_app() --- assert.spy(built_in_main_runner_mock.stop).was_called() --- runner.BuildInRunner = nil --- end) --- end) diff --git a/tests/java/java_spec.lua b/tests/java/java_spec.lua deleted file mode 100644 index 61a939e..0000000 --- a/tests/java/java_spec.lua +++ /dev/null @@ -1,18 +0,0 @@ -local plugin = require('java') -local mock = require('luassert.mock') - -describe('setup', function() - it('setup function', function() - assert('setup function is available', plugin.setup) - end) - - describe('check runner function available:', function() - local mock_runner = mock(plugin.runner, true) - - it('run_app', function() - mock_runner.run_app.returns({}) - - assert.same(plugin.runner.run_app(), {}) - end) - end) -end)