Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ac7e81f
feat:semantic versioning
Jul 30, 2020
ee29674
semver updated
Jul 30, 2020
4a5e75d
more validation for invalid cases added
Aug 5, 2020
01ed4da
feat: Semantic Version
oakbani Aug 21, 2020
796af4d
GE and LE with test cases
Aug 24, 2020
f318995
Update test_condition.py
Aug 24, 2020
e016cd8
added ge le
msohailhussain Aug 24, 2020
857e8de
PR comments resolved
Aug 25, 2020
5f793a3
comments resolved
Aug 25, 2020
cfb12df
Update condition.py
Aug 25, 2020
379d637
Merge branch 'uzair/semver' into amna/semver
oakbani Aug 26, 2020
1c37fbf
invalid test case for semver and comment fixed
Aug 26, 2020
dcd391f
Update test_condition.py
Aug 26, 2020
2affb9d
Update test_condition.py
Aug 26, 2020
032d9c1
Merge branch 'uzair/semver' into amna/semver
oakbani Aug 26, 2020
8577f7c
compare implemetation and invalid testcase fixed
Aug 26, 2020
32bed45
Merge branch 'uzair/semver' into amna/semver
oakbani Aug 27, 2020
426d2b7
Revert "compare implemetation and invalid testcase fixed"
oakbani Aug 27, 2020
ac8113e
passes fsc at this point
oakbani Aug 27, 2020
84f6c26
fix:lint
oakbani Aug 27, 2020
ca7984a
remove: additional lint fixes
oakbani Aug 27, 2020
9256e6a
additional removal
oakbani Aug 27, 2020
15fa71b
further removal
oakbani Aug 27, 2020
8414a92
address most comments
oakbani Aug 28, 2020
78ce524
reorganize
oakbani Aug 28, 2020
aa1fbaf
tests: revised all unit tests
oakbani Aug 31, 2020
c8c0e75
Merge branch 'master' into amna/semver
oakbani Sep 2, 2020
907fcf2
address comments
oakbani Sep 2, 2020
8b4567c
add further checks
oakbani Sep 3, 2020
8856665
comments resolved
Sep 9, 2020
7ed20f0
comments resolved
Sep 9, 2020
4f2c05e
Update test_condition.py
Sep 14, 2020
4070805
Revert "Update test_condition.py"
Sep 14, 2020
4c471bd
Update test_condition.py
Sep 14, 2020
68708d9
Update test_condition.py
Sep 16, 2020
09533b1
Merge branch 'master' into amna/semver
msohailhussain Sep 16, 2020
ad17c02
testcase fixed
Sep 17, 2020
93cbb2a
Update condition.py
Sep 17, 2020
25ab44d
fix condition
oakbani Sep 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
semver updated
  • Loading branch information
Amna Ejaz committed Jul 30, 2020
commit ee296748a5547eab11358f1e8e4755de3ad58280
36 changes: 21 additions & 15 deletions optimizely/helpers/condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def substring_evaluator(self, index):
return condition_value in user_value

def semver_equal_evaluator(self, index):
""" Evaluate the given semver equal match target version for the user version.
""" Evaluate the given semantic version equal match target version for the user version.

Args:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit. Indentation is off. This needs to align with the quotes above.

index: Index of the condition to be evaluated.
Expand All @@ -255,7 +255,7 @@ def semver_equal_evaluator(self, index):
return self.compare_user_version_with_target_version(index) == 0

def semver_greater_than_evaluator(self, index):
""" Evaluate the given semver greater than match target version for the user version.
""" Evaluate the given semantic version greater than match target version for the user version.

Args:
index: Index of the condition to be evaluated.
Expand All @@ -267,10 +267,10 @@ def semver_greater_than_evaluator(self, index):
None:
- if the user version value is not string type or is null.
"""
return self.compare_user_version_with_target_version(index) == 1
return self.compare_user_version_with_target_version(index) > 0

def semver_less_than_evaluator(self, index):
""" Evaluate the given semver less than match target version for the user version.
""" Evaluate the given semantic version less than match target version for the user version.

Args:
index: Index of the condition to be evaluated.
Expand All @@ -282,10 +282,10 @@ def semver_less_than_evaluator(self, index):
None:
- if the user version value is not string type or is null.
"""
return self.compare_user_version_with_target_version(index) == -1
return self.compare_user_version_with_target_version(index) < 0

