diff --git a/conservancy_beancount/reports/core.py b/conservancy_beancount/reports/core.py index 147c726f483187945b5baeaaa4083b808fd5d41f..be4b65d9f236a963064724e022a0128461c1cbf2 100644 --- a/conservancy_beancount/reports/core.py +++ b/conservancy_beancount/reports/core.py @@ -140,6 +140,15 @@ class RelatedPostings(Sequence[data.Posting]): def add(self, post: data.Posting) -> None: self._postings.append(post) + def all_meta_links(self, key: MetaKey) -> Set[str]: + retval: Set[str] = set() + for post in self: + try: + retval.update(post.meta.get_links(key)) + except TypeError: + pass + return retval + def clear(self) -> None: self._postings.clear() diff --git a/tests/test_reports_related_postings.py b/tests/test_reports_related_postings.py index 718ba04f4d05cb9dc4f92103c263922da851f06b..fbb484a2ff895ba3bccdf7a1105d75371e167d9e 100644 --- a/tests/test_reports_related_postings.py +++ b/tests/test_reports_related_postings.py @@ -196,6 +196,43 @@ def test_meta_values_many_types(): related.add(testutil.Posting('Income:Donations', -index, key=value)) assert related.meta_values('key') == expected +@pytest.mark.parametrize('count', range(3)) +def test_all_meta_links_zero(count): + postings = ( + testutil.Posting('Income:Donations', -n, testkey=str(n)) + for n in range(count) + ) + related = core.RelatedPostings( + post._replace(meta=data.Metadata(post.meta)) + for post in postings + ) + assert related.all_meta_links('approval') == set() + +def test_all_meta_links_singletons(): + postings = ( + testutil.Posting('Income:Donations', -10, statement=value) + for value in itertools.chain( + testutil.NON_LINK_METADATA_STRINGS, + testutil.LINK_METADATA_STRINGS, + testutil.NON_STRING_METADATA_VALUES, + )) + related = core.RelatedPostings( + post._replace(meta=data.Metadata(post.meta)) + for post in postings + ) + assert related.all_meta_links('statement') == testutil.LINK_METADATA_STRINGS + +def test_all_meta_links_multiples(): + postings = ( + testutil.Posting('Income:Donations', -10, approval=' '.join(value)) + for value in itertools.permutations(testutil.LINK_METADATA_STRINGS, 2) + ) + related = core.RelatedPostings( + post._replace(meta=data.Metadata(post.meta)) + for post in postings + ) + assert related.all_meta_links('approval') == testutil.LINK_METADATA_STRINGS + def test_group_by_meta_zero(): assert len(core.RelatedPostings.group_by_meta([], 'metacurrency')) == 0