Skip to content

Commit

Permalink
Merge pull request #243 from melexis/uncovered
Browse files Browse the repository at this point in the history
Add 'uncovered' flag to item-matrix directive
  • Loading branch information
Letme authored Sep 27, 2021
2 parents f4bd504 + 31b7c3b commit f761edc
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
10 changes: 10 additions & 0 deletions doc/integration_test_report.rst
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,16 @@ Traceability from SSS to SRS
:onlycovered:
:coverage: > 66.7

.. item-matrix:: System requirements fulfilled by software requirements - only show uncovered
:target: SRS
:source: SYS
:targettitle: software requirement
:sourcetitle: system requirement
:type: fulfilled_by
:stats:
:group: top
:onlyuncovered:

Another matrix that should spawn a warning as the relation in *type* does not exist
-----------------------------------------------------------------------------------

Expand Down
5 changes: 5 additions & 0 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ limitations in doing so:
By default, all source items are included. By providing the *onlycovered* flag, only covered items are shown in the
output. This option takes precedence over the ``:group:`` option.

:onlyuncovered: *optional*, *flag*

By default, all source items are included. By providing the *onlyuncovered* flag, only uncovered items are shown in
the output. This option takes precedence over the ``:group:`` option.

:nocaptions: *optional*, *flag*

By default, the caption for every item in the table is shown. By providing the *nocaptions* flag, the
Expand Down
22 changes: 17 additions & 5 deletions mlx/directives/item_matrix_directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def perform_replacement(self, app, collection):
covered = self._add_target_items(rights, target_items)
self._store_data(rows, source_link, rights, covered, app)

tgroup += self._build_table_body(rows, self['group'], self['onlycovered'])
tgroup += self._build_table_body(rows, self['group'], self['onlycovered'], self['onlyuncovered'])

count_total = rows.counters[0] + rows.counters[1] - duplicate_source_count
count_covered = rows.counters[0] - duplicate_source_count
Expand All @@ -124,6 +124,8 @@ def perform_replacement(self, app, collection):
pct=int(percentage))
if self['onlycovered']:
disp += ' (uncovered items are hidden)'
elif self['onlyuncovered']:
disp += ' (covered items are hidden)'
p_node = nodes.paragraph()
txt = nodes.Text(disp)
p_node += txt
Expand All @@ -132,20 +134,23 @@ def perform_replacement(self, app, collection):
top_node += table
self.replace_self(top_node)

def _build_table_body(self, rows, group, onlycovered):
def _build_table_body(self, rows, group, onlycovered, onlyuncovered):
""" Creates the table body and fills it with rows, grouping and excluding uncovered source items when desired
Args:
rows (Rows): Rows namedtuple object
group (str): Group option, falsy to disable grouping, 'top' or 'bottom' otherwise
onlycovered (bool): True to only include source items that are covered; False to include all
onlycovered (bool): True to only include source items that are covered; False otherwise
onlyuncovered (bool): True to only include source items that are uncovered; False otherwise
Returns:
nodes.tbody: Filled table body
"""
tbody = nodes.tbody()
if onlycovered:
tbody += rows.covered
elif onlyuncovered:
tbody += rows.uncovered
elif not group:
tbody += rows.sorted
elif group == 'top':
Expand Down Expand Up @@ -460,8 +465,7 @@ def _store_data(self, rows, source, right_cells, covered, app):
else:
rows.counters[1] += 1
rows.uncovered.extend(new_rows)
if not self['onlycovered']:
rows.sorted.extend(new_rows)
rows.sorted.extend(new_rows)

def _add_target_items(self, target_cells, target_items):
""" Stores target items after filtering by target option.
Expand Down Expand Up @@ -582,6 +586,7 @@ class ItemMatrixDirective(TraceableBaseDirective):
:splittargets:
:group: top | bottom
:onlycovered:
:onlyuncovered:
:stats:
:coverage: Evaluation, e.g. >=95
:nocaptions:
Expand Down Expand Up @@ -609,6 +614,7 @@ class ItemMatrixDirective(TraceableBaseDirective):
'splittargets': directives.flag,
'group': group_choice,
'onlycovered': directives.flag,
'onlyuncovered': directives.flag,
'coveredintermediates': directives.flag,
'stats': directives.flag,
'coverage': directives.unchanged,
Expand Down Expand Up @@ -688,10 +694,16 @@ def run(self):
self.check_option_presence(node, 'splitintermediates')
self.check_option_presence(node, 'splittargets')
self.check_option_presence(node, 'onlycovered')
self.check_option_presence(node, 'onlyuncovered')
self.check_option_presence(node, 'coveredintermediates')
self.check_option_presence(node, 'stats')
self.check_option_presence(node, 'hidetitle')

if node['onlycovered'] and node['onlyuncovered']:
raise TraceabilityException(
"Item-matrix directive cannot combine 'onlycovered' with 'onlyuncovered' flag",
docname=env.docname)

if node['targetattributes']:
node['splittargets'] = True

Expand Down
9 changes: 3 additions & 6 deletions tests/directives/test_item_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,11 @@ class TestItemMatrix(TestCase):
Rows = namedtuple('Rows', "sorted covered uncovered counters")

@parameterized.expand([
(True, False, True, [0, 0], [1, 1, 0]),
(False, False, True, [0, 0], [1, 0, 1]),
(True, True, True, [0, 0], [1, 1, 0]),
(False, True, True, [0, 0], [0, 0, 1]),
(True, True, [0, 0], [1, 1, 0]),
(False, True, [0, 0], [1, 0, 1]),
])
def test_store_data(self, covered, onlycovered, splittargets, attributes, expected_lengths):
def test_store_data(self, covered, splittargets, attributes, expected_lengths):
dut = ItemMatrix()
dut['onlycovered'] = onlycovered
dut['intermediate'] = ''
dut['sourceattributes'] = ['attr'] * attributes[0]
dut['targetattributes'] = ['attr'] * attributes[1]
Expand Down

0 comments on commit f761edc

Please sign in to comment.