---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch, redundant-parameter local render = require 'bugabinga.pivi.render' local entry = require 'bugabinga.pivi.entry' local transcript = require 'bugabinga.pivi.transcript' local tool = require 'bugabinga.pivi.tool' local fake = dofile 'tests/helpers/pivi_fake.lua' describe( 'pivi render', function() local bufnr before_each( function() bufnr = transcript.ensure 'rendering' transcript.clear( bufnr ) end ) after_each( function() transcript.forget_all() fake.close_extra_windows() end ) it( 'renders message formatting instead of showing markup', function() assert.is_true( render.highlighted( bufnr ) ) end ) it( 'conceals markup in its own windows only', function() local working = vim.api.nvim_get_current_win() local before = vim.wo[working].conceallevel local win = transcript.show( bufnr ) assert.equal( 2, vim.wo[win].conceallevel ) assert.equal( before, vim.wo[working].conceallevel ) vim.api.nvim_win_close( win, true ) end ) it( 'presents embedded code in its own language', function() local id = entry.open( bufnr, 'answer' ) for _, text in ipairs { 'text', '', '```lua', 'local value = 1', '```', } do entry.line( bufnr, id, text ) end entry.close( bufnr, id ) local parser = vim.treesitter.get_parser( bufnr, 'markdown' ) parser:parse( true ) local languages = {} parser:for_each_tree( function( _, tree ) languages[tree:lang()] = true end ) assert.is_true( languages.markdown ) assert.is_true( languages.lua ) end ) it( 'degrades to plain readable text when a format cannot be rendered', function() local plain = vim.api.nvim_create_buf( false, true ) vim.api.nvim_buf_set_lines( plain, 0, -1, false, { 'still readable', } ) assert.is_false( render.highlight( plain, 'definitely-not-a-language' ) or false ) assert.same( { 'still readable', }, vim.api.nvim_buf_get_lines( plain, 0, -1, false ) ) vim.api.nvim_buf_delete( plain, { force = true, } ) end ) it( 'stays responsive while a long answer streams', function() local id = entry.open( bufnr, 'answer' ) local started = vim.uv.hrtime() for index = 1, 400 do entry.write( bufnr, id, 'word ' .. index .. ' ' ) if index % 20 == 0 then entry.write( bufnr, id, '\n' ) end end local spent = ( vim.uv.hrtime() - started ) / 1e6 entry.close( bufnr, id ) -- Forcing a parse per delta costs hundreds of times this budget. assert.is_true( spent < 400, ( '400 deltas took %.1f ms' ):format( spent ) ) end ) it( 'frames an entry without writing anything into the buffer', function() local id = entry.open( bufnr, 'prompt', { text = 'ask', } ) entry.line( bufnr, id, 'ask' ) entry.close( bufnr, id ) local before = transcript.lines( bufnr ) render.decorate( bufnr, id ) assert.same( before, transcript.lines( bufnr ) ) assert.is_true( #render.marks( bufnr ) > 0 ) end ) it( 'shows a reported change with added and removed lines distinguished', function() local id = entry.open( bufnr, 'tool', { tool = 'edit', args = { path = 'a.lua', }, result = { details = { diff = ' 1 keep\n-2 old\n+2 new\n', }, }, } ) for _, text in ipairs { 'edit a.lua', ' 1 keep', '-2 old', '+2 new', } do entry.line( bufnr, id, text ) end entry.close( bufnr, id ) local before = transcript.lines( bufnr ) render.decorate( bufnr, id ) local groups = {} for _, mark in ipairs( render.marks( bufnr ) ) do local details = mark[4] or {} if details.line_hl_group then groups[mark[2] + 1] = details.line_hl_group end end local first = select( 1, entry.range( bufnr, id ) ) assert.equal( 'PiviTool', groups[first] ) assert.equal( 'PiviTool', groups[first + 1] ) assert.equal( 'DiffDelete', groups[first + 2] ) assert.equal( 'DiffAdd', groups[first + 3] ) -- The change is decoration over reported text, so the text is untouched. assert.same( before, transcript.lines( bufnr ) ) end ) it( 'leaves a tool that reported no change entirely dimmed', function() local id = entry.open( bufnr, 'tool', { tool = 'read', args = { path = 'a.lua', }, } ) for _, text in ipairs { 'read a.lua', '+ not a diff', } do entry.line( bufnr, id, text ) end entry.close( bufnr, id ) render.decorate( bufnr, id ) for _, mark in ipairs( render.marks( bufnr ) ) do assert.is_not.equal( 'DiffAdd', ( mark[4] or {} ).line_hl_group ) end end ) it( 'presents tool output in the language it came from', function() local id = entry.open( bufnr, 'tool', { tool = 'read', args = { path = '/work/greet.lua', }, cwd = '/work', result = { content = { { type = 'text', text = 'local value = 1', }, }, }, } ) entry.line( bufnr, id, 'read greet.lua' ) entry.line( bufnr, id, 'local value = 1' ) entry.close( bufnr, id ) local before = transcript.lines( bufnr ) render.decorate( bufnr, id ) local groups = {} for _, mark in ipairs( render.marks( bufnr ) ) do local group = ( mark[4] or {} ).hl_group if group then groups[group] = true end end assert.is_true( groups['@keyword.lua'] or groups['@variable.lua'] or false, 'no lua highlight was applied: ' .. vim.inspect( vim.tbl_keys( groups ) ) ) assert.same( before, transcript.lines( bufnr ) ) end ) it( 'leaves output alone when no language can be claimed', function() for _, meta in ipairs { { tool = 'bash', args = { command = 'ls', }, }, { tool = 'read', args = { path = '/work/notes.unknownext', }, }, { tool = 'read', args = {}, }, { tool = 'edit', args = { path = '/work/a.lua', }, result = { details = { diff = '+1 x', }, }, }, } do assert.is_nil( tool.language( meta ) ) end assert.equal( 'lua', tool.language { tool = 'read', args = { path = '/work/a.lua', }, result = { content = {}, }, } ) end ) it( 'decorates each kind with its own framing', function() for kind in pairs( entry.kinds ) do assert.is_table( render.frames[kind] ) end end ) end )