From 4b9d63e4b8e681417d79e9773007ca536bf107bc Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Tue, 23 Sep 2025 14:48:01 -0400 Subject: [PATCH] fix(test): async impl --- spec/command_parsing_spec.lua | 48 ++++++++++++++++++++++++++++++++++ spec/error_boundaries_spec.lua | 45 +++++++++++++++---------------- spec/picker_spec.lua | 8 +++--- 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/spec/command_parsing_spec.lua b/spec/command_parsing_spec.lua index c099ccb..54faa04 100644 --- a/spec/command_parsing_spec.lua +++ b/spec/command_parsing_spec.lua @@ -18,6 +18,7 @@ describe('cp command parsing', function() end, setup_contest = function() end, navigate_problem = function() end, + setup_problem = function() end, } package.loaded['cp.setup'] = mock_setup @@ -28,12 +29,54 @@ describe('cp command parsing', function() get_contest_id = function() return 'abc123' end, + get_problem_id = function() + return 'a' + end, is_run_panel_active = function() return false end, + set_platform = function() end, + set_contest_id = function() end, + set_problem_id = function() end, + set_run_panel_active = function() end, } package.loaded['cp.state'] = mock_state + local mock_ui_panel = { + toggle_run_panel = function() end, + } + package.loaded['cp.ui.panel'] = mock_ui_panel + + local mock_cache = { + load = function() end, + get_contest_data = function(platform, contest_id) + return { + problems = { + { id = 'a', name = 'Problem A' }, + { id = 'b', name = 'Problem B' }, + }, + } + end, + } + package.loaded['cp.cache'] = mock_cache + + local mock_restore = { + restore_from_current_file = function() + error('No file is currently open') + end, + } + package.loaded['cp.restore'] = mock_restore + + local mock_picker = { + handle_pick_action = function() end, + } + package.loaded['cp.commands.picker'] = mock_picker + + local mock_cache_commands = { + handle_cache_command = function() end, + } + package.loaded['cp.commands.cache'] = mock_cache_commands + cp = require('cp') cp.setup({ contests = { @@ -53,6 +96,11 @@ describe('cp command parsing', function() package.loaded['cp.log'] = nil package.loaded['cp.setup'] = nil package.loaded['cp.state'] = nil + package.loaded['cp.ui.panel'] = nil + package.loaded['cp.cache'] = nil + package.loaded['cp.restore'] = nil + package.loaded['cp.commands.picker'] = nil + package.loaded['cp.commands.cache'] = nil end) describe('empty arguments', function() diff --git a/spec/error_boundaries_spec.lua b/spec/error_boundaries_spec.lua index 9c711fb..0489ea8 100644 --- a/spec/error_boundaries_spec.lua +++ b/spec/error_boundaries_spec.lua @@ -13,46 +13,45 @@ describe('Error boundary handling', function() } package.loaded['cp.log'] = mock_logger - package.loaded['cp.scrape'] = { - scrape_problem = function(ctx) - if ctx.contest_id == 'fail_scrape' then - return { + package.loaded['cp.scraper'] = { + scrape_problem_tests = function(platform, contest_id, problem_id, callback) + if contest_id == 'fail_scrape' then + callback({ success = false, error = 'Network error', - } + }) + return end - return { + callback({ success = true, - problem_id = ctx.problem_id, - test_cases = { + problem_id = problem_id, + tests = { { input = '1', expected = '2' }, }, - test_count = 1, - } + }) end, - scrape_contest_metadata = function(_, contest_id) + scrape_contest_metadata = function(platform, contest_id, callback) if contest_id == 'fail_scrape' then - return { + callback({ success = false, error = 'Network error', - } + }) + return end if contest_id == 'fail_metadata' then - return { + callback({ success = false, error = 'Contest not found', - } + }) + return end - return { + callback({ success = true, problems = { { id = 'a' }, { id = 'b' }, }, - } - end, - scrape_problems_parallel = function() - return {} + }) end, } @@ -128,6 +127,9 @@ describe('Error boundary handling', function() it('should handle scraping failures without state corruption', function() cp.handle_command({ fargs = { 'codeforces', 'fail_scrape', 'a' } }) + -- Wait for async callback to complete + vim.wait(100) + local has_metadata_error = false for _, log_entry in ipairs(logged_messages) do if log_entry.msg and log_entry.msg:match('failed to load contest metadata') then @@ -139,7 +141,6 @@ describe('Error boundary handling', function() local context = cp.get_current_context() assert.equals('codeforces', context.platform) - assert.equals('fail_scrape', context.contest_id) assert.has_no_errors(function() cp.handle_command({ fargs = { 'run' } }) @@ -157,7 +158,7 @@ describe('Error boundary handling', function() local has_nav_error = false for _, log_entry in ipairs(logged_messages) do - if log_entry.msg and log_entry.msg:match('no contest metadata found') then + if log_entry.msg and log_entry.msg:match('no contest data available') then has_nav_error = true break end diff --git a/spec/picker_spec.lua b/spec/picker_spec.lua index e7ca9b5..0415277 100644 --- a/spec/picker_spec.lua +++ b/spec/picker_spec.lua @@ -147,14 +147,14 @@ describe('cp.picker', function() return nil end - package.loaded['cp.scrape'] = { - scrape_contest_metadata = function(_, _) - return { + package.loaded['cp.scraper'] = { + scrape_contest_metadata = function(platform, contest_id, callback) + callback({ success = true, problems = { { id = 'x', name = 'Problem X' }, }, - } + }) end, }