plugin: Link checkers use Metadata class.
This commit is contained in:
parent
9b63d898af
commit
46cfc558ec
5 changed files with 70 additions and 24 deletions
|
@ -67,13 +67,17 @@ class ConfigurationError(Error):
|
|||
|
||||
|
||||
class InvalidMetadataError(Error):
|
||||
def __init__(self, txn, key, value=None, post=None, source=None):
|
||||
def __init__(self, txn, key, value=None, post=None, need_type=str, source=None):
|
||||
if post is None:
|
||||
srcname = 'transaction'
|
||||
else:
|
||||
srcname = post.account
|
||||
if value is None:
|
||||
msg = "{} missing {}".format(srcname, key)
|
||||
else:
|
||||
elif isinstance(value, need_type):
|
||||
msg = "{} has invalid {}: {}".format(srcname, key, value)
|
||||
else:
|
||||
msg = "{} has wrong type of {}: expected {} but is a {}".format(
|
||||
srcname, key, need_type.__name__, type(value).__name__,
|
||||
)
|
||||
super().__init__(msg, txn, source)
|
||||
|
|
|
@ -23,11 +23,13 @@ from .. import errors as errormod
|
|||
from ..beancount_types import (
|
||||
MetaKey,
|
||||
MetaValue,
|
||||
Posting,
|
||||
Transaction,
|
||||
)
|
||||
|
||||
from typing import (
|
||||
Mapping,
|
||||
MutableMapping,
|
||||
Optional,
|
||||
)
|
||||
|
||||
class MetaRepoLinks(core.TransactionHook):
|
||||
|
@ -41,11 +43,18 @@ class MetaRepoLinks(core.TransactionHook):
|
|||
self.repo_path = repo_path
|
||||
|
||||
def _check_links(self,
|
||||
meta: MutableMapping[MetaKey, MetaValue],
|
||||
txn: Transaction,
|
||||
meta: Mapping[MetaKey, MetaValue],
|
||||
post: Optional[Posting]=None,
|
||||
) -> errormod.Iter:
|
||||
for key in data.LINK_METADATA.intersection(meta):
|
||||
for link in str(meta[key]).split():
|
||||
metadata = data.Metadata(meta)
|
||||
for key in data.LINK_METADATA:
|
||||
try:
|
||||
links = metadata.get_links(key)
|
||||
except TypeError:
|
||||
yield errormod.InvalidMetadataError(txn, key, meta[key], post)
|
||||
else:
|
||||
for link in links:
|
||||
match = self.PATH_PUNCT_RE.search(link)
|
||||
if match and match.group(0) == ':':
|
||||
pass
|
||||
|
@ -53,7 +62,7 @@ class MetaRepoLinks(core.TransactionHook):
|
|||
yield errormod.BrokenLinkError(txn, key, link)
|
||||
|
||||
def run(self, txn: Transaction) -> errormod.Iter:
|
||||
yield from self._check_links(txn, txn.meta)
|
||||
yield from self._check_links(txn.meta, txn)
|
||||
for post in txn.postings:
|
||||
if post.meta is not None:
|
||||
yield from self._check_links(txn, post.meta)
|
||||
yield from self._check_links(post.meta, txn, post)
|
||||
|
|
|
@ -21,11 +21,13 @@ from .. import errors as errormod
|
|||
from ..beancount_types import (
|
||||
MetaKey,
|
||||
MetaValue,
|
||||
Posting,
|
||||
Transaction,
|
||||
)
|
||||
|
||||
from typing import (
|
||||
Mapping,
|
||||
MutableMapping,
|
||||
Optional,
|
||||
)
|
||||
|
||||
class MetaRTLinks(core.TransactionHook):
|
||||
|
@ -39,11 +41,18 @@ class MetaRTLinks(core.TransactionHook):
|
|||
self.rt = rt_wrapper
|
||||
|
||||
def _check_links(self,
|
||||
meta: MutableMapping[MetaKey, MetaValue],
|
||||
txn: Transaction,
|
||||
meta: Mapping[MetaKey, MetaValue],
|
||||
post: Optional[Posting]=None,
|
||||
) -> errormod.Iter:
|
||||
for key in self.LINK_METADATA.intersection(meta):
|
||||
for link in str(meta[key]).split():
|
||||
metadata = data.Metadata(meta)
|
||||
for key in self.LINK_METADATA:
|
||||
try:
|
||||
links = metadata.get_links(key)
|
||||
except TypeError:
|
||||
yield errormod.InvalidMetadataError(txn, key, meta[key], post)
|
||||
else:
|
||||
for link in links:
|
||||
if not link.startswith('rt:'):
|
||||
continue
|
||||
parsed = self.rt.parse(link)
|
||||
|
@ -51,7 +60,7 @@ class MetaRTLinks(core.TransactionHook):
|
|||
yield errormod.BrokenRTLinkError(txn, key, link, parsed)
|
||||
|
||||
def run(self, txn: Transaction) -> errormod.Iter:
|
||||
yield from self._check_links(txn, txn.meta)
|
||||
yield from self._check_links(txn.meta, txn)
|
||||
for post in txn.postings:
|
||||
if post.meta is not None:
|
||||
yield from self._check_links(txn, post.meta)
|
||||
yield from self._check_links(post.meta, txn, post)
|
||||
|
|
|
@ -100,6 +100,18 @@ def test_bad_post_links(hook):
|
|||
actual = {error.message for error in hook.run(txn)}
|
||||
assert expected == actual
|
||||
|
||||
@pytest.mark.parametrize('value', testutil.NON_STRING_METADATA_VALUES)
|
||||
def test_bad_metadata_type(hook, value):
|
||||
txn = testutil.Transaction(**{'check': value}, postings=[
|
||||
('Income:Donations', -5),
|
||||
('Assets:Cash', 5),
|
||||
])
|
||||
expected = {'transaction has wrong type of check: expected str but is a {}'.format(
|
||||
type(value).__name__,
|
||||
)}
|
||||
actual = {error.message for error in hook.run(txn)}
|
||||
assert expected == actual
|
||||
|
||||
@pytest.mark.parametrize('ext_doc', [
|
||||
'rt:123',
|
||||
'rt:456/789',
|
||||
|
|
|
@ -119,6 +119,18 @@ def test_bad_post_links(hook, link_source, format_error):
|
|||
actual = {error.message for error in hook.run(txn)}
|
||||
assert expected == actual
|
||||
|
||||
@pytest.mark.parametrize('value', testutil.NON_STRING_METADATA_VALUES)
|
||||
def test_bad_metadata_type(hook, value):
|
||||
txn = testutil.Transaction(**{'rt-id': value}, postings=[
|
||||
('Income:Donations', -5),
|
||||
('Assets:Cash', 5),
|
||||
])
|
||||
expected = {'transaction has wrong type of rt-id: expected str but is a {}'.format(
|
||||
type(value).__name__,
|
||||
)}
|
||||
actual = {error.message for error in hook.run(txn)}
|
||||
assert expected == actual
|
||||
|
||||
@pytest.mark.parametrize('ext_doc', [
|
||||
'statement.txt',
|
||||
'https://example.org/',
|
||||
|
|
Loading…
Reference in a new issue