%% Analyze Coverage Data Using A Script
% This example shows how to load, parse, and query coverage data using a
% script.

% Copyright 2020 The MathWorks, Inc.

%% Load Coverage Data
% Load the model, then restore saved coverage data from the file
% |covdata.cvt| using <docid:slcoverage_ref#brxo2q3-1 |cvload|>. The
% data and test settings are retrieved in a cell array. The test settings
% are stored in a |cvtest| object that contains the parameters from the
% simulation that created the coverage data.
% 

load_system('slvnvdemo_ratelim_harness');
[savedSettings,savedData] = cvload('covdata');
savedData = savedData{1};

%% Extract Information from Coverage Data Objects
% Retrieve coverage information from a block path or block handle by using
% <docid:slcoverage_ref#brxo3wo-1 |decisioninfo|>. The output is a vector
% with the achieved and total outcomes for a single model object.
%  

subsysCov = decisioninfo(savedData,...
                   'slvnvdemo_ratelim_harness/Adjustable Rate Limiter')

%%
% Determine the percentage coverage achieved by using |decisioninfo|.
%

percentCov = 100 * (subsysCov(1)/subsysCov(2))

%%
% Specify that you want to extract the decision coverage data for the
% switch block called Apply Limited Gain by using |decisioninfo|. This
% returns a structure which contains the decisions and outcomes.
%  

[blockCov,desc] = decisioninfo(savedData, ...
         'slvnvdemo_ratelim_harness/Adjustable Rate Limiter/Apply limited gain');
descDecision = desc.decision;
outcome1 = desc.decision.outcome(1)
outcome2 = desc.decision.outcome(2)

%%
% From the |decisioninfo| output, you can see that the switch block called
% Apply Limited Gain was never false because the false case
% |executionCount| field has a value of |0|. If this behavior is expected,
% and you did not intend to execute this case with your tests, you can add
% a filter rule to justify this missing coverage using the
% <docid:slcoverage_ref#mw_0c38450a-8269-4485-b870-009e703a3ffe
% |slcoverage.Filter|> class.
%

%%
% First, query for the block instance to be filtered, because we only need
% to filter the one block instance that received incomplete coverage, and
% not all instances of that block type. Then use the
% <docid:slcoverage_ref#mw_6c069919-210c-4067-b9f4-d5109046a06b |BlockSelector|>
% class with the |BlockInstance| selector type to designate one block
% instance for filtering.
%

id = getSimulinkBlockHandle('slvnvdemo_ratelim_harness/Adjustable Rate Limiter/Apply limited gain');
sel = slcoverage.BlockSelector(slcoverage.BlockSelectorType.BlockInstance,id);

%%
% Create a filter object and a filter rule using the
% <docid:slcoverage_ref#mw_0c38450a-8269-4485-b870-009e703a3ffe |slcoverage.Filter|>
% and 
% <docid:slcoverage_ref#mw_9bd5a484-5c02-49f7-8439-ed837db7422c |slcoverage.FilterRule|>
% classes.
%

filt = slcoverage.Filter;
rule = slcoverage.FilterRule(sel,'Edge case',slcoverage.FilterMode.Justify);

%%
% Add the rule to the filter using the |addRule| method. Then save the new
% filter file with the |save| method.
%

filt.addRule(rule);
filt.save('blfilter');

%%
% Create a new |cvdata| object from the original object, and apply the
% filter file to it. Use |decisioninfo| on the filtered coverage data to
% see that there is now 100% decision coverage because the justified
% objectives are counted as satisfied.
% 

FilteredData = savedData;
FilteredData.filter = 'blfilter';
newCov = decisioninfo(FilteredData,...
                   'slvnvdemo_ratelim_harness/Adjustable Rate Limiter')
percentNewCov = 100 * (newCov(1)/newCov(2))