def semver_less_than_or_equal_evaluator(self, index):
""" Evaluate the given semver less than or equal to match target version for the user version.
""" Evaluate the given semantic version less than or equal to match target version for the user version.

Args:
index: Index of the condition to be evaluated.
Expand All @@ -300,7 +300,7 @@ def semver_less_than_or_equal_evaluator(self, index):
return self.compare_user_version_with_target_version(index) <= 0

def semver_greater_than_or_equal_evaluator(self, index):
""" Evaluate the given semver greater than or equal to match target version for the user version.
""" Evaluate the given semantic version greater than or equal to match target version for the user version.

Args:
index: Index of the condition to be evaluated.
Expand Down Expand Up @@ -328,9 +328,14 @@ def split_semantic_version(self, target):
"""
target_prefix = target
target_suffix = ""
target_parts = []

if self.is_pre_release(target) or self.is_build(target):
target_parts = target.split(SemverType.IS_PRE_RELEASE if self.is_pre_release(target) else SemverType.IS_BUILD)
if self.is_pre_release(target):
target_parts = target.split(SemverType.IS_PRE_RELEASE)
elif self.is_build(target):
target_parts = target.split(SemverType.IS_BUILD)

if target_parts:
if len(target_parts) < 1:
raise Exception(Errors.INVALID_ATTRIBUTE_FORMAT)

Expand Down Expand Up @@ -362,7 +367,6 @@ def is_pre_release(self, target):
def is_patch_pre_release(self, idx, idx_value):
return idx == SemverType.PATCH_INDEX and idx_value in SemverType.IS_PATCH_PRE_RELEASE


def is_build(self, target):
""" Method to check if the given version contains "+"

