Skip to content

Commit 5f793a3

Browse files
author
uzair-folio3
committed
comments resolved
1 parent 857e8de commit 5f793a3

File tree

2 files changed

+107
-100
lines changed

2 files changed

+107
-100
lines changed

optimizely/helpers/condition.py

Lines changed: 106 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,90 @@ def is_value_a_number(self, value):
9292

9393
return False
9494

95+
def is_pre_release(self, target):
96+
""" Method to check if the given version contains "-"
97+
98+
Args:
99+
target: Given version in string.
100+
101+
Returns:
102+
Boolean:
103+
- True if the given version does contain "-"
104+
- False if it doesn't
105+
"""
106+
return SemverType.IS_PRE_RELEASE in target
107+
108+
def is_patch_pre_release(self, idx, idx_value):
109+
return idx == SemverType.PATCH_INDEX and idx_value in SemverType.IS_PATCH_PRE_RELEASE
110+
111+
def is_build(self, target):
112+
""" Method to check if the given version contains "+"
113+
114+
Args:
115+
target: Given version in string.
116+
117+
Returns:
118+
Boolean:
119+
- True if the given version does contain "+"
120+
- False if it doesn't
121+
"""
122+
return SemverType.IS_BUILD in target
123+
124+
def has_white_space(self, target):
125+
""" Method to check if the given version contains " " (white space)
126+
127+
Args:
128+
target: Given version in string.
129+
130+
Returns:
131+
Boolean:
132+
- True if the given version does contain " "
133+
- False if it doesn't
134+
"""
135+
return SemverType.HAS_WHITE_SPACE in target
136+
137+
def compare_user_version_with_target_version(self, index):
138+
""" Method to compare user version with target version.
139+
140+
Args:
141+
index: Index of the condition to be evaluated.
142+
143+
Returns:
144+
Int:
145+
- 0 if user version is equal to target version.
146+
- 1 if user version is greater than target version.
147+
- -1 if user version is less than target version or, in case of exact string match, doesn't match the target
148+
version.
149+
None:
150+
- if the user version value is not string type or is null.
151+
"""
152+
condition_name = self.condition_data[index][0]
153+
target_version = self.condition_data[index][1]
154+
user_version = self.attributes.get(condition_name)
155+
156+
target_version_parts = self.split_semantic_version(target_version)
157+
user_version_parts = self.split_semantic_version(user_version)
158+
user_version_parts_len = len(user_version_parts)
159+
160+
for (idx, _) in enumerate(target_version_parts):
161+
if user_version_parts_len <= idx:
162+
return 1 if self.is_pre_release(target_version) else -1
163+
elif not user_version_parts[idx].isdigit():
164+
if user_version_parts[idx] < target_version_parts[idx]:
165+
return -1
166+
elif user_version_parts[idx] > target_version_parts[idx]:
167+
return 1
168+
else:
169+
user_version_part = int(user_version_parts[idx])
170+
target_version_part = int(target_version_parts[idx])
171+
if user_version_part > target_version_part:
172+
return 1
173+
elif user_version_part < target_version_part:
174+
return -1
175+
if self.is_pre_release(user_version) and not self.is_pre_release(target_version):
176+
return -1
177+
return 0
178+
95179
def exact_evaluator(self, index):
96180
""" Evaluate the given exact match condition for the user attributes.
97181
@@ -384,6 +468,21 @@ def semver_greater_than_or_equal_evaluator(self, index):
384468
"""
385469
return self.compare_user_version_with_target_version(index) >= 0
386470

