Add comparison tests

This commit is contained in:
Matt Nadareski
2024-03-05 12:14:55 -05:00
parent 113e8c9151
commit 058923a39d
6 changed files with 120 additions and 39 deletions

View File

@@ -0,0 +1,38 @@
using System;
using System.Linq;
using SabreTools.Matching.Compare;
using Xunit;
namespace SabreTools.Matching.Test.Compare
{
public class NaturalComparerTests
{
[Fact]
public void NaturalComparerListSortTest()
{
// Setup arrays
string[] sortable = ["0", "100", "5", "2", "1000"];
string[] expected = ["0", "2", "5", "100", "1000"];
// Run sorting on array
Array.Sort(sortable, new NaturalComparer());
// Check the output
Assert.True(sortable.SequenceEqual(expected));
}
[Fact]
public void NaturalReversedComparerListSortTest()
{
// Setup arrays
string[] sortable = ["0", "100", "5", "2", "1000"];
string[] expected = ["1000", "100", "5", "2", "0"];
// Run sorting on array
Array.Sort(sortable, new NaturalReversedComparer());
// Check the output
Assert.True(sortable.SequenceEqual(expected));
}
}
}

View File

@@ -0,0 +1,59 @@
using SabreTools.Matching.Compare;
using Xunit;
namespace SabreTools.Matching.Test.Compare
{
public class NaturalComparerUtilTests
{
[Fact]
public void CompareNumericBothNullTest()
{
int actual = NaturalComparerUtil.CompareNumeric(null, null);
Assert.Equal(0, actual);
}
[Fact]
public void CompareNumericSingleNullTest()
{
int actual = NaturalComparerUtil.CompareNumeric(null, "notnull");
Assert.Equal(-1, actual);
actual = NaturalComparerUtil.CompareNumeric("notnull", null);
Assert.Equal(1, actual);
}
[Fact]
public void CompareNumericBothEqualTest()
{
int actual = NaturalComparerUtil.CompareNumeric("notnull", "notnull");
Assert.Equal(0, actual);
}
[Fact]
public void CompareNumericBothEqualWithPathTest()
{
int actual = NaturalComparerUtil.CompareNumeric("notnull/file.ext", "notnull/file.ext");
Assert.Equal(0, actual);
}
[Fact]
public void CompareNumericNumericNonDecimalStringTest()
{
int actual = NaturalComparerUtil.CompareNumeric("100", "10");
Assert.Equal(1, actual);
actual = NaturalComparerUtil.CompareNumeric("10", "100");
Assert.Equal(-1, actual);
}
[Fact]
public void CompareNumericNumericDecimalStringTest()
{
int actual = NaturalComparerUtil.CompareNumeric("100.100", "100.10");
Assert.Equal(1, actual);
actual = NaturalComparerUtil.CompareNumeric("100.10", "100.100");
Assert.Equal(-1, actual);
}
}
}

View File

@@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@@ -41,16 +41,17 @@ namespace SabreTools.Matching.Compare
else
return 0;
}
if (x.ToLowerInvariant() == y.ToLowerInvariant())
{
return x.CompareTo(y);
}
if (!table.TryGetValue(x, out string[]? x1))
{
//x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)");
x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrEmpty(s)).ToArray();
table.Add(x, x1);
}
if (!table.TryGetValue(y, out string[]? y1))
{
//y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)");
@@ -61,41 +62,28 @@ namespace SabreTools.Matching.Compare
for (int i = 0; i < x1.Length && i < y1.Length; i++)
{
if (x1[i] != y1[i])
{
return PartCompare(x1[i], y1[i]);
}
}
if (y1.Length > x1.Length)
{
return 1;
}
else if (x1.Length > y1.Length)
{
return -1;
}
else
{
return x.CompareTo(y);
}
}
private static int PartCompare(string left, string right)
{
if (!long.TryParse(left, out long x))
{
return NaturalComparerUtil.CompareNumeric(left, right);
}
if (!long.TryParse(right, out long y))
{
return NaturalComparerUtil.CompareNumeric(left, right);
}
// If we have an equal part, then make sure that "longer" ones are taken into account
if (x.CompareTo(y) == 0)
{
return left.Length - right.Length;
}
return x.CompareTo(y);
}

View File

@@ -4,8 +4,21 @@ namespace SabreTools.Matching.Compare
{
public static class NaturalComparerUtil
{
public static int CompareNumeric(string s1, string s2)
/// <summary>
/// Compare two strings by numeric parts
/// </summary>
public static int CompareNumeric(string? s1, string? s2)
{
// If both strings are null, return
if (s1 == null && s2 == null)
return 0;
// If one is null, then say that's less than
if (s1 == null)
return -1;
if (s2 == null)
return 1;
// Save the orginal strings, for later comparison
string s1orig = s1;
string s2orig = s2;
@@ -18,12 +31,6 @@ namespace SabreTools.Matching.Compare
if (s1 == s2)
return s1orig.CompareTo(s2orig);
// If one is null, then say that's less than
if (s1 == null)
return -1;
if (s2 == null)
return 1;
// Now split into path parts after converting AltDirSeparator to DirSeparator
s1 = s1.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
s2 = s2.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);

View File

@@ -41,16 +41,17 @@ namespace SabreTools.Matching.Compare
else
return 0;
}
if (y.ToLowerInvariant() == x.ToLowerInvariant())
{
return y.CompareTo(x);
}
if (!table.TryGetValue(x, out string[]? x1))
{
//x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)");
x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrEmpty(s)).ToArray();
table.Add(x, x1);
}
if (!table.TryGetValue(y, out string[]? y1))
{
//y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)");
@@ -61,41 +62,28 @@ namespace SabreTools.Matching.Compare
for (int i = 0; i < x1.Length && i < y1.Length; i++)
{
if (x1[i] != y1[i])
{
return PartCompare(x1[i], y1[i]);
}
}
if (y1.Length > x1.Length)
{
return 1;
}
else if (x1.Length > y1.Length)
{
return -1;
}
else
{
return y.CompareTo(x);
}
}
private static int PartCompare(string left, string right)
{
if (!long.TryParse(left, out long x))
{
return NaturalComparerUtil.CompareNumeric(right, left);
}
if (!long.TryParse(right, out long y))
{
return NaturalComparerUtil.CompareNumeric(right, left);
}
// If we have an equal part, then make sure that "longer" ones are taken into account
if (y.CompareTo(x) == 0)
{
return right.Length - left.Length;
}
return y.CompareTo(x);
}