---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch, redundant-parameter local compose = require 'bugabinga.pivi.compose' local temp_file = function( lines, suffix ) local path = vim.fs.normalize( vim.fn.tempname() .. ( suffix or '.lua' ) ) vim.fn.writefile( lines, path ) return path end describe( 'pivi compose', function() after_each( function() vim.cmd 'silent! %bwipeout!' end ) describe( 'what was written', function() it( 'reads a leading bang as a command to run', function() local intent = compose.parse '!just test' assert.equal( 'bash', intent.kind ) assert.equal( 'just test', intent.command ) assert.is_false( intent.exclude ) end ) it( 'reads a doubled bang as a command kept out of the conversation', function() local intent = compose.parse '!!git status' assert.equal( 'bash', intent.kind ) assert.equal( 'git status', intent.command ) assert.is_true( intent.exclude ) end ) it( 'tolerates space after the bang', function() assert.equal( 'ls -la', compose.parse( '! ls -la' ).command ) assert.equal( 'ls', compose.parse( ' !! ls ' ).command ) end ) it( 'reads anything else as something said', function() local intent = compose.parse 'rename greet to hail' assert.equal( 'prompt', intent.kind ) assert.equal( 'rename greet to hail', intent.message ) end ) it( 'does not mistake a bang inside a sentence for a command', function() assert.equal( 'prompt', compose.parse( 'fix this!' ).kind ) assert.equal( 'prompt', compose.parse( 'why not use !! here' ).kind ) end ) end ) describe( 'what was referred to', function() it( 'names every reference', function() assert.same( { 'a.lua', 'src/b.lua', }, compose.references 'compare @a.lua with @src/b.lua' ) assert.same( {}, compose.references 'nothing here' ) end ) it( 'replaces a reference with the file itself', function() local path = temp_file { 'local value = 1', } local message, images, missing = compose.expand( 'look at @' .. path ) assert.same( {}, missing ) assert.same( {}, images ) assert.is_true( message:find( '', 1, true ) ~= nil ) assert.is_true( message:find( 'local value = 1', 1, true ) ~= nil ) assert.is_true( message:find( '', 1, true ) ~= nil ) end ) it( 'prefers what the buffer holds over what the file holds', function() local path = temp_file { 'on disk', } vim.cmd( 'edit! ' .. vim.fn.fnameescape( path ) ) vim.api.nvim_buf_set_lines( 0, 0, -1, false, { 'not saved yet', } ) local message = compose.expand( 'read @' .. path ) assert.is_true( message:find( 'not saved yet', 1, true ) ~= nil ) assert.is_nil( message:find( 'on disk', 1, true ) ) end ) it( 'resolves a relative reference against the session directory', function() local path = temp_file { 'relative', } local directory = vim.fs.dirname( path ) local message = compose.expand( '@' .. vim.fs.basename( path ), { cwd = directory, } ) assert.is_true( message:find( 'relative', 1, true ) ~= nil ) end ) it( 'attaches an image rather than inlining it', function() local path = vim.fs.normalize( vim.fn.tempname() .. '.png' ) local write = io.open( path, 'wb' ) write:write '\137PNG\r\n\26\n fake but binary' write:close() local message, images = compose.expand( 'see @' .. path ) assert.equal( 1, #images ) assert.equal( 'image/png', images[1].mimeType ) assert.equal( 'image', images[1].type ) assert.is_true( #images[1].data > 0 ) assert.is_true( message:find( '', 1, true ) ~= nil ) end ) it( 'reports a reference it cannot read and leaves it written', function() local absent = vim.fn.tempname() .. '-absent.lua' local message, _, missing = compose.expand( 'read @' .. absent ) assert.equal( 1, #missing ) assert.is_true( message:find( '@' .. absent, 1, true ) ~= nil ) end ) it( 'includes a file once however often it is named', function() local path = temp_file { 'once', } local message = compose.expand( ( '@%s and @%s' ):format( path, path ) ) local count = select( 2, message:gsub( 'once', '' ) ) assert.equal( 1, count ) end ) it( 'leaves text without references alone', function() local message, images, missing = compose.expand 'just words' assert.equal( 'just words', message ) assert.same( {}, images ) assert.same( {}, missing ) end ) end ) end )