_G.key = setmetatable({ set_index_miss_handler = function() end, set_newindex_miss_handler = function() end }, { __call = function() return {} end }) local function assert_markup_format(markup) if #markup == 0 then return end local tag_count = 0 for _ in string.gmatch(markup, '<.->') do tag_count = tag_count + 1 end assert.are_equal(2, tag_count) end local function get_first_part(markup) return string.match(markup, '^(.-)<') end local function get_highlighted_part(markup) return string.match(markup, '>(.-)<') end local function get_last_part(markup) return string.match(markup, '(.-)$') end local function get_prompt_text(markup) return get_first_part(markup)..get_highlighted_part(markup)..get_last_part(markup) end local function get_tag(markup) return string.match(markup, '<.->') end describe('helper functions', function() local sample_markup = 'FirstHighlightedEnd' it('main', function() assert.are_equal('First', get_first_part(sample_markup)) assert.are_equal('Highlighted', get_highlighted_part(sample_markup)) assert.are_equal('End', get_last_part(sample_markup)) assert.are_equal('FirstHighlightedEnd', get_prompt_text(sample_markup)) assert.are_equal('', get_tag(sample_markup)) end) end) describe('helper functions multibyte', function() local sample_markup = 'СперваВысокоосвещенныйКонечный' it('main', function() assert.are_equal('Сперва', get_first_part(sample_markup)) assert.are_equal('Высокоосвещенный', get_highlighted_part(sample_markup)) assert.are_equal('Конечный', get_last_part(sample_markup)) assert.are_equal('СперваВысокоосвещенныйКонечный', get_prompt_text(sample_markup)) assert.are_equal('', get_tag(sample_markup)) end) end) local function enter_text(callback, text) for char in string.gmatch(text, '([%z\1-\127\194-\244][\128-\191]*)') do callback({}, char, 'press') callback({}, char, 'release') end end insulate('main', function () _G.awesome = { connect_signal = function() end } _G.keygrabber = { run = function() end, stop = function() end, } _G.client = { connect_signal = function() end } -- luacheck: globals string function string.wlen(self) local _, string_length = string.gsub(self, "[^\128-\193]", "") local byte = string.byte(self) if ( #self > 0 and string_length == 0 ) or ( byte and ( (byte >= 194 and byte <= 244) ) and string_length == 1 and #self == 1 ) then return -1 end return string_length end local keygrabber = require("awful.keygrabber") package.loaded['awful.keygrabber'] = mock(keygrabber, true) keygrabber = require("awful.keygrabber") local prompt_callback package.loaded['awful.keygrabber'].run = function(g) prompt_callback = g end local gfs = require 'gears.filesystem' package.loaded['gears.filesystem'] = mock(gfs, true) local prompt = require 'awful.prompt' local markup local atextbox = { set_font = function() end, set_markup = function(_, input_markup) markup = input_markup assert_markup_format(markup) end, } local function assert_prompt_text(first_part, highlighted_part, last_part) assert.are_equal(first_part, get_first_part(markup)) assert.are_equal(highlighted_part, get_highlighted_part(markup)) assert.are_equal(last_part, get_last_part(markup)) end describe('basic insertion', function() it('basic command', function() prompt.run{ textbox = atextbox } enter_text(prompt_callback, 'command') assert.are_equal('command ', get_prompt_text(markup)) end) it('escape xml', function() prompt.run{ textbox = atextbox } enter_text(prompt_callback, '<') assert.are_equal('< ', get_prompt_text(markup)) end) end) describe('cancel cases', function() local function assert_cancel(mod, key) local done_callback = stub.new() prompt.run{ textbox = atextbox, done_callback = done_callback } enter_text(prompt_callback, 'command') assert.False(prompt_callback({mod}, key, 'press')) assert.stub(done_callback).was_called() assert.stub(keygrabber.stop).was_called() end it('Ctrl+c', function() assert_cancel('Control', 'c') end) it('Ctrl+g', function() assert_cancel('Control', 'g') end) it('Escape', function() assert_cancel(nil, 'Escape') end) end) describe('execute cases', function() local function assert_execute(mod, key) local done_callback = stub.new() local exe_callback = stub.new() prompt.run{ textbox = atextbox, done_callback = done_callback, exe_callback = exe_callback } enter_text(prompt_callback, 'command') prompt_callback({mod}, key, 'press') assert.stub(done_callback).was_called() assert.spy(exe_callback).was_called_with('command') assert.stub(keygrabber.stop).was_called() end it('Ctrl+j', function() assert_execute('Control', 'j') end) it('Ctrl+m', function() assert_execute('Control', 'm') end) it('Return', function() assert_execute(nil, 'Return') end) it('KP_Enter', function() assert_execute(nil, 'KP_Enter') end) end) describe('typing cases', function() it('moving cursor', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'command') prompt_callback({}, 'Home', 'press') assert_prompt_text('', 'c', 'ommand ') prompt_callback({}, 'Right', 'press') assert_prompt_text('c', 'o', 'mmand ') prompt_callback({}, 'End', 'press') assert_prompt_text('command', ' ', '') prompt_callback({}, 'Left', 'press') assert_prompt_text('comman', 'd', ' ') end) it('moving cursor readline', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'command') prompt_callback({'Control'}, 'a', 'press') assert_prompt_text('', 'c', 'ommand ') prompt_callback({'Control'}, 'f', 'press') assert_prompt_text('c', 'o', 'mmand ') prompt_callback({'Control'}, 'e', 'press') assert_prompt_text('command', ' ', '') prompt_callback({'Control'}, 'b', 'press') assert_prompt_text('comman', 'd', ' ') end) it('moving cursor readline multibyte', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'кокаинум') prompt_callback({'Control'}, 'a', 'press') assert_prompt_text('', 'к', 'окаинум ') prompt_callback({'Control'}, 'f', 'press') assert_prompt_text('к', 'о', 'каинум ') prompt_callback({'Control'}, 'e', 'press') assert_prompt_text('кокаинум', ' ', '') prompt_callback({'Control'}, 'b', 'press') assert_prompt_text('кокаину', 'м', ' ') end) it('backspace', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'command') prompt_callback({}, 'BackSpace', 'press') assert_prompt_text('comman', ' ', '') prompt_callback({}, 'Home', 'press') prompt_callback({}, 'BackSpace', 'press') assert_prompt_text('', 'c', 'omman ') prompt_callback({}, 'Right', 'press') prompt_callback({}, 'BackSpace', 'press') assert_prompt_text('', 'o', 'mman ') prompt_callback({}, 'Right', 'press') prompt_callback({}, 'Right', 'press') prompt_callback({}, 'BackSpace', 'press') assert_prompt_text('o', 'm', 'an ') end) it('backspace multibyte', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'кокаинум') prompt_callback({}, 'BackSpace', 'press') assert_prompt_text('кокаину', ' ', '') prompt_callback({}, 'Home', 'press') prompt_callback({}, 'BackSpace', 'press') assert_prompt_text('', 'к', 'окаину ') --@TODO: Left/Right not yet implemented for multibyte chars --prompt_callback({}, 'Right', 'press') --prompt_callback({}, 'BackSpace', 'press') --assert_prompt_text('', 'о', 'каину ') --prompt_callback({}, 'Right', 'press') --prompt_callback({}, 'Right', 'press') --prompt_callback({}, 'BackSpace', 'press') --assert_prompt_text('о', 'а', 'ину ') end) it('backspace readline', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'command') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('comman', ' ', '') prompt_callback({'Control'}, 'a', 'press') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('', 'c', 'omman ') prompt_callback({'Control'}, 'f', 'press') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('', 'o', 'mman ') prompt_callback({'Control'}, 'f', 'press') prompt_callback({'Control'}, 'f', 'press') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('o', 'm', 'an ') end) it('backspace readline multibyte', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'кокаинум') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('кокаину', ' ', '') prompt_callback({'Control'}, 'a', 'press') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('', 'к', 'окаину ') prompt_callback({'Control'}, 'f', 'press') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('', 'о', 'каину ') prompt_callback({'Control'}, 'f', 'press') prompt_callback({'Control'}, 'f', 'press') prompt_callback({'Control'}, 'h', 'press') assert_prompt_text('о', 'а', 'ину ') end) it('delete', function() prompt.run{ textbox = atextbox, } enter_text(prompt_callback, 'command') prompt_callback({}, 'Delete', 'press') assert_prompt_text('command', ' ', '') prompt_callback({}, 'Left', 'press') prompt_callback({}, 'Delete', 'press') assert_prompt_text('comman', ' ', '') prompt_callback({}, 'Home', 'press') prompt_callback({}, 'Delete', 'press') assert_prompt_text('', 'o', 'mman ') prompt_callback({}, 'Right', 'press') prompt_callback({}, 'Right', 'press') prompt_callback({}, 'Delete', 'press') assert_prompt_text('om', 'a', 'n ') end) end) describe('key-pressed callback', function() it('callback called with right arguments', function() local keypressed_callback = spy.new(function() return true end) prompt.run{ textbox = atextbox, keypressed_callback = keypressed_callback, } prompt_callback({'Control'}, 'x', 'press') assert.spy(keypressed_callback).was_called_with({['Control'] = true}, 'x', '') end) it('callback intercepts input', function() local keypressed_callback = spy.new(function() return true end) prompt.run{ textbox = atextbox, keypressed_callback = keypressed_callback, } enter_text(prompt_callback, 'a') assert.spy(keypressed_callback).was_called_with({}, 'a', '') assert.are_equal(' ', get_prompt_text(markup)) end) it('callback returns new prompt and command', function() local keypressed_callback = spy.new(function() return true, 'new_command', 'new_prompt:' end) prompt.run{ textbox = atextbox, keypressed_callback = keypressed_callback, } enter_text(prompt_callback, 'a') assert.spy(keypressed_callback).was_called_with({}, 'a', '') assert.are_equal('new_prompt:new_command ', get_prompt_text(markup)) end) end) describe('key-released callback', function() local keyreleased_callback = stub.new() it('callback called with mods', function() prompt.run{ textbox = atextbox, keyreleased_callback = keyreleased_callback, } prompt_callback({'Control'}, 'x', 'release') assert.stub(keyreleased_callback).was_called_with({['Control'] = true}, 'x', '') end) it('callbacks called with command', function() prompt.run{ textbox = atextbox, keyreleased_callback = keyreleased_callback, } enter_text(prompt_callback, 'com') assert.stub(keyreleased_callback).was_called_with({}, 'c', 'c') assert.stub(keyreleased_callback).was_called_with({}, 'o', 'co') assert.stub(keyreleased_callback).was_called_with({}, 'm', 'com') end) end) describe('hooks', function() it('callback called', function() local callback_arg = '' local callback = function(arg) callback_arg = arg end prompt.run{ textbox = atextbox, hooks = { { {'Shift'}, "Return", callback } } } enter_text(prompt_callback, 'command') prompt_callback({'Shift'}, 'Return', 'press') assert.are_equal('command', callback_arg) end) end) end) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80