#include "ConversionCandidates.hpp"
#include "ConfigBasedConverter.hpp"
#include "Conversion.hpp"
#include "ConversionChain.hpp"
#include "Converter.hpp"
#include "Lexicon.hpp"
#include "MaxMatchSegmentation.hpp"
#include "PipelineConverter.hpp"
#include "SingleStageConverter.hpp"
#include "TestUtils.hpp"
#include "TestUtilsUTF8.hpp"
#include "TextDict.hpp"
namespace opencc {
class ConversionCandidatesTest : public ::testing::Test {
protected:
static DictPtr MakeDict(
const std::vector<std::pair<std::string, std::vector<std::string>>>&
entries) {
LexiconPtr lexicon(new Lexicon);
for (const auto& entry : entries) {
lexicon->Add(DictEntryFactory::New(entry.first, entry.second));
}
lexicon->Sort();
return DictPtr(new TextDict(lexicon));
}
static ConverterPtr MakeConverter(const std::list<DictPtr>& dicts) {
std::list<ConversionPtr> conversions;
for (const DictPtr& dict : dicts) {
conversions.push_back(ConversionPtr(new Conversion(dict)));
}
ConversionChainPtr chain(new ConversionChain(conversions));
SegmentationPtr segmentation(
new MaxMatchSegmentation(dicts.empty() ? MakeDict({}) : dicts.front()));
return ConverterPtr(new SingleStageConverter(segmentation, chain));
}
};
TEST_F(ConversionCandidatesTest, SingleDictMultipleValues) {
const ConverterPtr converter =
MakeConverter({MakeDict({{utf8("里"), {utf8("里"), utf8("裏")}}})});
const std::vector<std::string> candidates =
GetAllConversions(*converter, utf8("里"));
EXPECT_EQ((std::vector<std::string>{utf8("里"), utf8("裏")}), candidates);
}
TEST_F(ConversionCandidatesTest, ChainedExpansionCarriesBranches) {
const ConverterPtr converter = MakeConverter({
MakeDict({{utf8("里"), {utf8("里"), utf8("裏")}}}),
MakeDict({{utf8("裏"), {utf8("裡")}}}),
});
const std::vector<std::string> candidates =
GetAllConversions(*converter, utf8("里"));
EXPECT_EQ((std::vector<std::string>{utf8("里"), utf8("裡")}), candidates);
}
TEST_F(ConversionCandidatesTest, DuplicateCandidatesAreDeduped) {
const ConverterPtr converter = MakeConverter({
MakeDict({{utf8("面"), {utf8("麵"), utf8("面")}}}),
MakeDict({{utf8("麵"), {utf8("面")}}}),
});
const std::vector<std::string> candidates =
GetAllConversions(*converter, utf8("面"));
EXPECT_EQ((std::vector<std::string>{utf8("面")}), candidates);
}
TEST_F(ConversionCandidatesTest, WordNotInAnyDictReturnsEmpty) {
const ConverterPtr converter =
MakeConverter({MakeDict({{utf8("里"), {utf8("裏")}}})});
EXPECT_TRUE(GetAllConversions(*converter, utf8("国")).empty());
}
TEST_F(ConversionCandidatesTest, PrefixOnlyMatchReturnsEmpty) {
const ConverterPtr converter =
MakeConverter({MakeDict({{utf8("里"), {utf8("裏")}}})});
EXPECT_TRUE(GetAllConversions(*converter, utf8("里面")).empty());
}
TEST_F(ConversionCandidatesTest, PartialConversionInLaterDict) {
const ConverterPtr converter = MakeConverter({
MakeDict({{utf8("里面"), {utf8("裏面")}}}),
MakeDict({{utf8("裏"), {utf8("裡")}}}),
});
const std::vector<std::string> candidates =
GetAllConversions(*converter, utf8("里面"));
EXPECT_EQ((std::vector<std::string>{utf8("裡面")}), candidates);
}
TEST_F(ConversionCandidatesTest, PipelineConverterYieldsEmpty) {
const ConverterPtr stage =
MakeConverter({MakeDict({{utf8("里"), {utf8("裏")}}})});
ConverterPtr pipeline(new PipelineConverter({stage}));
EXPECT_EQ(nullptr, pipeline->GetConversionChain());
EXPECT_TRUE(GetAllConversions(*pipeline, utf8("里")).empty());
}
TEST_F(ConversionCandidatesTest, KeyOnlyEntryPassesWordThrough) {
const ConverterPtr converter =
MakeConverter({MakeDict({{utf8("通道"), {}}})});
const std::vector<std::string> candidates =
GetAllConversions(*converter, utf8("通道"));
EXPECT_EQ((std::vector<std::string>{utf8("通道")}), candidates);
}
TEST_F(ConversionCandidatesTest, TruncatedUtf8InputIsSafe) {
const ConverterPtr converter =
MakeConverter({MakeDict({{utf8("里"), {utf8("裏")}}})});
EXPECT_TRUE(GetAllConversions(*converter, "\xE9\x87").empty());
EXPECT_TRUE(GetAllConversions(*converter, utf8("里") + "\xE9\x87").empty());
}
TEST_F(ConversionCandidatesTest, IdsKeptAtomicInLaterDict) {
const ConverterPtr converter = MakeConverter({
MakeDict({{utf8("里字"), {utf8("⿱艹里")}}}),
MakeDict({{utf8("里"), {utf8("裏")}}}),
});
const std::vector<std::string> candidates =
GetAllConversions(*converter, utf8("里字"));
EXPECT_EQ((std::vector<std::string>{utf8("⿱艹里")}), candidates);
}
TEST_F(ConversionCandidatesTest, NormalizationPrePassApplied) {
const ConverterPtr norm =
MakeConverter({MakeDict({{"\xEF\xA7\xA9", {utf8("里")}}})});
const ConverterPtr main =
MakeConverter({MakeDict({{utf8("里"), {utf8("里"), utf8("裏")}}})});
const ConverterPtr converter(new ConfigBasedConverter(norm, main));
const std::vector<std::string> candidates =
GetAllConversions(*converter, "\xEF\xA7\xA9");
EXPECT_EQ((std::vector<std::string>{utf8("里"), utf8("裏")}), candidates);
}
}