forked from lix-project/lix
Add some tests for the suggestions
This commit is contained in:
parent
c0792b1546
commit
2405bbbb5e
|
@ -5,15 +5,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
/**
|
int levenshteinDistance(std::string_view first, std::string_view second)
|
||||||
* Return `some(distance)` where distance is an integer representing some
|
|
||||||
* notion of distance between both arguments.
|
|
||||||
*
|
|
||||||
* If the distance is too big, return none
|
|
||||||
*/
|
|
||||||
int distanceBetween(std::string_view first, std::string_view second)
|
|
||||||
{
|
{
|
||||||
// Levenshtein distance.
|
|
||||||
// Implementation borrowed from
|
// Implementation borrowed from
|
||||||
// https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows
|
// https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows
|
||||||
|
|
||||||
|
@ -49,7 +42,7 @@ Suggestions Suggestions::bestMatches (
|
||||||
std::set<Suggestion> res;
|
std::set<Suggestion> res;
|
||||||
for (const auto & possibleMatch : allMatches) {
|
for (const auto & possibleMatch : allMatches) {
|
||||||
res.insert(Suggestion {
|
res.insert(Suggestion {
|
||||||
.distance = distanceBetween(query, possibleMatch),
|
.distance = levenshteinDistance(query, possibleMatch),
|
||||||
.suggestion = possibleMatch,
|
.suggestion = possibleMatch,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -63,7 +56,7 @@ Suggestions Suggestions::trim(int limit, int maxDistance) const
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (auto & elt : suggestions) {
|
for (auto & elt : suggestions) {
|
||||||
if (count >= limit || elt.distance >= maxDistance)
|
if (count >= limit || elt.distance > maxDistance)
|
||||||
break;
|
break;
|
||||||
count++;
|
count++;
|
||||||
res.insert(elt);
|
res.insert(elt);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
int levenshteinDistance(std::string_view first, std::string_view second);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A potential suggestion for the cli interface.
|
* A potential suggestion for the cli interface.
|
||||||
*/
|
*/
|
||||||
|
|
43
src/libutil/tests/suggestions.cc
Normal file
43
src/libutil/tests/suggestions.cc
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include "suggestions.hh"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
struct LevenshteinDistanceParam {
|
||||||
|
std::string s1, s2;
|
||||||
|
int distance;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LevenshteinDistanceTest :
|
||||||
|
public testing::TestWithParam<LevenshteinDistanceParam> {
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(LevenshteinDistanceTest, CorrectlyComputed) {
|
||||||
|
auto params = GetParam();
|
||||||
|
|
||||||
|
ASSERT_EQ(levenshteinDistance(params.s1, params.s2), params.distance);
|
||||||
|
ASSERT_EQ(levenshteinDistance(params.s2, params.s1), params.distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(LevenshteinDistance, LevenshteinDistanceTest,
|
||||||
|
testing::Values(
|
||||||
|
LevenshteinDistanceParam{"foo", "foo", 0},
|
||||||
|
LevenshteinDistanceParam{"foo", "", 3},
|
||||||
|
LevenshteinDistanceParam{"", "", 0},
|
||||||
|
LevenshteinDistanceParam{"foo", "fo", 1},
|
||||||
|
LevenshteinDistanceParam{"foo", "oo", 1},
|
||||||
|
LevenshteinDistanceParam{"foo", "fao", 1},
|
||||||
|
LevenshteinDistanceParam{"foo", "abc", 3}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
TEST(Suggestions, Trim) {
|
||||||
|
auto suggestions = Suggestions::bestMatches({"foooo", "bar", "fo", "gao"}, "foo");
|
||||||
|
auto onlyOne = suggestions.trim(1);
|
||||||
|
ASSERT_EQ(onlyOne.suggestions.size(), 1);
|
||||||
|
ASSERT_TRUE(onlyOne.suggestions.begin()->suggestion == "fo");
|
||||||
|
|
||||||
|
auto closest = suggestions.trim(999, 2);
|
||||||
|
ASSERT_EQ(closest.suggestions.size(), 3);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue