@@ -153,7 +153,7 @@ def _build(self, raw_matcher):
153153 :param raw_matcher: raw matcher as fetched from splitChanges response.
154154 :type raw_matcher: dict
155155 """
156- self ._data = raw_matcher [ 'stringMatcherData' ]
156+ self ._data = raw_matcher . get ( 'stringMatcherData' )
157157 self ._semver = Semver (self ._data )
158158
159159 def _match (self , key , attributes = None , context = None ):
@@ -198,7 +198,7 @@ def _build(self, raw_matcher):
198198 :param raw_matcher: raw matcher as fetched from splitChanges response.
199199 :type raw_matcher: dict
200200 """
201- self ._data = raw_matcher [ 'stringMatcherData' ]
201+ self ._data = raw_matcher . get ( 'stringMatcherData' )
202202 self ._semver = Semver (self ._data )
203203
204204 def _match (self , key , attributes = None , context = None ):
@@ -243,7 +243,7 @@ def _build(self, raw_matcher):
243243 :param raw_matcher: raw matcher as fetched from splitChanges response.
244244 :type raw_matcher: dict
245245 """
246- self ._data = raw_matcher [ 'stringMatcherData' ]
246+ self ._data = raw_matcher . get ( 'stringMatcherData' )
247247 self ._semver = Semver (self ._data )
248248
249249 def _match (self , key , attributes = None , context = None ):
@@ -277,3 +277,49 @@ def __str__(self):
277277 def _add_matcher_specific_properties_to_json (self ):
278278 """Add matcher specific properties to base dict before returning it."""
279279 return {'matcherType' : 'LESS_THAN_OR_EQUAL_TO_SEMVER' , 'stringMatcherData' : self ._data }
280+
281+ class BetweenSemverMatcher (Matcher ):
282+ """A matcher for Semver between."""
283+
284+ def _build (self , raw_matcher ):
285+ """
286+ Build a BetweenSemverMatcher.
287+
288+ :param raw_matcher: raw matcher as fetched from splitChanges response.
289+ :type raw_matcher: dict
290+ """
291+ self ._data = raw_matcher .get ('betweenStringMatcherData' )
292+ self ._semver_start = Semver (self ._data ['start' ]) if self ._data .get ('start' ) is not None else None
293+ self ._semver_end = Semver (self ._data ['end' ]) if self ._data .get ('end' ) is not None else None
294+
295+ def _match (self , key , attributes = None , context = None ):
296+ """
297+ Evaluate user input against a matcher and return whether the match is successful.
298+
299+ :param key: User key.
300+ :type key: str.
301+ :param attributes: Custom user attributes.
302+ :type attributes: dict.
303+ :param context: Evaluation context
304+ :type context: dict
305+
306+ :returns: Wheter the match is successful.
307+ :rtype: bool
308+ """
309+ if self ._data is None or self ._semver_start is None or self ._semver_end is None :
310+ _LOGGER .error ("betweenStringMatcherData is required for BETWEEN_SEMVER matcher type" )
311+ return None
312+
313+ matching_data = Sanitizer .ensure_string (self ._get_matcher_input (key , attributes ))
314+ if matching_data is None :
315+ return False
316+
317+ return (self ._semver_start .compare (Semver (matching_data )) in [0 , - 1 ]) and (self ._semver_end .compare (Semver (matching_data )) in [0 , 1 ])
318+
319+ def __str__ (self ):
320+ """Return string Representation."""
321+ return 'between semver {start} and {end}' .format (start = self ._data .get ('start' ), end = self ._data .get ('end' ))
322+
323+ def _add_matcher_specific_properties_to_json (self ):
324+ """Add matcher specific properties to base dict before returning it."""
325+ return {'matcherType' : 'BETWEEN_SEMVER' , 'betweenStringMatcherData' : self ._data }
0 commit comments