Skip to content

Commit 38e82b2

Browse files
authored
fix: Semantic version fix and multiple dash signs check added (#242)
* Comparision of multiple dashes and other fixes * unit test added
1 parent 7f59df3 commit 38e82b2

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,28 @@ public void TestGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValu
308308
Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 15 } }, Logger), Is.True);
309309
}
310310

311+
[Test]
312+
public void TestSemVerGTTargetBetaComplex()
313+
{
314+
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "2.1.3-beta+1", Match = "semver_gt", Type = "custom_attribute" };
315+
Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "2.1.3-beta+1.2.3" } }, Logger) ?? false);
316+
}
317+
318+
[Test]
319+
public void TestSemVerGTCompareAgainstPreReleaseToPreRelease()
320+
{
321+
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.1-prerelease+build", Match = "semver_gt", Type = "custom_attribute" };
322+
Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1-prerelease+rc" } }, Logger) ?? false);
323+
}
324+
325+
[Test]
326+
public void TestSemVerGTComparePrereleaseSmallerThanBuild()
327+
{
328+
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.1-prerelease", Match = "semver_gt", Type = "custom_attribute" };
329+
Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1+build" } }, Logger) ?? false);
330+
}
311331
#endregion // GTMatcher Tests
312-
332+
313333
#region GEMatcher Tests
314334

315335
[Test]
@@ -372,6 +392,20 @@ public void TestLTMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValue()
372392
Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 5 } }, Logger), Is.True);
373393
}
374394

395+
[Test]
396+
public void TestSemVerLTTargetBuildComplex()
397+
{
398+
var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "2.1.3-beta+1.2.3", Match = "semver_lt", Type = "custom_attribute" };
399+
Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta+1" } }, Logger) ?? false);
400+
}
401+
402+
[Test]
403+
public void TestSemVerLTCompareMultipleDash()
404+
{
405+
var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "2.1.3-beta-1.2.3", Match = "semver_lt", Type = "custom_attribute" };
406+
Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta-1" } }, Logger) ?? false);
407+
}
408+
375409
#endregion // LTMatcher Tests
376410

377411
#region LEMatcher Tests
@@ -503,6 +537,13 @@ public void TestSemVerEQMatcherReturnsTrueWhenAttributeValueIsEqualToConditionVa
503537
var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "3.7.0-beta.2.3", Match = "semver_eq", Type = "custom_attribute" };
504538
Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.0-beta.2.3" } }, Logger) ?? false);
505539
}
540+
541+
[Test]
542+
public void TestSemVerEQTargetBuildIgnores()
543+
{
544+
var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "2.1.3", Match = "semver_eq", Type = "custom_attribute" };
545+
Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2.1.3+build" } }, Logger) ?? false);
546+
}
506547
#endregion // SemVerEQMatcher Tests
507548

508549
#region SemVerGEMatcher Tests

OptimizelySDK/AudienceConditions/SemanticVersion.cs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,17 @@ public static bool ContainsWhiteSpace(this string semanticVersion)
4444
/// <returns>True if Semantic version contains '-', else false</returns>
4545
public static bool IsPreRelease(this string semanticVersion)
4646
{
47-
return semanticVersion.Contains(PreReleaseSeparator.ToString());
47+
var buildIndex = semanticVersion.IndexOf(BuildSeparator.ToString());
48+
var preReleaseIndex = semanticVersion.IndexOf(PreReleaseSeparator.ToString());
49+
if (buildIndex < 0)
50+
{
51+
return preReleaseIndex > 0;
52+
}
53+
else if (preReleaseIndex < 0)
54+
{
55+
return false;
56+
}
57+
return preReleaseIndex < buildIndex;
4858
}
4959

5060
/// <summary>
@@ -54,7 +64,17 @@ public static bool IsPreRelease(this string semanticVersion)
5464
/// <returns>True if Semantic version contains '+', else false</returns>
5565
public static bool IsBuild(this string semanticVersion)
5666
{
57-
return semanticVersion.Contains(BuildSeparator.ToString());
67+
var buildIndex = semanticVersion.IndexOf(BuildSeparator.ToString());
68+
var preReleaseIndex = semanticVersion.IndexOf(PreReleaseSeparator.ToString());
69+
if (preReleaseIndex < 0)
70+
{
71+
return buildIndex > 0;
72+
}
73+
else if (buildIndex < 0)
74+
{
75+
return false;
76+
}
77+
return buildIndex < preReleaseIndex;
5878
}
5979

6080
/// <summary>
@@ -88,7 +108,7 @@ public static string[] SplitSemanticVersion(this string version)
88108
if (version.IsBuild() || version.IsPreRelease())
89109
{
90110
var partialVersionParts = version.Split(new char [] { version.IsPreRelease() ?
91-
PreReleaseSeparator : BuildSeparator}, StringSplitOptions.RemoveEmptyEntries);
111+
PreReleaseSeparator : BuildSeparator}, 2, StringSplitOptions.RemoveEmptyEntries);
92112
if (partialVersionParts.Length <= 1)
93113
{
94114
// throw error
@@ -170,10 +190,14 @@ public int CompareTo(SemanticVersion targetedVersion)
170190
if (!int.TryParse(userVersionParts[index], out int userVersionPartInt))
171191
{
172192
// Compare strings
173-
int result = string.Compare(userVersionParts[index], targetedVersionParts[index]);
174-
if (result != 0)
193+
var result = string.Compare(userVersionParts[index], targetedVersionParts[index]);
194+
if (result < 0)
195+
{
196+
return targetedVersion.Version.IsPreRelease() && !Version.IsPreRelease() ? 1 : -1;
197+
}
198+
else if (result > 0)
175199
{
176-
return result;
200+
return !targetedVersion.Version.IsPreRelease() && Version.IsPreRelease() ? -1 : 1;
177201
}
178202
}
179203
else if (int.TryParse(targetedVersionParts[index], out int targetVersionPartInt))

0 commit comments

Comments
 (0)