143 lines
4.2 KiB
Lua
143 lines
4.2 KiB
Lua
local function IsRunningInStudio()
|
|
return game:GetService("RunService"):IsStudio()
|
|
end
|
|
|
|
local function assert_(condition, message)
|
|
if IsRunningInStudio() or _G.__TESTEZ_RUNNING_TEST__ then
|
|
assert(condition, message)
|
|
end
|
|
end
|
|
|
|
local ArgCheck = {}
|
|
|
|
function ArgCheck.isNonNegativeNumber(value, name)
|
|
-- Temporarily disabled outside of studio/tests. See MOBLUAPP-1161.
|
|
assert_(typeof(value) == "number" and value >= 0, string.format("expects %s to be a non-negative number!", name))
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.isType(value, expectedType, name)
|
|
assert_(typeof(value) == expectedType,
|
|
string.format("expects %s to be a %s! it was: %s", name, expectedType, typeof(value)))
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.isInTypes(value, expectedTypes, name)
|
|
for _, expectedType in ipairs(expectedTypes) do
|
|
if typeof(value) == expectedType then
|
|
return value
|
|
end
|
|
end
|
|
|
|
assert_(false, string.format("expects %s to be one of expectedTypes! it was: %s", name, typeof(value)))
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.isTypeOrNil(value, expectedType, name)
|
|
assert_(value == nil or typeof(value) == expectedType,
|
|
string.format("expects %s to be a %s! it was: %s", name, expectedType, typeof(value)))
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.isNotNil(value, name)
|
|
assert_(value ~= nil, string.format("expects %s to be not nil!", name))
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.isNonEmptyString(value, name)
|
|
assert_(typeof(value) == "string" and value ~= "" ,
|
|
string.format("expects %s to be a non-empty string!", name))
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.isEqual(value, expectedValue, name)
|
|
assert_(value == expectedValue, string.format("expects %s to equal %s! it was: %s", name, tostring(expectedValue), tostring(value)))
|
|
|
|
return value
|
|
end
|
|
|
|
-- checks for a number or string representing an integer
|
|
function ArgCheck.representsInteger(value, name)
|
|
local numberValue = tonumber(value)
|
|
assert_(numberValue ~= nil , string.format("expects %s to represent a number!", name))
|
|
assert_(numberValue % 1 == 0 , string.format("expects %s to represent an integer!", name))
|
|
|
|
return value
|
|
end
|
|
|
|
--[[
|
|
Checks if the value matches the given interface
|
|
iface is the interface description; it can be (in order of priority):
|
|
* a custom type name: checks against a type from dependencies (see below)
|
|
* an ArgCheck handler:
|
|
* "integer" => ArgCheck.representsInteger
|
|
* "nonEmptyString" => ArgCheck.isNonEmptyString
|
|
* a lua type (string): equivalent to ArgCheck.isType
|
|
* a list style table (only first item is considered):
|
|
checks for a list table with items matching the given interface
|
|
* a dict style table: checks for a table with keys matching the given interfaces
|
|
dependencies is a table of named interfaces that can be referenced in iface
|
|
Example:
|
|
local myTypes = {
|
|
Tree = {
|
|
value = "string",
|
|
leaves = {"string"},
|
|
branches = {"Tree"},
|
|
},
|
|
}
|
|
ArgCheck.matchesInterface(someValue, "Tree", "myVal", myTypes)
|
|
]]--
|
|
function ArgCheck.matchesInterface(value, iface, name, dependencies)
|
|
if IsRunningInStudio() or _G.__TESTEZ_RUNNING_TEST__ then
|
|
local checkFnList = {
|
|
integer = ArgCheck.representsInteger,
|
|
nonEmptyString = ArgCheck.isNonEmptyString,
|
|
}
|
|
if type(iface) == "string" then
|
|
if dependencies and dependencies[iface] then
|
|
ArgCheck.matchesInterface(value, dependencies[iface], name, dependencies)
|
|
else
|
|
local checkFn = checkFnList[iface]
|
|
if type(checkFn) == "function" then
|
|
checkFn(value, name)
|
|
else
|
|
ArgCheck.isType(value, iface, name)
|
|
end
|
|
end
|
|
else
|
|
-- assume iface describes a table (list or dict)
|
|
ArgCheck.isType(value, "table", name)
|
|
if iface[1] ~= nil then
|
|
for index, item in ipairs(value) do
|
|
ArgCheck.matchesInterface(item, iface[1], name .. "[" .. index .. "]", dependencies)
|
|
end
|
|
else
|
|
for key, desc in pairs(iface) do
|
|
if string.sub(key, 1, 1) ~= "_" then
|
|
local itemName = name .. "." .. key
|
|
local itemValue = value[key]
|
|
local isRequired = iface._required and iface._required[key]
|
|
if isRequired or itemValue ~= nil then
|
|
ArgCheck.matchesInterface(itemValue, desc, itemName, dependencies)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return value
|
|
end
|
|
|
|
function ArgCheck.assert(...)
|
|
assert_(...)
|
|
end
|
|
|
|
return ArgCheck
|