---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch local status = require 'bugabinga.pivi.status' local fold = function( events ) local state = status.initial() for _, event in ipairs( events ) do state = status.reduce( state, event ) end return state end describe( 'pivi status', function() it( 'starts idle and disconnected from any run', function() local state = status.initial() assert.equal( 'idle', state.run ) assert.is_false( status.is_busy( state ) ) assert.equal( 'pi:idle', status.summary( state ) ) end ) it( 'never mutates the state it folds', function() local before = status.initial() local after = status.reduce( before, { type = 'agent_start', } ) assert.equal( 'idle', before.run ) assert.equal( 'running', after.run ) end ) it( 'tracks a run from start to settlement', function() local state = fold { { type = 'agent_start', }, { type = 'tool_execution_start', toolCallId = 'c1', toolName = 'bash', }, } assert.is_true( status.is_busy( state ) ) assert.equal( 'bash', state.tool.name ) assert.equal( 'pi:bash', status.summary( state ) ) state = status.reduce( state, { type = 'tool_execution_end', toolCallId = 'c1', } ) assert.is_nil( state.tool ) state = status.reduce( state, { type = 'agent_settled', } ) assert.equal( 'idle', state.run ) assert.is_false( status.is_busy( state ) ) end ) it( 'stays busy between agent_end and agent_settled', function() local state = fold { { type = 'agent_start', }, { type = 'agent_end', willRetry = false, }, } assert.is_true( status.is_busy( state ) ) end ) it( 'reports queued steering and follow-up messages', function() local state = fold { { type = 'queue_update', steering = { 'focus on errors', }, followUp = { 'summarize', }, }, } assert.equal( 2, status.pending_count( state ) ) assert.equal( 'pi:idle+2', status.summary( state ) ) end ) it( 'tracks retry and clears it on success', function() local state = fold { { type = 'auto_retry_start', attempt = 1, maxAttempts = 3, delayMs = 2000, errorMessage = 'overloaded', }, } assert.equal( 'retrying', state.run ) assert.equal( 'pi:retry', status.summary( state ) ) state = status.reduce( state, { type = 'auto_retry_end', success = true, attempt = 2, } ) assert.equal( 'running', state.run ) assert.is_nil( state.error ) end ) it( 'keeps the final error when retry gives up', function() local state = fold { { type = 'auto_retry_start', attempt = 3, maxAttempts = 3, }, { type = 'auto_retry_end', success = false, attempt = 3, finalError = '529 overloaded', }, } assert.equal( 'idle', state.run ) assert.equal( '529 overloaded', state.error ) assert.equal( 'pi:error', status.summary( state ) ) end ) it( 'tracks compaction', function() local state = fold { { type = 'compaction_start', reason = 'threshold', }, } assert.is_true( state.compacting ) assert.equal( 'pi:compacting', status.summary( state ) ) state = status.reduce( state, { type = 'compaction_end', reason = 'threshold', } ) assert.is_false( state.compacting ) end ) it( 'surfaces a provider error reported on a finished message', function() local lines = vim.fn.readfile 'tests/fixtures/pivi/rpc-provider-error.jsonl' local recorded = vim.json.decode( lines[7] ) local state = status.reduce( status.initial(), recorded ) assert.is_string( state.error ) assert.equal( 'pi:error', status.summary( state ) ) end ) it( 'folds a get_state payload without contacting pi', function() local lines = vim.fn.readfile 'tests/fixtures/pivi/rpc-no-llm.jsonl' local recorded = vim.json.decode( lines[1] ) local state = status.reduce_state( status.initial(), recorded.data ) assert.equal( 'running', state.connection ) assert.is_string( state.model ) assert.is_string( state.thinking ) end ) it( 'reports a stopped process', function() local state = status.stopped( status.initial(), 1 ) assert.equal( 'stopped', state.connection ) assert.equal( 1, state.exit_code ) assert.equal( 'pi:off', status.summary( state ) ) end ) it( 'ignores malformed events', function() local state = status.reduce( status.initial(), 'nonsense' ) assert.equal( 'idle', state.run ) end ) end )