-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathCodeCoverageSummaryPlugin.m
More file actions
99 lines (81 loc) · 3.99 KB
/
Copy pathCodeCoverageSummaryPlugin.m
File metadata and controls
99 lines (81 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
classdef CodeCoverageSummaryPlugin < matlab.unittest.plugins.TestRunnerPlugin
% Copyright 2026 The MathWorks, Inc.
properties (Access=private)
CoverageFormat
Metrics
end
methods
function plugin = CodeCoverageSummaryPlugin(coverageFormat, metrics)
plugin.CoverageFormat = coverageFormat;
plugin.Metrics = metrics;
end
end
methods (Access=protected)
function runSession(plugin, pluginData)
% Run the session first (this ensures coverage data is collected)
runSession@matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData);
% Now extract and save coverage data
if isempty(plugin.CoverageFormat.Result)
warning("testframework:CodeCoverageSummaryPlugin:NoCoverageData", "No coverage data collected.");
return;
end
result = plugin.CoverageFormat.Result;
% Create coverage summary structure
coverageDetails = struct();
% Always get function and statement coverage
functionCoverage = coverageSummary(result, "function");
statementCoverage = coverageSummary(result, "statement");
coverageDetails.FunctionCoverage = sumCoverage(functionCoverage);
coverageDetails.StatementCoverage = sumCoverage(statementCoverage);
% Get decision coverage if metrics contains decision, condition, or mcdc
if any(ismember({'decision', 'condition', 'mcdc'}, plugin.Metrics))
decisionCoverage = coverageSummary(result, "decision");
coverageDetails.DecisionCoverage = sumCoverage(decisionCoverage);
end
% Get condition coverage if metrics contains condition or mcdc
if any(ismember({'condition', 'mcdc'}, plugin.Metrics))
conditionCoverage = coverageSummary(result, "condition");
coverageDetails.ConditionCoverage = sumCoverage(conditionCoverage);
end
% Get MC/DC coverage if metrics contains mcdc
if any(ismember({'mcdc'}, plugin.Metrics))
mcdcCoverage = coverageSummary(result, "mcdc");
coverageDetails.MCDCCoverage = sumCoverage(mcdcCoverage);
end
coverageResults = {coverageDetails};
% Determine file path for coverage results
coverageArtifactFile = fullfile(getenv("RUNNER_TEMP"), "matlabCoverageResults" + getenv("GITHUB_RUN_ID") + ".json");
try
JsonCoverageResults = jsonencode(coverageResults, "PrettyPrint", true);
[fID, msg] = fopen(coverageArtifactFile, "w");
if fID == -1
warning("testframework:CodeCoverageSummaryPlugin:UnableToOpenFile","Unable to open a file required to show code coverage data. (Cause: %s)", msg);
else
closeFile = onCleanup(@()fclose(fID));
fprintf(fID, '%s', JsonCoverageResults);
end
catch e
warning("testframework:CodeCoverageSummaryPlugin:UnableToJsonEncode","Unable to serialize code coverage data into JSON format. (Cause: %s)", e.message);
end
end
end
end
% Helper function to sum up the coverage data from multiple files
function coverageStruct = sumCoverage(coverageMatrix)
% Split the vector in half: first half is executed, second half is total
executed = sum(coverageMatrix(:, 1));
total = sum(coverageMatrix(:, 2));
coverageStruct = struct(...
'Executed', executed, ...
'Total', total, ...
'Percentage', calculatePercentage([executed, total]) ...
);
end
% function to calculate percentage
function percentage = calculatePercentage(coverageData)
if coverageData(2) == 0
percentage = NaN; % Avoid division by zero
else
percentage = (coverageData(1) / coverageData(2)) * 100;
end
end