fix(test): update text for stderr/stdout interleaving
This commit is contained in:
parent
56c31b22b9
commit
eada64de41
4 changed files with 210 additions and 66 deletions
196
doc/cp.txt
196
doc/cp.txt
|
|
@ -437,7 +437,10 @@ Test cases use competitive programming terminology with color highlighting:
|
||||||
|
|
||||||
Highlight Groups ~
|
Highlight Groups ~
|
||||||
*cp-highlights*
|
*cp-highlights*
|
||||||
cp.nvim defines the following highlight groups for status indicators:
|
cp.nvim defines comprehensive highlight groups for test status, ANSI colors,
|
||||||
|
and diff visualization.
|
||||||
|
|
||||||
|
Test Status Groups ~
|
||||||
|
|
||||||
CpTestAC Green foreground for AC status
|
CpTestAC Green foreground for AC status
|
||||||
CpTestWA Red foreground for WA status
|
CpTestWA Red foreground for WA status
|
||||||
|
|
@ -445,14 +448,193 @@ cp.nvim defines the following highlight groups for status indicators:
|
||||||
CpTestRTE Purple foreground for RTE status
|
CpTestRTE Purple foreground for RTE status
|
||||||
CpTestPending Gray foreground for pending tests
|
CpTestPending Gray foreground for pending tests
|
||||||
|
|
||||||
You can customize these colors by linking to other highlight groups in your
|
ANSI Color Support ~
|
||||||
colorscheme or by redefining them: >lua
|
*cp-ansi-colors*
|
||||||
vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'DiffAdd' })
|
cp.nvim preserves ANSI colors from compiler output and program stderr using
|
||||||
vim.api.nvim_set_hl(0, 'CpTestWA', { fg = '#ff0000' })
|
a sophisticated parsing system. Colors are automatically mapped to your
|
||||||
|
terminal colorscheme via vim.g.terminal_color_* variables.
|
||||||
|
|
||||||
|
ANSI Highlight Groups:
|
||||||
|
|
||||||
|
CpAnsiBold Bold text formatting
|
||||||
|
CpAnsiItalic Italic text formatting
|
||||||
|
CpAnsiBoldItalic Combined bold and italic formatting
|
||||||
|
|
||||||
|
Color combinations (16 standard terminal colors):
|
||||||
|
CpAnsiRed Standard red (terminal_color_1)
|
||||||
|
CpAnsiBoldRed Bold red combination
|
||||||
|
CpAnsiItalicRed Italic red combination
|
||||||
|
CpAnsiBoldItalicRed Bold italic red combination
|
||||||
|
|
||||||
|
CpAnsiGreen Standard green (terminal_color_2)
|
||||||
|
CpAnsiYellow Standard yellow (terminal_color_3)
|
||||||
|
CpAnsiBlue Standard blue (terminal_color_4)
|
||||||
|
CpAnsiMagenta Standard magenta (terminal_color_5)
|
||||||
|
CpAnsiCyan Standard cyan (terminal_color_6)
|
||||||
|
CpAnsiWhite Standard white (terminal_color_7)
|
||||||
|
CpAnsiBlack Standard black (terminal_color_0)
|
||||||
|
|
||||||
|
Bright color variants:
|
||||||
|
CpAnsiBrightRed Bright red (terminal_color_9)
|
||||||
|
CpAnsiBrightGreen Bright green (terminal_color_10)
|
||||||
|
CpAnsiBrightYellow Bright yellow (terminal_color_11)
|
||||||
|
CpAnsiBrightBlue Bright blue (terminal_color_12)
|
||||||
|
CpAnsiBrightMagenta Bright magenta (terminal_color_13)
|
||||||
|
CpAnsiBrightCyan Bright cyan (terminal_color_14)
|
||||||
|
CpAnsiBrightWhite Bright white (terminal_color_15)
|
||||||
|
CpAnsiBrightBlack Bright black (terminal_color_8)
|
||||||
|
|
||||||
|
Each color supports Bold, Italic, and BoldItalic variants automatically.
|
||||||
|
|
||||||
|
Diff Highlight Groups ~
|
||||||
|
|
||||||
|
CpDiffAdded Green background for added text in diffs
|
||||||
|
CpDiffRemoved Red background for removed text in diffs
|
||||||
|
|
||||||
|
Terminal Color Integration ~
|
||||||
|
*cp-terminal-colors*
|
||||||
|
ANSI colors automatically use your terminal's color palette through Neovim's
|
||||||
|
vim.g.terminal_color_* variables. This ensures compiler colors match your
|
||||||
|
colorscheme without manual configuration.
|
||||||
|
|
||||||
|
If your colorscheme doesn't set terminal colors, cp.nvim falls back to
|
||||||
|
sensible defaults. You can override terminal colors in your configuration: >vim
|
||||||
|
let g:terminal_color_1 = '#ff6b6b' " Custom red
|
||||||
|
let g:terminal_color_2 = '#51cf66' " Custom green
|
||||||
<
|
<
|
||||||
|
|
||||||
Keymaps ~
|
Highlight Customization ~
|
||||||
*cp-test-keys*
|
*cp-highlight-custom*
|
||||||
|
You can customize any highlight group by linking to existing groups or
|
||||||
|
defining custom colors: >lua
|
||||||
|
-- Link to existing colorscheme groups
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'DiffAdd' })
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestWA', { link = 'DiagnosticError' })
|
||||||
|
|
||||||
|
-- Define custom colors
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestTLE', { fg = '#ffa500', bold = true })
|
||||||
|
vim.api.nvim_set_hl(0, 'CpDiffAdded', { fg = '#10b981', bg = '#1e293b' })
|
||||||
|
|
||||||
|
-- Customize ANSI colors while preserving terminal integration
|
||||||
|
vim.api.nvim_set_hl(0, 'CpAnsiRed', {
|
||||||
|
fg = vim.g.terminal_color_1 or '#ef4444'
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
|
Place customizations in your init.lua or after the colorscheme loads to
|
||||||
|
prevent them from being overridden: >lua
|
||||||
|
vim.api.nvim_create_autocmd('ColorScheme', {
|
||||||
|
callback = function()
|
||||||
|
-- Your cp.nvim highlight customizations here
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'String' })
|
||||||
|
end
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
ANSI COLORS AND HIGHLIGHTING *cp-ansi*
|
||||||
|
|
||||||
|
cp.nvim provides comprehensive ANSI color support and highlighting for
|
||||||
|
compiler output, program stderr, and diff visualization.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
HIGHLIGHT GROUPS *cp-highlights*
|
||||||
|
|
||||||
|
Test Status Groups ~
|
||||||
|
|
||||||
|
Test cases use competitive programming terminology with color highlighting:
|
||||||
|
|
||||||
|
CpTestAC Green foreground for AC status
|
||||||
|
CpTestWA Red foreground for WA status
|
||||||
|
CpTestTLE Orange foreground for TLE status
|
||||||
|
CpTestRTE Purple foreground for RTE status
|
||||||
|
CpTestPending Gray foreground for pending tests
|
||||||
|
|
||||||
|
ANSI Color Groups ~
|
||||||
|
|
||||||
|
cp.nvim preserves ANSI colors from compiler output and program stderr using
|
||||||
|
a sophisticated parsing system. Colors are automatically mapped to your
|
||||||
|
terminal colorscheme via vim.g.terminal_color_* variables.
|
||||||
|
|
||||||
|
Basic formatting groups:
|
||||||
|
CpAnsiBold Bold text formatting
|
||||||
|
CpAnsiItalic Italic text formatting
|
||||||
|
CpAnsiBoldItalic Combined bold and italic formatting
|
||||||
|
|
||||||
|
Standard terminal colors (each supports Bold, Italic, BoldItalic variants):
|
||||||
|
CpAnsiRed Standard red (terminal_color_1)
|
||||||
|
CpAnsiGreen Standard green (terminal_color_2)
|
||||||
|
CpAnsiYellow Standard yellow (terminal_color_3)
|
||||||
|
CpAnsiBlue Standard blue (terminal_color_4)
|
||||||
|
CpAnsiMagenta Standard magenta (terminal_color_5)
|
||||||
|
CpAnsiCyan Standard cyan (terminal_color_6)
|
||||||
|
CpAnsiWhite Standard white (terminal_color_7)
|
||||||
|
CpAnsiBlack Standard black (terminal_color_0)
|
||||||
|
|
||||||
|
Bright color variants:
|
||||||
|
CpAnsiBrightRed Bright red (terminal_color_9)
|
||||||
|
CpAnsiBrightGreen Bright green (terminal_color_10)
|
||||||
|
CpAnsiBrightYellow Bright yellow (terminal_color_11)
|
||||||
|
CpAnsiBrightBlue Bright blue (terminal_color_12)
|
||||||
|
CpAnsiBrightMagenta Bright magenta (terminal_color_13)
|
||||||
|
CpAnsiBrightCyan Bright cyan (terminal_color_14)
|
||||||
|
CpAnsiBrightWhite Bright white (terminal_color_15)
|
||||||
|
CpAnsiBrightBlack Bright black (terminal_color_8)
|
||||||
|
|
||||||
|
Example combinations:
|
||||||
|
CpAnsiBoldRed Bold red combination
|
||||||
|
CpAnsiItalicGreen Italic green combination
|
||||||
|
CpAnsiBoldItalicYellow Bold italic yellow combination
|
||||||
|
|
||||||
|
Diff Highlight Groups ~
|
||||||
|
|
||||||
|
CpDiffAdded Green background for added text in diffs
|
||||||
|
CpDiffRemoved Red background for removed text in diffs
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
TERMINAL COLOR INTEGRATION *cp-terminal-colors*
|
||||||
|
|
||||||
|
ANSI colors automatically use your terminal's color palette through Neovim's
|
||||||
|
vim.g.terminal_color_* variables. This ensures compiler colors match your
|
||||||
|
colorscheme without manual configuration.
|
||||||
|
|
||||||
|
If your colorscheme doesn't set terminal colors, cp.nvim falls back to
|
||||||
|
sensible defaults. You can override terminal colors in your configuration: >vim
|
||||||
|
let g:terminal_color_1 = '#ff6b6b' " Custom red
|
||||||
|
let g:terminal_color_2 = '#51cf66' " Custom green
|
||||||
|
<
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
HIGHLIGHT CUSTOMIZATION *cp-highlight-custom*
|
||||||
|
|
||||||
|
You can customize any highlight group by linking to existing groups or
|
||||||
|
defining custom colors: >lua
|
||||||
|
-- Link to existing colorscheme groups
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'DiffAdd' })
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestWA', { link = 'DiagnosticError' })
|
||||||
|
|
||||||
|
-- Define custom colors
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestTLE', { fg = '#ffa500', bold = true })
|
||||||
|
vim.api.nvim_set_hl(0, 'CpDiffAdded', { fg = '#10b981', bg = '#1e293b' })
|
||||||
|
|
||||||
|
-- Customize ANSI colors while preserving terminal integration
|
||||||
|
vim.api.nvim_set_hl(0, 'CpAnsiRed', {
|
||||||
|
fg = vim.g.terminal_color_1 or '#ef4444'
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
|
Place customizations in your init.lua or after the colorscheme loads to
|
||||||
|
prevent them from being overridden: >lua
|
||||||
|
vim.api.nvim_create_autocmd('ColorScheme', {
|
||||||
|
callback = function()
|
||||||
|
-- Your cp.nvim highlight customizations here
|
||||||
|
vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'String' })
|
||||||
|
end
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
RUN PANEL KEYMAPS *cp-test-keys*
|
||||||
<c-n> Navigate to next test case (configurable via
|
<c-n> Navigate to next test case (configurable via
|
||||||
run_panel.next_test_key)
|
run_panel.next_test_key)
|
||||||
<c-p> Navigate to previous test case (configurable via
|
<c-p> Navigate to previous test case (configurable via
|
||||||
|
|
|
||||||
|
|
@ -395,50 +395,24 @@ describe('cp.execute', function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('integration tests', function()
|
describe('integration tests', function()
|
||||||
local function compile_and_run_fixture(fixture_name)
|
it('captures interleaved stderr/stdout with ANSI colors', function()
|
||||||
local source_file = string.format('spec/fixtures/%s.cpp', fixture_name)
|
|
||||||
local binary_file = string.format('build/%s', fixture_name)
|
|
||||||
|
|
||||||
local language_config = {
|
|
||||||
compile = { 'g++', '-o', '{binary}', '{source}' },
|
|
||||||
test = { '{binary}' },
|
|
||||||
}
|
|
||||||
local substitutions = {
|
|
||||||
source = source_file,
|
|
||||||
binary = binary_file,
|
|
||||||
}
|
|
||||||
|
|
||||||
local compile_result = execute.compile_generic(language_config, substitutions)
|
|
||||||
|
|
||||||
if compile_result.code ~= 0 then
|
|
||||||
return compile_result
|
|
||||||
end
|
|
||||||
|
|
||||||
local start_time = vim.uv.hrtime()
|
local start_time = vim.uv.hrtime()
|
||||||
local redirected_cmd = { 'sh', '-c', binary_file .. ' 2>&1' }
|
local python_cmd = {
|
||||||
local result = vim.system(redirected_cmd, { timeout = 2000, text = false }):wait()
|
'sh',
|
||||||
|
'-c',
|
||||||
|
"python3 -c \"import sys; print('\\033[32mstdout: \\033[1mSuccess\\033[0m'); print('\\033[31mstderr: \\033[1mWarning\\033[0m', file=sys.stderr); print('plain stdout')\" 2>&1",
|
||||||
|
}
|
||||||
|
local result = vim.system(python_cmd, { timeout = 2000, text = false }):wait()
|
||||||
local execution_time = (vim.uv.hrtime() - start_time) / 1000000
|
local execution_time = (vim.uv.hrtime() - start_time) / 1000000
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
local ansi = require('cp.ansi')
|
||||||
return {
|
local combined_output = ansi.bytes_to_string(result.stdout or '')
|
||||||
stdout = ansi.bytes_to_string(result.stdout or ''),
|
|
||||||
stderr = ansi.bytes_to_string(result.stderr or ''),
|
|
||||||
code = result.code or 0,
|
|
||||||
time_ms = execution_time,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it('captures interleaved stderr/stdout with ANSI colors', function()
|
|
||||||
local result = compile_and_run_fixture('interleaved')
|
|
||||||
|
|
||||||
assert.equals(0, result.code)
|
assert.equals(0, result.code)
|
||||||
|
|
||||||
local combined_output = result.stdout
|
|
||||||
assert.is_not_nil(string.find(combined_output, 'stdout:'))
|
assert.is_not_nil(string.find(combined_output, 'stdout:'))
|
||||||
assert.is_not_nil(string.find(combined_output, 'stderr:'))
|
assert.is_not_nil(string.find(combined_output, 'stderr:'))
|
||||||
assert.is_not_nil(string.find(combined_output, 'plain stdout'))
|
assert.is_not_nil(string.find(combined_output, 'plain stdout'))
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
|
||||||
local parsed = ansi.parse_ansi_text(combined_output)
|
local parsed = ansi.parse_ansi_text(combined_output)
|
||||||
local clean_text = table.concat(parsed.lines, '\n')
|
local clean_text = table.concat(parsed.lines, '\n')
|
||||||
|
|
||||||
|
|
@ -466,19 +440,24 @@ describe('cp.execute', function()
|
||||||
assert.is_true(has_bold, 'Should have bold highlights')
|
assert.is_true(has_bold, 'Should have bold highlights')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('handles compilation failures with combined output', function()
|
it('handles script failures with combined output', function()
|
||||||
local result = compile_and_run_fixture('syntax_error')
|
local python_cmd = {
|
||||||
|
'sh',
|
||||||
|
'-c',
|
||||||
|
"python3 -c \"import sys; print('Starting...'); print('ERROR: Something failed', file=sys.stderr); sys.exit(1)\" 2>&1",
|
||||||
|
}
|
||||||
|
local result = vim.system(python_cmd, { timeout = 2000, text = false }):wait()
|
||||||
|
|
||||||
assert.is_not_equals(0, result.code)
|
assert.is_not_equals(0, result.code)
|
||||||
|
|
||||||
local compile_output = result.stdout
|
|
||||||
assert.is_not_nil(string.find(compile_output, 'error'))
|
|
||||||
|
|
||||||
local ansi = require('cp.ansi')
|
local ansi = require('cp.ansi')
|
||||||
local parsed = ansi.parse_ansi_text(compile_output)
|
local combined_output = ansi.bytes_to_string(result.stdout or '')
|
||||||
local clean_text = table.concat(parsed.lines, '\n')
|
assert.is_not_nil(string.find(combined_output, 'Starting'))
|
||||||
|
assert.is_not_nil(string.find(combined_output, 'ERROR'))
|
||||||
|
|
||||||
assert.is_not_nil(string.find(clean_text, 'syntax_error.cpp'))
|
local parsed = ansi.parse_ansi_text(combined_output)
|
||||||
|
local clean_text = table.concat(parsed.lines, '\n')
|
||||||
|
assert.is_not_nil(string.find(clean_text, 'Something failed'))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
9
spec/fixtures/interleaved.cpp
vendored
9
spec/fixtures/interleaved.cpp
vendored
|
|
@ -1,9 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
std::cout << "\033[32mstdout: \033[1mSuccess\033[0m" << std::endl;
|
|
||||||
std::cerr << "\033[31mstderr: \033[1mWarning\033[0m" << std::endl;
|
|
||||||
std::cout << "plain stdout" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
8
spec/fixtures/syntax_error.cpp
vendored
8
spec/fixtures/syntax_error.cpp
vendored
|
|
@ -1,8 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
std::cout << "this will never compile" << std::endl
|
|
||||||
// missing semicolon above
|
|
||||||
undefined_function();
|
|
||||||
return 0
|
|
||||||
// missing semicolon again
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue