Skip to content

Commit

Permalink
Merge pull request #6 from vforteli/feature/options
Browse files Browse the repository at this point in the history
Feature/options
  • Loading branch information
vforteli authored Aug 29, 2022
2 parents 393172d + b855958 commit d62e70c
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 33 deletions.
2 changes: 1 addition & 1 deletion FuzzySearchNet.Benchmark/BenchmarkFuzzySearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ public class BenchmarkFuzzySearch
[Benchmark]
public void LevenshteinLong()
{
_ = FuzzySearch.FindLevenshtein(term2, text, 3).ToList();
_ = FuzzySearch.FindLevenshtein(term2, text, new FuzzySearchOptions(3)).ToList();
}
}
105 changes: 98 additions & 7 deletions FuzzySearchNet.Tests/Tests/FuzzySearchLevenshteinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,97 @@ public void TestMultipleMatchesConsecutive2()
}


[Test]
public void TestOptionsMaxSubstitutions()
{
var word = "pattern";
var text = "--patteron--";

var results = FuzzySearch.FindLevenshtein(word, text, new FuzzySearchOptions(1, 0, 0)).ToList();

Assert.Multiple(() =>
{
Assert.That(results.Count, Is.EqualTo(1));
TestUtils.AssertMatch(results[0], 2, "pattero", 1);
});
}

// The substitution can also be made by deleting one character and inserting one, therefore if we dont limit them, and the max distance is 2 or more, the text will still be matched
[Test]
public void TestOptionsMaxSubstitutions0()
{
var word = "patternsandpractices";
var text = "--patternsaxdpractices--";

var results = FuzzySearch.FindLevenshtein(word, text, new FuzzySearchOptions(1, maxSubstitutions: 0)).ToList();

Assert.Multiple(() =>
{
Assert.That(results.Count, Is.EqualTo(0));
});
}


[Test]
public void TestOptionsMaxInsertions()
{
var word = "pattern";
var text = "--patteron--";

var results = FuzzySearch.FindLevenshtein(word, text, new FuzzySearchOptions(0, 0, 1)).ToList();

Assert.Multiple(() =>
{
Assert.That(results.Count, Is.EqualTo(1));
TestUtils.AssertMatch(results[0], 2, "patteron", 1);
});
}

[Test]
public void TestOptionsMaxInsertions0()
{
var word = "patternsandpractices";
var text = "--patternsaxndpractices--";

var results = FuzzySearch.FindLevenshtein(word, text, new FuzzySearchOptions(3, maxInsertions: 0)).ToList();

Assert.Multiple(() =>
{
Assert.That(results.Count, Is.EqualTo(0));
});
}


[Test]
public void TestOptionsMaxDeletions()
{
var word = "pattern";
var text = "--patteron--";

var results = FuzzySearch.FindLevenshtein(word, text, new FuzzySearchOptions(0, 1, 0)).ToList();

Assert.Multiple(() =>
{
Assert.That(results.Count, Is.EqualTo(1));
TestUtils.AssertMatch(results[0], 2, "patter", 1);
});
}

[Test]
public void TestOptionsMaxDeletions0()
{
var word = "patternsandpractices";
var text = "--patternandpractices--";

var results = FuzzySearch.FindLevenshtein(word, text, new FuzzySearchOptions(3, maxDeletions: 0)).ToList();

Assert.Multiple(() =>
{
Assert.That(results.Count, Is.EqualTo(0));
});
}


[Test]
public void TestMultipleMatchesConsecutiveSubstitutions()
{
Expand Down Expand Up @@ -288,7 +379,7 @@ public void TestShorterTextNoMatch(string pattern, string text, int expectedMatc
[TestCase("pattern", "----------------------pattttern", 22, "pattttern", 2)]
public void TestLevenshteinBufferBoundary(string term, string text, int expectedStartIndex, string expectedMatch, int expectedDistance)
{
var results = FuzzySearch.FindLevenshtein(term, text, 3).ToList();
var results = FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(3)).ToList();

Assert.Multiple(() =>
{
Expand All @@ -315,7 +406,7 @@ public void TestLevenshteinBufferBoundary(string term, string text, int expected
[TestCase("ab", "axb", 0, "axb", 1)]
public void TestLevenshteinBufferBoundaryShort(string term, string text, int expectedStartIndex, string expectedMatch, int expectedDistance)
{
var results = FuzzySearch.FindLevenshtein(term, text, 1).ToList();
var results = FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(1)).ToList();

Assert.Multiple(() =>
{
Expand All @@ -330,7 +421,7 @@ public void TestLevenshteinBufferBoundaryShort(string term, string text, int exp
[TestCase("abc", "c", 0, "c", 2)]
public void TestLevenshteinBufferBoundaryShort2Distance(string term, string text, int expectedStartIndex, string expectedMatch, int expectedDistance)
{
var results = FuzzySearch.FindLevenshtein(term, text, 2).ToList();
var results = FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(2)).ToList();

Assert.Multiple(() =>
{
Expand All @@ -348,7 +439,7 @@ public void TestLevenshteinBufferBoundaryShort2Distance(string term, string text
[TestCase("abcd", "xc", 0, "xc", 3)]
public void TestLevenshteinBufferBoundaryShort3Distance(string term, string text, int expectedStartIndex, string expectedMatch, int expectedDistance)
{
var results = FuzzySearch.FindLevenshtein(term, text, 3).ToList();
var results = FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(3)).ToList();

Assert.Multiple(() =>
{
Expand All @@ -364,7 +455,7 @@ public void TestLevenshteinLinq()
var text = "---abcc----abc---axc--";
var term = "abc";

var results = FuzzySearch.FindLevenshtein(term, text, 2).ToList();
var results = FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(2)).ToList();

Assert.Multiple(() =>
{
Expand All @@ -376,8 +467,8 @@ public void TestLevenshteinLinq()

Assert.Multiple(() =>
{
Assert.That(FuzzySearch.FindLevenshtein(term, text, 3).Any());
TestUtils.AssertMatch(FuzzySearch.FindLevenshtein(term, text, 3).First(), 3, "abc", 0);
Assert.That(FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(3)).Any());
TestUtils.AssertMatch(FuzzySearch.FindLevenshtein(term, text, new FuzzySearchOptions(3)).First(), 3, "abc", 0);
});
}
}
112 changes: 112 additions & 0 deletions FuzzySearchNet.Tests/Tests/FuzzySearchOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
namespace FuzzySearchNet.Tests;

public class FuzzySearchOptionsTests
{
[Test]
public void TestCanSubstituteTotalDistance()
{
var options = new FuzzySearchOptions(3);

Assert.Multiple(() =>
{
Assert.That(options.CanSubstitute(3, 1), Is.False);
Assert.That(options.CanSubstitute(2, 1));
});
}

[Test]
public void TestCanSubstituteTotalAndMaxDistance()
{
var options = new FuzzySearchOptions(3, 1, 1, 1);

Assert.Multiple(() =>
{
Assert.That(options.CanSubstitute(2, 1), Is.False);
Assert.That(options.CanSubstitute(2, 0));
});
}

[Test]
public void TestCanSubstituteMaxSubstitutions()
{
var options = new FuzzySearchOptions(1, 1, 1);

Assert.Multiple(() =>
{
Assert.That(options.CanSubstitute(100, 1), Is.False);
Assert.That(options.CanSubstitute(0, 0));
});
}

[Test]
public void TestCanDeleteTotalDistance()
{
var options = new FuzzySearchOptions(3);

Assert.Multiple(() =>
{
Assert.That(options.CanDelete(3, 1), Is.False);
Assert.That(options.CanDelete(2, 1));
});
}

[Test]
public void TestCanDeleteTotalAndMaxDistance()
{
var options = new FuzzySearchOptions(3, 1, 1, 1);

Assert.Multiple(() =>
{
Assert.That(options.CanDelete(2, 1), Is.False);
Assert.That(options.CanDelete(2, 0));
});
}

[Test]
public void TestCanDeleteMaxSubstitutions()
{
var options = new FuzzySearchOptions(1, 1, 1);

Assert.Multiple(() =>
{
Assert.That(options.CanDelete(100, 1), Is.False);
Assert.That(options.CanDelete(0, 0));
});
}

[Test]
public void TestCanInsertTotalDistance()
{
var options = new FuzzySearchOptions(3);

Assert.Multiple(() =>
{
Assert.That(options.CanInsert(3, 1), Is.False);
Assert.That(options.CanInsert(2, 1));
});
}

[Test]
public void TestCanInsertTotalAndMaxDistance()
{
var options = new FuzzySearchOptions(3, 1, 1, 1);

Assert.Multiple(() =>
{
Assert.That(options.CanInsert(2, 1), Is.False);
Assert.That(options.CanInsert(2, 0));
});
}

[Test]
public void TestCanInsertMaxSubstitutions()
{
var options = new FuzzySearchOptions(1, 1, 1);

Assert.Multiple(() =>
{
Assert.That(options.CanInsert(100, 1), Is.False);
Assert.That(options.CanInsert(0, 0));
});
}
}
2 changes: 1 addition & 1 deletion FuzzySearchNet/FuzzySearchNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<PropertyGroup>
<PackageId>FuzzySearch.Net</PackageId>
<VersionPrefix>0.2.2</VersionPrefix>
<VersionPrefix>0.2.3</VersionPrefix>
<Title>FuzzySearch.Net</Title>
<Authors>Verner Fortelius</Authors>
<Description>Fuzzy search library for finding strings in strings. Inspired by and attempts to be somewhat compatible with fuzzysearch for python https://github.com/taleinat/fuzzysearch</Description>
Expand Down
3 changes: 1 addition & 2 deletions FuzzySearchNet/src/CandidateMatch.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace FuzzySearchNet;

public record struct CandidateMatch(int StartIndex, int TextIndex, int SubSequenceIndex = 0, int Position = 0, int Offset = 0, int Distance = 0, int Deletions = 0, int Substitutions = 0, int Insertions = 0);
public record struct CandidateMatch(int StartIndex, int TextIndex, int SubSequenceIndex = 0, int Position = 0, int Distance = 0, int Deletions = 0, int Substitutions = 0, int Insertions = 0);

// using a record struct improves performance around 30% in benchmarks
//public record CandidateMatch
Expand All @@ -9,7 +9,6 @@ public record struct CandidateMatch(int StartIndex, int TextIndex, int SubSequen
// public int TextIndex => StartIndex + Position;
// public int SubSequenceIndex => Position + Offset;
// public int Position = 0;
// public int Offset = 0;
// public int Deletions = 0;
// public int Substitutions = 0;
// public int Insertions = 0;
Expand Down
Loading

0 comments on commit d62e70c

Please sign in to comment.