1
0

Added VersionStringComparer

This commit is contained in:
2024-02-25 09:44:36 +01:00
parent d4b390ad91
commit cf425da609
3 changed files with 154 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace AMWD.Common.Comparer
{
/// <summary>
/// Defines a method to compare two <see cref="Version"/> strings.
/// </summary>
#if NET8_0_OR_GREATER
public partial class VersionStringComparer : IComparer<string>
{
private readonly Regex _versionRegex = VersionRegex();
#else
public class VersionStringComparer : IComparer<string>
{
private readonly Regex _versionRegex = new("([0-9.]+)");
#endif
/// <summary>
/// Compares two <see cref="Version"/> strings and returns a value indicating
/// whether one is less than, equal to, or greater than the other.
/// </summary>
/// <param name="x">The first version string.</param>
/// <param name="y">The second version string.</param>
/// <returns>
/// A signed integer that indicates the relative values of x and y, as shown in the following table:
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <description>Meaning</description>
/// </listheader>
/// <item>
/// <term>-1</term>
/// <description>x is less than y</description>
/// </item>
/// <item>
/// <term>0</term>
/// <description>x equals y</description>
/// </item>
/// <item>
/// <term>1</term>
/// <description>x is greater than y</description>
/// </item>
/// </list>
/// </returns>
public int Compare(string x, string y)
{
if (string.IsNullOrWhiteSpace(x) && string.IsNullOrWhiteSpace(y))
return 0;
if (string.IsNullOrWhiteSpace(x))
return -1;
if (string.IsNullOrWhiteSpace(y))
return 1;
string xMainVersion = _versionRegex.Match(x).Groups[1].Value;
string yMainVersion = _versionRegex.Match(y).Groups[1].Value;
string xAppendix = x.ReplaceStart(xMainVersion, "");
string yAppendix = y.ReplaceStart(yMainVersion, "");
if (xMainVersion.IndexOf('.') < 0)
xMainVersion += ".0";
if (yMainVersion.IndexOf('.') < 0)
yMainVersion += ".0";
var xVersion = Version.Parse(xMainVersion);
var yVersion = Version.Parse(yMainVersion);
int versionResult = xVersion.CompareTo(yVersion);
if (versionResult != 0)
return versionResult;
return xAppendix.CompareTo(yAppendix);
}
#if NET8_0_OR_GREATER
[GeneratedRegex("([0-9.]+)")]
private static partial Regex VersionRegex();
#endif
}
}

View File

@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `ArReader` and `ArWriter` for Unix archives - `ArReader` and `ArWriter` for Unix archives
- `TarReader` and `TarWriter` for TAR archives - `TarReader` and `TarWriter` for TAR archives
- `VersionStringComparer` to compare version strings (SemVer)
### Changed ### Changed

View File

@@ -0,0 +1,67 @@
using AMWD.Common.Comparer;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.Common.Comparer
{
[TestClass]
public class VersionStringComparerTests
{
[DataTestMethod]
[DataRow(null, "0")]
[DataRow("", "0")]
[DataRow("0", "1")]
[DataRow("1.0", "1.1")]
[DataRow("1.0.0", "1.0.1")]
[DataRow("1.0.0.0", "1.0.0.1")]
[DataRow("1.0.0.0-RC1", "1.0.0.0-RC2")]
public void ShouldBeLessThan(string x, string y)
{
// Arrange
var comparer = new VersionStringComparer();
// Act
int result = comparer.Compare(x, y);
// Assert
Assert.AreEqual(-1, result);
}
[DataTestMethod]
[DataRow("0", null)]
[DataRow("0", "")]
[DataRow("1", "0")]
[DataRow("1.1", "1.0")]
[DataRow("1.0.1", "1.0.0")]
[DataRow("1.0.0.1", "1.0.0.0")]
[DataRow("1.0.0.0-RC2", "1.0.0.0-RC1")]
public void ShouldBeGreaterThan(string x, string y)
{
// Arrange
var comparer = new VersionStringComparer();
// Act
int result = comparer.Compare(x, y);
// Assert
Assert.AreEqual(1, result);
}
[DataTestMethod]
[DataRow(null, null)]
[DataRow("", "")]
[DataRow("1", "1")]
[DataRow("1.2.3", "1.2.3")]
[DataRow("1.2.3-alpha", "1.2.3-alpha")]
public void ShouldBeEqual(string x, string y)
{
// Arrange
var comparer = new VersionStringComparer();
// Act
int result = comparer.Compare(x, y);
// Assert
Assert.AreEqual(0, result);
}
}
}