diff --git a/.busted b/.busted
new file mode 100644
index 00000000000..8135e3dd586
--- /dev/null
+++ b/.busted
@@ -0,0 +1,12 @@
+return {
+ _all = {
+ verbose = true,
+ helper = 'spec/test_helper.lua',
+ },
+ default = {
+ ROOT = {"spec"},
+ },
+ ci = {
+ ROOT = {"spec"},
+ },
+}
diff --git a/.github/workflows/luacheck.yml b/.github/workflows/luacheck.yml
index 1210c73ea2a..b19d8db35f0 100644
--- a/.github/workflows/luacheck.yml
+++ b/.github/workflows/luacheck.yml
@@ -1,34 +1,66 @@
-name: Code Style
+name: Code Style and Unit Tests
on: [pull_request, workflow_dispatch]
jobs:
- test-lua:
+ lua-code-style:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@master
+ - name: Checkout
+ uses: actions/checkout@master
- - uses: leafo/gh-actions-lua@v9
+ - name: Setup lua
+ uses: leafo/gh-actions-lua@v9
with:
- luaVersion: "5.1"
+ luaVersion: '5.1'
- - uses: leafo/gh-actions-luarocks@v4
+ - name: Setup luarock
+ uses: leafo/gh-actions-luarocks@v4
- - name: setup
+ - name: Setup dependencies
run: |
luarocks install luacheck
- - name: test
+ - name: Run lint
run: |
luacheck ./ |
luacheck ./ --formatter=JUnit > report.xml
- - name: junit
+ - name: Report lint
uses: mikepenz/action-junit-report@v3
if: always()
with:
report_paths: 'report.xml'
- check_name: 'junit-report'
- annotate_notice: false
+ check_name: 'Lint Report'
+ lua-unit-test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@master
+
+ - name: Setup lua
+ uses: leafo/gh-actions-lua@v9
+ with:
+ luaVersion: '5.1'
+
+ - name: Setup luarocks
+ uses: leafo/gh-actions-luarocks@v4
+
+ - name: Setup dependencies
+ run: |
+ luarocks install busted
+
+ - name: Run test
+ uses: lunarmodules/busted@v2.2.0
+ with:
+ args: --run=ci --output=junit > busted.xml
+
+ - name: Report test
+ uses: mikepenz/action-junit-report@v3
+ if: always()
+ with:
+ report_paths: 'busted.xml'
+ check_name: 'Test Report'
diff --git a/.luarc.json b/.luarc.json
index 71693a4f4b0..80bb1138924 100644
--- a/.luarc.json
+++ b/.luarc.json
@@ -9,5 +9,9 @@
"diagnostics.neededFileStatus": {
"codestyle-check": "None",
"name-style-check": "None"
- }
+ },
+ "workspace.library": [
+ "${3rd}/busted/library",
+ "${3rd}/luassert/library"
+ ]
}
diff --git a/definitions/mw.lua b/definitions/mw.lua
index de11c59840e..04a39696752 100644
--- a/definitions/mw.lua
+++ b/definitions/mw.lua
@@ -1,5 +1,6 @@
--- luacheck: ignore
---@meta mw
+-- luacheck: ignore
+---This file contains definitions and simulations of the MediaWiki enviroment
mw = {}
---Adds a warning which is displayed above the preview when previewing an edit. `text` is parsed as wikitext.
@@ -34,7 +35,10 @@ function mw.isSubsting() end
---See www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.loadData
---@param module string
---@return table
-function mw.loadData(module) end
+function mw.loadData(module)
+ --TODO: add __index that errors
+ return require(module)
+end
---This is the same as mw.loadData(), except it loads data from JSON pages rather than Lua tables. The JSON content must be an array or object. See also mw.text.jsonDecode().
---@param page string
@@ -215,7 +219,9 @@ function mw.language.fetchLanguageNames(inLanguage, include) end
---Returns a new language object for the wiki's default content language.
---@return Language
-function mw.language.getContentLanguage() end
+function mw.language.getContentLanguage()
+ return setmetatable(mw.language, {})
+end
mw.getContentLanguage = mw.language.getContentLanguage
---Returns a list of MediaWiki's fallback language codes for the specified code.
@@ -246,7 +252,9 @@ function mw.language.isValidCode(code) end
---Creates a new language object. Language objects do not have any publicly accessible properties, but they do have several methods, which are documented below.
---@param code string
---@return Language
-function mw.language.new(code) end
+function mw.language.new(code)
+ return mw.language.getContentLanguage()
+end
mw.getLanguage = mw.language.new
---Returns the language code for this language object.
@@ -289,8 +297,18 @@ function mw.language:caseFold(str) end
---Formats a number with grouping and decimal separators appropriate for the given language. Given 123456.78, this may produce "123,456.78", "123.456,78", or even something like "١٢٣٬٤٥٦٫٧٨" depending on the language and wiki configuration.
---@param num number
---@param options? {noCommafy: boolean}
----@return number
-function mw.language:formatNum(num, options) end
+---@return string
+function mw.language:formatNum(num, options)
+ local k
+ local formatted = tostring(num)
+ while true do
+ formatted, k = string.gsub(formatted, '^(-?%d+)(%d%d%d)', '%1,%2')
+ if (k == 0) then
+ break
+ end
+ end
+ return formatted
+end
---Formats a date according to the given format string. If timestamp is omitted, the default is the current time. The value for local must be a boolean or nil; if true, the time is formatted in the wiki's local time rather than in UTC.
---@param format string
@@ -483,7 +501,14 @@ function mw.text.nowiki(s) end
---@param pattern string?
---@param plain boolean?
---@return string[]
-function mw.text.split(s, pattern, plain) end
+function mw.text.split(s, pattern, plain)
+ pattern = pattern or "%s"
+ local t = {}
+ for str in string.gmatch(s, "([^"..pattern.."]+)") do
+ table.insert(t, str)
+ end
+ return t
+end
---Returns an iterator function that will iterate over the substrings that would be returned by the equivalent call to mw.text.split().
---@param s string
@@ -652,6 +677,148 @@ function mw.title:canonicalUrl(query) end
---@return string?
function mw.title:getContent() end
+---@class ustring
+---@field maxPatternLength number The maximum allowed length of a pattern, in bytes.
+---@field maxStringLength number The maximum allowed length of a string, in bytes.
+mw.ustring = {}
+
+---Returns individual bytes; identical to string.byte().
+---@see string.byte
+---@param s string|number
+---@param i? integer
+---@param j? integer
+---@return integer ...
+function mw.ustring.byte(s, i, j) end
+
+---Returns the byte offset of a character in the string. The default for both l and i is 1. i may be negative, in which case it counts from the end of the string.
+---@param s string|number
+---@param l? integer
+---@param i? integer
+---@return integer ...
+function mw.ustring.byteoffset(s, l, i) end
+
+---Much like string.char(), except that the integers are Unicode codepoints rather than byte values.
+---@see string.char
+---@param ... integer
+---@return string
+function mw.ustring.char(...) end
+
+---Much like string.byte(), except that the return values are codepoints and the offsets are characters rather than bytes.
+---@see string.byte
+---@param s string|number
+---@param i? integer
+---@param j? integer
+---@return integer ...
+function mw.ustring.codepoint(s, i, j) end
+
+---Much like string.find(), except that the pattern is extended as described in Ustring patterns and the init offset is in characters rather than bytes.
+---@see string.find
+---@param s string|number
+---@param pattern string|number
+---@param init? integer
+---@param plain? boolean
+---@return integer|nil start
+---@return integer|nil end
+---@return any|nil ... captured
+function mw.ustring.find(s, pattern, init, plain) end
+
+---Identical to string.format(). Widths and precisions for strings are expressed in bytes, not codepoints.
+---@see string.format
+---@param format string|number
+---@param ... any
+---@return string
+function mw.ustring.format(format, ...) end
+
+---Returns three values for iterating over the codepoints in the string. i defaults to 1, and j to -1. This is intended for use in the iterator form of for:
+---@param s string|number
+---@param i? integer
+---@param j? integer
+---@return string
+function mw.ustring.gcodepoint(s, i, j) end
+
+---Much like string.gmatch(), except that the pattern is extended as described in Ustring patterns.
+---@see string.gmatch
+---@param s string|number
+---@param pattern string|number
+---@return fun():string, ...
+function mw.ustring.gmatch(s, pattern) end
+
+---Much like string.gmatch(), except that the pattern is extended as described in Ustring patterns.
+---@see string.gsub
+---@param s string|number
+---@param pattern string|number
+---@param repl string|number|table|function
+---@param n? integer
+---@return string
+---@return integer count
+function mw.ustring.gsub(s, pattern, repl, n) end
+
+---Returns true if the string is valid UTF-8, false if not.
+---@param s string|number
+---@return boolean
+function mw.ustring.isutf8(s) end
+
+---Returns the length of the string in codepoints, or nil if the string is not valid UTF-8.
+---@see string.len
+---@param s string|number
+---@return integer
+function mw.ustring.len(s) end
+
+---Much like string.lower(), except that all characters with lowercase to uppercase definitions in Unicode are converted.
+---@see string.lower
+---@param s string|number
+---@return string
+function mw.ustring.lower(s) return string.lower(s) end
+
+---Much like string.match(), except that the pattern is extended as described in Ustring patterns and the init offset is in characters rather than bytes.
+---@see string.match
+---@param s string|number
+---@param pattern string|number
+---@param init? integer
+---@return any ...
+function mw.ustring.match(s, pattern, init) end
+
+---Identical to string.rep().
+---@see string.rep
+---@param s string|number
+---@param n integer
+---@return string
+function mw.ustring.rep(s, n) end
+
+---Identical to string.sub().
+---@see string.sub
+---@param s string|number
+---@param i integer
+---@param j? integer
+---@return string
+function mw.ustring.sub(s, i, j) end
+
+---Converts the string to Normalization Form C (also known as Normalization Form Canonical Composition). Returns nil if the string is not valid UTF-8.
+---@param s string|number
+---@return string?
+function mw.ustring.toNFC(s) return tostring(s) end
+
+---Converts the string to Normalization Form D (also known as Normalization Form Canonical Decomposition). Returns nil if the string is not valid UTF-8.
+---@param s string|number
+---@return string?
+function mw.ustring.toNFD(s) return tostring(s) end
+
+---Converts the string to Normalization Form KC (also known as Normalization Form Compatibility Composition). Returns nil if the string is not valid UTF-8.
+---@param s string|number
+---@return string?
+function mw.ustring.toNFKC(s) return tostring(s) end
+
+---Converts the string to Normalization Form KD (also known as Normalization Form Compatibility Decomposition). Returns nil if the string is not valid UTF-8.
+---@param s string|number
+---@return string?
+function mw.ustring.toNFKD(s) return tostring(s) end
+
+---Much like string.upper(), except that all characters with uppercase to lowercase definitions in Unicode are converted.
+---@see string.upper
+---@param s string|number
+---@return string
+function mw.ustring.upper(s) return string.upper(s) end
+
mw.ext = {}
mw.ext.LiquipediaDB = {}
@@ -665,4 +832,63 @@ function mw.ext.LiquipediaDB.lpdb_create_json(obj) end
---Encode an Array to a JSON array. Errors are raised if the passed value cannot be encoded in JSON.
function mw.ext.LiquipediaDB.lpdb_create_array(obj) end
+mw.ext.VariablesLua = {}
+---@alias wikiVaribleKey string|number
+---@alias wikiVariableValue string|number|nil
+
+---Fake storage for enviroment simulation
+---@private
+mw.ext.VariablesLua.variablesStorage = {}
+
+---Stores a wiki-variable and returns the empty string
+---@param name wikiVaribleKey
+---@param value wikiVariableValue
+---@return string #always an empty string
+function mw.ext.VariablesLua.vardefine(name, value)
+ mw.ext.VariablesLua.variablesStorage[name] = value
+ return ''
+end
+
+---Stores a wiki-variable and returns the stored value
+---@param name wikiVaribleKey Key of the wiki-variable
+---@param value wikiVariableValue Value of the wiki-variable
+---@return string
+function mw.ext.VariablesLua.vardefineecho(name, value)
+ mw.ext.VariablesLua.vardefine(name, value)
+ return mw.ext.VariablesLua.var(name)
+end
+
+---Gets the stored value of a wiki-variable
+---@param name wikiVaribleKey Key of the wiki-variable
+---@return string
+function mw.ext.VariablesLua.var(name)
+ return mw.ext.VariablesLua.variablesStorage[name] and tostring(mw.ext.VariablesLua.variablesStorage[name]) or ''
+end
+
+---Checks if a wiki-variable is stored
+---@param name wikiVaribleKey Key of the wiki-variable
+---@return boolean
+function mw.ext.VariablesLua.varexist(name)
+ return mw.ext.VariablesLua.variablesStorage[name] ~= nil
+end
+
+mw.ext.CurrencyExchange = {}
+
+---@param amount number
+---@param fromCurrency string
+---@param toCurrency string
+---@param date? string
+---@return number
+function mw.ext.CurrencyExchange.currencyexchange(amount, fromCurrency, toCurrency, date)
+ -- Fake mock number
+ return 0.97097276906869
+end
+
+mw.ext.TeamLiquidIntegration = {}
+
+---Adds a category to a page
+---@param name string
+---@param sortName string?
+function mw.ext.TeamLiquidIntegration.add_category(name, sortName) end
+
return mw
diff --git a/plugins/sumneko_plugin.lua b/plugins/sumneko_plugin.lua
index 00c6de4fada..25e6ac9449e 100644
--- a/plugins/sumneko_plugin.lua
+++ b/plugins/sumneko_plugin.lua
@@ -7,23 +7,31 @@ local liquipedia = {}
local importFunctions = {}
importFunctions.functions = {'require', 'mw%.loadData', 'Lua%.import', 'Lua%.requireIfExists'}
-importFunctions.prefixModules = {table = 'standard.', math = 'standard.', string = 'standard.'}
+importFunctions.prefixModules = {table = 'standard.', math = 'standard.', string = 'standard.', array = 'standard.'}
-function importFunctions._row(name)
- local normModuleName =
- name
- :gsub('Module:', '') -- Remove starting Module:
- :gsub('^%u', string.lower) -- Lower case first letter
- :gsub('%u', '_%0') -- Prefix uppercase letters with an underscore
- :gsub('/', '_') -- Change slash to underscore
- :gsub('__', '_') -- Never have two underscores in a row
- :lower() -- Lowercase everything
+---Transforms a MediaWiki module name, e.g. `Module:Array`, into a lua repository name, e.g. `array`
+---@param name string
+---@return string
+function importFunctions.luaifyModuleName(name)
+ local normModuleName = name
+ :gsub('Module:', '')-- Remove starting Module:
+ :gsub('^%u', string.lower)-- Lower case first letter
+ :gsub('%u', '_%0')-- Prefix uppercase letters with an underscore
+ :gsub('/', '_')-- Change slash to underscore
+ :gsub('__', '_')-- Never have two underscores in a row
+ :lower() -- Lowercase everything
if importFunctions.prefixModules[normModuleName] then
normModuleName = importFunctions.prefixModules[normModuleName] .. normModuleName
end
- return ' ---@module \'' .. normModuleName ..'\''
+ return normModuleName
+end
+
+function importFunctions._row(name)
+ local normModuleName = importFunctions.luaifyModuleName(name)
+
+ return ' ---@module \'' .. normModuleName .. '\''
end
function importFunctions.annotate(text, funcName, diffs)
@@ -57,9 +65,15 @@ function OnSetText(uri, text)
return nil
end
+ if text:sub(1, 8) == '---@meta' then
+ return nil
+ end
+
local diffs = {}
liquipedia.annotate(text, diffs)
return diffs
end
+
+return importFunctions
diff --git a/spec/abbreviation_spec.lua b/spec/abbreviation_spec.lua
new file mode 100644
index 00000000000..f9ab5dd24f4
--- /dev/null
+++ b/spec/abbreviation_spec.lua
@@ -0,0 +1,18 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('abbreviation', function()
+ local Abbreviation = require('Module:Abbreviation')
+
+ describe('make abbreviation', function()
+ it('Empty input returns nil', function()
+ assert.is_nil(Abbreviation.make())
+ assert.is_nil(Abbreviation.make(''))
+ end)
+ it('Only one input returns nil', function()
+ assert.is_nil(Abbreviation.make('Abc', nil))
+ assert.is_nil(Abbreviation.make('', 'Def'))
+ end)
+ it('Abbreviation works', function()
+ assert.are_same('Cake', Abbreviation.make('Cake', 'Cookie'))
+ end)
+ end)
+end)
diff --git a/spec/array_spec.lua b/spec/array_spec.lua
new file mode 100644
index 00000000000..4f5619f07b2
--- /dev/null
+++ b/spec/array_spec.lua
@@ -0,0 +1,208 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('array', function()
+ local Array = require('Module:Array')
+ local Table = require('Module:Table')
+
+ describe('isArray', function()
+ it('Empty table is array', function()
+ assert.is_true(Array.isArray{})
+ end)
+ it('Arrays are array', function()
+ assert.is_true(Array.isArray{5, 2, 3})
+ end)
+ it('Tables are array', function()
+ assert.is_false(Array.isArray{a = 1, [3] = 2, c = 3})
+ assert.is_false(Array.isArray{5, 2, c = 3})
+ end)
+ end)
+
+ describe('Copy', function()
+ it('check', function()
+ local a, b, c = {1, 2, 3}, {}, {{5}}
+ assert.are_same(a, Array.copy(a))
+ assert.is_false(Array.copy(b) == b)
+ assert.is_true(Array.copy(c)[1] == c[1])
+ end)
+ end)
+
+ describe('Sub', function()
+ it('check', function()
+ local a = {3, 5, 7, 11}
+ assert.are_same({5, 7, 11}, Array.sub(a, 2))
+ assert.are_same({5, 7}, Array.sub(a, 2, 3))
+ assert.are_same({7, 11}, Array.sub(a, -2, -1))
+ end)
+ end)
+
+ describe('Map', function()
+ it('check', function()
+ local a = {1, 2, 3}
+ assert.are_same({2, 4, 6}, Array.map(a, function(x)
+ return 2 * x
+ end))
+ end)
+ end)
+
+ describe('Filter', function()
+ it('check', function()
+ local a = {1, 2, 3}
+ assert.are_same({1, 3}, Array.filter(a, function(x)
+ return x % 2 == 1
+ end
+ ))
+ end)
+ end)
+
+ describe('Flatten', function()
+ it('check', function()
+ local a = {1, 2, 3, {5, 3}, {6, 4}}
+ assert.are_same({1, 2, 3, 5, 3, 6, 4}, Array.flatten(a))
+ end)
+ end)
+
+ describe('All', function()
+ it('check', function()
+ local a = {1, 2, 3}
+ assert.is_true(Array.all(a, function(value)
+ return type(value) == 'number'
+ end))
+ assert.is_false(Array.all(a, function(value)
+ return value < 3
+ end))
+ end)
+ end)
+
+ describe('Any', function()
+ it('check', function()
+ local a = {1, 2, 3}
+ assert.is_false(Array.any(a, function(value)
+ return type(value) == 'string'
+ end))
+ assert.is_true(Array.any(a, function(value)
+ return value < 3
+ end))
+ end)
+ end)
+
+ describe('Find', function()
+ it('check', function()
+ local a = {4, 6, 9}
+ local b = Array.find(a, function(value, index)
+ return index == 2
+ end)
+ local c = Array.find(a, function(value, index)
+ return index == -1
+ end)
+ assert.are_equal(6, b)
+ assert.are_equal(nil, c)
+ end)
+ end)
+
+ describe('Revese', function()
+ it('check', function()
+ local a = {4, 6, 9}
+ assert.are_same({9, 6, 4}, Array.reverse(a))
+ end)
+ end)
+
+ describe('Append', function()
+ it('check', function()
+ local a = {2, 3}
+ assert.are_same({2, 3, 5, 7, 11}, Array.append(a, 5, 7, 11))
+ assert.are_same({2, 3}, a)
+ end)
+ end)
+
+ describe('AppendWith', function()
+ it('check', function()
+ local a = {2, 3}
+ assert.are_same({2, 3, 5, 7, 11}, Array.appendWith(a, 5, 7, 11))
+ assert.are_same({2, 3, 5, 7, 11}, a)
+ end)
+ end)
+
+ describe('Extend', function()
+ it('check', function()
+ local a, b, c = {2, 3}, {5, 7, 11}, {13}
+ assert.are_same({2, 3, 5, 7, 11, 13}, Array.extend(a, b, c))
+ assert.are_same({2, 3}, a)
+ end)
+ end)
+
+ describe('ExtendWith', function()
+ it('check', function()
+ local a, b, c = {2, 3}, {5, 7, 11}, {13}
+ assert.are_same({2, 3, 5, 7, 11, 13}, Array.extendWith(a, b, c))
+ assert.are_same({2, 3, 5, 7, 11, 13}, a)
+ end)
+ end)
+
+ describe('MapIndexes', function()
+ it('check', function()
+ local a = {p1 = 'Abc', p2 = 'cd', p3 = 'cake'}
+ assert.are_same({'p1Abc', 'p2cd'}, Array.mapIndexes(function(x)
+ local prefix = 'p' .. x
+ return a[prefix] ~= 'cake' and (prefix .. a[prefix]) or nil
+ end))
+ end)
+ end)
+
+ describe('Range', function()
+ it('check', function()
+ assert.are_same({1, 2, 3}, Array.range(1, 3))
+ assert.are_same({2, 3}, Array.range(2, 3))
+ end)
+ end)
+
+ describe('ForEach', function()
+ it('check', function()
+ local a = {}
+ Array.forEach(Array.range(1, 3), function(x)
+ table.insert(a, 1, x)
+ end)
+ assert.are_same({3, 2, 1}, a)
+ end)
+ end)
+
+ describe('Reduce', function()
+ it('check', function()
+ local function pow(x, y) return x ^ y end
+ assert.are_same(32768, Array.reduce({2, 3, 5}, pow))
+ assert.are_same(1, Array.reduce({2, 3, 5}, pow, 1))
+ end)
+ end)
+
+ describe('ExtractValues', function()
+ it('check', function()
+ local a = {i = 1, j = 2, k = 3, z = 0}
+
+ local customOrder1 = function(_, key1, key2) return key1 > key2 end
+ local customOrder2 = function(tbl, key1, key2) return tbl[key1] < tbl[key2] end
+
+ assert.are_same({1, 2, 3, 0}, Array.extractValues(a, Table.iter.spairs))
+ assert.are_same({0, 3, 2, 1}, Array.extractValues(a, Table.iter.spairs, customOrder1))
+ assert.are_same({0, 1, 2, 3}, Array.extractValues(a, Table.iter.spairs, customOrder2))
+
+ local extractedArray = Array.extractValues(a)
+ table.sort(extractedArray)
+ assert.are_same({0, 1, 2, 3}, extractedArray)
+ end)
+ end)
+
+ describe('ExtractKeys', function()
+ it('check', function()
+ local a = {k = 3, i = 1, z = 0, j = 2}
+
+ local customOrder1 = function(_, key1, key2) return key1 > key2 end
+ local customOrder2 = function(tbl, key1, key2) return tbl[key1] < tbl[key2] end
+
+ assert.are_same({'i', 'j', 'k', 'z'}, Array.extractKeys(a, Table.iter.spairs))
+ assert.are_same({'z', 'k', 'j', 'i'}, Array.extractKeys(a, Table.iter.spairs, customOrder1))
+ assert.are_same({'z', 'i', 'j', 'k'}, Array.extractKeys(a, Table.iter.spairs, customOrder2))
+
+ local extractedKeys = Array.extractKeys(a)
+ table.sort(extractedKeys)
+ assert.are_same({'i', 'j', 'k', 'z'}, extractedKeys)
+ end)
+ end)
+end)
diff --git a/spec/currency_spec.lua b/spec/currency_spec.lua
new file mode 100644
index 00000000000..5a68718ab96
--- /dev/null
+++ b/spec/currency_spec.lua
@@ -0,0 +1,71 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('currency', function()
+ local Currency = require('Module:Currency')
+ local Variables = require('Module:Variables')
+
+ local DASH = '-'
+
+ describe('get exchange rate', function()
+ it('do it', function()
+ assert.are_equal(1.45,
+ Currency.getExchangeRate({currency = 'EUR', currencyRate = '1.45', setVariables = true}))
+ assert.are_equal(1.45, tonumber(Variables.varDefault('exchangerate_EUR')))
+ assert.are_equal(0.97097276906869, Currency.getExchangeRate{date = '2022-10-10', currency = 'EUR'})
+ end)
+ end)
+
+ describe('formatting money', function()
+ it('do it', function()
+ assert.are_equal(DASH, Currency.formatMoney('abc'))
+ assert.are_equal(DASH, Currency.formatMoney(nil))
+ assert.are_equal(DASH, Currency.formatMoney('0'))
+ assert.are_equal(DASH, Currency.formatMoney(0))
+ assert.are_equal(0, Currency.formatMoney('abc', nil, nil, false))
+ assert.are_equal(0, Currency.formatMoney(nil, nil, nil, false))
+ assert.are_equal('12', Currency.formatMoney(12))
+ assert.are_equal('1,200', Currency.formatMoney(1200))
+ assert.are_equal('1,200.00', Currency.formatMoney(1200, nil, true))
+ assert.are_equal('1,200.12', Currency.formatMoney(1200.12345))
+ assert.are_equal('1,200.1', Currency.formatMoney(1200.12345, 1))
+ assert.are_equal('1,200.1235', Currency.formatMoney(1200.12345, 4))
+ end)
+ end)
+
+ describe('raw', function()
+ it('validate incorrect input returns nil', function()
+ assert.is_nil(Currency.raw())
+ assert.is_nil(Currency.raw(''))
+ assert.is_nil(Currency.raw('dummy'))
+ end)
+ it('correct data works', function()
+ assert.are_same({
+ code = 'EUR',
+ name = 'Euro',
+ symbol = {
+ hasSpace = false,
+ isAfter = false,
+ text = '€',
+ },
+ },
+ Currency.raw('EUR')
+ )
+ end)
+ end)
+
+ describe('display', function()
+ it('validate incorrect input returns nil', function()
+ assert.is_nil(Currency.display())
+ assert.is_nil(Currency.display(''))
+ assert.is_nil(Currency.display('dummy'))
+ end)
+ it('validate options', function()
+ assert.are_equal(DASH, Currency.display('dummy', 0, {dashIfZero = true}))
+ assert.are_equal(DASH, Currency.display('EUR', 0, {dashIfZero = true}))
+ assert.are_equal('€1,200 EUR',
+ Currency.display('EUR', 1200, {formatValue = true}))
+ assert.are_equal('€1200 EUR', Currency.display('EUR', 1200))
+ assert.are_equal('€ EUR', Currency.display('EUR'))
+ assert.are_equal('€ EUR', Currency.display('EUR', nil, {useHtmlStyling = false}))
+ end)
+ end)
+end)
diff --git a/spec/date_ext_spec.lua b/spec/date_ext_spec.lua
new file mode 100644
index 00000000000..bcf628de18e
--- /dev/null
+++ b/spec/date_ext_spec.lua
@@ -0,0 +1,67 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('Variables', function()
+ local Variables = require('Module:Variables')
+
+ local DateExt = require('Module:Date/Ext')
+
+ local LanguageMock
+
+ before_each(function()
+ -- Because of the complex nature of `formatDate`, a lot of the tests are just "check it has been called"
+ LanguageMock = mock(mw.language, true)
+ end)
+
+ describe('read timestamp', function()
+ it('verify', function()
+ DateExt.readTimestamp('2021-10-17 17:40 EDT')
+ assert.stub(LanguageMock.formatDate).was.called_with(LanguageMock, 'U', '20211017 17:40 -4:00')
+
+ DateExt.readTimestamp('2021-10-17 21:40')
+ assert.stub(LanguageMock.formatDate).was.called_with(LanguageMock, 'U', '20211017 21:40')
+ end)
+ end)
+
+ describe('format', function()
+ it('verify', function()
+ DateExt.formatTimestamp('c', 1634506800)
+ assert.stub(LanguageMock.formatDate).was.called_with(LanguageMock, 'c', '@' .. 1634506800)
+ end)
+ end)
+
+ describe('toYmdInUtc', function()
+ it('verify', function()
+ DateExt.toYmdInUtc('November 08, 2021 - 13:00 CET')
+ assert.stub(LanguageMock.formatDate).was.called_with(LanguageMock, 'Y-m-d', '@')
+ end)
+ end)
+
+ describe('getContextualDateOrNow', function()
+ it('verify', function()
+ assert.are_equal(os.date('%F'), DateExt.getContextualDateOrNow())
+ assert.are_equal(nil, DateExt.getContextualDate())
+
+ Variables.varDefine('tournament_startdate', '2021-12-24')
+ assert.are_equal('2021-12-24', DateExt.getContextualDateOrNow())
+ assert.are_equal('2021-12-24', DateExt.getContextualDate())
+
+ Variables.varDefine('tournament_enddate', '2021-12-28')
+ assert.are_equal('2021-12-28', DateExt.getContextualDateOrNow())
+ assert.are_equal('2021-12-28', DateExt.getContextualDate())
+
+ Variables.varDefine('tournament_startdate')
+ Variables.varDefine('tournament_enddate')
+ end)
+ end)
+
+ describe('parse iso date', function()
+ it('verify', function()
+ assert.are_same({year = 2023, month = 7, day = 24}, DateExt.parseIsoDate('2023-07-24'))
+ assert.are_same({year = 2023, month = 7, day = 24},
+ DateExt.parseIsoDate('2023-07-24asdkosdkmoasjoikmakmslkm'))
+ assert.are_same({year = 2023, month = 7, day = 1}, DateExt.parseIsoDate('2023-07'))
+ assert.are_same({year = 2023, month = 7, day = 1}, DateExt.parseIsoDate('2023-07sdfsdfdfs'))
+ assert.are_same({year = 2023, month = 1, day = 1}, DateExt.parseIsoDate('2023'))
+ assert.is_nil(DateExt.parseIsoDate())
+ end)
+ end)
+end)
diff --git a/spec/flags_spec.lua b/spec/flags_spec.lua
new file mode 100644
index 00000000000..03ca1398096
--- /dev/null
+++ b/spec/flags_spec.lua
@@ -0,0 +1,89 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('flags', function()
+ local Flags = require('Module:Flags')
+ local Template = require('Module:Template')
+
+ describe('icon', function()
+ it('check', function()
+ local nlOutput = '[[File:nl_hd.png|36x24px|Netherlands|link=]]'
+ local nlOutputLink = '[[File:nl_hd.png|36x24px|Netherlands|link=Category:Netherlands]]'
+
+ assert.are_equal(nlOutput, Flags.Icon('nl'))
+ assert.are_equal(nlOutput, Flags.Icon('nld'))
+ assert.are_equal(nlOutput, Flags.Icon('holland'))
+ assert.are_equal(nlOutput, Flags.Icon({}, 'nl'))
+ assert.are_equal(nlOutput, Flags.Icon({}, 'nld'))
+ assert.are_equal(nlOutput, Flags.Icon({}, 'holland'))
+ assert.are_equal(nlOutputLink, Flags.Icon({shouldLink = true}, 'nl'))
+ assert.are_equal(nlOutputLink, Flags.Icon({shouldLink = true}, 'nld'))
+ assert.are_equal(nlOutputLink, Flags.Icon({shouldLink = true}, 'holland'))
+ assert.are_equal(nlOutput, Flags.Icon({shouldLink = false}, 'nl'))
+ assert.are_equal(nlOutput, Flags.Icon({shouldLink = false}, 'nld'))
+ assert.are_equal(nlOutput, Flags.Icon({shouldLink = false}, 'holland'))
+ assert.are_equal(nlOutputLink, Flags.Icon{shouldLink = true, flag = 'nl'})
+ assert.are_equal(nlOutputLink, Flags.Icon{shouldLink = true, flag = 'nld'})
+ assert.are_equal(nlOutputLink, Flags.Icon{shouldLink = true, flag = 'holland'})
+ assert.are_equal(nlOutput, Flags.Icon{shouldLink = false, flag = 'nl'})
+ assert.are_equal(nlOutput, Flags.Icon{shouldLink = false, flag = 'nld'})
+ assert.are_equal(nlOutput, Flags.Icon{shouldLink = false, flag = 'holland'})
+
+ assert.are_equal('[[File:Space filler flag.png|36x24px|link=]]',
+ Flags.Icon{flag = 'tbd'})
+
+ local TemplateMock = stub(Template, "safeExpand")
+
+ Flags.Icon{shouldLink = true, flag = 'dummy'}
+ assert.stub(TemplateMock).was.called_with(nil, 'Flag/dummy')
+
+ Flags.Icon{shouldLink = false, flag = 'dummy'}
+ assert.stub(TemplateMock).was.called_with(nil, 'FlagNoLink/dummy')
+ end)
+ end)
+
+ describe('localisation', function()
+ it('check', function()
+ local nlOutput = 'Dutch'
+ assert.are_equal(nlOutput, Flags.getLocalisation('nl'))
+ assert.are_equal(nlOutput, Flags.getLocalisation('Netherlands'))
+ assert.are_equal(nlOutput, Flags.getLocalisation('netherlands'))
+ assert.are_equal(nlOutput, Flags.getLocalisation('holland'))
+ end)
+ end)
+
+ describe('language icon', function()
+ it('check', function()
+ assert.are_equal('[[File:UsGb hd.png|36x24px|English Speaking|link=]]',
+ Flags.languageIcon('en'))
+ assert.are_equal('[[File:nl_hd.png|36x24px|Netherlands|link=]]',
+ Flags.languageIcon('nl'))
+ end)
+ end)
+
+ describe('country name', function()
+ it('check', function()
+ local nlOutput = 'Netherlands'
+ assert.are_equal(nlOutput, Flags.CountryName('nl'))
+ assert.are_equal(nlOutput, Flags.CountryName('Netherlands'))
+ assert.are_equal(nlOutput, Flags.CountryName('netherlands'))
+ assert.are_equal(nlOutput, Flags.CountryName('holland'))
+ end)
+ end)
+
+ describe('country code', function()
+ it('check', function()
+ local nlOutput = 'nl'
+ assert.are_equal(nlOutput, Flags.CountryCode('nl'))
+ assert.are_equal(nlOutput, Flags.CountryCode('Netherlands'))
+ assert.are_equal(nlOutput, Flags.CountryCode('netherlands'))
+ assert.are_equal(nlOutput, Flags.CountryCode('holland'))
+ end)
+ end)
+
+ describe('is valid flag', function()
+ it('check', function()
+ assert.is_true(Flags.isValidFlagInput('de'))
+ assert.is_true(Flags.isValidFlagInput('germany'))
+ assert.is_false(Flags.isValidFlagInput('aaaaaaa'))
+ end)
+ end)
+end)
diff --git a/spec/locale_spec.lua b/spec/locale_spec.lua
new file mode 100644
index 00000000000..f9cd0d974db
--- /dev/null
+++ b/spec/locale_spec.lua
@@ -0,0 +1,30 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('Variables', function()
+ local Locale = require('Module:Locale')
+
+ local NON_BREAKING_SPACE = ' '
+
+ describe('format location', function()
+ it('verify', function()
+ assert.are_equal('', Locale.formatLocation{})
+ assert.are_equal('abc,' .. NON_BREAKING_SPACE, Locale.formatLocation{city = 'abc'})
+ assert.are_equal('Sweden', Locale.formatLocation{country = 'Sweden'})
+ assert.are_equal('abc,' .. NON_BREAKING_SPACE .. 'Sweden',
+ Locale.formatLocation{city = 'abc', country = 'Sweden'})
+ end)
+ end)
+
+ describe('format locations', function()
+ it('verify', function()
+ local test1 = {venue = 'Abc', country1 = 'Sweden', country2 = 'Europe'}
+ local result1 = {country1 = 'se', region2 = 'Europe', venue1 = 'Abc'}
+
+ local test2 = {venue = 'Abc', country1 = 'Sweden', region1 = 'Europe', venuelink = 'https://lmgtfy.app/'}
+ local result2 = {country1 = 'se', region1 = 'Europe', venue1 = 'Abc', venuelink1 = 'https://lmgtfy.app/'}
+
+ assert.are_same(result1, Locale.formatLocations(test1))
+ assert.are_same(result2, Locale.formatLocations(test2))
+ assert.are_same({}, Locale.formatLocations{dummy = true})
+ end)
+ end)
+end)
diff --git a/spec/logic_spec.lua b/spec/logic_spec.lua
new file mode 100644
index 00000000000..97153cfb72d
--- /dev/null
+++ b/spec/logic_spec.lua
@@ -0,0 +1,191 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('logic', function()
+ local Logic = require('Module:Logic')
+ local Table = require('Module:Table')
+
+ describe('EmptyOr', function()
+ it('check', function()
+ assert.are_equal(1, Logic.emptyOr(1, 2, 3))
+ assert.are_equal(1, Logic.emptyOr(1, 2))
+ assert.are_equal(1, Logic.emptyOr(1, nil, 3))
+ assert.are_equal(1, Logic.emptyOr(1, '', 3))
+ assert.are_equal(1, Logic.emptyOr(1))
+ assert.are_equal(2, Logic.emptyOr(nil, 2, 3))
+ assert.are_equal(2, Logic.emptyOr('', 2, 3))
+ assert.are_equal(2, Logic.emptyOr(nil, 2))
+ assert.are_equal(2, Logic.emptyOr('', 2))
+ assert.are_equal(3, Logic.emptyOr(nil, nil, 3))
+ assert.are_equal(3, Logic.emptyOr({}, '', 3))
+ assert.is_nil(Logic.emptyOr())
+ end)
+ end)
+
+ describe('NilOr', function()
+ it('check', function()
+ assert.are_equal(1, Logic.nilOr(1, 2, 3))
+ assert.are_equal(1, Logic.nilOr(1, 2))
+ assert.are_equal(1, Logic.nilOr(1, nil, 3))
+ assert.are_equal(1, Logic.nilOr(1, '', 3))
+ assert.are_equal(1, Logic.nilOr(1))
+ assert.are_equal(2, Logic.nilOr(nil, 2, 3))
+ assert.are_equal('', Logic.nilOr('', 2, 3))
+ assert.are_equal(2, Logic.nilOr(nil, 2))
+ assert.are_equal('', Logic.nilOr('', 2))
+ assert.are_equal(3, Logic.nilOr(nil, nil, 3))
+ assert.are_same({}, Logic.nilOr({}, '', 3))
+ assert.is_nil(Logic.nilOr())
+ assert.are_equal(5, Logic.nilOr(nil, nil, nil, nil, 5))
+ end)
+ end)
+
+ describe('IsEmpty', function()
+ it('check', function()
+ assert.is_true(Logic.isEmpty({}))
+ assert.is_true(Logic.isEmpty())
+ assert.is_true(Logic.isEmpty(''))
+ assert.is_false(Logic.isEmpty({''}))
+ assert.is_false(Logic.isEmpty({'string'}))
+ assert.is_false(Logic.isEmpty({{}}))
+ assert.is_false(Logic.isEmpty(1))
+ assert.is_false(Logic.isEmpty('string'))
+ end)
+ end)
+
+ describe('IsDeepEmpty', function()
+ it('check', function()
+ assert.is_true(Logic.isDeepEmpty({}))
+ assert.is_true(Logic.isDeepEmpty())
+ assert.is_true(Logic.isDeepEmpty(''))
+ assert.is_true(Logic.isDeepEmpty({''}))
+ assert.is_false(Logic.isDeepEmpty({'string'}))
+ assert.is_true(Logic.isDeepEmpty({{}}))
+ assert.is_false(Logic.isDeepEmpty(1))
+ assert.is_false(Logic.isDeepEmpty('string'))
+ end)
+ end)
+
+ describe('ReadBool', function()
+ it('check', function()
+ assert.is_true(Logic.readBool(1))
+ assert.is_true(Logic.readBool('true'))
+ assert.is_true(Logic.readBool(true))
+ assert.is_true(Logic.readBool('t'))
+ assert.is_true(Logic.readBool('y'))
+ assert.is_true(Logic.readBool('yes'))
+ assert.is_true(Logic.readBool('1'))
+ assert.is_false(Logic.readBool(0))
+ assert.is_false(Logic.readBool(false))
+ assert.is_false(Logic.readBool('false'))
+ assert.is_false(Logic.readBool('f'))
+ assert.is_false(Logic.readBool('0'))
+ assert.is_false(Logic.readBool('no'))
+ assert.is_false(Logic.readBool('n'))
+ assert.is_false(Logic.readBool('someBs'))
+ assert.is_false(Logic.readBool())
+ ---intended bad value
+ ---@diagnostic disable-next-line: param-type-mismatch
+ assert.is_false(Logic.readBool{})
+ end)
+ end)
+
+ describe('ReadBoolOrNil', function()
+ it('check', function()
+ assert.is_true(Logic.readBoolOrNil(1))
+ assert.is_true(Logic.readBoolOrNil('true'))
+ assert.is_true(Logic.readBoolOrNil(true))
+ assert.is_true(Logic.readBoolOrNil('t'))
+ assert.is_true(Logic.readBoolOrNil('y'))
+ assert.is_true(Logic.readBoolOrNil('yes'))
+ assert.is_true(Logic.readBoolOrNil('1'))
+ assert.is_false(Logic.readBoolOrNil(0))
+ assert.is_false(Logic.readBoolOrNil(false))
+ assert.is_false(Logic.readBoolOrNil('false'))
+ assert.is_false(Logic.readBoolOrNil('f'))
+ assert.is_false(Logic.readBoolOrNil('0'))
+ assert.is_false(Logic.readBoolOrNil('no'))
+ assert.is_false(Logic.readBoolOrNil('n'))
+ assert.is_nil(Logic.readBoolOrNil('someBs'))
+ assert.is_nil(Logic.readBoolOrNil())
+ ---intended bad value
+ ---@diagnostic disable-next-line: param-type-mismatch
+ assert.is_nil(Logic.readBoolOrNil{})
+ end)
+ end)
+
+ describe('NilThrows', function()
+ it('check', function()
+ assert.are_equal('someVal', Logic.nilThrows('someVal'))
+ assert.are_equal('', Logic.nilThrows(''))
+ assert.are_equal(1, Logic.nilThrows(1))
+ assert.are_same({'someVal'}, Logic.nilThrows({'someVal'}))
+ assert.are_same({}, Logic.nilThrows({}))
+ assert.error(function() return Logic.nilThrows() end)
+ end)
+ end)
+
+ describe('TryCatch', function()
+ it('check', function()
+ local errorCaught = false
+ local catch = function(errorMessage) errorCaught = true end
+
+ assert.is_nil(Logic.tryCatch(function() error() end, catch))
+ assert.is_true(errorCaught)
+ errorCaught = false
+
+ assert.is_nil(Logic.tryCatch(function() error('some error') end, catch))
+ assert.is_true(errorCaught)
+ errorCaught = false
+
+ assert.is_nil(Logic.tryCatch(function() assert(false, 'some failed assert') end, catch))
+ assert.is_true(errorCaught)
+ errorCaught = false
+
+ assert.are_equal('someVal', Logic.tryCatch(function() return 'someVal' end, catch))
+ assert.is_false(errorCaught)
+ end)
+ end)
+
+ describe('IsNumeric', function()
+ it('check', function()
+ assert.is_true(Logic.isNumeric(1.5))
+ assert.is_true(Logic.isNumeric('1.5'))
+ assert.is_true(Logic.isNumeric('4.57e-3'))
+ assert.is_true(Logic.isNumeric(4.57e-3))
+ assert.is_true(Logic.isNumeric(0.3e12))
+ assert.is_true(Logic.isNumeric('0.3e12'))
+ assert.is_true(Logic.isNumeric(5e+20))
+ assert.is_true(Logic.isNumeric('5e+20'))
+ assert.is_false(Logic.isNumeric('1+2'))
+ assert.is_false(Logic.isNumeric())
+ assert.is_false(Logic.isNumeric('string'))
+ ---intended bad value
+ ---@diagnostic disable-next-line: param-type-mismatch
+ assert.is_false(Logic.isNumeric{})
+ ---intended bad value
+ ---@diagnostic disable-next-line: param-type-mismatch
+ assert.is_false(Logic.isNumeric{just = 'a table'})
+ end)
+ end)
+
+ describe('deepEquals', function()
+ it('check', function()
+ assert.is_true(Logic.deepEquals(1, 1))
+ assert.is_false(Logic.deepEquals(1, 2))
+ assert.is_true(Logic.deepEquals('a', 'a'))
+ assert.is_false(Logic.deepEquals('a', 'b'))
+
+ local tbl1 = {1, 2, {3, 4, {a = 'b'}}}
+ local tbl2 = {1, 2, {3, 4, {a = 'c'}}}
+ local tbl3 = {1, 2, {3, 4, {a = 'b'}, 6}}
+ assert.is_true(Logic.deepEquals(tbl1, tbl1))
+ assert.is_true(Logic.deepEquals(tbl1, Table.deepCopy(tbl1)))
+ assert.is_false(Logic.deepEquals(tbl1, tbl2))
+ assert.is_false(Logic.deepEquals(tbl1, tbl3))
+ end)
+ end)
+
+ --currently not testing:
+ ---try - just uses `Module:ResultOrError`
+ ---tryOrElseLog - uses `.try` plus `:catch` and `:get`
+ ---wrapTryOrLog - basically tryOrElseLog
+end)
diff --git a/spec/page_spec.lua b/spec/page_spec.lua
new file mode 100644
index 00000000000..b049a593437
--- /dev/null
+++ b/spec/page_spec.lua
@@ -0,0 +1,50 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('Page', function()
+ local Page = require('Module:Page')
+
+ local orig = mw.title.new
+ before_each(function()
+ mw.title.new = spy.new(function(page)
+ if page == 'https://google.com' then
+ return nil
+ end
+ return {exists = page == 'Module:Page'}
+ end)
+ end)
+ after_each(function()
+ mw.title.new = orig
+ end)
+
+ describe('exists', function()
+ it('verify', function()
+ assert.is_false(Page.exists('https://google.com'))
+ assert.is_false(Page.exists('PageThatDoesntExistPlx'))
+ assert.is_true(Page.exists('Module:Page'))
+ end)
+ end)
+
+ describe('internal link', function()
+ it('verify', function()
+ assert.are_equal('[[Module:Page|Module:Page]]', Page.makeInternalLink('Module:Page'))
+ assert.are_equal('[[Module:Page|DisplayText]]', Page.makeInternalLink('DisplayText', 'Module:Page'))
+ assert.are_equal('[[Module:Page|DisplayText]]', Page.makeInternalLink({}, 'DisplayText', 'Module:Page'))
+ assert.is_nil(
+ Page.makeInternalLink({onlyIfExists = true}, 'DisplayText', 'Module:PageThatDoesntExistPlx')
+ )
+ assert.are_equal(
+ '[[Module:Page|DisplayText]]',
+ Page.makeInternalLink({onlyIfExists = true}, 'DisplayText', 'Module:Page')
+ )
+ assert.is_nil(Page.makeInternalLink({}))
+ end)
+ end)
+
+ describe('external link', function()
+ it('verify', function()
+ assert.is_nil(Page.makeExternalLink('Display', ''))
+ assert.is_nil(Page.makeExternalLink('', 'https://google.com'))
+ assert.are_equal('[https://google.com Display Text]',
+ Page.makeExternalLink('Display Text', 'https://google.com'))
+ end)
+ end)
+end)
diff --git a/spec/test_helper.lua b/spec/test_helper.lua
new file mode 100644
index 00000000000..9a3dd00d2a5
--- /dev/null
+++ b/spec/test_helper.lua
@@ -0,0 +1,66 @@
+-- luacheck: ignore
+
+-- Copy from standard/lua.lua
+local function fileExists(name)
+ if package.loaded[name] then
+ return true
+ else
+ -- Package.Searchers was renamed from Loaders in lua5.2, have support for both
+ ---@diagnostic disable-next-line: deprecated
+ for _, searcher in ipairs(package.searchers or package.loaders) do
+ local loader = searcher(name)
+ if type(loader) == 'function' then
+ package.preload[name] = loader
+ return true
+ end
+ end
+ return false
+ end
+end
+
+local function resetMediawiki()
+ mw.ext.VariablesLua.variablesStorage = {}
+end
+
+local function setupForTesting()
+ require('definitions.mw')
+
+ package.path = '?.lua;' ..
+ 'standard/?.lua;' .. -- Load std folder
+ package.path
+
+ local require_original = require
+ local Plugin = require_original('plugins.sumneko_plugin')
+
+ function require(module)
+ local newName = module
+ if (string.find(module, 'Module:')) then
+ newName = Plugin.luaifyModuleName(module)
+ end
+
+ if fileExists(newName) then
+ return require_original(newName)
+ end
+
+ if newName == 'info' then
+ return require_original('info.commons.info')
+ end
+
+ if newName == 'region' or newName == 'region_data' then
+ return require('region.commons.' .. newName)
+ end
+
+ -- Just apply a fake function that returns the first input, as something
+ local mocked_import = {}
+ setmetatable(mocked_import, {
+ __index = function(t, k)
+ return function(v) return v end
+ end
+ })
+
+ return mocked_import
+ end
+end
+
+require('busted').subscribe({'suite', 'start'}, setupForTesting)
+require('busted').subscribe({'test', 'start'}, resetMediawiki)
diff --git a/spec/variables_spec.lua b/spec/variables_spec.lua
new file mode 100644
index 00000000000..1f22407ac65
--- /dev/null
+++ b/spec/variables_spec.lua
@@ -0,0 +1,37 @@
+--- Triple Comment to Enable our LLS Plugin
+describe('Variables', function()
+ local Variables = require('Module:Variables')
+
+ describe('varDefine', function()
+ it('verify', function()
+ assert.are_equal('', Variables.varDefine('test', 'foo'))
+ assert.are_equal('foo', Variables.varDefault('test'))
+
+ assert.are_equal('bar', Variables.varDefineEcho('test', 'bar'))
+ assert.are_equal('bar', Variables.varDefault('test'))
+
+ assert.are_equal('', Variables.varDefine('test', 3))
+ assert.are_equal('3', Variables.varDefault('test'))
+
+ assert.are_equal('', Variables.varDefine('test'))
+ assert.is_nil(Variables.varDefault('test'))
+ end)
+ end)
+
+ describe('varDefault', function()
+ it('verify', function()
+ Variables.varDefine('test', 'foo')
+ assert.are_equal('foo', Variables.varDefault('test'))
+ assert.is_nil(Variables.varDefault('bar'))
+ assert.are_equal('baz', Variables.varDefault('bar', 'baz'))
+ end)
+ end)
+
+ describe('VarDefaultMulti', function()
+ it('verify', function()
+ Variables.varDefine('baz', 'hello world')
+ assert.are_equal('hello world', Variables.varDefaultMulti('foo', 'bar', 'baz'))
+ assert.are_equal('banana', Variables.varDefaultMulti('foo', 'bar', 'banana'))
+ end)
+ end)
+end)
diff --git a/standard/currency/currency.lua b/standard/currency.lua
similarity index 98%
rename from standard/currency/currency.lua
rename to standard/currency.lua
index ed8284a8196..213831dc679 100644
--- a/standard/currency/currency.lua
+++ b/standard/currency.lua
@@ -11,7 +11,7 @@ local Arguments = require('Module:Arguments')
local CurrencyData = mw.loadData('Module:Currency/Data')
local Info = mw.loadData('Module:Info')
local Logic = require('Module:Logic')
-local Math = require('Module:Math')
+local Math = require('Module:MathUtil')
local String = require('Module:StringUtils')
local Variables = require('Module:Variables')
@@ -143,9 +143,11 @@ function Currency.formatMoney(value, precision, forceRoundPrecision, dashIfZero)
if not Logic.isNumeric(value) or (tonumber(value) == 0 and not forceRoundPrecision) then
return dashIfZero and DASH or 0
end
+ ---@cast value number
+
precision = tonumber(precision) or Info.defaultRoundPrecision or DEFAULT_ROUND_PRECISION
- local roundedValue = Math.round{value, precision}
+ local roundedValue = Math.round(value, precision)
local integer, decimal = math.modf(roundedValue)
if precision <= 0 or decimal == 0 and not forceRoundPrecision then
diff --git a/standard/currency/currency_data.lua b/standard/currency_data.lua
similarity index 100%
rename from standard/currency/currency_data.lua
rename to standard/currency_data.lua
diff --git a/standard/date_ext.lua b/standard/date_ext.lua
index a78689e3e4d..cad2c5445ad 100644
--- a/standard/date_ext.lua
+++ b/standard/date_ext.lua
@@ -7,7 +7,6 @@
--
local Logic = require('Module:Logic')
-local String = require('Module:StringUtils')
local Variables = require('Module:Variables')
--[[
@@ -104,11 +103,16 @@ function DateExt.parseIsoDate(str)
return
end
local year, month, day = str:match('^(%d%d%d%d)%-?(%d?%d?)%-?(%d?%d?)')
+ year, month, day = tonumber(year), tonumber(month), tonumber(day)
+
+ if not year then
+ return
+ end
-- Default month and day to 1 if not set
- if String.isEmpty(month) then
+ if not month then
month = 1
end
- if String.isEmpty(day) then
+ if not day then
day = 1
end
-- create simplified osdate
diff --git a/standard/flags.lua b/standard/flags.lua
index 7a98d00e548..294dc8c4aab 100644
--- a/standard/flags.lua
+++ b/standard/flags.lua
@@ -233,14 +233,17 @@ Flags.readKey('Czechoslovakia') -- returns nil
---@return string?
function Flags._convertToKey(flagName)
-- lowercase all unicode
- flagName = mw.ustring.lower(flagName)
-- removes all accents and special characters
- flagName = string.gsub(mw.ustring.toNFKD(flagName), '[^%l]', '')
+ local parsedName = mw.ustring.toNFKD(mw.ustring.lower(flagName))
+ if not parsedName then
+ return
+ end
+ parsedName = string.gsub(parsedName, '[^%l]', '')
- return MasterData.twoLetter[flagName]
- or MasterData.threeLetter[flagName]
- or MasterData.aliases[flagName]
- or (MasterData.data[flagName] and flagName)
+ return MasterData.twoLetter[parsedName]
+ or MasterData.threeLetter[parsedName]
+ or MasterData.aliases[parsedName]
+ or (MasterData.data[parsedName] and parsedName)
end
---@param langName string
diff --git a/standard/logic.lua b/standard/logic.lua
index 8ce93d3f09d..79911c60cc1 100644
--- a/standard/logic.lua
+++ b/standard/logic.lua
@@ -6,8 +6,6 @@
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute
--
-local Error = require('Module:Error')
-
local Logic = {}
---Returns `val1` if it isn't empty else returns `val2` if that isn't empty, else returns default
@@ -149,7 +147,7 @@ function Logic.tryOrElseLog(f, other, makeError)
return Logic.try(f)
:catch(function(error)
if type(error) == 'string' then
- error = Error(error)
+ error = require('Module:Error')(error)
end
error.header = 'Error occured while calling a function: (caught by Logic.tryOrElseLog)'
diff --git a/standard/math_util.lua b/standard/math_util.lua
index 311566ec258..9f7ea4b5bb1 100644
--- a/standard/math_util.lua
+++ b/standard/math_util.lua
@@ -76,4 +76,13 @@ function MathUtil.dotProduct(xs, ys)
return sum
end
+---Rounds a number to specified precision
+---@param value number
+---@param precision number?
+---@return number
+function MathUtil.round(value, precision)
+ local rescale = math.pow(10, precision or 0);
+ return math.floor(value * rescale + 0.5) / rescale;
+end
+
return MathUtil
diff --git a/standard/test/abbreviation_test.lua b/standard/test/abbreviation_test.lua
deleted file mode 100644
index 9d468c519fe..00000000000
--- a/standard/test/abbreviation_test.lua
+++ /dev/null
@@ -1,22 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Abbreviation/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Abbreviation = Lua.import('Module:Abbreviation', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testMakeAbbr()
- self:assertEquals(nil, Abbreviation.make())
- self:assertEquals(nil, Abbreviation.make(''))
- self:assertEquals('Cake', Abbreviation.make('Cake', 'Cookie'))
-end
-
-return suite
diff --git a/standard/test/array_test.lua b/standard/test/array_test.lua
deleted file mode 100644
index 8f317582b4c..00000000000
--- a/standard/test/array_test.lua
+++ /dev/null
@@ -1,175 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Array/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local Table = require('Module:Table')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Array = Lua.import('Module:Array', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testIsArray()
- self:assertTrue(Array.isArray{})
- self:assertTrue(Array.isArray{5, 2, 3})
- self:assertFalse(Array.isArray{a = 1, [3] = 2, c = 3})
- self:assertFalse(Array.isArray{5, 2, c = 3})
-end
-
-function suite:testCopy()
- local a, b, c = {1, 2, 3}, {}, {{5}}
- self:assertDeepEquals(a, Array.copy(a))
- self:assertFalse(Array.copy(b) == b)
- self:assertTrue(Array.copy(c)[1] == c[1])
-end
-
-function suite:testSub()
- local a = {3, 5, 7, 11}
- self:assertDeepEquals({5, 7, 11}, Array.sub(a, 2))
- self:assertDeepEquals({5, 7}, Array.sub(a, 2, 3))
- self:assertDeepEquals({7, 11}, Array.sub(a, -2, -1))
-end
-
-function suite:testMap()
- local a = {1, 2, 3}
- self:assertDeepEquals({2, 4, 6}, Array.map(a, function(x)
- return 2 * x
- end))
-end
-
-function suite:testFilter()
- local a = {1, 2, 3}
- self:assertDeepEquals({1, 3}, Array.filter(a, function(x)
- return x % 2 == 1 end
- ))
-end
-
-function suite:testFlatten()
- local a = {1, 2, 3, {5, 3}, {6, 4}}
- self:assertDeepEquals({1, 2, 3, 5, 3, 6, 4}, Array.flatten(a))
-end
-
-function suite:testAll()
- local a = {1, 2, 3}
- self:assertTrue(Array.all(a, function (value)
- return type(value) == 'number'
- end))
- self:assertFalse(Array.all(a, function (value)
- return value < 3
- end))
-end
-
-function suite:testAny()
- local a = {1, 2, 3}
- self:assertFalse(Array.any(a, function (value)
- return type(value) == 'string'
- end))
- self:assertTrue(Array.any(a, function (value)
- return value < 3
- end))
-end
-
-function suite:testFind()
- local a = {4, 6, 9}
- local b = Array.find(a, function (value, index)
- return index == 2
- end)
- local c = Array.find(a, function (value, index)
- return index == -1
- end)
- self:assertEquals(6, b)
- self:assertEquals(nil, c)
-end
-
-function suite:testRevese()
- local a = {4, 6, 9}
- self:assertDeepEquals({9, 6, 4}, Array.reverse(a))
-end
-
-function suite:testAppend()
- local a = {2, 3}
- self:assertDeepEquals({2, 3, 5, 7, 11}, Array.append(a, 5, 7, 11))
- self:assertDeepEquals({2, 3}, a)
-end
-
-function suite:testAppendWith()
- local a = {2, 3}
- self:assertDeepEquals({2, 3, 5, 7, 11}, Array.appendWith(a, 5, 7, 11))
- self:assertDeepEquals({2, 3, 5, 7, 11}, a)
-end
-
-function suite:testExtend()
- local a, b, c = {2, 3}, {5, 7, 11}, {13}
- self:assertDeepEquals({2, 3, 5, 7, 11, 13}, Array.extend(a, b, c))
- self:assertDeepEquals({2, 3}, a)
-end
-
-function suite:testExtendWith()
- local a, b, c = {2, 3}, {5, 7, 11}, {13}
- self:assertDeepEquals({2, 3, 5, 7, 11, 13}, Array.extendWith(a, b, c))
- self:assertDeepEquals({2, 3, 5, 7, 11, 13}, a)
-end
-
-function suite:testMapIndexes()
- local a = {p1 = 'Abc', p2 = 'cd', p3 = 'cake'}
- self:assertDeepEquals({'p1Abc', 'p2cd'}, Array.mapIndexes(function(x)
- local prefix = 'p'.. x
- return a[prefix] ~= 'cake' and (prefix .. a[prefix]) or nil
- end))
-end
-
-function suite:testRange()
- self:assertDeepEquals({1, 2, 3}, Array.range(1, 3))
- self:assertDeepEquals({2, 3}, Array.range(2, 3))
-end
-
-function suite:testForEach()
- local a = {}
- Array.forEach(Array.range(1, 3), function(x)
- table.insert(a, 1, x)
- end)
- self:assertDeepEquals({3, 2, 1}, a)
-end
-
-function suite:testReduce()
- local function pow(x, y) return x ^ y end
- self:assertDeepEquals(32768, Array.reduce({2, 3, 5}, pow))
- self:assertDeepEquals(1, Array.reduce({2, 3, 5}, pow, 1))
-end
-
-function suite:testExtractValues()
- local a = {i = 1, j = 2, k = 3, z = 0}
-
- local customOrder1 = function(_, key1, key2) return key1 > key2 end
- local customOrder2 = function(tbl, key1, key2) return tbl[key1] < tbl[key2] end
-
- self:assertDeepEquals({1, 2, 3, 0}, Array.extractValues(a, Table.iter.spairs))
- self:assertDeepEquals({0, 3, 2, 1}, Array.extractValues(a, Table.iter.spairs, customOrder1))
- self:assertDeepEquals({0, 1, 2, 3}, Array.extractValues(a, Table.iter.spairs, customOrder2))
-
- local extractedArray = Array.extractValues(a)
- table.sort(extractedArray)
- self:assertDeepEquals({0, 1, 2, 3}, extractedArray)
-end
-
-function suite:testExtractKeys()
- local a = {k = 3, i = 1, z = 0, j = 2}
-
- local customOrder1 = function(_, key1, key2) return key1 > key2 end
- local customOrder2 = function(tbl, key1, key2) return tbl[key1] < tbl[key2] end
-
- self:assertDeepEquals({'i', 'j', 'k', 'z'}, Array.extractKeys(a, Table.iter.spairs))
- self:assertDeepEquals({'z', 'k', 'j', 'i'}, Array.extractKeys(a, Table.iter.spairs, customOrder1))
- self:assertDeepEquals({'z', 'i', 'j', 'k'}, Array.extractKeys(a, Table.iter.spairs, customOrder2))
-
- local extractedKeys = Array.extractKeys(a)
- table.sort(extractedKeys)
- self:assertDeepEquals({'i', 'j', 'k', 'z'}, extractedKeys)
-end
-
-return suite
diff --git a/standard/test/currency_test.lua b/standard/test/currency_test.lua
deleted file mode 100644
index 11cd42cdac0..00000000000
--- a/standard/test/currency_test.lua
+++ /dev/null
@@ -1,69 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Currency/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Currency = Lua.import('Module:Currency', {requireDevIfEnabled = true})
-local Variables = Lua.import('Module:Variables', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-local DASH = '-'
-
-function suite:testGetExchangeRate()
- self:assertEquals(1.45, Currency.getExchangeRate{currency = 'EUR', currencyRate = '1.45', setVariables = true})
- self:assertEquals(1.45, tonumber(Variables.varDefault('exchangerate_EUR')))
- self:assertEquals(0.97035563534035, Currency.getExchangeRate{date = '2022-10-10', currency = 'EUR'})
-end
-
-function suite:testFormatMoney()
- self:assertEquals(DASH, Currency.formatMoney('abc'))
- self:assertEquals(DASH, Currency.formatMoney(nil))
- self:assertEquals(DASH, Currency.formatMoney('0'))
- self:assertEquals(DASH, Currency.formatMoney(0))
- self:assertEquals(0, Currency.formatMoney('abc', nil, nil, false))
- self:assertEquals(0, Currency.formatMoney(nil, nil, nil, false))
- self:assertEquals('12', Currency.formatMoney(12))
- self:assertEquals('1,200', Currency.formatMoney(1200))
- self:assertEquals('1,200.00', Currency.formatMoney(1200, nil, true))
- self:assertEquals('1,200.12', Currency.formatMoney(1200.12345))
- self:assertEquals('1,200.1', Currency.formatMoney(1200.12345, 1))
- self:assertEquals('1,200.1235', Currency.formatMoney(1200.12345, 4))
-end
-
-function suite:testRaw()
- self:assertEquals(nil, Currency.raw())
- self:assertEquals(nil, Currency.raw(''))
- self:assertEquals(nil, Currency.raw('dummy'))
- self:assertDeepEquals({
- code = 'EUR',
- name = 'Euro',
- symbol = {
- hasSpace = false,
- isAfter = false,
- text = '€',
- },
- },
- Currency.raw('EUR')
- )
-end
-
-function suite:testDisplay()
- self:assertEquals(nil, Currency.display())
- self:assertEquals(nil, Currency.display(''))
- self:assertEquals(nil, Currency.display('dummy'))
- self:assertEquals(DASH, Currency.display('dummy', 0, {dashIfZero = true}))
- self:assertEquals(DASH, Currency.display('EUR', 0, {dashIfZero = true}))
- self:assertEquals('€1,200 EUR', Currency.display('EUR', 1200, {formatValue = true}))
- self:assertEquals('€1200 EUR', Currency.display('EUR', 1200))
- self:assertEquals('€ EUR', Currency.display('EUR'))
- self:assertEquals('€ EUR', Currency.display('EUR', nil, {useHtmlStyling = false}))
-end
-
-return suite
diff --git a/standard/test/date_ext_test.lua b/standard/test/date_ext_test.lua
deleted file mode 100644
index 56b0320a143..00000000000
--- a/standard/test/date_ext_test.lua
+++ /dev/null
@@ -1,57 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Date/Ext/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-local Variables = require('Module:Variables')
-
-local DateExt = Lua.import('Module:Date/Ext', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testReadTimestamp()
- self:assertEquals(1634506800, DateExt.readTimestamp('2021-10-17 17:40 EDT'))
- self:assertEquals(1634506800, DateExt.readTimestamp('2021-10-17 21:40'))
-end
-
-function suite:testFormat()
- self:assertEquals('2021-10-17T21:40:00+00:00', DateExt.formatTimestamp('c', 1634506800))
-end
-
-function suite:testToYmdInUtc()
- self:assertEquals('2021-11-08', DateExt.toYmdInUtc('November 08, 2021 - 13:00 CET'))
- self:assertEquals('2021-11-09', DateExt.toYmdInUtc('2021-11-08 17:00 PST'))
-end
-
-function suite:testGetContextualDateOrNow()
- self:assertEquals(os.date('%F'), DateExt.getContextualDateOrNow())
- self:assertEquals(nil, DateExt.getContextualDate())
-
- Variables.varDefine('tournament_startdate', '2021-12-24')
- self:assertEquals('2021-12-24', DateExt.getContextualDateOrNow())
- self:assertEquals('2021-12-24', DateExt.getContextualDate())
-
- Variables.varDefine('tournament_enddate', '2021-12-28')
- self:assertEquals('2021-12-28', DateExt.getContextualDateOrNow())
- self:assertEquals('2021-12-28', DateExt.getContextualDate())
-
- Variables.varDefine('tournament_startdate')
- Variables.varDefine('tournament_enddate')
-end
-
-function suite:parseIsoDate()
- self:assertDeepEquals({year = 2023, month = 7, day = 24}, DateExt.parseIsoDate('2023-07-24'))
- self:assertDeepEquals({year = 2023, month = 7, day = 24}, DateExt.parseIsoDate('2023-07-24asdkosdkmoasjoikmakmslkm'))
- self:assertDeepEquals({year = 2023, month = 7, day = 1}, DateExt.parseIsoDate('2023-07'))
- self:assertDeepEquals({year = 2023, month = 7, day = 1}, DateExt.parseIsoDate('2023-07sdfsdfdfs'))
- self:assertDeepEquals({year = 2023, month = 1, day = 1}, DateExt.parseIsoDate('2023'))
- self:assertDeepEquals({year = 2023, month = 1, day = 1}, DateExt.parseIsoDate('202334rdfg'))
- self:assertEquals(nil, DateExt.parseIsoDate())
-end
-
-return suite
diff --git a/standard/test/flags_test.lua b/standard/test/flags_test.lua
deleted file mode 100644
index 6df322dba7c..00000000000
--- a/standard/test/flags_test.lua
+++ /dev/null
@@ -1,81 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Flags/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Flags = Lua.import('Module:Flags', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testIcon()
- local nlOutput = '[[File:nl_hd.png|Netherlands|link=]]'
- local nlOutputLink = '[[File:nl_hd.png|Netherlands|link=Category:Netherlands]]'
- local unknownCat = '[[Category:Pages with unknown flags]]'
-
- self:assertEquals(nlOutput, Flags.Icon('nl'))
- self:assertEquals(nlOutput, Flags.Icon('nld'))
- self:assertEquals(nlOutput, Flags.Icon('holland'))
- self:assertEquals(nlOutput, Flags.Icon({}, 'nl'))
- self:assertEquals(nlOutput, Flags.Icon({}, 'nld'))
- self:assertEquals(nlOutput, Flags.Icon({}, 'holland'))
- self:assertEquals(nlOutputLink, Flags.Icon({shouldLink = true}, 'nl'))
- self:assertEquals(nlOutputLink, Flags.Icon({shouldLink = true}, 'nld'))
- self:assertEquals(nlOutputLink, Flags.Icon({shouldLink = true}, 'holland'))
- self:assertEquals(nlOutput, Flags.Icon({shouldLink = false}, 'nl'))
- self:assertEquals(nlOutput, Flags.Icon({shouldLink = false}, 'nld'))
- self:assertEquals(nlOutput, Flags.Icon({shouldLink = false}, 'holland'))
- self:assertEquals(nlOutputLink, Flags.Icon{shouldLink = true, flag = 'nl'})
- self:assertEquals(nlOutputLink, Flags.Icon{shouldLink = true, flag = 'nld'})
- self:assertEquals(nlOutputLink, Flags.Icon{shouldLink = true, flag = 'holland'})
- self:assertEquals(nlOutput, Flags.Icon{shouldLink = false, flag = 'nl'})
- self:assertEquals(nlOutput, Flags.Icon{shouldLink = false, flag = 'nld'})
- self:assertEquals(nlOutput, Flags.Icon{shouldLink = false, flag = 'holland'})
-
- self:assertEquals('[[File:Space filler flag.png|link=]]', Flags.Icon{flag = 'tbd'})
-
- self:assertEquals(('[[Template:Flag/dummy]]' .. unknownCat), Flags.Icon{shouldLink = true, flag = 'dummy'})
- self:assertEquals(('[[Template:FlagNoLink/dummy]]' .. unknownCat), Flags.Icon{shouldLink = false, flag = 'dummy'})
-end
-
-function suite:testLocalisation()
- local nlOutput = 'Dutch'
- self:assertEquals(nlOutput, Flags.getLocalisation('nl'))
- self:assertEquals(nlOutput, Flags.getLocalisation('Netherlands'))
- self:assertEquals(nlOutput, Flags.getLocalisation('netherlands'))
- self:assertEquals(nlOutput, Flags.getLocalisation('holland'))
-end
-
-function suite:testLanguageIcon()
- self:assertEquals('[[File:UsGb hd.png|English Speaking|link=]]', Flags.languageIcon('en'))
- self:assertEquals('[[File:nl_hd.png|Netherlands|link=]]', Flags.languageIcon('nl'))
-end
-
-function suite:testCountryName()
- local nlOutput = 'Netherlands'
- self:assertEquals(nlOutput, Flags.CountryName('nl'))
- self:assertEquals(nlOutput, Flags.CountryName('Netherlands'))
- self:assertEquals(nlOutput, Flags.CountryName('netherlands'))
- self:assertEquals(nlOutput, Flags.CountryName('holland'))
-end
-
-function suite:testCountryCode()
- local nlOutput = 'nl'
- self:assertEquals(nlOutput, Flags.CountryCode('nl'))
- self:assertEquals(nlOutput, Flags.CountryCode('Netherlands'))
- self:assertEquals(nlOutput, Flags.CountryCode('netherlands'))
- self:assertEquals(nlOutput, Flags.CountryCode('holland'))
-end
-
-function suite:testIsValidFlagInput()
- self:assertEquals(true, Flags.isValidFlagInput('de'))
- self:assertEquals(true, Flags.isValidFlagInput('germany'))
- self:assertEquals(false, Flags.isValidFlagInput('aaaaaaa'))
-end
-
-return suite
diff --git a/standard/test/locale_test.lua b/standard/test/locale_test.lua
deleted file mode 100644
index 26652ff4d62..00000000000
--- a/standard/test/locale_test.lua
+++ /dev/null
@@ -1,37 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Locale/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Locale = Lua.import('Module:Locale', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-local NON_BREAKING_SPACE = ' '
-
-function suite:testFormatLocation()
- self:assertEquals('', Locale.formatLocation{})
- self:assertEquals('abc,' .. NON_BREAKING_SPACE, Locale.formatLocation{city = 'abc'})
- self:assertEquals('Sweden', Locale.formatLocation{country = 'Sweden'})
- self:assertEquals('abc,'.. NON_BREAKING_SPACE .. 'Sweden', Locale.formatLocation{city = 'abc', country = 'Sweden'})
-end
-
-function suite:testLocations()
- local test1 = {venue = 'Abc', country1 = 'Sweden', country2='Europe'}
- local result1 = {country1 = 'se', region2 = 'Europe', venue1 = 'Abc'}
-
- local test2 = {venue = 'Abc', country1 = 'Sweden', region1='Europe', venuelink = 'https://lmgtfy.app/'}
- local result2 = {country1 = 'se', region1 = 'Europe', venue1 = 'Abc', venuelink1 = 'https://lmgtfy.app/'}
-
- self:assertDeepEquals(result1, Locale.formatLocations(test1))
- self:assertDeepEquals(result2, Locale.formatLocations(test2))
- self:assertDeepEquals({}, Locale.formatLocations{dummy = true})
-end
-
-return suite
diff --git a/standard/test/logic_test.lua b/standard/test/logic_test.lua
deleted file mode 100644
index 62838b0d00e..00000000000
--- a/standard/test/logic_test.lua
+++ /dev/null
@@ -1,183 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Logic/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-local Table = require('Module:Table')
-
-local Logic = Lua.import('Module:Logic', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testEmptyOr()
- self:assertEquals(1, Logic.emptyOr(1, 2, 3))
- self:assertEquals(1, Logic.emptyOr(1, 2))
- self:assertEquals(1, Logic.emptyOr(1, nil, 3))
- self:assertEquals(1, Logic.emptyOr(1, '', 3))
- self:assertEquals(1, Logic.emptyOr(1))
- self:assertEquals(2, Logic.emptyOr(nil, 2, 3))
- self:assertEquals(2, Logic.emptyOr('', 2, 3))
- self:assertEquals(2, Logic.emptyOr(nil, 2))
- self:assertEquals(2, Logic.emptyOr('', 2))
- self:assertEquals(3, Logic.emptyOr(nil, nil, 3))
- self:assertEquals(3, Logic.emptyOr({}, '', 3))
- self:assertEquals(nil, Logic.emptyOr())
-end
-
-function suite:testNilOr()
- self:assertEquals(1, Logic.nilOr(1, 2, 3))
- self:assertEquals(1, Logic.nilOr(1, 2))
- self:assertEquals(1, Logic.nilOr(1, nil, 3))
- self:assertEquals(1, Logic.nilOr(1, '', 3))
- self:assertEquals(1, Logic.nilOr(1))
- self:assertEquals(2, Logic.nilOr(nil, 2, 3))
- self:assertEquals('', Logic.nilOr('', 2, 3))
- self:assertEquals(2, Logic.nilOr(nil, 2))
- self:assertEquals('', Logic.nilOr('', 2))
- self:assertEquals(3, Logic.nilOr(nil, nil, 3))
- self:assertDeepEquals({}, Logic.nilOr({}, '', 3))
- self:assertEquals(nil, Logic.nilOr())
- self:assertEquals(5, Logic.nilOr(nil, nil, nil, nil, 5))
-end
-
-function suite:testIsEmpty()
- self:assertTrue(Logic.isEmpty({}))
- self:assertTrue(Logic.isEmpty())
- self:assertTrue(Logic.isEmpty(''))
- self:assertFalse(Logic.isEmpty({''}))
- self:assertFalse(Logic.isEmpty({'string'}))
- self:assertFalse(Logic.isEmpty({{}}))
- self:assertFalse(Logic.isEmpty(1))
- self:assertFalse(Logic.isEmpty('string'))
-end
-
-function suite:testIsDeepEmpty()
- self:assertTrue(Logic.isDeepEmpty({}))
- self:assertTrue(Logic.isDeepEmpty())
- self:assertTrue(Logic.isDeepEmpty(''))
- self:assertTrue(Logic.isDeepEmpty({''}))
- self:assertFalse(Logic.isDeepEmpty({'string'}))
- self:assertTrue(Logic.isDeepEmpty({{}}))
- self:assertFalse(Logic.isDeepEmpty(1))
- self:assertFalse(Logic.isDeepEmpty('string'))
-end
-
-function suite:testReadBool()
- self:assertTrue(Logic.readBool(1))
- self:assertTrue(Logic.readBool('true'))
- self:assertTrue(Logic.readBool(true))
- self:assertTrue(Logic.readBool('t'))
- self:assertTrue(Logic.readBool('y'))
- self:assertTrue(Logic.readBool('yes'))
- self:assertTrue(Logic.readBool('1'))
- self:assertFalse(Logic.readBool(0))
- self:assertFalse(Logic.readBool(false))
- self:assertFalse(Logic.readBool('false'))
- self:assertFalse(Logic.readBool('f'))
- self:assertFalse(Logic.readBool('0'))
- self:assertFalse(Logic.readBool('no'))
- self:assertFalse(Logic.readBool('n'))
- self:assertFalse(Logic.readBool('someBs'))
- self:assertFalse(Logic.readBool())
- ---intended bad value
- ---@diagnostic disable-next-line: param-type-mismatch
- self:assertFalse(Logic.readBool{})
-end
-
-function suite:testReadBoolOrNil()
- self:assertTrue(Logic.readBoolOrNil(1))
- self:assertTrue(Logic.readBoolOrNil('true'))
- self:assertTrue(Logic.readBoolOrNil(true))
- self:assertTrue(Logic.readBoolOrNil('t'))
- self:assertTrue(Logic.readBoolOrNil('y'))
- self:assertTrue(Logic.readBoolOrNil('yes'))
- self:assertTrue(Logic.readBoolOrNil('1'))
- self:assertFalse(Logic.readBoolOrNil(0))
- self:assertFalse(Logic.readBoolOrNil(false))
- self:assertFalse(Logic.readBoolOrNil('false'))
- self:assertFalse(Logic.readBoolOrNil('f'))
- self:assertFalse(Logic.readBoolOrNil('0'))
- self:assertFalse(Logic.readBoolOrNil('no'))
- self:assertFalse(Logic.readBoolOrNil('n'))
- self:assertEquals(nil, Logic.readBoolOrNil('someBs'))
- self:assertEquals(nil, Logic.readBoolOrNil())
- ---intended bad value
- ---@diagnostic disable-next-line: param-type-mismatch
- self:assertEquals(nil, Logic.readBoolOrNil{})
-end
-
-function suite:testNilThrows()
- self:assertEquals('someVal', Logic.nilThrows('someVal'))
- self:assertEquals('', Logic.nilThrows(''))
- self:assertEquals(1, Logic.nilThrows(1))
- self:assertDeepEquals({'someVal'}, Logic.nilThrows({'someVal'}))
- self:assertDeepEquals({}, Logic.nilThrows({}))
- self:assertThrows(function() return Logic.nilThrows() end)
-end
-
-function suite:testTryCatch()
- local errorCaught = false
- local catch = function(errorMessage) errorCaught = true end
-
- self:assertEquals(nil, Logic.tryCatch(function() error() end, catch))
- self:assertTrue(errorCaught)
- errorCaught = false
-
- self:assertEquals(nil, Logic.tryCatch(function() error('some error') end, catch))
- self:assertTrue(errorCaught)
- errorCaught = false
-
- self:assertEquals(nil, Logic.tryCatch(function() assert(false, 'some failed assert') end, catch))
- self:assertTrue(errorCaught)
- errorCaught = false
-
- self:assertEquals('someVal', Logic.tryCatch(function() return 'someVal' end, catch))
- self:assertFalse(errorCaught)
-end
-
-function suite:testIsNumeric()
- self:assertTrue(Logic.isNumeric(1.5))
- self:assertTrue(Logic.isNumeric('1.5'))
- self:assertTrue(Logic.isNumeric('4.57e-3'))
- self:assertTrue(Logic.isNumeric(4.57e-3))
- self:assertTrue(Logic.isNumeric(0.3e12))
- self:assertTrue(Logic.isNumeric('0.3e12'))
- self:assertTrue(Logic.isNumeric(5e+20))
- self:assertTrue(Logic.isNumeric('5e+20'))
- self:assertFalse(Logic.isNumeric('1+2'))
- self:assertFalse(Logic.isNumeric())
- self:assertFalse(Logic.isNumeric('string'))
- ---intended bad value
- ---@diagnostic disable-next-line: param-type-mismatch
- self:assertFalse(Logic.isNumeric{})
- ---intended bad value
- ---@diagnostic disable-next-line: param-type-mismatch
- self:assertFalse(Logic.isNumeric{just = 'a table'})
-end
-
-function suite:testDeepEquals()
- self:assertTrue(Logic.deepEquals(1, 1))
- self:assertFalse(Logic.deepEquals(1, 2))
- self:assertTrue(Logic.deepEquals('a', 'a'))
- self:assertFalse(Logic.deepEquals('a', 'b'))
-
- local tbl1 = {1, 2, {3, 4, {a = 'b'}}}
- local tbl2 = {1, 2, {3, 4, {a = 'c'}}}
- local tbl3 = {1, 2, {3, 4, {a = 'b'}, 6}}
- self:assertTrue(Logic.deepEquals(tbl1, tbl1))
- self:assertTrue(Logic.deepEquals(tbl1, Table.deepCopy(tbl1)))
- self:assertFalse(Logic.deepEquals(tbl1, tbl2))
- self:assertFalse(Logic.deepEquals(tbl1, tbl3))
-end
-
---currently not testing:
----try - just uses `Module:ResultOrError`
----tryOrElseLog - uses `.try` plus `:catch` and `:get`
----wrapTryOrLog - basically tryOrElseLog
-
-return suite
diff --git a/standard/test/page_test.lua b/standard/test/page_test.lua
deleted file mode 100644
index 8ca0520ecf6..00000000000
--- a/standard/test/page_test.lua
+++ /dev/null
@@ -1,43 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Page/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Page = Lua.import('Module:Page', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testExists()
- self:assertFalse(Page.exists('https://google.com'))
- self:assertFalse(Page.exists('PageThatDoesntExistPlx'))
- self:assertTrue(Page.exists('Module:Page'))
-end
-
-function suite:testInternalLink()
- self:assertEquals('[[Module:Page|Module:Page]]', Page.makeInternalLink('Module:Page'))
- self:assertEquals('[[Module:Page|DisplayText]]', Page.makeInternalLink('DisplayText', 'Module:Page'))
- self:assertEquals('[[Module:Page|DisplayText]]', Page.makeInternalLink({}, 'DisplayText', 'Module:Page'))
- self:assertEquals(
- nil,
- Page.makeInternalLink({onlyIfExists = true}, 'DisplayText', 'Module:PageThatDoesntExistPlx')
- )
- self:assertEquals(
- '[[Module:Page|DisplayText]]',
- Page.makeInternalLink({onlyIfExists = true}, 'DisplayText', 'Module:Page')
- )
- self:assertEquals(nil, Page.makeInternalLink({}))
-end
-
-function suite:testExternalLink()
- self:assertEquals(nil, Page.makeExternalLink('Display', ''))
- self:assertEquals(nil, Page.makeExternalLink('', 'https://google.com'))
- self:assertEquals('[https://google.com Display Text]', Page.makeExternalLink('Display Text', 'https://google.com'))
-end
-
-return suite
diff --git a/standard/test/variables_test.lua b/standard/test/variables_test.lua
deleted file mode 100644
index b044fa4211e..00000000000
--- a/standard/test/variables_test.lua
+++ /dev/null
@@ -1,43 +0,0 @@
----
--- @Liquipedia
--- wiki=commons
--- page=Module:Variables/testcases
---
--- Please see https://github.com/Liquipedia/Lua-Modules to contribute
---
-
-local Lua = require('Module:Lua')
-local ScribuntoUnit = require('Module:ScribuntoUnit')
-
-local Variables = Lua.import('Module:Variables', {requireDevIfEnabled = true})
-
-local suite = ScribuntoUnit:new()
-
-function suite:testVarDefine()
- self:assertEquals('', Variables.varDefine('test', 'foo'))
- self:assertEquals('foo', Variables.varDefault('test'))
-
- self:assertEquals('bar', Variables.varDefineEcho('test', 'bar'))
- self:assertEquals('bar', Variables.varDefault('test'))
-
- self:assertEquals('', Variables.varDefine('test', 3))
- self:assertEquals('3', Variables.varDefault('test'))
-
- self:assertEquals('', Variables.varDefine('test'))
- self:assertEquals(nil, Variables.varDefault('test'))
-end
-
-function suite:testVarDefault()
- Variables.varDefine('test', 'foo')
- self:assertEquals('foo', Variables.varDefault('test'))
- self:assertEquals(nil, Variables.varDefault('bar'))
- self:assertEquals('baz', Variables.varDefault('bar', 'baz'))
-end
-
-function suite:testVarDefaultMulti()
- Variables.varDefine('baz', 'hello world')
- self:assertEquals('hello world', Variables.varDefaultMulti('foo', 'bar', 'baz'))
- self:assertEquals('banana', Variables.varDefaultMulti('foo', 'bar', 'banana'))
-end
-
-return suite
diff --git a/standard/variables.lua b/standard/variables.lua
index 1e6cbc9c2b7..2b82d258d93 100644
--- a/standard/variables.lua
+++ b/standard/variables.lua
@@ -10,9 +10,6 @@ local Class = require('Module:Class')
local Variables = {}
----@alias wikiVaribleKey string|number
----@alias wikiVariableValue string|number|nil
-
---Stores a wiki-variable and returns the empty string
---@param name wikiVaribleKey Key of the wiki-variable
---@param value wikiVariableValue Value of the wiki-variable