Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/tests/bugabinga/pivi/context_spec.lua

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

local scratch = function( lines )
  vim.cmd 'enew'
  local bufnr = vim.api.nvim_get_current_buf()
  vim.api.nvim_buf_set_name( bufnr, vim.fn.tempname() .. '.lua' )
  vim.api.nvim_buf_set_lines( bufnr, 0, -1, false, lines )
  return bufnr
end

describe( 'pivi context', function()
  after_each( function()
    vim.cmd 'silent! %bwipeout!'
  end )

  it( 'captures buffer identity, revision, and cursor', function()
    local bufnr = scratch { 'one', 'two', 'three', }
    vim.api.nvim_win_set_cursor( 0, { 2, 1, } )

    local shot = context.snapshot()

    assert.equal( bufnr, shot.buffer )
    assert.equal( vim.api.nvim_buf_get_changedtick( bufnr ), shot.revision )
    assert.equal( 2, shot.cursor[1] )
    assert.equal( 1, shot.cursor[2] )
    assert.equal( 3, shot.line_count )
  end )

  it( 'captures unsaved content', function()
    local bufnr = scratch { 'unsaved line', }
    local shot = context.snapshot()

    assert.is_true( shot.modified )
    assert.is_true( shot.surrounding:find( 'unsaved line', 1, true ) ~= nil )
  end )

  it( 'refuses mutation of a snapshot', function()
    scratch { 'a', }
    local shot = context.snapshot()
    assert.has_error( function() shot.path = 'elsewhere' end )
    assert.has_error( function() shot.cursor[1] = 99 end )
  end )

  it( 'keeps its own values when the buffer changes later', function()
    local bufnr = scratch { 'before', }
    local shot = context.snapshot()
    local revision = shot.revision

    vim.api.nvim_buf_set_lines( bufnr, 0, -1, false, { 'after', 'more', } )

    assert.equal( revision, shot.revision )
    assert.equal( 1, shot.line_count )
    assert.is_true( shot.surrounding:find( 'before', 1, true ) ~= nil )
    assert.is_nil( shot.surrounding:find( 'after', 1, true ) )
  end )

  it( 'captures a selected range and its text', function()
    scratch { 'one', 'two', 'three', }
    local shot = context.snapshot { range = { kind = 'V', first = { 1, 0, }, last = { 2, 0, }, }, }

    assert.equal( 'V', shot.selection_kind )
    assert.equal( 'one\ntwo', shot.selected_text )
  end )

  it( 'renders a stable prompt preamble', function()
    scratch { 'one', 'two', }
    local rendered = context.render( context.snapshot() )

    assert.is_true( rendered:find( '<editor-context>', 1, true ) == 1 )
    assert.is_true( rendered:find( 'revision:', 1, true ) ~= nil )
    assert.is_true( rendered:find( '</editor-context>', 1, true ) ~= nil )
  end )

  it( 'renders nothing without a snapshot', function()
    assert.equal( '', context.render( nil ) )
  end )

  it( 'skips buffers that are not editable files', function()
    local bufnr = vim.api.nvim_create_buf( false, true )
    vim.bo[bufnr].buftype = 'nofile'
    assert.is_nil( context.snapshot { bufnr = bufnr, } )
  end )

  describe( 'visible view', function()
    it( 'captures only the region the user can see', function()
      local many = {}
      for index = 1, 500 do many[index] = 'line ' .. index end
      scratch( many )
      vim.api.nvim_win_set_cursor( 0, { 250, 0, } )
      vim.cmd 'normal! zz'

      local view = context.visible()

      assert.is_true( view.first_line >= 1 )
      assert.is_true( view.last_line <= 500 )
      assert.equal( 500, view.line_count )
      assert.equal( view.last_line - view.first_line + 1, #view.lines )
      assert.is_true( #view.lines < 500 )
      assert.is_true( #view.lines <= context.visible_lines )
    end )

    it( 'describes the current buffer, cursor, and mode', function()
      local bufnr = scratch { 'alpha', 'beta', }
      vim.api.nvim_win_set_cursor( 0, { 2, 1, } )

      local view = context.visible()

      assert.equal( bufnr, view.buffer )
      assert.equal( 2, view.cursor[1] )
      assert.is_true( view.modified )
      assert.is_string( view.mode )
      assert.is_string( view.cwd )
    end )

    it( 'lists the windows of the current tabpage', function()
      scratch { 'one', }
      vim.cmd 'vsplit'
      local view = context.visible()
      vim.cmd 'only'

      assert.is_true( #view.windows >= 2 )
      local current = 0
      for _, entry in ipairs( view.windows ) do
        if entry.current then current = current + 1 end
      end
      assert.equal( 1, current )
    end )

    it( 'renders a bounded numbered preamble', function()
      scratch { 'alpha', 'beta', }
      local rendered = context.render_visible( context.visible() )

      assert.is_true( rendered:find( '<editor-view>', 1, true ) == 1 )
      assert.is_true( rendered:find( 'on screen (lines', 1, true ) ~= nil )
      assert.is_true( rendered:find( '1\talpha', 1, true ) ~= nil )
      assert.is_true( rendered:find( '</editor-view>', 1, true ) ~= nil )
    end )

    it( 'renders nothing without a view', function()
      assert.equal( '', context.render_visible( nil ) )
    end )

    it( 'carries recent messages and the last error', function()
      vim.v.errmsg = 'E42: something broke'
      vim.api.nvim_echo( { { 'a distinctive notice', }, }, true, {} )
      scratch { 'x', }

      local rendered = context.render_visible( context.visible() )

      assert.is_true( rendered:find( 'E42: something broke', 1, true ) ~= nil )
      assert.is_true( rendered:find( 'a distinctive notice', 1, true ) ~= nil )
      vim.v.errmsg = ''
    end )
  end )

  it( 'reports ambient editor state on demand', function()
    local bufnr = scratch { 'ambient', }
    local state = context.editor()

    assert.equal( bufnr, state.current_buffer )
    assert.is_string( state.mode )
    assert.is_true( #state.buffers > 0 )
    assert.is_true( #state.windows > 0 )

    local found = false
    for _, entry in ipairs( state.buffers ) do
      if entry.buffer == bufnr then
        found = true
        assert.is_true( entry.modified )
      end
    end
    assert.is_true( found )
  end )
end )