Skip to content

Commit

Permalink
feat: automated testing (#3490)
Browse files Browse the repository at this point in the history
* feat: automated testing

* fix lint check

* Move busted config to file to allow for local runs too

* move the root to all

* pipeline update

* split testing to it's own workflow

* name

* remove unneeded dep

* Try to improve the pipeline

* Job names

* Merge workflow fiels

* fix typo

* add logic test

* try to have some handling for files not on git

* Remove now unneeded old style tests

* Move Abbr to automated testing

* Clean ups

* Auto enable busted and luassert vscode addons

* Remove unneeded custom path

* undo last, is needed

* typo

* Move folder for currency

* Clean the package change

* Currency Tests plus stupid mediawiki mocking

* remove print

* name tests

* Flags, rework mw handling

* Page

* Add `ustring` to mw defines

* Fix flag testcases

* add `varexists`

* Fix comment

* Handle bad input in flags.lua

* Migrate variable tests, fix var sim

* Migrate Locale tests

* Migrate date tests

* unused import
  • Loading branch information
Rathoz authored Nov 10, 2023
1 parent 85a927a commit a969054
Show file tree
Hide file tree
Showing 31 changed files with 1,175 additions and 757 deletions.
12 changes: 12 additions & 0 deletions .busted
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
return {
_all = {
verbose = true,
helper = 'spec/test_helper.lua',
},
default = {
ROOT = {"spec"},
},
ci = {
ROOT = {"spec"},
},
}
54 changes: 43 additions & 11 deletions .github/workflows/luacheck.yml
Original file line number Diff line number Diff line change
@@ -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/[email protected]
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'
6 changes: 5 additions & 1 deletion .luarc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
"diagnostics.neededFileStatus": {
"codestyle-check": "None",
"name-style-check": "None"
}
},
"workspace.library": [
"${3rd}/busted/library",
"${3rd}/luassert/library"
]
}
240 changes: 233 additions & 7 deletions definitions/mw.lua
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 = {}

Expand All @@ -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
Loading

0 comments on commit a969054

Please sign in to comment.