Skip to content

Commit f89774a

Browse files
authored
fix: Predefined Routes with Deviation trigger + test (#1862)
1 parent e3b9f3d commit f89774a

File tree

2 files changed

+58
-24
lines changed

2 files changed

+58
-24
lines changed

main/src/main/java/org/mobilitydata/gtfsvalidator/report/model/FeedMetadata.java

+37-24
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public static FeedMetadata from(GtfsFeedContainer feedContainer, ImmutableSet<St
114114
(GtfsTableContainer<GtfsCalendarDate, ?>)
115115
feedContainer.getTableForFilename(GtfsCalendarDate.FILENAME).get());
116116
}
117+
117118
feedMetadata.loadSpecFeatures(feedContainer);
118119
return feedMetadata;
119120
}
@@ -195,25 +196,41 @@ private void loadDeviatedFixedRouteFeature(GtfsFeedContainer feedContainer) {
195196
}
196197

197198
private boolean hasAtLeastOneTripWithAllFields(GtfsFeedContainer feedContainer) {
198-
var optionalStopTimeTable = feedContainer.getTableForFilename(GtfsStopTime.FILENAME);
199-
if (optionalStopTimeTable.isPresent()) {
200-
for (GtfsEntity entity : optionalStopTimeTable.get().getEntities()) {
201-
if (entity instanceof GtfsStopTime) {
202-
GtfsStopTime stopTime = (GtfsStopTime) entity;
203-
return stopTime.hasTripId()
204-
&& stopTime.tripId() != null
205-
&& stopTime.hasLocationId()
206-
&& stopTime.locationId() != null
207-
&& stopTime.hasStopId()
208-
&& stopTime.stopId() != null
209-
&& stopTime.hasArrivalTime()
210-
&& stopTime.arrivalTime() != null
211-
&& stopTime.hasDepartureTime()
212-
&& stopTime.departureTime() != null;
213-
}
214-
}
215-
}
216-
return false;
199+
return feedContainer
200+
.getTableForFilename(GtfsStopTime.FILENAME)
201+
.map(table -> (GtfsStopTimeTableContainer) table)
202+
.map(GtfsStopTimeTableContainer::byTripIdMap)
203+
.map(
204+
byTripIdMap ->
205+
byTripIdMap.asMap().values().stream()
206+
.anyMatch(
207+
gtfsStopTimes -> {
208+
boolean hasTripId = false,
209+
hasLocationId = false,
210+
hasStopId = false,
211+
hasArrivalTime = false,
212+
hasDepartureTime = false;
213+
214+
for (GtfsStopTime stopTime : gtfsStopTimes) {
215+
hasTripId |= stopTime.hasTripId();
216+
hasLocationId |= stopTime.hasLocationId();
217+
hasStopId |= stopTime.hasStopId();
218+
hasArrivalTime |= stopTime.hasArrivalTime();
219+
hasDepartureTime |= stopTime.hasDepartureTime();
220+
221+
// Early return if all fields are found for this trip
222+
if (hasTripId
223+
&& hasLocationId
224+
&& hasStopId
225+
&& hasArrivalTime
226+
&& hasDepartureTime) {
227+
return true;
228+
}
229+
}
230+
// Continue checking other trips
231+
return false;
232+
}))
233+
.orElse(false);
217234
}
218235

219236
private void loadZoneBasedDemandResponsiveTransitFeature(GtfsFeedContainer feedContainer) {
@@ -228,11 +245,7 @@ private boolean hasAtLeastOneTripWithOnlyLocationId(GtfsFeedContainer feedContai
228245
for (GtfsEntity entity : optionalStopTimeTable.get().getEntities()) {
229246
if (entity instanceof GtfsStopTime) {
230247
GtfsStopTime stopTime = (GtfsStopTime) entity;
231-
if (stopTime.hasTripId()
232-
&& stopTime.tripId() != null
233-
&& stopTime.hasLocationId()
234-
&& stopTime.locationId() != null
235-
&& (!stopTime.hasStopId() || stopTime.stopId() == null)) {
248+
if (stopTime.hasTripId() && stopTime.hasLocationId() && (!stopTime.hasStopId())) {
236249
return true;
237250
}
238251
}

main/src/test/java/org/mobilitydata/gtfsvalidator/report/model/FeedMetadataTest.java

+21
Original file line numberDiff line numberDiff line change
@@ -513,4 +513,25 @@ public void containsWheelchairAccessibilityFeature() throws IOException, Interru
513513
true,
514514
ImmutableList.of(GtfsAgencyTableDescriptor.class, GtfsTripTableDescriptor.class));
515515
}
516+
517+
@Test
518+
public void containsDeviatedFixedRouteFeatureTest() throws IOException, InterruptedException {
519+
// Create stop times with various field combinations for the same trip
520+
String stopTimesContent =
521+
"trip_id, stop_sequence, arrival_time, departure_time, stop_id, location_id\n"
522+
+ "trip1,1,01:00:00,01:30:00,stop1,location1\n"
523+
+ "trip1,2,,02:30:00,,location2\n"
524+
+ "trip1,3,02:00:00,,stop2,location2";
525+
526+
createDataFile(GtfsStopTime.FILENAME, stopTimesContent);
527+
528+
// Validate that the feature is present
529+
validateSpecFeature(
530+
"Predefined Routes with Deviation",
531+
true,
532+
ImmutableList.of(
533+
GtfsAgencyTableDescriptor.class,
534+
GtfsStopTimeTableDescriptor.class,
535+
GtfsTripTableDescriptor.class));
536+
}
516537
}

0 commit comments

Comments
 (0)