Internal train network structure

- Defines Network, StopArea, StopPoints and JourneySections
- Loads them from json using the build_from_json method
This commit is contained in:
Paul Breugnot 2026-01-03 14:34:00 +01:00
parent 27c5a55400
commit 61aec3d856
9 changed files with 1877 additions and 0 deletions

View file

@ -3,11 +3,18 @@ add_subdirectory(googletest)
add_executable(
test_trenesis
trenesis/test.cpp
trenesis/network/graph.cpp
)
target_link_libraries(
test_trenesis
trenesis
GTest::gtest_main
GTest::gmock_main
)
include_directories(
assets
)
include(GoogleTest)

View file

@ -0,0 +1,994 @@
constexpr auto single_node_stop_points =
R"-(
{
"stop_points": [
{
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
},
"stop_area": {
"id": "stop_area:SNCF:87713040",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
}
}
}
]
}
)-";
constexpr auto single_node_journey =
// This is a simplified extract from /coverage/sncf/vehicle_journeys
// representing the line Dijon -> Cercy -> Nevers
R"-(
{
"vehicle_journeys": [
{
"stop_times": [
{
"arrival_time": "081200",
"utc_arrival_time": "071200",
"departure_time": "081200",
"utc_departure_time": "071200",
"headsign": "893009",
"stop_point": {
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": false,
"skipped_stop": false
}
]
}
]
}
)-";
constexpr auto dijon_cercy_nevers_stop_points =
// This is a simplified extract from /coverage/sncf/stop_points
// representing stations Dijon, Cercy, Nevers
R"-(
{
"stop_points": [
{
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
},
"stop_area": {
"id": "stop_area:SNCF:87713040",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
}
}
},
{
"id": "stop_point:SNCF:87696492:Train",
"name": "Cercy-la-Tour",
"label": "Cercy-la-Tour (Cercy-la-Tour)",
"coord": {
"lon": "3.645084",
"lat": "46.85793"
},
"stop_area": {
"id": "stop_area:SNCF:87696492",
"name": "Cercy-la-Tour",
"label": "Cercy-la-Tour (Cercy-la-Tour)",
"coord": {
"lon": "3.645084",
"lat": "46.85793"
}
}
},
{
"id": "stop_point:SNCF:87696005:Train",
"name": "Nevers",
"label": "Nevers (Nevers)",
"coord": {
"lon": "3.150743",
"lat": "46.987282"
},
"stop_area": {
"id": "stop_area:SNCF:87696005",
"name": "Nevers",
"label": "Nevers (Nevers)",
"coord": {
"lon": "3.150743",
"lat": "46.987282"
}
}
}
]
}
)-";
constexpr auto dijon_cercy_nevers_journey =
// This is a simplified extract from /coverage/sncf/vehicle_journeys
// representing the line Dijon -> Cercy -> Nevers
R"-(
{
"vehicle_journeys": [
{
"stop_times": [
{
"arrival_time": "081200",
"utc_arrival_time": "071200",
"departure_time": "081200",
"utc_departure_time": "071200",
"headsign": "893009",
"stop_point": {
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
}
}
},
{
"arrival_time": "095300",
"utc_arrival_time": "085300",
"departure_time": "095400",
"utc_departure_time": "085400",
"headsign": "893009",
"stop_point": {
"id": "stop_point:SNCF:87696492:Train",
"name": "Cercy-la-Tour",
"label": "Cercy-la-Tour (Cercy-la-Tour)",
"coord": {
"lon": "3.645084",
"lat": "46.85793"
}
}
},
{
"arrival_time": "102900",
"utc_arrival_time": "092900",
"departure_time": "102900",
"utc_departure_time": "092900",
"headsign": "893009",
"stop_point": {
"id": "stop_point:SNCF:87696005:Train",
"name": "Nevers",
"label": "Nevers (Nevers)",
"coord": {
"lon": "3.150743",
"lat": "46.987282"
}
}
}
]
}
]
}
)-";
constexpr auto besancon_dijon_lons_train_only_stop_points =
R"-(
{
"stop_points": [
{
"id": "stop_point:SNCF:87718007:Train",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
},
"stop_area": {
"id": "stop_area:SNCF:87718007",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
}
}
},
{
"id": "stop_point:SNCF:87713412:Train",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
},
"stop_area": {
"id": "stop_area:SNCF:87713412",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
}
}
},
{
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
},
"stop_area": {
"id": "stop_area:SNCF:87713040",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
}
}
},
{
"id": "stop_point:SNCF:87718841:Train",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
},
"stop_area": {
"id": "stop_area:SNCF:87718841",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
}
}
},
{
"id": "stop_point:SNCF:87718833:Train",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
},
"stop_area": {
"id": "stop_area:SNCF:87718833",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
}
}
},
{
"id": "stop_point:SNCF:87715003:Train",
"name": "Pontarlier",
"label": "Pontarlier (Pontarlier)",
"coord": {
"lon": "6.353418",
"lat": "46.900988"
},
"stop_area": {
"id": "stop_area:SNCF:87715003",
"name": "Pontarlier",
"label": "Pontarlier (Pontarlier)",
"coord": {
"lon": "6.353418",
"lat": "46.900988"
}
}
},
{
"id": "stop_point:SNCF:87718239:Train",
"name": "Lons-le-Saunier",
"label": "Lons-le-Saunier (Lons-le-Saunier)",
"coord": {
"lon": "5.551108",
"lat": "46.66858"
},
"stop_area": {
"id": "stop_area:SNCF:87718239",
"name": "Lons-le-Saunier",
"label": "Lons-le-Saunier (Lons-le-Saunier)",
"coord": {
"lon": "5.551108",
"lat": "46.66858"
}
}
}
]
}
)-";
constexpr auto besancon_dijon_lons_train_only_journeys =
R"-(
{
"vehicle_journeys": [
{
"id": "vehicle_journey:SNCF:2026-01-05:894210:1187:Train",
"name": "894210",
"journey_pattern": {
"id": "journey_pattern:1817",
"name": "journey_pattern:1817"
},
"stop_times": [
{
"arrival_time": "105600",
"utc_arrival_time": "095600",
"departure_time": "105600",
"utc_departure_time": "095600",
"headsign": "894210",
"stop_point": {
"id": "stop_point:SNCF:87718007:Train",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
}
}
},
{
"arrival_time": "112000",
"utc_arrival_time": "102000",
"departure_time": "112200",
"utc_departure_time": "102200",
"headsign": "894210",
"stop_point": {
"id": "stop_point:SNCF:87713412:Train",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
}
}
},
{
"arrival_time": "115200",
"utc_arrival_time": "105200",
"departure_time": "115200",
"utc_departure_time": "105200",
"headsign": "894210",
"stop_point": {
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
}
}
}
]
},
{
"id": "vehicle_journey:SNCF:2025-12-25:895705:1187:Train",
"name": "895705",
"journey_pattern": {
"id": "journey_pattern:1982",
"name": "journey_pattern:1982"
},
"stop_times": [
{
"arrival_time": "111400",
"utc_arrival_time": "101400",
"departure_time": "111400",
"utc_departure_time": "101400",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87713412:Train",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
}
}
},
{
"arrival_time": "113200",
"utc_arrival_time": "103200",
"departure_time": "113300",
"utc_departure_time": "103300",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87718841:Train",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
}
}
},
{
"arrival_time": "113900",
"utc_arrival_time": "103900",
"departure_time": "114200",
"utc_departure_time": "104200",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87718833:Train",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
}
}
},
{
"arrival_time": "123700",
"utc_arrival_time": "113700",
"departure_time": "123700",
"utc_departure_time": "113700",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87715003:Train",
"name": "Pontarlier",
"label": "Pontarlier (Pontarlier)",
"coord": {
"lon": "6.353418",
"lat": "46.900988"
}
}
}
]
},
{
"id": "vehicle_journey:SNCF:2025-12-30:895857:1187:Train",
"name": "895857",
"journey_pattern": {
"id": "journey_pattern:1899",
"name": "journey_pattern:1899"
},
"stop_times": [
{
"arrival_time": "164700",
"utc_arrival_time": "154700",
"departure_time": "165200",
"utc_departure_time": "155200",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718007:Train",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
}
}
},
{
"arrival_time": "171500",
"utc_arrival_time": "161500",
"departure_time": "171600",
"utc_departure_time": "161600",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718841:Train",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
}
}
},
{
"arrival_time": "172100",
"utc_arrival_time": "162100",
"departure_time": "172200",
"utc_departure_time": "162200",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718833:Train",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
}
}
},
{
"arrival_time": "175900",
"utc_arrival_time": "165900",
"departure_time": "180100",
"utc_departure_time": "170100",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718239:Train",
"name": "Lons-le-Saunier",
"label": "Lons-le-Saunier (Lons-le-Saunier)",
"coord": {
"lon": "5.551108",
"lat": "46.66858"
}
}
}
]
}
]
}
)-";
constexpr auto besancon_dijon_lons_stop_points =
R"-(
{
"stop_points": [
{
"id": "stop_point:SNCF:87718007:Train",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
},
"stop_area": {
"id": "stop_area:SNCF:87718007",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
}
}
},
{
"id": "stop_point:SNCF:87713412:Train",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
},
"stop_area": {
"id": "stop_area:SNCF:87713412",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
}
}
},
{
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
},
"stop_area": {
"id": "stop_area:SNCF:87713040",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
}
}
},
{
"id": "stop_point:SNCF:87718841:Train",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
},
"stop_area": {
"id": "stop_area:SNCF:87718841",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
}
}
},
{
"id": "stop_point:SNCF:87718833:Train",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
},
"stop_area": {
"id": "stop_area:SNCF:87718833",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
}
}
},
{
"id": "stop_point:SNCF:87715003:Train",
"name": "Pontarlier",
"label": "Pontarlier (Pontarlier)",
"coord": {
"lon": "6.353418",
"lat": "46.900988"
},
"stop_area": {
"id": "stop_area:SNCF:87715003",
"name": "Pontarlier",
"label": "Pontarlier (Pontarlier)",
"coord": {
"lon": "6.353418",
"lat": "46.900988"
}
}
},
{
"id": "stop_point:SNCF:87718007:LongDistanceTrain",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
},
"stop_area": {
"id": "stop_area:SNCF:87718007",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
}
}
},
{
"id": "stop_point:SNCF:87718841:LongDistanceTrain",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
},
"stop_area": {
"id": "stop_area:SNCF:87718841",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
}
}
},
{
"id": "stop_point:SNCF:87718833:LongDistanceTrain",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
},
"stop_area": {
"id": "stop_area:SNCF:87718833",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
}
}
},
{
"id": "stop_point:SNCF:87718239:LongDistanceTrain",
"name": "Lons-le-Saunier",
"label": "Lons-le-Saunier (Lons-le-Saunier)",
"coord": {
"lon": "5.551108",
"lat": "46.66858"
},
"stop_area": {
"id": "stop_area:SNCF:87718239",
"name": "Lons-le-Saunier",
"label": "Lons-le-Saunier (Lons-le-Saunier)",
"coord": {
"lon": "5.551108",
"lat": "46.66858"
}
}
}
]
}
)-";
constexpr auto besancon_dijon_lons_journeys =
R"-(
{
"vehicle_journeys": [
{
"id": "vehicle_journey:SNCF:2026-01-05:894210:1187:Train",
"name": "894210",
"journey_pattern": {
"id": "journey_pattern:1817",
"name": "journey_pattern:1817"
},
"stop_times": [
{
"arrival_time": "105600",
"utc_arrival_time": "095600",
"departure_time": "105600",
"utc_departure_time": "095600",
"headsign": "894210",
"stop_point": {
"id": "stop_point:SNCF:87718007:Train",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": false,
"skipped_stop": false
},
{
"arrival_time": "112000",
"utc_arrival_time": "102000",
"departure_time": "112200",
"utc_departure_time": "102200",
"headsign": "894210",
"stop_point": {
"id": "stop_point:SNCF:87713412:Train",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
},
{
"arrival_time": "115200",
"utc_arrival_time": "105200",
"departure_time": "115200",
"utc_departure_time": "105200",
"headsign": "894210",
"stop_point": {
"id": "stop_point:SNCF:87713040:Train",
"name": "Dijon",
"label": "Dijon (Dijon)",
"coord": {
"lon": "5.027256",
"lat": "47.323411"
},
"links": [],
"equipments": []
},
"pickup_allowed": false,
"drop_off_allowed": true,
"skipped_stop": false
}
]
},
{
"id": "vehicle_journey:SNCF:2025-12-25:895705:1187:Train",
"name": "895705",
"journey_pattern": {
"id": "journey_pattern:1982",
"name": "journey_pattern:1982"
},
"stop_times": [
{
"arrival_time": "111400",
"utc_arrival_time": "101400",
"departure_time": "111400",
"utc_departure_time": "101400",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87713412:Train",
"name": "Dole-Ville",
"label": "Dole-Ville (Dole)",
"coord": {
"lon": "5.48806",
"lat": "47.09615"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": false,
"skipped_stop": false
},
{
"arrival_time": "113200",
"utc_arrival_time": "103200",
"departure_time": "113300",
"utc_departure_time": "103300",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87718841:Train",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
},
{
"arrival_time": "113900",
"utc_arrival_time": "103900",
"departure_time": "114200",
"utc_departure_time": "104200",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87718833:Train",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
},
{
"arrival_time": "123700",
"utc_arrival_time": "113700",
"departure_time": "123700",
"utc_departure_time": "113700",
"headsign": "895705",
"stop_point": {
"id": "stop_point:SNCF:87715003:Train",
"name": "Pontarlier",
"label": "Pontarlier (Pontarlier)",
"coord": {
"lon": "6.353418",
"lat": "46.900988"
},
"links": [],
"equipments": []
},
"pickup_allowed": false,
"drop_off_allowed": true,
"skipped_stop": false
}
]
},
{
"id": "vehicle_journey:SNCF:2025-12-30:895857:1187:LongDistanceTrain",
"name": "895857",
"journey_pattern": {
"id": "journey_pattern:1899",
"name": "journey_pattern:1899"
},
"stop_times": [
{
"arrival_time": "164700",
"utc_arrival_time": "154700",
"departure_time": "165200",
"utc_departure_time": "155200",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718007:LongDistanceTrain",
"name": "Besançon Viotte",
"label": "Besançon Viotte (Besançon)",
"coord": {
"lon": "6.021943",
"lat": "47.247049"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
},
{
"arrival_time": "171500",
"utc_arrival_time": "161500",
"departure_time": "171600",
"utc_departure_time": "161600",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718841:LongDistanceTrain",
"name": "Arc-et-Senans",
"label": "Arc-et-Senans (Arc-et-Senans)",
"coord": {
"lon": "5.77683",
"lat": "47.030473"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
},
{
"arrival_time": "172100",
"utc_arrival_time": "162100",
"departure_time": "172200",
"utc_departure_time": "162200",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718833:LongDistanceTrain",
"name": "Mouchard",
"label": "Mouchard (Mouchard)",
"coord": {
"lon": "5.799698",
"lat": "46.976865"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
},
{
"arrival_time": "175900",
"utc_arrival_time": "165900",
"departure_time": "180100",
"utc_departure_time": "170100",
"headsign": "895857",
"stop_point": {
"id": "stop_point:SNCF:87718239:LongDistanceTrain",
"name": "Lons-le-Saunier",
"label": "Lons-le-Saunier (Lons-le-Saunier)",
"coord": {
"lon": "5.551108",
"lat": "46.66858"
},
"links": [],
"equipments": []
},
"pickup_allowed": true,
"drop_off_allowed": true,
"skipped_stop": false
}
]
}
]
}
)-";

View file

@ -0,0 +1,675 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#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<class... StopPoints>
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<class... Departures>
auto DeparturesFromStopPoint(Departures... departures) {
return Field(
"value",
&stop_point_pair::second,
Pointee(
Field(
"departures", &StopPoint::departures, UnorderedElementsAre(
departures...
)
)
)
);
}
template<class... DeparturesFromStopPoint>
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
)
)
);
}