125 lines
2.8 KiB
Lua
125 lines
2.8 KiB
Lua
local CodeCoverage = script.Parent
|
|
local LineScanner = require(CodeCoverage.LineScanner)
|
|
local LcovReporter = require(CodeCoverage.LcovReporter)
|
|
|
|
local ScriptContext = game:GetService("ScriptContext")
|
|
local CoreScriptSyncService = game:GetService("CoreScriptSyncService")
|
|
|
|
local Reporter = {}
|
|
Reporter.__index = Reporter
|
|
|
|
function Reporter.processCoverageStats()
|
|
local stats = ScriptContext:GetCoverageStats()
|
|
|
|
local files = {}
|
|
for _, scriptStats in ipairs(stats) do
|
|
local aScript = scriptStats.Script;
|
|
|
|
local source = aScript.Source
|
|
|
|
local hits = scriptStats.Hits
|
|
local lineHit = 0
|
|
local lineMissed = 0
|
|
local lines = {}
|
|
|
|
if scriptStats.HitsPrecise then
|
|
local sources = source:split('\n')
|
|
|
|
for n,h in ipairs(hits) do
|
|
local ignored = h < 0
|
|
|
|
if h > 0 then
|
|
lineHit = lineHit + 1
|
|
elseif h == 0 then
|
|
lineMissed = lineMissed + 1
|
|
end
|
|
|
|
lines[n] = {
|
|
source = sources[n],
|
|
ignored = ignored,
|
|
hits = math.max(h, 0)
|
|
}
|
|
end
|
|
else
|
|
local scanner = LineScanner:new()
|
|
local lineNumber = 1
|
|
|
|
for line in source:gmatch('([^\r\n]*)[\r\n]?') do
|
|
local excluded, excludedIfNotHit = scanner:consume(line)
|
|
|
|
local ignored = excluded
|
|
|
|
if not excluded then
|
|
if hits[lineNumber] and hits[lineNumber] > 0 then
|
|
lineHit = lineHit + 1
|
|
else
|
|
if excludedIfNotHit then
|
|
ignored = true
|
|
else
|
|
lineMissed = lineMissed + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
lines[lineNumber] = {
|
|
source = line,
|
|
ignored = ignored,
|
|
hits = hits[lineNumber] or 0
|
|
}
|
|
|
|
lineNumber = lineNumber + 1
|
|
end
|
|
end
|
|
|
|
table.insert(files, {
|
|
script = aScript,
|
|
path = CoreScriptSyncService:GetScriptFilePath(aScript),
|
|
lines = lines,
|
|
hits = lineHit,
|
|
misses = lineMissed,
|
|
})
|
|
end
|
|
|
|
return files
|
|
end
|
|
|
|
local function matchesAny(str, excludes)
|
|
if not str or str:len() == 0 or not excludes then
|
|
return false
|
|
end
|
|
|
|
for _,exclude in ipairs(excludes) do
|
|
if string.find(str, exclude) ~= nil then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Reporter.generateReport(path, excludes)
|
|
local report = LcovReporter.generate(Reporter.processCoverageStats(), function(file)
|
|
local isExcluded = file.script.Name:match(".spec$")
|
|
or file.script:FindFirstAncestor("TestEZ")
|
|
or file.script:IsDescendantOf(CodeCoverage)
|
|
or matchesAny(file.path, excludes)
|
|
local isIncluded = file.path and file.path:len() > 0
|
|
|
|
return isIncluded and not isExcluded
|
|
end)
|
|
if report:len() == 0 then
|
|
warn("Generating code coverage report failed. Produced report has zero size.")
|
|
return
|
|
end
|
|
|
|
local success, message = pcall(function() -- New API
|
|
local fs = game:GetService("FileSystemService")
|
|
fs:WriteFile(path, report)
|
|
end)
|
|
|
|
if not success then
|
|
warn("Failed to save code coverage report at path: " .. path .. "\nError: " .. message)
|
|
end
|
|
end
|
|
|
|
return Reporter
|