diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-12-13 16:10:08 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-12-13 16:10:08 +1100 |
| commit | 64b106c13e18c33be0f2b0de532054e0ed3f731d (patch) | |
| tree | b54b1c90d941bc456b4d51e864970720bdf2d648 /lib/lua-repl/t | |
| parent | 5a2f0b08e0e3f20cda977b510b680d5843ae7283 (diff) | |
| download | tangara-fw-64b106c13e18c33be0f2b0de532054e0ed3f731d.tar.gz | |
add a cool lua repl
Diffstat (limited to 'lib/lua-repl/t')
| -rw-r--r-- | lib/lua-repl/t/abstract-repl-tests.lua | 33 | ||||
| -rw-r--r-- | lib/lua-repl/t/clone-repl-tests.lua | 119 | ||||
| -rw-r--r-- | lib/lua-repl/t/lib/test-utils.lua | 56 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-after-tests.lua | 202 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-around-tests.lua | 218 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-basic-tests.lua | 206 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-before-tests.lua | 201 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-feature-tests.lua | 132 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-override-tests.lua | 201 | ||||
| -rw-r--r-- | lib/lua-repl/t/plugin-repl-tests.lua | 75 | ||||
| -rw-r--r-- | lib/lua-repl/t/sync-repl-tests.lua | 52 |
11 files changed, 1495 insertions, 0 deletions
diff --git a/lib/lua-repl/t/abstract-repl-tests.lua b/lib/lua-repl/t/abstract-repl-tests.lua new file mode 100644 index 00000000..50d4b07c --- /dev/null +++ b/lib/lua-repl/t/abstract-repl-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/clone-repl-tests.lua b/lib/lua-repl/t/clone-repl-tests.lua new file mode 100644 index 00000000..3ec82f92 --- /dev/null +++ b/lib/lua-repl/t/clone-repl-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/lib/test-utils.lua b/lib/lua-repl/t/lib/test-utils.lua new file mode 100644 index 00000000..a0bb16ac --- /dev/null +++ b/lib/lua-repl/t/lib/test-utils.lua @@ -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 diff --git a/lib/lua-repl/t/plugin-after-tests.lua b/lib/lua-repl/t/plugin-after-tests.lua new file mode 100644 index 00000000..15a24c11 --- /dev/null +++ b/lib/lua-repl/t/plugin-after-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/plugin-around-tests.lua b/lib/lua-repl/t/plugin-around-tests.lua new file mode 100644 index 00000000..df0ea073 --- /dev/null +++ b/lib/lua-repl/t/plugin-around-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/plugin-basic-tests.lua b/lib/lua-repl/t/plugin-basic-tests.lua new file mode 100644 index 00000000..21283ef8 --- /dev/null +++ b/lib/lua-repl/t/plugin-basic-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/plugin-before-tests.lua b/lib/lua-repl/t/plugin-before-tests.lua new file mode 100644 index 00000000..cc23ba78 --- /dev/null +++ b/lib/lua-repl/t/plugin-before-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/plugin-feature-tests.lua b/lib/lua-repl/t/plugin-feature-tests.lua new file mode 100644 index 00000000..4c74a4c1 --- /dev/null +++ b/lib/lua-repl/t/plugin-feature-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/plugin-override-tests.lua b/lib/lua-repl/t/plugin-override-tests.lua new file mode 100644 index 00000000..6ea11d8b --- /dev/null +++ b/lib/lua-repl/t/plugin-override-tests.lua @@ -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 diff --git a/lib/lua-repl/t/plugin-repl-tests.lua b/lib/lua-repl/t/plugin-repl-tests.lua new file mode 100644 index 00000000..b3aa7665 --- /dev/null +++ b/lib/lua-repl/t/plugin-repl-tests.lua @@ -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 -- }}} diff --git a/lib/lua-repl/t/sync-repl-tests.lua b/lib/lua-repl/t/sync-repl-tests.lua new file mode 100644 index 00000000..d5249ec2 --- /dev/null +++ b/lib/lua-repl/t/sync-repl-tests.lua @@ -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) |
