2018-12-31 07:10:35 +01:00
|
|
|
|
_G.key = setmetatable({
|
|
|
|
|
set_index_miss_handler = function() end,
|
|
|
|
|
set_newindex_miss_handler = function() end
|
|
|
|
|
}, {
|
|
|
|
|
__call = function() return {} end
|
|
|
|
|
})
|
|
|
|
|
|
2017-07-14 21:32:21 +02:00
|
|
|
|
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, '</span>(.-)$')
|
|
|
|
|
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 = 'First<span property1="foo">Highlighted</span>End'
|
|
|
|
|
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('<span property1="foo">', get_tag(sample_markup))
|
|
|
|
|
end)
|
|
|
|
|
end)
|
2021-06-11 03:17:00 +02:00
|
|
|
|
describe('helper functions multibyte', function()
|
|
|
|
|
local sample_markup = 'Сперва<span property1="foo">Высокоосвещенный</span>Конечный'
|
|
|
|
|
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('<span property1="foo">', get_tag(sample_markup))
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
2017-07-14 21:32:21 +02:00
|
|
|
|
|
|
|
|
|
local function enter_text(callback, text)
|
2021-06-11 03:17:00 +02:00
|
|
|
|
for char in string.gmatch(text, '([%z\1-\127\194-\244][\128-\191]*)') do
|
2017-07-14 21:32:21 +02:00
|
|
|
|
callback({}, char, 'press')
|
|
|
|
|
callback({}, char, 'release')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
insulate('main', function ()
|
|
|
|
|
_G.awesome = {
|
|
|
|
|
connect_signal = function() end
|
|
|
|
|
}
|
2018-07-22 22:10:46 +02:00
|
|
|
|
_G.keygrabber = {
|
|
|
|
|
run = function() end,
|
|
|
|
|
stop = function() end,
|
|
|
|
|
}
|
2019-12-02 01:58:51 +01:00
|
|
|
|
_G.client = {
|
|
|
|
|
connect_signal = function() end
|
|
|
|
|
}
|
2017-07-14 21:32:21 +02:00
|
|
|
|
-- luacheck: globals string
|
|
|
|
|
function string.wlen(self)
|
2021-06-11 03:17:00 +02:00
|
|
|
|
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
|
2017-07-14 21:32:21 +02:00
|
|
|
|
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)
|
2021-06-11 03:17:00 +02:00
|
|
|
|
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)
|
2017-07-14 21:32:21 +02:00
|
|
|
|
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)
|
2021-06-11 03:17:00 +02:00
|
|
|
|
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)
|
2017-07-14 21:32:21 +02:00
|
|
|
|
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
|