From 336e4f994d1823ba48ad85c4c9faa059d08fea6b Mon Sep 17 00:00:00 2001 From: Yuri Gorshenin Date: Tue, 7 Nov 2017 16:57:46 +0300 Subject: [PATCH] [search] SearchAPI tests. --- map/map_tests/CMakeLists.txt | 6 + map/map_tests/map_tests.pro | 6 +- map/map_tests/search_api_tests.cpp | 133 ++++++++++++++++++ search/engine.cpp | 2 + search/pysearch/bindings.cpp | 35 +++-- .../downloader_search_test.cpp | 17 +-- .../generate_tests.cpp | 11 +- search/search_integration_tests/helpers.cpp | 56 +++----- search/search_integration_tests/helpers.hpp | 113 +++------------ .../interactive_search_test.cpp | 13 +- .../pre_ranker_test.cpp | 25 ++-- .../processor_test.cpp | 8 +- .../features_collector_tool.cpp | 9 +- .../search_quality_tool.cpp | 20 +-- search/search_tests/CMakeLists.txt | 1 + search/search_tests/locality_finder_test.cpp | 9 +- search/search_tests/search_tests.pro | 2 +- search/search_tests_support/CMakeLists.txt | 4 + .../search_tests_support.pro | 4 + .../test_results_matching.cpp | 7 + .../test_results_matching.hpp | 2 + .../test_search_engine.cpp | 21 ++- .../test_search_engine.hpp | 28 ++-- .../test_with_classificator.cpp | 17 +++ .../test_with_classificator.hpp | 14 ++ .../test_with_custom_mwms.cpp | 31 ++++ .../test_with_custom_mwms.hpp | 93 ++++++++++++ 27 files changed, 464 insertions(+), 223 deletions(-) create mode 100644 map/map_tests/search_api_tests.cpp create mode 100644 search/search_tests_support/test_with_classificator.cpp create mode 100644 search/search_tests_support/test_with_classificator.hpp create mode 100644 search/search_tests_support/test_with_custom_mwms.cpp create mode 100644 search/search_tests_support/test_with_custom_mwms.hpp diff --git a/map/map_tests/CMakeLists.txt b/map/map_tests/CMakeLists.txt index 1c77f52720..8cbc14b9cd 100644 --- a/map/map_tests/CMakeLists.txt +++ b/map/map_tests/CMakeLists.txt @@ -15,6 +15,7 @@ set( gps_track_test.cpp kmz_unarchive_test.cpp mwm_url_tests.cpp + search_api_tests.cpp transliteration_test.cpp working_time_tests.cpp ) @@ -23,6 +24,10 @@ omim_add_test(${PROJECT_NAME} ${SRC}) omim_link_libraries( ${PROJECT_NAME} + search_tests_support + generator_tests_support + indexer_tests_support + generator map drape_frontend routing @@ -59,6 +64,7 @@ omim_link_libraries( oauthcpp drape_frontend drape + tess2 stb_image sdf_image ${Qt5Widgets_LIBRARIES} diff --git a/map/map_tests/map_tests.pro b/map/map_tests/map_tests.pro index fa8c562e1f..abbfba28c4 100644 --- a/map/map_tests/map_tests.pro +++ b/map/map_tests/map_tests.pro @@ -6,10 +6,11 @@ CONFIG -= app_bundle TEMPLATE = app ROOT_DIR = ../.. -DEPENDENCIES = map drape_frontend routing traffic routing_common search storage tracking drape \ +DEPENDENCIES = search_tests_support generator_tests_support indexer_tests_support generator \ + map drape_frontend routing traffic routing_common search storage tracking drape \ ugc indexer partners_api local_ads platform editor mwm_diff bsdiff geometry coding base \ freetype expat protobuf jansson osrm stats_client minizip succinct pugixml \ - stats_client stb_image sdf_image icu agg + stats_client tess2 stb_image sdf_image icu agg DEPENDENCIES *= opening_hours @@ -44,6 +45,7 @@ SOURCES += \ gps_track_test.cpp \ kmz_unarchive_test.cpp \ mwm_url_tests.cpp \ + search_api_tests.cpp \ transliteration_test.cpp \ !linux* { diff --git a/map/map_tests/search_api_tests.cpp b/map/map_tests/search_api_tests.cpp new file mode 100644 index 0000000000..20b03d2484 --- /dev/null +++ b/map/map_tests/search_api_tests.cpp @@ -0,0 +1,133 @@ +// NOTE: the purpose of this test is to test interaction between +// SearchAPI and search engine. If you would like to test search +// engine behaviour, please, consider to implement one more search +// integration test. + +#include "testing/testing.hpp" + +#include "generator/generator_tests_support/test_feature.hpp" + +#include "search/search_tests_support/test_results_matching.hpp" +#include "search/search_tests_support/test_with_custom_mwms.hpp" + +#include "map/search_api.hpp" + +#include "search/viewport_search_params.hpp" + +#include "storage/country_info_getter.hpp" +#include "storage/storage.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/index.hpp" + +#include +#include +#include +#include +#include + +using namespace search::tests_support; +using namespace generator::tests_support; +using namespace search; +using namespace std; +using namespace storage; + +namespace +{ +using Rules = vector>; + +struct TestCafe : public TestPOI +{ +public: + TestCafe(m2::PointD const & center, string const & name, string const & lang) + : TestPOI(center, name, lang) + { + SetTypes({{"amenity", "cafe"}}); + } + + ~TestCafe() override = default; +}; + +class Delegate : public SearchAPI::Delegate +{ +public: + ~Delegate() override = default; + + // SearchAPI::Delegate overrides: + void RunUITask(function fn) override { fn(); } +}; + +class SearchAPITest : public TestWithCustomMwms +{ +public: + SearchAPITest() + : m_infoGetter(CountryInfoReader::CreateCountryInfoReader(GetPlatform())) + , m_api(m_index, m_storage, *m_infoGetter, m_delegate) + { + } + +protected: + Storage m_storage; + unique_ptr m_infoGetter; + Delegate m_delegate; + SearchAPI m_api; +}; + +UNIT_CLASS_TEST(SearchAPITest, MultipleViewportRequests) +{ + TestCafe cafe1(m2::PointD(0, 0), "cafe 1", "en"); + TestCafe cafe2(m2::PointD(0, 0), "cafe 2", "en"); + TestCafe cafe3(m2::PointD(10, 10), "cafe 3", "en"); + TestCafe cafe4(m2::PointD(10, 10), "cafe 4", "en"); + + auto const id = BuildCountry("Wonderland", [&](TestMwmBuilder & builder) { + builder.Add(cafe1); + builder.Add(cafe2); + builder.Add(cafe3); + builder.Add(cafe4); + }); + + atomic stage{0}; + + promise promise0; + auto future0 = promise0.get_future(); + + promise promise1; + auto future1 = promise1.get_future(); + + ViewportSearchParams params; + params.m_query = "cafe "; + params.m_inputLocale = "en"; + + params.m_onCompleted = [&](Results const & results) { + TEST(!results.IsEndedCancelled(), ()); + + if (!results.IsEndMarker()) + return; + + if (stage == 0) + { + Rules const rules = {ExactMatch(id, cafe1), ExactMatch(id, cafe2)}; + TEST(MatchResults(m_index, rules, results), ()); + + promise0.set_value(); + } + else + { + TEST_EQUAL(stage, 1, ()); + Rules const rules = {ExactMatch(id, cafe3), ExactMatch(id, cafe4)}; + TEST(MatchResults(m_index, rules, results), ()); + + promise1.set_value(); + } + }; + + m_api.OnViewportChanged(m2::RectD(-1, -1, 1, 1)); + m_api.SearchInViewport(params); + future0.wait(); + + ++stage; + m_api.OnViewportChanged(m2::RectD(9, 9, 11, 11)); + future1.wait(); +} +} // namespace diff --git a/search/engine.cpp b/search/engine.cpp index 2426492bb1..0c360a264c 100644 --- a/search/engine.cpp +++ b/search/engine.cpp @@ -109,6 +109,8 @@ Engine::Engine(Index & index, CategoriesHolder const & categories, m_threads.reserve(params.m_numThreads); for (size_t i = 0; i < params.m_numThreads; ++i) m_threads.emplace_back(&Engine::MainLoop, this, ref(m_contexts[i])); + + LoadCitiesBoundaries(); } Engine::~Engine() diff --git a/search/pysearch/bindings.cpp b/search/pysearch/bindings.cpp index fd081f48ee..19067c2b31 100644 --- a/search/pysearch/bindings.cpp +++ b/search/pysearch/bindings.cpp @@ -137,31 +137,40 @@ struct Result Mercator m_center; }; +unique_ptr CreateCountryInfoGetter() +{ + CHECK(g_affiliations.get(), ("init() was not called.")); + auto & platform = GetPlatform(); + auto infoGetter = storage::CountryInfoReader::CreateCountryInfoReader(platform); + infoGetter->InitAffiliationsInfo(&*g_affiliations); + return infoGetter; +} + +struct Context +{ + Context() : m_engine(m_index, CreateCountryInfoGetter(), search::Engine::Params{}) {} + + Index m_index; + search::tests_support::TestSearchEngine m_engine; +}; + struct SearchEngineProxy { - SearchEngineProxy() + SearchEngineProxy() : m_context(make_shared()) { - CHECK(g_affiliations.get(), ("init() was not called.")); - auto & platform = GetPlatform(); - auto infoGetter = storage::CountryInfoReader::CreateCountryInfoReader(platform); - infoGetter->InitAffiliationsInfo(&*g_affiliations); - - m_engine = make_shared(move(infoGetter), - search::Engine::Params{}); - vector mwms; platform::FindAllLocalMapsAndCleanup(numeric_limits::max() /* the latest version */, mwms); for (auto & mwm : mwms) { mwm.SyncWithDisk(); - m_engine->RegisterMap(mwm); + m_context->m_index.RegisterMap(mwm); } } boost::python::list Query(Params const & params) const { - m_engine->SetLocale(params.m_locale); + m_context->m_engine.SetLocale(params.m_locale); search::SearchParams sp; sp.m_query = params.m_query; @@ -174,7 +183,7 @@ struct SearchEngineProxy auto const & topRight = params.m_viewport.m_max; sp.m_viewport = m2::RectD(bottomLeft.m_x, bottomLeft.m_y, topRight.m_x, topRight.m_y); - search::tests_support::TestSearchRequest request(*m_engine, sp); + search::tests_support::TestSearchRequest request(m_context->m_engine, sp); request.Run(); boost::python::list results; @@ -183,7 +192,7 @@ struct SearchEngineProxy return results; } - shared_ptr m_engine; + shared_ptr m_context; }; } // namespace diff --git a/search/search_integration_tests/downloader_search_test.cpp b/search/search_integration_tests/downloader_search_test.cpp index 9d3023c90f..35e98834f1 100644 --- a/search/search_integration_tests/downloader_search_test.cpp +++ b/search/search_integration_tests/downloader_search_test.cpp @@ -24,6 +24,8 @@ using namespace generator::tests_support; using namespace search::tests_support; +class Index; + namespace search { namespace @@ -105,12 +107,11 @@ public: class DownloaderSearchRequest : public TestSearchRequest, public TestDelegate { public: - DownloaderSearchRequest(TestSearchEngine & engine, string const & query) + DownloaderSearchRequest(Index & index, TestSearchEngine & engine, string const & query) : TestSearchRequest(engine, MakeSearchParams(query)) , m_storage(kCountriesTxt, make_unique()) - , m_downloaderCallback(static_cast(*this), - m_engine /* index */, m_engine.GetCountryInfoGetter(), m_storage, - MakeDownloaderParams(query)) + , m_downloaderCallback(static_cast(*this), index, + m_engine.GetCountryInfoGetter(), m_storage, MakeDownloaderParams(query)) { SetCustomOnResults(bind(&DownloaderSearchRequest::OnResultsDownloader, this, _1)); } @@ -221,7 +222,7 @@ UNIT_CLASS_TEST(DownloaderSearchTest, Smoke) BuildWorld(); { - DownloaderSearchRequest request(m_engine, "square one"); + DownloaderSearchRequest request(m_index, m_engine, "square one"); request.Run(); TestResults(request.GetResults(), @@ -229,7 +230,7 @@ UNIT_CLASS_TEST(DownloaderSearchTest, Smoke) } { - DownloaderSearchRequest request(m_engine, "shortpondland"); + DownloaderSearchRequest request(m_index, m_engine, "shortpondland"); request.Run(); TestResults(request.GetResults(), @@ -237,14 +238,14 @@ UNIT_CLASS_TEST(DownloaderSearchTest, Smoke) } { - DownloaderSearchRequest request(m_engine, "flatland"); + DownloaderSearchRequest request(m_index, m_engine, "flatland"); request.Run(); TestResults(request.GetResults(), {storage::DownloaderSearchResult("Flatland", "Flatland")}); } { - DownloaderSearchRequest request(m_engine, "square"); + DownloaderSearchRequest request(m_index, m_engine, "square"); request.Run(); TestResults(request.GetResults(), diff --git a/search/search_integration_tests/generate_tests.cpp b/search/search_integration_tests/generate_tests.cpp index b489897a6a..f73906b024 100644 --- a/search/search_integration_tests/generate_tests.cpp +++ b/search/search_integration_tests/generate_tests.cpp @@ -1,6 +1,6 @@ #include "testing/testing.hpp" -#include "search/search_integration_tests/helpers.hpp" +#include "search/search_tests_support/test_with_classificator.hpp" #include "generator/generator_tests_support/test_mwm_builder.hpp" @@ -15,8 +15,15 @@ #include "platform/local_country_file.hpp" -using namespace search; +#include +#include +#include +#include + using namespace generator::tests_support; +using namespace search::tests_support; +using namespace search; +using namespace std; namespace { diff --git a/search/search_integration_tests/helpers.cpp b/search/search_integration_tests/helpers.cpp index 46112a9187..2234345340 100644 --- a/search/search_integration_tests/helpers.cpp +++ b/search/search_integration_tests/helpers.cpp @@ -1,44 +1,22 @@ #include "search/search_integration_tests/helpers.hpp" -#include "search/editor_delegate.hpp" -#include "search/search_tests_support/test_search_request.hpp" +#include "storage/country_info_getter.hpp" -#include "indexer/classificator_loader.hpp" -#include "indexer/indexer_tests_support/helpers.hpp" -#include "indexer/map_style.hpp" -#include "indexer/map_style_reader.hpp" #include "indexer/scales.hpp" -#include "platform/platform.hpp" - #include "geometry/mercator.hpp" #include "geometry/rect2d.hpp" +using namespace std; + namespace search { -// TestWithClassificator --------------------------------------------------------------------------- -TestWithClassificator::TestWithClassificator() -{ - GetStyleReader().SetCurrentStyle(MapStyleMerged); - classificator::Load(); -} - -// SearchTest -------------------------------------------------------------------------------------- SearchTest::SearchTest() - : m_platform(GetPlatform()) - , m_scopedLog(LDEBUG) - , m_engine(make_unique(), Engine::Params{}) + : m_scopedLog(LDEBUG) + , m_engine(m_index, make_unique(), Engine::Params{}) { - indexer::tests_support::SetUpEditorForTesting(make_unique(m_engine)); - - SetViewport(m2::RectD(MercatorBounds::minX, MercatorBounds::minY, - MercatorBounds::maxX, MercatorBounds::maxY)); -} - -SearchTest::~SearchTest() -{ - for (auto const & file : m_files) - Cleanup(file); + SetViewport(m2::RectD(MercatorBounds::minX, MercatorBounds::minY, MercatorBounds::maxX, + MercatorBounds::maxY)); } void SearchTest::RegisterCountry(string const & name, m2::RectD const & rect) @@ -60,7 +38,7 @@ bool SearchTest::ResultsMatch(string const & query, { tests_support::TestSearchRequest request(m_engine, query, locale, Mode::Everywhere, m_viewport); request.Run(); - return MatchResults(m_engine, rules, request.Results()); + return MatchResults(m_index, rules, request.Results()); } bool SearchTest::ResultsMatch(string const & query, Mode mode, @@ -68,12 +46,12 @@ bool SearchTest::ResultsMatch(string const & query, Mode mode, { tests_support::TestSearchRequest request(m_engine, query, "en", mode, m_viewport); request.Run(); - return MatchResults(m_engine, rules, request.Results()); + return MatchResults(m_index, rules, request.Results()); } bool SearchTest::ResultsMatch(vector const & results, TRules const & rules) { - return MatchResults(m_engine, rules, results); + return MatchResults(m_index, rules, results); } bool SearchTest::ResultsMatch(SearchParams const & params, TRules const & rules) @@ -85,7 +63,7 @@ bool SearchTest::ResultsMatch(SearchParams const & params, TRules const & rules) bool SearchTest::ResultMatches(search::Result const & result, TRule const & rule) { - return tests_support::ResultMatches(m_engine, rule, result); + return tests_support::ResultMatches(m_index, rule, result); } unique_ptr SearchTest::MakeRequest( @@ -108,14 +86,18 @@ size_t SearchTest::CountFeatures(m2::RectD const & rect) { size_t count = 0; auto counter = [&count](const FeatureType & /* ft */) { ++count; }; - m_engine.ForEachInRect(counter, rect, scales::GetUpperScale()); + m_index.ForEachInRect(counter, rect, scales::GetUpperScale()); return count; } // static -void SearchTest::Cleanup(platform::LocalCountryFile const & map) +void SearchTest::OnMwmBuilded(MwmInfo const & info) { - platform::CountryIndexes::DeleteFromDisk(map); - map.DeleteFromDisk(MapOptions::Map); + switch (info.GetType()) + { + case MwmInfo::COUNTRY: RegisterCountry(info.GetCountryName(), info.m_limitRect); break; + case MwmInfo::WORLD: m_engine.LoadCitiesBoundaries(); break; + case MwmInfo::COASTS: break; + } } } // namespace search diff --git a/search/search_integration_tests/helpers.hpp b/search/search_integration_tests/helpers.hpp index a6074a6a3d..169060716a 100644 --- a/search/search_integration_tests/helpers.hpp +++ b/search/search_integration_tests/helpers.hpp @@ -3,133 +3,58 @@ #include "search/search_tests_support/test_results_matching.hpp" #include "search/search_tests_support/test_search_engine.hpp" #include "search/search_tests_support/test_search_request.hpp" +#include "search/search_tests_support/test_with_custom_mwms.hpp" -#include "generator/generator_tests_support/test_mwm_builder.hpp" - -#include "storage/country_decl.hpp" -#include "storage/country_info_getter.hpp" - -#include "indexer/feature.hpp" -#include "indexer/feature_decl.hpp" -#include "indexer/index.hpp" #include "indexer/indexer_tests_support/helpers.hpp" -#include "indexer/mwm_set.hpp" #include "geometry/rect2d.hpp" -#include "platform/country_file.hpp" -#include "platform/local_country_file.hpp" -#include "platform/local_country_file_utils.hpp" - -#include "base/assert.hpp" - -#include "std/unique_ptr.hpp" -#include "std/vector.hpp" - -class Platform; +#include +#include +#include +#include namespace search { -class TestWithClassificator +class SearchTest : public tests_support::TestWithCustomMwms { public: - TestWithClassificator(); -}; - -class SearchTest : public TestWithClassificator -{ -public: - using TRule = shared_ptr; - using TRules = vector; + using TRule = std::shared_ptr; + using TRules = std::vector; SearchTest(); - - ~SearchTest(); + ~SearchTest() override = default; // Registers country in internal records. Note that physical country // file may be absent. - void RegisterCountry(string const & name, m2::RectD const & rect); - - // Creates a physical country file on a disk, which will be removed - // at the end of the test. |fn| is a delegate that accepts a single - // argument - TestMwmBuilder and adds all necessary features to the - // country file. - // - // *NOTE* when |type| is feature::DataHeader::country, the country - // with |name| will be automatically registered. - template - MwmSet::MwmId BuildMwm(string const & name, feature::DataHeader::MapType type, TBuildFn && fn) - { - m_files.emplace_back(m_platform.WritableDir(), platform::CountryFile(name), 0 /* version */); - auto & file = m_files.back(); - Cleanup(file); - - { - generator::tests_support::TestMwmBuilder builder(file, type); - fn(builder); - } - - auto result = m_engine.RegisterMap(file); - CHECK_EQUAL(result.second, MwmSet::RegResult::Success, ()); - - auto const & id = result.first; - if (type == feature::DataHeader::country) - { - if (auto const & info = id.GetInfo()) - RegisterCountry(name, info->m_limitRect); - } - return id; - } - - template - MwmSet::MwmId BuildWorld(TBuildFn && fn) - { - auto const id = BuildMwm("testWorld", feature::DataHeader::world, forward(fn)); - m_engine.LoadCitiesBoundaries(); - return id; - } - - template - MwmSet::MwmId BuildCountry(string const & name, TBuildFn && fn) - { - return BuildMwm(name, feature::DataHeader::country, forward(fn)); - } - - template - void EditFeature(FeatureID const & id, TEditorFn && fn) - { - Index::FeaturesLoaderGuard loader(m_engine, id.m_mwmId); - FeatureType ft; - CHECK(loader.GetFeatureByIndex(id.m_index, ft), ()); - indexer::tests_support::EditFeature(ft, forward(fn)); - } + void RegisterCountry(std::string const & name, m2::RectD const & rect); inline void SetViewport(m2::RectD const & viewport) { m_viewport = viewport; } - bool ResultsMatch(string const & query, TRules const & rules); + bool ResultsMatch(std::string const & query, TRules const & rules); - bool ResultsMatch(string const & query, string const & locale, TRules const & rules); + bool ResultsMatch(std::string const & query, string const & locale, TRules const & rules); - bool ResultsMatch(string const & query, Mode mode, TRules const & rules); + bool ResultsMatch(std::string const & query, Mode mode, TRules const & rules); - bool ResultsMatch(vector const & results, TRules const & rules); + bool ResultsMatch(std::vector const & results, TRules const & rules); bool ResultsMatch(SearchParams const & params, TRules const & rules); bool ResultMatches(search::Result const & result, TRule const & rule); - unique_ptr MakeRequest(string const & query, - string const & locale = "en"); + std::unique_ptr MakeRequest(std::string const & query, + std::string const & locale = "en"); size_t CountFeatures(m2::RectD const & rect); protected: - static void Cleanup(platform::LocalCountryFile const & map); + void OnMwmBuilded(MwmInfo const & /* info */) override; - Platform & m_platform; my::ScopedLogLevelChanger m_scopedLog; - vector m_files; + tests_support::TestSearchEngine m_engine; + m2::RectD m_viewport; }; } // namespace search diff --git a/search/search_integration_tests/interactive_search_test.cpp b/search/search_integration_tests/interactive_search_test.cpp index 1ffc39a2b1..8324ac5cf7 100644 --- a/search/search_integration_tests/interactive_search_test.cpp +++ b/search/search_integration_tests/interactive_search_test.cpp @@ -104,7 +104,7 @@ UNIT_CLASS_TEST(InteractiveSearchTest, Smoke) ExactMatch(id, cafes[2]), ExactMatch(id, cafes[3])}; TEST(!mode, ()); - TEST(MatchResults(m_engine, rules, request.Results()), ()); + TEST(MatchResults(m_index, rules, request.Results()), ()); } { @@ -117,7 +117,7 @@ UNIT_CLASS_TEST(InteractiveSearchTest, Smoke) ExactMatch(id, hotels[2]), ExactMatch(id, hotels[3])}; TEST(mode, ()); - TEST(MatchResults(m_engine, rules, request.Results()), ()); + TEST(MatchResults(m_index, rules, request.Results()), ()); } } @@ -148,8 +148,8 @@ UNIT_CLASS_TEST(InteractiveSearchTest, NearbyFeaturesInViewport) TestSearchRequest request(m_engine, params); request.Run(); - TEST(MatchResults(m_engine, TRules{ExactMatch(id, cafe1), ExactMatch(id, cafe2), - ExactMatch(id, cafe3), ExactMatch(id, cafe4)}, + TEST(MatchResults(m_index, TRules{ExactMatch(id, cafe1), ExactMatch(id, cafe2), + ExactMatch(id, cafe3), ExactMatch(id, cafe4)}, request.Results()), ()); } @@ -162,8 +162,9 @@ UNIT_CLASS_TEST(InteractiveSearchTest, NearbyFeaturesInViewport) auto const & results = request.Results(); - TEST(MatchResults(m_engine, TRules{ExactMatch(id, cafe1), ExactMatch(id, cafe3)}, results) || - MatchResults(m_engine, TRules{ExactMatch(id, cafe2), ExactMatch(id, cafe4)}, results), ()); + TEST(MatchResults(m_index, TRules{ExactMatch(id, cafe1), ExactMatch(id, cafe3)}, results) || + MatchResults(m_index, TRules{ExactMatch(id, cafe2), ExactMatch(id, cafe4)}, results), + ()); } } } // namespace diff --git a/search/search_integration_tests/pre_ranker_test.cpp b/search/search_integration_tests/pre_ranker_test.cpp index c3903aac8b..9c7387a77e 100644 --- a/search/search_integration_tests/pre_ranker_test.cpp +++ b/search/search_integration_tests/pre_ranker_test.cpp @@ -38,6 +38,13 @@ using namespace generator::tests_support; using namespace search::tests_support; +class Index; + +namespace storage +{ +class CountryInfoGetter; +} + namespace search { namespace @@ -45,12 +52,12 @@ namespace class TestRanker : public Ranker { public: - TestRanker(TestSearchEngine & engine, CitiesBoundariesTable const & boundariesTable, - KeywordLangMatcher & keywordsScorer, Emitter & emitter, - vector const & suggests, VillagesCache & villagesCache, + TestRanker(Index & index, storage::CountryInfoGetter & infoGetter, + CitiesBoundariesTable const & boundariesTable, KeywordLangMatcher & keywordsScorer, + Emitter & emitter, vector const & suggests, VillagesCache & villagesCache, my::Cancellable const & cancellable, vector & results) - : Ranker(static_cast(engine), boundariesTable, engine.GetCountryInfoGetter(), - keywordsScorer, emitter, GetDefaultCategories(), suggests, villagesCache, cancellable) + : Ranker(index, boundariesTable, infoGetter, keywordsScorer, emitter, + GetDefaultCategories(), suggests, villagesCache, cancellable) , m_results(results) { } @@ -115,13 +122,13 @@ UNIT_CLASS_TEST(PreRankerTest, Smoke) vector results; Emitter emitter; - CitiesBoundariesTable boundariesTable(m_engine); + CitiesBoundariesTable boundariesTable(m_index); VillagesCache villagesCache(m_cancellable); KeywordLangMatcher keywordsScorer(0 /* maxLanguageTiers */); - TestRanker ranker(m_engine, boundariesTable, keywordsScorer, emitter, m_suggests, villagesCache, - m_cancellable, results); + TestRanker ranker(m_index, m_engine.GetCountryInfoGetter(), boundariesTable, keywordsScorer, + emitter, m_suggests, villagesCache, m_cancellable, results); - PreRanker preRanker(m_engine, ranker); + PreRanker preRanker(m_index, ranker); PreRanker::Params params; params.m_viewport = kViewport; params.m_accuratePivotCenter = kPivot; diff --git a/search/search_integration_tests/processor_test.cpp b/search/search_integration_tests/processor_test.cpp index 552efe5f84..4f4ce3ce73 100644 --- a/search/search_integration_tests/processor_test.cpp +++ b/search/search_integration_tests/processor_test.cpp @@ -555,7 +555,7 @@ UNIT_CLASS_TEST(ProcessorTest, TestPostcodes) // Tests that postcode is added to the search index. { - MwmContext context(m_engine.GetMwmHandleById(countryId)); + MwmContext context(m_index.GetMwmHandleById(countryId)); my::Cancellable cancellable; QueryParams params; @@ -573,7 +573,7 @@ UNIT_CLASS_TEST(ProcessorTest, TestPostcodes) while (!features->GetBit(index)) ++index; - Index::FeaturesLoaderGuard loader(m_engine, countryId); + Index::FeaturesLoaderGuard loader(m_index, countryId); FeatureType ft; TEST(loader.GetFeatureByIndex(base::checked_cast(index), ft), ()); @@ -670,7 +670,7 @@ UNIT_CLASS_TEST(ProcessorTest, TestCategories) TEST(ResultsMatch(request->Results(), rules), ()); for (auto const & result : request->Results()) { - Index::FeaturesLoaderGuard loader(m_engine, wonderlandId); + Index::FeaturesLoaderGuard loader(m_index, wonderlandId); FeatureType ft; TEST(loader.GetFeatureByIndex(result.GetFeatureID().m_index, ft), ()); @@ -1112,7 +1112,7 @@ UNIT_CLASS_TEST(ProcessorTest, CityBoundaryLoad) TEST(ResultsMatch("moscow", "en", rules), ()); } - CitiesBoundariesTable table(m_engine); + CitiesBoundariesTable table(m_index); TEST(table.Load(), ()); TEST(table.Has(0 /* fid */), ()); TEST(!table.Has(10 /* fid */), ()); diff --git a/search/search_quality/features_collector_tool/features_collector_tool.cpp b/search/search_quality/features_collector_tool/features_collector_tool.cpp index 5c7a82072d..36cfdea799 100644 --- a/search/search_quality/features_collector_tool/features_collector_tool.cpp +++ b/search/search_quality/features_collector_tool/features_collector_tool.cpp @@ -8,6 +8,7 @@ #include "search/search_tests_support/test_search_request.hpp" #include "indexer/classificator_loader.hpp" +#include "indexer/index.hpp" #include "storage/country_info_getter.hpp" #include "storage/index.hpp" @@ -151,7 +152,7 @@ int main(int argc, char * argv[]) } classificator::Load(); - TestSearchEngine engine(move(infoGetter), Engine::Params{}); + Index index; vector mwms; platform::FindAllLocalMapsAndCleanup(numeric_limits::max() /* the latest version */, @@ -159,11 +160,13 @@ int main(int argc, char * argv[]) for (auto & mwm : mwms) { mwm.SyncWithDisk(); - engine.RegisterMap(mwm); + index.RegisterMap(mwm); } + TestSearchEngine engine(index, move(infoGetter), Engine::Params{}); + vector stats(samples.size()); - FeatureLoader loader(engine); + FeatureLoader loader(index); Matcher matcher(loader); cout << "SampleId,"; diff --git a/search/search_quality/search_quality_tool/search_quality_tool.cpp b/search/search_quality/search_quality_tool/search_quality_tool.cpp index 8d4dd71faa..b670b08488 100644 --- a/search/search_quality/search_quality_tool/search_quality_tool.cpp +++ b/search/search_quality/search_quality_tool/search_quality_tool.cpp @@ -197,11 +197,11 @@ void Split(string const & s, char delim, vector & parts) // Returns the position of the result that is expected to be found by geocoder completeness // tests in the |result| vector or -1 if it does not occur there. -int FindResult(TestSearchEngine & engine, string const & mwmName, uint32_t const featureId, - double const lat, double const lon, vector const & results) +int FindResult(Index & index, string const & mwmName, uint32_t const featureId, double const lat, + double const lon, vector const & results) { CHECK_LESS_OR_EQUAL(results.size(), numeric_limits::max(), ()); - auto const mwmId = engine.GetMwmIdByCountryFile(platform::CountryFile(mwmName)); + auto const mwmId = index.GetMwmIdByCountryFile(platform::CountryFile(mwmName)); FeatureID const expectedFeatureId(mwmId, featureId); for (size_t i = 0; i < results.size(); ++i) { @@ -279,7 +279,8 @@ void ParseCompletenessQuery(string & s, CompletenessQuery & q) // from |path|, executes them against the |engine| with viewport set to |viewport| // and reports the number of queries whose expected result is among the returned results. // Exact feature id is expected, but a close enough (lat, lon) is good too. -void CheckCompleteness(string const & path, m2::RectD const & viewport, TestSearchEngine & engine) +void CheckCompleteness(string const & path, m2::RectD const & viewport, Index & index, + TestSearchEngine & engine) { my::ScopedLogAbortLevelChanger const logAbortLevel(LCRITICAL); @@ -321,7 +322,7 @@ void CheckCompleteness(string const & path, m2::RectD const & viewport, TestSear LOG(LDEBUG, (q.m_query, q.m_request->Results())); int pos = - FindResult(engine, q.m_mwmName, q.m_featureId, q.m_lat, q.m_lon, q.m_request->Results()); + FindResult(index, q.m_mwmName, q.m_featureId, q.m_lat, q.m_lon, q.m_request->Results()); if (pos >= 0) ++expectedResultsFound; if (pos == 0) @@ -377,7 +378,8 @@ int main(int argc, char * argv[]) Engine::Params params; params.m_locale = FLAGS_locale; params.m_numThreads = FLAGS_num_threads; - TestSearchEngine engine(move(infoGetter), params); + + Index index; vector mwms; if (!FLAGS_mwm_list_path.empty()) @@ -399,10 +401,12 @@ int main(int argc, char * argv[]) { mwm.SyncWithDisk(); cout << mwm.GetCountryName() << " " << ReadVersionFromHeader(mwm) << endl; - engine.RegisterMap(mwm); + index.RegisterMap(mwm); } cout << endl; + TestSearchEngine engine(index, move(infoGetter), params); + m2::RectD viewport; { string name = FLAGS_viewport; @@ -421,7 +425,7 @@ int main(int argc, char * argv[]) if (!FLAGS_check_completeness.empty()) { - CheckCompleteness(FLAGS_check_completeness, viewport, engine); + CheckCompleteness(FLAGS_check_completeness, viewport, index, engine); return 0; } diff --git a/search/search_tests/CMakeLists.txt b/search/search_tests/CMakeLists.txt index 7b34a3d12f..3d0ad38ba9 100644 --- a/search/search_tests/CMakeLists.txt +++ b/search/search_tests/CMakeLists.txt @@ -27,6 +27,7 @@ omim_add_test(${PROJECT_NAME} ${SRC}) omim_link_libraries( ${PROJECT_NAME} + search_tests_support search indexer editor diff --git a/search/search_tests/locality_finder_test.cpp b/search/search_tests/locality_finder_test.cpp index e069d74eac..fb3052d17b 100644 --- a/search/search_tests/locality_finder_test.cpp +++ b/search/search_tests/locality_finder_test.cpp @@ -1,5 +1,7 @@ #include "testing/testing.hpp" +#include "search/search_tests_support/test_with_classificator.hpp" + #include "indexer/data_header.hpp" #include "indexer/index.hpp" #include "indexer/classificator_loader.hpp" @@ -16,12 +18,7 @@ namespace { -struct TestWithClassificator -{ - TestWithClassificator() { classificator::Load(); } -}; - -class LocalityFinderTest : public TestWithClassificator +class LocalityFinderTest : public search::tests_support::TestWithClassificator { platform::LocalCountryFile m_worldFile; diff --git a/search/search_tests/search_tests.pro b/search/search_tests/search_tests.pro index 0cd00fa2c4..be2c938c63 100644 --- a/search/search_tests/search_tests.pro +++ b/search/search_tests/search_tests.pro @@ -6,7 +6,7 @@ CONFIG -= app_bundle TEMPLATE = app ROOT_DIR = ../.. -DEPENDENCIES = search indexer platform editor geometry coding icu base protobuf jansson succinct pugixml stats_client +DEPENDENCIES = search_tests_support search indexer platform editor geometry coding icu base protobuf jansson succinct pugixml stats_client include($$ROOT_DIR/common.pri) diff --git a/search/search_tests_support/CMakeLists.txt b/search/search_tests_support/CMakeLists.txt index bebe7ac592..c78ef9d224 100644 --- a/search/search_tests_support/CMakeLists.txt +++ b/search/search_tests_support/CMakeLists.txt @@ -8,6 +8,10 @@ set( test_search_engine.hpp test_search_request.cpp test_search_request.hpp + test_with_classificator.cpp + test_with_classificator.hpp + test_with_custom_mwms.cpp + test_with_custom_mwms.hpp ) add_library(${PROJECT_NAME} ${SRC}) diff --git a/search/search_tests_support/search_tests_support.pro b/search/search_tests_support/search_tests_support.pro index 080bb3ba51..444aa57ab0 100644 --- a/search/search_tests_support/search_tests_support.pro +++ b/search/search_tests_support/search_tests_support.pro @@ -10,8 +10,12 @@ SOURCES += \ test_results_matching.cpp \ test_search_engine.cpp \ test_search_request.cpp \ + test_with_classificator.cpp \ + test_with_custom_mwms.cpp \ HEADERS += \ test_results_matching.hpp \ test_search_engine.hpp \ test_search_request.hpp \ + test_with_classificator.hpp \ + test_with_custom_mwms.hpp \ diff --git a/search/search_tests_support/test_results_matching.cpp b/search/search_tests_support/test_results_matching.cpp index 386ff118d1..4430ddb8d0 100644 --- a/search/search_tests_support/test_results_matching.cpp +++ b/search/search_tests_support/test_results_matching.cpp @@ -99,6 +99,13 @@ bool MatchResults(Index const & index, vector> rules, return false; } +bool MatchResults(Index const & index, vector> rules, + search::Results const & actual) +{ + vector const results(actual.begin(), actual.end()); + return MatchResults(index, rules, results); +} + bool ResultMatches(Index const & index, shared_ptr rule, search::Result const & result) { diff --git a/search/search_tests_support/test_results_matching.hpp b/search/search_tests_support/test_results_matching.hpp index 54b351b348..fe62995574 100644 --- a/search/search_tests_support/test_results_matching.hpp +++ b/search/search_tests_support/test_results_matching.hpp @@ -74,6 +74,8 @@ shared_ptr AlternativesMatch(TArgs &&... args) bool MatchResults(Index const & index, vector> rules, vector const & actual); +bool MatchResults(Index const & index, vector> rules, + search::Results const & actual); bool ResultMatches(Index const & index, shared_ptr rule, search::Result const & result); diff --git a/search/search_tests_support/test_search_engine.cpp b/search/search_tests_support/test_search_engine.cpp index 6eaec449aa..bdad06f314 100644 --- a/search/search_tests_support/test_search_engine.cpp +++ b/search/search_tests_support/test_search_engine.cpp @@ -2,31 +2,28 @@ #include "indexer/categories_holder.hpp" -#include "storage/country_info_getter.hpp" - #include "platform/platform.hpp" +#include + +using namespace std; + namespace search { namespace tests_support { -TestSearchEngine::TestSearchEngine(unique_ptr infoGetter, +TestSearchEngine::TestSearchEngine(Index & index, unique_ptr infoGetter, Engine::Params const & params) - : m_platform(GetPlatform()) - , m_infoGetter(move(infoGetter)) - , m_engine(*this, GetDefaultCategories(), *m_infoGetter, params) + : m_infoGetter(move(infoGetter)), m_engine(index, GetDefaultCategories(), *m_infoGetter, params) { } -TestSearchEngine::TestSearchEngine(Engine::Params const & params) - : m_platform(GetPlatform()) - , m_infoGetter(storage::CountryInfoReader::CreateCountryInfoReader(m_platform)) - , m_engine(*this, GetDefaultCategories(), *m_infoGetter, params) +TestSearchEngine::TestSearchEngine(Index & index, Engine::Params const & params) + : m_infoGetter(storage::CountryInfoReader::CreateCountryInfoReader(GetPlatform())) + , m_engine(index, GetDefaultCategories(), *m_infoGetter, params) { } -TestSearchEngine::~TestSearchEngine() {} - weak_ptr<::search::ProcessorHandle> TestSearchEngine::Search(::search::SearchParams const & params) { return m_engine.Search(params); diff --git a/search/search_tests_support/test_search_engine.hpp b/search/search_tests_support/test_search_engine.hpp index 585e758cfe..4badad5903 100644 --- a/search/search_tests_support/test_search_engine.hpp +++ b/search/search_tests_support/test_search_engine.hpp @@ -1,19 +1,13 @@ #pragma once -#include "indexer/index.hpp" - #include "search/engine.hpp" -#include "std/string.hpp" -#include "std/unique_ptr.hpp" -#include "std/weak_ptr.hpp" +#include "storage/country_info_getter.hpp" -class Platform; +#include +#include -namespace storage -{ -class CountryInfoGetter; -} +class Index; namespace search { @@ -21,25 +15,23 @@ struct SearchParams; namespace tests_support { -class TestSearchEngine : public Index +class TestSearchEngine { public: - TestSearchEngine(unique_ptr infoGetter, + TestSearchEngine(Index & index, std::unique_ptr infoGetter, Engine::Params const & params); - TestSearchEngine(Engine::Params const & params); - ~TestSearchEngine() override; + TestSearchEngine(Index & index, Engine::Params const & params); - void SetLocale(string const & locale) { m_engine.SetLocale(locale); } + void SetLocale(std::string const & locale) { m_engine.SetLocale(locale); } void LoadCitiesBoundaries() { m_engine.LoadCitiesBoundaries(); } - weak_ptr Search(search::SearchParams const & params); + std::weak_ptr Search(search::SearchParams const & params); storage::CountryInfoGetter & GetCountryInfoGetter() { return *m_infoGetter; } private: - Platform & m_platform; - unique_ptr m_infoGetter; + std::unique_ptr m_infoGetter; search::Engine m_engine; }; } // namespace tests_support diff --git a/search/search_tests_support/test_with_classificator.cpp b/search/search_tests_support/test_with_classificator.cpp new file mode 100644 index 0000000000..819a198e6b --- /dev/null +++ b/search/search_tests_support/test_with_classificator.cpp @@ -0,0 +1,17 @@ +#include "search/search_tests_support/test_with_classificator.hpp" + +#include "indexer/classificator_loader.hpp" +#include "indexer/map_style.hpp" +#include "indexer/map_style_reader.hpp" + +namespace search +{ +namespace tests_support +{ +TestWithClassificator::TestWithClassificator() +{ + GetStyleReader().SetCurrentStyle(MapStyleMerged); + classificator::Load(); +} +} // namespace tests_support +} // namespace search diff --git a/search/search_tests_support/test_with_classificator.hpp b/search/search_tests_support/test_with_classificator.hpp new file mode 100644 index 0000000000..eaf3f12ee7 --- /dev/null +++ b/search/search_tests_support/test_with_classificator.hpp @@ -0,0 +1,14 @@ +#pragma once + +namespace search +{ +namespace tests_support +{ +class TestWithClassificator +{ +public: + TestWithClassificator(); + virtual ~TestWithClassificator() = default; +}; +} // namespace tests_support +} // namespace search diff --git a/search/search_tests_support/test_with_custom_mwms.cpp b/search/search_tests_support/test_with_custom_mwms.cpp new file mode 100644 index 0000000000..32bf5f6f15 --- /dev/null +++ b/search/search_tests_support/test_with_custom_mwms.cpp @@ -0,0 +1,31 @@ +#include "search/search_tests_support/test_with_custom_mwms.hpp" + +#include "search/editor_delegate.hpp" + +#include "platform/local_country_file_utils.hpp" + +#include "base/stl_add.hpp" + +namespace search +{ +namespace tests_support +{ +TestWithCustomMwms::TestWithCustomMwms() +{ + indexer::tests_support::SetUpEditorForTesting(my::make_unique(m_index)); +} + +TestWithCustomMwms::~TestWithCustomMwms() +{ + for (auto const & file : m_files) + Cleanup(file); +} + +// static +void TestWithCustomMwms::Cleanup(platform::LocalCountryFile const & file) +{ + platform::CountryIndexes::DeleteFromDisk(file); + file.DeleteFromDisk(MapOptions::Map); +} +} // namespace tests_support +} // namespace search diff --git a/search/search_tests_support/test_with_custom_mwms.hpp b/search/search_tests_support/test_with_custom_mwms.hpp new file mode 100644 index 0000000000..618da2311c --- /dev/null +++ b/search/search_tests_support/test_with_custom_mwms.hpp @@ -0,0 +1,93 @@ +#pragma once + +#include "search/search_tests_support/test_with_classificator.hpp" + +#include "generator/generator_tests_support/test_mwm_builder.hpp" + +#include "indexer/indexer_tests_support/helpers.hpp" + +#include "indexer/data_header.hpp" +#include "indexer/feature.hpp" +#include "indexer/index.hpp" +#include "indexer/mwm_set.hpp" + +#include "platform/country_file.hpp" +#include "platform/local_country_file.hpp" +#include "platform/platform.hpp" + +#include "base/assert.hpp" + +#include +#include +#include + +namespace search +{ +namespace tests_support +{ +class TestWithCustomMwms : public TestWithClassificator +{ +public: + TestWithCustomMwms(); + ~TestWithCustomMwms() override; + + // Creates a physical country file on a disk, which will be removed + // at the end of the test. |fn| is a delegate that accepts a single + // argument - TestMwmBuilder and adds all necessary features to the + // country file. + // + // *NOTE* when |type| is feature::DataHeader::country, the country + // with |name| will be automatically registered. + template + MwmSet::MwmId BuildMwm(std::string const & name, feature::DataHeader::MapType type, BuildFn && fn) + { + m_files.emplace_back(GetPlatform().WritableDir(), platform::CountryFile(name), 0 /* version */); + auto & file = m_files.back(); + Cleanup(file); + + { + generator::tests_support::TestMwmBuilder builder(file, type); + fn(builder); + } + + auto result = m_index.RegisterMap(file); + CHECK_EQUAL(result.second, MwmSet::RegResult::Success, ()); + + auto const id = result.first; + auto const info = id.GetInfo(); + CHECK(info.get(), ()); + OnMwmBuilded(*info); + return id; + } + + template + MwmSet::MwmId BuildWorld(BuildFn && fn) + { + return BuildMwm("testWorld", feature::DataHeader::world, std::forward(fn)); + } + + template + MwmSet::MwmId BuildCountry(std::string const & name, BuildFn && fn) + { + return BuildMwm(name, feature::DataHeader::country, std::forward(fn)); + } + + template + void EditFeature(FeatureID const & id, EditorFn && fn) + { + Index::FeaturesLoaderGuard loader(m_index, id.m_mwmId); + FeatureType ft; + CHECK(loader.GetFeatureByIndex(id.m_index, ft), ()); + indexer::tests_support::EditFeature(ft, forward(fn)); + } + +protected: + static void Cleanup(platform::LocalCountryFile const & file); + + virtual void OnMwmBuilded(MwmInfo const & /* info */) {} + + Index m_index; + std::vector m_files; +}; +} // namespace tests_support +} // namespace search