add gs
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
--[[
|
||||
Provides an interface to quickly run and report tests from a given object.
|
||||
]]
|
||||
|
||||
local TestPlanner = require(script.Parent.TestPlanner)
|
||||
local TestRunner = require(script.Parent.TestRunner)
|
||||
local TextReporter = require(script.Parent.Reporters.TextReporter)
|
||||
|
||||
local TestBootstrap = {}
|
||||
|
||||
local function stripSpecSuffix(name)
|
||||
return (name:gsub("%.spec$", ""))
|
||||
end
|
||||
local function isSpecScript(aScript)
|
||||
return aScript:IsA("ModuleScript") and aScript.Name:match("%.spec$")
|
||||
end
|
||||
|
||||
local function getPath(module, root)
|
||||
root = root or game
|
||||
|
||||
local path = {}
|
||||
local last = module
|
||||
|
||||
while last ~= nil and last ~= root do
|
||||
table.insert(path, stripSpecSuffix(last.Name))
|
||||
last = last.Parent
|
||||
end
|
||||
table.insert(path, stripSpecSuffix(root.Name))
|
||||
|
||||
return path
|
||||
end
|
||||
|
||||
--[[
|
||||
Find all the ModuleScripts in this tree that are tests.
|
||||
]]
|
||||
function TestBootstrap:getModules(root, modules, current)
|
||||
modules = modules or {}
|
||||
current = current or root
|
||||
|
||||
if isSpecScript(current) then
|
||||
local method = require(current)
|
||||
local path = getPath(current, root)
|
||||
|
||||
table.insert(modules, {
|
||||
method = method,
|
||||
path = path
|
||||
})
|
||||
end
|
||||
|
||||
for _, child in ipairs(current:GetChildren()) do
|
||||
self:getModules(root, modules, child)
|
||||
end
|
||||
|
||||
table.sort(modules, function(a, b)
|
||||
return a.path[#a.path]:lower() < b.path[#b.path]:lower()
|
||||
end)
|
||||
|
||||
return modules
|
||||
end
|
||||
|
||||
--[[
|
||||
Runs all test and reports the results using the given test reporter.
|
||||
|
||||
If no reporter is specified, a reasonable default is provided.
|
||||
|
||||
This function demonstrates the expected workflow with this testing system:
|
||||
1. Locate test modules
|
||||
2. Generate test plan
|
||||
3. Run test plan
|
||||
4. Report test results
|
||||
|
||||
This means we could hypothetically present a GUI to the developer that shows
|
||||
the test plan before we execute it, allowing them to toggle specific tests
|
||||
before they're run, but after they've been identified!
|
||||
]]
|
||||
function TestBootstrap:run(roots, reporter, otherOptions)
|
||||
reporter = reporter or TextReporter
|
||||
|
||||
otherOptions = otherOptions or {}
|
||||
local showTimingInfo = otherOptions["showTimingInfo"] or false
|
||||
local noXpcallByDefault = otherOptions["noXpcallByDefault"] or false
|
||||
local testNamePattern = otherOptions["testNamePattern"]
|
||||
|
||||
if type(roots) ~= "table" then
|
||||
error(("Bad argument #1 to TestBootstrap:run. Expected table, got %s"):format(typeof(roots)), 2)
|
||||
end
|
||||
|
||||
local startTime = tick()
|
||||
|
||||
local modules
|
||||
for _, subRoot in ipairs(roots) do
|
||||
modules = self:getModules(subRoot, modules)
|
||||
end
|
||||
|
||||
local afterModules = tick()
|
||||
|
||||
local plan = TestPlanner.createPlan(modules, noXpcallByDefault, testNamePattern)
|
||||
local afterPlan = tick()
|
||||
|
||||
local results = TestRunner.runPlan(plan)
|
||||
local afterRun = tick()
|
||||
|
||||
reporter.report(results)
|
||||
local afterReport = tick()
|
||||
|
||||
if showTimingInfo then
|
||||
local timing = {
|
||||
("Took %f seconds to locate test modules"):format(afterModules - startTime),
|
||||
("Took %f seconds to create test plan"):format(afterPlan - afterModules),
|
||||
("Took %f seconds to run tests"):format(afterRun - afterPlan),
|
||||
("Took %f seconds to report tests"):format(afterReport - afterRun),
|
||||
}
|
||||
|
||||
print(table.concat(timing, "\n"))
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
return TestBootstrap
|
||||
Reference in New Issue
Block a user