#include #include #include "trenesis/network/graph.h" #include "trenesis/network/graph_assets.h" using namespace testing; namespace trenesis { using stop_area_pair = decltype(trenesis::Network::stop_areas)::value_type; using stop_point_pair = decltype(trenesis::StopArea::stop_points)::value_type; namespace matchers { template auto StopArea(const char* stop_area_id, StopPoints... stop_points) { return AllOf( Field( "key", &stop_area_pair::first, stop_area_id ), Field( "value", &stop_area_pair::second, Pointee(Field("stop_points", &StopArea::stop_points, UnorderedElementsAre( Field( "key", &stop_point_pair::first, stop_points // Dijon )... ) )) ) ); } auto Departure( const Network& graph, const char* origin_stop_area, const char* origin_stop_point, const char* destination_stop_area, const char* destination_stop_point, const char* departure_time, const char* arrival_time ) { return AllOf( Field( "origin", &JourneySection::origin, graph.stop_areas.at(origin_stop_area)->stop_points.at(origin_stop_point).get() ), Field( "destination", &JourneySection::destination, graph.stop_areas.at(destination_stop_area)->stop_points.at(destination_stop_point).get() ), Field( "departure_time", &JourneySection::departure_time, departure_time ), Field( "arrival_time", &JourneySection::arrival_time, arrival_time ) ); } template auto DeparturesFromStopPoint(Departures... departures) { return Field( "value", &stop_point_pair::second, Pointee( Field( "departures", &StopPoint::departures, UnorderedElementsAre( departures... ) ) ) ); } template auto DeparturesFromStopArea( DeparturesFromStopPoint... departures_from_stop_point ) { return Pointer( Field("stop_points", &StopArea::stop_points, UnorderedElementsAre( departures_from_stop_point... ) ) ); } } } using namespace trenesis; /* * Builds a graph with a single node to test node parsing. */ TEST(Network, build_simple_node) { const auto graph = trenesis::Network::build_from_json( json::parse(single_node_journey), json::parse(single_node_stop_points) ); // Complete stop areas matching is only performed in this test. For the // rest of the test, only the structure of the network (i.e. stop points and // departures) are tested. EXPECT_THAT(graph.stop_areas, UnorderedElementsAre( AllOf( Field( "key", &stop_area_pair::first, "stop_area:SNCF:87713040" ), Field( "value", &stop_area_pair::second, Pointer(AllOf( Field(&trenesis::StopArea::id, "stop_area:SNCF:87713040"), Field(&trenesis::StopArea::name, "Dijon"), Field(&trenesis::StopArea::label, "Dijon (Dijon)"), Field( &trenesis::StopArea::coord, AllOf( Field(&trenesis::Point::longitude, 5.027256), Field(&trenesis::Point::latitude, 47.323411) ) ), Field(&trenesis::StopArea::stop_points, UnorderedElementsAre( AllOf( Field("key", &stop_point_pair::first, "stop_point:SNCF:87713040:Train"), Field( "value", &stop_point_pair::second, Pointer(AllOf( Field(&trenesis::StopPoint::id, "stop_point:SNCF:87713040:Train"), Field(&trenesis::StopPoint::name, "Dijon"), Field(&trenesis::StopPoint::label, "Dijon (Dijon)"), Field( &trenesis::StopPoint::coord, AllOf( Field(&trenesis::Point::longitude, 5.027256), Field(&trenesis::Point::latitude, 47.323411) ) ) )) ) ) )) )) ) ) )); } /* * Builds a linear graph with 3 nodes */ TEST(Network, build_simple_graph) { const auto graph = trenesis::Network::build_from_json( json::parse(dijon_cercy_nevers_journey), json::parse(dijon_cercy_nevers_stop_points) ); // Check stop_areas EXPECT_THAT(graph.stop_areas, UnorderedElementsAre( matchers::StopArea( // Dijon "stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train" ), matchers::StopArea( // Cercy "stop_area:SNCF:87696492", "stop_point:SNCF:87696492:Train" ), matchers::StopArea( // Nevers "stop_area:SNCF:87696005", "stop_point:SNCF:87696005:Train" ) )); // Check departures // Dijon EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713040"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Dijon "stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train", // Cercy "stop_area:SNCF:87696492", "stop_point:SNCF:87696492:Train", // Departure "081200", // Arrival "095300") ) ) ); // Cercy EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87696492"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Cercy "stop_area:SNCF:87696492", "stop_point:SNCF:87696492:Train", // Nevers "stop_area:SNCF:87696005", "stop_point:SNCF:87696005:Train", // Departure "095400", // Arrival "102900" ) ) ) ); // Nevers EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87696005"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); } /* * Builds a graph with 4 nodes and the following shape: * * Besançon -- Dole -- Dijon * \ / * Arc-et-Senans * | * --Mouchard * / | * / Pontarlier * | * Lons-le-Saunier */ TEST(Network, build_complex_graph) { const auto graph = trenesis::Network::build_from_json( // This is a simplified extract from /coverage/sncf/vehicle_journeys json::parse(besancon_dijon_lons_train_only_journeys), json::parse(besancon_dijon_lons_train_only_stop_points) ); // Check stop_areas EXPECT_THAT(graph.stop_areas, UnorderedElementsAre( matchers::StopArea( // Besançon Viotte "stop_area:SNCF:87718007","stop_point:SNCF:87718007:Train" ), matchers::StopArea( // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train" ), matchers::StopArea( // Dijon "stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train" ), matchers::StopArea( // Arc-et-senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train" ), matchers::StopArea( // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train" ), matchers::StopArea( // Pontarlier "stop_area:SNCF:87715003","stop_point:SNCF:87715003:Train" ), matchers::StopArea( // Lons-le-Saunier "stop_area:SNCF:87718239", "stop_point:SNCF:87718239:Train" ) ) ); // Check departures // Besançon Viotte EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718007"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Besançon "stop_area:SNCF:87718007", "stop_point:SNCF:87718007:Train", // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train", // Departure "105600", // Arrival "112000" ), matchers::Departure( graph, // Besançon "stop_area:SNCF:87718007", "stop_point:SNCF:87718007:Train", // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", // Departure "165200", // Arrival "171500" ) ) ) ); // Dole EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713412"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train", // Dijon "stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train", // Departure "112200", // Arrival "115200" ), matchers::Departure( graph, // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train", // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", // Departure "111400", // Arrival "113200" ) ) ) ); // Dijon EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713040"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); // Arc-et-Senans EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718841"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", // Departure "113300", // Arrival "113900" ), matchers::Departure( graph, // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", // Departure "171600", // Arrival "172100" ) ) ) ); // Mouchard EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718833"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", // Pontarlier "stop_area:SNCF:87715003", "stop_point:SNCF:87715003:Train", // Departure "114200", // Arrival "123700" ), matchers::Departure( graph, // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", // Lons-le-Saunier "stop_area:SNCF:87718239", "stop_point:SNCF:87718239:Train", // Departure "172200", // Arrival "175900" ) ) ) ); // Pontarlier EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87715003"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); // Lons-le-Saunier EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718239"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); } /* * Builds a graph with 4 nodes and the following shape: * * Besançon -- Dole -- Dijon * \ / * Arc-et-Senans * | | * --Mouchard * / | * / Pontarlier * | * Lons-le-Saunier */ TEST(Network, build_complex_graph_with_long_distance_train) { const auto graph = trenesis::Network::build_from_json( json::parse(besancon_dijon_lons_journeys), json::parse(besancon_dijon_lons_stop_points) ); // Check stop_areas EXPECT_THAT(graph.stop_areas, UnorderedElementsAre( matchers::StopArea( // Besançon Viotte "stop_area:SNCF:87718007", "stop_point:SNCF:87718007:Train", "stop_point:SNCF:87718007:LongDistanceTrain" ), matchers::StopArea( // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train" ), matchers::StopArea( // Dijon "stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train" ), matchers::StopArea( // Arc-et-senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", "stop_point:SNCF:87718841:LongDistanceTrain" ), matchers::StopArea( // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", "stop_point:SNCF:87718833:LongDistanceTrain" ), matchers::StopArea( // Pontarlier "stop_area:SNCF:87715003","stop_point:SNCF:87715003:Train" ), matchers::StopArea( // Lons-le-Saunier "stop_area:SNCF:87718239", "stop_point:SNCF:87718239:LongDistanceTrain" ) ) ); // Check departures // Besançon Viotte EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718007"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Besançon "stop_area:SNCF:87718007", "stop_point:SNCF:87718007:Train", // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train", // Departure "105600", // Arrival "112000" ) ), matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Besançon "stop_area:SNCF:87718007", "stop_point:SNCF:87718007:LongDistanceTrain", // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:LongDistanceTrain", // Departure "165200", // Arrival "171500" ) ) ) ); // Dole EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713412"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train", // Dijon "stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train", // Departure "112200", // Arrival "115200" ), matchers::Departure( graph, // Dole "stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train", // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", // Departure "111400", // Arrival "113200" ) ) ) ); // Dijon EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713040"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); // Arc-et-Senans EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718841"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train", // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", // Departure "113300", // Arrival "113900" ) ), matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Arc-et-Senans "stop_area:SNCF:87718841", "stop_point:SNCF:87718841:LongDistanceTrain", // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:LongDistanceTrain", // Departure "171600", // Arrival "172100" ) ) ) ); // Mouchard EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718833"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train", // Pontarlier "stop_area:SNCF:87715003", "stop_point:SNCF:87715003:Train", // Departure "114200", // Arrival "123700" ) ), matchers::DeparturesFromStopPoint( matchers::Departure( graph, // Mouchard "stop_area:SNCF:87718833", "stop_point:SNCF:87718833:LongDistanceTrain", // Lons-le-Saunier "stop_area:SNCF:87718239", "stop_point:SNCF:87718239:LongDistanceTrain", // Departure "172200", // Arrival "175900" ) ) ) ); // Pontarlier EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87715003"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); // Lons-le-Saunier EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718239"), matchers::DeparturesFromStopArea( matchers::DeparturesFromStopPoint( // None ) ) ); }