summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Albright <eric_albright@sil.org>2007-12-07 10:03:51 +0000
committerEric Albright <eric_albright@sil.org>2007-12-07 10:03:51 +0000
commit0d20be5a760553647dbd970a46307877a36055f7 (patch)
tree0f1dd396a1101e240a94e8ddf2fc21e038c15408
parentecd6723df72585fba3d269aebc2e28fd057dd74a (diff)
downloadenchant-0d20be5a760553647dbd970a46307877a36055f7.tar.gz
Fix pwl suggest. When a word is a prefix of another word and the edits the word being searched is shorter, the prefixed word was not found.
git-svn-id: svn+ssh://svn.abisource.com/svnroot/enchant/trunk@22362 bcba8976-2d24-0410-9c9c-aab3bd5fdfd6
-rw-r--r--src/pwl.c16
-rw-r--r--unittests/pwl/enchant_pwl_tests.cpp103
2 files changed, 110 insertions, 9 deletions
diff --git a/src/pwl.c b/src/pwl.c
index 6fc9f55..6580602 100644
--- a/src/pwl.c
+++ b/src/pwl.c
@@ -889,7 +889,7 @@ static void enchant_trie_find_matches(EnchantTrie* trie,EnchantTrieMatcher *matc
g_return_if_fail(matcher);
- /* Cant match in the empty trie */
+ /* Can't match in the empty trie */
if(trie == NULL) {
return;
}
@@ -960,19 +960,19 @@ static void enchant_trie_find_matches(EnchantTrie* trie,EnchantTrieMatcher *matc
g_free(nxtChS);
+ matcher->num_errors++;
if (matcher->word[matcher->word_pos] != '\0') {
- matcher->num_errors++;
/* Match on inserting word[0] */
oldPos = matcher->word_pos;
matcher->word_pos = nxtChI;
enchant_trie_find_matches(trie,matcher);
matcher->word_pos = oldPos;
- /* for each subtrie, match on delete or swap word[0] */
- g_hash_table_foreach(trie->subtries,
- enchant_trie_find_matches_cb,
- matcher);
- matcher->num_errors--;
- }
+ }
+ /* for each subtrie, match on delete or substitute word[0] */
+ g_hash_table_foreach(trie->subtries,
+ enchant_trie_find_matches_cb,
+ matcher);
+ matcher->num_errors--;
}
static void enchant_trie_find_matches_cb(void* keyV,void* subtrieV,void* matcherV)
diff --git a/unittests/pwl/enchant_pwl_tests.cpp b/unittests/pwl/enchant_pwl_tests.cpp
index 4b67b54..44a1595 100644
--- a/unittests/pwl/enchant_pwl_tests.cpp
+++ b/unittests/pwl/enchant_pwl_tests.cpp
@@ -731,7 +731,7 @@ TEST_FIXTURE(EnchantPwl_TestFixture,
AddWordToDictionary("Eric");
AddWordToDictionary("Ericson");
- std::vector<const std::string> suggestions = GetSuggestionsFromWord("eric");
+ std::vector<const std::string> suggestions = GetSuggestionsFromWord("eruc");
std::vector<const std::string> expected;
expected.push_back("Eric");
@@ -1031,3 +1031,104 @@ TEST_FIXTURE(EnchantPwl_TestFixture,
}
CHECK(!IsWordInDictionary(*removed) );
}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Pwl Edit distance bugs
+TEST_FIXTURE(EnchantPwl_TestFixture,
+ PwlSuggest_HasProperSubset_SubstituteFirstChar_Insert1)
+{
+ std::vector<const std::string> sWords;
+ sWords.push_back("cats"); //2
+
+ AddWordsToDictionary(sWords);
+
+ AddWordToDictionary("catsup"); //4
+
+ std::vector<const std::string> suggestions = GetSuggestionsFromWord("tat");
+
+ CHECK_EQUAL(sWords.size(), suggestions.size());
+
+ std::sort(sWords.begin(), sWords.end());
+ std::sort(suggestions.begin(), suggestions.end());
+
+ CHECK_ARRAY_EQUAL(sWords, suggestions, std::min(sWords.size(), suggestions.size()));
+}
+
+TEST_FIXTURE(EnchantPwl_TestFixture,
+ PwlSuggest_HasProperSubset_SubstituteFirstChar_Insert2)
+{
+ std::vector<const std::string> sWords;
+ sWords.push_back("catch"); //3
+
+ AddWordsToDictionary(sWords);
+
+ AddWordToDictionary("catchy"); //4
+
+ std::vector<const std::string> suggestions = GetSuggestionsFromWord("tat");
+
+ CHECK_EQUAL(sWords.size(), suggestions.size());
+
+ std::sort(sWords.begin(), sWords.end());
+ std::sort(suggestions.begin(), suggestions.end());
+
+ CHECK_ARRAY_EQUAL(sWords, suggestions, std::min(sWords.size(), suggestions.size()));
+}
+
+TEST_FIXTURE(EnchantPwl_TestFixture,
+ PwlSuggest_HasProperSubset_Insert1)
+{
+ std::vector<const std::string> sWords;
+ sWords.push_back("tad"); //1
+
+ AddWordsToDictionary(sWords);
+
+ AddWordToDictionary("taddle"); //4
+
+ std::vector<const std::string> suggestions = GetSuggestionsFromWord("ta");
+
+ CHECK_EQUAL(sWords.size(), suggestions.size());
+
+ std::sort(sWords.begin(), sWords.end());
+ std::sort(suggestions.begin(), suggestions.end());
+
+ CHECK_ARRAY_EQUAL(sWords, suggestions, std::min(sWords.size(), suggestions.size()));
+}
+
+TEST_FIXTURE(EnchantPwl_TestFixture,
+ PwlSuggest_HasProperSubset_Insert2)
+{
+ std::vector<const std::string> sWords;
+ sWords.push_back("tote"); //2
+
+ AddWordsToDictionary(sWords);
+
+ AddWordToDictionary("totems"); //4
+
+ std::vector<const std::string> suggestions = GetSuggestionsFromWord("to");
+
+ CHECK_EQUAL(sWords.size(), suggestions.size());
+
+ std::sort(sWords.begin(), sWords.end());
+ std::sort(suggestions.begin(), suggestions.end());
+
+ CHECK_ARRAY_EQUAL(sWords, suggestions, std::min(sWords.size(), suggestions.size()));
+}
+TEST_FIXTURE(EnchantPwl_TestFixture,
+ PwlSuggest_HasProperSubset_Insert3)
+{
+ std::vector<const std::string> sWords;
+ sWords.push_back("catch"); //3
+
+ AddWordsToDictionary(sWords);
+
+ AddWordToDictionary("catchy"); //4
+
+ std::vector<const std::string> suggestions = GetSuggestionsFromWord("ca");
+
+ CHECK_EQUAL(sWords.size(), suggestions.size());
+
+ std::sort(sWords.begin(), sWords.end());
+ std::sort(suggestions.begin(), suggestions.end());
+
+ CHECK_ARRAY_EQUAL(sWords, suggestions, std::min(sWords.size(), suggestions.size()));
+}