Skip to content

Commit

Permalink
sq: a wee adjustments; tests and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszachy committed May 14, 2024
1 parent 8c3b29e commit d17cecc
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 11 deletions.
10 changes: 10 additions & 0 deletions docs/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ In the fmf file it is better to use single quotes ``'`` as they do not need such

__ https://docs.python.org/3/library/re.html#re.sub

Remove parent value only if it matches regular expression is done using ``-~`` suffix.
If value matches any of provided `regular expressions`__ it is removed, these regular expressions
can be just a single item or a list of strings::

desc-~: '.*'
require-~:
- 'python2.*'

__ https://docs.python.org/3/library/re.html#regular-expression-syntax

Elasticity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
7 changes: 7 additions & 0 deletions examples/merge/parent.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ very:
tags~:
- "/Tier(.)/t\\1/"
- /Tier2/t3/

/minus-regexp:
description-~: '.*'
tags-~:
- '.ier1'
vars-~:
- 'y'
7 changes: 2 additions & 5 deletions fmf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,12 @@ def _merge_regexp(self, data, key, value):
"MergeError: Key '{0}' in {1} (wrong type).".format(
key, self.name))

import pysnooper

@pysnooper.snoop()
def _merge_minus_regexp(self, data, key, value):
""" Handle removing current values if they match regexp """
# A bit faster but essentially `any`
def lazy_any_search(item, patterns):
for p in patterns:
if re.search(p, item):
if re.search(p, str(item)):
return True
return False
if isinstance(value, str):
Expand All @@ -223,7 +220,7 @@ def lazy_any_search(item, patterns):
if lazy_any_search(data[key], value):
data[key] = ''
elif isinstance(data[key], dict):
for k in list(data.keys()):
for k in list(data[key].keys()):
if lazy_any_search(k, value):
data[key].pop(k, None)
else:
Expand Down
9 changes: 8 additions & 1 deletion tests/unit/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,14 @@ def test_merge_regexp(self):
assert 'general' == child.data['description']
# First rule changes the Tier2 into t2,
# thus /Tier2/t3/ no longer matches.
assert child.data['tags'] == ['t1', 't2']
assert ['t1', 't2'] == child.data['tags']

def test_merge_minus_regexp(self):
""" Merging with '-~' operation """
child = self.merge.find('/parent/minus-regexp')
assert '' == child.data['description']
assert ['Tier2'] == child.data['tags']
assert {'x': 1} == child.data['vars']

def test_merge_deep(self):
""" Merging a deeply nested dictionary """
Expand Down
18 changes: 13 additions & 5 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,11 +437,19 @@ def test_sort(self):


class TestBETTERNAME:
def test_invalid(self):
for s in ["", "/", ";/;", ";;;", "/a/b/c", "/a/b/c/d",
"/x;y/", "/a/a;"]:
with pytest.raises(utils.FormatError):
utils.split_pattern_repl(s)
@pytest.mark.parametrize("src", [
"", # Empty input
"/", # Not long enough input
";/;", # Not long enough - missing 'REPL;'
";;;", # PATTERN and REPL parts empty
"/a/b/c", # Input after trailing deliminer
"/a/b/c/d", # More parts after trailig delimiter
"/x;y/", # No REPL part as delimiter is /
"/a/a;" # No trailing delimiter
])
def test_invalid(self, src):
with pytest.raises(utils.FormatError):
utils.split_pattern_repl(src)

def test_simple(self):
assert utils.split_pattern_repl('/a/b/') == utils.PatternRepl('a', 'b')
Expand Down

0 comments on commit d17cecc

Please sign in to comment.