From 887d2eeb87443c626cb69aca0e307615b26edded Mon Sep 17 00:00:00 2001 From: muhammadnoman Date: Thu, 3 Sep 2020 21:31:13 +0500 Subject: [PATCH 1/2] Comparision of multiple dashes and other fixes --- .../ConditionEvaluationTest.cs | 43 ++++++++++++++++++- .../AudienceConditions/SemanticVersion.cs | 36 +++++++++++++--- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs index 07b8d337..ce1fbe51 100644 --- a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs +++ b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs @@ -308,8 +308,28 @@ public void TestGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValu Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 15 } }, Logger), Is.True); } + [Test] + public void TestSemVerGTTargetBetaComplex() + { + var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "2.1.3-beta+1", Match = "semver_gt", Type = "custom_attribute" }; + Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "2.1.3-beta+1.2.3" } }, Logger) ?? false); + } + + [Test] + public void TestSemVerGTCompareAgainstPreReleaseToPreRelease() + { + var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.0-beta.2-beta3.4-5+2.3.2", Match = "semver_gt", Type = "custom_attribute" }; + Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0+a--b" } }, Logger) ?? false); + } + + [Test] + public void TestSemVerGTComparePrereleaseSmallerThanBuild() + { + var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.1-prerelease", Match = "semver_gt", Type = "custom_attribute" }; + Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1+build" } }, Logger) ?? false); + } #endregion // GTMatcher Tests - + #region GEMatcher Tests [Test] @@ -372,6 +392,20 @@ public void TestLTMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValue() Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 5 } }, Logger), Is.True); } + [Test] + public void TestSemVerLTTargetBuildComplex() + { + var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "2.1.3-beta+1.2.3", Match = "semver_lt", Type = "custom_attribute" }; + Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta+1" } }, Logger) ?? false); + } + + [Test] + public void TestSemVerLTCompareMultipleDash() + { + var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "2.1.3-beta-1.2.3", Match = "semver_lt", Type = "custom_attribute" }; + Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta-1" } }, Logger) ?? false); + } + #endregion // LTMatcher Tests #region LEMatcher Tests @@ -503,6 +537,13 @@ public void TestSemVerEQMatcherReturnsTrueWhenAttributeValueIsEqualToConditionVa var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "3.7.0-beta.2.3", Match = "semver_eq", Type = "custom_attribute" }; Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.0-beta.2.3" } }, Logger) ?? false); } + + [Test] + public void TestSemVerEQTargetBuildIgnores() + { + var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "2.1.3", Match = "semver_eq", Type = "custom_attribute" }; + Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2.1.3+build" } }, Logger) ?? false); + } #endregion // SemVerEQMatcher Tests #region SemVerGEMatcher Tests diff --git a/OptimizelySDK/AudienceConditions/SemanticVersion.cs b/OptimizelySDK/AudienceConditions/SemanticVersion.cs index ef8ac8e0..e191dc51 100644 --- a/OptimizelySDK/AudienceConditions/SemanticVersion.cs +++ b/OptimizelySDK/AudienceConditions/SemanticVersion.cs @@ -44,7 +44,17 @@ public static bool ContainsWhiteSpace(this string semanticVersion) /// True if Semantic version contains '-', else false public static bool IsPreRelease(this string semanticVersion) { - return semanticVersion.Contains(PreReleaseSeparator.ToString()); + var buildIndex = semanticVersion.IndexOf(BuildSeparator.ToString()); + var preReleaseIndex = semanticVersion.IndexOf(PreReleaseSeparator.ToString()); + if (buildIndex < 0) + { + return preReleaseIndex > 0; + } + else if (preReleaseIndex < 0) + { + return false; + } + return preReleaseIndex < buildIndex; } /// @@ -54,7 +64,17 @@ public static bool IsPreRelease(this string semanticVersion) /// True if Semantic version contains '+', else false public static bool IsBuild(this string semanticVersion) { - return semanticVersion.Contains(BuildSeparator.ToString()); + var buildIndex = semanticVersion.IndexOf(BuildSeparator.ToString()); + var preReleaseIndex = semanticVersion.IndexOf(PreReleaseSeparator.ToString()); + if (preReleaseIndex < 0) + { + return buildIndex > 0; + } + else if (buildIndex < 0) + { + return false; + } + return buildIndex < preReleaseIndex; } /// @@ -88,7 +108,7 @@ public static string[] SplitSemanticVersion(this string version) if (version.IsBuild() || version.IsPreRelease()) { var partialVersionParts = version.Split(new char [] { version.IsPreRelease() ? - PreReleaseSeparator : BuildSeparator}, StringSplitOptions.RemoveEmptyEntries); + PreReleaseSeparator : BuildSeparator}, 2, StringSplitOptions.RemoveEmptyEntries); if (partialVersionParts.Length <= 1) { // throw error @@ -170,10 +190,14 @@ public int CompareTo(SemanticVersion targetedVersion) if (!int.TryParse(userVersionParts[index], out int userVersionPartInt)) { // Compare strings - int result = string.Compare(userVersionParts[index], targetedVersionParts[index]); - if (result != 0) + var result = string.Compare(userVersionParts[index], targetedVersionParts[index]); + if (result < 0) + { + return targetedVersion.Version.IsPreRelease() && !Version.IsPreRelease() ? 1 : -1; + } + else if (result > 0) { - return result; + return !targetedVersion.Version.IsPreRelease() && Version.IsPreRelease() ? -1 : 1; } } else if (int.TryParse(targetedVersionParts[index], out int targetVersionPartInt)) From 7d8345d011c6608f448feeccc9d592093affdd72 Mon Sep 17 00:00:00 2001 From: muhammadnoman Date: Thu, 3 Sep 2020 21:35:59 +0500 Subject: [PATCH 2/2] unit test added --- .../AudienceConditionsTests/ConditionEvaluationTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs index ce1fbe51..dc5d66b2 100644 --- a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs +++ b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs @@ -318,8 +318,8 @@ public void TestSemVerGTTargetBetaComplex() [Test] public void TestSemVerGTCompareAgainstPreReleaseToPreRelease() { - var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.0-beta.2-beta3.4-5+2.3.2", Match = "semver_gt", Type = "custom_attribute" }; - Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0+a--b" } }, Logger) ?? false); + var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.1-prerelease+build", Match = "semver_gt", Type = "custom_attribute" }; + Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1-prerelease+rc" } }, Logger) ?? false); } [Test]