feat: simplify ansi buffer approach
This commit is contained in:
parent
f493b44ca3
commit
b507dad4a7
4 changed files with 185 additions and 103 deletions
|
|
@ -22,7 +22,6 @@ local function get_language_from_file(source_file, contest_config)
|
||||||
|
|
||||||
local extension = vim.fn.fnamemodify(source_file, ':e')
|
local extension = vim.fn.fnamemodify(source_file, ':e')
|
||||||
local language = filetype_to_language[extension] or contest_config.default_language
|
local language = filetype_to_language[extension] or contest_config.default_language
|
||||||
logger.log(('detected language: %s (extension: %s)'):format(language, extension))
|
|
||||||
return language
|
return language
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -83,10 +82,13 @@ function M.compile_generic(language_config, substitutions)
|
||||||
end
|
end
|
||||||
|
|
||||||
local compile_cmd = substitute_template(language_config.compile, substitutions)
|
local compile_cmd = substitute_template(language_config.compile, substitutions)
|
||||||
logger.log(('compiling: %s'):format(table.concat(compile_cmd, ' ')))
|
local redirected_cmd = vim.deepcopy(compile_cmd)
|
||||||
|
redirected_cmd[#redirected_cmd] = redirected_cmd[#redirected_cmd] .. ' 2>&1'
|
||||||
|
|
||||||
local start_time = vim.uv.hrtime()
|
local start_time = vim.uv.hrtime()
|
||||||
local result = vim.system(compile_cmd, { text = false }):wait()
|
local result = vim
|
||||||
|
.system({ 'sh', '-c', table.concat(redirected_cmd, ' ') }, { text = false })
|
||||||
|
:wait()
|
||||||
local compile_time = (vim.uv.hrtime() - start_time) / 1000000
|
local compile_time = (vim.uv.hrtime() - start_time) / 1000000
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
local ansi = require('cp.ansi')
|
||||||
|
|
@ -113,12 +115,13 @@ local function execute_command(cmd, input_data, timeout_ms)
|
||||||
timeout_ms = { timeout_ms, 'number' },
|
timeout_ms = { timeout_ms, 'number' },
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.log(('executing: %s'):format(table.concat(cmd, ' ')))
|
local redirected_cmd = vim.deepcopy(cmd)
|
||||||
|
redirected_cmd[#redirected_cmd] = redirected_cmd[#redirected_cmd] .. ' 2>&1'
|
||||||
|
|
||||||
local start_time = vim.uv.hrtime()
|
local start_time = vim.uv.hrtime()
|
||||||
|
|
||||||
local result = vim
|
local result = vim
|
||||||
.system(cmd, {
|
.system({ 'sh', '-c', table.concat(redirected_cmd, ' ') }, {
|
||||||
stdin = input_data,
|
stdin = input_data,
|
||||||
timeout = timeout_ms,
|
timeout = timeout_ms,
|
||||||
text = true,
|
text = true,
|
||||||
|
|
@ -203,7 +206,7 @@ end
|
||||||
---@param ctx ProblemContext
|
---@param ctx ProblemContext
|
||||||
---@param contest_config ContestConfig
|
---@param contest_config ContestConfig
|
||||||
---@param is_debug? boolean
|
---@param is_debug? boolean
|
||||||
---@return {success: boolean, stderr: string?}
|
---@return {success: boolean, output: string?}
|
||||||
function M.compile_problem(ctx, contest_config, is_debug)
|
function M.compile_problem(ctx, contest_config, is_debug)
|
||||||
vim.validate({
|
vim.validate({
|
||||||
ctx = { ctx, 'table' },
|
ctx = { ctx, 'table' },
|
||||||
|
|
@ -215,7 +218,7 @@ function M.compile_problem(ctx, contest_config, is_debug)
|
||||||
|
|
||||||
if not language_config then
|
if not language_config then
|
||||||
logger.log('No configuration for language: ' .. language, vim.log.levels.ERROR)
|
logger.log('No configuration for language: ' .. language, vim.log.levels.ERROR)
|
||||||
return { success = false, stderr = 'No configuration for language: ' .. language }
|
return { success = false, output = 'No configuration for language: ' .. language }
|
||||||
end
|
end
|
||||||
|
|
||||||
local substitutions = {
|
local substitutions = {
|
||||||
|
|
@ -230,12 +233,12 @@ function M.compile_problem(ctx, contest_config, is_debug)
|
||||||
language_config.compile = compile_cmd
|
language_config.compile = compile_cmd
|
||||||
local compile_result = M.compile_generic(language_config, substitutions)
|
local compile_result = M.compile_generic(language_config, substitutions)
|
||||||
if compile_result.code ~= 0 then
|
if compile_result.code ~= 0 then
|
||||||
return { success = false, stderr = compile_result.stderr or 'unknown error' }
|
return { success = false, output = compile_result.stdout or 'unknown error' }
|
||||||
end
|
end
|
||||||
logger.log(('compilation successful (%s)'):format(is_debug and 'debug mode' or 'test mode'))
|
logger.log(('compilation successful (%s)'):format(is_debug and 'debug mode' or 'test mode'))
|
||||||
end
|
end
|
||||||
|
|
||||||
return { success = true, stderr = nil }
|
return { success = true, output = nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.run_problem(ctx, contest_config, is_debug)
|
function M.run_problem(ctx, contest_config, is_debug)
|
||||||
|
|
|
||||||
|
|
@ -227,8 +227,9 @@ local function toggle_run_panel(is_debug)
|
||||||
local diff_namespace = highlight.create_namespace()
|
local diff_namespace = highlight.create_namespace()
|
||||||
|
|
||||||
local test_list_namespace = vim.api.nvim_create_namespace('cp_test_list')
|
local test_list_namespace = vim.api.nvim_create_namespace('cp_test_list')
|
||||||
|
local ansi_namespace = vim.api.nvim_create_namespace('cp_ansi_highlights')
|
||||||
|
|
||||||
local function update_buffer_content(bufnr, lines, highlights)
|
local function update_buffer_content(bufnr, lines, highlights, namespace)
|
||||||
local was_readonly = vim.api.nvim_get_option_value('readonly', { buf = bufnr })
|
local was_readonly = vim.api.nvim_get_option_value('readonly', { buf = bufnr })
|
||||||
|
|
||||||
vim.api.nvim_set_option_value('readonly', false, { buf = bufnr })
|
vim.api.nvim_set_option_value('readonly', false, { buf = bufnr })
|
||||||
|
|
@ -237,30 +238,8 @@ local function toggle_run_panel(is_debug)
|
||||||
vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr })
|
vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr })
|
||||||
vim.api.nvim_set_option_value('readonly', was_readonly, { buf = bufnr })
|
vim.api.nvim_set_option_value('readonly', was_readonly, { buf = bufnr })
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
local highlight = require('cp.highlight')
|
||||||
ansi.setup_highlight_groups()
|
highlight.apply_highlights(bufnr, highlights, namespace or test_list_namespace)
|
||||||
|
|
||||||
vim.api.nvim_buf_clear_namespace(bufnr, test_list_namespace, 0, -1)
|
|
||||||
for _, hl in ipairs(highlights) do
|
|
||||||
logger.log(
|
|
||||||
'Applying extmark: buf='
|
|
||||||
.. bufnr
|
|
||||||
.. ' line='
|
|
||||||
.. hl.line
|
|
||||||
.. ' col='
|
|
||||||
.. hl.col_start
|
|
||||||
.. '-'
|
|
||||||
.. hl.col_end
|
|
||||||
.. ' group='
|
|
||||||
.. (hl.highlight_group or 'nil')
|
|
||||||
)
|
|
||||||
|
|
||||||
vim.api.nvim_buf_set_extmark(bufnr, test_list_namespace, hl.line, hl.col_start, {
|
|
||||||
end_col = hl.col_end,
|
|
||||||
hl_group = hl.highlight_group,
|
|
||||||
priority = 200,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function create_vim_diff_layout(parent_win, expected_content, actual_content)
|
local function create_vim_diff_layout(parent_win, expected_content, actual_content)
|
||||||
|
|
@ -427,7 +406,12 @@ local function toggle_run_panel(is_debug)
|
||||||
else
|
else
|
||||||
if desired_mode == 'single' then
|
if desired_mode == 'single' then
|
||||||
local lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
local lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
||||||
update_buffer_content(current_diff_layout.buffers[1], lines, actual_highlights)
|
update_buffer_content(
|
||||||
|
current_diff_layout.buffers[1],
|
||||||
|
lines,
|
||||||
|
actual_highlights,
|
||||||
|
ansi_namespace
|
||||||
|
)
|
||||||
elseif desired_mode == 'git' then
|
elseif desired_mode == 'git' then
|
||||||
local diff_backend = require('cp.diff')
|
local diff_backend = require('cp.diff')
|
||||||
local backend = diff_backend.get_best_backend('git')
|
local backend = diff_backend.get_best_backend('git')
|
||||||
|
|
@ -441,13 +425,23 @@ local function toggle_run_panel(is_debug)
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
local lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
local lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
||||||
update_buffer_content(current_diff_layout.buffers[1], lines, actual_highlights)
|
update_buffer_content(
|
||||||
|
current_diff_layout.buffers[1],
|
||||||
|
lines,
|
||||||
|
actual_highlights,
|
||||||
|
ansi_namespace
|
||||||
|
)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local expected_lines = vim.split(expected_content, '\n', { plain = true, trimempty = true })
|
local expected_lines = vim.split(expected_content, '\n', { plain = true, trimempty = true })
|
||||||
local actual_lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
local actual_lines = vim.split(actual_content, '\n', { plain = true, trimempty = true })
|
||||||
update_buffer_content(current_diff_layout.buffers[1], expected_lines, {})
|
update_buffer_content(current_diff_layout.buffers[1], expected_lines, {})
|
||||||
update_buffer_content(current_diff_layout.buffers[2], actual_lines, actual_highlights)
|
update_buffer_content(
|
||||||
|
current_diff_layout.buffers[2],
|
||||||
|
actual_lines,
|
||||||
|
actual_highlights,
|
||||||
|
ansi_namespace
|
||||||
|
)
|
||||||
|
|
||||||
if should_show_diff then
|
if should_show_diff then
|
||||||
vim.api.nvim_set_option_value('diff', true, { win = current_diff_layout.windows[1] })
|
vim.api.nvim_set_option_value('diff', true, { win = current_diff_layout.windows[1] })
|
||||||
|
|
@ -476,8 +470,6 @@ local function toggle_run_panel(is_debug)
|
||||||
local run_render = require('cp.run_render')
|
local run_render = require('cp.run_render')
|
||||||
run_render.setup_highlights()
|
run_render.setup_highlights()
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
|
||||||
ansi.setup_highlight_groups()
|
|
||||||
local test_state = run.get_run_panel_state()
|
local test_state = run.get_run_panel_state()
|
||||||
local tab_lines, tab_highlights = run_render.render_test_list(test_state)
|
local tab_lines, tab_highlights = run_render.render_test_list(test_state)
|
||||||
update_buffer_content(test_buffers.tab_buf, tab_lines, tab_highlights)
|
update_buffer_content(test_buffers.tab_buf, tab_lines, tab_highlights)
|
||||||
|
|
@ -540,11 +532,19 @@ local function toggle_run_panel(is_debug)
|
||||||
if compile_result.success then
|
if compile_result.success then
|
||||||
run.run_all_test_cases(ctx, contest_config, config)
|
run.run_all_test_cases(ctx, contest_config, config)
|
||||||
else
|
else
|
||||||
run.handle_compilation_failure(compile_result.stderr)
|
run.handle_compilation_failure(compile_result.output)
|
||||||
end
|
end
|
||||||
|
|
||||||
refresh_run_panel()
|
refresh_run_panel()
|
||||||
|
|
||||||
|
vim.schedule(function()
|
||||||
|
local ansi = require('cp.ansi')
|
||||||
|
ansi.setup_highlight_groups()
|
||||||
|
if current_diff_layout then
|
||||||
|
update_diff_panes()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
vim.api.nvim_set_current_win(test_windows.tab_win)
|
vim.api.nvim_set_current_win(test_windows.tab_win)
|
||||||
|
|
||||||
state.run_panel_active = true
|
state.run_panel_active = true
|
||||||
|
|
|
||||||
|
|
@ -188,13 +188,22 @@ local function run_single_test_case(ctx, contest_config, cp_config, test_case)
|
||||||
if language_config.compile and vim.fn.filereadable(ctx.binary_file) == 0 then
|
if language_config.compile and vim.fn.filereadable(ctx.binary_file) == 0 then
|
||||||
logger.log('binary not found, compiling first...')
|
logger.log('binary not found, compiling first...')
|
||||||
local compile_cmd = substitute_template(language_config.compile, substitutions)
|
local compile_cmd = substitute_template(language_config.compile, substitutions)
|
||||||
local compile_result = vim.system(compile_cmd, { text = true }):wait()
|
local redirected_cmd = vim.deepcopy(compile_cmd)
|
||||||
|
redirected_cmd[#redirected_cmd] = redirected_cmd[#redirected_cmd] .. ' 2>&1'
|
||||||
|
local compile_result = vim
|
||||||
|
.system({ 'sh', '-c', table.concat(redirected_cmd, ' ') }, { text = false })
|
||||||
|
:wait()
|
||||||
|
|
||||||
|
local ansi = require('cp.ansi')
|
||||||
|
compile_result.stdout = ansi.bytes_to_string(compile_result.stdout or '')
|
||||||
|
compile_result.stderr = ansi.bytes_to_string(compile_result.stderr or '')
|
||||||
|
|
||||||
if compile_result.code ~= 0 then
|
if compile_result.code ~= 0 then
|
||||||
return {
|
return {
|
||||||
status = 'fail',
|
status = 'fail',
|
||||||
actual = '',
|
actual = '',
|
||||||
error = 'Compilation failed: ' .. (compile_result.stderr or 'Unknown error'),
|
error = 'Compilation failed: ' .. (compile_result.stdout or 'Unknown error'),
|
||||||
stderr = compile_result.stderr or '',
|
stderr = compile_result.stdout or '',
|
||||||
time_ms = 0,
|
time_ms = 0,
|
||||||
code = compile_result.code,
|
code = compile_result.code,
|
||||||
ok = false,
|
ok = false,
|
||||||
|
|
@ -214,8 +223,10 @@ local function run_single_test_case(ctx, contest_config, cp_config, test_case)
|
||||||
if not run_panel_state.constraints then
|
if not run_panel_state.constraints then
|
||||||
logger.log('no problem constraints available, using default 2000ms timeout')
|
logger.log('no problem constraints available, using default 2000ms timeout')
|
||||||
end
|
end
|
||||||
|
local redirected_run_cmd = vim.deepcopy(run_cmd)
|
||||||
|
redirected_run_cmd[#redirected_run_cmd] = redirected_run_cmd[#redirected_run_cmd] .. ' 2>&1'
|
||||||
local result = vim
|
local result = vim
|
||||||
.system(run_cmd, {
|
.system({ 'sh', '-c', table.concat(redirected_run_cmd, ' ') }, {
|
||||||
stdin = stdin_content,
|
stdin = stdin_content,
|
||||||
timeout = timeout_ms,
|
timeout = timeout_ms,
|
||||||
text = false,
|
text = false,
|
||||||
|
|
@ -225,35 +236,14 @@ local function run_single_test_case(ctx, contest_config, cp_config, test_case)
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
local ansi = require('cp.ansi')
|
||||||
local stdout_str = ansi.bytes_to_string(result.stdout or '')
|
local stdout_str = ansi.bytes_to_string(result.stdout or '')
|
||||||
local stderr_str = ansi.bytes_to_string(result.stderr or '')
|
|
||||||
|
|
||||||
local actual_output = stdout_str:gsub('\n$', '')
|
local actual_output = stdout_str:gsub('\n$', '')
|
||||||
local stderr_output = stderr_str:gsub('\n$', '')
|
|
||||||
|
|
||||||
local actual_highlights = {}
|
local actual_highlights = {}
|
||||||
|
|
||||||
if stderr_output ~= '' then
|
if actual_output ~= '' then
|
||||||
local stderr_parsed = ansi.parse_ansi_text(stderr_output)
|
local parsed = ansi.parse_ansi_text(actual_output)
|
||||||
local clean_stderr = table.concat(stderr_parsed.lines, '\n')
|
actual_output = table.concat(parsed.lines, '\n')
|
||||||
|
actual_highlights = parsed.highlights
|
||||||
local line_offset
|
|
||||||
if actual_output ~= '' then
|
|
||||||
local stdout_lines = vim.split(actual_output, '\n')
|
|
||||||
line_offset = #stdout_lines + 2 -- +1 for empty line, +1 for "--- stderr ---"
|
|
||||||
actual_output = actual_output .. '\n\n--- stderr ---\n' .. clean_stderr
|
|
||||||
else
|
|
||||||
line_offset = 1 -- +1 for "--- stderr ---"
|
|
||||||
actual_output = '--- stderr ---\n' .. clean_stderr
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, highlight in ipairs(stderr_parsed.highlights) do
|
|
||||||
table.insert(actual_highlights, {
|
|
||||||
line = highlight.line + line_offset,
|
|
||||||
col_start = highlight.col_start,
|
|
||||||
col_end = highlight.col_end,
|
|
||||||
highlight_group = highlight.highlight_group,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local max_lines = cp_config.run_panel.max_output_lines
|
local max_lines = cp_config.run_panel.max_output_lines
|
||||||
|
|
@ -289,8 +279,8 @@ local function run_single_test_case(ctx, contest_config, cp_config, test_case)
|
||||||
status = status,
|
status = status,
|
||||||
actual = actual_output,
|
actual = actual_output,
|
||||||
actual_highlights = actual_highlights,
|
actual_highlights = actual_highlights,
|
||||||
error = result.code ~= 0 and result.stderr or nil,
|
error = result.code ~= 0 and actual_output or nil,
|
||||||
stderr = result.stderr or '',
|
stderr = '',
|
||||||
time_ms = execution_time,
|
time_ms = execution_time,
|
||||||
code = result.code,
|
code = result.code,
|
||||||
ok = ok,
|
ok = ok,
|
||||||
|
|
@ -335,7 +325,6 @@ function M.run_test_case(ctx, contest_config, cp_config, index)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
logger.log(('running test case %d'):format(index))
|
|
||||||
test_case.status = 'running'
|
test_case.status = 'running'
|
||||||
|
|
||||||
local result = run_single_test_case(ctx, contest_config, cp_config, test_case)
|
local result = run_single_test_case(ctx, contest_config, cp_config, test_case)
|
||||||
|
|
@ -371,39 +360,13 @@ function M.get_run_panel_state()
|
||||||
return run_panel_state
|
return run_panel_state
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.handle_compilation_failure(compilation_stderr)
|
function M.handle_compilation_failure(compilation_output)
|
||||||
local ansi = require('cp.ansi')
|
local ansi = require('cp.ansi')
|
||||||
local clean_text = 'Compilation failed'
|
|
||||||
local highlights = {}
|
|
||||||
|
|
||||||
if compilation_stderr and compilation_stderr ~= '' then
|
-- Always parse the compilation output - it contains everything now
|
||||||
logger.log('Raw compilation stderr length: ' .. #compilation_stderr)
|
local parsed = ansi.parse_ansi_text(compilation_output or '')
|
||||||
logger.log('Has ANSI codes: ' .. tostring(compilation_stderr:find('\027%[[%d;]*m') ~= nil))
|
local clean_text = table.concat(parsed.lines, '\n')
|
||||||
|
local highlights = parsed.highlights
|
||||||
-- Show first 200 chars to see actual ANSI sequences
|
|
||||||
local sample = compilation_stderr:sub(1, 200):gsub('\027', '\\027')
|
|
||||||
logger.log('Stderr sample: ' .. sample)
|
|
||||||
|
|
||||||
local parsed = ansi.parse_ansi_text(compilation_stderr)
|
|
||||||
clean_text = table.concat(parsed.lines, '\n')
|
|
||||||
highlights = parsed.highlights
|
|
||||||
|
|
||||||
logger.log('Parsed highlights count: ' .. #highlights)
|
|
||||||
for i, hl in ipairs(highlights) do
|
|
||||||
logger.log(
|
|
||||||
'Highlight '
|
|
||||||
.. i
|
|
||||||
.. ': line='
|
|
||||||
.. hl.line
|
|
||||||
.. ' col='
|
|
||||||
.. hl.col_start
|
|
||||||
.. '-'
|
|
||||||
.. hl.col_end
|
|
||||||
.. ' group='
|
|
||||||
.. (hl.highlight_group or 'nil')
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, test_case in ipairs(run_panel_state.test_cases) do
|
for _, test_case in ipairs(run_panel_state.test_cases) do
|
||||||
test_case.status = 'fail'
|
test_case.status = 'fail'
|
||||||
|
|
|
||||||
116
tests/execute_spec.lua
Normal file
116
tests/execute_spec.lua
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
local execute = require('cp.execute')
|
||||||
|
|
||||||
|
describe('execute module', function()
|
||||||
|
local test_ctx
|
||||||
|
local test_config
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
test_ctx = {
|
||||||
|
source_file = 'test.cpp',
|
||||||
|
binary_file = 'build/test',
|
||||||
|
input_file = 'io/test.cpin',
|
||||||
|
output_file = 'io/test.cpout',
|
||||||
|
}
|
||||||
|
|
||||||
|
test_config = {
|
||||||
|
default_language = 'cpp',
|
||||||
|
cpp = {
|
||||||
|
version = 17,
|
||||||
|
compile = { 'g++', '-std=c++17', '-o', '{binary}', '{source}' },
|
||||||
|
test = { '{binary}' },
|
||||||
|
executable = nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe('compile_generic', function()
|
||||||
|
it('should use stderr redirection (2>&1)', function()
|
||||||
|
local original_system = vim.system
|
||||||
|
local captured_command = nil
|
||||||
|
|
||||||
|
vim.system = function(cmd, opts)
|
||||||
|
captured_command = cmd
|
||||||
|
return {
|
||||||
|
wait = function()
|
||||||
|
return { code = 0, stdout = '', stderr = '' }
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local substitutions = { source = 'test.cpp', binary = 'build/test', version = '17' }
|
||||||
|
execute.compile_generic(test_config.cpp, substitutions)
|
||||||
|
|
||||||
|
assert.is_not_nil(captured_command)
|
||||||
|
assert.equals('sh', captured_command[1])
|
||||||
|
assert.equals('-c', captured_command[2])
|
||||||
|
assert.is_true(
|
||||||
|
string.find(captured_command[3], '2>&1') ~= nil,
|
||||||
|
'Command should contain 2>&1 redirection'
|
||||||
|
)
|
||||||
|
|
||||||
|
vim.system = original_system
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('should return combined stdout+stderr in result', function()
|
||||||
|
local original_system = vim.system
|
||||||
|
local test_output = 'STDOUT: Hello\nSTDERR: Error message\n'
|
||||||
|
|
||||||
|
vim.system = function(cmd, opts)
|
||||||
|
return {
|
||||||
|
wait = function()
|
||||||
|
return { code = 1, stdout = test_output, stderr = '' }
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local substitutions = { source = 'test.cpp', binary = 'build/test', version = '17' }
|
||||||
|
local result = execute.compile_generic(test_config.cpp, substitutions)
|
||||||
|
|
||||||
|
assert.equals(1, result.code)
|
||||||
|
assert.equals(test_output, result.stdout)
|
||||||
|
|
||||||
|
vim.system = original_system
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe('compile_problem', function()
|
||||||
|
it('should return combined output in stderr field for compatibility', function()
|
||||||
|
local original_system = vim.system
|
||||||
|
local test_error_output = 'test.cpp:1:1: error: expected declaration\n'
|
||||||
|
|
||||||
|
vim.system = function(cmd, opts)
|
||||||
|
return {
|
||||||
|
wait = function()
|
||||||
|
return { code = 1, stdout = test_error_output, stderr = '' }
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = execute.compile_problem(test_ctx, test_config, false)
|
||||||
|
|
||||||
|
assert.is_false(result.success)
|
||||||
|
assert.equals(test_error_output, result.output)
|
||||||
|
|
||||||
|
vim.system = original_system
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('should return success=true when compilation succeeds', function()
|
||||||
|
local original_system = vim.system
|
||||||
|
|
||||||
|
vim.system = function(cmd, opts)
|
||||||
|
return {
|
||||||
|
wait = function()
|
||||||
|
return { code = 0, stdout = '', stderr = '' }
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = execute.compile_problem(test_ctx, test_config, false)
|
||||||
|
|
||||||
|
assert.is_true(result.success)
|
||||||
|
assert.is_nil(result.output)
|
||||||
|
|
||||||
|
vim.system = original_system
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue