Skip to content

Commit 2d8979e

Browse files
authored
Merge pull request #509 from splitio/semver-equalto-matcher
Semver equalto matcher
2 parents 8374bb5 + 1499f6d commit 2d8979e

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

splitio/models/grammar/matchers/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from splitio.models.grammar.matchers.string import ContainsStringMatcher, \
99
EndsWithMatcher, RegexMatcher, StartsWithMatcher, WhitelistMatcher
1010
from splitio.models.grammar.matchers.misc import BooleanMatcher, DependencyMatcher
11+
from splitio.models.grammar.matchers.semver import EqualToSemverMatcher
1112

1213

1314
MATCHER_TYPE_ALL_KEYS = 'ALL_KEYS'
@@ -27,6 +28,7 @@
2728
MATCHER_TYPE_IN_SPLIT_TREATMENT = 'IN_SPLIT_TREATMENT'
2829
MATCHER_TYPE_EQUAL_TO_BOOLEAN = 'EQUAL_TO_BOOLEAN'
2930
MATCHER_TYPE_MATCHES_STRING = 'MATCHES_STRING'
31+
MATCHER_TYPE_EQUAL_TO_SEMVER = 'EQUAL_TO_SEMVER'
3032

3133

3234
_MATCHER_BUILDERS = {
@@ -46,7 +48,9 @@
4648
MATCHER_TYPE_CONTAINS_STRING: ContainsStringMatcher,
4749
MATCHER_TYPE_IN_SPLIT_TREATMENT: DependencyMatcher,
4850
MATCHER_TYPE_EQUAL_TO_BOOLEAN: BooleanMatcher,
49-
MATCHER_TYPE_MATCHES_STRING: RegexMatcher
51+
MATCHER_TYPE_MATCHES_STRING: RegexMatcher,
52+
MATCHER_TYPE_EQUAL_TO_SEMVER: EqualToSemverMatcher
53+
5054
}
5155

5256

splitio/models/grammar/matchers/semver.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Semver matcher classes."""
22
import logging
3-
import pytest
3+
4+
from splitio.models.grammar.matchers.base import Matcher
5+
from splitio.models.grammar.matchers.string import Sanitizer
46

57
_LOGGER = logging.getLogger(__name__)
68

@@ -163,3 +165,52 @@ def _compare_vars(self, var1, var2):
163165
if var1 > var2:
164166
return 1
165167
return -1
168+
169+
class EqualToSemverMatcher(Matcher):
170+
"""A matcher for Semver equal to."""
171+
172+
def _build(self, raw_matcher):
173+
"""
174+
Build an EqualToSemverMatcher.
175+
176+
:param raw_matcher: raw matcher as fetched from splitChanges response.
177+
:type raw_matcher: dict
178+
"""
179+
self._data = raw_matcher.get('stringMatcherData')
180+
self._semver = Semver.build(self._data)
181+
182+
def _match(self, key, attributes=None, context=None):
183+
"""
184+
Evaluate user input against a matcher and return whether the match is successful.
185+
186+
:param key: User key.
187+
:type key: str.
188+
:param attributes: Custom user attributes.
189+
:type attributes: dict.
190+
:param context: Evaluation context
191+
:type context: dict
192+
193+
:returns: Wheter the match is successful.
194+
:rtype: bool
195+
"""
196+
if self._data is None or self._semver is None:
197+
_LOGGER.error("stringMatcherData is required for EQUAL_TO_SEMVER matcher type")
198+
return False
199+
200+
matching_data = Sanitizer.ensure_string(self._get_matcher_input(key, attributes))
201+
if matching_data is None:
202+
return False
203+
204+
matching_semver = Semver.build(matching_data)
205+
if matching_semver is None:
206+
return False
207+
208+
return self._semver.version == matching_semver.version
209+
210+
def __str__(self):
211+
"""Return string Representation."""
212+
return 'equal semver {data}'.format(data=self._data)
213+
214+
def _add_matcher_specific_properties_to_json(self):
215+
"""Add matcher specific properties to base dict before returning it."""
216+
return {'matcherType': 'EQUAL_TO_SEMVER', 'stringMatcherData': self._data}

tests/models/grammar/test_matchers.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from datetime import datetime
1111

1212
from splitio.models.grammar import matchers
13+
from splitio.models.grammar.matchers.semver import Semver
1314
from splitio.storage import SegmentStorage
1415
from splitio.engine.evaluator import Evaluator
1516

@@ -884,3 +885,44 @@ def test_to_json(self):
884885
as_json = matchers.RegexMatcher(self.raw).to_json()
885886
assert as_json['matcherType'] == 'MATCHES_STRING'
886887
assert as_json['stringMatcherData'] == "^[a-z][A-Z][0-9]$"
888+
889+
class EqualToSemverMatcherTests(MatcherTestsBase):
890+
"""Semver equalto matcher test cases."""
891+
892+
raw = {
893+
'negate': False,
894+
'matcherType': 'EQUAL_TO_SEMVER',
895+
'stringMatcherData': "2.1.8"
896+
}
897+
898+
def test_from_raw(self, mocker):
899+
"""Test parsing from raw json/dict."""
900+
parsed = matchers.from_raw(self.raw)
901+
assert isinstance(parsed, matchers.EqualToSemverMatcher)
902+
assert parsed._data == "2.1.8"
903+
assert isinstance(parsed._semver, Semver)
904+
assert parsed._semver._major == 2
905+
assert parsed._semver._minor == 1
906+
assert parsed._semver._patch == 8
907+
assert parsed._semver._pre_release == []
908+
909+
def test_matcher_behaviour(self, mocker):
910+
"""Test if the matcher works properly."""
911+
parsed = matchers.from_raw(self.raw)
912+
assert not parsed._match("2.1.8+rc")
913+
assert parsed._match("2.1.8")
914+
assert not parsed._match("2.1.5")
915+
assert not parsed._match("2.1.5-rc1")
916+
assert not parsed._match(None)
917+
assert not parsed._match("semver")
918+
919+
def test_to_json(self):
920+
"""Test that the object serializes to JSON properly."""
921+
as_json = matchers.EqualToSemverMatcher(self.raw).to_json()
922+
assert as_json['matcherType'] == 'EQUAL_TO_SEMVER'
923+
assert as_json['stringMatcherData'] == "2.1.8"
924+
925+
def test_to_str(self):
926+
"""Test that the object serializes to str properly."""
927+
as_str = matchers.EqualToSemverMatcher(self.raw)
928+
assert str(as_str) == "equal semver 2.1.8"

0 commit comments

Comments
 (0)