471+
EVALUATORS_BY_MATCH_TYPE = {
472+
ConditionMatchTypes.EXACT: exact_evaluator,
473+
ConditionMatchTypes.EXISTS: exists_evaluator,
474+
ConditionMatchTypes.GREATER_THAN: greater_than_evaluator,
475+
ConditionMatchTypes.LESS_THAN: less_than_evaluator,
476+
ConditionMatchTypes.SEMVER_EQ: semver_equal_evaluator,
477+
ConditionMatchTypes.SEMVER_GE: semver_greater_than_or_equal_evaluator,
478+
ConditionMatchTypes.SEMVER_GT: semver_greater_than_evaluator,
479+
ConditionMatchTypes.SEMVER_LE: semver_less_than_or_equal_evaluator,
480+
ConditionMatchTypes.SEMVER_LT: semver_less_than_evaluator,
481+
ConditionMatchTypes.SUBSTRING: substring_evaluator,
482+
ConditionMatchTypes.LESS_THAN_OR_EQUAL: less_than_or_equal_evaluator,
483+
ConditionMatchTypes.GREATER_THAN_OR_EQUAL: greater_than_or_equal_evaluator,
484+
}
485+
387486
def split_semantic_version(self, target):
388487
""" Method to split the given version.
389488
@@ -400,22 +499,29 @@ def split_semantic_version(self, target):
400499
target_suffix = ""
401500
target_parts = []
402501

502+
""" remove spaces from target version string """
503+
403504
if self.has_white_space(target):
404505
self.logger.warning(Errors.INVALID_ATTRIBUTE_FORMAT)
405506
return None
406507

508+
""" check for pre release e.g. 1.0.0-alpha where 'alpha' is a pre release otherwise
509+
check for build e.g. 1.0.0+001 where 001 is a build metadata"""
510+
407511
if self.is_pre_release(target):
408512
target_parts = target.split(SemverType.IS_PRE_RELEASE)
409513
elif self.is_build(target):
410514
target_parts = target.split(SemverType.IS_BUILD)
411515

516+
""" validate target version into prefix and suffix """
412517
if target_parts:
413518
if len(target_parts) < 1:
414519
self.logger.warning(Errors.INVALID_ATTRIBUTE_FORMAT)
415520
return None
416521
target_prefix = str(target_parts[0])
417522
target_suffix = target_parts[1:]
418523

524+
""" validate dot counts in a target version """
419525
dot_count = target_prefix.count(".")
420526
if dot_count > 2:
421527
self.logger.warning(Errors.INVALID_ATTRIBUTE_FORMAT)
@@ -434,105 +540,6 @@ def split_semantic_version(self, target):
434540
target_version_parts.extend(target_suffix)
435541
return target_version_parts
436542

437-
def is_pre_release(self, target):
438-
""" Method to check if the given version contains "-"
439-
440-
Args:
441-
target: Given version in string.
442-
443-
Returns:
444-
Boolean:
445-
- True if the given version does contain "-"
446-
- False if it doesn't
447-
"""
448-
return SemverType.IS_PRE_RELEASE in target
449-
450-
def is_patch_pre_release(self, idx, idx_value):
451-
return idx == SemverType.PATCH_INDEX and idx_value in SemverType.IS_PATCH_PRE_RELEASE
452-
453-
def is_build(self, target):
454-
""" Method to check if the given version contains "+"
455-
456-
Args:
457-
target: Given version in string.
458-
459-
Returns:
460-
Boolean:
461-
- True if the given version does contain "+"
462-
- False if it doesn't
463-
"""
464-
return SemverType.IS_BUILD in target
465-
466-
def has_white_space(self, target):
467-
""" Method to check if the given version contains " " (white space)
468-
469-
Args:
470-
target: Given version in string.
471-
472-
Returns:
473-
Boolean:
474-
- True if the given version does contain " "
475-
- False if it doesn't
476-
"""
477-
return SemverType.HAS_WHITE_SPACE in target
478-
479-
def compare_user_version_with_target_version(self, index):
480-
""" Method to compare user version with target version.
481-
482-
Args:
483-
index: Index of the condition to be evaluated.
484-
485-
Returns:
486-
Int:
487-
- 0 if user version is equal to target version.
488-
- 1 if user version is greater than target version.
489-
- -1 if user version is less than target version or, in case of exact string match, doesn't match the target
490-
version.
491-
None:
492-
- if the user version value is not string type or is null.
493-
"""
494-
condition_name = self.condition_data[index][0]
495-
target_version = self.condition_data[index][1]
496-
user_version = self.attributes.get(condition_name)
497-
498-
target_version_parts = self.split_semantic_version(target_version)
499-
user_version_parts = self.split_semantic_version(user_version)
500-
user_version_parts_len = len(user_version_parts)
501-
502-
for (idx, _) in enumerate(target_version_parts):
503-
if user_version_parts_len <= idx:
504-
return 1 if self.is_pre_release(target_version) else -1
505-
elif not user_version_parts[idx].isdigit():
506-
if user_version_parts[idx] < target_version_parts[idx]:
507-
return -1
508-
elif user_version_parts[idx] > target_version_parts[idx]:
509-
return 1
510-
else:
511-
user_version_part = int(user_version_parts[idx])
512-
target_version_part = int(target_version_parts[idx])
513-
if user_version_part > target_version_part:
514-
return 1
515-
elif user_version_part < target_version_part:
516-
return -1
517-
if self.is_pre_release(user_version) and not self.is_pre_release(target_version):
518-
return -1
519-
return 0
520-
521-
EVALUATORS_BY_MATCH_TYPE = {
522-
ConditionMatchTypes.EXACT: exact_evaluator,
523-
ConditionMatchTypes.EXISTS: exists_evaluator,
524-
ConditionMatchTypes.GREATER_THAN: greater_than_evaluator,
525-
ConditionMatchTypes.LESS_THAN: less_than_evaluator,
526-
ConditionMatchTypes.SEMVER_EQ: semver_equal_evaluator,
527-
ConditionMatchTypes.SEMVER_GE: semver_greater_than_or_equal_evaluator,
528-
ConditionMatchTypes.SEMVER_GT: semver_greater_than_evaluator,
529-
ConditionMatchTypes.SEMVER_LE: semver_less_than_or_equal_evaluator,
530-
ConditionMatchTypes.SEMVER_LT: semver_less_than_evaluator,
531-
ConditionMatchTypes.SUBSTRING: substring_evaluator,
532-
ConditionMatchTypes.LESS_THAN_OR_EQUAL: less_than_or_equal_evaluator,
533-
ConditionMatchTypes.GREATER_THAN_OR_EQUAL: greater_than_or_equal_evaluator,
534-
}
535-
536543
def evaluate(self, index):
537544
""" Given a custom attribute audience condition and user attributes, evaluate the
538545
condition against the attributes.

optimizely/helpers/enums.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,5 @@ class NotificationTypes(object):
161161

162162
class SemverType(object):
163163
IS_PRE_RELEASE = '-'
164-
HAS_WHITE_SPACE = " "
164+
HAS_WHITE_SPACE = ' '
165165
IS_BUILD = '+'

0 commit comments

Comments
 (0)