-
Notifications
You must be signed in to change notification settings - Fork 30
feat: Semantic Versioning suppport in Audience Evaluation #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes requested.
protected function semverEqualEvaluator($condition) | ||
{ | ||
$comparison = $this->semverEvaluator($condition); | ||
if ($comparison !== null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Will be more readable if you do:
if ($comparison === null) { return null } return $comparison === 0
For all others too
|
||
public function testSemVerGTMatcherReturnsFalseWhenAttributeValueIsLessThanOrEqualToConditionValue() | ||
{ | ||
$customAttrConditionEvaluator = new CustomAttributeConditionEvaluator( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. define the condition inside this method just like you have done below. testSemVerGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValueBeta()
$invalidValues = ["-", ".", "..", "+", "+test", " ", "2 .3. 0", "2.", | ||
".2.2", "3.7.2.2", "3.x", ",", "+build-prerelease"]; | ||
|
||
foreach ($invalidValues as $val) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you write the above tests in a for loop just like you have done here?
seta custom error message and send it to assert call as last argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than creating SemVersionConditionEvaluator as a separate class and creating it's instance on every evaluation call. Make method inside SemVerionEvaluator static. And directly use them from different evaluator methods. Pass logger as a param to compare_version static method. And move string validation to compare_version method as well.
compare_version should get (target_version, user_version, logger)
$conditionValue = $condition['value']; | ||
$userValue = isset($this->userAttributes[$conditionName]) ? $this->userAttributes[$conditionName] : null; | ||
|
||
if (!Validator::validateNonEmptyString($conditionValue)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$userValue should be checked here instead of $conditionValue. And a unit test written if not already.
private function toInt($str) | ||
{ | ||
if (is_numeric($str)) { | ||
return intval($str); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can directly use PHP intVal method. https://www.php.net/manual/en/function.intval.php
The integer value of var on success, or 0 on failure. Empty arrays return 0, non-empty arrays return 1.
} | ||
|
||
/** | ||
* checks if string contains prerelease seperator before build separator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checks if given string is a prerelease version?
prerelease seperator before build separator. is an implementation detail that should come as a comment inside code.
/** | ||
* checks if string contains prerelease seperator before build separator. | ||
* | ||
* @param string $str value to be checked. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's rename $str to $version
* | ||
* @param string $str value to be checked. | ||
* | ||
* @return bool true if prerelease seperator comes first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true if given version is a prerelease
* @return null|array array if provided string was successfully split, | ||
* null if any issues occured. | ||
*/ | ||
protected function splitSemanticVersion($targetedVersion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit.rename to $version. This method doesn't know if it's targeted or userVersion
$targetSuffix = array(); | ||
|
||
if ($this->isPreRelease($targetedVersion) || $this->isBuild($targetedVersion)) { | ||
$targetParts = explode($this->isPreRelease($targetPrefix) ? self::PRE_RELEASE_SEPARATOR : self::BUILD_SEPARATOR, $targetedVersion, 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->isPreRelease($targetPrefix) ? self::PRE_RELEASE_SEPARATOR : self::BUILD_SEPARATOR
assign this to a variable before use. Readability.
if ($targetedVersionParts === null) { | ||
return null; | ||
} | ||
$versionParts = $this->splitSemanticVersion($this->condition); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. rename userVersionParts
|
||
// Up to the precision of targetedVersion, expect version to match exactly. | ||
for ($i = 0; $i < count($targetedVersionParts); $i++) { | ||
if (count($versionParts) <= $i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
count($versionParts)
assign this to a variable at top and resuse
// Up to the precision of targetedVersion, expect version to match exactly. | ||
for ($i = 0; $i < count($targetedVersionParts); $i++) { | ||
if (count($versionParts) <= $i) { | ||
// even if they are equal at this point. if the target is a prerelease then it must be greater than the pre release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. looks like there is something wrong with this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
@@ -143,15 +143,13 @@ protected function semverEvaluator($condition) | |||
$conditionValue = $condition['value']; | |||
$userValue = isset($this->userAttributes[$conditionName]) ? $this->userAttributes[$conditionName] : null; | |||
|
|||
if (!Validator::validateNonEmptyString($conditionValue)) { | |||
if (!Validator::validateNonEmptyString($conditionValue) || !Validator::validateNonEmptyString($userValue)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just remove the check for conditionValue. We assume that we get string semantic version value from the datafile/backend.
And in case of bad condition value, the error message being logged is misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit.
Modify doc string of this method to returns result of SemVersionConditionEvaluator::compareVersion for given target and user versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yasirfolio3 Code Optimization
$targetSuffix = array(); | ||
|
||
if (self::isPreRelease($version) || self::isBuild($version)) { | ||
$separator = self::isPreRelease($targetPrefix) ? self::PRE_RELEASE_SEPARATOR : self::BUILD_SEPARATOR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self::isPreRelease($targetPrefix)
nit. do this once
if (self::isPreRelease)
$separator = ...
elseif(self::isBuild)
$separator = ...
if (!self::isPreRelease($targetedVersion) && self::isPreRelease($userVersion)) { | ||
return -1; | ||
} | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assign self::isPreRelease($targetedVersion) and self::isPreRelease($userVersion) to variables at the top of this method. And reuse them at all places.
return array(self::EXACT_MATCH_TYPE, self::EXISTS_MATCH_TYPE, self::GREATER_THAN_MATCH_TYPE, self::GREATER_THAN_EQUAL_TO_MATCH_TYPE, | ||
self::LESS_THAN_MATCH_TYPE, self::LESS_THAN_EQUAL_TO_MATCH_TYPE, self::SUBSTRING_MATCH_TYPE, self::SEMVER_EQ, | ||
self::SEMVER_GT, self::SEMVER_GE, self::SEMVER_LT, self::SEMVER_LE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be made nicer by having these on separate lines and alphabetized.
$evaluatorsByMatchType[self::SUBSTRING_MATCH_TYPE] = 'substringEvaluator'; | ||
$evaluatorsByMatchType[self::SEMVER_EQ] = 'semverEqualEvaluator'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Alphabetize.
@@ -109,6 +125,33 @@ protected function isValueTypeValidForExactConditions($value) | |||
return false; | |||
} | |||
|
|||
/** | |||
* returns result of SemVersionConditionEvaluator::compareVersion for given target and user versions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Returns
* @return null|int 0 if user's semver attribute is equal to the semver condition value, | ||
* 1 if user's semver attribute is greater than the semver condition value, | ||
* -1 if user's semver attribute is less than the semver condition value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User has a version attribute. Semver is a specification.
* | ||
* @param object $condition | ||
* | ||
* @return boolean true if user's semver attribute is greater than the semver condition value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. version attribute. Please update at all places.
/** | ||
* compares targeted version with the provided user version. | ||
* | ||
* @param object $targetedVersion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't the versions string?
* | ||
* @return bool true if given version is a build. | ||
*/ | ||
private static function isBuild($version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. isBuildVersion
* | ||
* @return bool true if given version is a prerelease. | ||
*/ | ||
private static function isPreRelease($version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. isPreReleaseVersion
* @param string $userVersion | ||
* @param object $logger | ||
* | ||
* @return null|int 0 if user's semver attribute is equal to the semver condition value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. user's attribute
or user's version attribute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please apply this feedback throughout the PR.
* @param string $userVersion | ||
* @param object $logger | ||
* | ||
* @return null|int 0 if user's semver attribute is equal to the semver condition value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please apply this feedback throughout the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Summary