fix(panel): toggle state correctly
This commit is contained in:
parent
b3ccce1ee7
commit
67fad79fb6
2 changed files with 365 additions and 0 deletions
|
|
@ -103,6 +103,7 @@ local function setup_problem(contest_id, problem_id, language)
|
|||
end
|
||||
|
||||
vim.cmd('silent only')
|
||||
state.run_panel_active = false
|
||||
|
||||
state.contest_id = contest_id
|
||||
state.problem_id = problem_id
|
||||
|
|
|
|||
364
spec/run_panel_integration_spec.lua
Normal file
364
spec/run_panel_integration_spec.lua
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
describe('run panel state integration', function()
|
||||
local cp
|
||||
local logged_messages
|
||||
local mock_vim_api_calls
|
||||
local mock_vim_cmd_calls
|
||||
|
||||
before_each(function()
|
||||
logged_messages = {}
|
||||
mock_vim_api_calls = {}
|
||||
mock_vim_cmd_calls = {}
|
||||
|
||||
local mock_logger = {
|
||||
log = function(msg, level)
|
||||
table.insert(logged_messages, { msg = msg, level = level })
|
||||
end,
|
||||
set_config = function() end,
|
||||
}
|
||||
|
||||
local mock_cache = {
|
||||
load = function() end,
|
||||
get_test_cases = function()
|
||||
return nil
|
||||
end,
|
||||
set_test_cases = function() end,
|
||||
get_contest_data = function(platform, contest_id)
|
||||
if platform == 'atcoder' and contest_id == 'abc123' then
|
||||
return {
|
||||
problems = {
|
||||
{ id = 'a', name = 'Problem A' },
|
||||
{ id = 'b', name = 'Problem B' },
|
||||
{ id = 'c', name = 'Problem C' },
|
||||
},
|
||||
}
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
set_file_state = function() end,
|
||||
get_file_state = function()
|
||||
return nil
|
||||
end,
|
||||
}
|
||||
|
||||
local mock_scrape = {
|
||||
scrape_contest_metadata = function()
|
||||
return { success = false, error = 'mocked disabled' }
|
||||
end,
|
||||
scrape_problem = function()
|
||||
return { success = false, error = 'mocked disabled' }
|
||||
end,
|
||||
}
|
||||
|
||||
local mock_problem = {
|
||||
create_context = function(platform, contest_id, problem_id, config, language)
|
||||
return {
|
||||
platform = platform,
|
||||
contest_id = contest_id,
|
||||
problem_id = problem_id,
|
||||
source_file = '/tmp/test.cpp',
|
||||
problem_name = problem_id or contest_id,
|
||||
}
|
||||
end,
|
||||
}
|
||||
|
||||
local mock_snippets = {
|
||||
setup = function() end,
|
||||
}
|
||||
|
||||
local mock_run = {
|
||||
load_test_cases = function()
|
||||
return false
|
||||
end,
|
||||
get_run_panel_state = function()
|
||||
return { test_cases = {}, current_index = 1 }
|
||||
end,
|
||||
run_all_test_cases = function() end,
|
||||
handle_compilation_failure = function() end,
|
||||
}
|
||||
|
||||
local mock_execute = {
|
||||
compile_problem = function()
|
||||
return { success = true }
|
||||
end,
|
||||
}
|
||||
|
||||
local mock_run_render = {
|
||||
setup_highlights = function() end,
|
||||
render_test_list = function()
|
||||
return {}, {}
|
||||
end,
|
||||
}
|
||||
|
||||
local mock_vim = {
|
||||
fn = {
|
||||
has = function()
|
||||
return 1
|
||||
end,
|
||||
mkdir = function() end,
|
||||
expand = function(str)
|
||||
if str == '%:t:r' then
|
||||
return 'test'
|
||||
end
|
||||
if str == '%:p' then
|
||||
return '/tmp/test.cpp'
|
||||
end
|
||||
return str
|
||||
end,
|
||||
tempname = function()
|
||||
return '/tmp/test_session'
|
||||
end,
|
||||
delete = function() end,
|
||||
},
|
||||
cmd = {
|
||||
e = function() end,
|
||||
split = function() end,
|
||||
vsplit = function() end,
|
||||
startinsert = function() end,
|
||||
stopinsert = function() end,
|
||||
diffthis = function() end,
|
||||
},
|
||||
api = {
|
||||
nvim_get_current_buf = function()
|
||||
return 1
|
||||
end,
|
||||
nvim_get_current_win = function()
|
||||
return 1
|
||||
end,
|
||||
nvim_create_buf = function()
|
||||
return 2
|
||||
end,
|
||||
nvim_set_option_value = function(opt, val, opts)
|
||||
table.insert(mock_vim_api_calls, { 'set_option_value', opt, val, opts })
|
||||
end,
|
||||
nvim_get_option_value = function(opt, opts)
|
||||
if opt == 'readonly' then
|
||||
return false
|
||||
end
|
||||
if opt == 'filetype' then
|
||||
return 'cpp'
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
nvim_win_set_buf = function() end,
|
||||
nvim_buf_set_lines = function() end,
|
||||
nvim_buf_get_lines = function()
|
||||
return { '' }
|
||||
end,
|
||||
nvim_win_set_cursor = function() end,
|
||||
nvim_win_get_cursor = function()
|
||||
return { 1, 0 }
|
||||
end,
|
||||
nvim_create_namespace = function()
|
||||
return 1
|
||||
end,
|
||||
nvim_win_close = function() end,
|
||||
nvim_buf_delete = function() end,
|
||||
nvim_win_call = function(win, fn)
|
||||
fn()
|
||||
end,
|
||||
},
|
||||
keymap = {
|
||||
set = function() end,
|
||||
},
|
||||
schedule = function(fn)
|
||||
fn()
|
||||
end,
|
||||
log = {
|
||||
levels = {
|
||||
ERROR = 1,
|
||||
WARN = 2,
|
||||
INFO = 3,
|
||||
},
|
||||
},
|
||||
tbl_contains = function(tbl, val)
|
||||
for _, v in ipairs(tbl) do
|
||||
if v == val then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
tbl_map = function(fn, tbl)
|
||||
local result = {}
|
||||
for i, v in ipairs(tbl) do
|
||||
result[i] = fn(v)
|
||||
end
|
||||
return result
|
||||
end,
|
||||
tbl_filter = function(fn, tbl)
|
||||
local result = {}
|
||||
for _, v in ipairs(tbl) do
|
||||
if fn(v) then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end,
|
||||
split = function(str, sep)
|
||||
local result = {}
|
||||
for token in string.gmatch(str, '[^' .. sep .. ']+') do
|
||||
table.insert(result, token)
|
||||
end
|
||||
return result
|
||||
end,
|
||||
}
|
||||
|
||||
package.loaded['cp.log'] = mock_logger
|
||||
package.loaded['cp.cache'] = mock_cache
|
||||
package.loaded['cp.scrape'] = mock_scrape
|
||||
package.loaded['cp.problem'] = mock_problem
|
||||
package.loaded['cp.snippets'] = mock_snippets
|
||||
package.loaded['cp.run'] = mock_run
|
||||
package.loaded['cp.execute'] = mock_execute
|
||||
package.loaded['cp.run_render'] = mock_run_render
|
||||
|
||||
_G.vim = mock_vim
|
||||
|
||||
mock_vim.cmd = function(cmd_str)
|
||||
table.insert(mock_vim_cmd_calls, cmd_str)
|
||||
if cmd_str == 'silent only' then
|
||||
-- Simulate closing all windows
|
||||
end
|
||||
end
|
||||
|
||||
cp = require('cp')
|
||||
cp.setup({
|
||||
contests = {
|
||||
atcoder = {
|
||||
default_language = 'cpp',
|
||||
cpp = { extension = 'cpp' },
|
||||
},
|
||||
},
|
||||
scrapers = {}, -- Disable scrapers for testing
|
||||
run_panel = {
|
||||
diff_mode = 'vim',
|
||||
toggle_diff_key = 'd',
|
||||
next_test_key = 'j',
|
||||
prev_test_key = 'k',
|
||||
ansi = false,
|
||||
},
|
||||
})
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
package.loaded['cp.log'] = nil
|
||||
package.loaded['cp.cache'] = nil
|
||||
package.loaded['cp.scrape'] = nil
|
||||
package.loaded['cp.problem'] = nil
|
||||
package.loaded['cp.snippets'] = nil
|
||||
package.loaded['cp.run'] = nil
|
||||
package.loaded['cp.execute'] = nil
|
||||
package.loaded['cp.run_render'] = nil
|
||||
_G.vim = nil
|
||||
end)
|
||||
|
||||
describe('run panel state bug fix', function()
|
||||
it('properly resets run panel state after navigation', function()
|
||||
-- Setup: configure a contest with problems
|
||||
cp.handle_command({ fargs = { 'atcoder', 'abc123', 'a' } })
|
||||
|
||||
-- Clear previous messages
|
||||
logged_messages = {}
|
||||
mock_vim_cmd_calls = {}
|
||||
|
||||
-- Step 1: Run cp run to open the test panel
|
||||
cp.handle_command({ fargs = { 'run' } })
|
||||
|
||||
-- Verify panel would be opened (no test cases means it logs a warning but state is set)
|
||||
local panel_opened = false
|
||||
for _, log in ipairs(logged_messages) do
|
||||
if log.msg:match('no test cases found') then
|
||||
panel_opened = true -- Panel was attempted to open
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(panel_opened, 'First run command should attempt to open panel')
|
||||
|
||||
-- Clear messages and cmd calls for next step
|
||||
logged_messages = {}
|
||||
mock_vim_cmd_calls = {}
|
||||
|
||||
-- Step 2: Run cp next to navigate to next problem
|
||||
cp.handle_command({ fargs = { 'next' } })
|
||||
|
||||
-- Verify that 'silent only' was called (which closes windows)
|
||||
local silent_only_called = false
|
||||
for _, cmd in ipairs(mock_vim_cmd_calls) do
|
||||
if cmd == 'silent only' then
|
||||
silent_only_called = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(silent_only_called, 'Navigation should close all windows')
|
||||
|
||||
-- Clear messages for final step
|
||||
logged_messages = {}
|
||||
|
||||
-- Step 3: Run cp run again - this should try to OPEN the panel, not close it
|
||||
cp.handle_command({ fargs = { 'run' } })
|
||||
|
||||
-- Verify panel would be opened again (not closed)
|
||||
local panel_opened_again = false
|
||||
for _, log in ipairs(logged_messages) do
|
||||
if log.msg:match('no test cases found') then
|
||||
panel_opened_again = true -- Panel was attempted to open again
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(
|
||||
panel_opened_again,
|
||||
'Second run command should attempt to open panel, not close it'
|
||||
)
|
||||
|
||||
-- Verify no "test panel closed" message
|
||||
local panel_closed = false
|
||||
for _, log in ipairs(logged_messages) do
|
||||
if log.msg:match('test panel closed') then
|
||||
panel_closed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_false(panel_closed, 'Second run command should not close panel')
|
||||
end)
|
||||
|
||||
it('handles navigation to previous problem correctly', function()
|
||||
-- Setup: configure a contest starting with problem b
|
||||
cp.handle_command({ fargs = { 'atcoder', 'abc123', 'b' } })
|
||||
|
||||
-- Clear messages
|
||||
logged_messages = {}
|
||||
mock_vim_cmd_calls = {}
|
||||
|
||||
-- Open test panel
|
||||
cp.handle_command({ fargs = { 'run' } })
|
||||
|
||||
-- Navigate to previous problem (should go to 'a')
|
||||
logged_messages = {}
|
||||
mock_vim_cmd_calls = {}
|
||||
cp.handle_command({ fargs = { 'prev' } })
|
||||
|
||||
-- Verify 'silent only' was called
|
||||
local silent_only_called = false
|
||||
for _, cmd in ipairs(mock_vim_cmd_calls) do
|
||||
if cmd == 'silent only' then
|
||||
silent_only_called = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(silent_only_called, 'Previous navigation should also close all windows')
|
||||
|
||||
-- Run again - should open panel
|
||||
logged_messages = {}
|
||||
cp.handle_command({ fargs = { 'run' } })
|
||||
|
||||
local panel_opened = false
|
||||
for _, log in ipairs(logged_messages) do
|
||||
if log.msg:match('no test cases found') then
|
||||
panel_opened = true
|
||||
break
|
||||
end
|
||||
end
|
||||
assert.is_true(panel_opened, 'After previous navigation, run should open panel')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
Loading…
Add table
Add a link
Reference in a new issue