Expand All @@ -386,7 +390,8 @@ def compare_user_version_with_target_version(self, index):
Int:
- 0 if user version is equal to target version.
- 1 if user version is greater than target version.
- -1 if user version is less than target version or, in case of exact string match, doesn't match the target version.
- -1 if user version is less than target version or, in case of exact string match, doesn't match the target
version.
None:
- if the user version value is not string type or is null.
"""
Expand All @@ -396,7 +401,8 @@ def compare_user_version_with_target_version(self, index):

if not isinstance(user_version, string_types):
self.logger.warning(
audience_logs.UNEXPECTED_TYPE.format(self._get_condition_json(index), type(user_version), condition_name)
audience_logs.UNEXPECTED_TYPE.format(self._get_condition_json(index), type(user_version),
condition_name)
)
return None

Expand All @@ -408,13 +414,13 @@ def compare_user_version_with_target_version(self, index):
for (idx, _) in enumerate(target_version_parts):
if user_version_parts_len <= idx:
return -1
# compare strings e.g: alpha/beta/release
# compare strings
elif not user_version_parts[idx].isdigit():
if user_version_parts[idx] < target_version_parts[idx]:
return -1
elif user_version_parts[idx] > target_version_parts[idx]:
return 1
# compare numbers e.g: n1.n2.n3
# compare numbers
else:
user_version_part = int(user_version_parts[idx])
target_version_part = int(target_version_parts[idx])
Expand All @@ -423,7 +429,7 @@ def compare_user_version_with_target_version(self, index):
elif user_version_part < target_version_part:
return -1
if user_version_parts_len > target_version_parts_len:
if self.is_patch_pre_release(user_version_parts_len-1, user_version_parts[user_version_parts_len-1]):
if self.is_patch_pre_release(user_version_parts_len - 1, user_version_parts[user_version_parts_len - 1]):
return -1
return 0

Expand Down
4 changes: 2 additions & 2 deletions tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,8 @@ def setUp(self, config_dict='config_dict'):
'audienceConditions': [
'and',
['or', '3468206642', '3988293898'],
['or', '3988293899', '3468206646', '3468206647', '3468206644', '3468206643', '18278344267'],
['or', '3988293899', '3468206646', '3468206647', '3468206644', '3468206643',
'18278344267'],
],
'variations': [
{'variables': [], 'id': '11557362670', 'key': '11557362670', 'featureEnabled': True}
Expand Down Expand Up @@ -879,7 +880,6 @@ def setUp(self, config_dict='config_dict'):
{'key': 'should_do_it', 'id': '594017'},
{'key': 'favorite_ice_cream', 'id': '594018'},
{'key': 'android-release', 'id': '594019'},

],
'botFiltering': False,
'accountId': '4879520872',
Expand Down
103 changes: 53 additions & 50 deletions tests/helpers_tests/test_condition.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016-2019, Optimizely
# Copyright 2016-2020, Optimizely
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand Down Expand Up @@ -122,165 +122,162 @@ def test_evaluate__returns_null__when_condition_has_an_invalid_type_property(sel

self.assertIsNone(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_matches_target_version(self):
def test_evaluate__returns_true__when_user_version_2_matches_target_version_2(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_condition_list, {'Android': '2.0'}, self.mock_client_logger
semver_equal_2_condition_list, {'Android': '2'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_0_condition_list, {'Android': '2.0.0'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))
def test_evaluate__returns_true__when_user_version_2_2_matches_target_version_2(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_1_beta_condition_list, {'Android': '2.0.1-beta'}, self.mock_client_logger
semver_equal_2_condition_list, {'Android': '2.2'}, self.mock_client_logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this set true?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparison is made upto the len of target version. The target version is set to 2 here. @thomaszurkan-optimizely

)

self.assertStrictTrue(evaluator.evaluate(0))

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_0_condition_list, {'Android': '2.0.0.123'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))
def test_evaluate__returns_true__when_user_version_2_0_matches_target_version_2_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_condition_list, {'Android': '2.123'}, self.mock_client_logger
semver_equal_2_0_condition_list, {'Android': '2.0'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_false__when_user_version_does_not_match_target_version(self):
def test_evaluate__returns_true__when_user_version_2_0_0_matches_target_version_2_0_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_condition_list, {'Android': '1.0'}, self.mock_client_logger
semver_equal_2_0_0_condition_list, {'Android': '2.0.0'}, self.mock_client_logger
)

self.assertStrictFalse(evaluator.evaluate(0))
self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_false__when_user_version_2_0_does_not_match_target_version_2_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_0_condition_list, {'Android': '2.0'}, self.mock_client_logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this false?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason as above. The target version has been defined to higher precision 2.0.0. And the user version is only 2.0

)

self.assertStrictFalse(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_is_greater_than_target_version(self):
def test_evaluate__returns_true__when_user_version_2_0_0_release_is_greater_than_target_version_2_0_0_beta(
self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_2_0_0_beta_condition_list, {'Android': '2.0.0-release'}, self.mock_client_logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is greater because release > beta?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah

)

self.assertStrictTrue(evaluator.evaluate(0))

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_2_0_0_condition_list, {'Android': '2.0.1-release'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_false__when_user_version_is_not_greater_than_target_version(self):
def test_evaluate__returns_true__when_user_version_2_0_1_is_greater_than_target_version__2_0_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_2_0_0_condition_list, {'Android': '1.1.1'}, self.mock_client_logger
semver_greater_than_2_0_0_condition_list, {'Android': '2.0.1'}, self.mock_client_logger
)

self.assertStrictFalse(evaluator.evaluate(0))
self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_is_less_than_target_version(self):
def test_evaluate__returns_true__when_user_version_1_9_9_is_less_than_target_version_2_0_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_2_0_0_condition_list, {'Android': '1.9.1'}, self.mock_client_logger
semver_less_than_2_0_0_condition_list, {'Android': '1.9.9'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_1_9_0_beta_is_less_than_target_version_2_0_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_2_0_0_condition_list, {'Android': '1.9.0-beta'}, self.mock_client_logger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will get better to compare 2.0.0-beta against 2.0.0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this test different from test_evaluate__returns_true__when_user_version_2_0_0_beta_is_less_than_target_version_2_0_0_release ? We are not learning anything new.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, removed this one. The other that you mentioned should suffice.

)

self.assertStrictTrue(evaluator.evaluate(0))

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_2_0_0_release_condition_list, {'Android': '2.0.0-beta'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))
def test_evaluate__returns_true__when_user_version_2_0_0_release_is_less_than_target_version_2_0_0(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_2_0_0_condition_list, {'Android': '2.0.0-beta'}, self.mock_client_logger
semver_less_than_2_0_0_condition_list, {'Android': '2.0.0-release'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_2_0_0_beta_is_less_than_target_version_2_0_0_release(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_2_0_0_condition_list, {'Android': '2.0.0-release'}, self.mock_client_logger
semver_less_than_2_0_0_release_condition_list, {'Android': '2.0.0-beta'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_false__when_user_version_is_not_less_than_target_version(self):
def test_evaluate__returns_false__when_user_version_2_0_0_release_is_not_less_than_target_version_2_0_0_beta(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_2_0_0_beta_condition_list, {'Android': '2.0.0-release'}, self.mock_client_logger
)

self.assertStrictFalse(evaluator.evaluate(0))



def test_evaluate__returns_true__when_user_version_is_greater_than_or_equal_to_target_version(self):
def test_evaluate__returns_true__when_user_version_2_0_9_is_greater_than_or_equal_to_target_version_2_0_9(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_or_equal_2_0_9_condition_list, {'Android': '2.0.9'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_2_3_is_greater_than_or_equal_to_target_version_2_0_9(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_or_equal_2_0_9_condition_list, {'Android': '2.3'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_2_0_9_beta_is_greater_than_or_equal_to_target_version_2_0_9_beta(
self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_or_equal_2_0_9_beta_condition_list, {'Android': '2.0.9-beta'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_false__when_user_version_is_not_greater_than_or_equal_to_target_version(self):
def test_evaluate__returns_false__when_user_version_1_0_0_is_not_greater_than_or_equal_to_target_version_2_0_9(
self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_greater_than_or_equal_2_0_9_condition_list, {'Android': '1.0.0'}, self.mock_client_logger
)

self.assertStrictFalse(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_is_less_than_or_equal_to_target_version(self):
def test_evaluate__returns_true__when_user_version_2_0_1_is_less_than_or_equal_to_target_version_2_0_1(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_or_equal_2_0_1_condition_list, {'Android': '2.0.1'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_1_1_is_less_than_or_equal_to_target_version_2_0_1(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_or_equal_2_0_1_condition_list, {'Android': '1.1'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_true__when_user_version_2_0_1_beta_is_less_than_or_equal_to_target_version_2_0_1(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_or_equal_2_0_1_beta_condition_list, {'Android': '2.0.1-beta'}, self.mock_client_logger
semver_less_than_or_equal_2_0_1_condition_list, {'Android': '2.0.1-beta'}, self.mock_client_logger
)

self.assertStrictTrue(evaluator.evaluate(0))

def test_evaluate__returns_false__when_user_version_is_not_less_than_or_equal_to_target_version(self):
def test_evaluate__returns_false__when_user_version_3_0_1_is_not_less_than_or_equal_to_target_version_2_0_1(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
semver_less_than_or_equal_2_0_1_condition_list, {'Android': '3.0.1'}, self.mock_client_logger
Expand All @@ -304,27 +301,33 @@ def test_evaluate__returns_null__when_user_provided_version_is_null(self):

self.assertIsNone(evaluator.evaluate(0))

def test_evaluate__returns_null__when_user_provided_version_is_invalid(self):
def test_evaluate__returns_exception__when_user_provided_version_is_invalid1(self):

evaluator = condition_helper.CustomAttributeConditionEvaluator(
condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_condition_list, {'Android': "+"}, self.mock_client_logger
)

self.assertRaises(Exception)

evaluator = condition_helper.CustomAttributeConditionEvaluator(
def test_evalduate__returns_exception__when_user_provided_version_is_invalid2(self):

condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_condition_list, {'Android': "+--"}, self.mock_client_logger
)

self.assertRaises(Exception)

evaluator = condition_helper.CustomAttributeConditionEvaluator(
def test_evalduate__returns_exception__when_user_provided_version_is_invalid3(self):

condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_condition_list, {'Android': "...+"}, self.mock_client_logger
)

self.assertRaises(Exception)

evaluator = condition_helper.CustomAttributeConditionEvaluator(
def test_evalduate__returns_exception__when_user_provided_version_is_invalid4(self):

condition_helper.CustomAttributeConditionEvaluator(
semver_equal_2_0_condition_list, {'Android': "+test"}, self.mock_client_logger
)

Expand Down