local library_util = require('libraryUtil')
local check_type = library_util.checkType
-- Allow examples to be a string in a sort of TSV format,
-- consisting of one or more lines with two or three non-empty arguments
-- separated by one or more tabs. Single-line Lua comments are stripped, as well as
-- whitespace at the beginning and end of each line.
-- Empty lines and lines consisting of whitespace are skipped.
local function examples_string_to_array(examples)
examples = examples:gsub("%s*%-%-[^\n]*", "")
local array = {}
for line in examples:gmatch("[^\n]+") do
line = mw.text.trim(line)
if line ~= "" then
local original, expected, sc = line:match("^([^\t]+)\t+([^\t]+)\t-([^\t]-)$")
if not original then
error("The following line did not consist of two or three arguments separated by tabs:\n"
.. line)
end
if sc == "" then sc = nil end
table.insert(array, { original, expected, sc })
end
end
return array
end
local function _check(funcName, expectType)
return function(argIndex, arg, expectType, nilOk)
check_type(funcName, argIndex, arg, expectType, nilOk)
end
end
local function get_translit_function(module_name)
local success, translit_module = pcall(require, 'Module:' .. module_name)
if not success then
error('Error requiring Module:' .. module_name .. ': ' .. tostring(translit_module))
end
translit_function = translit_module.tr
if type(translit_function) ~= 'function' then
error('Module:' .. module_name .. ' does not contain a function \'tr\'.')
end
return translit_function
end
return function(translit_function, examples, sc_code, lang_code, options)
local module_name
if type(translit_function) == 'table' then
local args = translit_function
module_name, examples, sc_code, lang_code
= args.module, args.examples, args.sc, args.lang
options = {}
for k, v in pairs(args) do
if not (k == 'module' or k == 'examples' or k == 'sc' or k == 'lang') then
options[k] = v
end
end
elseif type(translit_function) == 'string' then
module_name, translit_function = translit_function, nil
end
if module_name then
translit_function = get_translit_function(module_name)
end
-- C H E C K P A R A M E T E R S --
local check_type = _check('translit_module_testcases')
check_type(1, translit_function, 'function')
check_type(3, sc_code, 'string')
check_type(4, lang_code, 'string')
check_type(5, options, 'table', true)
options = options or {}
if type(examples) == "table" then
if not require('Module:table').isArray(examples) then
error('Third argument or "examples" argument to translit_module_testcases should be an array.')
end
elseif type(examples) == "string" then
examples = examples_string_to_array(examples)
else
error('Third argument or "examples" argument to translit_module_testcases should be an array or string.')
end
-- Get canonical name and validate language code.
local lang_object = require('Module:languages').getByCode(lang_code)
or error('The language code ' .. lang_code .. ' is not valid.')
local canonical_name = lang_object:getCanonicalName()
-- Validate script code.
if not mw.loadData('Module:scripts/data')[sc_code] then
error('The script code ' .. sc_code .. ' is not valid.')
end
-- M A K E T E S T F U N C T I O N --
local tests = require('Module:UnitTests')
local normalize = mw.ustring.toNFD
local opening_tag = '<span class="' .. sc_code .. '" lang="' .. lang_code .. '">'
local template
if options.nolink then
template = opening_tag .. '&</span>'
else
template = opening_tag .. '[[&#' .. canonical_name .. '|&]]</span>'
end
if options.func_with_link then
format_text = options.func_with_link
if type(format_text) ~= "function" then
error("func_with_link in options table should be a function.")
end
elseif options.func_before_link then
local func = options.func_before_link
if type(func) ~= "function" then
error("func_before_link in options table should be a function.")
end
function format_text(text)
return template:gsub('&', (func(text)))
end
else
function format_text(text)
return template:gsub('&', text)
end
end
local self_equals_options = { display = options.output_display }
function tests:check(example, expected, manual_sc, manual_lang)
ex_tr = translit_function(example, manual_lang or lang_code, manual_sc or sc_code)
or 'NIL' -- Handle transliteration function returning nil, a valid function value.
self:equals(format_text(example, expected, manual_sc, manual_lang),
normalize(ex_tr),
expected and normalize(expected),
self_equals_options
)
end
function tests:test()
self:iterate(examples, 'check')
end
if module_name then
tests["testcases for <code>tr</code> function in [[Module:" .. module_name .. "]]"], tests.test
= tests.test, nil
end
return tests
end