215 lines
7.7 KiB
Lua
215 lines
7.7 KiB
Lua
describe('ansi parser', function()
|
|
local ansi = require('cp.ansi')
|
|
|
|
describe('bytes_to_string', function()
|
|
it('returns string as-is', function()
|
|
local input = 'hello world'
|
|
assert.equals('hello world', ansi.bytes_to_string(input))
|
|
end)
|
|
|
|
it('converts byte array to string', function()
|
|
local input = { 104, 101, 108, 108, 111 }
|
|
assert.equals('hello', ansi.bytes_to_string(input))
|
|
end)
|
|
end)
|
|
|
|
describe('parse_ansi_text', function()
|
|
it('strips ansi codes from simple text', function()
|
|
local input = 'Hello \027[31mworld\027[0m!'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello world!', table.concat(result.lines, '\n'))
|
|
end)
|
|
|
|
it('handles text without ansi codes', function()
|
|
local input = 'Plain text'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Plain text', table.concat(result.lines, '\n'))
|
|
assert.equals(0, #result.highlights)
|
|
end)
|
|
|
|
it('creates correct highlight for simple colored text', function()
|
|
local input = 'Hello \027[31mworld\027[0m!'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals(0, highlight.line)
|
|
assert.equals(6, highlight.col_start)
|
|
assert.equals(11, highlight.col_end)
|
|
assert.equals('CpAnsiRed', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles bold text', function()
|
|
local input = 'Hello \027[1mbold\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello bold world', table.concat(result.lines, '\n'))
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiBold', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles italic text', function()
|
|
local input = 'Hello \027[3mitalic\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello italic world', table.concat(result.lines, '\n'))
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiItalic', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles bold + color combination', function()
|
|
local input = 'Hello \027[1;31mbold red\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello bold red world', table.concat(result.lines, '\n'))
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiBoldRed', highlight.highlight_group)
|
|
assert.equals(6, highlight.col_start)
|
|
assert.equals(14, highlight.col_end)
|
|
end)
|
|
|
|
it('handles italic + color combination', function()
|
|
local input = 'Hello \027[3;32mitalic green\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello italic green world', table.concat(result.lines, '\n'))
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiItalicGreen', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles bold + italic + color combination', function()
|
|
local input = 'Hello \027[1;3;33mbold italic yellow\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello bold italic yellow world', table.concat(result.lines, '\n'))
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiBoldItalicYellow', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles sequential attribute setting', function()
|
|
local input = 'Hello \027[1m\027[31mbold red\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello bold red world', table.concat(result.lines, '\n'))
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiBoldRed', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles selective attribute reset', function()
|
|
local input = 'Hello \027[1;31mbold red\027[22mno longer bold\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('Hello bold redno longer bold world', table.concat(result.lines, '\n'))
|
|
assert.equals(2, #result.highlights)
|
|
|
|
local bold_red = result.highlights[1]
|
|
assert.equals('CpAnsiBoldRed', bold_red.highlight_group)
|
|
assert.equals(6, bold_red.col_start)
|
|
assert.equals(14, bold_red.col_end)
|
|
|
|
local just_red = result.highlights[2]
|
|
assert.equals('CpAnsiRed', just_red.highlight_group)
|
|
assert.equals(14, just_red.col_start)
|
|
assert.equals(28, just_red.col_end)
|
|
end)
|
|
|
|
it('handles bright colors', function()
|
|
local input = 'Hello \027[91mbright red\027[0m world'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals(1, #result.highlights)
|
|
local highlight = result.highlights[1]
|
|
assert.equals('CpAnsiBrightRed', highlight.highlight_group)
|
|
end)
|
|
|
|
it('handles compiler-like output with complex formatting', function()
|
|
local input =
|
|
"error.cpp:10:5: \027[1m\027[31merror:\027[0m\027[1m 'undefined' was not declared\027[0m"
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
local clean_text = table.concat(result.lines, '\n')
|
|
assert.equals("error.cpp:10:5: error: 'undefined' was not declared", clean_text)
|
|
assert.equals(2, #result.highlights)
|
|
|
|
local error_highlight = result.highlights[1]
|
|
assert.equals('CpAnsiBoldRed', error_highlight.highlight_group)
|
|
assert.equals(16, error_highlight.col_start)
|
|
assert.equals(22, error_highlight.col_end)
|
|
|
|
local message_highlight = result.highlights[2]
|
|
assert.equals('CpAnsiBold', message_highlight.highlight_group)
|
|
assert.equals(22, message_highlight.col_start)
|
|
assert.equals(48, message_highlight.col_end)
|
|
end)
|
|
|
|
it('handles multiline with persistent state', function()
|
|
local input = '\027[1;31mline1\nline2\nline3\027[0m'
|
|
local result = ansi.parse_ansi_text(input)
|
|
|
|
assert.equals('line1\nline2\nline3', table.concat(result.lines, '\n'))
|
|
assert.equals(3, #result.highlights)
|
|
|
|
for i, highlight in ipairs(result.highlights) do
|
|
assert.equals('CpAnsiBoldRed', highlight.highlight_group)
|
|
assert.equals(i - 1, highlight.line)
|
|
assert.equals(0, highlight.col_start)
|
|
assert.equals(5, highlight.col_end)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
describe('update_ansi_state', function()
|
|
it('resets all state on reset code', function()
|
|
local state = { bold = true, italic = true, foreground = 'Red' }
|
|
ansi.update_ansi_state(state, '0')
|
|
|
|
assert.is_false(state.bold)
|
|
assert.is_false(state.italic)
|
|
assert.is_nil(state.foreground)
|
|
end)
|
|
|
|
it('sets individual attributes', function()
|
|
local state = { bold = false, italic = false, foreground = nil }
|
|
|
|
ansi.update_ansi_state(state, '1')
|
|
assert.is_true(state.bold)
|
|
|
|
ansi.update_ansi_state(state, '3')
|
|
assert.is_true(state.italic)
|
|
|
|
ansi.update_ansi_state(state, '31')
|
|
assert.equals('Red', state.foreground)
|
|
end)
|
|
|
|
it('handles compound codes', function()
|
|
local state = { bold = false, italic = false, foreground = nil }
|
|
ansi.update_ansi_state(state, '1;3;31')
|
|
|
|
assert.is_true(state.bold)
|
|
assert.is_true(state.italic)
|
|
assert.equals('Red', state.foreground)
|
|
end)
|
|
|
|
it('handles selective resets', function()
|
|
local state = { bold = true, italic = true, foreground = 'Red' }
|
|
|
|
ansi.update_ansi_state(state, '22')
|
|
assert.is_false(state.bold)
|
|
assert.is_true(state.italic)
|
|
assert.equals('Red', state.foreground)
|
|
|
|
ansi.update_ansi_state(state, '39')
|
|
assert.is_false(state.bold)
|
|
assert.is_true(state.italic)
|
|
assert.is_nil(state.foreground)
|
|
end)
|
|
end)
|
|
end)
|