add gs
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"lint": {
|
||||
"LocalShadow": "fatal",
|
||||
"LocalUnused": "fatal",
|
||||
"ImportUnused": "fatal",
|
||||
"ImplicitReturn": "fatal",
|
||||
"DeprecatedGlobal": "fatal"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
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
|
||||
@@ -0,0 +1,287 @@
|
||||
return function()
|
||||
local ArgCheck = require(script.Parent.ArgCheck)
|
||||
|
||||
describe("isNonNegativeNumber", function()
|
||||
it("should assert if given non-number, or negative number", function()
|
||||
expect(function()
|
||||
ArgCheck.isNonNegativeNumber(nil, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isNonNegativeNumber({}, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isNonNegativeNumber("string", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isNonNegativeNumber(-1, "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the value if it is a non-negative number", function()
|
||||
expect(ArgCheck.isNonNegativeNumber(0, "")).to.equal(0)
|
||||
expect(ArgCheck.isNonNegativeNumber(1, "")).to.equal(1)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("isType", function()
|
||||
it("should assert if type is wrong", function()
|
||||
expect(function()
|
||||
ArgCheck.isType(nil, "number", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isType("test", "number", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isType(5, "string", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isType(5, "table", "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the value if the type is correct", function()
|
||||
expect(ArgCheck.isType(0, "number", "")).to.equal(0)
|
||||
expect(ArgCheck.isType("test", "string", "")).to.equal("test")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("isInTypes", function()
|
||||
it("should assert if type is not expected", function()
|
||||
expect(function()
|
||||
ArgCheck.isInTypes(nil, {"number", "string", "table"}, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isInTypes("test", {"number", "table"}, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isInTypes(5, {"string", "table"}, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isInTypes({}, {"number", "string"}, "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the value if the type is expected", function()
|
||||
expect(ArgCheck.isInTypes(0, {"number", "string"}, "")).to.equal(0)
|
||||
expect(ArgCheck.isInTypes("test", {"table", "string"}, "")).to.equal("test")
|
||||
local testTable = {}
|
||||
expect(ArgCheck.isInTypes(testTable, {"table", "string"}, "")).to.equal(testTable)
|
||||
local testFunction = function() end
|
||||
expect(ArgCheck.isInTypes(testFunction, {"function", "string"}, "")).to.equal(testFunction)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("isTypeOrNil", function()
|
||||
it("should assert if type is wrong", function()
|
||||
expect(function()
|
||||
ArgCheck.isTypeOrNil("test", "number", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isTypeOrNil(5, "string", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isTypeOrNil(5, "table", "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the value if the type is correct", function()
|
||||
expect(ArgCheck.isTypeOrNil(nil, "number", "")).to.equal(nil)
|
||||
expect(ArgCheck.isTypeOrNil(0, "number", "")).to.equal(0)
|
||||
expect(ArgCheck.isTypeOrNil("test", "string", "")).to.equal("test")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("isNotNil", function()
|
||||
it("should assert if type is nil", function()
|
||||
expect(function()
|
||||
ArgCheck.isNotNil(nil, "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the value if it's not nil", function()
|
||||
expect(ArgCheck.isNotNil(0, "")).to.equal(0)
|
||||
expect(ArgCheck.isNotNil("test", "")).to.equal("test")
|
||||
local testTable = {}
|
||||
expect(ArgCheck.isNotNil(testTable, "")).to.equal(testTable)
|
||||
local testFunction = function() end
|
||||
expect(ArgCheck.isNotNil(testFunction, "")).to.equal(testFunction)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("isEqual", function()
|
||||
it("should assert if not equal", function()
|
||||
expect(function()
|
||||
ArgCheck.isEqual(0, nil, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isEqual(2, 1, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isEqual("", "test", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isEqual({}, {}, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.isEqual(function() end, function() end, "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the value if value is equal to expected value", function()
|
||||
expect(ArgCheck.isEqual(nil, nil, "")).to.equal(nil)
|
||||
expect(ArgCheck.isEqual(0, 0, "")).to.equal(0)
|
||||
expect(ArgCheck.isEqual(true, true, "")).to.equal(true)
|
||||
expect(ArgCheck.isEqual("test", "test", "")).to.equal("test")
|
||||
local testTable = {}
|
||||
expect(ArgCheck.isEqual(testTable, testTable, "")).to.equal(testTable)
|
||||
local testFunction = function() end
|
||||
expect(ArgCheck.isEqual(testFunction, testFunction, "")).to.equal(testFunction)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("representsInteger", function()
|
||||
it("should fail if not a number", function()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger(nil, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger({}, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger(function()end, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger(true, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger("NaN", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger("1test", "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should fail if not an integer", function()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger(1.5, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger("1.5", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.representsInteger("1e-1", "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the same value on success", function()
|
||||
expect(ArgCheck.representsInteger(5, "")).to.equal(5)
|
||||
expect(ArgCheck.representsInteger("-5", "")).to.equal("-5")
|
||||
expect(ArgCheck.representsInteger("1e1", "")).to.equal("1e1")
|
||||
expect(ArgCheck.representsInteger("0xa", "")).to.equal("0xa")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("matchesInterface", function()
|
||||
it("should match a simple interface", function()
|
||||
local interface = {
|
||||
num = "number",
|
||||
str = "string",
|
||||
bool = "boolean",
|
||||
func = "function",
|
||||
tab = "table",
|
||||
list = {"number"},
|
||||
-- only num is required, rest is optional
|
||||
_required = {
|
||||
num = true,
|
||||
}
|
||||
}
|
||||
local obj1 = {
|
||||
num = 5,
|
||||
str = "5",
|
||||
bool = true,
|
||||
func = function()end,
|
||||
tab = {},
|
||||
list = {1, 2, 3}
|
||||
}
|
||||
local obj2 = {
|
||||
num = "5",
|
||||
}
|
||||
local obj3 = {
|
||||
num = 5,
|
||||
list = {"NaN"},
|
||||
}
|
||||
local obj4 = {
|
||||
str = "5",
|
||||
}
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(obj1, interface, "")
|
||||
end).to.never.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(obj2, interface, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(obj3, interface, "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(obj4, interface, "")
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should match ArgCheck functions", function()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface("5", "nonEmptyString", "")
|
||||
end).to.never.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(5, "nonEmptyString", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface("", "nonEmptyString", "")
|
||||
end).to.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface({str = "5"}, {str = "nonEmptyString"}, "")
|
||||
end).to.never.throw()
|
||||
end)
|
||||
|
||||
it("should match dependent types", function()
|
||||
local types = {
|
||||
child = {
|
||||
name = "string",
|
||||
},
|
||||
parent = {
|
||||
name = "string",
|
||||
children = {"child"},
|
||||
}
|
||||
}
|
||||
local child1 = {
|
||||
name = "child1",
|
||||
}
|
||||
local child2 = {
|
||||
name = "child2",
|
||||
}
|
||||
local parent1 = {
|
||||
name = "parent1",
|
||||
children = {child1, child2},
|
||||
}
|
||||
local parent2 = {
|
||||
name = "parent2",
|
||||
children = {"child1", "child2"},
|
||||
}
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(child1, types.child, "", types)
|
||||
end).to.never.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(parent1, types.parent, "", types)
|
||||
end).to.never.throw()
|
||||
expect(function()
|
||||
ArgCheck.matchesInterface(parent2, types.parent, "", types)
|
||||
end).to.throw()
|
||||
end)
|
||||
|
||||
it("should return the same value on success", function()
|
||||
expect(ArgCheck.matchesInterface(5, "number", "")).to.equal(5)
|
||||
expect(ArgCheck.matchesInterface("5", "nonEmptyString", "")).to.equal("5")
|
||||
local list = {1, 2, 3}
|
||||
expect(ArgCheck.matchesInterface(list, {"number"}, "")).to.equal(list)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1 @@
|
||||
return require(script.ArgCheck)
|
||||
Reference in New Issue
Block a user