Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/tests/bugabinga/pivi/tool_spec.lua

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

-- Shapes recorded from the installed Pi implementation: edit always reports a
-- change, bash reports truncation and a full output path, the search tools
-- report the limit they hit, and write reports nothing.
local EDIT_DIFF = table.concat( {
  ' 1 local function greet(name)',
  '-2   return name',
  '+2   return "hello " .. name',
  '+3   -- added',
  ' 4 end',
}, '\n' )

describe( 'pivi tool', function()
  describe( 'subject', function()
    it( 'names a path relative to the session directory', function()
      assert.equal( 'lua/deep/file.lua', tool.subject {
        tool = 'edit',
        args = { path = '/work/lua/deep/file.lua', },
        cwd = '/work',
      } )
    end )

    it( 'falls back to the basename of a foreign path', function()
      assert.equal( 'file.lua', tool.subject {
        tool = 'read',
        args = { path = '/elsewhere/file.lua', },
        cwd = '/work',
      } )
    end )

    it( 'names a command, a pattern, a tag or a title', function()
      assert.equal( 'ls -la', tool.subject { args = { command = 'ls -la', }, } )
      assert.equal( 'needle', tool.subject { args = { pattern = 'needle', }, } )
      assert.equal( 'quickfix', tool.subject { args = { tag = 'quickfix', }, } )
      assert.equal( 'review', tool.subject { args = { title = 'review', }, } )
    end )

    it( 'collapses whitespace and bounds the length', function()
      local long = tool.subject { args = { command = string.rep( 'x', 200 ), }, }
      assert.is_true( #long <= tool.max_subject + 2 )

      assert.equal( 'a b c', tool.subject { args = { command = 'a  b\tc', }, } )
    end )

    it( 'names nothing when the arguments name nothing', function()
      assert.is_nil( tool.subject { tool = 'nvim_state', args = {}, } )
      assert.is_nil( tool.subject( nil ) )
    end )
  end )

  describe( 'outcome', function()
    it( 'counts what an edit added and removed', function()
      assert.equal( '+2 -1', tool.outcome {
        tool = 'edit',
        result = { details = { diff = EDIT_DIFF, }, },
      } )
    end )

    it( 'reports a truncated result', function()
      assert.equal( 'truncated', tool.outcome {
        tool = 'bash',
        result = { details = { truncation = { truncated = true, }, fullOutputPath = '/tmp/out.log', }, },
      } )
    end )

    it( 'reports the limit a search tool hit', function()
      assert.equal( 'match limit', tool.outcome {
        tool = 'grep',
        result = { details = { matchLimitReached = 100, }, },
      } )
      assert.equal( 'result limit', tool.outcome {
        tool = 'find',
        result = { details = { resultLimitReached = 100, }, },
      } )
      assert.equal( 'entry limit', tool.outcome {
        tool = 'ls',
        result = { details = { entryLimitReached = 500, }, },
      } )
    end )

    it( 'reports a failure whatever the tool reported', function()
      assert.equal( 'failed', tool.outcome { tool = 'bash', failed = true, } )
      assert.equal( 'truncated  failed', tool.outcome {
        tool = 'bash',
        failed = true,
        result = { details = { truncation = { truncated = true, }, }, },
      } )
    end )

    it( 'reports nothing for a tool that reported nothing', function()
      assert.is_nil( tool.outcome { tool = 'write', result = { content = {}, }, } )
      assert.is_nil( tool.outcome { tool = 'read', result = { content = {}, details = nil, }, } )
      assert.is_nil( tool.outcome( nil ) )
    end )

    it( 'ignores a truncation that did not happen', function()
      assert.is_nil( tool.outcome {
        tool = 'read',
        result = { details = { truncation = { truncated = false, }, }, },
      } )
    end )
  end )

  describe( 'the change an edit reported', function()
    it( 'keeps the change as the tool formatted it', function()
      local change = tool.diff { tool = 'edit', result = { details = { diff = EDIT_DIFF .. '\n\n', }, }, }

      assert.equal( EDIT_DIFF, change )
    end )

    it( 'reports no change when none was reported', function()
      assert.is_nil( tool.diff { tool = 'write', result = { content = {}, }, } )
      assert.is_nil( tool.diff { tool = 'edit', result = { details = { diff = '', }, }, } )
    end )

    it( 'distinguishes added from removed lines', function()
      assert.equal( 'DiffAdd', tool.diff_highlight '+2   return "hello"' )
      assert.equal( 'DiffDelete', tool.diff_highlight '-2   return name' )
      assert.is_nil( tool.diff_highlight ' 1 local function greet(name)' )
      assert.is_nil( tool.diff_highlight( nil ) )
    end )

    it( 'shows the change rather than a sentence about it', function()
      local shown = tool.body {
        tool = 'edit',
        result = {
          content = { { type = 'text', text = 'Successfully replaced 1 block(s) in a.lua.', }, },
          details = { diff = EDIT_DIFF, },
        },
      }

      assert.same( vim.split( EDIT_DIFF, '\n', { plain = true, } ), shown )
    end )

    it( 'shows what a tool produced when it reported no change', function()
      assert.same( { 'alpha', 'beta', }, tool.body {
        tool = 'read',
        result = { content = { { type = 'text', text = 'alpha\nbeta\n', }, }, },
      } )
    end )

    it( 'shows a failure when a tool produced nothing at all', function()
      assert.same( { 'failed', }, tool.body { tool = 'bash', failed = true, result = { content = {}, }, } )
      assert.same( {}, tool.body { tool = 'write', result = { content = {}, }, } )
    end )
  end )

  describe( 'icons', function()
    it( 'shows the kind of work rather than the name of the tool', function()
      local glyph = require 'std.icon'

      assert.equal( glyph.edit, tool.icon { tool = 'edit', } )
      assert.equal( glyph.edit, tool.icon { tool = 'write', } )
      assert.equal( glyph.file, tool.icon { tool = 'read', } )
      assert.equal( glyph.shell, tool.icon { tool = 'bash', } )
      assert.equal( glyph.search, tool.icon { tool = 'grep', } )
      assert.equal( glyph.search, tool.icon { tool = 'find', } )
      assert.equal( glyph.folder, tool.icon { tool = 'ls', } )
      assert.equal( glyph.help, tool.icon { tool = 'nvim_help', } )
    end )

    it( 'falls back for a tool it has never heard of', function()
      local glyph = require 'std.icon'

      assert.equal( glyph.command, tool.icon { tool = 'something_new', } )
      assert.equal( glyph.command, tool.icon( nil ) )
    end )
  end )

  describe( 'truncation', function()
    it( 'knows a result was kept only in part', function()
      assert.is_true( tool.truncated {
        tool = 'bash',
        result = { details = { truncation = { truncated = true, }, }, },
      } )
      assert.is_false( tool.truncated {
        tool = 'bash',
        result = { details = { truncation = { truncated = false, }, }, },
      } )
      assert.is_false( tool.truncated { tool = 'write', result = { content = {}, }, } )
    end )

    it( 'knows where the full output still lives', function()
      assert.equal( '/tmp/pi-bash-abc.log', tool.full_output {
        tool = 'bash',
        result = { details = { truncation = { truncated = true, }, fullOutputPath = '/tmp/pi-bash-abc.log', }, },
      } )
      assert.is_nil( tool.full_output { tool = 'read', result = { details = { truncation = {}, }, }, } )
    end )
  end )

  describe( 'lines', function()
    it( 'opens an entry with the tool and what it acted on', function()
      assert.equal( 'edit  a.lua', tool.headline { tool = 'edit', args = { path = 'a.lua', }, } )
      assert.equal( 'nvim_state', tool.headline { tool = 'nvim_state', args = {}, } )
    end )

    it( 'states subject and outcome together for a collapsed entry', function()
      local collapsed = tool.summary {
        tool = 'edit',
        args = { path = 'a.lua', },
        result = { details = { diff = EDIT_DIFF, }, },
      }

      assert.is_true( collapsed:find( 'edit', 1, true ) ~= nil )
      assert.is_true( collapsed:find( 'a.lua', 1, true ) ~= nil )
      assert.is_true( collapsed:find( '+2 -1', 1, true ) ~= nil )
    end )

    it( 'degrades to the subject alone when nothing was reported', function()
      assert.equal( 'write  a.lua', tool.summary { tool = 'write', args = { path = 'a.lua', }, } )
    end )
  end )
end )