Skip to content

Commit

Permalink
Merge pull request #974 from getslash/bugfix/973
Browse files Browse the repository at this point in the history
Make tag matching with '-k' match whole tag names (closes #973)
  • Loading branch information
vmalloc committed Sep 10, 2019
2 parents 4f84685 + e176543 commit a8030c5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
40 changes: 25 additions & 15 deletions slash/core/tagging.py
Expand Up @@ -2,11 +2,10 @@

from ..exceptions import TaggingConflict

_TAGS_NAME = '__slash_tags__'
_TAGS_NAME = "__slash_tags__"


class Tagger(object):

def __init__(self, tag_name, tag_value):
self.tag_name = tag_name
self.tag_value = tag_value
Expand All @@ -17,6 +16,7 @@ def __call__(self, target):

def __rfloordiv__(self, other):
from .fixtures.parameters import ParametrizationValue

return ParametrizationValue(value=other, tags=[(self.tag_name, self.tag_value)])


Expand All @@ -26,7 +26,7 @@ def tag_test(test, tag_name, tag_value):
tags = Tags()
setattr(test, _TAGS_NAME, tags)
if tags.get(tag_name, NOTHING) not in (tag_value, NOTHING):
raise TaggingConflict('Tag {} is already set on {}'.format(tag_name, test))
raise TaggingConflict("Tag {} is already set on {}".format(tag_name, test))
tags[tag_name] = tag_value
return test

Expand All @@ -42,7 +42,6 @@ def get_tags(test):


class Tags(object):

def __init__(self, tags=None):
super(Tags, self).__init__()
if tags is None:
Expand All @@ -61,16 +60,23 @@ def __contains__(self, tag_name):
has_tag = __contains__

def _check_conflicting_tags(self, other):
for tag_name, tag_value in other._tags.items(): # pylint: disable=protected-access
for (
tag_name,
tag_value,
) in other._tags.items(): # pylint: disable=protected-access
if self.get(tag_name, NOTHING) not in (tag_value, NOTHING):
raise TaggingConflict('Conflicting tag: {} when adding {}, {}'.format(tag_name, self, other))
raise TaggingConflict(
"Conflicting tag: {} when adding {}, {}".format(
tag_name, self, other
)
)

def __add__(self, other):
if other is NO_TAGS:
return self
self._check_conflicting_tags(other)
new_tags = self._tags.copy()
new_tags.update(other._tags) # pylint: disable=protected-access
new_tags.update(other._tags) # pylint: disable=protected-access
return Tags(new_tags)

def copy(self):
Expand All @@ -80,28 +86,31 @@ def update(self, other):
if other is NO_TAGS:
return
self._check_conflicting_tags(other)
self._tags.update(other._tags) # pylint: disable=protected-access
self._tags.update(other._tags) # pylint: disable=protected-access

def get(self, *args, **kwargs):
return self._tags.get(*args, **kwargs)

def matches_pattern(self, pattern):
if '=' in pattern:
key, predicate = pattern.split('=', 1)
def matches_pattern(self, pattern, exact=False):
if "=" in pattern:
key, predicate = pattern.split("=", 1)
value = self._tags.get(key, NOTHING)
return value is not NOTHING and str(value) == predicate

for key, value in self._tags.items():
if pattern in key:
return True
if exact:
if pattern == key:
return True
else:
if pattern in key:
return True
return False

def __iter__(self):
return iter(self._tags)


class _NoTags(object):

def __contains__(self, tag_name):
return False

Expand All @@ -110,10 +119,11 @@ def __add__(self, other):

has_tag = __contains__

def matches_pattern(self, pattern): # pylint: disable=unused-argument
def matches_pattern(self, pattern, **_): # pylint: disable=unused-argument
return False

def __iter__(self):
return iter([])


NO_TAGS = _NoTags()
4 changes: 3 additions & 1 deletion slash/utils/pattern_matching.py
Expand Up @@ -14,15 +14,17 @@ def __init__(self, t):
super(Include, self).__init__()
self.only_tags = False
self.pattern = t[0]
self.exact = False
if len(t) == 2 and t[0] == "tag:":
self.only_tags = True
self.exact = True
self.pattern = t[1]

def matches(self, metadata):
if isinstance(metadata, str):
return self.pattern in metadata

if metadata.tags.matches_pattern(self.pattern):
if metadata.tags.matches_pattern(self.pattern, exact=self.exact):
return True
if self.only_tags:
return False
Expand Down
9 changes: 8 additions & 1 deletion tests/test_pattern_matching.py
Expand Up @@ -81,7 +81,14 @@ def test_matches_tag_exclusively():
assert not Matcher("tag:bla").matches(FakeMetadata("bla", {"bloop": 2}))


def test_matches_tag_whitespaces():
def test_matches_tag_exactly():
matcher = Matcher("tag:bla")
assert matcher.matches(FakeMetadata("something", {"bla": 2}))
for non_matching_tag in ("bla1", "1bla", "1bla2"):
assert not matcher.matches(FakeMetadata("something", {non_matching_tag: 2}))


def tet_matches_tag_whitespaces():
assert Matcher("tag: bla").matches(FakeMetadata("something", {"bla": 2}))
assert not Matcher("tag: bla").matches(FakeMetadata("bla", {"bloop": 2}))

Expand Down

0 comments on commit a8030c5

Please sign in to comment.