From b4b10b3e7d2bd804ad43b63268f5df62fa413c1c Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Thu, 26 Nov 2015 23:16:26 -0800 Subject: [PATCH] Fixed Metadata interface and implementation, added missing unit tests. --- generator/osm2meta.hpp | 32 ++++++++--------- indexer/feature.cpp | 2 +- indexer/feature_meta.hpp | 31 ++++++++++------ .../indexer_tests/feature_metadata_test.cpp | 36 +++++++++++++++++++ 4 files changed, 73 insertions(+), 28 deletions(-) diff --git a/generator/osm2meta.hpp b/generator/osm2meta.hpp index 79efd40fb9..8874dfb7a7 100644 --- a/generator/osm2meta.hpp +++ b/generator/osm2meta.hpp @@ -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; } diff --git a/indexer/feature.cpp b/indexer/feature.cpp index d46961bdf0..434d6e0611 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -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; } diff --git a/indexer/feature_meta.hpp b/indexer/feature_meta.hpp index 363f899ded..3a082f32eb 100644 --- a/indexer/feature_meta.hpp +++ b/indexer/feature_meta.hpp @@ -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(); } diff --git a/indexer/indexer_tests/feature_metadata_test.cpp b/indexer/indexer_tests/feature_metadata_test.cpp index b61a17df5c..38647b56ce 100644 --- a/indexer/indexer_tests/feature_metadata_test.cpp +++ b/indexer/indexer_tests/feature_metadata_test.cpp @@ -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 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;