@@ -1548,3 +1548,139 @@ TEST_CASE("allPathsTo with closed roads") {
15481548 CHECK_FALSE (pathMap.contains (1 ));
15491549 }
15501550}
1551+
1552+ TEST_CASE (" Change Street Lanes" ) {
1553+ Road::setMeanVehicleLength (5 .);
1554+
1555+ SUBCASE (" changeStreetNLanesById" ) {
1556+ GIVEN (" A network with multiple streets" ) {
1557+ RoadNetwork graph{};
1558+ graph.addNode (0 , dsf::geometry::Point (0.0 , 0.0 ));
1559+ graph.addNode (1 , dsf::geometry::Point (1.0 , 0.0 ));
1560+ graph.addNode (2 , dsf::geometry::Point (2.0 , 0.0 ));
1561+
1562+ Street s01 (10 , std::make_pair (0 , 1 ), 100.0 , 20.0 , 2 );
1563+ Street s12 (11 , std::make_pair (1 , 2 ), 150.0 , 25.0 , 3 );
1564+ graph.addStreets (s01, s12);
1565+
1566+ auto const * pStreet01 = graph.street (0 , 1 );
1567+ REQUIRE (pStreet01 != nullptr );
1568+ auto const initialCapacity = (*pStreet01)->capacity ();
1569+ auto const initialMaxSpeed = (*pStreet01)->maxSpeed ();
1570+
1571+ WHEN (" Lanes are increased for street by id" ) {
1572+ graph.changeStreetNLanesById (10 , 4 );
1573+
1574+ THEN (" The street's properties are updated correctly" ) {
1575+ CHECK_EQ ((*pStreet01)->nLanes (), 4 );
1576+ CHECK_EQ ((*pStreet01)->capacity (), initialCapacity * 2 );
1577+ CHECK_EQ ((*pStreet01)->maxSpeed (), initialMaxSpeed);
1578+ CHECK_EQ ((*pStreet01)->exitQueues ().size (), 4 );
1579+ }
1580+ }
1581+
1582+ WHEN (" Lanes are changed with speed factor" ) {
1583+ graph.changeStreetNLanesById (10 , 1 , 0.6 );
1584+
1585+ THEN (" Both lanes and speed are updated" ) {
1586+ CHECK_EQ ((*pStreet01)->nLanes (), 1 );
1587+ CHECK_EQ ((*pStreet01)->maxSpeed (), doctest::Approx (initialMaxSpeed * 0.6 ));
1588+ }
1589+ }
1590+
1591+ WHEN (" Invalid street id is provided" ) {
1592+ THEN (" Exception is thrown" ) {
1593+ CHECK_THROWS_AS (graph.changeStreetNLanesById (999 , 2 ), std::out_of_range);
1594+ }
1595+ }
1596+
1597+ WHEN (" Invalid number of lanes is provided" ) {
1598+ THEN (" Exception is thrown" ) {
1599+ CHECK_THROWS_AS (graph.changeStreetNLanesById (10 , 0 ), std::invalid_argument);
1600+ CHECK_THROWS_AS (graph.changeStreetNLanesById (10 , -1 ), std::invalid_argument);
1601+ }
1602+ }
1603+ }
1604+ }
1605+
1606+ SUBCASE (" changeStreetNLanesByName" ) {
1607+ GIVEN (" A network with named streets" ) {
1608+ RoadNetwork graph{};
1609+ graph.addNode (0 , dsf::geometry::Point (0.0 , 0.0 ));
1610+ graph.addNode (1 , dsf::geometry::Point (1.0 , 0.0 ));
1611+ graph.addNode (2 , dsf::geometry::Point (2.0 , 0.0 ));
1612+ graph.addNode (3 , dsf::geometry::Point (1.0 , 1.0 ));
1613+
1614+ Street s01 (10 , std::make_pair (0 , 1 ), 100.0 , 20.0 , 2 , " Main Street" );
1615+ Street s12 (11 , std::make_pair (1 , 2 ), 150.0 , 25.0 , 3 , " Main Street" );
1616+ Street s03 (12 , std::make_pair (0 , 3 ), 120.0 , 15.0 , 1 , " Side Road" );
1617+ Street s32 (13 , std::make_pair (3 , 2 ), 130.0 , 18.0 , 2 , " Side Road" );
1618+ graph.addStreets (s01, s12, s03, s32);
1619+
1620+ auto const * pMainStreet1 = graph.street (0 , 1 );
1621+ auto const * pMainStreet2 = graph.street (1 , 2 );
1622+ auto const * pSideRoad1 = graph.street (0 , 3 );
1623+ auto const * pSideRoad2 = graph.street (3 , 2 );
1624+
1625+ REQUIRE (pMainStreet1 != nullptr );
1626+ REQUIRE (pMainStreet2 != nullptr );
1627+ REQUIRE (pSideRoad1 != nullptr );
1628+ REQUIRE (pSideRoad2 != nullptr );
1629+
1630+ auto const initialMainSpeed1 = (*pMainStreet1)->maxSpeed ();
1631+ auto const initialMainSpeed2 = (*pMainStreet2)->maxSpeed ();
1632+ auto const initialSideSpeed1 = (*pSideRoad1)->maxSpeed ();
1633+ auto const initialSideSpeed2 = (*pSideRoad2)->maxSpeed ();
1634+
1635+ WHEN (" All streets with 'Main' in name are changed" ) {
1636+ graph.changeStreetNLanesByName (" Main" , 1 );
1637+
1638+ THEN (" Only Main Streets are affected" ) {
1639+ CHECK_EQ ((*pMainStreet1)->nLanes (), 1 );
1640+ CHECK_EQ ((*pMainStreet2)->nLanes (), 1 );
1641+ CHECK_EQ ((*pSideRoad1)->nLanes (), 1 ); // unchanged
1642+ CHECK_EQ ((*pSideRoad2)->nLanes (), 2 ); // unchanged
1643+ CHECK_EQ ((*pMainStreet1)->maxSpeed (), initialMainSpeed1);
1644+ CHECK_EQ ((*pMainStreet2)->maxSpeed (), initialMainSpeed2);
1645+ }
1646+ }
1647+
1648+ WHEN (" Streets are changed by name with speed factor" ) {
1649+ graph.changeStreetNLanesByName (" Side" , 3 , 0.8 );
1650+
1651+ THEN (" Only Side Roads are affected with both changes" ) {
1652+ CHECK_EQ ((*pSideRoad1)->nLanes (), 3 );
1653+ CHECK_EQ ((*pSideRoad2)->nLanes (), 3 );
1654+ CHECK_EQ ((*pMainStreet1)->nLanes (), 2 ); // unchanged
1655+ CHECK_EQ ((*pMainStreet2)->nLanes (), 3 ); // unchanged
1656+ CHECK_EQ ((*pSideRoad1)->maxSpeed (), doctest::Approx (initialSideSpeed1 * 0.8 ));
1657+ CHECK_EQ ((*pSideRoad2)->maxSpeed (), doctest::Approx (initialSideSpeed2 * 0.8 ));
1658+ CHECK_EQ ((*pMainStreet1)->maxSpeed (), initialMainSpeed1); // unchanged
1659+ CHECK_EQ ((*pMainStreet2)->maxSpeed (), initialMainSpeed2); // unchanged
1660+ }
1661+ }
1662+
1663+ WHEN (" No streets match the name pattern" ) {
1664+ graph.changeStreetNLanesByName (" NonExistent" , 5 );
1665+
1666+ THEN (" No streets are changed" ) {
1667+ CHECK_EQ ((*pMainStreet1)->nLanes (), 2 );
1668+ CHECK_EQ ((*pMainStreet2)->nLanes (), 3 );
1669+ CHECK_EQ ((*pSideRoad1)->nLanes (), 1 );
1670+ CHECK_EQ ((*pSideRoad2)->nLanes (), 2 );
1671+ }
1672+ }
1673+
1674+ WHEN (" Partial name match is used" ) {
1675+ graph.changeStreetNLanesByName (" Street" , 4 );
1676+
1677+ THEN (" All streets with 'Street' in name are changed" ) {
1678+ CHECK_EQ ((*pMainStreet1)->nLanes (), 4 );
1679+ CHECK_EQ ((*pMainStreet2)->nLanes (), 4 );
1680+ CHECK_EQ ((*pSideRoad1)->nLanes (), 1 ); // unchanged
1681+ CHECK_EQ ((*pSideRoad2)->nLanes (), 2 ); // unchanged
1682+ }
1683+ }
1684+ }
1685+ }
1686+ }
0 commit comments