add a cool lua repl
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
|
||||
plan(8)
|
||||
|
||||
do -- getprompt tests {{{
|
||||
is(repl:getprompt(1), '>')
|
||||
is(repl:getprompt(2), '>>')
|
||||
end -- }}}
|
||||
|
||||
do -- prompt abstract tests {{{
|
||||
error_like(function()
|
||||
repl:prompt(1)
|
||||
end, 'You must implement the showprompt method')
|
||||
|
||||
error_like(function()
|
||||
repl:prompt(2)
|
||||
end, 'You must implement the showprompt method')
|
||||
end -- }}}
|
||||
|
||||
do -- name tests {{{
|
||||
is(repl:name(), 'REPL')
|
||||
end -- }}}
|
||||
|
||||
do -- handleline abstract tests {{{
|
||||
is(_G.testresult, nil)
|
||||
error_like(function()
|
||||
repl:handleline '_G.testresult = 17'
|
||||
end, 'You must implement the displayresults method')
|
||||
is(_G.testresult, 17)
|
||||
end -- }}}
|
||||
@@ -0,0 +1,119 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
|
||||
plan(45)
|
||||
|
||||
local clone = repl:clone()
|
||||
local prompt
|
||||
local results
|
||||
local errmsg
|
||||
|
||||
isnt(type(clone), 'nil')
|
||||
|
||||
function clone:showprompt(p)
|
||||
prompt = p
|
||||
end
|
||||
|
||||
function clone:displayresults(r)
|
||||
results = r
|
||||
end
|
||||
|
||||
function clone:displayerror(err)
|
||||
errmsg = err
|
||||
end
|
||||
|
||||
do -- prompt tests {{{
|
||||
lives_ok(function()
|
||||
clone:prompt(1)
|
||||
end)
|
||||
|
||||
is(prompt, '>')
|
||||
|
||||
lives_ok(function()
|
||||
clone:prompt(2)
|
||||
end)
|
||||
|
||||
is(prompt, '>>')
|
||||
end -- }}}
|
||||
|
||||
do -- handleline tests {{{
|
||||
is(_G.testresult, nil)
|
||||
is(results, nil)
|
||||
|
||||
lives_ok(function()
|
||||
clone:handleline '_G.testresult = 18'
|
||||
end)
|
||||
|
||||
is(_G.testresult, 18)
|
||||
|
||||
is(type(results), 'table')
|
||||
is(results.n, 0)
|
||||
is(#results, 0)
|
||||
|
||||
lives_ok(function()
|
||||
clone:handleline 'return 19'
|
||||
end)
|
||||
|
||||
is(type(results), 'table')
|
||||
is(results.n, 1)
|
||||
is(#results, 1)
|
||||
is(results[1], 19)
|
||||
|
||||
lives_ok(function()
|
||||
clone:handleline 'return 20, 21, 22'
|
||||
end)
|
||||
|
||||
is(type(results), 'table')
|
||||
is(results.n, 3)
|
||||
is(#results, 3)
|
||||
is(results[1], 20)
|
||||
is(results[2], 21)
|
||||
is(results[3], 22)
|
||||
|
||||
lives_ok(function()
|
||||
clone:handleline 'return 1, nil, nil, nil, nil, nil, nil, 2'
|
||||
end)
|
||||
|
||||
is(type(results), 'table')
|
||||
is(results.n, 8)
|
||||
is(results[1], 1)
|
||||
for i = 2, 7 do
|
||||
is(results[i], nil)
|
||||
end
|
||||
is(results[8], 2)
|
||||
end -- }}}
|
||||
|
||||
do -- error handling tests {{{
|
||||
lives_ok(function()
|
||||
clone:handleline '3 4'
|
||||
end)
|
||||
|
||||
isnt(type(errmsg), 'nil')
|
||||
|
||||
errmsg = nil
|
||||
|
||||
lives_ok(function()
|
||||
clone:handleline 'error "foo"'
|
||||
end)
|
||||
|
||||
like(errmsg, 'foo')
|
||||
end -- }}}
|
||||
|
||||
do -- multi-line input tests {{{
|
||||
errmsg = nil
|
||||
_G.t = {}
|
||||
|
||||
lives_ok(function()
|
||||
clone:handleline 'for i = 1, 3 do'
|
||||
clone:handleline ' table.insert(_G.t, i)'
|
||||
clone:handleline 'end'
|
||||
end)
|
||||
|
||||
is(errmsg, nil)
|
||||
is(#_G.t, 3)
|
||||
is(_G.t[1], 1)
|
||||
is(_G.t[2], 2)
|
||||
is(_G.t[3], 3)
|
||||
end -- }}}
|
||||
@@ -0,0 +1,56 @@
|
||||
local _M = {}
|
||||
|
||||
function _M.next_line_number()
|
||||
local info = debug.getinfo(2, 'l')
|
||||
return info.currentline + 1 -- doesn't work with whitespace
|
||||
end
|
||||
|
||||
function _M.cmp_tables(lhs, rhs)
|
||||
local ok = true
|
||||
local got
|
||||
local expected
|
||||
local failing_k
|
||||
|
||||
for k, v in pairs(lhs) do
|
||||
local rv = rhs[k]
|
||||
|
||||
if v ~= rv then
|
||||
ok = false
|
||||
failing_k = k
|
||||
got = v
|
||||
expected = rv
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if ok then
|
||||
for k, v in pairs(rhs) do
|
||||
local lv = lhs[k]
|
||||
|
||||
if v ~= lv then
|
||||
ok = false
|
||||
failing_k = k
|
||||
got = lv
|
||||
expected = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ok then
|
||||
pass()
|
||||
else
|
||||
fail 'value mismatch'
|
||||
diag(string.format(' got[%q]: %s', tostring(failing_k), tostring(got)))
|
||||
diag(string.format('expected[%q]: %s', tostring(failing_k), tostring(expected)))
|
||||
end
|
||||
end
|
||||
|
||||
function _M.gather_results(...)
|
||||
return {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
|
||||
return _M
|
||||
@@ -0,0 +1,202 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
local utils = require 'test-utils'
|
||||
|
||||
plan(26)
|
||||
|
||||
local clone = repl:clone()
|
||||
|
||||
do -- basic tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_normal
|
||||
local has_called_after
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_normal = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo()
|
||||
has_called_after = true
|
||||
ok(has_called_normal)
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
ok(has_called_normal)
|
||||
ok(has_called_after)
|
||||
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
function after:nonexistent()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format("%d: The 'nonexistent' method does not exist", line_no))
|
||||
|
||||
_, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
after.foo = 17
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format('%d: 17 is not a function', line_no))
|
||||
end -- }}}
|
||||
|
||||
do -- arguments tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
local orig_args
|
||||
local got_args
|
||||
|
||||
function with_plugin:foo(...)
|
||||
orig_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo(...)
|
||||
got_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
is(got_args.n, 0)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
|
||||
with_plugin:foo(1, 2, 3)
|
||||
is(got_args.n, 3)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], 2)
|
||||
is(got_args[3], 3)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
|
||||
with_plugin:foo(1, nil, nil, nil, 5)
|
||||
is(got_args.n, 5)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], nil)
|
||||
is(got_args[3], nil)
|
||||
is(got_args[4], nil)
|
||||
is(got_args[5], 5)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
end -- }}}
|
||||
|
||||
do -- exception tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_original
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_original = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo()
|
||||
error 'uh-oh'
|
||||
end
|
||||
end)
|
||||
|
||||
local _, err = pcall(with_plugin.foo, with_plugin)
|
||||
|
||||
like(err, 'uh%-oh')
|
||||
ok(has_called_original)
|
||||
end -- }}}
|
||||
|
||||
do -- return value tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
function with_plugin:foo()
|
||||
return 17
|
||||
end
|
||||
|
||||
function with_plugin:bar()
|
||||
return 18, 19, 20
|
||||
end
|
||||
|
||||
function with_plugin:baz()
|
||||
return 1, nil, nil, nil, 5
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo()
|
||||
return 18
|
||||
end
|
||||
|
||||
function after:bar()
|
||||
return 18
|
||||
end
|
||||
|
||||
function after:baz()
|
||||
return 18
|
||||
end
|
||||
end)
|
||||
|
||||
local result = with_plugin:foo()
|
||||
is(result, 17)
|
||||
|
||||
local results = utils.gather_results(with_plugin:bar())
|
||||
utils.cmp_tables(results, { n = 3, 18, 19, 20 })
|
||||
|
||||
results = utils.gather_results(with_plugin:baz())
|
||||
utils.cmp_tables(results, { n = 5, 1, nil, nil, nil, 5 })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, multiple plugins {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo()
|
||||
calls[#calls + 1] = 'first'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo()
|
||||
calls[#calls + 1] = 'second'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'original', 'first', 'second' })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, single plugin {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function after:foo()
|
||||
calls[#calls + 1] = 'first'
|
||||
end
|
||||
|
||||
function after:foo()
|
||||
calls[#calls + 1] = 'second'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'original', 'first', 'second' })
|
||||
end -- }}}
|
||||
@@ -0,0 +1,218 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
local compat = require 'repl.compat'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
local utils = require 'test-utils'
|
||||
|
||||
plan(27)
|
||||
|
||||
local clone = repl:clone()
|
||||
|
||||
do -- basic tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_normal
|
||||
local has_called_around
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_normal = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo(orig, ...)
|
||||
has_called_around = true
|
||||
ok(not has_called_normal)
|
||||
local return_values = utils.gather_results(orig(self, ...))
|
||||
ok(has_called_normal)
|
||||
return compat.unpack(return_values, 1, return_values.n)
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
ok(has_called_normal)
|
||||
ok(has_called_around)
|
||||
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
function around:nonexistent()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format("%d: The 'nonexistent' method does not exist", line_no))
|
||||
|
||||
_, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
around.foo = 17
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format('%d: 17 is not a function', line_no))
|
||||
end -- }}}
|
||||
|
||||
do -- arguments tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
local orig_args
|
||||
local got_args
|
||||
|
||||
function with_plugin:foo(...)
|
||||
orig_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo(orig, ...)
|
||||
got_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
|
||||
return orig(self, ...)
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
is(got_args.n, 0)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
|
||||
with_plugin:foo(1, 2, 3)
|
||||
is(got_args.n, 3)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], 2)
|
||||
is(got_args[3], 3)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
|
||||
with_plugin:foo(1, nil, nil, nil, 5)
|
||||
is(got_args.n, 5)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], nil)
|
||||
is(got_args[3], nil)
|
||||
is(got_args[4], nil)
|
||||
is(got_args[5], 5)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
end -- }}}
|
||||
|
||||
do -- exception tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_original
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_original = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo()
|
||||
error 'uh-oh'
|
||||
end
|
||||
end)
|
||||
|
||||
local _, err = pcall(with_plugin.foo, with_plugin)
|
||||
|
||||
like(err, 'uh%-oh')
|
||||
ok(not has_called_original)
|
||||
end -- }}}
|
||||
|
||||
do -- return value tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
function with_plugin:foo()
|
||||
return 17
|
||||
end
|
||||
|
||||
function with_plugin:bar()
|
||||
return 18, 19, 20
|
||||
end
|
||||
|
||||
function with_plugin:baz()
|
||||
return 1, nil, nil, nil, 5
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo()
|
||||
return 18
|
||||
end
|
||||
|
||||
function around:bar()
|
||||
return 19, 20, 21
|
||||
end
|
||||
|
||||
function around:baz()
|
||||
return 1, nil, nil, 4
|
||||
end
|
||||
end)
|
||||
|
||||
local result = with_plugin:foo()
|
||||
is(result, 18)
|
||||
|
||||
local results = utils.gather_results(with_plugin:bar())
|
||||
utils.cmp_tables(results, { n = 3, 19, 20, 21 })
|
||||
|
||||
results = utils.gather_results(with_plugin:baz())
|
||||
utils.cmp_tables(results, { n = 4, 1, nil, nil, 4 })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, multiple plugins {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo(orig)
|
||||
calls[#calls + 1] = 'before_one'
|
||||
orig()
|
||||
calls[#calls + 1] = 'after_one'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo(orig)
|
||||
calls[#calls + 1] = 'before_two'
|
||||
orig()
|
||||
calls[#calls + 1] = 'after_two'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'before_two', 'before_one', 'original',
|
||||
'after_one', 'after_two' })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, single plugin {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function around:foo(orig)
|
||||
calls[#calls + 1] = 'before_one'
|
||||
orig()
|
||||
calls[#calls + 1] = 'after_one'
|
||||
end
|
||||
|
||||
function around:foo(orig)
|
||||
calls[#calls + 1] = 'before_two'
|
||||
orig()
|
||||
calls[#calls + 1] = 'after_two'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'before_two', 'before_one', 'original',
|
||||
'after_one', 'after_two' })
|
||||
end -- }}}
|
||||
@@ -0,0 +1,206 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
local utils = require 'test-utils'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
|
||||
plan(28)
|
||||
|
||||
local clone = repl:clone()
|
||||
|
||||
do -- basic tests {{{
|
||||
local loaded
|
||||
|
||||
clone:loadplugin(function()
|
||||
loaded = true
|
||||
end)
|
||||
|
||||
ok(loaded)
|
||||
|
||||
error_like(function()
|
||||
clone:loadplugin(function()
|
||||
error 'uh-oh'
|
||||
end)
|
||||
end, 'uh%-oh')
|
||||
|
||||
end -- }}}
|
||||
|
||||
do -- loading the same plugin twice {{{
|
||||
local function plugin()
|
||||
end
|
||||
|
||||
local line_no
|
||||
|
||||
clone:loadplugin(plugin)
|
||||
local _, err = pcall(function()
|
||||
line_no = utils.next_line_number()
|
||||
clone:loadplugin(plugin)
|
||||
end)
|
||||
like(err, tostring(line_no) .. ': plugin "function:%s+%S+" has already been loaded')
|
||||
|
||||
_, err = pcall(function()
|
||||
line_no = utils.next_line_number()
|
||||
clone:clone():loadplugin(plugin)
|
||||
end)
|
||||
like(err, tostring(line_no) .. ': plugin "function:%s+%S+" has already been loaded')
|
||||
|
||||
repl:clone():loadplugin(plugin)
|
||||
repl:clone():loadplugin(plugin)
|
||||
end -- }}}
|
||||
|
||||
do -- loading plugins by name {{{
|
||||
local loaded
|
||||
|
||||
package.preload['repl.plugins.test'] = function()
|
||||
loaded = true
|
||||
end
|
||||
|
||||
clone:clone():loadplugin 'test'
|
||||
|
||||
ok(loaded)
|
||||
loaded = false
|
||||
|
||||
clone:clone():loadplugin 'test'
|
||||
|
||||
ok(loaded, 'loading a plugin twice should initialize it twice')
|
||||
|
||||
package.preload['repl.plugins.test'] = function()
|
||||
error 'uh-oh'
|
||||
end
|
||||
|
||||
error_like(function()
|
||||
clone:clone():loadplugin 'test'
|
||||
end, 'uh%-oh')
|
||||
|
||||
package.preload['repl.plugins.test'] = nil
|
||||
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
line_no = utils.next_line_number()
|
||||
clone:clone():loadplugin 'test'
|
||||
end)
|
||||
like(err, tostring(line_no) .. ': unable to locate plugin')
|
||||
end -- }}}
|
||||
|
||||
do -- hasplugin tests {{{
|
||||
local child = repl:clone()
|
||||
|
||||
local plugin = function()
|
||||
end
|
||||
|
||||
child:loadplugin(plugin)
|
||||
|
||||
local grandchild = child:clone()
|
||||
|
||||
ok(not repl:hasplugin(plugin))
|
||||
ok(child:hasplugin(plugin))
|
||||
ok(grandchild:hasplugin(plugin))
|
||||
|
||||
plugin = function()
|
||||
end
|
||||
|
||||
child:loadplugin(plugin)
|
||||
|
||||
ok(not repl:hasplugin(plugin))
|
||||
ok(child:hasplugin(plugin))
|
||||
ok(not grandchild:hasplugin(plugin))
|
||||
end -- }}}
|
||||
|
||||
do -- global tests {{{
|
||||
local clone = repl:clone()
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
clone:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
foo = 17
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, tostring(line_no) .. ': global environment is read%-only %(key = "foo"%)')
|
||||
|
||||
_, err = pcall(function()
|
||||
clone:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
_G.foo = 17
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, tostring(line_no) .. ': global environment is read%-only %(key = "foo"%)')
|
||||
end -- }}}
|
||||
|
||||
do -- ifplugin tests {{{
|
||||
local clone = repl:clone()
|
||||
local has_run
|
||||
|
||||
package.preload['repl.plugins.test'] = function()
|
||||
end
|
||||
|
||||
clone:ifplugin('test', function()
|
||||
has_run = true
|
||||
end)
|
||||
|
||||
ok(not has_run)
|
||||
|
||||
clone:loadplugin 'test'
|
||||
|
||||
ok(has_run)
|
||||
|
||||
has_run = false
|
||||
|
||||
clone:ifplugin('test', function()
|
||||
has_run = true
|
||||
end)
|
||||
|
||||
ok(has_run)
|
||||
end -- }}}
|
||||
|
||||
do -- ifplugin multiple times {{{
|
||||
local clone = repl:clone()
|
||||
local has_run
|
||||
local has_run2
|
||||
|
||||
package.preload['repl.plugins.test'] = function()
|
||||
end
|
||||
|
||||
clone:ifplugin('test', function()
|
||||
has_run = true
|
||||
end)
|
||||
|
||||
clone:ifplugin('test', function()
|
||||
has_run2 = true
|
||||
end)
|
||||
|
||||
clone:loadplugin 'test'
|
||||
|
||||
ok(has_run)
|
||||
ok(has_run2)
|
||||
end -- }}}
|
||||
|
||||
do -- plugin return value {{{
|
||||
local clone = repl:clone()
|
||||
|
||||
local result = clone:loadplugin(function()
|
||||
return 17
|
||||
end)
|
||||
|
||||
local result2 = clone:loadplugin(function()
|
||||
end)
|
||||
|
||||
local result3, result4 = clone:loadplugin(function()
|
||||
return 18, 19
|
||||
end)
|
||||
|
||||
local result5, result6, result7 = clone:loadplugin(function()
|
||||
return 20, nil, 21
|
||||
end)
|
||||
|
||||
is(result, 17)
|
||||
is(result2, nil)
|
||||
is(result3, 18)
|
||||
is(result4, 19)
|
||||
is(result5, 20)
|
||||
is(result6, nil)
|
||||
is(result7, 21)
|
||||
end -- }}}
|
||||
@@ -0,0 +1,201 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
local utils = require 'test-utils'
|
||||
|
||||
plan(26)
|
||||
|
||||
local clone = repl:clone()
|
||||
|
||||
do -- basic tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_normal
|
||||
local has_called_before
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_normal = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo()
|
||||
has_called_before = true
|
||||
ok(not has_called_normal)
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
ok(has_called_normal)
|
||||
ok(has_called_before)
|
||||
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
function before:nonexistent()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format("%d: The 'nonexistent' method does not exist", line_no))
|
||||
|
||||
_, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
before.foo = 17
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format('%d: 17 is not a function', line_no))
|
||||
end -- }}}
|
||||
|
||||
do -- arguments tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
local orig_args
|
||||
local got_args
|
||||
|
||||
function with_plugin:foo(...)
|
||||
orig_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo(...)
|
||||
got_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
is(got_args.n, 0)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
|
||||
with_plugin:foo(1, 2, 3)
|
||||
is(got_args.n, 3)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], 2)
|
||||
is(got_args[3], 3)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
|
||||
with_plugin:foo(1, nil, nil, nil, 5)
|
||||
is(got_args.n, 5)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], nil)
|
||||
is(got_args[3], nil)
|
||||
is(got_args[4], nil)
|
||||
is(got_args[5], 5)
|
||||
utils.cmp_tables(orig_args, got_args)
|
||||
end -- }}}
|
||||
|
||||
do -- exception tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_original
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_original = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo()
|
||||
error 'uh-oh'
|
||||
end
|
||||
end)
|
||||
|
||||
local _, err = pcall(with_plugin.foo, with_plugin)
|
||||
|
||||
like(err, 'uh%-oh')
|
||||
ok(not has_called_original)
|
||||
end -- }}}
|
||||
|
||||
do -- return value tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
function with_plugin:foo()
|
||||
return 17
|
||||
end
|
||||
|
||||
function with_plugin:bar()
|
||||
return 18, 19, 20
|
||||
end
|
||||
|
||||
function with_plugin:baz()
|
||||
return 1, nil, nil, nil, 5
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo()
|
||||
return 18
|
||||
end
|
||||
|
||||
function before:bar()
|
||||
return 18
|
||||
end
|
||||
|
||||
function before:baz()
|
||||
end
|
||||
end)
|
||||
|
||||
local result = with_plugin:foo()
|
||||
is(result, 17)
|
||||
|
||||
local results = utils.gather_results(with_plugin:bar())
|
||||
utils.cmp_tables(results, { n = 3, 18, 19, 20 })
|
||||
|
||||
results = utils.gather_results(with_plugin:baz())
|
||||
utils.cmp_tables(results, { n = 5, 1, nil, nil, nil, 5 })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, multiple plugins {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo()
|
||||
calls[#calls + 1] = 'first'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo()
|
||||
calls[#calls + 1] = 'second'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'second', 'first', 'original' })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, single plugin {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function before:foo()
|
||||
calls[#calls + 1] = 'first'
|
||||
end
|
||||
|
||||
function before:foo()
|
||||
calls[#calls + 1] = 'second'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'second', 'first', 'original' })
|
||||
end -- }}}
|
||||
@@ -0,0 +1,132 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
local utils = require 'test-utils'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
|
||||
plan(19)
|
||||
|
||||
do -- basic tests {{{
|
||||
local clone = repl:clone()
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
ok(clone:hasfeature 'foo')
|
||||
ok(not clone:hasfeature 'bar')
|
||||
ok(not clone:hasfeature 'baz')
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = { 'bar', 'baz' }
|
||||
end)
|
||||
|
||||
ok(clone:hasfeature 'foo')
|
||||
ok(clone:hasfeature 'bar')
|
||||
ok(clone:hasfeature 'baz')
|
||||
end -- }}}
|
||||
|
||||
do -- requirefeature {{{
|
||||
local clone = repl:clone()
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
clone:requirefeature 'foo'
|
||||
|
||||
local line_no
|
||||
local _, err = pcall(function()
|
||||
line_no = utils.next_line_number()
|
||||
clone:requirefeature 'bar'
|
||||
end)
|
||||
|
||||
like(err, tostring(line_no) .. ': required feature "bar" not present')
|
||||
end -- }}}
|
||||
|
||||
do -- conflicts {{{
|
||||
local clone = repl:clone()
|
||||
local line_no
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
local _, err = pcall(function()
|
||||
line_no = utils.next_line_number()
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
end)
|
||||
like(err, tostring(line_no) .. ': feature "foo" already present')
|
||||
|
||||
-- XXX what about methods injected into the object?
|
||||
end -- }}}
|
||||
|
||||
do -- clone:hasfeature {{{
|
||||
local child = repl:clone()
|
||||
|
||||
child:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
local grandchild = child:clone()
|
||||
|
||||
ok(not repl:hasfeature 'foo')
|
||||
ok(child:hasfeature 'foo')
|
||||
ok(grandchild:hasfeature 'foo')
|
||||
|
||||
child:loadplugin(function()
|
||||
features = 'bar'
|
||||
end)
|
||||
|
||||
ok(not repl:hasfeature 'bar')
|
||||
ok(child:hasfeature 'bar')
|
||||
ok(not grandchild:hasfeature 'bar')
|
||||
end -- }}}
|
||||
|
||||
do -- iffeature tests {{{
|
||||
local clone = repl:clone()
|
||||
local has_run
|
||||
|
||||
clone:iffeature('foo', function()
|
||||
has_run = true
|
||||
end)
|
||||
|
||||
ok(not has_run)
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
ok(has_run)
|
||||
|
||||
has_run = false
|
||||
|
||||
clone:iffeature('foo', function()
|
||||
has_run = true
|
||||
end)
|
||||
|
||||
ok(has_run)
|
||||
end -- }}}
|
||||
|
||||
do -- iffeature multiple times {{{
|
||||
local clone = repl:clone()
|
||||
local has_run
|
||||
local has_run2
|
||||
|
||||
clone:iffeature('foo', function()
|
||||
has_run = true
|
||||
end)
|
||||
|
||||
clone:iffeature('foo', function()
|
||||
has_run2 = true
|
||||
end)
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
ok(has_run)
|
||||
ok(has_run2)
|
||||
end -- }}}
|
||||
@@ -0,0 +1,201 @@
|
||||
-- vim:foldmethod=marker
|
||||
local repl = require 'repl'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
local utils = require 'test-utils'
|
||||
|
||||
plan(25)
|
||||
|
||||
local clone = repl:clone()
|
||||
|
||||
do -- basic tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_normal
|
||||
local has_called_override
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_normal = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo()
|
||||
has_called_override = true
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
ok(not has_called_normal)
|
||||
ok(has_called_override)
|
||||
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
function override:nonexistent()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format("%d: The 'nonexistent' method does not exist", line_no))
|
||||
|
||||
_, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
override.foo = 17
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format('%d: 17 is not a function', line_no))
|
||||
end -- }}}
|
||||
|
||||
do -- arguments tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
local orig_args
|
||||
local got_args
|
||||
|
||||
function with_plugin:foo(...)
|
||||
orig_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo(...)
|
||||
got_args = {
|
||||
n = select('#', ...),
|
||||
...,
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
is(got_args.n, 0)
|
||||
ok(not orig_args)
|
||||
|
||||
with_plugin:foo(1, 2, 3)
|
||||
is(got_args.n, 3)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], 2)
|
||||
is(got_args[3], 3)
|
||||
ok(not orig_args)
|
||||
|
||||
with_plugin:foo(1, nil, nil, nil, 5)
|
||||
is(got_args.n, 5)
|
||||
is(got_args[1], 1)
|
||||
is(got_args[2], nil)
|
||||
is(got_args[3], nil)
|
||||
is(got_args[4], nil)
|
||||
is(got_args[5], 5)
|
||||
ok(not orig_args)
|
||||
end -- }}}
|
||||
|
||||
do -- exception tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
local has_called_original
|
||||
|
||||
function with_plugin:foo()
|
||||
has_called_original = true
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo()
|
||||
error 'uh-oh'
|
||||
end
|
||||
end)
|
||||
|
||||
local _, err = pcall(with_plugin.foo, with_plugin)
|
||||
|
||||
like(err, 'uh%-oh')
|
||||
ok(not has_called_original)
|
||||
end -- }}}
|
||||
|
||||
do -- return value tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
function with_plugin:foo()
|
||||
return 17
|
||||
end
|
||||
|
||||
function with_plugin:bar()
|
||||
return 18, 19, 20
|
||||
end
|
||||
|
||||
function with_plugin:baz()
|
||||
return 1, nil, nil, nil, 5
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo()
|
||||
return 18
|
||||
end
|
||||
|
||||
function override:bar()
|
||||
return 19, 20, 21
|
||||
end
|
||||
|
||||
function override:baz()
|
||||
return 1, nil, nil, 4
|
||||
end
|
||||
end)
|
||||
|
||||
local result = with_plugin:foo()
|
||||
is(result, 18)
|
||||
|
||||
local results = utils.gather_results(with_plugin:bar())
|
||||
utils.cmp_tables(results, { n = 3, 19, 20, 21 })
|
||||
|
||||
results = utils.gather_results(with_plugin:baz())
|
||||
utils.cmp_tables(results, { n = 4, 1, nil, nil, 4 })
|
||||
end -- }}}
|
||||
|
||||
do -- multiple advice, multiple plugins {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo()
|
||||
calls[#calls + 1] = 'first'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo()
|
||||
calls[#calls + 1] = 'second'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'second' })
|
||||
end
|
||||
|
||||
do -- multiple advice, single plugin {{{
|
||||
local with_plugin = clone:clone()
|
||||
local calls = {}
|
||||
|
||||
function with_plugin:foo()
|
||||
calls[#calls + 1] = 'original'
|
||||
end
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function override:foo()
|
||||
calls[#calls + 1] = 'first'
|
||||
end
|
||||
|
||||
function override:foo()
|
||||
calls[#calls + 1] = 'second'
|
||||
end
|
||||
end)
|
||||
|
||||
with_plugin:foo()
|
||||
|
||||
utils.cmp_tables(calls, { 'second' })
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
-- vim:foldmethod=marker
|
||||
local r = require 'repl' -- we don't call it 'repl' so we don't shadow
|
||||
-- repl in the plugin environment
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
local utils = require 'test-utils'
|
||||
|
||||
plan(5)
|
||||
|
||||
local clone = r:clone()
|
||||
|
||||
do -- basic tests {{{
|
||||
local with_plugin = clone:clone()
|
||||
|
||||
function with_plugin:foo()
|
||||
end
|
||||
|
||||
local line_no
|
||||
|
||||
local _, err = pcall(function()
|
||||
with_plugin:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
function repl:foo()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, string.format("%d: The 'foo' method already exists", line_no))
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
function repl:bar()
|
||||
return 17
|
||||
end
|
||||
end)
|
||||
|
||||
is(with_plugin:bar(), 17)
|
||||
|
||||
with_plugin:loadplugin(function()
|
||||
repl.baz = 18
|
||||
end)
|
||||
|
||||
is(with_plugin.baz, 18)
|
||||
end -- }}}
|
||||
|
||||
do -- conflict tests {{{
|
||||
local clone = r:clone()
|
||||
local line_no
|
||||
|
||||
clone:loadplugin(function()
|
||||
function repl:foo()
|
||||
end
|
||||
end)
|
||||
|
||||
local _, err = pcall(function()
|
||||
clone:loadplugin(function()
|
||||
line_no = utils.next_line_number()
|
||||
function repl:foo()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
like(err, tostring(line_no) .. ": The 'foo' method already exists")
|
||||
end -- }}}
|
||||
|
||||
do -- proxy tests {{{
|
||||
local clone = r:clone()
|
||||
|
||||
clone:loadplugin(function()
|
||||
features = 'foo'
|
||||
end)
|
||||
|
||||
clone:loadplugin(function()
|
||||
ok(repl:hasfeature 'foo')
|
||||
end)
|
||||
end -- }}}
|
||||
@@ -0,0 +1,52 @@
|
||||
-- vim:foldmethod=marker
|
||||
local sync = require 'repl.sync'
|
||||
pcall(require, 'luarocks.loader')
|
||||
require 'Test.More'
|
||||
|
||||
plan(13)
|
||||
|
||||
local clone = sync:clone()
|
||||
local resultlist = {}
|
||||
|
||||
function clone:lines()
|
||||
local index = 0
|
||||
local function iterator(s)
|
||||
index = index + 1
|
||||
return s[index]
|
||||
end
|
||||
|
||||
return iterator, {
|
||||
'return foo',
|
||||
'return 1',
|
||||
'return "bar"',
|
||||
'return {}',
|
||||
'return 1, 2, 3',
|
||||
}
|
||||
end
|
||||
|
||||
function clone:showprompt()
|
||||
end
|
||||
|
||||
function clone:displayresults(results)
|
||||
resultlist[#resultlist + 1] = results
|
||||
end
|
||||
|
||||
clone:run()
|
||||
|
||||
is(#resultlist, 5)
|
||||
is(resultlist[1].n, 1)
|
||||
is(resultlist[1][1], nil)
|
||||
|
||||
is(resultlist[2].n, 1)
|
||||
is(resultlist[2][1], 1)
|
||||
|
||||
is(resultlist[3].n, 1)
|
||||
is(resultlist[3][1], 'bar')
|
||||
|
||||
is(resultlist[4].n, 1)
|
||||
is(type(resultlist[4][1]), 'table')
|
||||
|
||||
is(resultlist[5].n, 3)
|
||||
is(resultlist[5][1], 1)
|
||||
is(resultlist[5][2], 2)
|
||||
is(resultlist[5][3], 3)
|
||||
Reference in New Issue
Block a user