Fixed Metadata interface and implementation, added missing unit tests.

This commit is contained in:
Alex Zolotarev 2015-11-26 23:16:26 -08:00
parent afae5a24f8
commit b4b10b3e7d
4 changed files with 73 additions and 28 deletions

View file

@ -31,97 +31,97 @@ public:
{
string const & value = ValidateAndFormat_cuisine(v);
if (!value.empty())
md.Add(Metadata::FMD_CUISINE, value);
md.Set(Metadata::FMD_CUISINE, value);
}
else if (k == "phone" || k == "contact:phone")
{
string const & value = ValidateAndFormat_phone(v);
if (!value.empty())
md.Add(Metadata::FMD_PHONE_NUMBER, value);
md.Set(Metadata::FMD_PHONE_NUMBER, value);
}
else if (k == "maxspeed")
{
string const & value = ValidateAndFormat_maxspeed(v);
if (!value.empty())
md.Add(Metadata::FMD_MAXSPEED, value);
md.Set(Metadata::FMD_MAXSPEED, value);
}
else if (k == "stars")
{
string const & value = ValidateAndFormat_stars(v);
if (!value.empty())
md.Add(Metadata::FMD_STARS, value);
md.Set(Metadata::FMD_STARS, value);
}
else if (k == "addr:postcode")
{
string const & value = ValidateAndFormat_postcode(v);
if (!value.empty())
md.Add(Metadata::FMD_POSTCODE, value);
md.Set(Metadata::FMD_POSTCODE, value);
}
else if (k == "url")
{
string const & value = ValidateAndFormat_url(v);
if (!value.empty())
md.Add(Metadata::FMD_URL, value);
md.Set(Metadata::FMD_URL, value);
}
else if (k == "website" || k == "contact:website")
{
string const & value = ValidateAndFormat_url(v);
if (!value.empty())
md.Add(Metadata::FMD_WEBSITE, value);
md.Set(Metadata::FMD_WEBSITE, value);
}
else if (k == "operator")
{
string const & value = ValidateAndFormat_operator(v);
if (!value.empty())
md.Add(Metadata::FMD_OPERATOR, value);
md.Set(Metadata::FMD_OPERATOR, value);
}
else if (k == "opening_hours")
{
string const & value = ValidateAndFormat_opening_hours(v);
if (!value.empty())
md.Add(Metadata::FMD_OPEN_HOURS, value);
md.Set(Metadata::FMD_OPEN_HOURS, value);
}
else if (k == "ele")
{
string const & value = ValidateAndFormat_ele(v);
if (!value.empty())
md.Add(Metadata::FMD_ELE, value);
md.Set(Metadata::FMD_ELE, value);
}
else if (k == "turn:lanes")
{
string const & value = ValidateAndFormat_turn_lanes(v);
if (!value.empty())
md.Add(Metadata::FMD_TURN_LANES, value);
md.Set(Metadata::FMD_TURN_LANES, value);
}
else if (k == "turn:lanes:forward")
{
string const & value = ValidateAndFormat_turn_lanes_forward(v);
if (!value.empty())
md.Add(Metadata::FMD_TURN_LANES_FORWARD, value);
md.Set(Metadata::FMD_TURN_LANES_FORWARD, value);
}
else if (k == "turn:lanes:backward")
{
string const & value = ValidateAndFormat_turn_lanes_backward(v);
if (!value.empty())
md.Add(Metadata::FMD_TURN_LANES_BACKWARD, value);
md.Set(Metadata::FMD_TURN_LANES_BACKWARD, value);
}
else if (k == "email" || k == "contact:email")
{
string const & value = ValidateAndFormat_email(v);
if (!value.empty())
md.Add(Metadata::FMD_EMAIL, value);
md.Set(Metadata::FMD_EMAIL, value);
}
else if (k == "wikipedia")
{
string const & value = ValidateAndFormat_wikipedia(v);
if (!value.empty())
md.Add(Metadata::FMD_WIKIPEDIA, value);
md.Set(Metadata::FMD_WIKIPEDIA, value);
}
else if (k == "addr:flats")
{
string const & value = ValidateAndFormat_flats(v);
if (!value.empty())
md.Add(Metadata::FMD_FLATS, value);
md.Set(Metadata::FMD_FLATS, value);
}
return false;
}

View file

@ -144,7 +144,7 @@ void FeatureType::ParseMetadata() const
m_pLoader->ParseMetadata();
if (HasInternet())
m_metadata.Add(Metadata::FMD_INTERNET, "wlan");
m_metadata.Set(Metadata::FMD_INTERNET, "wlan");
m_bMetadataParsed = true;
}

View file

@ -42,14 +42,28 @@ namespace feature
static_assert(FMD_COUNT <= 255, "Meta types count is limited to one byte.");
bool Add(EType type, string const & s)
/// Empty value drops (clears) corresponding type.
void Set(EType type, string const & value)
{
string & val = m_metadata[type];
if (val.empty())
val = s;
auto found = m_metadata.find(type);
if (found == m_metadata.end())
{
if (!value.empty())
m_metadata[type] = value;
}
else
val = val + ", " + s;
return true;
{
if (value.empty())
m_metadata.erase(found);
else
found->second = value;
}
}
/// Synonym of Set(type, "").
void Drop(EType type)
{
Set(type, "");
}
string Get(EType type) const
@ -69,11 +83,6 @@ namespace feature
return types;
}
void Drop(EType type)
{
m_metadata.erase(type);
}
inline bool Empty() const { return m_metadata.empty(); }
inline size_t Size() const { return m_metadata.size(); }

View file

@ -9,6 +9,42 @@
using feature::Metadata;
UNIT_TEST(Feature_Metadata_GetSet)
{
Metadata m;
Metadata::EType const type = Metadata::FMD_ELE;
// Absent types should return empty values.
TEST_EQUAL(m.Get(type), "", ());
m.Set(type, "12345");
TEST_EQUAL(m.Get(type), "12345", ());
TEST_EQUAL(m.Size(), 1, ());
// Same types should replace old metadata values.
m.Set(type, "5678");
TEST_EQUAL(m.Get(type), "5678", ());
// Empty values should drop fields.
m.Set(type, "");
TEST_EQUAL(m.Get(type), "", ());
TEST_EQUAL(m.Size(), 0, ());
TEST(m.Empty(), ());
}
static map<Metadata::EType, string> const kPairs = { {Metadata::FMD_ELE, "12345"},
{Metadata::FMD_CUISINE, "greek;mediterranean"},
{Metadata::FMD_EMAIL, "cool@email.at"} };
UNIT_TEST(Feature_Metadata_PresentTypes)
{
Metadata m;
for (auto const & value : kPairs)
m.Set(value.first, value.second);
TEST_EQUAL(m.Size(), kPairs.size(), ());
auto const types = m.GetPresentTypes();
TEST_EQUAL(types.size(), m.Size(), ());
for (auto const & type : types)
TEST_EQUAL(m.Get(type), kPairs.find(type)->second, ());
}
UNIT_TEST(Feature_Serialization)
{
Metadata original;