diff --git a/generator/generator_tests/restriction_test.cpp b/generator/generator_tests/restriction_test.cpp index 7be2e9e084..190193b395 100644 --- a/generator/generator_tests/restriction_test.cpp +++ b/generator/generator_tests/restriction_test.cpp @@ -17,6 +17,7 @@ #include "coding/file_container.hpp" +#include "base/assert.hpp" #include "base/file_name_utils.hpp" #include "base/logging.hpp" @@ -45,12 +46,56 @@ string const kTestMwm = "test"; string const kRestrictionFileName = "restrictions_in_osm_ids.csv"; string const kOsmIdsToFeatureIdsName = "osm_ids_to_feature_ids" OSM2FEATURE_FILE_EXTENSION; +struct RestrictionUTurnForTests +{ + RestrictionUTurnForTests(Restriction::Type type, uint32_t featureId, bool viaIsFirstPoint) + : m_type(type), + m_featureId(featureId), + m_viaIsFirstPoint(viaIsFirstPoint) + { + CHECK(m_type == Restriction::Type::NoUTurn || m_type == Restriction::Type::OnlyUTurn, ()); + } + + bool operator==(RestrictionUTurnForTests const & rhs) const + { + return m_type == rhs.m_type && m_featureId == rhs.m_featureId && + m_viaIsFirstPoint == rhs.m_viaIsFirstPoint; + } + + bool operator<(RestrictionUTurnForTests const & rhs) const + { + if (m_type != rhs.m_type) + return m_type < rhs.m_type; + + if (m_featureId != rhs.m_featureId) + return m_featureId < rhs.m_featureId; + + return m_viaIsFirstPoint < rhs.m_viaIsFirstPoint; + } + + Restriction::Type m_type; + uint32_t m_featureId; + bool m_viaIsFirstPoint; +}; + +string DebugPrint(RestrictionUTurnForTests const & r) +{ + ostringstream ss; + ss << "[" << DebugPrint(r.m_type) << "]: " + << "feature: " << r.m_featureId << ", " + << "isFirstPoint: " << r.m_viaIsFirstPoint; + + return ss.str(); +} + void BuildEmptyMwm(LocalCountryFile & country) { generator::tests_support::TestMwmBuilder builder(country, feature::DataHeader::country); } -void LoadRestrictions(string const & mwmFilePath, vector & restrictions) +void LoadRestrictions(string const & mwmFilePath, + vector & restrictions, + vector & restrictionsUTurn) { FilesContainerR const cont(mwmFilePath); if (!cont.IsExist(RESTRICTIONS_FILE_TAG)) @@ -65,13 +110,22 @@ void LoadRestrictions(string const & mwmFilePath, vector & restrict RestrictionVec restrictionsNo; RestrictionVec restrictionsOnly; - RestrictionSerializer::Deserialize(header, restrictionsNo, restrictionsOnly, src); + vector restrictionsNoUTurn; + vector restrictionsOnlyUTurn; + RestrictionSerializer::Deserialize(header, restrictionsNo, restrictionsOnly, + restrictionsNoUTurn, restrictionsOnlyUTurn, src); for (auto const & r : restrictionsNo) restrictions.emplace_back(Restriction::Type::No, vector(r.begin(), r.end())); for (auto const & r : restrictionsOnly) restrictions.emplace_back(Restriction::Type::Only, vector(r.begin(), r.end())); + + for (auto const & r : restrictionsNoUTurn) + restrictionsUTurn.emplace_back(Restriction::Type::NoUTurn, r.m_featureId, r.m_viaIsFirstPoint); + + for (auto const & r : restrictionsOnlyUTurn) + restrictionsUTurn.emplace_back(Restriction::Type::OnlyUTurn, r.m_featureId, r.m_viaIsFirstPoint); } catch (Reader::OpenException const & e) { @@ -86,7 +140,8 @@ void LoadRestrictions(string const & mwmFilePath, vector & restrict void TestRestrictionBuilding(string const & restrictionPath, string const & osmIdsToFeatureIdContent, unique_ptr graph, - vector & expected) + vector & expectedNotUTurn, + vector & expectedUTurn) { Platform & platform = GetPlatform(); string const writableDir = platform.WritableDir(); @@ -123,12 +178,17 @@ void TestRestrictionBuilding(string const & restrictionPath, // Reading from mwm section and testing restrictions. vector restrictionsFromMwm; - LoadRestrictions(mwmFullPath, restrictionsFromMwm); + vector restrictionsUTurnFromMwm; + LoadRestrictions(mwmFullPath, restrictionsFromMwm, restrictionsUTurnFromMwm); sort(restrictionsFromMwm.begin(), restrictionsFromMwm.end()); - sort(expected.begin(), expected.end()); + sort(restrictionsUTurnFromMwm.begin(), restrictionsUTurnFromMwm.end()); - TEST_EQUAL(restrictionsFromMwm, expected, ()); + sort(expectedNotUTurn.begin(), expectedNotUTurn.end()); + sort(expectedUTurn.begin(), expectedUTurn.end()); + + TEST_EQUAL(restrictionsFromMwm, expectedNotUTurn, ()); + TEST_EQUAL(restrictionsUTurnFromMwm, expectedUTurn, ()); } // 2 * @@ -138,7 +198,7 @@ void TestRestrictionBuilding(string const & restrictionPath, // 1 * *<- F3 ->*-> F8 -> *-> F10 -> * // ↖ ↑ ↗ // F6 F2 F9 -// Start ↖ ↑ ↗ +// Start ↘ ↑ ↗ // 0 *-> F7 ->*-> F0 ->*-> F1 ->* // -1 0 1 2 3 4 // @@ -158,7 +218,7 @@ pair, string> BuildTwoCubeGraph() RoadGeometry::Points({{0.0, 2.0}, {1.0, 1.0}})); loader->AddRoad(5 /* feature id */, true /* one way */, 1.0 /* speed */, RoadGeometry::Points({{-1.0, 1.0}, {0.0, 2.0}})); - loader->AddRoad(6 /* feature id */, true /* one way */, 1.0 /* speed */, + loader->AddRoad(6 /* feature id */, false /* one way */, 1.0 /* speed */, RoadGeometry::Points({{0.0, 0.0}, {-1.0, 1.0}})); loader->AddRoad(7 /* feature id */, true /* one way */, 1.0 /* speed */, RoadGeometry::Points({{-1.0, 0.0}, {0.0, 0.0}})); @@ -211,12 +271,13 @@ UNIT_TEST(RestrictionGenerationTest_1) /* Type ViaType ViaNodeCoords: x y from to */ R"(Only, node, 1.0, 0.0, 0, 1)"; - vector expected = { + vector expectedNotUTurn = { {Restriction::Type::Only, {0, 1}} }; + vector expectedUTurn; TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), - expected); + expectedNotUTurn, expectedUTurn); } UNIT_TEST(RestrictionGenerationTest_2) @@ -229,12 +290,13 @@ UNIT_TEST(RestrictionGenerationTest_2) /* Type ViaType from ViaWayId to */ R"(Only, way, 0, 1 2)"; - vector expected = { + vector expectedNotUTurn = { {Restriction::Type::Only, {0, 1, 2}} }; + vector expectedUTurn; TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), - expected); + expectedNotUTurn, expectedUTurn); } UNIT_TEST(RestrictionGenerationTest_3) @@ -244,17 +306,18 @@ UNIT_TEST(RestrictionGenerationTest_3) tie(indexGraph, osmIdsToFeatureIdsContent) = BuildTwoCubeGraph(); string const restrictionPath = - /* Type ViaType ViaNodeCoords: x y from to */ - R"(Only, node, 0.0, 0.0, 7, 6 + /* Type ViaType ViaNodeCoords: x y from via to */ + R"(Only, node, 0.0, 0.0, 7, 6 No, way, 2, 8, 10)"; - vector expected = { + vector expectedNotUTurn = { {Restriction::Type::Only, {7, 6}}, {Restriction::Type::No, {2, 8, 10}} }; + vector expectedUTurn; TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), - expected); + expectedNotUTurn, expectedUTurn); } UNIT_TEST(RestrictionGenerationTest_BadConnection_1) @@ -265,17 +328,18 @@ UNIT_TEST(RestrictionGenerationTest_BadConnection_1) // Here features 7 and 6 don't connect at (2.0, 0.0) string const restrictionPath = - /* Type ViaType ViaNodeCoords: x y from to */ - R"(Only, node, 2.0, 0.0, 7, 6 + /* Type ViaType ViaNodeCoords: x y from via to */ + R"(Only, node, 2.0, 0.0, 7, 6 No, way, 2, 8, 10)"; // So we don't expect first restriction here. - vector expected = { + vector expectedNotUTurn = { {Restriction::Type::No, {2, 8, 10}} }; + vector expectedUTurn; TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), - expected); + expectedNotUTurn, expectedUTurn); } UNIT_TEST(RestrictionGenerationTest_BadConnection_2) @@ -286,16 +350,90 @@ UNIT_TEST(RestrictionGenerationTest_BadConnection_2) // Here features 0, 1 and 3 don't have common joints (namely 1 and 3). string const restrictionPath = - /* Type ViaType ViaNodeCoords: x y from to */ - R"(Only, node, 0.0, 0.0, 7, 6 + /* Type ViaType ViaNodeCoords: x y from via to */ + R"(Only, node, 0.0, 0.0, 7, 6 No, way, 0, 1, 3)"; // So we don't expect second restriction here. - vector expected = { + vector expectedNotUTurn = { {Restriction::Type::Only, {7, 6}} }; + vector expectedUTurn; + + TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), + expectedNotUTurn, expectedUTurn); +} + +UNIT_TEST(RestrictionGenerationTest_WithUTurn_1) +{ + string osmIdsToFeatureIdsContent; + unique_ptr indexGraph; + tie(indexGraph, osmIdsToFeatureIdsContent) = BuildTwoCubeGraph(); + + string const restrictionPath = + /* Type ViaType ViaNodeCoords: x y from to */ + R"(NoUTurn, node, 2.0, 1.0, 3, 3 + OnlyUTurn, node, 0.0, 0.0, 6, 6)"; + + // So we don't expect second restriction here. + vector expectedNotUTurn; + vector expectedUTurn = { + {Restriction::Type::NoUTurn, 3 /* featureId */, false /* viaIsFirstPoint */}, + {Restriction::Type::OnlyUTurn, 6 /* featureId */, true /* viaIsFirstPoint */} + }; TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), - expected); + expectedNotUTurn, expectedUTurn); +} + +UNIT_TEST(RestrictionGenerationTest_WithUTurn_2) +{ + string osmIdsToFeatureIdsContent; + unique_ptr indexGraph; + tie(indexGraph, osmIdsToFeatureIdsContent) = BuildTwoCubeGraph(); + + // First two are not UTurn restrictions, but still correct restriction. + // We should just convert them. + string const restrictionPath = + /* Type ViaType ViaNodeCoords: x y from via to */ + R"(NoUTurn, node, 2.0, 1.0, 2, 8 + NoUTurn, way, 2, 8, 10 + OnlyUTurn, way, 6, 5, 4 + OnlyUTurn, node, -1.0, 1.0, 6, 6)"; + + // So we don't expect second restriction here. + vector expectedNotUTurn = { + {Restriction::Type::No, {2, 8}}, + {Restriction::Type::No, {2, 8, 10}}, + {Restriction::Type::Only, {6, 5, 4}} + }; + + vector expectedUTurn = { + {Restriction::Type::OnlyUTurn, 6 /* featureId */, false /* viaIsFirstPoint */} + }; + + TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), + expectedNotUTurn, expectedUTurn); +} + +UNIT_TEST(RestrictionGenerationTest_WithUTurn_BadConnection_1) +{ + string osmIdsToFeatureIdsContent; + unique_ptr indexGraph; + tie(indexGraph, osmIdsToFeatureIdsContent) = BuildTwoCubeGraph(); + + string const restrictionPath = + /* Type ViaType ViaNodeCoords: x y from via to */ + R"(NoUTurn, node, 20.0, 11.0, 2, 8 + OnlyUTurn, way, 6, 2, 4 + OnlyUTurn, node, -10.0, 10.0, 6, 6 + NoUTurn, node, -10.0, 10.0, 6, 6)"; + + // So we don't expect second restriction here. + vector expectedNotUTurn; + vector expectedUTurn; + + TestRestrictionBuilding(restrictionPath, osmIdsToFeatureIdsContent, move(indexGraph), + expectedNotUTurn, expectedUTurn); } } // namespace