From 756a5ac8fe58c4f1ae0460e129f05b8ff5d50cda Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 1 Dec 2025 16:08:25 -0700 Subject: [PATCH 1/3] Make ShingleBased public and add unit tests, #21 --- src/F23.StringSimilarity/ShingleBased.cs | 7 ++- test/F23.StringSimilarity.Tests/CosineTest.cs | 53 ++++++++++--------- .../F23.StringSimilarity.Tests/JaccardTest.cs | 17 +++++- test/F23.StringSimilarity.Tests/QGramTest.cs | 15 ++++++ .../SorensenDiceTest.cs | 15 ++++++ 5 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/F23.StringSimilarity/ShingleBased.cs b/src/F23.StringSimilarity/ShingleBased.cs index 2b2e70f..bc354d4 100644 --- a/src/F23.StringSimilarity/ShingleBased.cs +++ b/src/F23.StringSimilarity/ShingleBased.cs @@ -24,7 +24,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Text.RegularExpressions; namespace F23.StringSimilarity @@ -43,7 +42,7 @@ public abstract class ShingleBased /// private static readonly Regex SPACE_REG = new Regex("\\s+", RegexOptions.Compiled); - /// + /// /// /// /// If k is less than or equal to 0. @@ -56,10 +55,10 @@ protected ShingleBased(int k) this.k = k; } - + protected ShingleBased() : this(DEFAULT_K) { } - protected internal Dictionary GetProfile(string s) + public Dictionary GetProfile(string s) { var shingles = new Dictionary(); diff --git a/test/F23.StringSimilarity.Tests/CosineTest.cs b/test/F23.StringSimilarity.Tests/CosineTest.cs index b209382..7d5c31a 100644 --- a/test/F23.StringSimilarity.Tests/CosineTest.cs +++ b/test/F23.StringSimilarity.Tests/CosineTest.cs @@ -22,31 +22,20 @@ * THE SOFTWARE. */ -using System; -using System.CodeDom; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.IO; using System.Reflection; using System.Threading.Tasks; using F23.StringSimilarity.Tests.TestUtil; using Xunit; -using Xunit.Abstractions; namespace F23.StringSimilarity.Tests { [SuppressMessage("ReSharper", "ArgumentsStyleLiteral")] [SuppressMessage("ReSharper", "ArgumentsStyleNamedExpression")] - public class CosineTest + public class CosineTest() { - private readonly ITestOutputHelper _testOutputHelper; - - public CosineTest(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - } - [Fact] public void TestSimilarity() { @@ -55,8 +44,8 @@ public void TestSimilarity() var result = instance.Similarity("ABC", "ABCE"); Assert.Equal( - expected: 0.71, - actual: result, + expected: 0.71, + actual: result, precision: 2 // 0.01 ); @@ -71,8 +60,8 @@ public void TestSmallString() var result = instance.Similarity("AB", "ABCE"); Assert.Equal( - expected: 0.0, - actual: result, + expected: 0.0, + actual: result, precision: 5 //0.00001 ); } @@ -89,7 +78,7 @@ public async Task TestLargeString() var result = instance.Similarity(string1, string2); Assert.Equal( - expected: 0.8115, + expected: 0.8115, actual: result, precision: 3 //0.001 ); @@ -144,19 +133,33 @@ public void DocumentationExampleTest() Assert.Equal(0.516185, cosine.Similarity(profile1, profile2), 6); } + /// + /// StringSimilarity.NET specific. Ensures that GetProfile is public. + /// + /// + /// https://github.com/feature23/StringSimilarity.NET/issues/21 + /// + [Fact] + public void GetProfile_IsPublic() + { + var cosine = new Cosine(k: 2); + var profile = cosine.GetProfile("test string"); + + Assert.NotNull(profile); + } + private static async Task ReadResourceFileAsync(string file) { var assembly = Assembly.GetExecutingAssembly(); var resourceName = $"{typeof(CosineTest).Namespace}.{file}"; - using (var stream = assembly.GetManifestResourceStream(resourceName)) - { - Debug.Assert(stream != null, "stream != null"); - using (var reader = new StreamReader(stream)) - { - return await reader.ReadToEndAsync(); - } - } + await using var stream = assembly.GetManifestResourceStream(resourceName); + + Debug.Assert(stream != null, "stream != null"); + + using var reader = new StreamReader(stream); + + return await reader.ReadToEndAsync(); } } } diff --git a/test/F23.StringSimilarity.Tests/JaccardTest.cs b/test/F23.StringSimilarity.Tests/JaccardTest.cs index 10bb8d3..33f4781 100644 --- a/test/F23.StringSimilarity.Tests/JaccardTest.cs +++ b/test/F23.StringSimilarity.Tests/JaccardTest.cs @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - + using System.Diagnostics.CodeAnalysis; using F23.StringSimilarity.Tests.TestUtil; using Xunit; @@ -59,5 +59,20 @@ public void TestDistance() NullEmptyTests.TestDistance(instance); } + + /// + /// StringSimilarity.NET specific. Ensures that GetProfile is public. + /// + /// + /// https://github.com/feature23/StringSimilarity.NET/issues/21 + /// + [Fact] + public void GetProfile_IsPublic() + { + var cosine = new Jaccard(k: 2); + var profile = cosine.GetProfile("test string"); + + Assert.NotNull(profile); + } } } diff --git a/test/F23.StringSimilarity.Tests/QGramTest.cs b/test/F23.StringSimilarity.Tests/QGramTest.cs index a2f8569..2caa241 100644 --- a/test/F23.StringSimilarity.Tests/QGramTest.cs +++ b/test/F23.StringSimilarity.Tests/QGramTest.cs @@ -63,5 +63,20 @@ public void TestDistance() NullEmptyTests.AssertArgumentNullExceptions(instance); } + + /// + /// StringSimilarity.NET specific. Ensures that GetProfile is public. + /// + /// + /// https://github.com/feature23/StringSimilarity.NET/issues/21 + /// + [Fact] + public void GetProfile_IsPublic() + { + var cosine = new QGram(k: 2); + var profile = cosine.GetProfile("test string"); + + Assert.NotNull(profile); + } } } diff --git a/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs b/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs index d190df7..0521ac3 100644 --- a/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs +++ b/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs @@ -58,5 +58,20 @@ public void TestDistance() var instance = new SorensenDice(); NullEmptyTests.TestDistance(instance); } + + /// + /// StringSimilarity.NET specific. Ensures that GetProfile is public. + /// + /// + /// https://github.com/feature23/StringSimilarity.NET/issues/21 + /// + [Fact] + public void GetProfile_IsPublic() + { + var cosine = new SorensenDice(k: 2); + var profile = cosine.GetProfile("test string"); + + Assert.NotNull(profile); + } } } From b2ffabf2c6db5607bbb17ce5579905a6088defd6 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 1 Dec 2025 16:13:19 -0700 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- test/F23.StringSimilarity.Tests/CosineTest.cs | 2 +- test/F23.StringSimilarity.Tests/JaccardTest.cs | 4 ++-- test/F23.StringSimilarity.Tests/QGramTest.cs | 4 ++-- test/F23.StringSimilarity.Tests/SorensenDiceTest.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/F23.StringSimilarity.Tests/CosineTest.cs b/test/F23.StringSimilarity.Tests/CosineTest.cs index 7d5c31a..feda7e4 100644 --- a/test/F23.StringSimilarity.Tests/CosineTest.cs +++ b/test/F23.StringSimilarity.Tests/CosineTest.cs @@ -34,7 +34,7 @@ namespace F23.StringSimilarity.Tests { [SuppressMessage("ReSharper", "ArgumentsStyleLiteral")] [SuppressMessage("ReSharper", "ArgumentsStyleNamedExpression")] - public class CosineTest() + public class CosineTest { [Fact] public void TestSimilarity() diff --git a/test/F23.StringSimilarity.Tests/JaccardTest.cs b/test/F23.StringSimilarity.Tests/JaccardTest.cs index 33f4781..83dcf05 100644 --- a/test/F23.StringSimilarity.Tests/JaccardTest.cs +++ b/test/F23.StringSimilarity.Tests/JaccardTest.cs @@ -69,8 +69,8 @@ public void TestDistance() [Fact] public void GetProfile_IsPublic() { - var cosine = new Jaccard(k: 2); - var profile = cosine.GetProfile("test string"); + var jaccard = new Jaccard(k: 2); + var profile = jaccard.GetProfile("test string"); Assert.NotNull(profile); } diff --git a/test/F23.StringSimilarity.Tests/QGramTest.cs b/test/F23.StringSimilarity.Tests/QGramTest.cs index 2caa241..de4e20f 100644 --- a/test/F23.StringSimilarity.Tests/QGramTest.cs +++ b/test/F23.StringSimilarity.Tests/QGramTest.cs @@ -73,8 +73,8 @@ public void TestDistance() [Fact] public void GetProfile_IsPublic() { - var cosine = new QGram(k: 2); - var profile = cosine.GetProfile("test string"); + var qgram = new QGram(k: 2); + var profile = qgram.GetProfile("test string"); Assert.NotNull(profile); } diff --git a/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs b/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs index 0521ac3..c174466 100644 --- a/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs +++ b/test/F23.StringSimilarity.Tests/SorensenDiceTest.cs @@ -68,8 +68,8 @@ public void TestDistance() [Fact] public void GetProfile_IsPublic() { - var cosine = new SorensenDice(k: 2); - var profile = cosine.GetProfile("test string"); + var dice = new SorensenDice(k: 2); + var profile = dice.GetProfile("test string"); Assert.NotNull(profile); } From d818d3dcebbaa1eb185e8b5aa89dd4be510c9839 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 1 Dec 2025 16:19:35 -0700 Subject: [PATCH 3/3] Fix netstandard2.0 issue with GetManifestResourceStream --- test/F23.StringSimilarity.Tests/CosineTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/F23.StringSimilarity.Tests/CosineTest.cs b/test/F23.StringSimilarity.Tests/CosineTest.cs index feda7e4..2a4fcea 100644 --- a/test/F23.StringSimilarity.Tests/CosineTest.cs +++ b/test/F23.StringSimilarity.Tests/CosineTest.cs @@ -153,7 +153,8 @@ private static async Task ReadResourceFileAsync(string file) var assembly = Assembly.GetExecutingAssembly(); var resourceName = $"{typeof(CosineTest).Namespace}.{file}"; - await using var stream = assembly.GetManifestResourceStream(resourceName); + // ReSharper disable once UseAwaitUsing - not supported on netstandard2.0 + using var stream = assembly.GetManifestResourceStream(resourceName); Debug.Assert(stream != null, "stream != null");