Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/tests/bugabinga/pivi/editor/publish_spec.lua

Raw
---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch
local publish = require 'bugabinga.pivi.publish'
local status = require 'bugabinga.pivi.status'

describe( 'pivi publish', function()
  after_each( function()
    publish.reset()
  end )

  it( 'reports nothing when pivi never published anything', function()
    vim.g[publish.variable] = nil
    assert.equal( '', publish.summary() )
    assert.same( {}, publish.read().sessions )
  end )

  it( 'caches one session status in a native variable', function()
    local state = status.reduce( status.initial(), { type = 'agent_start', } )
    publish.session_status( 'work', state )

    local cached = publish.read()
    assert.equal( 'work', cached.active )
    assert.equal( 'running', cached.sessions.work.run )
    assert.equal( 'pi:run', cached.sessions.work.summary )
  end )

  it( 'announces a change through a semantic user event', function()
    local seen = {}
    local group = vim.api.nvim_create_augroup( 'pivi_publish_spec', { clear = true, } )
    vim.api.nvim_create_autocmd( 'User', {
      group = group,
      pattern = publish.status_pattern,
      callback = function( event ) table.insert( seen, event.data ) end,
    } )

    publish.session_status( 'work', status.initial() )

    assert.equal( 1, #seen )
    assert.equal( 'work', seen[1].session )
    assert.equal( 'pi:idle', seen[1].status.summary )

    vim.api.nvim_del_augroup_by_id( group )
  end )

  it( 'lets a consumer read cached status without any process', function()
    publish.session_status( 'work', status.reduce( status.initial(), {
      type = 'tool_execution_start',
      toolCallId = 'c1',
      toolName = 'grep',
    } ) )

    local statusline = function() return publish.summary 'work' end

    assert.equal( 'pi:grep', statusline() )
    assert.equal( 'pi:grep', statusline() )
  end )

  it( 'degrades to an empty statusline for an unknown session', function()
    publish.session_status( 'work', status.initial() )
    assert.equal( '', publish.summary 'absent' )
  end )

  it( 'moves the active session and forgets a removed one', function()
    publish.session_status( 'one', status.initial() )
    publish.session_status( 'two', status.initial() )
    assert.equal( 'one', publish.read().active )

    publish.set_active 'two'
    assert.equal( 'two', publish.read().active )

    publish.remove 'two'
    assert.equal( 'one', publish.read().active )
    assert.is_nil( publish.read().sessions.two )
  end )

  it( 'forwards model, thinking, context, cost and tokens to consumers', function()
    local state = status.reduce_stats(
      status.reduce_state( status.initial(), {
        model = { id = 'gpt-5.6-luna', }, thinkingLevel = 'high',
      } ),
      {
        cost = 2.67,
        tokens = { input = 88, output = 17000, total = 17088, },
        contextUsage = { percent = 1, contextWindow = 262000, },
      }
    )
    publish.session_status( 'work', state )

    local cached = publish.read().sessions.work
    assert.equal( 'gpt-5.6-luna', cached.model )
    assert.equal( 'high', cached.thinking )
    assert.equal( 2.67, cached.cost )
    assert.equal( 17000, cached.tokens.output )
    assert.equal( 1, cached.context.percent )
  end )

  it( 'passes extension status and widgets through by key, free of ansi', function()
    publish.session_status( 'work', status.initial(), {
      status = { ['context-size'] = '\27[38;5;8m\u{2500}\u{2500}\u{2500}\27[39m 0% 0k/262k', },
      widget = { rate = { '\27[32m99.3/s\27[0m', 'line two', }, },
    } )

    local cached = publish.read().sessions.work
    assert.equal( '\u{2500}\u{2500}\u{2500} 0% 0k/262k', cached.ext.status['context-size'] )
    assert.same( { '99.3/s', 'line two', }, cached.ext.widget.rate )
  end )

  it( 'omits extension entries when none were reported', function()
    publish.session_status( 'work', status.initial() )
    assert.is_nil( publish.read().sessions.work.ext )
  end )

  it( 'announces activity separately from status', function()
    local seen = {}
    local group = vim.api.nvim_create_augroup( 'pivi_publish_activity_spec', { clear = true, } )
    vim.api.nvim_create_autocmd( 'User', {
      group = group,
      pattern = publish.activity_pattern,
      callback = function( event ) table.insert( seen, event.data ) end,
    } )

    publish.activity { kind = 'findings', count = 2, }

    assert.equal( 1, #seen )
    assert.equal( 'findings', seen[1].kind )

    vim.api.nvim_del_augroup_by_id( group )
  end )
end )