[search] Fixed an out-of-bounds error.

Tracer assumed that every token will have a type but we
do not have a special type for unrecognized tokens and
set their type to COUNT instead. With relaxed parsing,
some tokens were left unclassified and this led to an error.
This commit is contained in:
Maxim Pimenov 2019-08-20 21:37:21 +03:00 committed by Tatiana Yan
parent 1a1f0098f9
commit 4cd51efdbf
2 changed files with 43 additions and 16 deletions

View file

@ -28,36 +28,62 @@ UNIT_CLASS_TEST(TracerTest, Smoke)
TestCity moscow(m2::PointD(0, 0), "Moscow", "en", 100 /* rank */);
TestCafe regularCafe(m2::PointD(0, 0));
TestCafe moscowCafe(m2::PointD(0, 0), "Moscow", "en");
TestStreet tverskaya(vector<m2::PointD>{m2::PointD(0, 0), m2::PointD(0, 1)}, "Tverskaya street",
"en");
BuildWorld([&](TestMwmBuilder & builder) { builder.Add(moscow); });
auto const id = BuildCountry("Wonderland", [&](TestMwmBuilder & builder) {
builder.Add(regularCafe);
builder.Add(moscowCafe);
builder.Add(tverskaya);
});
auto tracer = make_shared<Tracer>();
SearchParams params;
params.m_query = "moscow cafe";
params.m_inputLocale = "en";
params.m_viewport = m2::RectD(-1, -1, 1, 1);
params.m_mode = Mode::Everywhere;
params.m_tracer = tracer;
TestSearchRequest request(m_engine, params);
request.Run();
Rules rules = {ExactMatch(id, regularCafe), ExactMatch(id, moscowCafe)};
TEST(ResultsMatch(request.Results(), rules), ());
{
params.m_query = "moscow cafe";
auto tracer = make_shared<Tracer>();
params.m_tracer = tracer;
auto const actual = tracer->GetUniqueParses();
TestSearchRequest request(m_engine, params);
request.Run();
Rules rules = {ExactMatch(id, regularCafe), ExactMatch(id, moscowCafe)};
TEST(ResultsMatch(request.Results(), rules), ());
vector<Tracer::Parse> const expected{
Tracer::Parse{{{TokenType::TOKEN_TYPE_POI, TokenRange(0, 2)}}, false /* category */},
Tracer::Parse{{{TokenType::TOKEN_TYPE_CITY, TokenRange(0, 1)},
{TokenType::TOKEN_TYPE_POI, TokenRange(1, 2)}},
true /* category */}};
auto const actual = tracer->GetUniqueParses();
TEST_EQUAL(expected, actual, ());
vector<Tracer::Parse> const expected{
Tracer::Parse{{{TokenType::TOKEN_TYPE_POI, TokenRange(0, 2)}}, false /* category */},
Tracer::Parse{{{TokenType::TOKEN_TYPE_CITY, TokenRange(0, 1)},
{TokenType::TOKEN_TYPE_POI, TokenRange(1, 2)}},
true /* category */}};
TEST_EQUAL(expected, actual, ());
}
{
params.m_query = "moscow tverskaya 1 or 2";
auto tracer = make_shared<Tracer>();
params.m_tracer = tracer;
TestSearchRequest request(m_engine, params);
request.Run();
TEST(ResultsMatch(request.Results(), {ExactMatch(id, tverskaya)}), ());
auto const actual = tracer->GetUniqueParses();
// Unrecognized tokens are not included into the parses.
vector<Tracer::Parse> const expected{
Tracer::Parse{{{TokenType::TOKEN_TYPE_STREET, TokenRange(1, 2)}}, false /* category */},
Tracer::Parse{{{TokenType::TOKEN_TYPE_CITY, TokenRange(0, 1)},
{TokenType::TOKEN_TYPE_STREET, TokenRange(1, 2)}},
false /* category */},
};
TEST_EQUAL(expected, actual, ());
}
}
} // namespace

View file

@ -21,7 +21,8 @@ Tracer::Parse::Parse(vector<TokenType> const & types, bool category) : m_categor
auto j = i + 1;
while (j != types.size() && types[j] == type)
++j;
m_ranges[type] = TokenRange(i, j);
if (type < TokenType::TOKEN_TYPE_COUNT)
m_ranges[type] = TokenRange(i, j);
i = j;
}
}