diff --git a/CSF.Extensions.WebDriver.Tests/Identification/BrowserVersionIntegrationTests.cs b/CSF.Extensions.WebDriver.Tests/Identification/BrowserVersionIntegrationTests.cs
new file mode 100644
index 0000000..76fe0c2
--- /dev/null
+++ b/CSF.Extensions.WebDriver.Tests/Identification/BrowserVersionIntegrationTests.cs
@@ -0,0 +1,41 @@
+namespace CSF.Extensions.WebDriver.Identification;
+
+[TestFixture, Parallelizable]
+public class BrowserVersionIntegrationTests
+{
+ [Test]
+ public void ALowerVersionShouldBeLessThanAHigherOneWithMoreComponents()
+ {
+ var first = BrowserVersion.Create("95.0.4638");
+ var second = BrowserVersion.Create("95.1.1234.5678");
+
+ Assert.That(first, Is.LessThan(second), "First version is less than second version");
+ }
+
+ [Test]
+ public void AHigherVersionShouldBeGreaterThanALowerOneWithMoreComponents()
+ {
+ var first = BrowserVersion.Create("95.2.4638");
+ var second = BrowserVersion.Create("95.1.1234.5678");
+
+ Assert.That(first, Is.GreaterThan(second), "First version is greater than second version");
+ }
+
+ [Test]
+ public void ALowerVersionShouldBeLessThanAHigherOneWithFewerComponents()
+ {
+ var first = BrowserVersion.Create("95.0.4638.1234");
+ var second = BrowserVersion.Create("95.1");
+
+ Assert.That(first, Is.LessThan(second), "First version is less than second version");
+ }
+
+ [Test]
+ public void AHigherVersionShouldBeGreaterThanALowerOneWithFewerComponents()
+ {
+ var first = BrowserVersion.Create("95.2.4638.1234");
+ var second = BrowserVersion.Create("95.1");
+
+ Assert.That(first, Is.GreaterThan(second), "First version is greater than second version");
+ }
+}
\ No newline at end of file
diff --git a/CSF.Extensions.WebDriver.Tests/Identification/DottedNumericBrowserVersionTests.cs b/CSF.Extensions.WebDriver.Tests/Identification/DottedNumericBrowserVersionTests.cs
index ca3d1fa..c235347 100644
--- a/CSF.Extensions.WebDriver.Tests/Identification/DottedNumericBrowserVersionTests.cs
+++ b/CSF.Extensions.WebDriver.Tests/Identification/DottedNumericBrowserVersionTests.cs
@@ -61,4 +61,36 @@ public void TryParseShouldReturnFalseForAnInvalidVersion()
{
Assert.That(DottedNumericBrowserVersion.TryParse("Elephants", out _), Is.False);
}
+
+ [Test, AutoMoqData]
+ public void GetHashCodeShouldReturnTheSameResultForTwoEqualInstances()
+ {
+ var one = new DottedNumericBrowserVersion([1, 2, 3]);
+ var two = new DottedNumericBrowserVersion([1, 2, 3]);
+
+ Assert.That(one.GetHashCode(), Is.EqualTo(two.GetHashCode()));
+ }
+
+ [Test, AutoMoqData]
+ public void EqualsObjectShouldReturnTrueForTwoEqualInstances()
+ {
+ object one = new DottedNumericBrowserVersion([1, 2, 3]);
+ object two = new DottedNumericBrowserVersion([1, 2, 3]);
+
+#pragma warning disable NUnit2010 // Use EqualConstraint - not doing this to explicitly show what I'm testing
+ Assert.That(one.Equals(two), Is.True);
+#pragma warning restore NUnit2010
+ }
+
+ [Test, AutoMoqData]
+ public void ConstructorShouldThrowForAnEmptyListOfComponents()
+ {
+ Assert.That(() => new DottedNumericBrowserVersion([]), Throws.ArgumentException);
+ }
+
+ [Test, AutoMoqData]
+ public void ConstructorShouldThrowForANullListOfComponents()
+ {
+ Assert.That(() => new DottedNumericBrowserVersion(null), Throws.ArgumentNullException);
+ }
}
\ No newline at end of file
diff --git a/CSF.Extensions.WebDriver/Identification/BrowserVersion.cs b/CSF.Extensions.WebDriver/Identification/BrowserVersion.cs
index 80a387c..731cf56 100644
--- a/CSF.Extensions.WebDriver/Identification/BrowserVersion.cs
+++ b/CSF.Extensions.WebDriver/Identification/BrowserVersion.cs
@@ -166,7 +166,7 @@ public static BrowserVersion Create(string version, string requestedVersion = nu
if (SemanticBrowserVersion.TryParse(version, out var semVersion)) return semVersion;
if (DottedNumericBrowserVersion.TryParse(version, out var numericVersion)) return numericVersion;
if (SemanticBrowserVersion.TryParse(requestedVersion, out var requestedSemVersion, true)) return requestedSemVersion;
- if (DottedNumericBrowserVersion.TryParse(requestedVersion, out var requestedNumericVersion)) return requestedNumericVersion;
+ if (DottedNumericBrowserVersion.TryParse(requestedVersion, out var requestedNumericVersion, true)) return requestedNumericVersion;
if (UnrecognisedBrowserVersion.TryParse(version, out var unrecognisedVersion)) return unrecognisedVersion;
if (UnrecognisedBrowserVersion.TryParse(requestedVersion, out var requestedUnrecognisedVersion)) return requestedUnrecognisedVersion;
diff --git a/CSF.Extensions.WebDriver/Identification/DottedNumericVersion.cs b/CSF.Extensions.WebDriver/Identification/DottedNumericBrowserVersion.cs
similarity index 80%
rename from CSF.Extensions.WebDriver/Identification/DottedNumericVersion.cs
rename to CSF.Extensions.WebDriver/Identification/DottedNumericBrowserVersion.cs
index d815220..836e222 100644
--- a/CSF.Extensions.WebDriver/Identification/DottedNumericVersion.cs
+++ b/CSF.Extensions.WebDriver/Identification/DottedNumericBrowserVersion.cs
@@ -16,11 +16,17 @@ namespace CSF.Extensions.WebDriver.Identification
/// - It permits any amount of leading and trailing non-numeric characters
/// - It permits any number of 'version' components, not just a maximum of 3 as is the case with SemVer
///
+ ///
+ /// The implementations of and include special-case logic for comparing/equating
+ /// dotted numeric versions with instances. If these methods (from this type) are used with a semantic version
+ /// then that semantic version is converted into a dotted numeric version first, using .
+ /// The methods then proceed according to their usual logic, with the resulting converted version.
+ ///
///
public sealed class DottedNumericBrowserVersion : BrowserVersion
{
const string parserPattern = @"(\d+)(?:\.(\d+))*";
- static readonly Regex parser = new Regex(parserPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant);
+ static readonly Regex parser = new Regex(parserPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant, TimeSpan.FromMilliseconds(50));
readonly IReadOnlyList components;
@@ -33,8 +39,13 @@ public sealed class DottedNumericBrowserVersion : BrowserVersion
///
public override int CompareTo(BrowserVersion other)
{
- if (other is null || !(other is DottedNumericBrowserVersion version)) return 1;
+ if(other is DottedNumericBrowserVersion dotVersion) return CompareTo(dotVersion);
+ if(other is SemanticBrowserVersion semVersion) return CompareTo(semVersion.ToDottedNumericBrowserVersion());
+ return 1;
+ }
+ int CompareTo(DottedNumericBrowserVersion version)
+ {
var theirCount = version.VersionComponents.Count;
for (var i = 0; i < VersionComponents.Count; i++)
{
@@ -54,10 +65,10 @@ public override int CompareTo(BrowserVersion other)
///
public override bool Equals(BrowserVersion other)
- {
- if (other is null || !(other is DottedNumericBrowserVersion version)) return false;
- return VersionComponents.SequenceEqual(version.VersionComponents);
- }
+ => other is DottedNumericBrowserVersion dotVersion && VersionComponents.SequenceEqual(dotVersion.VersionComponents);
+
+ ///
+ public override bool Equals(object obj) => obj is BrowserVersion ver && Equals(ver);
///
public override int GetHashCode() => VersionComponents.Aggregate(17, HashFunction);
diff --git a/CSF.Extensions.WebDriver/Identification/SemanticBrowserVersion.cs b/CSF.Extensions.WebDriver/Identification/SemanticBrowserVersion.cs
index 8433b39..34d38c5 100644
--- a/CSF.Extensions.WebDriver/Identification/SemanticBrowserVersion.cs
+++ b/CSF.Extensions.WebDriver/Identification/SemanticBrowserVersion.cs
@@ -17,6 +17,13 @@ namespace CSF.Extensions.WebDriver.Identification
/// to permit some common improper representations of a semantic version. The TryParse function in this class
/// uses to enable very generous parsing.
///
+ ///
+ /// The implementations of and include special-case logic for comparing/equating
+ /// semantic versions with instances. If these methods (from this type) are used with a dotted numeric version
+ /// then the current instance is converted into a dotted numeric version first, using .
+ /// The equality/comparison methods then make use of and
+ /// accordingly, performing using the comparison functions from the converted version instead.
+ ///
///
public sealed class SemanticBrowserVersion : BrowserVersion
{
@@ -28,16 +35,31 @@ public sealed class SemanticBrowserVersion : BrowserVersion
///
public override int CompareTo(BrowserVersion other)
{
- if (other is null || !(other is SemanticBrowserVersion semVersion)) return 1;
- return Version.CompareSortOrderTo(semVersion.Version);
+ if(other is SemanticBrowserVersion semVersion) return Version.CompareSortOrderTo(semVersion.Version);
+ if(other is DottedNumericBrowserVersion dotVersion) return ToDottedNumericBrowserVersion().CompareTo(dotVersion);
+ return 1;
}
///
public override bool Equals(BrowserVersion other)
- {
- if (other is null || !(other is SemanticBrowserVersion semVersion)) return false;
- return Version.Equals(semVersion.Version);
- }
+ => other is SemanticBrowserVersion semVersion && Version.Equals(semVersion.Version);
+
+ ///
+ public override bool Equals(object obj) => obj is BrowserVersion ver && Equals(ver);
+
+ ///
+ /// Converts the current into an instance of .
+ ///
+ ///
+ ///
+ /// This is useful in situations where the current version must be compared with a dotted numeric version.
+ /// Note that only the Major, Minor and Patch version components are converted. Any prerelease information or build
+ /// metadata are omitted from this conversion process.
+ ///
+ ///
+ /// A dotted numeric browser version, created from the major, minor and patch components of this semantic version.
+ public DottedNumericBrowserVersion ToDottedNumericBrowserVersion()
+ => new DottedNumericBrowserVersion(new [] {Version.Major, Version.Minor, Version.Patch}, IsPresumedVersion);
///
public override int GetHashCode() => Version.GetHashCode();