repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/tests/bugabinga/pivi/backfill_spec.lua
Raw---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch
local backfill = require 'bugabinga.pivi.backfill'
local entries = function( list ) return { entries = list, } end
local message = function( role, content, extra )
return { type = 'message', message = vim.tbl_extend( 'force', { role = role, content = content, }, extra or {} ), }
end
describe( 'pivi backfill', function()
it( 'plans nothing from empty or malformed history', function()
assert.same( {}, backfill.plan( nil ) )
assert.same( {}, backfill.plan( {} ) )
assert.same( {}, backfill.plan( entries { { type = 'model_change', }, } ) )
end )
it( 'turns a user message into a prompt op', function()
local ops = backfill.plan( entries { message( 'user', 'hello there' ), } )
assert.equal( 1, #ops )
assert.equal( 'prompt', ops[1].kind )
assert.equal( 'hello there', ops[1].text )
end )
it( 'reads user text from content parts as well as a bare string', function()
local ops = backfill.plan( entries {
message( 'user', { { type = 'text', text = 'part one ', }, { type = 'text', text = 'part two', }, } ),
} )
assert.equal( 'part one part two', ops[1].text )
end )
it( 'turns assistant text into an answer op', function()
local ops = backfill.plan( entries {
message( 'assistant', { { type = 'text', text = 'the answer', }, } ),
} )
assert.equal( 'answer', ops[1].kind )
assert.equal( 'the answer', ops[1].text )
end )
it( 'pairs a tool call with its result by call id', function()
local ops = backfill.plan( entries {
message( 'assistant', {
{ type = 'tool_call', id = 'c1', name = 'nu', arguments = { command = 'ls', }, },
} ),
message( 'toolResult', { { type = 'text', text = 'file.txt', }, }, {
toolCallId = 'c1', toolName = 'nu', isError = false,
} ),
} )
assert.equal( 1, #ops )
local call = ops[1]
assert.equal( 'tool', call.kind )
assert.equal( 'nu', call.tool )
assert.equal( 'ls', call.args.command )
assert.equal( 'c1', call.call )
assert.same( { { type = 'text', text = 'file.txt', }, }, call.result.content )
assert.is_false( call.failed )
end )
it( 'marks a failed tool result', function()
local ops = backfill.plan( entries {
message( 'assistant', { { type = 'tool_call', id = 'c9', name = 'nu', arguments = {}, }, } ),
message( 'toolResult', { { type = 'text', text = 'boom', }, }, { toolCallId = 'c9', isError = true, } ),
} )
assert.is_true( ops[1].failed )
end )
it( 'keeps text before and after a tool call as separate answer ops', function()
local ops = backfill.plan( entries {
message( 'assistant', {
{ type = 'text', text = 'before', },
{ type = 'tool_call', id = 'c1', name = 'nu', arguments = {}, },
{ type = 'text', text = 'after', },
} ),
} )
assert.equal( 'answer', ops[1].kind )
assert.equal( 'before', ops[1].text )
assert.equal( 'tool', ops[2].kind )
assert.equal( 'answer', ops[3].kind )
assert.equal( 'after', ops[3].text )
end )
it( 'orders a whole conversation as it happened', function()
local ops = backfill.plan( entries {
{ type = 'model_change', },
message( 'user', 'do it' ),
message( 'assistant', { { type = 'text', text = 'working', }, { type = 'tool_call', id = 'c1', name = 'nu', arguments = {}, }, } ),
message( 'toolResult', { { type = 'text', text = 'done', }, }, { toolCallId = 'c1', } ),
message( 'assistant', { { type = 'text', text = 'finished', }, } ),
} )
local kinds = vim.tbl_map( function( op ) return op.kind end, ops )
assert.same( { 'prompt', 'answer', 'tool', 'answer', }, kinds )
end )
end )