---@diagnostic disable: duplicate-set-field, need-check-nil, param-type-mismatch, assign-type-mismatch local dialog = require 'bugabinga.pivi.dialog' describe( 'pivi dialog', function() local original_select, original_input, original_notify before_each( function() original_select = vim.ui.select original_input = vim.ui.input original_notify = vim.notify end ) after_each( function() vim.ui.select = original_select vim.ui.input = original_input vim.notify = original_notify dialog.reset() end ) local collect = function() local answers = {} return answers, function( response ) table.insert( answers, response ) end end it( 'ignores frames that are not extension ui requests', function() local _, respond = collect() assert.is_false( dialog.handle( { type = 'agent_start', }, respond ) ) end ) it( 'answers a selection with the request identifier', function() local offered vim.ui.select = function( items, _, on_choice ) offered = items on_choice( items[2] ) end local answers, respond = collect() local handled = dialog.handle( { type = 'extension_ui_request', id = 'uuid-1', method = 'select', title = 'Allow dangerous command?', options = { 'Allow', 'Block', }, }, respond ) assert.is_true( handled ) assert.same( { 'Allow', 'Block', }, offered ) assert.equal( 'extension_ui_response', answers[1].type ) assert.equal( 'uuid-1', answers[1].id ) assert.equal( 'Block', answers[1].value ) end ) it( 'answers a dismissed dialog as cancelled', function() vim.ui.select = function( _, _, on_choice ) on_choice( nil ) end local answers, respond = collect() dialog.handle( { type = 'extension_ui_request', id = 'uuid-2', method = 'select', title = 'pick', options = { 'a', }, }, respond ) assert.is_true( answers[1].cancelled ) assert.is_nil( answers[1].value ) end ) it( 'answers a confirmation with a boolean', function() vim.ui.select = function( _, _, on_choice ) on_choice 'yes' end local answers, respond = collect() dialog.handle( { type = 'extension_ui_request', id = 'uuid-3', method = 'confirm', title = 'Clear session?', message = 'All messages will be lost.', }, respond ) assert.is_true( answers[1].confirmed ) assert.equal( 'uuid-3', answers[1].id ) end ) it( 'answers text input and editor requests', function() vim.ui.input = function( options, on_confirm ) on_confirm( ( options.default or '' ) .. '!' ) end local answers, respond = collect() dialog.handle( { type = 'extension_ui_request', id = 'uuid-4', method = 'input', title = 'Enter a value', placeholder = 'seed', }, respond ) dialog.handle( { type = 'extension_ui_request', id = 'uuid-5', method = 'editor', title = 'Edit text', prefill = 'draft', }, respond ) assert.equal( 'seed!', answers[1].value ) assert.equal( 'uuid-4', answers[1].id ) assert.equal( 'draft!', answers[2].value ) assert.equal( 'uuid-5', answers[2].id ) end ) it( 'shows a notification without answering', function() local seen = {} vim.notify = function( message, level ) table.insert( seen, { message, level, } ) end local answers, respond = collect() local handled = dialog.handle( { type = 'extension_ui_request', id = 'uuid-6', method = 'notify', message = 'Command blocked by user', notifyType = 'warning', }, respond ) assert.is_true( handled ) assert.equal( 0, #answers ) assert.equal( 'Command blocked by user', seen[1][1] ) assert.equal( vim.log.levels.WARN, seen[1][2] ) end ) it( 'keeps status and widget entries without answering', function() local answers, respond = collect() dialog.handle( { type = 'extension_ui_request', id = 'uuid-7', method = 'setStatus', statusKey = 'ext', statusText = 'Turn 3 running...', }, respond ) dialog.handle( { type = 'extension_ui_request', id = 'uuid-8', method = 'setWidget', widgetKey = 'ext', widgetLines = { 'line one', 'line two', }, }, respond ) assert.equal( 0, #answers ) assert.equal( 'Turn 3 running...', dialog.statuses().ext ) assert.same( { 'line one', 'line two', }, dialog.widgets().ext ) dialog.handle( { type = 'extension_ui_request', id = 'uuid-9', method = 'setStatus', statusKey = 'ext', }, respond ) assert.is_nil( dialog.statuses().ext ) end ) it( 'reports an unsupported method as unhandled', function() local _, respond = collect() assert.is_false( dialog.handle( { type = 'extension_ui_request', id = 'uuid-10', method = 'custom', }, respond ) ) end ) end )